xref: /qemu/target/hexagon/gen_tcg_funcs.py (revision 8afc43ea)
1#!/usr/bin/env python3
2
3##
4##  Copyright(c) 2019-2023 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##
27## Helpers for gen_tcg_func
28##
29def gen_decl_ea_tcg(f, tag):
30    f.write("    TCGv EA G_GNUC_UNUSED = tcg_temp_new();\n")
31
32
33def genptr_decl_pair_writable(f, tag, regtype, regid, regno):
34    regN = f"{regtype}{regid}N"
35    if regtype == "R":
36        f.write(f"    const int {regN} = insn->regno[{regno}];\n")
37    elif regtype == "C":
38        f.write(f"    const int {regN} = insn->regno[{regno}] + HEX_REG_SA0;\n")
39    else:
40        print("Bad register parse: ", regtype, regid)
41    f.write(f"    TCGv_i64 {regtype}{regid}V = " f"get_result_gpr_pair(ctx, {regN});\n")
42
43
44def genptr_decl_writable(f, tag, regtype, regid, regno):
45    regN = f"{regtype}{regid}N"
46    if regtype == "R":
47        f.write(f"    const int {regN} = insn->regno[{regno}];\n")
48        f.write(f"    TCGv {regtype}{regid}V = get_result_gpr(ctx, {regN});\n")
49    elif regtype == "C":
50        f.write(f"    const int {regN} = insn->regno[{regno}] + HEX_REG_SA0;\n")
51        f.write(f"    TCGv {regtype}{regid}V = get_result_gpr(ctx, {regN});\n")
52    elif regtype == "P":
53        f.write(f"    const int {regN} = insn->regno[{regno}];\n")
54        f.write(f"    TCGv {regtype}{regid}V = tcg_temp_new();\n")
55    else:
56        print("Bad register parse: ", regtype, regid)
57
58
59def genptr_decl(f, tag, regtype, regid, regno):
60    regN = f"{regtype}{regid}N"
61    if regtype == "R":
62        if regid in {"ss", "tt"}:
63            f.write(f"    TCGv_i64 {regtype}{regid}V = tcg_temp_new_i64();\n")
64            f.write(f"    const int {regN} = insn->regno[{regno}];\n")
65        elif regid in {"dd", "ee", "xx", "yy"}:
66            genptr_decl_pair_writable(f, tag, regtype, regid, regno)
67        elif regid in {"s", "t", "u", "v"}:
68            f.write(
69                f"    TCGv {regtype}{regid}V = " f"hex_gpr[insn->regno[{regno}]];\n"
70            )
71        elif regid in {"d", "e", "x", "y"}:
72            genptr_decl_writable(f, tag, regtype, regid, regno)
73        else:
74            print("Bad register parse: ", regtype, regid)
75    elif regtype == "P":
76        if regid in {"s", "t", "u", "v"}:
77            f.write(
78                f"    TCGv {regtype}{regid}V = " f"hex_pred[insn->regno[{regno}]];\n"
79            )
80        elif regid in {"d", "e", "x"}:
81            genptr_decl_writable(f, tag, regtype, regid, regno)
82        else:
83            print("Bad register parse: ", regtype, regid)
84    elif regtype == "C":
85        if regid == "ss":
86            f.write(f"    TCGv_i64 {regtype}{regid}V = " f"tcg_temp_new_i64();\n")
87            f.write(f"    const int {regN} = insn->regno[{regno}] + " "HEX_REG_SA0;\n")
88        elif regid == "dd":
89            genptr_decl_pair_writable(f, tag, regtype, regid, regno)
90        elif regid == "s":
91            f.write(f"    TCGv {regtype}{regid}V = tcg_temp_new();\n")
92            f.write(
93                f"    const int {regtype}{regid}N = insn->regno[{regno}] + "
94                "HEX_REG_SA0;\n"
95            )
96        elif regid == "d":
97            genptr_decl_writable(f, tag, regtype, regid, regno)
98        else:
99            print("Bad register parse: ", regtype, regid)
100    elif regtype == "M":
101        if regid == "u":
102            f.write(f"    const int {regtype}{regid}N = " f"insn->regno[{regno}];\n")
103            f.write(
104                f"    TCGv {regtype}{regid}V = hex_gpr[{regtype}{regid}N + "
105                "HEX_REG_M0];\n"
106            )
107        else:
108            print("Bad register parse: ", regtype, regid)
109    elif regtype == "V":
110        if regid in {"dd"}:
111            f.write(f"    const int {regtype}{regid}N = " f"insn->regno[{regno}];\n")
112            f.write(f"    const intptr_t {regtype}{regid}V_off =\n")
113            if hex_common.is_tmp_result(tag):
114                f.write(
115                    f"        ctx_tmp_vreg_off(ctx, {regtype}{regid}N, 2, " "true);\n"
116                )
117            else:
118                f.write(f"        ctx_future_vreg_off(ctx, {regtype}{regid}N,")
119                f.write(" 2, true);\n")
120            if not hex_common.skip_qemu_helper(tag):
121                f.write(f"    TCGv_ptr {regtype}{regid}V = " "tcg_temp_new_ptr();\n")
122                f.write(
123                    f"    tcg_gen_addi_ptr({regtype}{regid}V, cpu_env, "
124                    f"{regtype}{regid}V_off);\n"
125                )
126        elif regid in {"uu", "vv", "xx"}:
127            f.write(f"    const int {regtype}{regid}N = " f"insn->regno[{regno}];\n")
128            f.write(f"    const intptr_t {regtype}{regid}V_off =\n")
129            f.write(f"        offsetof(CPUHexagonState, {regtype}{regid}V);\n")
130            if not hex_common.skip_qemu_helper(tag):
131                f.write(f"    TCGv_ptr {regtype}{regid}V = " "tcg_temp_new_ptr();\n")
132                f.write(
133                    f"    tcg_gen_addi_ptr({regtype}{regid}V, cpu_env, "
134                    f"{regtype}{regid}V_off);\n"
135                )
136        elif regid in {"s", "u", "v", "w"}:
137            f.write(f"    const int {regtype}{regid}N = " f"insn->regno[{regno}];\n")
138            f.write(f"    const intptr_t {regtype}{regid}V_off =\n")
139            f.write(f"        vreg_src_off(ctx, {regtype}{regid}N);\n")
140            if not hex_common.skip_qemu_helper(tag):
141                f.write(f"    TCGv_ptr {regtype}{regid}V = " "tcg_temp_new_ptr();\n")
142        elif regid in {"d", "x", "y"}:
143            f.write(f"    const int {regtype}{regid}N = " f"insn->regno[{regno}];\n")
144            f.write(f"    const intptr_t {regtype}{regid}V_off =\n")
145            if regid == "y":
146                f.write("        offsetof(CPUHexagonState, vtmp);\n")
147            elif hex_common.is_tmp_result(tag):
148                f.write(
149                    f"        ctx_tmp_vreg_off(ctx, {regtype}{regid}N, 1, " "true);\n"
150                )
151            else:
152                f.write(f"        ctx_future_vreg_off(ctx, {regtype}{regid}N,")
153                f.write(" 1, true);\n")
154
155            if not hex_common.skip_qemu_helper(tag):
156                f.write(f"    TCGv_ptr {regtype}{regid}V = " "tcg_temp_new_ptr();\n")
157                f.write(
158                    f"    tcg_gen_addi_ptr({regtype}{regid}V, cpu_env, "
159                    f"{regtype}{regid}V_off);\n"
160                )
161        else:
162            print("Bad register parse: ", regtype, regid)
163    elif regtype == "Q":
164        if regid in {"d", "e", "x"}:
165            f.write(f"    const int {regtype}{regid}N = " f"insn->regno[{regno}];\n")
166            f.write(f"    const intptr_t {regtype}{regid}V_off =\n")
167            f.write(f"        get_result_qreg(ctx, {regtype}{regid}N);\n")
168            if not hex_common.skip_qemu_helper(tag):
169                f.write(f"    TCGv_ptr {regtype}{regid}V = " "tcg_temp_new_ptr();\n")
170                f.write(
171                    f"    tcg_gen_addi_ptr({regtype}{regid}V, cpu_env, "
172                    f"{regtype}{regid}V_off);\n"
173                )
174        elif regid in {"s", "t", "u", "v"}:
175            f.write(f"    const int {regtype}{regid}N = " f"insn->regno[{regno}];\n")
176            f.write(f"    const intptr_t {regtype}{regid}V_off =\n")
177            f.write(
178                f"        offsetof(CPUHexagonState, " f"QRegs[{regtype}{regid}N]);\n"
179            )
180            if not hex_common.skip_qemu_helper(tag):
181                f.write(f"    TCGv_ptr {regtype}{regid}V = " "tcg_temp_new_ptr();\n")
182        else:
183            print("Bad register parse: ", regtype, regid)
184    else:
185        print("Bad register parse: ", regtype, regid)
186
187
188def genptr_decl_new(f, tag, regtype, regid, regno):
189    if regtype == "N":
190        if regid in {"s", "t"}:
191            f.write(
192                f"    TCGv {regtype}{regid}N = "
193                f"hex_new_value[insn->regno[{regno}]];\n"
194            )
195        else:
196            print("Bad register parse: ", regtype, regid)
197    elif regtype == "P":
198        if regid in {"t", "u", "v"}:
199            f.write(
200                f"    TCGv {regtype}{regid}N = "
201                f"hex_new_pred_value[insn->regno[{regno}]];\n"
202            )
203        else:
204            print("Bad register parse: ", regtype, regid)
205    elif regtype == "O":
206        if regid == "s":
207            f.write(
208                f"    const intptr_t {regtype}{regid}N_num = "
209                f"insn->regno[{regno}];\n"
210            )
211            if hex_common.skip_qemu_helper(tag):
212                f.write(f"    const intptr_t {regtype}{regid}N_off =\n")
213                f.write("         ctx_future_vreg_off(ctx, " f"{regtype}{regid}N_num,")
214                f.write(" 1, true);\n")
215            else:
216                f.write(
217                    f"    TCGv {regtype}{regid}N = "
218                    f"tcg_constant_tl({regtype}{regid}N_num);\n"
219                )
220        else:
221            print("Bad register parse: ", regtype, regid)
222    else:
223        print("Bad register parse: ", regtype, regid)
224
225
226def genptr_decl_opn(f, tag, regtype, regid, toss, numregs, i):
227    if hex_common.is_pair(regid):
228        genptr_decl(f, tag, regtype, regid, i)
229    elif hex_common.is_single(regid):
230        if hex_common.is_old_val(regtype, regid, tag):
231            genptr_decl(f, tag, regtype, regid, i)
232        elif hex_common.is_new_val(regtype, regid, tag):
233            genptr_decl_new(f, tag, regtype, regid, i)
234        else:
235            print("Bad register parse: ", regtype, regid, toss, numregs)
236    else:
237        print("Bad register parse: ", regtype, regid, toss, numregs)
238
239
240def genptr_decl_imm(f, immlett):
241    if immlett.isupper():
242        i = 1
243    else:
244        i = 0
245    f.write(f"    int {hex_common.imm_name(immlett)} = insn->immed[{i}];\n")
246
247
248def genptr_src_read(f, tag, regtype, regid):
249    if regtype == "R":
250        if regid in {"ss", "tt", "xx", "yy"}:
251            f.write(
252                f"    tcg_gen_concat_i32_i64({regtype}{regid}V, "
253                f"hex_gpr[{regtype}{regid}N],\n"
254            )
255            f.write(
256                f"                                 hex_gpr[{regtype}"
257                f"{regid}N + 1]);\n"
258            )
259        elif regid in {"x", "y"}:
260            ## For read/write registers, we need to get the original value into
261            ## the result TCGv.  For conditional instructions, this is done in
262            ## gen_start_packet.  For unconditional instructions, we do it here.
263            if "A_CONDEXEC" not in hex_common.attribdict[tag]:
264                f.write(
265                    f"    tcg_gen_mov_tl({regtype}{regid}V, "
266                    f"hex_gpr[{regtype}{regid}N]);\n"
267                )
268        elif regid not in {"s", "t", "u", "v"}:
269            print("Bad register parse: ", regtype, regid)
270    elif regtype == "P":
271        if regid == "x":
272            f.write(
273                f"    tcg_gen_mov_tl({regtype}{regid}V, "
274                f"hex_pred[{regtype}{regid}N]);\n"
275            )
276        elif regid not in {"s", "t", "u", "v"}:
277            print("Bad register parse: ", regtype, regid)
278    elif regtype == "C":
279        if regid == "ss":
280            f.write(
281                f"    gen_read_ctrl_reg_pair(ctx, {regtype}{regid}N, "
282                f"{regtype}{regid}V);\n"
283            )
284        elif regid == "s":
285            f.write(
286                f"    gen_read_ctrl_reg(ctx, {regtype}{regid}N, "
287                f"{regtype}{regid}V);\n"
288            )
289        else:
290            print("Bad register parse: ", regtype, regid)
291    elif regtype == "M":
292        if regid != "u":
293            print("Bad register parse: ", regtype, regid)
294    elif regtype == "V":
295        if regid in {"uu", "vv", "xx"}:
296            f.write(f"    tcg_gen_gvec_mov(MO_64, {regtype}{regid}V_off,\n")
297            f.write(f"        vreg_src_off(ctx, {regtype}{regid}N),\n")
298            f.write("        sizeof(MMVector), sizeof(MMVector));\n")
299            f.write("    tcg_gen_gvec_mov(MO_64,\n")
300            f.write(f"        {regtype}{regid}V_off + sizeof(MMVector),\n")
301            f.write(f"        vreg_src_off(ctx, {regtype}{regid}N ^ 1),\n")
302            f.write("        sizeof(MMVector), sizeof(MMVector));\n")
303        elif regid in {"s", "u", "v", "w"}:
304            if not hex_common.skip_qemu_helper(tag):
305                f.write(
306                    f"    tcg_gen_addi_ptr({regtype}{regid}V, cpu_env, "
307                    f"{regtype}{regid}V_off);\n"
308                )
309        elif regid in {"x", "y"}:
310            f.write(f"    tcg_gen_gvec_mov(MO_64, {regtype}{regid}V_off,\n")
311            f.write(f"        vreg_src_off(ctx, {regtype}{regid}N),\n")
312            f.write("        sizeof(MMVector), sizeof(MMVector));\n")
313        else:
314            print("Bad register parse: ", regtype, regid)
315    elif regtype == "Q":
316        if regid in {"s", "t", "u", "v"}:
317            if not hex_common.skip_qemu_helper(tag):
318                f.write(
319                    f"    tcg_gen_addi_ptr({regtype}{regid}V, cpu_env, "
320                    f"{regtype}{regid}V_off);\n"
321                )
322        elif regid in {"x"}:
323            f.write(f"    tcg_gen_gvec_mov(MO_64, {regtype}{regid}V_off,\n")
324            f.write(
325                f"        offsetof(CPUHexagonState, " f"QRegs[{regtype}{regid}N]),\n"
326            )
327            f.write("        sizeof(MMQReg), sizeof(MMQReg));\n")
328        else:
329            print("Bad register parse: ", regtype, regid)
330    else:
331        print("Bad register parse: ", regtype, regid)
332
333
334def genptr_src_read_new(f, regtype, regid):
335    if regtype == "N":
336        if regid not in {"s", "t"}:
337            print("Bad register parse: ", regtype, regid)
338    elif regtype == "P":
339        if regid not in {"t", "u", "v"}:
340            print("Bad register parse: ", regtype, regid)
341    elif regtype == "O":
342        if regid != "s":
343            print("Bad register parse: ", regtype, regid)
344    else:
345        print("Bad register parse: ", regtype, regid)
346
347
348def genptr_src_read_opn(f, regtype, regid, tag):
349    if hex_common.is_pair(regid):
350        genptr_src_read(f, tag, regtype, regid)
351    elif hex_common.is_single(regid):
352        if hex_common.is_old_val(regtype, regid, tag):
353            genptr_src_read(f, tag, regtype, regid)
354        elif hex_common.is_new_val(regtype, regid, tag):
355            genptr_src_read_new(f, regtype, regid)
356        else:
357            print("Bad register parse: ", regtype, regid, toss, numregs)
358    else:
359        print("Bad register parse: ", regtype, regid, toss, numregs)
360
361
362def gen_helper_call_opn(f, tag, regtype, regid, toss, numregs, i):
363    if i > 0:
364        f.write(", ")
365    if hex_common.is_pair(regid):
366        f.write(f"{regtype}{regid}V")
367    elif hex_common.is_single(regid):
368        if hex_common.is_old_val(regtype, regid, tag):
369            f.write(f"{regtype}{regid}V")
370        elif hex_common.is_new_val(regtype, regid, tag):
371            f.write(f"{regtype}{regid}N")
372        else:
373            print("Bad register parse: ", regtype, regid, toss, numregs)
374    else:
375        print("Bad register parse: ", regtype, regid, toss, numregs)
376
377
378def gen_helper_decl_imm(f, immlett):
379    f.write(
380        f"    TCGv tcgv_{hex_common.imm_name(immlett)} = "
381        f"tcg_constant_tl({hex_common.imm_name(immlett)});\n"
382    )
383
384
385def gen_helper_call_imm(f, immlett):
386    f.write(f", tcgv_{hex_common.imm_name(immlett)}")
387
388
389def genptr_dst_write_pair(f, tag, regtype, regid):
390    f.write(f"    gen_log_reg_write_pair({regtype}{regid}N, " f"{regtype}{regid}V);\n")
391
392
393def genptr_dst_write(f, tag, regtype, regid):
394    if regtype == "R":
395        if regid in {"dd", "xx", "yy"}:
396            genptr_dst_write_pair(f, tag, regtype, regid)
397        elif regid in {"d", "e", "x", "y"}:
398            f.write(
399                f"    gen_log_reg_write({regtype}{regid}N, " f"{regtype}{regid}V);\n"
400            )
401        else:
402            print("Bad register parse: ", regtype, regid)
403    elif regtype == "P":
404        if regid in {"d", "e", "x"}:
405            f.write(
406                f"    gen_log_pred_write(ctx, {regtype}{regid}N, "
407                f"{regtype}{regid}V);\n"
408            )
409        else:
410            print("Bad register parse: ", regtype, regid)
411    elif regtype == "C":
412        if regid == "dd":
413            f.write(
414                f"    gen_write_ctrl_reg_pair(ctx, {regtype}{regid}N, "
415                f"{regtype}{regid}V);\n"
416            )
417        elif regid == "d":
418            f.write(
419                f"    gen_write_ctrl_reg(ctx, {regtype}{regid}N, "
420                f"{regtype}{regid}V);\n"
421            )
422        else:
423            print("Bad register parse: ", regtype, regid)
424    else:
425        print("Bad register parse: ", regtype, regid)
426
427
428def genptr_dst_write_ext(f, tag, regtype, regid, newv="EXT_DFL"):
429    if regtype == "V":
430        if regid in {"xx"}:
431            f.write(
432                f"    gen_log_vreg_write_pair(ctx, {regtype}{regid}V_off, "
433                f"{regtype}{regid}N, {newv});\n"
434            )
435        elif regid in {"y"}:
436            f.write(
437                f"    gen_log_vreg_write(ctx, {regtype}{regid}V_off, "
438                f"{regtype}{regid}N, {newv});\n"
439            )
440        elif regid not in {"dd", "d", "x"}:
441            print("Bad register parse: ", regtype, regid)
442    elif regtype == "Q":
443        if regid not in {"d", "e", "x"}:
444            print("Bad register parse: ", regtype, regid)
445    else:
446        print("Bad register parse: ", regtype, regid)
447
448
449def genptr_dst_write_opn(f, regtype, regid, tag):
450    if hex_common.is_pair(regid):
451        if hex_common.is_hvx_reg(regtype):
452            if hex_common.is_tmp_result(tag):
453                genptr_dst_write_ext(f, tag, regtype, regid, "EXT_TMP")
454            else:
455                genptr_dst_write_ext(f, tag, regtype, regid)
456        else:
457            genptr_dst_write(f, tag, regtype, regid)
458    elif hex_common.is_single(regid):
459        if hex_common.is_hvx_reg(regtype):
460            if hex_common.is_new_result(tag):
461                genptr_dst_write_ext(f, tag, regtype, regid, "EXT_NEW")
462            elif hex_common.is_tmp_result(tag):
463                genptr_dst_write_ext(f, tag, regtype, regid, "EXT_TMP")
464            else:
465                genptr_dst_write_ext(f, tag, regtype, regid, "EXT_DFL")
466        else:
467            genptr_dst_write(f, tag, regtype, regid)
468    else:
469        print("Bad register parse: ", regtype, regid, toss, numregs)
470
471
472##
473## Generate the TCG code to call the helper
474##     For A2_add: Rd32=add(Rs32,Rt32), { RdV=RsV+RtV;}
475##     We produce:
476##    static void generate_A2_add(DisasContext *ctx)
477##    {
478##        Insn *insn __attribute__((unused)) = ctx->insn;
479##        const int RdN = insn->regno[0];
480##        TCGv RdV = get_result_gpr(ctx, RdN);
481##        TCGv RsV = hex_gpr[insn->regno[1]];
482##        TCGv RtV = hex_gpr[insn->regno[2]];
483##        <GEN>
484##        gen_log_reg_write(RdN, RdV);
485##    }
486##
487##       where <GEN> depends on hex_common.skip_qemu_helper(tag)
488##       if hex_common.skip_qemu_helper(tag) is True
489##       <GEN>  is fGEN_TCG_A2_add({ RdV=RsV+RtV;});
490##       if hex_common.skip_qemu_helper(tag) is False
491##       <GEN>  is gen_helper_A2_add(RdV, cpu_env, RsV, RtV);
492##
493def gen_tcg_func(f, tag, regs, imms):
494    f.write(f"static void generate_{tag}(DisasContext *ctx)\n")
495    f.write("{\n")
496
497    f.write("    Insn *insn __attribute__((unused)) = ctx->insn;\n")
498
499    if hex_common.need_ea(tag):
500        gen_decl_ea_tcg(f, tag)
501    i = 0
502    ## Declare all the operands (regs and immediates)
503    for regtype, regid, toss, numregs in regs:
504        genptr_decl_opn(f, tag, regtype, regid, toss, numregs, i)
505        i += 1
506    for immlett, bits, immshift in imms:
507        genptr_decl_imm(f, immlett)
508
509    if "A_PRIV" in hex_common.attribdict[tag]:
510        f.write("    fCHECKFORPRIV();\n")
511    if "A_GUEST" in hex_common.attribdict[tag]:
512        f.write("    fCHECKFORGUEST();\n")
513
514    ## Read all the inputs
515    for regtype, regid, toss, numregs in regs:
516        if hex_common.is_read(regid):
517            genptr_src_read_opn(f, regtype, regid, tag)
518
519    if hex_common.is_idef_parser_enabled(tag):
520        declared = []
521        ## Handle registers
522        for regtype, regid, toss, numregs in regs:
523            if hex_common.is_pair(regid) or (
524                hex_common.is_single(regid)
525                and hex_common.is_old_val(regtype, regid, tag)
526            ):
527                declared.append(f"{regtype}{regid}V")
528                if regtype == "M":
529                    declared.append(f"{regtype}{regid}N")
530            elif hex_common.is_new_val(regtype, regid, tag):
531                declared.append(f"{regtype}{regid}N")
532            else:
533                print("Bad register parse: ", regtype, regid, toss, numregs)
534
535        ## Handle immediates
536        for immlett, bits, immshift in imms:
537            declared.append(hex_common.imm_name(immlett))
538
539        arguments = ", ".join(["ctx", "ctx->insn", "ctx->pkt"] + declared)
540        f.write(f"    emit_{tag}({arguments});\n")
541
542    elif hex_common.skip_qemu_helper(tag):
543        f.write(f"    fGEN_TCG_{tag}({hex_common.semdict[tag]});\n")
544    else:
545        ## Generate the call to the helper
546        for immlett, bits, immshift in imms:
547            gen_helper_decl_imm(f, immlett)
548        if hex_common.need_pkt_has_multi_cof(tag):
549            f.write("    TCGv pkt_has_multi_cof = ")
550            f.write("tcg_constant_tl(ctx->pkt->pkt_has_multi_cof);\n")
551        if hex_common.need_part1(tag):
552            f.write("    TCGv part1 = tcg_constant_tl(insn->part1);\n")
553        if hex_common.need_slot(tag):
554            f.write("    TCGv slot = tcg_constant_tl(insn->slot);\n")
555        if hex_common.need_PC(tag):
556            f.write("    TCGv PC = tcg_constant_tl(ctx->pkt->pc);\n")
557        if hex_common.helper_needs_next_PC(tag):
558            f.write("    TCGv next_PC = tcg_constant_tl(ctx->next_PC);\n")
559        f.write(f"    gen_helper_{tag}(")
560        i = 0
561        ## If there is a scalar result, it is the return type
562        for regtype, regid, toss, numregs in regs:
563            if hex_common.is_written(regid):
564                if hex_common.is_hvx_reg(regtype):
565                    continue
566                gen_helper_call_opn(f, tag, regtype, regid, toss, numregs, i)
567                i += 1
568        if i > 0:
569            f.write(", ")
570        f.write("cpu_env")
571        i = 1
572        ## For conditional instructions, we pass in the destination register
573        if "A_CONDEXEC" in hex_common.attribdict[tag]:
574            for regtype, regid, toss, numregs in regs:
575                if hex_common.is_writeonly(regid) and not hex_common.is_hvx_reg(
576                    regtype
577                ):
578                    gen_helper_call_opn(f, tag, regtype, regid, toss, numregs, i)
579                    i += 1
580        for regtype, regid, toss, numregs in regs:
581            if hex_common.is_written(regid):
582                if not hex_common.is_hvx_reg(regtype):
583                    continue
584                gen_helper_call_opn(f, tag, regtype, regid, toss, numregs, i)
585                i += 1
586        for regtype, regid, toss, numregs in regs:
587            if hex_common.is_read(regid):
588                if hex_common.is_hvx_reg(regtype) and hex_common.is_readwrite(regid):
589                    continue
590                gen_helper_call_opn(f, tag, regtype, regid, toss, numregs, i)
591                i += 1
592        for immlett, bits, immshift in imms:
593            gen_helper_call_imm(f, immlett)
594
595        if hex_common.need_pkt_has_multi_cof(tag):
596            f.write(", pkt_has_multi_cof")
597        if hex_common.need_PC(tag):
598            f.write(", PC")
599        if hex_common.helper_needs_next_PC(tag):
600            f.write(", next_PC")
601        if hex_common.need_slot(tag):
602            f.write(", slot")
603        if hex_common.need_part1(tag):
604            f.write(", part1")
605        f.write(");\n")
606
607    ## Write all the outputs
608    for regtype, regid, toss, numregs in regs:
609        if hex_common.is_written(regid):
610            genptr_dst_write_opn(f, regtype, regid, tag)
611
612    f.write("}\n\n")
613
614
615def gen_def_tcg_func(f, tag, tagregs, tagimms):
616    regs = tagregs[tag]
617    imms = tagimms[tag]
618
619    gen_tcg_func(f, tag, regs, imms)
620
621
622def main():
623    hex_common.read_semantics_file(sys.argv[1])
624    hex_common.read_attribs_file(sys.argv[2])
625    hex_common.read_overrides_file(sys.argv[3])
626    hex_common.read_overrides_file(sys.argv[4])
627    hex_common.calculate_attribs()
628    ## Whether or not idef-parser is enabled is
629    ## determined by the number of arguments to
630    ## this script:
631    ##
632    ##   5 args. -> not enabled,
633    ##   6 args. -> idef-parser enabled.
634    ##
635    ## The 6:th arg. then holds a list of the successfully
636    ## parsed instructions.
637    is_idef_parser_enabled = len(sys.argv) > 6
638    if is_idef_parser_enabled:
639        hex_common.read_idef_parser_enabled_file(sys.argv[5])
640    tagregs = hex_common.get_tagregs()
641    tagimms = hex_common.get_tagimms()
642
643    output_file = sys.argv[-1]
644    with open(output_file, "w") as f:
645        f.write("#ifndef HEXAGON_TCG_FUNCS_H\n")
646        f.write("#define HEXAGON_TCG_FUNCS_H\n\n")
647        if is_idef_parser_enabled:
648            f.write('#include "idef-generated-emitter.h.inc"\n\n')
649
650        for tag in hex_common.tags:
651            ## Skip the priv instructions
652            if "A_PRIV" in hex_common.attribdict[tag]:
653                continue
654            ## Skip the guest instructions
655            if "A_GUEST" in hex_common.attribdict[tag]:
656                continue
657            ## Skip the diag instructions
658            if tag == "Y6_diag":
659                continue
660            if tag == "Y6_diag0":
661                continue
662            if tag == "Y6_diag1":
663                continue
664
665            gen_def_tcg_func(f, tag, tagregs, tagimms)
666
667        f.write("#endif    /* HEXAGON_TCG_FUNCS_H */\n")
668
669
670if __name__ == "__main__":
671    main()
672