forked from mirror/qemu
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
174 lines
6.2 KiB
Python
174 lines
6.2 KiB
Python
#!/usr/bin/env python3
|
|
|
|
##
|
|
## Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
|
##
|
|
## This program is free software; you can redistribute it and/or modify
|
|
## it under the terms of the GNU General Public License as published by
|
|
## the Free Software Foundation; either version 2 of the License, or
|
|
## (at your option) any later version.
|
|
##
|
|
## This program is distributed in the hope that it will be useful,
|
|
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
## GNU General Public License for more details.
|
|
##
|
|
## You should have received a copy of the GNU General Public License
|
|
## along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
##
|
|
|
|
import sys
|
|
import re
|
|
import string
|
|
import hex_common
|
|
|
|
##
|
|
## Generate data for printing each instruction (format string + operands)
|
|
##
|
|
def regprinter(m):
|
|
str = m.group(1)
|
|
str += ":".join(["%d"]*len(m.group(2)))
|
|
str += m.group(3)
|
|
if ('S' in m.group(1)) and (len(m.group(2)) == 1):
|
|
str += "/%s"
|
|
elif ('C' in m.group(1)) and (len(m.group(2)) == 1):
|
|
str += "/%s"
|
|
return str
|
|
|
|
def spacify(s):
|
|
# Regular expression that matches any operator that contains '=' character:
|
|
opswithequal_re = '[-+^&|!<>=]?='
|
|
# Regular expression that matches any assignment operator.
|
|
assignment_re = '[-+^&|]?='
|
|
|
|
# Out of the operators that contain the = sign, if the operator is also an
|
|
# assignment, spaces will be added around it, unless it's enclosed within
|
|
# parentheses, or spaces are already present.
|
|
|
|
equals = re.compile(opswithequal_re)
|
|
assign = re.compile(assignment_re)
|
|
|
|
slen = len(s)
|
|
paren_count = {}
|
|
i = 0
|
|
pc = 0
|
|
while i < slen:
|
|
c = s[i]
|
|
if c == '(':
|
|
pc += 1
|
|
elif c == ')':
|
|
pc -= 1
|
|
paren_count[i] = pc
|
|
i += 1
|
|
|
|
# Iterate over all operators that contain the equal sign. If any
|
|
# match is also an assignment operator, add spaces around it if
|
|
# the parenthesis count is 0.
|
|
pos = 0
|
|
out = []
|
|
for m in equals.finditer(s):
|
|
ms = m.start()
|
|
me = m.end()
|
|
# t is the string that matched opswithequal_re.
|
|
t = m.string[ms:me]
|
|
out += s[pos:ms]
|
|
pos = me
|
|
if paren_count[ms] == 0:
|
|
# Check if the entire string t is an assignment.
|
|
am = assign.match(t)
|
|
if am and len(am.group(0)) == me-ms:
|
|
# Don't add spaces if they are already there.
|
|
if ms > 0 and s[ms-1] != ' ':
|
|
out.append(' ')
|
|
out += t
|
|
if me < slen and s[me] != ' ':
|
|
out.append(' ')
|
|
continue
|
|
# If this is not an assignment, just append it to the output
|
|
# string.
|
|
out += t
|
|
|
|
# Append the remaining part of the string.
|
|
out += s[pos:len(s)]
|
|
return ''.join(out)
|
|
|
|
def main():
|
|
hex_common.read_semantics_file(sys.argv[1])
|
|
hex_common.read_attribs_file(sys.argv[2])
|
|
|
|
immext_casere = re.compile(r'IMMEXT\(([A-Za-z])')
|
|
|
|
with open(sys.argv[3], 'w') as f:
|
|
for tag in hex_common.tags:
|
|
if not hex_common.behdict[tag]: continue
|
|
extendable_upper_imm = False
|
|
extendable_lower_imm = False
|
|
m = immext_casere.search(hex_common.semdict[tag])
|
|
if m:
|
|
if m.group(1).isupper():
|
|
extendable_upper_imm = True
|
|
else:
|
|
extendable_lower_imm = True
|
|
beh = hex_common.behdict[tag]
|
|
beh = hex_common.regre.sub(regprinter,beh)
|
|
beh = hex_common.absimmre.sub(r"#%s0x%x",beh)
|
|
beh = hex_common.relimmre.sub(r"PC+%s%d",beh)
|
|
beh = spacify(beh)
|
|
# Print out a literal "%s" at the end, used to match empty string
|
|
# so C won't complain at us
|
|
if ("A_VECX" in hex_common.attribdict[tag]):
|
|
macname = "DEF_VECX_PRINTINFO"
|
|
else: macname = "DEF_PRINTINFO"
|
|
f.write('%s(%s,"%s%%s"' % (macname,tag,beh))
|
|
regs_or_imms = \
|
|
hex_common.reg_or_immre.findall(hex_common.behdict[tag])
|
|
ri = 0
|
|
seenregs = {}
|
|
for allregs,a,b,c,d,allimm,immlett,bits,immshift in regs_or_imms:
|
|
if a:
|
|
#register
|
|
if b in seenregs:
|
|
regno = seenregs[b]
|
|
else:
|
|
regno = ri
|
|
if len(b) == 1:
|
|
f.write(', insn->regno[%d]' % regno)
|
|
if 'S' in a:
|
|
f.write(', sreg2str(insn->regno[%d])' % regno)
|
|
elif 'C' in a:
|
|
f.write(', creg2str(insn->regno[%d])' % regno)
|
|
elif len(b) == 2:
|
|
f.write(', insn->regno[%d] + 1, insn->regno[%d]' % \
|
|
(regno,regno))
|
|
else:
|
|
print("Put some stuff to handle quads here")
|
|
if b not in seenregs:
|
|
seenregs[b] = ri
|
|
ri += 1
|
|
else:
|
|
#immediate
|
|
if (immlett.isupper()):
|
|
if extendable_upper_imm:
|
|
if immlett in 'rR':
|
|
f.write(',insn->extension_valid?"##":""')
|
|
else:
|
|
f.write(',insn->extension_valid?"#":""')
|
|
else:
|
|
f.write(',""')
|
|
ii = 1
|
|
else:
|
|
if extendable_lower_imm:
|
|
if immlett in 'rR':
|
|
f.write(',insn->extension_valid?"##":""')
|
|
else:
|
|
f.write(',insn->extension_valid?"#":""')
|
|
else:
|
|
f.write(',""')
|
|
ii = 0
|
|
f.write(', insn->immed[%d]' % ii)
|
|
# append empty string so there is at least one more arg
|
|
f.write(',"")\n')
|
|
|
|
if __name__ == "__main__":
|
|
main()
|