#!/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 . ## 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()