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