1#!/usr/bin/env python3 2 3## 4## Copyright(c) 2019-2023 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## 27## Generate data for printing each instruction (format string + operands) 28## 29def regprinter(m): 30 str = m.group(1) 31 str += ":".join(["%d"] * len(m.group(2))) 32 str += m.group(3) 33 if ("S" in m.group(1)) and (len(m.group(2)) == 1): 34 str += "/%s" 35 elif ("C" in m.group(1)) and (len(m.group(2)) == 1): 36 str += "/%s" 37 return str 38 39 40def spacify(s): 41 # Regular expression that matches any operator that contains '=' character: 42 opswithequal_re = "[-+^&|!<>=]?=" 43 # Regular expression that matches any assignment operator. 44 assignment_re = "[-+^&|]?=" 45 46 # Out of the operators that contain the = sign, if the operator is also an 47 # assignment, spaces will be added around it, unless it's enclosed within 48 # parentheses, or spaces are already present. 49 50 equals = re.compile(opswithequal_re) 51 assign = re.compile(assignment_re) 52 53 slen = len(s) 54 paren_count = {} 55 i = 0 56 pc = 0 57 while i < slen: 58 c = s[i] 59 if c == "(": 60 pc += 1 61 elif c == ")": 62 pc -= 1 63 paren_count[i] = pc 64 i += 1 65 66 # Iterate over all operators that contain the equal sign. If any 67 # match is also an assignment operator, add spaces around it if 68 # the parenthesis count is 0. 69 pos = 0 70 out = [] 71 for m in equals.finditer(s): 72 ms = m.start() 73 me = m.end() 74 # t is the string that matched opswithequal_re. 75 t = m.string[ms:me] 76 out += s[pos:ms] 77 pos = me 78 if paren_count[ms] == 0: 79 # Check if the entire string t is an assignment. 80 am = assign.match(t) 81 if am and len(am.group(0)) == me - ms: 82 # Don't add spaces if they are already there. 83 if ms > 0 and s[ms - 1] != " ": 84 out.append(" ") 85 out += t 86 if me < slen and s[me] != " ": 87 out.append(" ") 88 continue 89 # If this is not an assignment, just append it to the output 90 # string. 91 out += t 92 93 # Append the remaining part of the string. 94 out += s[pos : len(s)] 95 return "".join(out) 96 97 98def main(): 99 hex_common.read_semantics_file(sys.argv[1]) 100 hex_common.read_attribs_file(sys.argv[2]) 101 102 immext_casere = re.compile(r"IMMEXT\(([A-Za-z])") 103 104 with open(sys.argv[3], "w") as f: 105 for tag in hex_common.tags: 106 if not hex_common.behdict[tag]: 107 continue 108 extendable_upper_imm = False 109 extendable_lower_imm = False 110 m = immext_casere.search(hex_common.semdict[tag]) 111 if m: 112 if m.group(1).isupper(): 113 extendable_upper_imm = True 114 else: 115 extendable_lower_imm = True 116 beh = hex_common.behdict[tag] 117 beh = hex_common.regre.sub(regprinter, beh) 118 beh = hex_common.absimmre.sub(r"#%s0x%x", beh) 119 beh = hex_common.relimmre.sub(r"PC+%s%d", beh) 120 beh = spacify(beh) 121 # Print out a literal "%s" at the end, used to match empty string 122 # so C won't complain at us 123 if "A_VECX" in hex_common.attribdict[tag]: 124 macname = "DEF_VECX_PRINTINFO" 125 else: 126 macname = "DEF_PRINTINFO" 127 f.write(f'{macname}({tag},"{beh}%s"') 128 regs_or_imms = hex_common.reg_or_immre.findall(hex_common.behdict[tag]) 129 ri = 0 130 seenregs = {} 131 for allregs, a, b, c, d, allimm, immlett, bits, immshift in regs_or_imms: 132 if a: 133 # register 134 if b in seenregs: 135 regno = seenregs[b] 136 else: 137 regno = ri 138 if len(b) == 1: 139 f.write(f", insn->regno[{regno}]") 140 if "S" in a: 141 f.write(f", sreg2str(insn->regno[{regno}])") 142 elif "C" in a: 143 f.write(f", creg2str(insn->regno[{regno}])") 144 elif len(b) == 2: 145 f.write(f", insn->regno[{regno}] + 1" f", insn->regno[{regno}]") 146 else: 147 print("Put some stuff to handle quads here") 148 if b not in seenregs: 149 seenregs[b] = ri 150 ri += 1 151 else: 152 # immediate 153 if immlett.isupper(): 154 if extendable_upper_imm: 155 if immlett in "rR": 156 f.write(',insn->extension_valid?"##":""') 157 else: 158 f.write(',insn->extension_valid?"#":""') 159 else: 160 f.write(',""') 161 ii = 1 162 else: 163 if extendable_lower_imm: 164 if immlett in "rR": 165 f.write(',insn->extension_valid?"##":""') 166 else: 167 f.write(',insn->extension_valid?"#":""') 168 else: 169 f.write(',""') 170 ii = 0 171 f.write(f", insn->immed[{ii}]") 172 # append empty string so there is at least one more arg 173 f.write(',"")\n') 174 175 176if __name__ == "__main__": 177 main() 178