GitLab: Add "Bug" issue reporting template
[qemu.git] / target / hexagon / gen_printinsn.py
blob12737bf8a05f2c8e51dcb40512bc9bac32b5c939
1 #!/usr/bin/env python3
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.
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.
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/>.
20 import sys
21 import re
22 import string
23 import hex_common
26 ## Generate data for printing each instruction (format string + operands)
28 def 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
38 def 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 = '[-+^&|]?='
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.
48 equals = re.compile(opswithequal_re)
49 assign = re.compile(assignment_re)
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
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
91 # Append the remaining part of the string.
92 out += s[pos:len(s)]
93 return ''.join(out)
95 def main():
96 hex_common.read_semantics_file(sys.argv[1])
97 hex_common.read_attribs_file(sys.argv[2])
99 immext_casere = re.compile(r'IMMEXT\(([A-Za-z])')
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')
172 if __name__ == "__main__":
173 main()