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        hex_common.bad_register(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        hex_common.bad_register(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            hex_common.bad_register(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            hex_common.bad_register(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            hex_common.bad_register(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            hex_common.bad_register(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            hex_common.bad_register(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            hex_common.bad_register(regtype, regid)
184    else:
185        hex_common.bad_register(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"get_result_gpr(ctx, insn->regno[{regno}]);\n"
194            )
195        else:
196            hex_common.bad_register(regtype, regid)
197    elif regtype == "P":
198        if regid in {"t", "u", "v"}:
199            f.write(
200                f"    TCGv {regtype}{regid}N = "
201                f"ctx->new_pred_value[insn->regno[{regno}]];\n"
202            )
203        else:
204            hex_common.bad_register(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            hex_common.bad_register(regtype, regid)
222    else:
223        hex_common.bad_register(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            hex_common.bad_register(regtype, regid, toss, numregs)
236    else:
237        hex_common.bad_register(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            hex_common.bad_register(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            hex_common.bad_register(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            hex_common.bad_register(regtype, regid)
291    elif regtype == "M":
292        if regid != "u":
293            hex_common.bad_register(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            hex_common.bad_register(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            hex_common.bad_register(regtype, regid)
330    else:
331        hex_common.bad_register(regtype, regid)
332
333
334def genptr_src_read_new(f, regtype, regid):
335    if regtype == "N":
336        if regid not in {"s", "t"}:
337            hex_common.bad_register(regtype, regid)
338    elif regtype == "P":
339        if regid not in {"t", "u", "v"}:
340            hex_common.bad_register(regtype, regid)
341    elif regtype == "O":
342        if regid != "s":
343            hex_common.bad_register(regtype, regid)
344    else:
345        hex_common.bad_register(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            hex_common.bad_register(regtype, regid, toss, numregs)
358    else:
359        hex_common.bad_register(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            hex_common.bad_register(regtype, regid, toss, numregs)
374    else:
375        hex_common.bad_register(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(ctx, {regtype}{regid}N, "
391            f"{regtype}{regid}V);\n")
392
393
394def genptr_dst_write(f, tag, regtype, regid):
395    if regtype == "R":
396        if regid in {"dd", "xx", "yy"}:
397            genptr_dst_write_pair(f, tag, regtype, regid)
398        elif regid in {"d", "e", "x", "y"}:
399            f.write(
400                f"    gen_log_reg_write(ctx, {regtype}{regid}N, "
401                f"{regtype}{regid}V);\n"
402            )
403        else:
404            hex_common.bad_register(regtype, regid)
405    elif regtype == "P":
406        if regid in {"d", "e", "x"}:
407            f.write(
408                f"    gen_log_pred_write(ctx, {regtype}{regid}N, "
409                f"{regtype}{regid}V);\n"
410            )
411        else:
412            hex_common.bad_register(regtype, regid)
413    elif regtype == "C":
414        if regid == "dd":
415            f.write(
416                f"    gen_write_ctrl_reg_pair(ctx, {regtype}{regid}N, "
417                f"{regtype}{regid}V);\n"
418            )
419        elif regid == "d":
420            f.write(
421                f"    gen_write_ctrl_reg(ctx, {regtype}{regid}N, "
422                f"{regtype}{regid}V);\n"
423            )
424        else:
425            hex_common.bad_register(regtype, regid)
426    else:
427        hex_common.bad_register(regtype, regid)
428
429
430def genptr_dst_write_ext(f, tag, regtype, regid, newv="EXT_DFL"):
431    if regtype == "V":
432        if regid in {"xx"}:
433            f.write(
434                f"    gen_log_vreg_write_pair(ctx, {regtype}{regid}V_off, "
435                f"{regtype}{regid}N, {newv});\n"
436            )
437        elif regid in {"y"}:
438            f.write(
439                f"    gen_log_vreg_write(ctx, {regtype}{regid}V_off, "
440                f"{regtype}{regid}N, {newv});\n"
441            )
442        elif regid not in {"dd", "d", "x"}:
443            hex_common.bad_register(regtype, regid)
444    elif regtype == "Q":
445        if regid not in {"d", "e", "x"}:
446            hex_common.bad_register(regtype, regid)
447    else:
448        hex_common.bad_register(regtype, regid)
449
450
451def genptr_dst_write_opn(f, regtype, regid, tag):
452    if hex_common.is_pair(regid):
453        if hex_common.is_hvx_reg(regtype):
454            if hex_common.is_tmp_result(tag):
455                genptr_dst_write_ext(f, tag, regtype, regid, "EXT_TMP")
456            else:
457                genptr_dst_write_ext(f, tag, regtype, regid)
458        else:
459            genptr_dst_write(f, tag, regtype, regid)
460    elif hex_common.is_single(regid):
461        if hex_common.is_hvx_reg(regtype):
462            if hex_common.is_new_result(tag):
463                genptr_dst_write_ext(f, tag, regtype, regid, "EXT_NEW")
464            elif hex_common.is_tmp_result(tag):
465                genptr_dst_write_ext(f, tag, regtype, regid, "EXT_TMP")
466            else:
467                genptr_dst_write_ext(f, tag, regtype, regid, "EXT_DFL")
468        else:
469            genptr_dst_write(f, tag, regtype, regid)
470    else:
471        hex_common.bad_register(regtype, regid, toss, numregs)
472
473
474##
475## Generate the TCG code to call the helper
476##     For A2_add: Rd32=add(Rs32,Rt32), { RdV=RsV+RtV;}
477##     We produce:
478##    static void generate_A2_add(DisasContext *ctx)
479##    {
480##        Insn *insn __attribute__((unused)) = ctx->insn;
481##        const int RdN = insn->regno[0];
482##        TCGv RdV = get_result_gpr(ctx, RdN);
483##        TCGv RsV = hex_gpr[insn->regno[1]];
484##        TCGv RtV = hex_gpr[insn->regno[2]];
485##        <GEN>
486##        gen_log_reg_write(ctx, RdN, RdV);
487##    }
488##
489##       where <GEN> depends on hex_common.skip_qemu_helper(tag)
490##       if hex_common.skip_qemu_helper(tag) is True
491##       <GEN>  is fGEN_TCG_A2_add({ RdV=RsV+RtV;});
492##       if hex_common.skip_qemu_helper(tag) is False
493##       <GEN>  is gen_helper_A2_add(RdV, cpu_env, RsV, RtV);
494##
495def gen_tcg_func(f, tag, regs, imms):
496    f.write(f"static void generate_{tag}(DisasContext *ctx)\n")
497    f.write("{\n")
498
499    f.write("    Insn *insn __attribute__((unused)) = ctx->insn;\n")
500
501    if hex_common.need_ea(tag):
502        gen_decl_ea_tcg(f, tag)
503    i = 0
504    ## Declare all the operands (regs and immediates)
505    for regtype, regid, toss, numregs in regs:
506        genptr_decl_opn(f, tag, regtype, regid, toss, numregs, i)
507        i += 1
508    for immlett, bits, immshift in imms:
509        genptr_decl_imm(f, immlett)
510
511    if "A_PRIV" in hex_common.attribdict[tag]:
512        f.write("    fCHECKFORPRIV();\n")
513    if "A_GUEST" in hex_common.attribdict[tag]:
514        f.write("    fCHECKFORGUEST();\n")
515
516    ## Read all the inputs
517    for regtype, regid, toss, numregs in regs:
518        if hex_common.is_read(regid):
519            genptr_src_read_opn(f, regtype, regid, tag)
520
521    if hex_common.is_idef_parser_enabled(tag):
522        declared = []
523        ## Handle registers
524        for regtype, regid, toss, numregs in regs:
525            if hex_common.is_pair(regid) or (
526                hex_common.is_single(regid)
527                and hex_common.is_old_val(regtype, regid, tag)
528            ):
529                declared.append(f"{regtype}{regid}V")
530                if regtype == "M":
531                    declared.append(f"{regtype}{regid}N")
532            elif hex_common.is_new_val(regtype, regid, tag):
533                declared.append(f"{regtype}{regid}N")
534            else:
535                hex_common.bad_register(regtype, regid, toss, numregs)
536
537        ## Handle immediates
538        for immlett, bits, immshift in imms:
539            declared.append(hex_common.imm_name(immlett))
540
541        arguments = ", ".join(["ctx", "ctx->insn", "ctx->pkt"] + declared)
542        f.write(f"    emit_{tag}({arguments});\n")
543
544    elif hex_common.skip_qemu_helper(tag):
545        f.write(f"    fGEN_TCG_{tag}({hex_common.semdict[tag]});\n")
546    else:
547        ## Generate the call to the helper
548        for immlett, bits, immshift in imms:
549            gen_helper_decl_imm(f, immlett)
550        if hex_common.need_pkt_has_multi_cof(tag):
551            f.write("    TCGv pkt_has_multi_cof = ")
552            f.write("tcg_constant_tl(ctx->pkt->pkt_has_multi_cof);\n")
553        if hex_common.need_pkt_need_commit(tag):
554            f.write("    TCGv pkt_need_commit = ")
555            f.write("tcg_constant_tl(ctx->need_commit);\n")
556        if hex_common.need_part1(tag):
557            f.write("    TCGv part1 = tcg_constant_tl(insn->part1);\n")
558        if hex_common.need_slot(tag):
559            f.write("    TCGv slotval = gen_slotval(ctx);\n")
560        if hex_common.need_PC(tag):
561            f.write("    TCGv PC = tcg_constant_tl(ctx->pkt->pc);\n")
562        if hex_common.helper_needs_next_PC(tag):
563            f.write("    TCGv next_PC = tcg_constant_tl(ctx->next_PC);\n")
564        f.write(f"    gen_helper_{tag}(")
565        i = 0
566        ## If there is a scalar result, it is the return type
567        for regtype, regid, toss, numregs in regs:
568            if hex_common.is_written(regid):
569                if hex_common.is_hvx_reg(regtype):
570                    continue
571                gen_helper_call_opn(f, tag, regtype, regid, toss, numregs, i)
572                i += 1
573        if i > 0:
574            f.write(", ")
575        f.write("cpu_env")
576        i = 1
577        ## For conditional instructions, we pass in the destination register
578        if "A_CONDEXEC" in hex_common.attribdict[tag]:
579            for regtype, regid, toss, numregs in regs:
580                if hex_common.is_writeonly(regid) and not hex_common.is_hvx_reg(
581                    regtype
582                ):
583                    gen_helper_call_opn(f, tag, regtype, regid, toss, numregs, i)
584                    i += 1
585        for regtype, regid, toss, numregs in regs:
586            if hex_common.is_written(regid):
587                if not hex_common.is_hvx_reg(regtype):
588                    continue
589                gen_helper_call_opn(f, tag, regtype, regid, toss, numregs, i)
590                i += 1
591        for regtype, regid, toss, numregs in regs:
592            if hex_common.is_read(regid):
593                if hex_common.is_hvx_reg(regtype) and hex_common.is_readwrite(regid):
594                    continue
595                gen_helper_call_opn(f, tag, regtype, regid, toss, numregs, i)
596                i += 1
597        for immlett, bits, immshift in imms:
598            gen_helper_call_imm(f, immlett)
599
600        if hex_common.need_pkt_has_multi_cof(tag):
601            f.write(", pkt_has_multi_cof")
602        if hex_common.need_pkt_need_commit(tag):
603            f.write(", pkt_need_commit")
604        if hex_common.need_PC(tag):
605            f.write(", PC")
606        if hex_common.helper_needs_next_PC(tag):
607            f.write(", next_PC")
608        if hex_common.need_slot(tag):
609            f.write(", slotval")
610        if hex_common.need_part1(tag):
611            f.write(", part1")
612        f.write(");\n")
613
614    ## Write all the outputs
615    for regtype, regid, toss, numregs in regs:
616        if hex_common.is_written(regid):
617            genptr_dst_write_opn(f, regtype, regid, tag)
618
619    f.write("}\n\n")
620
621
622def gen_def_tcg_func(f, tag, tagregs, tagimms):
623    regs = tagregs[tag]
624    imms = tagimms[tag]
625
626    gen_tcg_func(f, tag, regs, imms)
627
628
629def main():
630    hex_common.read_semantics_file(sys.argv[1])
631    hex_common.read_attribs_file(sys.argv[2])
632    hex_common.read_overrides_file(sys.argv[3])
633    hex_common.read_overrides_file(sys.argv[4])
634    hex_common.calculate_attribs()
635    ## Whether or not idef-parser is enabled is
636    ## determined by the number of arguments to
637    ## this script:
638    ##
639    ##   5 args. -> not enabled,
640    ##   6 args. -> idef-parser enabled.
641    ##
642    ## The 6:th arg. then holds a list of the successfully
643    ## parsed instructions.
644    is_idef_parser_enabled = len(sys.argv) > 6
645    if is_idef_parser_enabled:
646        hex_common.read_idef_parser_enabled_file(sys.argv[5])
647    tagregs = hex_common.get_tagregs()
648    tagimms = hex_common.get_tagimms()
649
650    output_file = sys.argv[-1]
651    with open(output_file, "w") as f:
652        f.write("#ifndef HEXAGON_TCG_FUNCS_H\n")
653        f.write("#define HEXAGON_TCG_FUNCS_H\n\n")
654        if is_idef_parser_enabled:
655            f.write('#include "idef-generated-emitter.h.inc"\n\n')
656
657        for tag in hex_common.tags:
658            ## Skip the priv instructions
659            if "A_PRIV" in hex_common.attribdict[tag]:
660                continue
661            ## Skip the guest instructions
662            if "A_GUEST" in hex_common.attribdict[tag]:
663                continue
664            ## Skip the diag instructions
665            if tag == "Y6_diag":
666                continue
667            if tag == "Y6_diag0":
668                continue
669            if tag == "Y6_diag1":
670                continue
671
672            gen_def_tcg_func(f, tag, tagregs, tagimms)
673
674        f.write("#endif    /* HEXAGON_TCG_FUNCS_H */\n")
675
676
677if __name__ == "__main__":
678    main()
679