]>
Commit | Line | Data |
---|---|---|
793958c9 TS |
1 | #!/usr/bin/env python3 |
2 | ||
3 | ## | |
fb67c2bf | 4 | ## Copyright(c) 2019-2022 Qualcomm Innovation Center, Inc. All Rights Reserved. |
793958c9 TS |
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 | ## Helpers for gen_helper_prototype | |
27 | ## | |
28 | def_helper_types = { | |
29 | 'N' : 's32', | |
30 | 'O' : 's32', | |
31 | 'P' : 's32', | |
32 | 'M' : 's32', | |
33 | 'C' : 's32', | |
34 | 'R' : 's32', | |
35 | 'V' : 'ptr', | |
36 | 'Q' : 'ptr' | |
37 | } | |
38 | ||
39 | def_helper_types_pair = { | |
40 | 'R' : 's64', | |
41 | 'C' : 's64', | |
42 | 'S' : 's64', | |
43 | 'G' : 's64', | |
44 | 'V' : 'ptr', | |
45 | 'Q' : 'ptr' | |
46 | } | |
47 | ||
48 | def gen_def_helper_opn(f, tag, regtype, regid, toss, numregs, i): | |
49 | if (hex_common.is_pair(regid)): | |
50 | f.write(", %s" % (def_helper_types_pair[regtype])) | |
51 | elif (hex_common.is_single(regid)): | |
52 | f.write(", %s" % (def_helper_types[regtype])) | |
53 | else: | |
54 | print("Bad register parse: ",regtype,regid,toss,numregs) | |
55 | ||
56 | ## | |
57 | ## Generate the DEF_HELPER prototype for an instruction | |
58 | ## For A2_add: Rd32=add(Rs32,Rt32) | |
59 | ## We produce: | |
60 | ## DEF_HELPER_3(A2_add, s32, env, s32, s32) | |
61 | ## | |
62 | def gen_helper_prototype(f, tag, tagregs, tagimms): | |
63 | regs = tagregs[tag] | |
64 | imms = tagimms[tag] | |
65 | ||
66 | numresults = 0 | |
67 | numscalarresults = 0 | |
68 | numscalarreadwrite = 0 | |
69 | for regtype,regid,toss,numregs in regs: | |
70 | if (hex_common.is_written(regid)): | |
71 | numresults += 1 | |
72 | if (hex_common.is_scalar_reg(regtype)): | |
73 | numscalarresults += 1 | |
74 | if (hex_common.is_readwrite(regid)): | |
75 | if (hex_common.is_scalar_reg(regtype)): | |
76 | numscalarreadwrite += 1 | |
77 | ||
78 | if (numscalarresults > 1): | |
79 | ## The helper is bogus when there is more than one result | |
80 | f.write('DEF_HELPER_1(%s, void, env)\n' % tag) | |
81 | else: | |
82 | ## Figure out how many arguments the helper will take | |
83 | if (numscalarresults == 0): | |
84 | def_helper_size = len(regs)+len(imms)+numscalarreadwrite+1 | |
fb67c2bf | 85 | if hex_common.need_pkt_has_multi_cof(tag): def_helper_size += 1 |
793958c9 TS |
86 | if hex_common.need_part1(tag): def_helper_size += 1 |
87 | if hex_common.need_slot(tag): def_helper_size += 1 | |
40085901 | 88 | if hex_common.need_PC(tag): def_helper_size += 1 |
613653e5 | 89 | if hex_common.helper_needs_next_PC(tag): def_helper_size += 1 |
793958c9 TS |
90 | f.write('DEF_HELPER_%s(%s' % (def_helper_size, tag)) |
91 | ## The return type is void | |
92 | f.write(', void' ) | |
93 | else: | |
94 | def_helper_size = len(regs)+len(imms)+numscalarreadwrite | |
fb67c2bf | 95 | if hex_common.need_pkt_has_multi_cof(tag): def_helper_size += 1 |
793958c9 TS |
96 | if hex_common.need_part1(tag): def_helper_size += 1 |
97 | if hex_common.need_slot(tag): def_helper_size += 1 | |
40085901 | 98 | if hex_common.need_PC(tag): def_helper_size += 1 |
613653e5 | 99 | if hex_common.helper_needs_next_PC(tag): def_helper_size += 1 |
793958c9 TS |
100 | f.write('DEF_HELPER_%s(%s' % (def_helper_size, tag)) |
101 | ||
102 | ## Generate the qemu DEF_HELPER type for each result | |
ccd9eec8 TS |
103 | ## Iterate over this list twice |
104 | ## - Emit the scalar result | |
105 | ## - Emit the vector result | |
793958c9 TS |
106 | i=0 |
107 | for regtype,regid,toss,numregs in regs: | |
108 | if (hex_common.is_written(regid)): | |
ccd9eec8 TS |
109 | if (not hex_common.is_hvx_reg(regtype)): |
110 | gen_def_helper_opn(f, tag, regtype, regid, toss, numregs, i) | |
793958c9 TS |
111 | i += 1 |
112 | ||
113 | ## Put the env between the outputs and inputs | |
114 | f.write(', env' ) | |
115 | i += 1 | |
116 | ||
ccd9eec8 TS |
117 | # Second pass |
118 | for regtype,regid,toss,numregs in regs: | |
119 | if (hex_common.is_written(regid)): | |
120 | if (hex_common.is_hvx_reg(regtype)): | |
121 | gen_def_helper_opn(f, tag, regtype, regid, toss, numregs, i) | |
122 | i += 1 | |
123 | ||
793958c9 TS |
124 | ## Generate the qemu type for each input operand (regs and immediates) |
125 | for regtype,regid,toss,numregs in regs: | |
126 | if (hex_common.is_read(regid)): | |
ccd9eec8 TS |
127 | if (hex_common.is_hvx_reg(regtype) and |
128 | hex_common.is_readwrite(regid)): | |
129 | continue | |
793958c9 TS |
130 | gen_def_helper_opn(f, tag, regtype, regid, toss, numregs, i) |
131 | i += 1 | |
132 | for immlett,bits,immshift in imms: | |
133 | f.write(", s32") | |
134 | ||
fb67c2bf TS |
135 | ## Add the arguments for the instruction pkt_has_multi_cof, slot and |
136 | ## part1 (if needed) | |
137 | if hex_common.need_pkt_has_multi_cof(tag): f.write(', i32') | |
40085901 | 138 | if hex_common.need_PC(tag): f.write(', i32') |
613653e5 | 139 | if hex_common.helper_needs_next_PC(tag): f.write(', i32') |
793958c9 TS |
140 | if hex_common.need_slot(tag): f.write(', i32' ) |
141 | if hex_common.need_part1(tag): f.write(' , i32' ) | |
142 | f.write(')\n') | |
143 | ||
144 | def main(): | |
145 | hex_common.read_semantics_file(sys.argv[1]) | |
146 | hex_common.read_attribs_file(sys.argv[2]) | |
147 | hex_common.read_overrides_file(sys.argv[3]) | |
d51bcabe | 148 | hex_common.read_overrides_file(sys.argv[4]) |
e71fdc4f ADF |
149 | ## Whether or not idef-parser is enabled is |
150 | ## determined by the number of arguments to | |
151 | ## this script: | |
152 | ## | |
153 | ## 5 args. -> not enabled, | |
154 | ## 6 args. -> idef-parser enabled. | |
155 | ## | |
156 | ## The 6:th arg. then holds a list of the successfully | |
157 | ## parsed instructions. | |
158 | is_idef_parser_enabled = len(sys.argv) > 6 | |
159 | if is_idef_parser_enabled: | |
160 | hex_common.read_idef_parser_enabled_file(sys.argv[5]) | |
793958c9 TS |
161 | hex_common.calculate_attribs() |
162 | tagregs = hex_common.get_tagregs() | |
163 | tagimms = hex_common.get_tagimms() | |
164 | ||
e71fdc4f ADF |
165 | output_file = sys.argv[-1] |
166 | with open(output_file, 'w') as f: | |
793958c9 TS |
167 | for tag in hex_common.tags: |
168 | ## Skip the priv instructions | |
169 | if ( "A_PRIV" in hex_common.attribdict[tag] ) : | |
170 | continue | |
171 | ## Skip the guest instructions | |
172 | if ( "A_GUEST" in hex_common.attribdict[tag] ) : | |
173 | continue | |
174 | ## Skip the diag instructions | |
175 | if ( tag == "Y6_diag" ) : | |
176 | continue | |
177 | if ( tag == "Y6_diag0" ) : | |
178 | continue | |
179 | if ( tag == "Y6_diag1" ) : | |
180 | continue | |
181 | ||
182 | if ( hex_common.skip_qemu_helper(tag) ): | |
183 | continue | |
e71fdc4f ADF |
184 | if ( hex_common.is_idef_parser_enabled(tag) ): |
185 | continue | |
793958c9 TS |
186 | |
187 | gen_helper_prototype(f, tag, tagregs, tagimms) | |
188 | ||
189 | if __name__ == "__main__": | |
190 | main() |