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