tests/data/qobject/qdict.txt: Avoid non-inclusive words
[qemu/kevin.git] / target / hexagon / gen_helper_funcs.py
blobce21d3b688ed695cdb2f49775202775526aa5d5b
1 #!/usr/bin/env python3
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.
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
27 ## Helpers for gen_helper_function
29 def gen_decl_ea(f):
30 f.write(" uint32_t EA;\n")
33 def gen_helper_return_type(f, regtype, regid, regno):
34 if regno > 1:
35 f.write(", ")
36 f.write("int32_t")
39 def gen_helper_return_type_pair(f, regtype, regid, regno):
40 if regno > 1:
41 f.write(", ")
42 f.write("int64_t")
45 def gen_helper_arg(f, regtype, regid, regno):
46 if regno > 0:
47 f.write(", ")
48 f.write(f"int32_t {regtype}{regid}V")
51 def gen_helper_arg_new(f, regtype, regid, regno):
52 if regno >= 0:
53 f.write(", ")
54 f.write(f"int32_t {regtype}{regid}N")
57 def gen_helper_arg_pair(f, regtype, regid, regno):
58 if regno >= 0:
59 f.write(", ")
60 f.write(f"int64_t {regtype}{regid}V")
63 def gen_helper_arg_ext(f, regtype, regid, regno):
64 if regno > 0:
65 f.write(", ")
66 f.write(f"void *{regtype}{regid}V_void")
69 def gen_helper_arg_ext_pair(f, regtype, regid, regno):
70 if regno > 0:
71 f.write(", ")
72 f.write(f"void *{regtype}{regid}V_void")
75 def gen_helper_arg_opn(f, regtype, regid, i, tag):
76 if hex_common.is_pair(regid):
77 if hex_common.is_hvx_reg(regtype):
78 gen_helper_arg_ext_pair(f, regtype, regid, i)
79 else:
80 gen_helper_arg_pair(f, regtype, regid, i)
81 elif hex_common.is_single(regid):
82 if hex_common.is_old_val(regtype, regid, tag):
83 if hex_common.is_hvx_reg(regtype):
84 gen_helper_arg_ext(f, regtype, regid, i)
85 else:
86 gen_helper_arg(f, regtype, regid, i)
87 elif hex_common.is_new_val(regtype, regid, tag):
88 gen_helper_arg_new(f, regtype, regid, i)
89 else:
90 hex_common.bad_register(regtype, regid)
91 else:
92 hex_common.bad_register(regtype, regid)
95 def gen_helper_arg_imm(f, immlett):
96 f.write(f", int32_t {hex_common.imm_name(immlett)}")
99 def gen_helper_dest_decl(f, regtype, regid, regno, subfield=""):
100 f.write(f" int32_t {regtype}{regid}V{subfield} = 0;\n")
103 def gen_helper_dest_decl_pair(f, regtype, regid, regno, subfield=""):
104 f.write(f" int64_t {regtype}{regid}V{subfield} = 0;\n")
107 def gen_helper_dest_decl_ext(f, regtype, regid):
108 if regtype == "Q":
109 f.write(
110 f" /* {regtype}{regid}V is *(MMQReg *)" f"({regtype}{regid}V_void) */\n"
112 else:
113 f.write(
114 f" /* {regtype}{regid}V is *(MMVector *)"
115 f"({regtype}{regid}V_void) */\n"
119 def gen_helper_dest_decl_ext_pair(f, regtype, regid, regno):
120 f.write(
121 f" /* {regtype}{regid}V is *(MMVectorPair *))"
122 f"{regtype}{regid}V_void) */\n"
126 def gen_helper_dest_decl_opn(f, regtype, regid, i):
127 if hex_common.is_pair(regid):
128 if hex_common.is_hvx_reg(regtype):
129 gen_helper_dest_decl_ext_pair(f, regtype, regid, i)
130 else:
131 gen_helper_dest_decl_pair(f, regtype, regid, i)
132 elif hex_common.is_single(regid):
133 if hex_common.is_hvx_reg(regtype):
134 gen_helper_dest_decl_ext(f, regtype, regid)
135 else:
136 gen_helper_dest_decl(f, regtype, regid, i)
137 else:
138 hex_common.bad_register(regtype, regid)
141 def gen_helper_src_var_ext(f, regtype, regid):
142 if regtype == "Q":
143 f.write(
144 f" /* {regtype}{regid}V is *(MMQReg *)" f"({regtype}{regid}V_void) */\n"
146 else:
147 f.write(
148 f" /* {regtype}{regid}V is *(MMVector *)"
149 f"({regtype}{regid}V_void) */\n"
153 def gen_helper_src_var_ext_pair(f, regtype, regid, regno):
154 f.write(
155 f" /* {regtype}{regid}V{regno} is *(MMVectorPair *)"
156 f"({regtype}{regid}V{regno}_void) */\n"
160 def gen_helper_return(f, regtype, regid, regno):
161 f.write(f" return {regtype}{regid}V;\n")
164 def gen_helper_return_pair(f, regtype, regid, regno):
165 f.write(f" return {regtype}{regid}V;\n")
168 def gen_helper_dst_write_ext(f, regtype, regid):
169 return
172 def gen_helper_dst_write_ext_pair(f, regtype, regid):
173 return
176 def gen_helper_return_opn(f, regtype, regid, i):
177 if hex_common.is_pair(regid):
178 if hex_common.is_hvx_reg(regtype):
179 gen_helper_dst_write_ext_pair(f, regtype, regid)
180 else:
181 gen_helper_return_pair(f, regtype, regid, i)
182 elif hex_common.is_single(regid):
183 if hex_common.is_hvx_reg(regtype):
184 gen_helper_dst_write_ext(f, regtype, regid)
185 else:
186 gen_helper_return(f, regtype, regid, i)
187 else:
188 hex_common.bad_register(regtype, regid)
192 ## Generate the TCG code to call the helper
193 ## For A2_add: Rd32=add(Rs32,Rt32), { RdV=RsV+RtV;}
194 ## We produce:
195 ## int32_t HELPER(A2_add)(CPUHexagonState *env, int32_t RsV, int32_t RtV)
196 ## {
197 ## uint32_t slot __attribute__(unused)) = 4;
198 ## int32_t RdV = 0;
199 ## { RdV=RsV+RtV;}
200 ## COUNT_HELPER(A2_add);
201 ## return RdV;
202 ## }
204 def gen_helper_function(f, tag, tagregs, tagimms):
205 regs = tagregs[tag]
206 imms = tagimms[tag]
208 numresults = 0
209 numscalarresults = 0
210 numscalarreadwrite = 0
211 for regtype, regid in regs:
212 if hex_common.is_written(regid):
213 numresults += 1
214 if hex_common.is_scalar_reg(regtype):
215 numscalarresults += 1
216 if hex_common.is_readwrite(regid):
217 if hex_common.is_scalar_reg(regtype):
218 numscalarreadwrite += 1
220 if numscalarresults > 1:
221 ## The helper is bogus when there is more than one result
222 f.write(
223 f"void HELPER({tag})(CPUHexagonState *env) " f"{{ BOGUS_HELPER({tag}); }}\n"
225 else:
226 ## The return type of the function is the type of the destination
227 ## register (if scalar)
228 i = 0
229 for regtype, regid in regs:
230 if hex_common.is_written(regid):
231 if hex_common.is_pair(regid):
232 if hex_common.is_hvx_reg(regtype):
233 continue
234 else:
235 gen_helper_return_type_pair(f, regtype, regid, i)
236 elif hex_common.is_single(regid):
237 if hex_common.is_hvx_reg(regtype):
238 continue
239 else:
240 gen_helper_return_type(f, regtype, regid, i)
241 else:
242 hex_common.bad_register(regtype, regid)
243 i += 1
245 if numscalarresults == 0:
246 f.write("void")
247 f.write(f" HELPER({tag})(CPUHexagonState *env")
249 ## Arguments include the vector destination operands
250 i = 1
251 for regtype, regid in regs:
252 if hex_common.is_written(regid):
253 if hex_common.is_pair(regid):
254 if hex_common.is_hvx_reg(regtype):
255 gen_helper_arg_ext_pair(f, regtype, regid, i)
256 else:
257 continue
258 elif hex_common.is_single(regid):
259 if hex_common.is_hvx_reg(regtype):
260 gen_helper_arg_ext(f, regtype, regid, i)
261 else:
262 # This is the return value of the function
263 continue
264 else:
265 hex_common.bad_register(regtype, regid)
266 i += 1
268 ## For conditional instructions, we pass in the destination register
269 if "A_CONDEXEC" in hex_common.attribdict[tag]:
270 for regtype, regid in regs:
271 if hex_common.is_writeonly(regid) and not hex_common.is_hvx_reg(
272 regtype
274 gen_helper_arg_opn(f, regtype, regid, i, tag)
275 i += 1
277 ## Arguments to the helper function are the source regs and immediates
278 for regtype, regid in regs:
279 if hex_common.is_read(regid):
280 if hex_common.is_hvx_reg(regtype) and hex_common.is_readwrite(regid):
281 continue
282 gen_helper_arg_opn(f, regtype, regid, i, tag)
283 i += 1
284 for immlett, bits, immshift in imms:
285 gen_helper_arg_imm(f, immlett)
286 i += 1
288 if hex_common.need_pkt_has_multi_cof(tag):
289 f.write(", uint32_t pkt_has_multi_cof")
290 if (hex_common.need_pkt_need_commit(tag)):
291 f.write(", uint32_t pkt_need_commit")
293 if hex_common.need_PC(tag):
294 if i > 0:
295 f.write(", ")
296 f.write("target_ulong PC")
297 i += 1
298 if hex_common.helper_needs_next_PC(tag):
299 if i > 0:
300 f.write(", ")
301 f.write("target_ulong next_PC")
302 i += 1
303 if hex_common.need_slot(tag):
304 if i > 0:
305 f.write(", ")
306 f.write("uint32_t slotval")
307 i += 1
308 if hex_common.need_part1(tag):
309 if i > 0:
310 f.write(", ")
311 f.write("uint32_t part1")
312 f.write(")\n{\n")
313 if hex_common.need_ea(tag):
314 gen_decl_ea(f)
315 ## Declare the return variable
316 i = 0
317 if "A_CONDEXEC" not in hex_common.attribdict[tag]:
318 for regtype, regid in regs:
319 if hex_common.is_writeonly(regid):
320 gen_helper_dest_decl_opn(f, regtype, regid, i)
321 i += 1
323 for regtype, regid in regs:
324 if hex_common.is_read(regid):
325 if hex_common.is_pair(regid):
326 if hex_common.is_hvx_reg(regtype):
327 gen_helper_src_var_ext_pair(f, regtype, regid, i)
328 elif hex_common.is_single(regid):
329 if hex_common.is_hvx_reg(regtype):
330 gen_helper_src_var_ext(f, regtype, regid)
331 else:
332 hex_common.bad_register(regtype, regid)
334 if hex_common.need_slot(tag):
335 if "A_LOAD" in hex_common.attribdict[tag]:
336 f.write(" bool pkt_has_store_s1 = slotval & 0x1;\n")
337 f.write(" uint32_t slot = slotval >> 1;\n")
339 if "A_FPOP" in hex_common.attribdict[tag]:
340 f.write(" arch_fpop_start(env);\n")
342 f.write(f" {hex_common.semdict[tag]}\n")
344 if "A_FPOP" in hex_common.attribdict[tag]:
345 f.write(" arch_fpop_end(env);\n")
347 ## Save/return the return variable
348 for regtype, regid in regs:
349 if hex_common.is_written(regid):
350 gen_helper_return_opn(f, regtype, regid, i)
351 f.write("}\n\n")
352 ## End of the helper definition
355 def main():
356 hex_common.read_semantics_file(sys.argv[1])
357 hex_common.read_attribs_file(sys.argv[2])
358 hex_common.read_overrides_file(sys.argv[3])
359 hex_common.read_overrides_file(sys.argv[4])
360 ## Whether or not idef-parser is enabled is
361 ## determined by the number of arguments to
362 ## this script:
364 ## 5 args. -> not enabled,
365 ## 6 args. -> idef-parser enabled.
367 ## The 6:th arg. then holds a list of the successfully
368 ## parsed instructions.
369 is_idef_parser_enabled = len(sys.argv) > 6
370 if is_idef_parser_enabled:
371 hex_common.read_idef_parser_enabled_file(sys.argv[5])
372 hex_common.calculate_attribs()
373 tagregs = hex_common.get_tagregs()
374 tagimms = hex_common.get_tagimms()
376 output_file = sys.argv[-1]
377 with open(output_file, "w") as f:
378 for tag in hex_common.tags:
379 ## Skip the priv instructions
380 if "A_PRIV" in hex_common.attribdict[tag]:
381 continue
382 ## Skip the guest instructions
383 if "A_GUEST" in hex_common.attribdict[tag]:
384 continue
385 ## Skip the diag instructions
386 if tag == "Y6_diag":
387 continue
388 if tag == "Y6_diag0":
389 continue
390 if tag == "Y6_diag1":
391 continue
392 if hex_common.skip_qemu_helper(tag):
393 continue
394 if hex_common.is_idef_parser_enabled(tag):
395 continue
397 gen_helper_function(f, tag, tagregs, tagimms)
400 if __name__ == "__main__":
401 main()