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_helper_funcs.py (7622B)


      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_helper_function
     27##
     28def gen_decl_ea(f):
     29    f.write("    uint32_t EA;\n")
     30
     31def gen_helper_return_type(f,regtype,regid,regno):
     32    if regno > 1 : f.write(", ")
     33    f.write("int32_t")
     34
     35def gen_helper_return_type_pair(f,regtype,regid,regno):
     36    if regno > 1 : f.write(", ")
     37    f.write("int64_t")
     38
     39def gen_helper_arg(f,regtype,regid,regno):
     40    if regno > 0 : f.write(", " )
     41    f.write("int32_t %s%sV" % (regtype,regid))
     42
     43def gen_helper_arg_new(f,regtype,regid,regno):
     44    if regno >= 0 : f.write(", " )
     45    f.write("int32_t %s%sN" % (regtype,regid))
     46
     47def gen_helper_arg_pair(f,regtype,regid,regno):
     48    if regno >= 0 : f.write(", ")
     49    f.write("int64_t %s%sV" % (regtype,regid))
     50
     51def gen_helper_arg_opn(f,regtype,regid,i,tag):
     52    if (hex_common.is_pair(regid)):
     53        gen_helper_arg_pair(f,regtype,regid,i)
     54    elif (hex_common.is_single(regid)):
     55        if hex_common.is_old_val(regtype, regid, tag):
     56            gen_helper_arg(f,regtype,regid,i)
     57        elif hex_common.is_new_val(regtype, regid, tag):
     58            gen_helper_arg_new(f,regtype,regid,i)
     59        else:
     60            print("Bad register parse: ",regtype,regid,toss,numregs)
     61    else:
     62        print("Bad register parse: ",regtype,regid,toss,numregs)
     63
     64def gen_helper_arg_imm(f,immlett):
     65    f.write(", int32_t %s" % (hex_common.imm_name(immlett)))
     66
     67def gen_helper_dest_decl(f,regtype,regid,regno,subfield=""):
     68    f.write("    int32_t %s%sV%s = 0;\n" % \
     69        (regtype,regid,subfield))
     70
     71def gen_helper_dest_decl_pair(f,regtype,regid,regno,subfield=""):
     72    f.write("    int64_t %s%sV%s = 0;\n" % \
     73        (regtype,regid,subfield))
     74
     75def gen_helper_dest_decl_opn(f,regtype,regid,i):
     76    if (hex_common.is_pair(regid)):
     77        gen_helper_dest_decl_pair(f,regtype,regid,i)
     78    elif (hex_common.is_single(regid)):
     79        gen_helper_dest_decl(f,regtype,regid,i)
     80    else:
     81        print("Bad register parse: ",regtype,regid,toss,numregs)
     82
     83def gen_helper_return(f,regtype,regid,regno):
     84    f.write("    return %s%sV;\n" % (regtype,regid))
     85
     86def gen_helper_return_pair(f,regtype,regid,regno):
     87    f.write("    return %s%sV;\n" % (regtype,regid))
     88
     89def gen_helper_return_opn(f, regtype, regid, i):
     90    if (hex_common.is_pair(regid)):
     91        gen_helper_return_pair(f,regtype,regid,i)
     92    elif (hex_common.is_single(regid)):
     93        gen_helper_return(f,regtype,regid,i)
     94    else:
     95        print("Bad register parse: ",regtype,regid,toss,numregs)
     96
     97##
     98## Generate the TCG code to call the helper
     99##     For A2_add: Rd32=add(Rs32,Rt32), { RdV=RsV+RtV;}
    100##     We produce:
    101##       int32_t HELPER(A2_add)(CPUHexagonState *env, int32_t RsV, int32_t RtV)
    102##       {
    103##           uint32_t slot __attribute__(unused)) = 4;
    104##           int32_t RdV = 0;
    105##           { RdV=RsV+RtV;}
    106##           COUNT_HELPER(A2_add);
    107##           return RdV;
    108##       }
    109##
    110def gen_helper_function(f, tag, tagregs, tagimms):
    111    regs = tagregs[tag]
    112    imms = tagimms[tag]
    113
    114    numresults = 0
    115    numscalarresults = 0
    116    numscalarreadwrite = 0
    117    for regtype,regid,toss,numregs in regs:
    118        if (hex_common.is_written(regid)):
    119            numresults += 1
    120            if (hex_common.is_scalar_reg(regtype)):
    121                numscalarresults += 1
    122        if (hex_common.is_readwrite(regid)):
    123            if (hex_common.is_scalar_reg(regtype)):
    124                numscalarreadwrite += 1
    125
    126    if (numscalarresults > 1):
    127        ## The helper is bogus when there is more than one result
    128        f.write("void HELPER(%s)(CPUHexagonState *env) { BOGUS_HELPER(%s); }\n"
    129                % (tag, tag))
    130    else:
    131        ## The return type of the function is the type of the destination
    132        ## register
    133        i=0
    134        for regtype,regid,toss,numregs in regs:
    135            if (hex_common.is_written(regid)):
    136                if (hex_common.is_pair(regid)):
    137                    gen_helper_return_type_pair(f,regtype,regid,i)
    138                elif (hex_common.is_single(regid)):
    139                    gen_helper_return_type(f,regtype,regid,i)
    140                else:
    141                    print("Bad register parse: ",regtype,regid,toss,numregs)
    142            i += 1
    143
    144        if (numscalarresults == 0):
    145            f.write("void")
    146        f.write(" HELPER(%s)(CPUHexagonState *env" % tag)
    147
    148        i = 1
    149
    150        ## Arguments to the helper function are the source regs and immediates
    151        for regtype,regid,toss,numregs in regs:
    152            if (hex_common.is_read(regid)):
    153                gen_helper_arg_opn(f,regtype,regid,i,tag)
    154                i += 1
    155        for immlett,bits,immshift in imms:
    156            gen_helper_arg_imm(f,immlett)
    157            i += 1
    158        if hex_common.need_slot(tag):
    159            if i > 0: f.write(", ")
    160            f.write("uint32_t slot")
    161            i += 1
    162        if hex_common.need_part1(tag):
    163            if i > 0: f.write(", ")
    164            f.write("uint32_t part1")
    165        f.write(")\n{\n")
    166        if (not hex_common.need_slot(tag)):
    167            f.write("    uint32_t slot __attribute__((unused)) = 4;\n" )
    168        if hex_common.need_ea(tag): gen_decl_ea(f)
    169        ## Declare the return variable
    170        i=0
    171        for regtype,regid,toss,numregs in regs:
    172            if (hex_common.is_writeonly(regid)):
    173                gen_helper_dest_decl_opn(f,regtype,regid,i)
    174            i += 1
    175
    176        if 'A_FPOP' in hex_common.attribdict[tag]:
    177            f.write('    arch_fpop_start(env);\n');
    178
    179        f.write("    %s\n" % hex_common.semdict[tag])
    180
    181        if 'A_FPOP' in hex_common.attribdict[tag]:
    182            f.write('    arch_fpop_end(env);\n');
    183
    184        ## Save/return the return variable
    185        for regtype,regid,toss,numregs in regs:
    186            if (hex_common.is_written(regid)):
    187                gen_helper_return_opn(f, regtype, regid, i)
    188        f.write("}\n\n")
    189        ## End of the helper definition
    190
    191def main():
    192    hex_common.read_semantics_file(sys.argv[1])
    193    hex_common.read_attribs_file(sys.argv[2])
    194    hex_common.read_overrides_file(sys.argv[3])
    195    hex_common.calculate_attribs()
    196    tagregs = hex_common.get_tagregs()
    197    tagimms = hex_common.get_tagimms()
    198
    199    with open(sys.argv[4], 'w') as f:
    200        for tag in hex_common.tags:
    201            ## Skip the priv instructions
    202            if ( "A_PRIV" in hex_common.attribdict[tag] ) :
    203                continue
    204            ## Skip the guest instructions
    205            if ( "A_GUEST" in hex_common.attribdict[tag] ) :
    206                continue
    207            ## Skip the diag instructions
    208            if ( tag == "Y6_diag" ) :
    209                continue
    210            if ( tag == "Y6_diag0" ) :
    211                continue
    212            if ( tag == "Y6_diag1" ) :
    213                continue
    214            if ( hex_common.skip_qemu_helper(tag) ):
    215                continue
    216
    217            gen_helper_function(f, tag, tagregs, tagimms)
    218
    219if __name__ == "__main__":
    220    main()