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_protos.py (4974B)


      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_prototype
     27##
     28def_helper_types = {
     29    'N' : 's32',
     30    'O' : 's32',
     31    'P' : 's32',
     32    'M' : 's32',
     33    'C' : 's32',
     34    'R' : 's32',
     35    'V' : 'ptr',
     36    'Q' : 'ptr'
     37}
     38
     39def_helper_types_pair = {
     40    'R' : 's64',
     41    'C' : 's64',
     42    'S' : 's64',
     43    'G' : 's64',
     44    'V' : 'ptr',
     45    'Q' : 'ptr'
     46}
     47
     48def gen_def_helper_opn(f, tag, regtype, regid, toss, numregs, i):
     49    if (hex_common.is_pair(regid)):
     50        f.write(", %s" % (def_helper_types_pair[regtype]))
     51    elif (hex_common.is_single(regid)):
     52        f.write(", %s" % (def_helper_types[regtype]))
     53    else:
     54        print("Bad register parse: ",regtype,regid,toss,numregs)
     55
     56##
     57## Generate the DEF_HELPER prototype for an instruction
     58##     For A2_add: Rd32=add(Rs32,Rt32)
     59##     We produce:
     60##         DEF_HELPER_3(A2_add, s32, env, s32, s32)
     61##
     62def gen_helper_prototype(f, tag, tagregs, tagimms):
     63    regs = tagregs[tag]
     64    imms = tagimms[tag]
     65
     66    numresults = 0
     67    numscalarresults = 0
     68    numscalarreadwrite = 0
     69    for regtype,regid,toss,numregs in regs:
     70        if (hex_common.is_written(regid)):
     71            numresults += 1
     72            if (hex_common.is_scalar_reg(regtype)):
     73                numscalarresults += 1
     74        if (hex_common.is_readwrite(regid)):
     75            if (hex_common.is_scalar_reg(regtype)):
     76                numscalarreadwrite += 1
     77
     78    if (numscalarresults > 1):
     79        ## The helper is bogus when there is more than one result
     80        f.write('DEF_HELPER_1(%s, void, env)\n' % tag)
     81    else:
     82        ## Figure out how many arguments the helper will take
     83        if (numscalarresults == 0):
     84            def_helper_size = len(regs)+len(imms)+numscalarreadwrite+1
     85            if hex_common.need_part1(tag): def_helper_size += 1
     86            if hex_common.need_slot(tag): def_helper_size += 1
     87            f.write('DEF_HELPER_%s(%s' % (def_helper_size, tag))
     88            ## The return type is void
     89            f.write(', void' )
     90        else:
     91            def_helper_size = len(regs)+len(imms)+numscalarreadwrite
     92            if hex_common.need_part1(tag): def_helper_size += 1
     93            if hex_common.need_slot(tag): def_helper_size += 1
     94            f.write('DEF_HELPER_%s(%s' % (def_helper_size, tag))
     95
     96        ## Generate the qemu DEF_HELPER type for each result
     97        i=0
     98        for regtype,regid,toss,numregs in regs:
     99            if (hex_common.is_written(regid)):
    100                gen_def_helper_opn(f, tag, regtype, regid, toss, numregs, i)
    101                i += 1
    102
    103        ## Put the env between the outputs and inputs
    104        f.write(', env' )
    105        i += 1
    106
    107        ## Generate the qemu type for each input operand (regs and immediates)
    108        for regtype,regid,toss,numregs in regs:
    109            if (hex_common.is_read(regid)):
    110                gen_def_helper_opn(f, tag, regtype, regid, toss, numregs, i)
    111                i += 1
    112        for immlett,bits,immshift in imms:
    113            f.write(", s32")
    114
    115        ## Add the arguments for the instruction slot and part1 (if needed)
    116        if hex_common.need_slot(tag): f.write(', i32' )
    117        if hex_common.need_part1(tag): f.write(' , i32' )
    118        f.write(')\n')
    119
    120def main():
    121    hex_common.read_semantics_file(sys.argv[1])
    122    hex_common.read_attribs_file(sys.argv[2])
    123    hex_common.read_overrides_file(sys.argv[3])
    124    hex_common.calculate_attribs()
    125    tagregs = hex_common.get_tagregs()
    126    tagimms = hex_common.get_tagimms()
    127
    128    with open(sys.argv[4], 'w') as f:
    129        for tag in hex_common.tags:
    130            ## Skip the priv instructions
    131            if ( "A_PRIV" in hex_common.attribdict[tag] ) :
    132                continue
    133            ## Skip the guest instructions
    134            if ( "A_GUEST" in hex_common.attribdict[tag] ) :
    135                continue
    136            ## Skip the diag instructions
    137            if ( tag == "Y6_diag" ) :
    138                continue
    139            if ( tag == "Y6_diag0" ) :
    140                continue
    141            if ( tag == "Y6_diag1" ) :
    142                continue
    143
    144            if ( hex_common.skip_qemu_helper(tag) ):
    145                continue
    146
    147            gen_helper_prototype(f, tag, tagregs, tagimms)
    148
    149if __name__ == "__main__":
    150    main()