OSDN Git Service

Merge tag 'for_upstream' of https://git.kernel.org/pub/scm/virt/kvm/mst/qemu into...
[qmiga/qemu.git] / target / hexagon / gen_printinsn.py
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
20 import sys
21 import re
22 import string
23 import hex_common
24
25
26 ##
27 ##     Generate data for printing each instruction (format string + operands)
28 ##
29 def 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
40 def 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
98 def 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
176 if __name__ == "__main__":
177     main()