cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

gen_tcg_funcs.py (19219B)


      1#!/usr/bin/env python3
      2
      3##
      4##  Copyright(c) 2019-2021 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    else:
    123        print("Bad register parse: ", regtype, regid)
    124
    125def genptr_decl_new(f,regtype,regid,regno):
    126    if (regtype == "N"):
    127        if (regid in {"s", "t"}):
    128            f.write("    TCGv %s%sN = hex_new_value[insn->regno[%d]];\n" % \
    129                (regtype, regid, regno))
    130        else:
    131            print("Bad register parse: ", regtype, regid)
    132    elif (regtype == "P"):
    133        if (regid in {"t", "u", "v"}):
    134            f.write("    TCGv %s%sN = hex_new_pred_value[insn->regno[%d]];\n" % \
    135                (regtype, regid, regno))
    136        else:
    137            print("Bad register parse: ", regtype, regid)
    138    else:
    139        print("Bad register parse: ", regtype, regid)
    140
    141def genptr_decl_opn(f, tag, regtype, regid, toss, numregs, i):
    142    if (hex_common.is_pair(regid)):
    143        genptr_decl(f, tag, regtype, regid, i)
    144    elif (hex_common.is_single(regid)):
    145        if hex_common.is_old_val(regtype, regid, tag):
    146            genptr_decl(f,tag, regtype, regid, i)
    147        elif hex_common.is_new_val(regtype, regid, tag):
    148            genptr_decl_new(f,regtype,regid,i)
    149        else:
    150            print("Bad register parse: ",regtype,regid,toss,numregs)
    151    else:
    152        print("Bad register parse: ",regtype,regid,toss,numregs)
    153
    154def genptr_decl_imm(f,immlett):
    155    if (immlett.isupper()):
    156        i = 1
    157    else:
    158        i = 0
    159    f.write("    int %s = insn->immed[%d];\n" % \
    160        (hex_common.imm_name(immlett), i))
    161
    162def genptr_free(f,regtype,regid,regno):
    163    if (regtype == "R"):
    164        if (regid in {"dd", "ss", "tt", "xx", "yy"}):
    165            f.write("    tcg_temp_free_i64(%s%sV);\n" % (regtype, regid))
    166        elif (regid in {"d", "e", "x", "y"}):
    167            f.write("    tcg_temp_free(%s%sV);\n" % (regtype, regid))
    168        elif (regid not in {"s", "t", "u", "v"}):
    169            print("Bad register parse: ",regtype,regid)
    170    elif (regtype == "P"):
    171        if (regid in {"d", "e", "x"}):
    172            f.write("    tcg_temp_free(%s%sV);\n" % (regtype, regid))
    173        elif (regid not in {"s", "t", "u", "v"}):
    174            print("Bad register parse: ",regtype,regid)
    175    elif (regtype == "C"):
    176        if (regid in {"dd", "ss"}):
    177            f.write("    tcg_temp_free_i64(%s%sV);\n" % (regtype, regid))
    178        elif (regid in {"d", "s"}):
    179            f.write("    tcg_temp_free(%s%sV);\n" % (regtype, regid))
    180        else:
    181            print("Bad register parse: ",regtype,regid)
    182    elif (regtype == "M"):
    183        if (regid != "u"):
    184            print("Bad register parse: ", regtype, regid)
    185    else:
    186        print("Bad register parse: ", regtype, regid)
    187
    188def genptr_free_new(f,regtype,regid,regno):
    189    if (regtype == "N"):
    190        if (regid not in {"s", "t"}):
    191            print("Bad register parse: ", regtype, regid)
    192    elif (regtype == "P"):
    193        if (regid not in {"t", "u", "v"}):
    194            print("Bad register parse: ", regtype, regid)
    195    else:
    196        print("Bad register parse: ", regtype, regid)
    197
    198def genptr_free_opn(f,regtype,regid,i,tag):
    199    if (hex_common.is_pair(regid)):
    200        genptr_free(f,regtype,regid,i)
    201    elif (hex_common.is_single(regid)):
    202        if hex_common.is_old_val(regtype, regid, tag):
    203            genptr_free(f,regtype,regid,i)
    204        elif hex_common.is_new_val(regtype, regid, tag):
    205            genptr_free_new(f,regtype,regid,i)
    206        else:
    207            print("Bad register parse: ",regtype,regid,toss,numregs)
    208    else:
    209        print("Bad register parse: ",regtype,regid,toss,numregs)
    210
    211def genptr_src_read(f,regtype,regid):
    212    if (regtype == "R"):
    213        if (regid in {"ss", "tt", "xx", "yy"}):
    214            f.write("    tcg_gen_concat_i32_i64(%s%sV, hex_gpr[%s%sN],\n" % \
    215                (regtype, regid, regtype, regid))
    216            f.write("                                 hex_gpr[%s%sN + 1]);\n" % \
    217                (regtype, regid))
    218        elif (regid in {"x", "y"}):
    219            f.write("    tcg_gen_mov_tl(%s%sV, hex_gpr[%s%sN]);\n" % \
    220                (regtype,regid,regtype,regid))
    221        elif (regid not in {"s", "t", "u", "v"}):
    222            print("Bad register parse: ", regtype, regid)
    223    elif (regtype == "P"):
    224        if (regid == "x"):
    225            f.write("    tcg_gen_mov_tl(%s%sV, hex_pred[%s%sN]);\n" % \
    226                (regtype, regid, regtype, regid))
    227        elif (regid not in {"s", "t", "u", "v"}):
    228            print("Bad register parse: ", regtype, regid)
    229    elif (regtype == "C"):
    230        if (regid == "ss"):
    231            f.write("    gen_read_ctrl_reg_pair(ctx, %s%sN, %s%sV);\n" % \
    232                             (regtype, regid, regtype, regid))
    233        elif (regid == "s"):
    234            f.write("    gen_read_ctrl_reg(ctx, %s%sN, %s%sV);\n" % \
    235                             (regtype, regid, regtype, regid))
    236        else:
    237            print("Bad register parse: ", regtype, regid)
    238    elif (regtype == "M"):
    239        if (regid != "u"):
    240            print("Bad register parse: ", regtype, regid)
    241    else:
    242        print("Bad register parse: ", regtype, regid)
    243
    244def genptr_src_read_new(f,regtype,regid):
    245    if (regtype == "N"):
    246        if (regid not in {"s", "t"}):
    247            print("Bad register parse: ", regtype, regid)
    248    elif (regtype == "P"):
    249        if (regid not in {"t", "u", "v"}):
    250            print("Bad register parse: ", regtype, regid)
    251    else:
    252        print("Bad register parse: ", regtype, regid)
    253
    254def genptr_src_read_opn(f,regtype,regid,tag):
    255    if (hex_common.is_pair(regid)):
    256        genptr_src_read(f,regtype,regid)
    257    elif (hex_common.is_single(regid)):
    258        if hex_common.is_old_val(regtype, regid, tag):
    259            genptr_src_read(f,regtype,regid)
    260        elif hex_common.is_new_val(regtype, regid, tag):
    261            genptr_src_read_new(f,regtype,regid)
    262        else:
    263            print("Bad register parse: ",regtype,regid,toss,numregs)
    264    else:
    265        print("Bad register parse: ",regtype,regid,toss,numregs)
    266
    267def gen_helper_call_opn(f, tag, regtype, regid, toss, numregs, i):
    268    if (i > 0): f.write(", ")
    269    if (hex_common.is_pair(regid)):
    270        f.write("%s%sV" % (regtype,regid))
    271    elif (hex_common.is_single(regid)):
    272        if hex_common.is_old_val(regtype, regid, tag):
    273            f.write("%s%sV" % (regtype,regid))
    274        elif hex_common.is_new_val(regtype, regid, tag):
    275            f.write("%s%sN" % (regtype,regid))
    276        else:
    277            print("Bad register parse: ",regtype,regid,toss,numregs)
    278    else:
    279        print("Bad register parse: ",regtype,regid,toss,numregs)
    280
    281def gen_helper_decl_imm(f,immlett):
    282    f.write("    TCGv tcgv_%s = tcg_const_tl(%s);\n" % \
    283        (hex_common.imm_name(immlett), hex_common.imm_name(immlett)))
    284
    285def gen_helper_call_imm(f,immlett):
    286    f.write(", tcgv_%s" % hex_common.imm_name(immlett))
    287
    288def gen_helper_free_imm(f,immlett):
    289    f.write("    tcg_temp_free(tcgv_%s);\n" % hex_common.imm_name(immlett))
    290
    291def genptr_dst_write_pair(f, tag, regtype, regid):
    292    if ('A_CONDEXEC' in hex_common.attribdict[tag]):
    293        f.write("    gen_log_predicated_reg_write_pair(%s%sN, %s%sV, insn->slot);\n" % \
    294            (regtype, regid, regtype, regid))
    295    else:
    296        f.write("    gen_log_reg_write_pair(%s%sN, %s%sV);\n" % \
    297            (regtype, regid, regtype, regid))
    298    f.write("    ctx_log_reg_write_pair(ctx, %s%sN);\n" % \
    299        (regtype, regid))
    300
    301def genptr_dst_write(f, tag, regtype, regid):
    302    if (regtype == "R"):
    303        if (regid in {"dd", "xx", "yy"}):
    304            genptr_dst_write_pair(f, tag, regtype, regid)
    305        elif (regid in {"d", "e", "x", "y"}):
    306            if ('A_CONDEXEC' in hex_common.attribdict[tag]):
    307                f.write("    gen_log_predicated_reg_write(%s%sN, %s%sV,\n" % \
    308                    (regtype, regid, regtype, regid))
    309                f.write("                                 insn->slot);\n")
    310            else:
    311                f.write("    gen_log_reg_write(%s%sN, %s%sV);\n" % \
    312                    (regtype, regid, regtype, regid))
    313            f.write("    ctx_log_reg_write(ctx, %s%sN);\n" % \
    314                (regtype, regid))
    315        else:
    316            print("Bad register parse: ", regtype, regid)
    317    elif (regtype == "P"):
    318        if (regid in {"d", "e", "x"}):
    319            f.write("    gen_log_pred_write(ctx, %s%sN, %s%sV);\n" % \
    320                (regtype, regid, regtype, regid))
    321            f.write("    ctx_log_pred_write(ctx, %s%sN);\n" % \
    322                (regtype, regid))
    323        else:
    324            print("Bad register parse: ", regtype, regid)
    325    elif (regtype == "C"):
    326        if (regid == "dd"):
    327            f.write("    gen_write_ctrl_reg_pair(ctx, %s%sN, %s%sV);\n" % \
    328                             (regtype, regid, regtype, regid))
    329        elif (regid == "d"):
    330            f.write("    gen_write_ctrl_reg(ctx, %s%sN, %s%sV);\n" % \
    331                             (regtype, regid, regtype, regid))
    332        else:
    333            print("Bad register parse: ", regtype, regid)
    334    else:
    335        print("Bad register parse: ", regtype, regid)
    336
    337def genptr_dst_write_opn(f,regtype, regid, tag):
    338    if (hex_common.is_pair(regid)):
    339        genptr_dst_write(f, tag, regtype, regid)
    340    elif (hex_common.is_single(regid)):
    341        genptr_dst_write(f, tag, regtype, regid)
    342    else:
    343        print("Bad register parse: ",regtype,regid,toss,numregs)
    344
    345##
    346## Generate the TCG code to call the helper
    347##     For A2_add: Rd32=add(Rs32,Rt32), { RdV=RsV+RtV;}
    348##     We produce:
    349##    static void generate_A2_add()
    350##                    CPUHexagonState *env
    351##                    DisasContext *ctx,
    352##                    Insn *insn,
    353##                    Packet *pkt)
    354##       {
    355##           TCGv RdV = tcg_temp_local_new();
    356##           const int RdN = insn->regno[0];
    357##           TCGv RsV = hex_gpr[insn->regno[1]];
    358##           TCGv RtV = hex_gpr[insn->regno[2]];
    359##           <GEN>
    360##           gen_log_reg_write(RdN, RdV);
    361##           ctx_log_reg_write(ctx, RdN);
    362##           tcg_temp_free(RdV);
    363##       }
    364##
    365##       where <GEN> depends on hex_common.skip_qemu_helper(tag)
    366##       if hex_common.skip_qemu_helper(tag) is True
    367##       <GEN>  is fGEN_TCG_A2_add({ RdV=RsV+RtV;});
    368##       if hex_common.skip_qemu_helper(tag) is False
    369##       <GEN>  is gen_helper_A2_add(RdV, cpu_env, RsV, RtV);
    370##
    371def gen_tcg_func(f, tag, regs, imms):
    372    f.write("static void generate_%s(\n" %tag)
    373    f.write("                CPUHexagonState *env,\n")
    374    f.write("                DisasContext *ctx,\n")
    375    f.write("                Insn *insn,\n")
    376    f.write("                Packet *pkt)\n")
    377    f.write('{\n')
    378    if hex_common.need_ea(tag): gen_decl_ea_tcg(f, tag)
    379    i=0
    380    ## Declare all the operands (regs and immediates)
    381    for regtype,regid,toss,numregs in regs:
    382        genptr_decl_opn(f, tag, regtype, regid, toss, numregs, i)
    383        i += 1
    384    for immlett,bits,immshift in imms:
    385        genptr_decl_imm(f,immlett)
    386
    387    if 'A_PRIV' in hex_common.attribdict[tag]:
    388        f.write('    fCHECKFORPRIV();\n')
    389    if 'A_GUEST' in hex_common.attribdict[tag]:
    390        f.write('    fCHECKFORGUEST();\n')
    391
    392    ## Read all the inputs
    393    for regtype,regid,toss,numregs in regs:
    394        if (hex_common.is_read(regid)):
    395            genptr_src_read_opn(f,regtype,regid,tag)
    396
    397    if ( hex_common.skip_qemu_helper(tag) ):
    398        f.write("    fGEN_TCG_%s(%s);\n" % (tag, hex_common.semdict[tag]))
    399    else:
    400        ## Generate the call to the helper
    401        for immlett,bits,immshift in imms:
    402            gen_helper_decl_imm(f,immlett)
    403        if hex_common.need_part1(tag):
    404            f.write("    TCGv part1 = tcg_const_tl(insn->part1);\n")
    405        if hex_common.need_slot(tag):
    406            f.write("    TCGv slot = tcg_constant_tl(insn->slot);\n")
    407        f.write("    gen_helper_%s(" % (tag))
    408        i=0
    409        ## If there is a scalar result, it is the return type
    410        for regtype,regid,toss,numregs in regs:
    411            if (hex_common.is_written(regid)):
    412                gen_helper_call_opn(f, tag, regtype, regid, toss, numregs, i)
    413                i += 1
    414        if (i > 0): f.write(", ")
    415        f.write("cpu_env")
    416        i=1
    417        for regtype,regid,toss,numregs in regs:
    418            if (hex_common.is_read(regid)):
    419                gen_helper_call_opn(f, tag, regtype, regid, toss, numregs, i)
    420                i += 1
    421        for immlett,bits,immshift in imms:
    422            gen_helper_call_imm(f,immlett)
    423
    424        if hex_common.need_slot(tag): f.write(", slot")
    425        if hex_common.need_part1(tag): f.write(", part1" )
    426        f.write(");\n")
    427        if hex_common.need_part1(tag):
    428            f.write("    tcg_temp_free(part1);\n")
    429        for immlett,bits,immshift in imms:
    430            gen_helper_free_imm(f,immlett)
    431
    432    ## Write all the outputs
    433    for regtype,regid,toss,numregs in regs:
    434        if (hex_common.is_written(regid)):
    435            genptr_dst_write_opn(f,regtype, regid, tag)
    436
    437    ## Free all the operands (regs and immediates)
    438    if hex_common.need_ea(tag): gen_free_ea_tcg(f)
    439    for regtype,regid,toss,numregs in regs:
    440        genptr_free_opn(f,regtype,regid,i,tag)
    441        i += 1
    442
    443    f.write("}\n\n")
    444
    445def gen_def_tcg_func(f, tag, tagregs, tagimms):
    446    regs = tagregs[tag]
    447    imms = tagimms[tag]
    448
    449    gen_tcg_func(f, tag, regs, imms)
    450
    451def main():
    452    hex_common.read_semantics_file(sys.argv[1])
    453    hex_common.read_attribs_file(sys.argv[2])
    454    hex_common.read_overrides_file(sys.argv[3])
    455    hex_common.calculate_attribs()
    456    tagregs = hex_common.get_tagregs()
    457    tagimms = hex_common.get_tagimms()
    458
    459    with open(sys.argv[4], 'w') as f:
    460        f.write("#ifndef HEXAGON_TCG_FUNCS_H\n")
    461        f.write("#define HEXAGON_TCG_FUNCS_H\n\n")
    462
    463        for tag in hex_common.tags:
    464            ## Skip the priv instructions
    465            if ( "A_PRIV" in hex_common.attribdict[tag] ) :
    466                continue
    467            ## Skip the guest instructions
    468            if ( "A_GUEST" in hex_common.attribdict[tag] ) :
    469                continue
    470            ## Skip the diag instructions
    471            if ( tag == "Y6_diag" ) :
    472                continue
    473            if ( tag == "Y6_diag0" ) :
    474                continue
    475            if ( tag == "Y6_diag1" ) :
    476                continue
    477
    478            gen_def_tcg_func(f, tag, tagregs, tagimms)
    479
    480        f.write("#endif    /* HEXAGON_TCG_FUNCS_H */\n")
    481
    482if __name__ == "__main__":
    483    main()