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 20import sys 21import re 22import string 23import hex_common 24 25## 26## Generate data for printing each instruction (format string + operands) 27## 28def 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 38def 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 95def 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 172if __name__ == "__main__": 173 main()