qemu

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

gen_printinsn.py (6348B)


      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 
     20 import sys
     21 import re
     22 import string
     23 import hex_common
     24 
     25 ##
     26 ##     Generate data for printing each instruction (format string + operands)
     27 ##
     28 def regprinter(m):
     29     str = m.group(1)
     30     str += ":".join(["%d"]*len(m.group(2)))
     31     str += m.group(3)
     32     if ('S' in m.group(1)) and (len(m.group(2)) == 1):
     33         str += "/%s"
     34     elif ('C' in m.group(1)) and (len(m.group(2)) == 1):
     35         str += "/%s"
     36     return str
     37 
     38 def spacify(s):
     39     # Regular expression that matches any operator that contains '=' character:
     40     opswithequal_re = '[-+^&|!<>=]?='
     41     # Regular expression that matches any assignment operator.
     42     assignment_re = '[-+^&|]?='
     43 
     44     # Out of the operators that contain the = sign, if the operator is also an
     45     # assignment, spaces will be added around it, unless it's enclosed within
     46     # parentheses, or spaces are already present.
     47 
     48     equals = re.compile(opswithequal_re)
     49     assign = re.compile(assignment_re)
     50 
     51     slen = len(s)
     52     paren_count = {}
     53     i = 0
     54     pc = 0
     55     while i < slen:
     56         c = s[i]
     57         if c == '(':
     58             pc += 1
     59         elif c == ')':
     60             pc -= 1
     61         paren_count[i] = pc
     62         i += 1
     63 
     64     # Iterate over all operators that contain the equal sign. If any
     65     # match is also an assignment operator, add spaces around it if
     66     # the parenthesis count is 0.
     67     pos = 0
     68     out = []
     69     for m in equals.finditer(s):
     70         ms = m.start()
     71         me = m.end()
     72         # t is the string that matched opswithequal_re.
     73         t = m.string[ms:me]
     74         out += s[pos:ms]
     75         pos = me
     76         if paren_count[ms] == 0:
     77             # Check if the entire string t is an assignment.
     78             am = assign.match(t)
     79             if am and len(am.group(0)) == me-ms:
     80                 # Don't add spaces if they are already there.
     81                 if ms > 0 and s[ms-1] != ' ':
     82                     out.append(' ')
     83                 out += t
     84                 if me < slen and s[me] != ' ':
     85                     out.append(' ')
     86                 continue
     87         # If this is not an assignment, just append it to the output
     88         # string.
     89         out += t
     90 
     91     # Append the remaining part of the string.
     92     out += s[pos:len(s)]
     93     return ''.join(out)
     94 
     95 def main():
     96     hex_common.read_semantics_file(sys.argv[1])
     97     hex_common.read_attribs_file(sys.argv[2])
     98 
     99     immext_casere = re.compile(r'IMMEXT\(([A-Za-z])')
    100 
    101     with open(sys.argv[3], 'w') as f:
    102         for tag in hex_common.tags:
    103             if not hex_common.behdict[tag]: continue
    104             extendable_upper_imm = False
    105             extendable_lower_imm = False
    106             m = immext_casere.search(hex_common.semdict[tag])
    107             if m:
    108                 if m.group(1).isupper():
    109                     extendable_upper_imm = True
    110                 else:
    111                     extendable_lower_imm = True
    112             beh = hex_common.behdict[tag]
    113             beh = hex_common.regre.sub(regprinter,beh)
    114             beh = hex_common.absimmre.sub(r"#%s0x%x",beh)
    115             beh = hex_common.relimmre.sub(r"PC+%s%d",beh)
    116             beh = spacify(beh)
    117             # Print out a literal "%s" at the end, used to match empty string
    118             # so C won't complain at us
    119             if ("A_VECX" in hex_common.attribdict[tag]):
    120                 macname = "DEF_VECX_PRINTINFO"
    121             else: macname = "DEF_PRINTINFO"
    122             f.write('%s(%s,"%s%%s"' % (macname,tag,beh))
    123             regs_or_imms = \
    124                 hex_common.reg_or_immre.findall(hex_common.behdict[tag])
    125             ri = 0
    126             seenregs = {}
    127             for allregs,a,b,c,d,allimm,immlett,bits,immshift in regs_or_imms:
    128                 if a:
    129                     #register
    130                     if b in seenregs:
    131                         regno = seenregs[b]
    132                     else:
    133                         regno = ri
    134                     if len(b) == 1:
    135                         f.write(', insn->regno[%d]' % regno)
    136                         if 'S' in a:
    137                             f.write(', sreg2str(insn->regno[%d])' % regno)
    138                         elif 'C' in a:
    139                             f.write(', creg2str(insn->regno[%d])' % regno)
    140                     elif len(b) == 2:
    141                         f.write(', insn->regno[%d] + 1, insn->regno[%d]' % \
    142                             (regno,regno))
    143                     else:
    144                         print("Put some stuff to handle quads here")
    145                     if b not in seenregs:
    146                         seenregs[b] = ri
    147                         ri += 1
    148                 else:
    149                     #immediate
    150                     if (immlett.isupper()):
    151                         if extendable_upper_imm:
    152                             if immlett in 'rR':
    153                                 f.write(',insn->extension_valid?"##":""')
    154                             else:
    155                                 f.write(',insn->extension_valid?"#":""')
    156                         else:
    157                             f.write(',""')
    158                         ii = 1
    159                     else:
    160                         if extendable_lower_imm:
    161                             if immlett in 'rR':
    162                                 f.write(',insn->extension_valid?"##":""')
    163                             else:
    164                                 f.write(',insn->extension_valid?"#":""')
    165                         else:
    166                             f.write(',""')
    167                         ii = 0
    168                     f.write(', insn->immed[%d]' % ii)
    169             # append empty string so there is at least one more arg
    170             f.write(',"")\n')
    171 
    172 if __name__ == "__main__":
    173     main()