]> Git Repo - qemu.git/blob - target/hexagon/gen_tcg_funcs.py
Merge tag 'pull-loongarch-20230106' of https://gitlab.com/gaosong/qemu into staging
[qemu.git] / target / hexagon / gen_tcg_funcs.py
1 #!/usr/bin/env python3
2
3 ##
4 ##  Copyright(c) 2019-2022 Qualcomm Innovation Center, Inc. All Rights Reserved.
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
38 def genptr_decl_pair_writable(f, tag, regtype, regid, regno):
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
57 def genptr_decl_writable(f, tag, regtype, regid, regno):
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"}):
81             genptr_decl_pair_writable(f, tag, regtype, regid, regno)
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"}):
86             genptr_decl_writable(f, tag, regtype, regid, regno)
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"}):
94             genptr_decl_writable(f, tag, regtype, regid, regno)
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"):
104             genptr_decl_pair_writable(f, tag, regtype, regid, regno)
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"):
111             genptr_decl_writable(f, tag, regtype, regid, regno)
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)
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))
167             if (regid == "y"):
168                 f.write("        offsetof(CPUHexagonState, vtmp);\n")
169             elif (hex_common.is_tmp_result(tag)):
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");
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
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)
221     else:
222         print("Bad register parse: ", regtype, regid)
223
224 def genptr_decl_new(f, tag, regtype, regid, regno):
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)
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)
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):
262             genptr_decl_new(f, tag, regtype, regid, i)
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
276 def genptr_free(f, tag, regtype, regid, regno):
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)
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)
314     else:
315         print("Bad register parse: ", regtype, regid)
316
317 def genptr_free_new(f, tag, regtype, regid, regno):
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)
324     elif (regtype == "O"):
325         if (regid != "s"):
326             print("Bad register parse: ", regtype, regid)
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)):
332         genptr_free(f, tag, regtype, regid, i)
333     elif (hex_common.is_single(regid)):
334         if hex_common.is_old_val(regtype, regid, tag):
335             genptr_free(f, tag, regtype, regid, i)
336         elif hex_common.is_new_val(regtype, regid, tag):
337             genptr_free_new(f, tag, regtype, regid, i)
338         else:
339             print("Bad register parse: ",regtype,regid,toss,numregs)
340     else:
341         print("Bad register parse: ",regtype,regid,toss,numregs)
342
343 def genptr_src_read(f, tag, regtype, regid):
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)
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")
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)
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)
421     elif (regtype == "O"):
422         if (regid != "s"):
423             print("Bad register parse: ", regtype, regid)
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)):
429         genptr_src_read(f, tag, regtype, regid)
430     elif (hex_common.is_single(regid)):
431         if hex_common.is_old_val(regtype, regid, tag):
432             genptr_src_read(f, tag, regtype, regid)
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):
455     f.write("    TCGv tcgv_%s = tcg_constant_tl(%s);\n" % \
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
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"}):
489             f.write("    gen_log_pred_write(ctx, %s%sN, %s%sV);\n" % \
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
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
550 def genptr_dst_write_opn(f,regtype, regid, tag):
551     if (hex_common.is_pair(regid)):
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)
559     elif (hex_common.is_single(regid)):
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")
563             elif (hex_common.is_tmp_result(tag)):
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)
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:
576 ##    static void generate_A2_add(DisasContext *ctx)
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):
595     f.write("static void generate_%s(DisasContext *ctx)\n" %tag)
596     f.write('{\n')
597
598     f.write("    Insn *insn __attribute__((unused)) = ctx->insn;\n")
599
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.is_idef_parser_enabled(tag):
620         declared = []
621         ## Handle registers
622         for regtype,regid,toss,numregs in regs:
623             if (hex_common.is_pair(regid)
624                 or (hex_common.is_single(regid)
625                     and hex_common.is_old_val(regtype, regid, tag))):
626                 declared.append("%s%sV" % (regtype, regid))
627                 if regtype == "M":
628                     declared.append("%s%sN" % (regtype, regid))
629             elif hex_common.is_new_val(regtype, regid, tag):
630                 declared.append("%s%sN" % (regtype,regid))
631             else:
632                 print("Bad register parse: ",regtype,regid,toss,numregs)
633
634         ## Handle immediates
635         for immlett,bits,immshift in imms:
636             declared.append(hex_common.imm_name(immlett))
637
638         arguments = ", ".join(["ctx", "ctx->insn", "ctx->pkt"] + declared)
639         f.write("    emit_%s(%s);\n" % (tag, arguments))
640
641     elif ( hex_common.skip_qemu_helper(tag) ):
642         f.write("    fGEN_TCG_%s(%s);\n" % (tag, hex_common.semdict[tag]))
643     else:
644         ## Generate the call to the helper
645         for immlett,bits,immshift in imms:
646             gen_helper_decl_imm(f,immlett)
647         if hex_common.need_pkt_has_multi_cof(tag):
648             f.write("    TCGv pkt_has_multi_cof = ")
649             f.write("tcg_constant_tl(ctx->pkt->pkt_has_multi_cof);\n")
650         if hex_common.need_part1(tag):
651             f.write("    TCGv part1 = tcg_constant_tl(insn->part1);\n")
652         if hex_common.need_slot(tag):
653             f.write("    TCGv slot = tcg_constant_tl(insn->slot);\n")
654         if hex_common.need_PC(tag):
655             f.write("    TCGv PC = tcg_constant_tl(ctx->pkt->pc);\n")
656         if hex_common.helper_needs_next_PC(tag):
657             f.write("    TCGv next_PC = tcg_constant_tl(ctx->next_PC);\n")
658         f.write("    gen_helper_%s(" % (tag))
659         i=0
660         ## If there is a scalar result, it is the return type
661         for regtype,regid,toss,numregs in regs:
662             if (hex_common.is_written(regid)):
663                 if (hex_common.is_hvx_reg(regtype)):
664                     continue
665                 gen_helper_call_opn(f, tag, regtype, regid, toss, numregs, i)
666                 i += 1
667         if (i > 0): f.write(", ")
668         f.write("cpu_env")
669         i=1
670         for regtype,regid,toss,numregs in regs:
671             if (hex_common.is_written(regid)):
672                 if (not hex_common.is_hvx_reg(regtype)):
673                     continue
674                 gen_helper_call_opn(f, tag, regtype, regid, toss, numregs, i)
675                 i += 1
676         for regtype,regid,toss,numregs in regs:
677             if (hex_common.is_read(regid)):
678                 if (hex_common.is_hvx_reg(regtype) and
679                     hex_common.is_readwrite(regid)):
680                     continue
681                 gen_helper_call_opn(f, tag, regtype, regid, toss, numregs, i)
682                 i += 1
683         for immlett,bits,immshift in imms:
684             gen_helper_call_imm(f,immlett)
685
686         if hex_common.need_pkt_has_multi_cof(tag):
687             f.write(", pkt_has_multi_cof")
688         if hex_common.need_PC(tag): f.write(", PC")
689         if hex_common.helper_needs_next_PC(tag): f.write(", next_PC")
690         if hex_common.need_slot(tag): f.write(", slot")
691         if hex_common.need_part1(tag): f.write(", part1" )
692         f.write(");\n")
693
694     ## Write all the outputs
695     for regtype,regid,toss,numregs in regs:
696         if (hex_common.is_written(regid)):
697             genptr_dst_write_opn(f,regtype, regid, tag)
698
699     ## Free all the operands (regs and immediates)
700     if hex_common.need_ea(tag): gen_free_ea_tcg(f)
701     for regtype,regid,toss,numregs in regs:
702         genptr_free_opn(f,regtype,regid,i,tag)
703         i += 1
704
705     f.write("}\n\n")
706
707 def gen_def_tcg_func(f, tag, tagregs, tagimms):
708     regs = tagregs[tag]
709     imms = tagimms[tag]
710
711     gen_tcg_func(f, tag, regs, imms)
712
713 def main():
714     hex_common.read_semantics_file(sys.argv[1])
715     hex_common.read_attribs_file(sys.argv[2])
716     hex_common.read_overrides_file(sys.argv[3])
717     hex_common.read_overrides_file(sys.argv[4])
718     hex_common.calculate_attribs()
719     ## Whether or not idef-parser is enabled is
720     ## determined by the number of arguments to
721     ## this script:
722     ##
723     ##   5 args. -> not enabled,
724     ##   6 args. -> idef-parser enabled.
725     ##
726     ## The 6:th arg. then holds a list of the successfully
727     ## parsed instructions.
728     is_idef_parser_enabled = len(sys.argv) > 6
729     if is_idef_parser_enabled:
730         hex_common.read_idef_parser_enabled_file(sys.argv[5])
731     tagregs = hex_common.get_tagregs()
732     tagimms = hex_common.get_tagimms()
733
734     output_file = sys.argv[-1]
735     with open(output_file, 'w') as f:
736         f.write("#ifndef HEXAGON_TCG_FUNCS_H\n")
737         f.write("#define HEXAGON_TCG_FUNCS_H\n\n")
738         if is_idef_parser_enabled:
739             f.write("#include \"idef-generated-emitter.h.inc\"\n\n")
740
741         for tag in hex_common.tags:
742             ## Skip the priv instructions
743             if ( "A_PRIV" in hex_common.attribdict[tag] ) :
744                 continue
745             ## Skip the guest instructions
746             if ( "A_GUEST" in hex_common.attribdict[tag] ) :
747                 continue
748             ## Skip the diag instructions
749             if ( tag == "Y6_diag" ) :
750                 continue
751             if ( tag == "Y6_diag0" ) :
752                 continue
753             if ( tag == "Y6_diag1" ) :
754                 continue
755
756             gen_def_tcg_func(f, tag, tagregs, tagimms)
757
758         f.write("#endif    /* HEXAGON_TCG_FUNCS_H */\n")
759
760 if __name__ == "__main__":
761     main()
This page took 0.072159 seconds and 4 git commands to generate.