Data for printing (disassembling) each instruction (format string + operands)

Signed-off-by: Taylor Simpson <tsimp...@quicinc.com>
---
 target/hexagon/do_qemu.py | 151 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 151 insertions(+)

diff --git a/target/hexagon/do_qemu.py b/target/hexagon/do_qemu.py
index 7520464..974d45e 100755
--- a/target/hexagon/do_qemu.py
+++ b/target/hexagon/do_qemu.py
@@ -896,3 +896,154 @@ realf.write(f.getvalue())
 realf.close()
 f.close()
 
+##
+## Generate the printinsn_generated.h file
+##     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
+
+# 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)
+
+def spacify(s):
+    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)
+
+immext_casere = re.compile(r'IMMEXT\(([A-Za-z])')
+
+f = StringIO()
+
+for tag in tags:
+    if not behdict[tag]: continue
+    extendable_upper_imm = False
+    extendable_lower_imm = False
+    m = immext_casere.search(semdict[tag])
+    if m:
+        if m.group(1).isupper():
+            extendable_upper_imm = True
+        else:
+            extendable_lower_imm = True
+    beh = behdict[tag]
+    beh = regre.sub(regprinter,beh)
+    beh = absimmre.sub(r"#%s0x%x",beh)
+    beh = 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 attribdict[tag]): macname = "DEF_VECX_PRINTINFO"
+    else: macname = "DEF_PRINTINFO"
+    f.write('%s(%s,"%s%%s"' % (macname,tag,beh))
+    regs_or_imms = reg_or_immre.findall(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(',REGNO(%d)' % regno)
+                if 'S' in a:
+                    f.write(',sreg2str(REGNO(%d))' % regno)
+                elif 'C' in a:
+                    f.write(',creg2str(REGNO(%d))' % regno)
+            elif len(b) == 2:
+                f.write(',REGNO(%d)+1,REGNO(%d)' % (regno,regno))
+            elif len(b) == 4:
+                f.write(',REGNO(%d)^3,REGNO(%d)^2,REGNO(%d)^1,REGNO(%d)' % \
+                        (regno,regno,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(',IMMNO(%d)' % ii)
+    # append empty string so there is at least one more arg
+    f.write(',"")\n')
+
+realf = open('printinsn_generated.h','w')
+realf.write(f.getvalue())
+realf.close()
+f.close()
+
+
-- 
2.7.4

Reply via email to