xref: /openbmc/qemu/target/hexagon/gen_tcg_funcs.py (revision 5e78c98b7cc98619d2740c7c5030aa56fb22e79f)
1 #!/usr/bin/env python3
2 
3 ##
4 ##  Copyright(c) 2019-2021 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 (hex_common.is_tmp_result(tag)):
168                 f.write("        ctx_tmp_vreg_off(ctx, %s%sN, 1, true);\n" % \
169                     (regtype, regid))
170             else:
171                 f.write("        ctx_future_vreg_off(ctx, %s%sN," % \
172                     (regtype, regid))
173                 f.write(" 1, true);\n");
174             if (not hex_common.skip_qemu_helper(tag)):
175                 f.write("    TCGv_ptr %s%sV = tcg_temp_new_ptr();\n" % \
176                     (regtype, regid))
177                 f.write("    tcg_gen_addi_ptr(%s%sV, cpu_env, %s%sV_off);\n" % \
178                     (regtype, regid, regtype, regid))
179         else:
180             print("Bad register parse: ", regtype, regid)
181     elif (regtype == "Q"):
182         if (regid in {"d", "e", "x"}):
183             f.write("    const int %s%sN = insn->regno[%d];\n" % \
184                 (regtype, regid, regno))
185             f.write("    const intptr_t %s%sV_off =\n" % \
186                 (regtype, regid))
187             f.write("        offsetof(CPUHexagonState,\n")
188             f.write("                 future_QRegs[%s%sN]);\n" % \
189                 (regtype, regid))
190             if (not hex_common.skip_qemu_helper(tag)):
191                 f.write("    TCGv_ptr %s%sV = tcg_temp_new_ptr();\n" % \
192                     (regtype, regid))
193                 f.write("    tcg_gen_addi_ptr(%s%sV, cpu_env, %s%sV_off);\n" % \
194                     (regtype, regid, regtype, regid))
195         elif (regid in {"s", "t", "u", "v"}):
196             f.write("    const int %s%sN = insn->regno[%d];\n" % \
197                 (regtype, regid, regno))
198             f.write("    const intptr_t %s%sV_off =\n" %\
199                 (regtype, regid))
200             f.write("        offsetof(CPUHexagonState, QRegs[%s%sN]);\n" % \
201                 (regtype, regid))
202             if (not hex_common.skip_qemu_helper(tag)):
203                 f.write("    TCGv_ptr %s%sV = tcg_temp_new_ptr();\n" % \
204                     (regtype, regid))
205         else:
206             print("Bad register parse: ", regtype, regid)
207     else:
208         print("Bad register parse: ", regtype, regid)
209 
210 def genptr_decl_new(f, tag, regtype, regid, regno):
211     if (regtype == "N"):
212         if (regid in {"s", "t"}):
213             f.write("    TCGv %s%sN = hex_new_value[insn->regno[%d]];\n" % \
214                 (regtype, regid, regno))
215         else:
216             print("Bad register parse: ", regtype, regid)
217     elif (regtype == "P"):
218         if (regid in {"t", "u", "v"}):
219             f.write("    TCGv %s%sN = hex_new_pred_value[insn->regno[%d]];\n" % \
220                 (regtype, regid, regno))
221         else:
222             print("Bad register parse: ", regtype, regid)
223     elif (regtype == "O"):
224         if (regid == "s"):
225             f.write("    const intptr_t %s%sN_num = insn->regno[%d];\n" % \
226                 (regtype, regid, regno))
227             if (hex_common.skip_qemu_helper(tag)):
228                 f.write("    const intptr_t %s%sN_off =\n" % \
229                     (regtype, regid))
230                 f.write("         ctx_future_vreg_off(ctx, %s%sN_num," % \
231                     (regtype, regid))
232                 f.write(" 1, true);\n")
233             else:
234                 f.write("    TCGv %s%sN = tcg_constant_tl(%s%sN_num);\n" % \
235                     (regtype, regid, regtype, regid))
236         else:
237             print("Bad register parse: ", regtype, regid)
238     else:
239         print("Bad register parse: ", regtype, regid)
240 
241 def genptr_decl_opn(f, tag, regtype, regid, toss, numregs, i):
242     if (hex_common.is_pair(regid)):
243         genptr_decl(f, tag, regtype, regid, i)
244     elif (hex_common.is_single(regid)):
245         if hex_common.is_old_val(regtype, regid, tag):
246             genptr_decl(f,tag, regtype, regid, i)
247         elif hex_common.is_new_val(regtype, regid, tag):
248             genptr_decl_new(f, tag, regtype, regid, i)
249         else:
250             print("Bad register parse: ",regtype,regid,toss,numregs)
251     else:
252         print("Bad register parse: ",regtype,regid,toss,numregs)
253 
254 def genptr_decl_imm(f,immlett):
255     if (immlett.isupper()):
256         i = 1
257     else:
258         i = 0
259     f.write("    int %s = insn->immed[%d];\n" % \
260         (hex_common.imm_name(immlett), i))
261 
262 def genptr_free(f, tag, regtype, regid, regno):
263     if (regtype == "R"):
264         if (regid in {"dd", "ss", "tt", "xx", "yy"}):
265             f.write("    tcg_temp_free_i64(%s%sV);\n" % (regtype, regid))
266         elif (regid in {"d", "e", "x", "y"}):
267             f.write("    tcg_temp_free(%s%sV);\n" % (regtype, regid))
268         elif (regid not in {"s", "t", "u", "v"}):
269             print("Bad register parse: ",regtype,regid)
270     elif (regtype == "P"):
271         if (regid in {"d", "e", "x"}):
272             f.write("    tcg_temp_free(%s%sV);\n" % (regtype, regid))
273         elif (regid not in {"s", "t", "u", "v"}):
274             print("Bad register parse: ",regtype,regid)
275     elif (regtype == "C"):
276         if (regid in {"dd", "ss"}):
277             f.write("    tcg_temp_free_i64(%s%sV);\n" % (regtype, regid))
278         elif (regid in {"d", "s"}):
279             f.write("    tcg_temp_free(%s%sV);\n" % (regtype, regid))
280         else:
281             print("Bad register parse: ",regtype,regid)
282     elif (regtype == "M"):
283         if (regid != "u"):
284             print("Bad register parse: ", regtype, regid)
285     elif (regtype == "V"):
286         if (regid in {"dd", "uu", "vv", "xx", \
287                       "d", "s", "u", "v", "w", "x", "y"}):
288             if (not hex_common.skip_qemu_helper(tag)):
289                 f.write("    tcg_temp_free_ptr(%s%sV);\n" % \
290                     (regtype, regid))
291         else:
292             print("Bad register parse: ", regtype, regid)
293     elif (regtype == "Q"):
294         if (regid in {"d", "e", "s", "t", "u", "v", "x"}):
295             if (not hex_common.skip_qemu_helper(tag)):
296                 f.write("    tcg_temp_free_ptr(%s%sV);\n" % \
297                     (regtype, regid))
298         else:
299             print("Bad register parse: ", regtype, regid)
300     else:
301         print("Bad register parse: ", regtype, regid)
302 
303 def genptr_free_new(f, tag, regtype, regid, regno):
304     if (regtype == "N"):
305         if (regid not in {"s", "t"}):
306             print("Bad register parse: ", regtype, regid)
307     elif (regtype == "P"):
308         if (regid not in {"t", "u", "v"}):
309             print("Bad register parse: ", regtype, regid)
310     elif (regtype == "O"):
311         if (regid != "s"):
312             print("Bad register parse: ", regtype, regid)
313     else:
314         print("Bad register parse: ", regtype, regid)
315 
316 def genptr_free_opn(f,regtype,regid,i,tag):
317     if (hex_common.is_pair(regid)):
318         genptr_free(f, tag, regtype, regid, i)
319     elif (hex_common.is_single(regid)):
320         if hex_common.is_old_val(regtype, regid, tag):
321             genptr_free(f, tag, regtype, regid, i)
322         elif hex_common.is_new_val(regtype, regid, tag):
323             genptr_free_new(f, tag, regtype, regid, i)
324         else:
325             print("Bad register parse: ",regtype,regid,toss,numregs)
326     else:
327         print("Bad register parse: ",regtype,regid,toss,numregs)
328 
329 def genptr_src_read(f, tag, regtype, regid):
330     if (regtype == "R"):
331         if (regid in {"ss", "tt", "xx", "yy"}):
332             f.write("    tcg_gen_concat_i32_i64(%s%sV, hex_gpr[%s%sN],\n" % \
333                 (regtype, regid, regtype, regid))
334             f.write("                                 hex_gpr[%s%sN + 1]);\n" % \
335                 (regtype, regid))
336         elif (regid in {"x", "y"}):
337             f.write("    tcg_gen_mov_tl(%s%sV, hex_gpr[%s%sN]);\n" % \
338                 (regtype,regid,regtype,regid))
339         elif (regid not in {"s", "t", "u", "v"}):
340             print("Bad register parse: ", regtype, regid)
341     elif (regtype == "P"):
342         if (regid == "x"):
343             f.write("    tcg_gen_mov_tl(%s%sV, hex_pred[%s%sN]);\n" % \
344                 (regtype, regid, regtype, regid))
345         elif (regid not in {"s", "t", "u", "v"}):
346             print("Bad register parse: ", regtype, regid)
347     elif (regtype == "C"):
348         if (regid == "ss"):
349             f.write("    gen_read_ctrl_reg_pair(ctx, %s%sN, %s%sV);\n" % \
350                              (regtype, regid, regtype, regid))
351         elif (regid == "s"):
352             f.write("    gen_read_ctrl_reg(ctx, %s%sN, %s%sV);\n" % \
353                              (regtype, regid, regtype, regid))
354         else:
355             print("Bad register parse: ", regtype, regid)
356     elif (regtype == "M"):
357         if (regid != "u"):
358             print("Bad register parse: ", regtype, regid)
359     elif (regtype == "V"):
360         if (regid in {"uu", "vv", "xx"}):
361             f.write("    tcg_gen_gvec_mov(MO_64, %s%sV_off,\n" % \
362                 (regtype, regid))
363             f.write("        vreg_src_off(ctx, %s%sN),\n" % \
364                 (regtype, regid))
365             f.write("        sizeof(MMVector), sizeof(MMVector));\n")
366             f.write("    tcg_gen_gvec_mov(MO_64,\n")
367             f.write("        %s%sV_off + sizeof(MMVector),\n" % \
368                 (regtype, regid))
369             f.write("        vreg_src_off(ctx, %s%sN ^ 1),\n" % \
370                 (regtype, regid))
371             f.write("        sizeof(MMVector), sizeof(MMVector));\n")
372         elif (regid in {"s", "u", "v", "w"}):
373             if (not hex_common.skip_qemu_helper(tag)):
374                 f.write("    tcg_gen_addi_ptr(%s%sV, cpu_env, %s%sV_off);\n" % \
375                                  (regtype, regid, regtype, regid))
376         elif (regid in {"x", "y"}):
377             f.write("    tcg_gen_gvec_mov(MO_64, %s%sV_off,\n" % \
378                              (regtype, regid))
379             f.write("        vreg_src_off(ctx, %s%sN),\n" % \
380                              (regtype, regid))
381             f.write("        sizeof(MMVector), sizeof(MMVector));\n")
382             if (not hex_common.skip_qemu_helper(tag)):
383                 f.write("    tcg_gen_addi_ptr(%s%sV, cpu_env, %s%sV_off);\n" % \
384                                  (regtype, regid, regtype, regid))
385         else:
386             print("Bad register parse: ", regtype, regid)
387     elif (regtype == "Q"):
388         if (regid in {"s", "t", "u", "v"}):
389             if (not hex_common.skip_qemu_helper(tag)):
390                 f.write("    tcg_gen_addi_ptr(%s%sV, cpu_env, %s%sV_off);\n" % \
391                     (regtype, regid, regtype, regid))
392         elif (regid in {"x"}):
393             f.write("    tcg_gen_gvec_mov(MO_64, %s%sV_off,\n" % \
394                 (regtype, regid))
395             f.write("        offsetof(CPUHexagonState, QRegs[%s%sN]),\n" % \
396                 (regtype, regid))
397             f.write("        sizeof(MMQReg), sizeof(MMQReg));\n")
398         else:
399             print("Bad register parse: ", regtype, regid)
400     else:
401         print("Bad register parse: ", regtype, regid)
402 
403 def genptr_src_read_new(f,regtype,regid):
404     if (regtype == "N"):
405         if (regid not in {"s", "t"}):
406             print("Bad register parse: ", regtype, regid)
407     elif (regtype == "P"):
408         if (regid not in {"t", "u", "v"}):
409             print("Bad register parse: ", regtype, regid)
410     elif (regtype == "O"):
411         if (regid != "s"):
412             print("Bad register parse: ", regtype, regid)
413     else:
414         print("Bad register parse: ", regtype, regid)
415 
416 def genptr_src_read_opn(f,regtype,regid,tag):
417     if (hex_common.is_pair(regid)):
418         genptr_src_read(f, tag, regtype, regid)
419     elif (hex_common.is_single(regid)):
420         if hex_common.is_old_val(regtype, regid, tag):
421             genptr_src_read(f, tag, regtype, regid)
422         elif hex_common.is_new_val(regtype, regid, tag):
423             genptr_src_read_new(f,regtype,regid)
424         else:
425             print("Bad register parse: ",regtype,regid,toss,numregs)
426     else:
427         print("Bad register parse: ",regtype,regid,toss,numregs)
428 
429 def gen_helper_call_opn(f, tag, regtype, regid, toss, numregs, i):
430     if (i > 0): f.write(", ")
431     if (hex_common.is_pair(regid)):
432         f.write("%s%sV" % (regtype,regid))
433     elif (hex_common.is_single(regid)):
434         if hex_common.is_old_val(regtype, regid, tag):
435             f.write("%s%sV" % (regtype,regid))
436         elif hex_common.is_new_val(regtype, regid, tag):
437             f.write("%s%sN" % (regtype,regid))
438         else:
439             print("Bad register parse: ",regtype,regid,toss,numregs)
440     else:
441         print("Bad register parse: ",regtype,regid,toss,numregs)
442 
443 def gen_helper_decl_imm(f,immlett):
444     f.write("    TCGv tcgv_%s = tcg_constant_tl(%s);\n" % \
445         (hex_common.imm_name(immlett), hex_common.imm_name(immlett)))
446 
447 def gen_helper_call_imm(f,immlett):
448     f.write(", tcgv_%s" % hex_common.imm_name(immlett))
449 
450 def genptr_dst_write_pair(f, tag, regtype, regid):
451     if ('A_CONDEXEC' in hex_common.attribdict[tag]):
452         f.write("    gen_log_predicated_reg_write_pair(%s%sN, %s%sV, insn->slot);\n" % \
453             (regtype, regid, regtype, regid))
454     else:
455         f.write("    gen_log_reg_write_pair(%s%sN, %s%sV);\n" % \
456             (regtype, regid, regtype, regid))
457     f.write("    ctx_log_reg_write_pair(ctx, %s%sN);\n" % \
458         (regtype, regid))
459 
460 def genptr_dst_write(f, tag, regtype, regid):
461     if (regtype == "R"):
462         if (regid in {"dd", "xx", "yy"}):
463             genptr_dst_write_pair(f, tag, regtype, regid)
464         elif (regid in {"d", "e", "x", "y"}):
465             if ('A_CONDEXEC' in hex_common.attribdict[tag]):
466                 f.write("    gen_log_predicated_reg_write(%s%sN, %s%sV,\n" % \
467                     (regtype, regid, regtype, regid))
468                 f.write("                                 insn->slot);\n")
469             else:
470                 f.write("    gen_log_reg_write(%s%sN, %s%sV);\n" % \
471                     (regtype, regid, regtype, regid))
472             f.write("    ctx_log_reg_write(ctx, %s%sN);\n" % \
473                 (regtype, regid))
474         else:
475             print("Bad register parse: ", regtype, regid)
476     elif (regtype == "P"):
477         if (regid in {"d", "e", "x"}):
478             f.write("    gen_log_pred_write(ctx, %s%sN, %s%sV);\n" % \
479                 (regtype, regid, regtype, regid))
480             f.write("    ctx_log_pred_write(ctx, %s%sN);\n" % \
481                 (regtype, regid))
482         else:
483             print("Bad register parse: ", regtype, regid)
484     elif (regtype == "C"):
485         if (regid == "dd"):
486             f.write("    gen_write_ctrl_reg_pair(ctx, %s%sN, %s%sV);\n" % \
487                              (regtype, regid, regtype, regid))
488         elif (regid == "d"):
489             f.write("    gen_write_ctrl_reg(ctx, %s%sN, %s%sV);\n" % \
490                              (regtype, regid, regtype, regid))
491         else:
492             print("Bad register parse: ", regtype, regid)
493     else:
494         print("Bad register parse: ", regtype, regid)
495 
496 def genptr_dst_write_ext(f, tag, regtype, regid, newv="EXT_DFL"):
497     if (regtype == "V"):
498         if (regid in {"dd", "xx", "yy"}):
499             if ('A_CONDEXEC' in hex_common.attribdict[tag]):
500                 is_predicated = "true"
501             else:
502                 is_predicated = "false"
503             f.write("    gen_log_vreg_write_pair(ctx, %s%sV_off, %s%sN, " % \
504                 (regtype, regid, regtype, regid))
505             f.write("%s, insn->slot, %s);\n" % \
506                 (newv, is_predicated))
507             f.write("    ctx_log_vreg_write_pair(ctx, %s%sN, %s,\n" % \
508                 (regtype, regid, newv))
509             f.write("        %s);\n" % (is_predicated))
510         elif (regid in {"d", "x", "y"}):
511             if ('A_CONDEXEC' in hex_common.attribdict[tag]):
512                 is_predicated = "true"
513             else:
514                 is_predicated = "false"
515             f.write("    gen_log_vreg_write(ctx, %s%sV_off, %s%sN, %s, " % \
516                 (regtype, regid, regtype, regid, newv))
517             f.write("insn->slot, %s);\n" % \
518                 (is_predicated))
519             f.write("    ctx_log_vreg_write(ctx, %s%sN, %s, %s);\n" % \
520                 (regtype, regid, newv, is_predicated))
521         else:
522             print("Bad register parse: ", regtype, regid)
523     elif (regtype == "Q"):
524         if (regid in {"d", "e", "x"}):
525             if ('A_CONDEXEC' in hex_common.attribdict[tag]):
526                 is_predicated = "true"
527             else:
528                 is_predicated = "false"
529             f.write("    gen_log_qreg_write(%s%sV_off, %s%sN, %s, " % \
530                 (regtype, regid, regtype, regid, newv))
531             f.write("insn->slot, %s);\n" % (is_predicated))
532             f.write("    ctx_log_qreg_write(ctx, %s%sN, %s);\n" % \
533                 (regtype, regid, is_predicated))
534         else:
535             print("Bad register parse: ", regtype, regid)
536     else:
537         print("Bad register parse: ", regtype, regid)
538 
539 def genptr_dst_write_opn(f,regtype, regid, tag):
540     if (hex_common.is_pair(regid)):
541         if (hex_common.is_hvx_reg(regtype)):
542             if (hex_common.is_tmp_result(tag)):
543                 genptr_dst_write_ext(f, tag, regtype, regid, "EXT_TMP")
544             else:
545                 genptr_dst_write_ext(f, tag, regtype, regid)
546         else:
547             genptr_dst_write(f, tag, regtype, regid)
548     elif (hex_common.is_single(regid)):
549         if (hex_common.is_hvx_reg(regtype)):
550             if (hex_common.is_new_result(tag)):
551                 genptr_dst_write_ext(f, tag, regtype, regid, "EXT_NEW")
552             if (hex_common.is_tmp_result(tag)):
553                 genptr_dst_write_ext(f, tag, regtype, regid, "EXT_TMP")
554             else:
555                 genptr_dst_write_ext(f, tag, regtype, regid, "EXT_DFL")
556         else:
557             genptr_dst_write(f, tag, regtype, regid)
558     else:
559         print("Bad register parse: ",regtype,regid,toss,numregs)
560 
561 ##
562 ## Generate the TCG code to call the helper
563 ##     For A2_add: Rd32=add(Rs32,Rt32), { RdV=RsV+RtV;}
564 ##     We produce:
565 ##    static void generate_A2_add()
566 ##                    CPUHexagonState *env
567 ##                    DisasContext *ctx,
568 ##                    Insn *insn,
569 ##                    Packet *pkt)
570 ##       {
571 ##           TCGv RdV = tcg_temp_local_new();
572 ##           const int RdN = insn->regno[0];
573 ##           TCGv RsV = hex_gpr[insn->regno[1]];
574 ##           TCGv RtV = hex_gpr[insn->regno[2]];
575 ##           <GEN>
576 ##           gen_log_reg_write(RdN, RdV);
577 ##           ctx_log_reg_write(ctx, RdN);
578 ##           tcg_temp_free(RdV);
579 ##       }
580 ##
581 ##       where <GEN> depends on hex_common.skip_qemu_helper(tag)
582 ##       if hex_common.skip_qemu_helper(tag) is True
583 ##       <GEN>  is fGEN_TCG_A2_add({ RdV=RsV+RtV;});
584 ##       if hex_common.skip_qemu_helper(tag) is False
585 ##       <GEN>  is gen_helper_A2_add(RdV, cpu_env, RsV, RtV);
586 ##
587 def gen_tcg_func(f, tag, regs, imms):
588     f.write("static void generate_%s(\n" %tag)
589     f.write("                CPUHexagonState *env,\n")
590     f.write("                DisasContext *ctx,\n")
591     f.write("                Insn *insn,\n")
592     f.write("                Packet *pkt)\n")
593     f.write('{\n')
594     if hex_common.need_ea(tag): gen_decl_ea_tcg(f, tag)
595     i=0
596     ## Declare all the operands (regs and immediates)
597     for regtype,regid,toss,numregs in regs:
598         genptr_decl_opn(f, tag, regtype, regid, toss, numregs, i)
599         i += 1
600     for immlett,bits,immshift in imms:
601         genptr_decl_imm(f,immlett)
602 
603     if 'A_PRIV' in hex_common.attribdict[tag]:
604         f.write('    fCHECKFORPRIV();\n')
605     if 'A_GUEST' in hex_common.attribdict[tag]:
606         f.write('    fCHECKFORGUEST();\n')
607 
608     ## Read all the inputs
609     for regtype,regid,toss,numregs in regs:
610         if (hex_common.is_read(regid)):
611             genptr_src_read_opn(f,regtype,regid,tag)
612 
613     if ( hex_common.skip_qemu_helper(tag) ):
614         f.write("    fGEN_TCG_%s(%s);\n" % (tag, hex_common.semdict[tag]))
615     else:
616         ## Generate the call to the helper
617         for immlett,bits,immshift in imms:
618             gen_helper_decl_imm(f,immlett)
619         if hex_common.need_part1(tag):
620             f.write("    TCGv part1 = tcg_constant_tl(insn->part1);\n")
621         if hex_common.need_slot(tag):
622             f.write("    TCGv slot = tcg_constant_tl(insn->slot);\n")
623         f.write("    gen_helper_%s(" % (tag))
624         i=0
625         ## If there is a scalar result, it is the return type
626         for regtype,regid,toss,numregs in regs:
627             if (hex_common.is_written(regid)):
628                 if (hex_common.is_hvx_reg(regtype)):
629                     continue
630                 gen_helper_call_opn(f, tag, regtype, regid, toss, numregs, i)
631                 i += 1
632         if (i > 0): f.write(", ")
633         f.write("cpu_env")
634         i=1
635         for regtype,regid,toss,numregs in regs:
636             if (hex_common.is_written(regid)):
637                 if (not hex_common.is_hvx_reg(regtype)):
638                     continue
639                 gen_helper_call_opn(f, tag, regtype, regid, toss, numregs, i)
640                 i += 1
641         for regtype,regid,toss,numregs in regs:
642             if (hex_common.is_read(regid)):
643                 if (hex_common.is_hvx_reg(regtype) and
644                     hex_common.is_readwrite(regid)):
645                     continue
646                 gen_helper_call_opn(f, tag, regtype, regid, toss, numregs, i)
647                 i += 1
648         for immlett,bits,immshift in imms:
649             gen_helper_call_imm(f,immlett)
650 
651         if hex_common.need_slot(tag): f.write(", slot")
652         if hex_common.need_part1(tag): f.write(", part1" )
653         f.write(");\n")
654 
655     ## Write all the outputs
656     for regtype,regid,toss,numregs in regs:
657         if (hex_common.is_written(regid)):
658             genptr_dst_write_opn(f,regtype, regid, tag)
659 
660     ## Free all the operands (regs and immediates)
661     if hex_common.need_ea(tag): gen_free_ea_tcg(f)
662     for regtype,regid,toss,numregs in regs:
663         genptr_free_opn(f,regtype,regid,i,tag)
664         i += 1
665 
666     f.write("}\n\n")
667 
668 def gen_def_tcg_func(f, tag, tagregs, tagimms):
669     regs = tagregs[tag]
670     imms = tagimms[tag]
671 
672     gen_tcg_func(f, tag, regs, imms)
673 
674 def main():
675     hex_common.read_semantics_file(sys.argv[1])
676     hex_common.read_attribs_file(sys.argv[2])
677     hex_common.read_overrides_file(sys.argv[3])
678     hex_common.read_overrides_file(sys.argv[4])
679     hex_common.calculate_attribs()
680     tagregs = hex_common.get_tagregs()
681     tagimms = hex_common.get_tagimms()
682 
683     with open(sys.argv[5], 'w') as f:
684         f.write("#ifndef HEXAGON_TCG_FUNCS_H\n")
685         f.write("#define HEXAGON_TCG_FUNCS_H\n\n")
686 
687         for tag in hex_common.tags:
688             ## Skip the priv instructions
689             if ( "A_PRIV" in hex_common.attribdict[tag] ) :
690                 continue
691             ## Skip the guest instructions
692             if ( "A_GUEST" in hex_common.attribdict[tag] ) :
693                 continue
694             ## Skip the diag instructions
695             if ( tag == "Y6_diag" ) :
696                 continue
697             if ( tag == "Y6_diag0" ) :
698                 continue
699             if ( tag == "Y6_diag1" ) :
700                 continue
701 
702             gen_def_tcg_func(f, tag, tagregs, tagimms)
703 
704         f.write("#endif    /* HEXAGON_TCG_FUNCS_H */\n")
705 
706 if __name__ == "__main__":
707     main()
708