]>
Commit | Line | Data |
---|---|---|
793958c9 TS |
1 | #!/usr/bin/env python3 |
2 | ||
3 | ## | |
1e814a0d | 4 | ## Copyright(c) 2019-2022 Qualcomm Innovation Center, Inc. All Rights Reserved. |
793958c9 TS |
5 | ## |
6 | ## This program is free software; you can redistribute it and/or modify | |
7 | ## it under the terms of the GNU General Public License as published by | |
8 | ## the Free Software Foundation; either version 2 of the License, or | |
9 | ## (at your option) any later version. | |
10 | ## | |
11 | ## This program is distributed in the hope that it will be useful, | |
12 | ## but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | ## GNU General Public License for more details. | |
15 | ## | |
16 | ## You should have received a copy of the GNU General Public License | |
17 | ## along with this program; if not, see <http://www.gnu.org/licenses/>. | |
18 | ## | |
19 | ||
20 | import sys | |
21 | import re | |
22 | import string | |
23 | import hex_common | |
24 | ||
25 | ## | |
26 | ## Helpers for gen_tcg_func | |
27 | ## | |
28 | def gen_decl_ea_tcg(f, tag): | |
29 | if ('A_CONDEXEC' in hex_common.attribdict[tag] or | |
30 | 'A_LOAD' in hex_common.attribdict[tag]): | |
31 | f.write(" TCGv EA = tcg_temp_local_new();\n") | |
32 | else: | |
33 | f.write(" TCGv EA = tcg_temp_new();\n") | |
34 | ||
35 | def gen_free_ea_tcg(f): | |
36 | f.write(" tcg_temp_free(EA);\n") | |
37 | ||
fc253f4a | 38 | def genptr_decl_pair_writable(f, tag, regtype, regid, regno): |
793958c9 TS |
39 | regN="%s%sN" % (regtype,regid) |
40 | f.write(" TCGv_i64 %s%sV = tcg_temp_local_new_i64();\n" % \ | |
41 | (regtype, regid)) | |
42 | if (regtype == "C"): | |
43 | f.write(" const int %s = insn->regno[%d] + HEX_REG_SA0;\n" % \ | |
44 | (regN, regno)) | |
45 | else: | |
46 | f.write(" const int %s = insn->regno[%d];\n" % (regN, regno)) | |
47 | if ('A_CONDEXEC' in hex_common.attribdict[tag]): | |
48 | f.write(" if (!is_preloaded(ctx, %s)) {\n" % regN) | |
49 | f.write(" tcg_gen_mov_tl(hex_new_value[%s], hex_gpr[%s]);\n" % \ | |
50 | (regN, regN)) | |
51 | f.write(" }\n") | |
52 | f.write(" if (!is_preloaded(ctx, %s + 1)) {\n" % regN) | |
53 | f.write(" tcg_gen_mov_tl(hex_new_value[%s + 1], hex_gpr[%s + 1]);\n" % \ | |
54 | (regN, regN)) | |
55 | f.write(" }\n") | |
56 | ||
fc253f4a | 57 | def genptr_decl_writable(f, tag, regtype, regid, regno): |
793958c9 TS |
58 | regN="%s%sN" % (regtype,regid) |
59 | f.write(" TCGv %s%sV = tcg_temp_local_new();\n" % \ | |
60 | (regtype, regid)) | |
61 | if (regtype == "C"): | |
62 | f.write(" const int %s = insn->regno[%d] + HEX_REG_SA0;\n" % \ | |
63 | (regN, regno)) | |
64 | else: | |
65 | f.write(" const int %s = insn->regno[%d];\n" % (regN, regno)) | |
66 | if ('A_CONDEXEC' in hex_common.attribdict[tag]): | |
67 | f.write(" if (!is_preloaded(ctx, %s)) {\n" % regN) | |
68 | f.write(" tcg_gen_mov_tl(hex_new_value[%s], hex_gpr[%s]);\n" % \ | |
69 | (regN, regN)) | |
70 | f.write(" }\n") | |
71 | ||
72 | def genptr_decl(f, tag, regtype, regid, regno): | |
73 | regN="%s%sN" % (regtype,regid) | |
74 | if (regtype == "R"): | |
75 | if (regid in {"ss", "tt"}): | |
76 | f.write(" TCGv_i64 %s%sV = tcg_temp_local_new_i64();\n" % \ | |
77 | (regtype, regid)) | |
78 | f.write(" const int %s = insn->regno[%d];\n" % \ | |
79 | (regN, regno)) | |
80 | elif (regid in {"dd", "ee", "xx", "yy"}): | |
fc253f4a | 81 | genptr_decl_pair_writable(f, tag, regtype, regid, regno) |
793958c9 TS |
82 | elif (regid in {"s", "t", "u", "v"}): |
83 | f.write(" TCGv %s%sV = hex_gpr[insn->regno[%d]];\n" % \ | |
84 | (regtype, regid, regno)) | |
85 | elif (regid in {"d", "e", "x", "y"}): | |
fc253f4a | 86 | genptr_decl_writable(f, tag, regtype, regid, regno) |
793958c9 TS |
87 | else: |
88 | print("Bad register parse: ", regtype, regid) | |
89 | elif (regtype == "P"): | |
90 | if (regid in {"s", "t", "u", "v"}): | |
91 | f.write(" TCGv %s%sV = hex_pred[insn->regno[%d]];\n" % \ | |
92 | (regtype, regid, regno)) | |
93 | elif (regid in {"d", "e", "x"}): | |
fc253f4a | 94 | genptr_decl_writable(f, tag, regtype, regid, regno) |
793958c9 TS |
95 | else: |
96 | print("Bad register parse: ", regtype, regid) | |
97 | elif (regtype == "C"): | |
98 | if (regid == "ss"): | |
99 | f.write(" TCGv_i64 %s%sV = tcg_temp_local_new_i64();\n" % \ | |
100 | (regtype, regid)) | |
101 | f.write(" const int %s = insn->regno[%d] + HEX_REG_SA0;\n" % \ | |
102 | (regN, regno)) | |
103 | elif (regid == "dd"): | |
fc253f4a | 104 | genptr_decl_pair_writable(f, tag, regtype, regid, regno) |
793958c9 TS |
105 | elif (regid == "s"): |
106 | f.write(" TCGv %s%sV = tcg_temp_local_new();\n" % \ | |
107 | (regtype, regid)) | |
108 | f.write(" const int %s%sN = insn->regno[%d] + HEX_REG_SA0;\n" % \ | |
109 | (regtype, regid, regno)) | |
110 | elif (regid == "d"): | |
fc253f4a | 111 | genptr_decl_writable(f, tag, regtype, regid, regno) |
793958c9 TS |
112 | else: |
113 | print("Bad register parse: ", regtype, regid) | |
114 | elif (regtype == "M"): | |
115 | if (regid == "u"): | |
116 | f.write(" const int %s%sN = insn->regno[%d];\n"% \ | |
117 | (regtype, regid, regno)) | |
118 | f.write(" TCGv %s%sV = hex_gpr[%s%sN + HEX_REG_M0];\n" % \ | |
119 | (regtype, regid, regtype, regid)) | |
120 | else: | |
121 | print("Bad register parse: ", regtype, regid) | |
ccd9eec8 TS |
122 | elif (regtype == "V"): |
123 | if (regid in {"dd"}): | |
124 | f.write(" const int %s%sN = insn->regno[%d];\n" %\ | |
125 | (regtype, regid, regno)) | |
126 | f.write(" const intptr_t %s%sV_off =\n" %\ | |
127 | (regtype, regid)) | |
128 | if (hex_common.is_tmp_result(tag)): | |
129 | f.write(" ctx_tmp_vreg_off(ctx, %s%sN, 2, true);\n" % \ | |
130 | (regtype, regid)) | |
131 | else: | |
132 | f.write(" ctx_future_vreg_off(ctx, %s%sN," % \ | |
133 | (regtype, regid)) | |
134 | f.write(" 2, true);\n") | |
135 | if (not hex_common.skip_qemu_helper(tag)): | |
136 | f.write(" TCGv_ptr %s%sV = tcg_temp_new_ptr();\n" % \ | |
137 | (regtype, regid)) | |
138 | f.write(" tcg_gen_addi_ptr(%s%sV, cpu_env, %s%sV_off);\n" % \ | |
139 | (regtype, regid, regtype, regid)) | |
140 | elif (regid in {"uu", "vv", "xx"}): | |
141 | f.write(" const int %s%sN = insn->regno[%d];\n" % \ | |
142 | (regtype, regid, regno)) | |
143 | f.write(" const intptr_t %s%sV_off =\n" % \ | |
144 | (regtype, regid)) | |
145 | f.write(" offsetof(CPUHexagonState, %s%sV);\n" % \ | |
146 | (regtype, regid)) | |
147 | if (not hex_common.skip_qemu_helper(tag)): | |
148 | f.write(" TCGv_ptr %s%sV = tcg_temp_new_ptr();\n" % \ | |
149 | (regtype, regid)) | |
150 | f.write(" tcg_gen_addi_ptr(%s%sV, cpu_env, %s%sV_off);\n" % \ | |
151 | (regtype, regid, regtype, regid)) | |
152 | elif (regid in {"s", "u", "v", "w"}): | |
153 | f.write(" const int %s%sN = insn->regno[%d];\n" % \ | |
154 | (regtype, regid, regno)) | |
155 | f.write(" const intptr_t %s%sV_off =\n" % \ | |
156 | (regtype, regid)) | |
157 | f.write(" vreg_src_off(ctx, %s%sN);\n" % \ | |
158 | (regtype, regid)) | |
159 | if (not hex_common.skip_qemu_helper(tag)): | |
160 | f.write(" TCGv_ptr %s%sV = tcg_temp_new_ptr();\n" % \ | |
161 | (regtype, regid)) | |
162 | elif (regid in {"d", "x", "y"}): | |
163 | f.write(" const int %s%sN = insn->regno[%d];\n" % \ | |
164 | (regtype, regid, regno)) | |
165 | f.write(" const intptr_t %s%sV_off =\n" % \ | |
166 | (regtype, regid)) | |
1e814a0d TS |
167 | if (regid == "y"): |
168 | f.write(" offsetof(CPUHexagonState, vtmp);\n") | |
169 | elif (hex_common.is_tmp_result(tag)): | |
ccd9eec8 TS |
170 | f.write(" ctx_tmp_vreg_off(ctx, %s%sN, 1, true);\n" % \ |
171 | (regtype, regid)) | |
172 | else: | |
173 | f.write(" ctx_future_vreg_off(ctx, %s%sN," % \ | |
174 | (regtype, regid)) | |
175 | f.write(" 1, true);\n"); | |
83853ea0 TS |
176 | if 'A_CONDEXEC' in hex_common.attribdict[tag]: |
177 | f.write(" if (!is_vreg_preloaded(ctx, %s)) {\n" % (regN)) | |
178 | f.write(" intptr_t src_off =") | |
179 | f.write(" offsetof(CPUHexagonState, VRegs[%s%sN]);\n"% \ | |
180 | (regtype, regid)) | |
181 | f.write(" tcg_gen_gvec_mov(MO_64, %s%sV_off,\n" % \ | |
182 | (regtype, regid)) | |
183 | f.write(" src_off,\n") | |
184 | f.write(" sizeof(MMVector),\n") | |
185 | f.write(" sizeof(MMVector));\n") | |
186 | f.write(" }\n") | |
187 | ||
ccd9eec8 TS |
188 | if (not hex_common.skip_qemu_helper(tag)): |
189 | f.write(" TCGv_ptr %s%sV = tcg_temp_new_ptr();\n" % \ | |
190 | (regtype, regid)) | |
191 | f.write(" tcg_gen_addi_ptr(%s%sV, cpu_env, %s%sV_off);\n" % \ | |
192 | (regtype, regid, regtype, regid)) | |
193 | else: | |
194 | print("Bad register parse: ", regtype, regid) | |
195 | elif (regtype == "Q"): | |
196 | if (regid in {"d", "e", "x"}): | |
197 | f.write(" const int %s%sN = insn->regno[%d];\n" % \ | |
198 | (regtype, regid, regno)) | |
199 | f.write(" const intptr_t %s%sV_off =\n" % \ | |
200 | (regtype, regid)) | |
201 | f.write(" offsetof(CPUHexagonState,\n") | |
202 | f.write(" future_QRegs[%s%sN]);\n" % \ | |
203 | (regtype, regid)) | |
204 | if (not hex_common.skip_qemu_helper(tag)): | |
205 | f.write(" TCGv_ptr %s%sV = tcg_temp_new_ptr();\n" % \ | |
206 | (regtype, regid)) | |
207 | f.write(" tcg_gen_addi_ptr(%s%sV, cpu_env, %s%sV_off);\n" % \ | |
208 | (regtype, regid, regtype, regid)) | |
209 | elif (regid in {"s", "t", "u", "v"}): | |
210 | f.write(" const int %s%sN = insn->regno[%d];\n" % \ | |
211 | (regtype, regid, regno)) | |
212 | f.write(" const intptr_t %s%sV_off =\n" %\ | |
213 | (regtype, regid)) | |
214 | f.write(" offsetof(CPUHexagonState, QRegs[%s%sN]);\n" % \ | |
215 | (regtype, regid)) | |
216 | if (not hex_common.skip_qemu_helper(tag)): | |
217 | f.write(" TCGv_ptr %s%sV = tcg_temp_new_ptr();\n" % \ | |
218 | (regtype, regid)) | |
219 | else: | |
220 | print("Bad register parse: ", regtype, regid) | |
793958c9 TS |
221 | else: |
222 | print("Bad register parse: ", regtype, regid) | |
223 | ||
ccd9eec8 | 224 | def genptr_decl_new(f, tag, regtype, regid, regno): |
793958c9 TS |
225 | if (regtype == "N"): |
226 | if (regid in {"s", "t"}): | |
227 | f.write(" TCGv %s%sN = hex_new_value[insn->regno[%d]];\n" % \ | |
228 | (regtype, regid, regno)) | |
229 | else: | |
230 | print("Bad register parse: ", regtype, regid) | |
231 | elif (regtype == "P"): | |
232 | if (regid in {"t", "u", "v"}): | |
233 | f.write(" TCGv %s%sN = hex_new_pred_value[insn->regno[%d]];\n" % \ | |
234 | (regtype, regid, regno)) | |
235 | else: | |
236 | print("Bad register parse: ", regtype, regid) | |
ccd9eec8 TS |
237 | elif (regtype == "O"): |
238 | if (regid == "s"): | |
239 | f.write(" const intptr_t %s%sN_num = insn->regno[%d];\n" % \ | |
240 | (regtype, regid, regno)) | |
241 | if (hex_common.skip_qemu_helper(tag)): | |
242 | f.write(" const intptr_t %s%sN_off =\n" % \ | |
243 | (regtype, regid)) | |
244 | f.write(" ctx_future_vreg_off(ctx, %s%sN_num," % \ | |
245 | (regtype, regid)) | |
246 | f.write(" 1, true);\n") | |
247 | else: | |
248 | f.write(" TCGv %s%sN = tcg_constant_tl(%s%sN_num);\n" % \ | |
249 | (regtype, regid, regtype, regid)) | |
250 | else: | |
251 | print("Bad register parse: ", regtype, regid) | |
793958c9 TS |
252 | else: |
253 | print("Bad register parse: ", regtype, regid) | |
254 | ||
255 | def genptr_decl_opn(f, tag, regtype, regid, toss, numregs, i): | |
256 | if (hex_common.is_pair(regid)): | |
257 | genptr_decl(f, tag, regtype, regid, i) | |
258 | elif (hex_common.is_single(regid)): | |
259 | if hex_common.is_old_val(regtype, regid, tag): | |
260 | genptr_decl(f,tag, regtype, regid, i) | |
261 | elif hex_common.is_new_val(regtype, regid, tag): | |
ccd9eec8 | 262 | genptr_decl_new(f, tag, regtype, regid, i) |
793958c9 TS |
263 | else: |
264 | print("Bad register parse: ",regtype,regid,toss,numregs) | |
265 | else: | |
266 | print("Bad register parse: ",regtype,regid,toss,numregs) | |
267 | ||
268 | def genptr_decl_imm(f,immlett): | |
269 | if (immlett.isupper()): | |
270 | i = 1 | |
271 | else: | |
272 | i = 0 | |
273 | f.write(" int %s = insn->immed[%d];\n" % \ | |
274 | (hex_common.imm_name(immlett), i)) | |
275 | ||
ccd9eec8 | 276 | def genptr_free(f, tag, regtype, regid, regno): |
793958c9 TS |
277 | if (regtype == "R"): |
278 | if (regid in {"dd", "ss", "tt", "xx", "yy"}): | |
279 | f.write(" tcg_temp_free_i64(%s%sV);\n" % (regtype, regid)) | |
280 | elif (regid in {"d", "e", "x", "y"}): | |
281 | f.write(" tcg_temp_free(%s%sV);\n" % (regtype, regid)) | |
282 | elif (regid not in {"s", "t", "u", "v"}): | |
283 | print("Bad register parse: ",regtype,regid) | |
284 | elif (regtype == "P"): | |
285 | if (regid in {"d", "e", "x"}): | |
286 | f.write(" tcg_temp_free(%s%sV);\n" % (regtype, regid)) | |
287 | elif (regid not in {"s", "t", "u", "v"}): | |
288 | print("Bad register parse: ",regtype,regid) | |
289 | elif (regtype == "C"): | |
290 | if (regid in {"dd", "ss"}): | |
291 | f.write(" tcg_temp_free_i64(%s%sV);\n" % (regtype, regid)) | |
292 | elif (regid in {"d", "s"}): | |
293 | f.write(" tcg_temp_free(%s%sV);\n" % (regtype, regid)) | |
294 | else: | |
295 | print("Bad register parse: ",regtype,regid) | |
296 | elif (regtype == "M"): | |
297 | if (regid != "u"): | |
298 | print("Bad register parse: ", regtype, regid) | |
ccd9eec8 TS |
299 | elif (regtype == "V"): |
300 | if (regid in {"dd", "uu", "vv", "xx", \ | |
301 | "d", "s", "u", "v", "w", "x", "y"}): | |
302 | if (not hex_common.skip_qemu_helper(tag)): | |
303 | f.write(" tcg_temp_free_ptr(%s%sV);\n" % \ | |
304 | (regtype, regid)) | |
305 | else: | |
306 | print("Bad register parse: ", regtype, regid) | |
307 | elif (regtype == "Q"): | |
308 | if (regid in {"d", "e", "s", "t", "u", "v", "x"}): | |
309 | if (not hex_common.skip_qemu_helper(tag)): | |
310 | f.write(" tcg_temp_free_ptr(%s%sV);\n" % \ | |
311 | (regtype, regid)) | |
312 | else: | |
313 | print("Bad register parse: ", regtype, regid) | |
793958c9 TS |
314 | else: |
315 | print("Bad register parse: ", regtype, regid) | |
316 | ||
ccd9eec8 | 317 | def genptr_free_new(f, tag, regtype, regid, regno): |
793958c9 TS |
318 | if (regtype == "N"): |
319 | if (regid not in {"s", "t"}): | |
320 | print("Bad register parse: ", regtype, regid) | |
321 | elif (regtype == "P"): | |
322 | if (regid not in {"t", "u", "v"}): | |
323 | print("Bad register parse: ", regtype, regid) | |
ccd9eec8 TS |
324 | elif (regtype == "O"): |
325 | if (regid != "s"): | |
326 | print("Bad register parse: ", regtype, regid) | |
793958c9 TS |
327 | else: |
328 | print("Bad register parse: ", regtype, regid) | |
329 | ||
330 | def genptr_free_opn(f,regtype,regid,i,tag): | |
331 | if (hex_common.is_pair(regid)): | |
ccd9eec8 | 332 | genptr_free(f, tag, regtype, regid, i) |
793958c9 TS |
333 | elif (hex_common.is_single(regid)): |
334 | if hex_common.is_old_val(regtype, regid, tag): | |
ccd9eec8 | 335 | genptr_free(f, tag, regtype, regid, i) |
793958c9 | 336 | elif hex_common.is_new_val(regtype, regid, tag): |
ccd9eec8 | 337 | genptr_free_new(f, tag, regtype, regid, i) |
793958c9 TS |
338 | else: |
339 | print("Bad register parse: ",regtype,regid,toss,numregs) | |
340 | else: | |
341 | print("Bad register parse: ",regtype,regid,toss,numregs) | |
342 | ||
ccd9eec8 | 343 | def genptr_src_read(f, tag, regtype, regid): |
793958c9 TS |
344 | if (regtype == "R"): |
345 | if (regid in {"ss", "tt", "xx", "yy"}): | |
346 | f.write(" tcg_gen_concat_i32_i64(%s%sV, hex_gpr[%s%sN],\n" % \ | |
347 | (regtype, regid, regtype, regid)) | |
348 | f.write(" hex_gpr[%s%sN + 1]);\n" % \ | |
349 | (regtype, regid)) | |
350 | elif (regid in {"x", "y"}): | |
351 | f.write(" tcg_gen_mov_tl(%s%sV, hex_gpr[%s%sN]);\n" % \ | |
352 | (regtype,regid,regtype,regid)) | |
353 | elif (regid not in {"s", "t", "u", "v"}): | |
354 | print("Bad register parse: ", regtype, regid) | |
355 | elif (regtype == "P"): | |
356 | if (regid == "x"): | |
357 | f.write(" tcg_gen_mov_tl(%s%sV, hex_pred[%s%sN]);\n" % \ | |
358 | (regtype, regid, regtype, regid)) | |
359 | elif (regid not in {"s", "t", "u", "v"}): | |
360 | print("Bad register parse: ", regtype, regid) | |
361 | elif (regtype == "C"): | |
362 | if (regid == "ss"): | |
363 | f.write(" gen_read_ctrl_reg_pair(ctx, %s%sN, %s%sV);\n" % \ | |
364 | (regtype, regid, regtype, regid)) | |
365 | elif (regid == "s"): | |
366 | f.write(" gen_read_ctrl_reg(ctx, %s%sN, %s%sV);\n" % \ | |
367 | (regtype, regid, regtype, regid)) | |
368 | else: | |
369 | print("Bad register parse: ", regtype, regid) | |
370 | elif (regtype == "M"): | |
371 | if (regid != "u"): | |
372 | print("Bad register parse: ", regtype, regid) | |
ccd9eec8 TS |
373 | elif (regtype == "V"): |
374 | if (regid in {"uu", "vv", "xx"}): | |
375 | f.write(" tcg_gen_gvec_mov(MO_64, %s%sV_off,\n" % \ | |
376 | (regtype, regid)) | |
377 | f.write(" vreg_src_off(ctx, %s%sN),\n" % \ | |
378 | (regtype, regid)) | |
379 | f.write(" sizeof(MMVector), sizeof(MMVector));\n") | |
380 | f.write(" tcg_gen_gvec_mov(MO_64,\n") | |
381 | f.write(" %s%sV_off + sizeof(MMVector),\n" % \ | |
382 | (regtype, regid)) | |
383 | f.write(" vreg_src_off(ctx, %s%sN ^ 1),\n" % \ | |
384 | (regtype, regid)) | |
385 | f.write(" sizeof(MMVector), sizeof(MMVector));\n") | |
386 | elif (regid in {"s", "u", "v", "w"}): | |
387 | if (not hex_common.skip_qemu_helper(tag)): | |
388 | f.write(" tcg_gen_addi_ptr(%s%sV, cpu_env, %s%sV_off);\n" % \ | |
389 | (regtype, regid, regtype, regid)) | |
390 | elif (regid in {"x", "y"}): | |
391 | f.write(" tcg_gen_gvec_mov(MO_64, %s%sV_off,\n" % \ | |
392 | (regtype, regid)) | |
393 | f.write(" vreg_src_off(ctx, %s%sN),\n" % \ | |
394 | (regtype, regid)) | |
395 | f.write(" sizeof(MMVector), sizeof(MMVector));\n") | |
ccd9eec8 TS |
396 | else: |
397 | print("Bad register parse: ", regtype, regid) | |
398 | elif (regtype == "Q"): | |
399 | if (regid in {"s", "t", "u", "v"}): | |
400 | if (not hex_common.skip_qemu_helper(tag)): | |
401 | f.write(" tcg_gen_addi_ptr(%s%sV, cpu_env, %s%sV_off);\n" % \ | |
402 | (regtype, regid, regtype, regid)) | |
403 | elif (regid in {"x"}): | |
404 | f.write(" tcg_gen_gvec_mov(MO_64, %s%sV_off,\n" % \ | |
405 | (regtype, regid)) | |
406 | f.write(" offsetof(CPUHexagonState, QRegs[%s%sN]),\n" % \ | |
407 | (regtype, regid)) | |
408 | f.write(" sizeof(MMQReg), sizeof(MMQReg));\n") | |
409 | else: | |
410 | print("Bad register parse: ", regtype, regid) | |
793958c9 TS |
411 | else: |
412 | print("Bad register parse: ", regtype, regid) | |
413 | ||
414 | def genptr_src_read_new(f,regtype,regid): | |
415 | if (regtype == "N"): | |
416 | if (regid not in {"s", "t"}): | |
417 | print("Bad register parse: ", regtype, regid) | |
418 | elif (regtype == "P"): | |
419 | if (regid not in {"t", "u", "v"}): | |
420 | print("Bad register parse: ", regtype, regid) | |
ccd9eec8 TS |
421 | elif (regtype == "O"): |
422 | if (regid != "s"): | |
423 | print("Bad register parse: ", regtype, regid) | |
793958c9 TS |
424 | else: |
425 | print("Bad register parse: ", regtype, regid) | |
426 | ||
427 | def genptr_src_read_opn(f,regtype,regid,tag): | |
428 | if (hex_common.is_pair(regid)): | |
ccd9eec8 | 429 | genptr_src_read(f, tag, regtype, regid) |
793958c9 TS |
430 | elif (hex_common.is_single(regid)): |
431 | if hex_common.is_old_val(regtype, regid, tag): | |
ccd9eec8 | 432 | genptr_src_read(f, tag, regtype, regid) |
793958c9 TS |
433 | elif hex_common.is_new_val(regtype, regid, tag): |
434 | genptr_src_read_new(f,regtype,regid) | |
435 | else: | |
436 | print("Bad register parse: ",regtype,regid,toss,numregs) | |
437 | else: | |
438 | print("Bad register parse: ",regtype,regid,toss,numregs) | |
439 | ||
440 | def gen_helper_call_opn(f, tag, regtype, regid, toss, numregs, i): | |
441 | if (i > 0): f.write(", ") | |
442 | if (hex_common.is_pair(regid)): | |
443 | f.write("%s%sV" % (regtype,regid)) | |
444 | elif (hex_common.is_single(regid)): | |
445 | if hex_common.is_old_val(regtype, regid, tag): | |
446 | f.write("%s%sV" % (regtype,regid)) | |
447 | elif hex_common.is_new_val(regtype, regid, tag): | |
448 | f.write("%s%sN" % (regtype,regid)) | |
449 | else: | |
450 | print("Bad register parse: ",regtype,regid,toss,numregs) | |
451 | else: | |
452 | print("Bad register parse: ",regtype,regid,toss,numregs) | |
453 | ||
454 | def gen_helper_decl_imm(f,immlett): | |
f448397a | 455 | f.write(" TCGv tcgv_%s = tcg_constant_tl(%s);\n" % \ |
793958c9 TS |
456 | (hex_common.imm_name(immlett), hex_common.imm_name(immlett))) |
457 | ||
458 | def gen_helper_call_imm(f,immlett): | |
459 | f.write(", tcgv_%s" % hex_common.imm_name(immlett)) | |
460 | ||
793958c9 TS |
461 | def genptr_dst_write_pair(f, tag, regtype, regid): |
462 | if ('A_CONDEXEC' in hex_common.attribdict[tag]): | |
463 | f.write(" gen_log_predicated_reg_write_pair(%s%sN, %s%sV, insn->slot);\n" % \ | |
464 | (regtype, regid, regtype, regid)) | |
465 | else: | |
466 | f.write(" gen_log_reg_write_pair(%s%sN, %s%sV);\n" % \ | |
467 | (regtype, regid, regtype, regid)) | |
468 | f.write(" ctx_log_reg_write_pair(ctx, %s%sN);\n" % \ | |
469 | (regtype, regid)) | |
470 | ||
471 | def genptr_dst_write(f, tag, regtype, regid): | |
472 | if (regtype == "R"): | |
473 | if (regid in {"dd", "xx", "yy"}): | |
474 | genptr_dst_write_pair(f, tag, regtype, regid) | |
475 | elif (regid in {"d", "e", "x", "y"}): | |
476 | if ('A_CONDEXEC' in hex_common.attribdict[tag]): | |
477 | f.write(" gen_log_predicated_reg_write(%s%sN, %s%sV,\n" % \ | |
478 | (regtype, regid, regtype, regid)) | |
479 | f.write(" insn->slot);\n") | |
480 | else: | |
481 | f.write(" gen_log_reg_write(%s%sN, %s%sV);\n" % \ | |
482 | (regtype, regid, regtype, regid)) | |
483 | f.write(" ctx_log_reg_write(ctx, %s%sN);\n" % \ | |
484 | (regtype, regid)) | |
485 | else: | |
486 | print("Bad register parse: ", regtype, regid) | |
487 | elif (regtype == "P"): | |
488 | if (regid in {"d", "e", "x"}): | |
6c677c60 | 489 | f.write(" gen_log_pred_write(ctx, %s%sN, %s%sV);\n" % \ |
793958c9 TS |
490 | (regtype, regid, regtype, regid)) |
491 | f.write(" ctx_log_pred_write(ctx, %s%sN);\n" % \ | |
492 | (regtype, regid)) | |
493 | else: | |
494 | print("Bad register parse: ", regtype, regid) | |
495 | elif (regtype == "C"): | |
496 | if (regid == "dd"): | |
497 | f.write(" gen_write_ctrl_reg_pair(ctx, %s%sN, %s%sV);\n" % \ | |
498 | (regtype, regid, regtype, regid)) | |
499 | elif (regid == "d"): | |
500 | f.write(" gen_write_ctrl_reg(ctx, %s%sN, %s%sV);\n" % \ | |
501 | (regtype, regid, regtype, regid)) | |
502 | else: | |
503 | print("Bad register parse: ", regtype, regid) | |
504 | else: | |
505 | print("Bad register parse: ", regtype, regid) | |
506 | ||
ccd9eec8 TS |
507 | def genptr_dst_write_ext(f, tag, regtype, regid, newv="EXT_DFL"): |
508 | if (regtype == "V"): | |
509 | if (regid in {"dd", "xx", "yy"}): | |
510 | if ('A_CONDEXEC' in hex_common.attribdict[tag]): | |
511 | is_predicated = "true" | |
512 | else: | |
513 | is_predicated = "false" | |
514 | f.write(" gen_log_vreg_write_pair(ctx, %s%sV_off, %s%sN, " % \ | |
515 | (regtype, regid, regtype, regid)) | |
516 | f.write("%s, insn->slot, %s);\n" % \ | |
517 | (newv, is_predicated)) | |
518 | f.write(" ctx_log_vreg_write_pair(ctx, %s%sN, %s,\n" % \ | |
519 | (regtype, regid, newv)) | |
520 | f.write(" %s);\n" % (is_predicated)) | |
521 | elif (regid in {"d", "x", "y"}): | |
522 | if ('A_CONDEXEC' in hex_common.attribdict[tag]): | |
523 | is_predicated = "true" | |
524 | else: | |
525 | is_predicated = "false" | |
526 | f.write(" gen_log_vreg_write(ctx, %s%sV_off, %s%sN, %s, " % \ | |
527 | (regtype, regid, regtype, regid, newv)) | |
528 | f.write("insn->slot, %s);\n" % \ | |
529 | (is_predicated)) | |
530 | f.write(" ctx_log_vreg_write(ctx, %s%sN, %s, %s);\n" % \ | |
531 | (regtype, regid, newv, is_predicated)) | |
532 | else: | |
533 | print("Bad register parse: ", regtype, regid) | |
534 | elif (regtype == "Q"): | |
535 | if (regid in {"d", "e", "x"}): | |
536 | if ('A_CONDEXEC' in hex_common.attribdict[tag]): | |
537 | is_predicated = "true" | |
538 | else: | |
539 | is_predicated = "false" | |
540 | f.write(" gen_log_qreg_write(%s%sV_off, %s%sN, %s, " % \ | |
541 | (regtype, regid, regtype, regid, newv)) | |
542 | f.write("insn->slot, %s);\n" % (is_predicated)) | |
543 | f.write(" ctx_log_qreg_write(ctx, %s%sN, %s);\n" % \ | |
544 | (regtype, regid, is_predicated)) | |
545 | else: | |
546 | print("Bad register parse: ", regtype, regid) | |
547 | else: | |
548 | print("Bad register parse: ", regtype, regid) | |
549 | ||
793958c9 TS |
550 | def genptr_dst_write_opn(f,regtype, regid, tag): |
551 | if (hex_common.is_pair(regid)): | |
ccd9eec8 TS |
552 | if (hex_common.is_hvx_reg(regtype)): |
553 | if (hex_common.is_tmp_result(tag)): | |
554 | genptr_dst_write_ext(f, tag, regtype, regid, "EXT_TMP") | |
555 | else: | |
556 | genptr_dst_write_ext(f, tag, regtype, regid) | |
557 | else: | |
558 | genptr_dst_write(f, tag, regtype, regid) | |
793958c9 | 559 | elif (hex_common.is_single(regid)): |
ccd9eec8 TS |
560 | if (hex_common.is_hvx_reg(regtype)): |
561 | if (hex_common.is_new_result(tag)): | |
562 | genptr_dst_write_ext(f, tag, regtype, regid, "EXT_NEW") | |
772b3eb4 | 563 | elif (hex_common.is_tmp_result(tag)): |
ccd9eec8 TS |
564 | genptr_dst_write_ext(f, tag, regtype, regid, "EXT_TMP") |
565 | else: | |
566 | genptr_dst_write_ext(f, tag, regtype, regid, "EXT_DFL") | |
567 | else: | |
568 | genptr_dst_write(f, tag, regtype, regid) | |
793958c9 TS |
569 | else: |
570 | print("Bad register parse: ",regtype,regid,toss,numregs) | |
571 | ||
572 | ## | |
573 | ## Generate the TCG code to call the helper | |
574 | ## For A2_add: Rd32=add(Rs32,Rt32), { RdV=RsV+RtV;} | |
575 | ## We produce: | |
1e536334 | 576 | ## static void generate_A2_add(DisasContext *ctx) |
793958c9 TS |
577 | ## { |
578 | ## TCGv RdV = tcg_temp_local_new(); | |
579 | ## const int RdN = insn->regno[0]; | |
580 | ## TCGv RsV = hex_gpr[insn->regno[1]]; | |
581 | ## TCGv RtV = hex_gpr[insn->regno[2]]; | |
582 | ## <GEN> | |
583 | ## gen_log_reg_write(RdN, RdV); | |
584 | ## ctx_log_reg_write(ctx, RdN); | |
585 | ## tcg_temp_free(RdV); | |
586 | ## } | |
587 | ## | |
588 | ## where <GEN> depends on hex_common.skip_qemu_helper(tag) | |
589 | ## if hex_common.skip_qemu_helper(tag) is True | |
590 | ## <GEN> is fGEN_TCG_A2_add({ RdV=RsV+RtV;}); | |
591 | ## if hex_common.skip_qemu_helper(tag) is False | |
592 | ## <GEN> is gen_helper_A2_add(RdV, cpu_env, RsV, RtV); | |
593 | ## | |
594 | def gen_tcg_func(f, tag, regs, imms): | |
1e536334 | 595 | f.write("static void generate_%s(DisasContext *ctx)\n" %tag) |
793958c9 | 596 | f.write('{\n') |
1e536334 TS |
597 | |
598 | f.write(" Insn *insn __attribute__((unused)) = ctx->insn;\n") | |
599 | ||
793958c9 TS |
600 | if hex_common.need_ea(tag): gen_decl_ea_tcg(f, tag) |
601 | i=0 | |
602 | ## Declare all the operands (regs and immediates) | |
603 | for regtype,regid,toss,numregs in regs: | |
604 | genptr_decl_opn(f, tag, regtype, regid, toss, numregs, i) | |
605 | i += 1 | |
606 | for immlett,bits,immshift in imms: | |
607 | genptr_decl_imm(f,immlett) | |
608 | ||
609 | if 'A_PRIV' in hex_common.attribdict[tag]: | |
610 | f.write(' fCHECKFORPRIV();\n') | |
611 | if 'A_GUEST' in hex_common.attribdict[tag]: | |
612 | f.write(' fCHECKFORGUEST();\n') | |
613 | ||
614 | ## Read all the inputs | |
615 | for regtype,regid,toss,numregs in regs: | |
616 | if (hex_common.is_read(regid)): | |
617 | genptr_src_read_opn(f,regtype,regid,tag) | |
618 | ||
619 | if ( hex_common.skip_qemu_helper(tag) ): | |
620 | f.write(" fGEN_TCG_%s(%s);\n" % (tag, hex_common.semdict[tag])) | |
621 | else: | |
622 | ## Generate the call to the helper | |
623 | for immlett,bits,immshift in imms: | |
624 | gen_helper_decl_imm(f,immlett) | |
fb67c2bf TS |
625 | if hex_common.need_pkt_has_multi_cof(tag): |
626 | f.write(" TCGv pkt_has_multi_cof = ") | |
627 | f.write("tcg_constant_tl(ctx->pkt->pkt_has_multi_cof);\n") | |
793958c9 | 628 | if hex_common.need_part1(tag): |
f448397a | 629 | f.write(" TCGv part1 = tcg_constant_tl(insn->part1);\n") |
793958c9 | 630 | if hex_common.need_slot(tag): |
23803bbe | 631 | f.write(" TCGv slot = tcg_constant_tl(insn->slot);\n") |
40085901 TS |
632 | if hex_common.need_PC(tag): |
633 | f.write(" TCGv PC = tcg_constant_tl(ctx->pkt->pc);\n") | |
793958c9 TS |
634 | f.write(" gen_helper_%s(" % (tag)) |
635 | i=0 | |
636 | ## If there is a scalar result, it is the return type | |
637 | for regtype,regid,toss,numregs in regs: | |
638 | if (hex_common.is_written(regid)): | |
ccd9eec8 TS |
639 | if (hex_common.is_hvx_reg(regtype)): |
640 | continue | |
793958c9 TS |
641 | gen_helper_call_opn(f, tag, regtype, regid, toss, numregs, i) |
642 | i += 1 | |
643 | if (i > 0): f.write(", ") | |
644 | f.write("cpu_env") | |
645 | i=1 | |
ccd9eec8 TS |
646 | for regtype,regid,toss,numregs in regs: |
647 | if (hex_common.is_written(regid)): | |
648 | if (not hex_common.is_hvx_reg(regtype)): | |
649 | continue | |
650 | gen_helper_call_opn(f, tag, regtype, regid, toss, numregs, i) | |
651 | i += 1 | |
793958c9 TS |
652 | for regtype,regid,toss,numregs in regs: |
653 | if (hex_common.is_read(regid)): | |
ccd9eec8 TS |
654 | if (hex_common.is_hvx_reg(regtype) and |
655 | hex_common.is_readwrite(regid)): | |
656 | continue | |
793958c9 TS |
657 | gen_helper_call_opn(f, tag, regtype, regid, toss, numregs, i) |
658 | i += 1 | |
659 | for immlett,bits,immshift in imms: | |
660 | gen_helper_call_imm(f,immlett) | |
661 | ||
fb67c2bf TS |
662 | if hex_common.need_pkt_has_multi_cof(tag): |
663 | f.write(", pkt_has_multi_cof") | |
40085901 | 664 | if hex_common.need_PC(tag): f.write(", PC") |
793958c9 TS |
665 | if hex_common.need_slot(tag): f.write(", slot") |
666 | if hex_common.need_part1(tag): f.write(", part1" ) | |
667 | f.write(");\n") | |
793958c9 TS |
668 | |
669 | ## Write all the outputs | |
670 | for regtype,regid,toss,numregs in regs: | |
671 | if (hex_common.is_written(regid)): | |
672 | genptr_dst_write_opn(f,regtype, regid, tag) | |
673 | ||
674 | ## Free all the operands (regs and immediates) | |
675 | if hex_common.need_ea(tag): gen_free_ea_tcg(f) | |
676 | for regtype,regid,toss,numregs in regs: | |
677 | genptr_free_opn(f,regtype,regid,i,tag) | |
678 | i += 1 | |
679 | ||
680 | f.write("}\n\n") | |
681 | ||
682 | def gen_def_tcg_func(f, tag, tagregs, tagimms): | |
683 | regs = tagregs[tag] | |
684 | imms = tagimms[tag] | |
685 | ||
686 | gen_tcg_func(f, tag, regs, imms) | |
687 | ||
688 | def main(): | |
689 | hex_common.read_semantics_file(sys.argv[1]) | |
690 | hex_common.read_attribs_file(sys.argv[2]) | |
691 | hex_common.read_overrides_file(sys.argv[3]) | |
d51bcabe | 692 | hex_common.read_overrides_file(sys.argv[4]) |
793958c9 TS |
693 | hex_common.calculate_attribs() |
694 | tagregs = hex_common.get_tagregs() | |
695 | tagimms = hex_common.get_tagimms() | |
696 | ||
d51bcabe | 697 | with open(sys.argv[5], 'w') as f: |
793958c9 TS |
698 | f.write("#ifndef HEXAGON_TCG_FUNCS_H\n") |
699 | f.write("#define HEXAGON_TCG_FUNCS_H\n\n") | |
700 | ||
701 | for tag in hex_common.tags: | |
702 | ## Skip the priv instructions | |
703 | if ( "A_PRIV" in hex_common.attribdict[tag] ) : | |
704 | continue | |
705 | ## Skip the guest instructions | |
706 | if ( "A_GUEST" in hex_common.attribdict[tag] ) : | |
707 | continue | |
708 | ## Skip the diag instructions | |
709 | if ( tag == "Y6_diag" ) : | |
710 | continue | |
711 | if ( tag == "Y6_diag0" ) : | |
712 | continue | |
713 | if ( tag == "Y6_diag1" ) : | |
714 | continue | |
715 | ||
716 | gen_def_tcg_func(f, tag, tagregs, tagimms) | |
717 | ||
718 | f.write("#endif /* HEXAGON_TCG_FUNCS_H */\n") | |
719 | ||
720 | if __name__ == "__main__": | |
721 | main() |