qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

gen_tcg_funcs.py (30168B)


      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 
     20 import sys
     21 import re
     22 import string
     23 import hex_common
     24 
     25 ##
     26 ## Helpers for gen_tcg_func
     27 ##
     28 def 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 
     35 def gen_free_ea_tcg(f):
     36     f.write("    tcg_temp_free(EA);\n")
     37 
     38 def 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 
     57 def 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 
     72 def 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 
    212 def 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 
    243 def 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 
    256 def 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 
    264 def 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 
    305 def 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 
    318 def 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 
    331 def 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 
    402 def 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 
    415 def 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 
    428 def 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 
    442 def 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 
    446 def gen_helper_call_imm(f,immlett):
    447     f.write(", tcgv_%s" % hex_common.imm_name(immlett))
    448 
    449 def 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 
    459 def 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 
    495 def 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 
    538 def 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             elif (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 ##
    586 def 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 
    667 def 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 
    673 def 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 
    705 if __name__ == "__main__":
    706     main()