xref: /qemu/target/hexagon/gen_tcg_funcs.py (revision b83a80e8)
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
20import sys
21import re
22import string
23import hex_common
24
25##
26## Helpers for gen_tcg_func
27##
28def 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
35def gen_free_ea_tcg(f):
36    f.write("    tcg_temp_free(EA);\n")
37
38def 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
57def 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
72def 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
210def 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
241def 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
254def 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
262def 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
303def 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
316def 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
329def 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
403def 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
416def 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
429def 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
443def 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
447def gen_helper_call_imm(f,immlett):
448    f.write(", tcgv_%s" % hex_common.imm_name(immlett))
449
450def 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
460def 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
496def 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
539def 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##
587def 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
668def 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
674def 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
706if __name__ == "__main__":
707    main()
708