1#!/usr/bin/env python3 2 3## 4## Copyright(c) 2019-2024 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 101 immext_casere = re.compile(r"IMMEXT\(([A-Za-z])") 102 103 with open(sys.argv[-1], "w") as f: 104 for tag in hex_common.tags: 105 if not hex_common.behdict[tag]: 106 continue 107 extendable_upper_imm = False 108 extendable_lower_imm = False 109 m = immext_casere.search(hex_common.semdict[tag]) 110 if m: 111 if m.group(1).isupper(): 112 extendable_upper_imm = True 113 else: 114 extendable_lower_imm = True 115 beh = hex_common.behdict[tag] 116 beh = hex_common.regre.sub(regprinter, beh) 117 beh = hex_common.absimmre.sub(r"#%s0x%x", beh) 118 beh = hex_common.relimmre.sub(r"PC+%s%d", beh) 119 beh = spacify(beh) 120 # Print out a literal "%s" at the end, used to match empty string 121 # so C won't complain at us 122 if "A_VECX" in hex_common.attribdict[tag]: 123 macname = "DEF_VECX_PRINTINFO" 124 else: 125 macname = "DEF_PRINTINFO" 126 f.write(f'{macname}({tag},"{beh}%s"') 127 regs_or_imms = hex_common.reg_or_immre.findall(hex_common.behdict[tag]) 128 ri = 0 129 seenregs = {} 130 for allregs, a, b, c, d, allimm, immlett, bits, immshift in regs_or_imms: 131 if a: 132 # register 133 if b in seenregs: 134 regno = seenregs[b] 135 else: 136 regno = ri 137 if len(b) == 1: 138 f.write(f", insn->regno[{regno}]") 139 if "S" in a: 140 f.write(f", sreg2str(insn->regno[{regno}])") 141 elif "C" in a: 142 f.write(f", creg2str(insn->regno[{regno}])") 143 elif len(b) == 2: 144 f.write(f", insn->regno[{regno}] + 1" f", insn->regno[{regno}]") 145 else: 146 print("Put some stuff to handle quads here") 147 if b not in seenregs: 148 seenregs[b] = ri 149 ri += 1 150 else: 151 # immediate 152 if immlett.isupper(): 153 if extendable_upper_imm: 154 if immlett in "rR": 155 f.write(',insn->extension_valid?"##":""') 156 else: 157 f.write(',insn->extension_valid?"#":""') 158 else: 159 f.write(',""') 160 ii = 1 161 else: 162 if extendable_lower_imm: 163 if immlett in "rR": 164 f.write(',insn->extension_valid?"##":""') 165 else: 166 f.write(',insn->extension_valid?"#":""') 167 else: 168 f.write(',""') 169 ii = 0 170 f.write(f", insn->immed[{ii}]") 171 # append empty string so there is at least one more arg 172 f.write(',"")\n') 173 174 175if __name__ == "__main__": 176 main() 177