summaryrefslogtreecommitdiffstats
path: root/target/hexagon/gen_printinsn.py
diff options
context:
space:
mode:
authorTaylor Simpson2021-02-08 06:46:10 +0100
committerRichard Henderson2021-02-18 16:48:22 +0100
commit793958c93a08e933f9319b5e165767ea03849c58 (patch)
tree59a25bfed2e71c51031fb87809203db350baf266 /target/hexagon/gen_printinsn.py
parentHexagon (target/hexagon) generator phase 1 - C preprocessor for semantics (diff)
downloadqemu-793958c93a08e933f9319b5e165767ea03849c58.tar.gz
qemu-793958c93a08e933f9319b5e165767ea03849c58.tar.xz
qemu-793958c93a08e933f9319b5e165767ea03849c58.zip
Hexagon (target/hexagon) generator phase 2 - generate header files
Python scripts generate the following files helper_protos_generated.h.inc For each instruction we create DEF_HELPER function prototype helper_funcs_generated.c.inc For each instruction we create the helper function definition tcg_funcs_generated.c.inc For each instruction we create TCG code to generate call to helper tcg_func_table_generated.c.inc Table of function pointers indexed by opcode shortcode_generated.h.inc Generate a table of instruction "shortcode" semantics opcodes_def_generated.h.inc Gives a list of all the opcodes op_attribs_generated.h.inc Lists all the attributes associated with each instruction op_regs_generated.h.inc Lists the register and immediate operands for each instruction printinsn_generated.h.inc Data for printing (disassembling) each instruction (format string + operands) Signed-off-by: Taylor Simpson <tsimpson@quicinc.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <1612763186-18161-21-git-send-email-tsimpson@quicinc.com> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'target/hexagon/gen_printinsn.py')
-rwxr-xr-xtarget/hexagon/gen_printinsn.py173
1 files changed, 173 insertions, 0 deletions
diff --git a/target/hexagon/gen_printinsn.py b/target/hexagon/gen_printinsn.py
new file mode 100755
index 0000000000..12737bf8a0
--- /dev/null
+++ b/target/hexagon/gen_printinsn.py
@@ -0,0 +1,173 @@
+#!/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()