master
py 1,430 lines 47 KB
Raw
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
20 import sys
21 import re
22 import string
23 import textwrap
24 import argparse
25
26 behdict = {} # tag ->behavior
27 semdict = {} # tag -> semantics
28 attribdict = {} # tag -> attributes
29 macros = {} # macro -> macro information...
30 registers = {} # register -> register functions
31 new_registers = {}
32 tags = [] # list of all tags
33 overrides = {} # tags with helper overrides
34 idef_parser_enabled = {} # tags enabled for idef-parser
35
36
37 def is_sysemu_tag(tag):
38 return bool(attribdict[tag] & {"A_PRIV", "A_GUEST"})
39
40
41 def tag_ignore(tag):
42 tag_skips = (
43 "Y6_diag",
44 "Y6_diag0",
45 "Y6_diag1",
46 )
47 attr_skips = {
48 "A_FAKEINSN",
49 "A_MAPPING",
50 "A_CONDMAPPING",
51 }
52 return tag in tag_skips or attribdict[tag] & attr_skips
53
54
55 def get_sys_tags():
56 return sorted(
57 tag for tag in frozenset(tags) if is_sysemu_tag(tag)
58 )
59
60
61 def get_user_tags():
62 return sorted(
63 tag for tag in frozenset(tags) if not is_sysemu_tag(tag)
64 )
65
66
67 def get_all_tags():
68 return get_user_tags() + get_sys_tags()
69
70
71 # We should do this as a hash for performance,
72 # but to keep order let's keep it as a list.
73 def uniquify(seq):
74 seen = set()
75 seen_add = seen.add
76 return [x for x in seq if x not in seen and not seen_add(x)]
77
78
79 regre = re.compile(r"((?<!DUP)[MNORCPQXSGVZA])([stuvwxyzdefg]+)([.]?[LlHh]?)(\d+S?)")
80 immre = re.compile(r"[#]([rRsSuUm])(\d+)(?:[:](\d+))?")
81 reg_or_immre = re.compile(
82 r"(((?<!DUP)[MNRCOPQXSGVZA])([stuvwxyzdefg]+)"
83 r"([.]?[LlHh]?)(\d+S?))|([#]([rRsSuUm])(\d+)[:]?(\d+)?)"
84 )
85 relimmre = re.compile(r"[#]([rR])(\d+)(?:[:](\d+))?")
86 absimmre = re.compile(r"[#]([sSuUm])(\d+)(?:[:](\d+))?")
87
88 finished_macros = set()
89
90
91 def expand_macro_attribs(macro, allmac_re):
92 if macro.key not in finished_macros:
93 # Get a list of all things that might be macros
94 l = allmac_re.findall(macro.beh)
95 for submacro in l:
96 if not submacro:
97 continue
98 if not macros[submacro]:
99 raise Exception(f"Couldn't find macro: <{l}>")
100 macro.attribs |= expand_macro_attribs(macros[submacro], allmac_re)
101 finished_macros.add(macro.key)
102 return macro.attribs
103
104
105 # When qemu needs an attribute that isn't in the imported files,
106 # we'll add it here.
107 def add_qemu_macro_attrib(name, attrib):
108 macros[name].attribs.add(attrib)
109
110
111 immextre = re.compile(r"f(MUST_)?IMMEXT[(]([UuSsRr])")
112
113
114 def is_cond_jump(tag):
115 if tag == "J2_rte":
116 return False
117 if "A_HWLOOP0_END" in attribdict[tag] or "A_HWLOOP1_END" in attribdict[tag]:
118 return False
119 return re.compile(r"(if.*fBRANCH)|(if.*fJUMPR)").search(semdict[tag]) != None
120
121
122 def is_cond_call(tag):
123 return re.compile(r"(if.*fCALL)").search(semdict[tag]) != None
124
125
126 def calculate_attribs():
127 add_qemu_macro_attrib("fREAD_PC", "A_IMPLICIT_READS_PC")
128 add_qemu_macro_attrib("fTRAP", "A_IMPLICIT_READS_PC")
129 add_qemu_macro_attrib("fSET_OVERFLOW", "A_IMPLICIT_WRITES_USR")
130 add_qemu_macro_attrib("fSET_LPCFG", "A_IMPLICIT_WRITES_USR")
131 add_qemu_macro_attrib("fCLEAR_RTE_EX", "A_IMPLICIT_WRITES_SSR")
132 add_qemu_macro_attrib("fLOAD", "A_SCALAR_LOAD")
133 add_qemu_macro_attrib("fSTORE", "A_SCALAR_STORE")
134 add_qemu_macro_attrib("fSET_K0_LOCK", "A_IMPLICIT_READS_PC")
135 add_qemu_macro_attrib("fSET_TLB_LOCK", "A_IMPLICIT_READS_PC")
136 add_qemu_macro_attrib('fLSBNEW0', 'A_IMPLICIT_READS_P0')
137 add_qemu_macro_attrib('fLSBNEW0NOT', 'A_IMPLICIT_READS_P0')
138 add_qemu_macro_attrib('fREAD_P0', 'A_IMPLICIT_READS_P0')
139 add_qemu_macro_attrib('fLSBNEW1', 'A_IMPLICIT_READS_P1')
140 add_qemu_macro_attrib('fLSBNEW1NOT', 'A_IMPLICIT_READS_P1')
141 add_qemu_macro_attrib('fREAD_P3', 'A_IMPLICIT_READS_P3')
142 add_qemu_macro_attrib('fREAD_SP', 'A_IMPLICIT_READS_SP')
143
144 # Recurse down macros, find attributes from sub-macros
145 macroValues = list(macros.values())
146 allmacros_restr = "|".join(set([m.re.pattern for m in macroValues]))
147 allmacros_re = re.compile(allmacros_restr)
148 for macro in macroValues:
149 expand_macro_attribs(macro, allmacros_re)
150 # Append attributes to all instructions
151 for tag in tags:
152 for macname in allmacros_re.findall(semdict[tag]):
153 if not macname:
154 continue
155 macro = macros[macname]
156 attribdict[tag] |= set(macro.attribs)
157 # Mark conditional jumps and calls
158 # Not all instructions are properly marked with A_CONDEXEC
159 for tag in tags:
160 if is_cond_jump(tag) or is_cond_call(tag):
161 attribdict[tag].add("A_CONDEXEC")
162
163
164 def SEMANTICS(tag, beh, sem):
165 # print tag,beh,sem
166 behdict[tag] = beh
167 semdict[tag] = sem
168 attribdict[tag] = set()
169 tags.append(tag) # dicts have no order, this is for order
170
171
172 def ATTRIBUTES(tag, attribstring):
173 attribstring = attribstring.replace("ATTRIBS", "").replace("(", "").replace(")", "")
174 if not attribstring:
175 return
176 attribs = attribstring.split(",")
177 for attrib in attribs:
178 attribdict[tag].add(attrib.strip())
179
180
181 class Macro(object):
182 __slots__ = ["key", "name", "beh", "attribs", "re"]
183
184 def __init__(self, name, beh, attribs):
185 self.key = name
186 self.name = name
187 self.beh = beh
188 self.attribs = set(attribs)
189 self.re = re.compile("\\b" + name + "\\b")
190
191
192 def MACROATTRIB(macname, beh, attribstring):
193 attribstring = attribstring.replace("(", "").replace(")", "")
194 if attribstring:
195 attribs = attribstring.split(",")
196 else:
197 attribs = []
198 macros[macname] = Macro(macname, beh, attribs)
199
200 def compute_tag_regs(tag, full):
201 tagregs = regre.findall(behdict[tag])
202 if not full:
203 tagregs = map(lambda reg: reg[:2], tagregs)
204 return uniquify(tagregs)
205
206 def compute_tag_immediates(tag):
207 return uniquify(immre.findall(behdict[tag]))
208
209
210 ##
211 ## tagregs is the main data structure we'll use
212 ## tagregs[tag] will contain the registers used by an instruction
213 ## Within each entry, we'll use the regtype and regid fields
214 ## regtype can be one of the following
215 ## C control register
216 ## N new register value
217 ## P predicate register
218 ## R GPR register
219 ## M modifier register
220 ## Q HVX predicate vector
221 ## V HVX vector register
222 ## O HVX new vector register
223 ## regid can be one of the following
224 ## d, e destination register
225 ## dd destination register pair
226 ## s, t, u, v, w source register
227 ## ss, tt, uu, vv source register pair
228 ## x, y read-write register
229 ## xx, yy read-write register pair
230 ##
231 def get_tagregs(full=False):
232 compute_func = lambda tag: compute_tag_regs(tag, full)
233 return dict(zip(tags, list(map(compute_func, tags))))
234
235 def get_tagimms():
236 return dict(zip(tags, list(map(compute_tag_immediates, tags))))
237
238
239 def need_p0(tag):
240 return "A_IMPLICIT_READS_P0" in attribdict[tag]
241
242
243 def need_sp(tag):
244 return "A_IMPLICIT_READS_SP" in attribdict[tag]
245
246
247 def is_hvx_insn(tag):
248 return "A_CVI" in attribdict[tag]
249
250
251 def need_env(tag):
252 return ("A_STORE" in attribdict[tag] or
253 "A_LOAD" in attribdict[tag] or
254 "A_CVI_GATHER" in attribdict[tag] or
255 "A_CVI_SCATTER" in attribdict[tag] or
256 "A_HVX_IEEE_FP" in attribdict[tag] or
257 "A_HVX_FLT" in attribdict[tag] or
258 "A_IMPLICIT_WRITES_USR" in attribdict[tag] or
259 "A_PRIV" in attribdict[tag] or
260 "J2_trap" in tag)
261
262
263 def need_slot(tag):
264 if (
265 "A_CVI_SCATTER" not in attribdict[tag]
266 and "A_CVI_GATHER" not in attribdict[tag]
267 and ("A_STORE" in attribdict[tag]
268 or "A_LOAD" in attribdict[tag])
269 and tag != "L4_loadw_phys"
270 and tag != "L6_memcpy"
271 and tag != "Y6_dmlink"
272 ):
273 return 1
274 else:
275 return 0
276
277
278 def need_part1(tag):
279 return re.compile(r"fPART1").search(semdict[tag])
280
281
282 def need_ea(tag):
283 return re.compile(r"\bEA\b").search(semdict[tag])
284
285
286 def need_PC(tag):
287 return "A_IMPLICIT_READS_PC" in attribdict[tag]
288
289
290 def need_next_PC(tag):
291 return "A_CALL" in attribdict[tag]
292
293
294 def need_pkt_has_multi_cof(tag):
295 if attribdict[tag] & {"A_JUMP", "A_CALL"}:
296 return tag != "J4_hintjumpr"
297 return False
298
299
300 def need_pkt_need_commit(tag):
301 return 'A_IMPLICIT_WRITES_USR' in attribdict[tag]
302
303
304 def skip_qemu_helper(tag):
305 return tag in overrides.keys()
306
307
308 def is_idef_parser_enabled(tag):
309 return tag in idef_parser_enabled
310
311
312 def is_hvx_insn(tag):
313 return "A_CVI" in attribdict[tag]
314
315
316 def has_hvx_helper(tag):
317 return (is_hvx_insn(tag) and
318 not skip_qemu_helper(tag) and
319 not is_idef_parser_enabled(tag))
320
321
322 def imm_name(immlett):
323 return f"{immlett}iV"
324
325
326 def read_semantics_file(name):
327 eval_line = ""
328 for line in open(name, "rt").readlines():
329 if not line.startswith("#"):
330 eval_line += line
331 if line.endswith("\\\n"):
332 eval_line.rstrip("\\\n")
333 else:
334 eval(eval_line.strip())
335 eval_line = ""
336
337
338 def read_overrides_file(name):
339 overridere = re.compile(r"#define fGEN_TCG_([A-Za-z0-9_]+)\(.*")
340 for line in open(name, "rt").readlines():
341 if not overridere.match(line):
342 continue
343 tag = overridere.findall(line)[0]
344 overrides[tag] = True
345
346
347 def read_idef_parser_enabled_file(name):
348 global idef_parser_enabled
349 with open(name, "r") as idef_parser_enabled_file:
350 lines = idef_parser_enabled_file.read().strip().split("\n")
351 idef_parser_enabled = set(lines)
352
353
354 def is_predicated(tag):
355 return "A_CONDEXEC" in attribdict[tag]
356
357
358 def code_fmt(txt):
359 return textwrap.indent(textwrap.dedent(txt), " ")
360
361
362 def hvx_newv(tag):
363 if "A_CVI_NEW" in attribdict[tag]:
364 return "EXT_NEW"
365 elif "A_CVI_TMP" in attribdict[tag] or "A_CVI_TMP_DST" in attribdict[tag]:
366 return "EXT_TMP"
367 else:
368 return "EXT_DFL"
369
370 def vreg_offset_func(tag):
371 if "A_CVI_TMP" in attribdict[tag] or "A_CVI_TMP_DST" in attribdict[tag]:
372 return "ctx_tmp_vreg_off"
373 else:
374 return "ctx_future_vreg_off"
375
376 class HelperArg:
377 def __init__(self, proto_arg, call_arg, func_arg):
378 self.proto_arg = proto_arg
379 self.call_arg = call_arg
380 self.func_arg = func_arg
381
382 class Register:
383 def __init__(self, regtype, regid):
384 self.regtype = regtype
385 self.regid = regid
386 self.reg_num = f"{regtype}{regid}N"
387 def decl_reg_num(self, f, regno):
388 f.write(code_fmt(f"""\
389 const int {self.reg_num} = insn->regno[{regno}];
390 """))
391 def idef_arg(self, declared):
392 declared.append(self.reg_tcg())
393 def may_alias_gpr(self):
394 return False
395 def helper_arg(self):
396 return HelperArg(
397 self.helper_proto_type(),
398 self.reg_tcg(),
399 f"{self.helper_arg_type()} {self.helper_arg_name()}"
400 )
401
402
403 #
404 # Every register is either Single or Pair or Hvx
405 #
406 class Scalar:
407 def is_scalar_reg(self):
408 return True
409 def is_hvx_reg(self):
410 return False
411 def helper_arg_name(self):
412 return self.reg_tcg()
413
414 class Single(Scalar):
415 def helper_proto_type(self):
416 return "s32"
417 def helper_arg_type(self):
418 return "int32_t"
419 def is_pair(self):
420 return False
421
422 class Pair(Scalar):
423 def helper_proto_type(self):
424 return "s64"
425 def helper_arg_type(self):
426 return "int64_t"
427 def is_pair(self):
428 return True
429
430 class Hvx:
431 def is_scalar_reg(self):
432 return False
433 def is_hvx_reg(self):
434 return True
435 def hvx_off(self):
436 return f"{self.reg_tcg()}_off"
437 def helper_proto_type(self):
438 return "ptr"
439 def helper_arg_type(self):
440 return "void *"
441 def helper_arg_name(self):
442 return f"{self.reg_tcg()}_void"
443
444 #
445 # Every register is either Dest or OldSource or NewSource or ReadWrite
446 #
447 class Dest:
448 def reg_tcg(self):
449 return f"{self.regtype}{self.regid}V"
450 def is_written(self):
451 return True
452 def is_writeonly(self):
453 return True
454 def is_read(self):
455 return False
456 def is_readwrite(self):
457 return False
458
459 class Source:
460 def is_written(self):
461 return False
462 def is_writeonly(self):
463 return False
464 def is_read(self):
465 return True
466 def is_readwrite(self):
467 return False
468
469 class OldSource(Source):
470 def reg_tcg(self):
471 return f"{self.regtype}{self.regid}V"
472 def is_old(self):
473 return True
474 def is_new(self):
475 return False
476
477 class NewSource(Source):
478 def reg_tcg(self):
479 return f"{self.regtype}{self.regid}N"
480 def is_old(self):
481 return False
482 def is_new(self):
483 return True
484
485 class ReadWrite:
486 def reg_tcg(self):
487 return f"{self.regtype}{self.regid}V"
488 def is_written(self):
489 return True
490 def is_writeonly(self):
491 return False
492 def is_read(self):
493 return True
494 def is_readwrite(self):
495 return True
496 def is_old(self):
497 return True
498 def is_new(self):
499 return False
500
501 class GprDest(Register, Single, Dest):
502 def may_alias_gpr(self):
503 return True
504 def decl_tcg(self, f, tag, regno):
505 self.decl_reg_num(f, regno)
506 f.write(code_fmt(f"""\
507 TCGv {self.reg_tcg()} = get_result_gpr(ctx, {self.reg_num});
508 """))
509 def gen_write(self, f, tag):
510 ## No write needed
511 return
512 def analyze_write(self, f, tag, regno):
513 predicated = "true" if is_predicated(tag) else "false"
514 f.write(code_fmt(f"""\
515 ctx_log_reg_write(ctx, {self.reg_num}, {predicated});
516 """))
517
518 class GprSource(Register, Single, OldSource):
519 def may_alias_gpr(self):
520 return True
521 def decl_tcg(self, f, tag, regno):
522 self.decl_reg_num(f, regno)
523 f.write(code_fmt(f"""\
524 TCGv {self.reg_tcg()} = hex_gpr[{self.reg_num}];
525 """))
526 def analyze_read(self, f, regno):
527 f.write(code_fmt(f"""\
528 ctx_log_reg_read(ctx, {self.reg_num});
529 """))
530
531 class GprNewSource(Register, Single, NewSource):
532 def decl_tcg(self, f, tag, regno):
533 f.write(code_fmt(f"""\
534 TCGv {self.reg_tcg()} = get_result_gpr(ctx, insn->regno[{regno}]);
535 """))
536 def analyze_read(self, f, regno):
537 f.write(code_fmt(f"""\
538 ctx_log_reg_read_new(ctx, {self.reg_num});
539 """))
540
541 class GprReadWrite(Register, Single, ReadWrite):
542 def may_alias_gpr(self):
543 return True
544 def decl_tcg(self, f, tag, regno):
545 self.decl_reg_num(f, regno)
546 f.write(code_fmt(f"""\
547 TCGv {self.reg_tcg()} = get_result_gpr(ctx, {self.reg_num});
548 """))
549 ## For read/write registers, we need to get the original value into
550 ## the result TCGv. For predicated instructions, this is done in
551 ## gen_start_packet. For un-predicated instructions, we do it here.
552 if not is_predicated(tag):
553 f.write(code_fmt(f"""\
554 tcg_gen_mov_tl({self.reg_tcg()}, hex_gpr[{self.reg_num}]);
555 """))
556 def gen_write(self, f, tag):
557 ## No write needed
558 return
559 def analyze_read(self, f, regno):
560 f.write(code_fmt(f"""\
561 ctx_log_reg_read(ctx, {self.reg_num});
562 """))
563 def analyze_write(self, f, tag, regno):
564 predicated = "true" if is_predicated(tag) else "false"
565 f.write(code_fmt(f"""\
566 ctx_log_reg_write(ctx, {self.reg_num}, {predicated});
567 """))
568
569 class ControlDest(Register, Single, Dest):
570 def may_alias_gpr(self):
571 return True
572 def decl_reg_num(self, f, regno):
573 f.write(code_fmt(f"""\
574 const int {self.reg_num} = insn->regno[{regno}] + HEX_REG_SA0;
575 """))
576 def decl_tcg(self, f, tag, regno):
577 self.decl_reg_num(f, regno)
578 f.write(code_fmt(f"""\
579 TCGv {self.reg_tcg()} = get_result_gpr(ctx, {self.reg_num});
580 """))
581 def gen_write(self, f, tag):
582 f.write(code_fmt(f"""\
583 gen_write_ctrl_reg(ctx, {self.reg_num}, {self.reg_tcg()});
584 """))
585 def analyze_write(self, f, tag, regno):
586 predicated = "true" if is_predicated(tag) else "false"
587 f.write(code_fmt(f"""\
588 ctx_log_reg_write(ctx, {self.reg_num}, {predicated});
589 """))
590
591 class ControlSource(Register, Single, OldSource):
592 def decl_reg_num(self, f, regno):
593 f.write(code_fmt(f"""\
594 const int {self.reg_num} = insn->regno[{regno}] + HEX_REG_SA0;
595 """))
596 def decl_tcg(self, f, tag, regno):
597 self.decl_reg_num(f, regno);
598 f.write(code_fmt(f"""\
599 TCGv {self.reg_tcg()} = tcg_temp_new();
600 gen_read_ctrl_reg(ctx, {self.reg_num}, {self.reg_tcg()});
601 """))
602 def analyze_read(self, f, regno):
603 f.write(code_fmt(f"""\
604 ctx_log_reg_read(ctx, {self.reg_num});
605 """))
606
607 class ModifierSource(Register, Single, OldSource):
608 def may_alias_gpr(self):
609 return True
610 def decl_reg_num(self, f, regno):
611 f.write(code_fmt(f"""\
612 const int {self.reg_num} = insn->regno[{regno}] + HEX_REG_M0;
613 """))
614 def decl_tcg(self, f, tag, regno):
615 self.decl_reg_num(f, regno)
616 f.write(code_fmt(f"""\
617 TCGv {self.reg_tcg()} = hex_gpr[{self.reg_num}];
618 TCGv CS G_GNUC_UNUSED =
619 hex_gpr[{self.reg_num} - HEX_REG_M0 + HEX_REG_CS0];
620 """))
621 def idef_arg(self, declared):
622 declared.append(self.reg_tcg())
623 declared.append("CS")
624 def analyze_read(self, f, regno):
625 f.write(code_fmt(f"""\
626 ctx_log_reg_read(ctx, {self.reg_num});
627 """))
628
629 class PredDest(Register, Single, Dest):
630 def decl_tcg(self, f, tag, regno):
631 self.decl_reg_num(f, regno)
632 f.write(code_fmt(f"""\
633 TCGv {self.reg_tcg()} = tcg_temp_new();
634 """))
635 def gen_write(self, f, tag):
636 f.write(code_fmt(f"""\
637 gen_pred_write(ctx, {self.reg_num}, {self.reg_tcg()});
638 """))
639 def analyze_write(self, f, tag, regno):
640 f.write(code_fmt(f"""\
641 ctx_log_pred_write(ctx, {self.reg_num});
642 """))
643
644 class PredSource(Register, Single, OldSource):
645 def decl_tcg(self, f, tag, regno):
646 self.decl_reg_num(f, regno)
647 f.write(code_fmt(f"""\
648 TCGv {self.reg_tcg()} = hex_pred[{self.reg_num}];
649 """))
650 def analyze_read(self, f, regno):
651 f.write(code_fmt(f"""\
652 ctx_log_pred_read(ctx, {self.reg_num});
653 """))
654
655 class PredNewSource(Register, Single, NewSource):
656 def decl_tcg(self, f, tag, regno):
657 f.write(code_fmt(f"""\
658 TCGv {self.reg_tcg()} = get_result_pred(ctx, insn->regno[{regno}]);
659 """))
660 def analyze_read(self, f, regno):
661 f.write(code_fmt(f"""\
662 ctx_log_pred_read_new(ctx, {self.reg_num});
663 """))
664
665 class PredReadWrite(Register, Single, ReadWrite):
666 def decl_tcg(self, f, tag, regno):
667 self.decl_reg_num(f, regno)
668 f.write(code_fmt(f"""\
669 TCGv {self.reg_tcg()} = tcg_temp_new();
670 tcg_gen_mov_tl({self.reg_tcg()}, hex_pred[{self.reg_num}]);
671 """))
672 def gen_write(self, f, tag):
673 f.write(code_fmt(f"""\
674 gen_pred_write(ctx, {self.reg_num}, {self.reg_tcg()});
675 """))
676 def analyze_read(self, f, regno):
677 f.write(code_fmt(f"""\
678 ctx_log_pred_read(ctx, {self.reg_num});
679 """))
680 def analyze_write(self, f, tag, regno):
681 f.write(code_fmt(f"""\
682 ctx_log_pred_write(ctx, {self.reg_num});
683 """))
684
685 class PairDest(Register, Pair, Dest):
686 def decl_tcg(self, f, tag, regno):
687 self.decl_reg_num(f, regno)
688 f.write(code_fmt(f"""\
689 TCGv_i64 {self.reg_tcg()} =
690 get_result_gpr_pair(ctx, {self.reg_num});
691 """))
692 def gen_write(self, f, tag):
693 f.write(code_fmt(f"""\
694 gen_write_reg_pair(ctx, {self.reg_num}, {self.reg_tcg()});
695 """))
696 def analyze_write(self, f, tag, regno):
697 predicated = "true" if is_predicated(tag) else "false"
698 f.write(code_fmt(f"""\
699 ctx_log_reg_write_pair(ctx, {self.reg_num}, {predicated});
700 """))
701
702 class PairSource(Register, Pair, OldSource):
703 def decl_tcg(self, f, tag, regno):
704 self.decl_reg_num(f, regno)
705 f.write(code_fmt(f"""\
706 TCGv_i64 {self.reg_tcg()} = tcg_temp_new_i64();
707 tcg_gen_concat_i32_i64({self.reg_tcg()},
708 hex_gpr[{self.reg_num}],
709 hex_gpr[{self.reg_num} + 1]);
710 """))
711 def analyze_read(self, f, regno):
712 f.write(code_fmt(f"""\
713 ctx_log_reg_read_pair(ctx, {self.reg_num});
714 """))
715
716 class PairReadWrite(Register, Pair, ReadWrite):
717 def decl_tcg(self, f, tag, regno):
718 self.decl_reg_num(f, regno)
719 f.write(code_fmt(f"""\
720 TCGv_i64 {self.reg_tcg()} =
721 get_result_gpr_pair(ctx, {self.reg_num});
722 tcg_gen_concat_i32_i64({self.reg_tcg()},
723 hex_gpr[{self.reg_num}],
724 hex_gpr[{self.reg_num} + 1]);
725 """))
726 def gen_write(self, f, tag):
727 f.write(code_fmt(f"""\
728 gen_write_reg_pair(ctx, {self.reg_num}, {self.reg_tcg()});
729 """))
730 def analyze_read(self, f, regno):
731 f.write(code_fmt(f"""\
732 ctx_log_reg_read_pair(ctx, {self.reg_num});
733 """))
734 def analyze_write(self, f, tag, regno):
735 predicated = "true" if is_predicated(tag) else "false"
736 f.write(code_fmt(f"""\
737 ctx_log_reg_write_pair(ctx, {self.reg_num}, {predicated});
738 """))
739
740 class ControlPairDest(Register, Pair, Dest):
741 def decl_reg_num(self, f, regno):
742 f.write(code_fmt(f"""\
743 const int {self.reg_num} = insn->regno[{regno}] + HEX_REG_SA0;
744 """))
745 def decl_tcg(self, f, tag, regno):
746 self.decl_reg_num(f, regno)
747 f.write(code_fmt(f"""\
748 TCGv_i64 {self.reg_tcg()} =
749 get_result_gpr_pair(ctx, {self.reg_num});
750 """))
751 def gen_write(self, f, tag):
752 f.write(code_fmt(f"""\
753 gen_write_ctrl_reg_pair(ctx, {self.reg_num}, {self.reg_tcg()});
754 """))
755 def analyze_write(self, f, tag, regno):
756 predicated = "true" if is_predicated(tag) else "false"
757 f.write(code_fmt(f"""\
758 ctx_log_reg_write_pair(ctx, {self.reg_num}, {predicated});
759 """))
760
761 class ControlPairSource(Register, Pair, OldSource):
762 def decl_reg_num(self, f, regno):
763 f.write(code_fmt(f"""\
764 const int {self.reg_num} = insn->regno[{regno}] + HEX_REG_SA0;
765 """))
766 def decl_tcg(self, f, tag, regno):
767 self.decl_reg_num(f, regno)
768 f.write(code_fmt(f"""\
769 TCGv_i64 {self.reg_tcg()} = tcg_temp_new_i64();
770 gen_read_ctrl_reg_pair(ctx, {self.reg_num}, {self.reg_tcg()});
771 """))
772 def analyze_read(self, f, regno):
773 f.write(code_fmt(f"""\
774 ctx_log_reg_read_pair(ctx, {self.reg_num});
775 """))
776
777 class VRegDest(Register, Hvx, Dest):
778 def decl_tcg(self, f, tag, regno):
779 self.decl_reg_num(f, regno)
780 f.write(code_fmt(f"""\
781 const intptr_t {self.hvx_off()} =
782 {vreg_offset_func(tag)}(ctx, {self.reg_num}, 1, true);
783 """))
784 if not skip_qemu_helper(tag):
785 f.write(code_fmt(f"""\
786 TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
787 tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
788 """))
789 def gen_zero(self, f):
790 f.write(code_fmt(f"""\
791 tcg_gen_gvec_dup_imm(MO_64, {self.hvx_off()},
792 sizeof(MMVector), sizeof(MMVector), 0);
793 """))
794 def gen_write(self, f, tag):
795 pass
796 def helper_hvx_desc(self, f):
797 f.write(code_fmt(f"""\
798 /* {self.reg_tcg()} is *(MMVector *)({self.helper_arg_name()}) */
799 """))
800 def analyze_write(self, f, tag, regno):
801 newv = hvx_newv(tag)
802 predicated = "true" if is_predicated(tag) else "false"
803 f.write(code_fmt(f"""\
804 ctx_log_vreg_write(ctx, {self.reg_num}, {newv}, {predicated},
805 insn_has_hvx_helper);
806 """))
807
808 class VRegSource(Register, Hvx, OldSource):
809 def decl_tcg(self, f, tag, regno):
810 self.decl_reg_num(f, regno)
811 f.write(code_fmt(f"""\
812 const intptr_t {self.hvx_off()} = vreg_src_off(ctx, {self.reg_num});
813 """))
814 if not skip_qemu_helper(tag):
815 f.write(code_fmt(f"""\
816 TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
817 tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
818 """))
819 def helper_hvx_desc(self, f):
820 f.write(code_fmt(f"""\
821 /* {self.reg_tcg()} is *(MMVector *)({self.helper_arg_name()}) */
822 """))
823 def analyze_read(self, f, regno):
824 f.write(code_fmt(f"""\
825 ctx_log_vreg_read(ctx, {self.reg_num}, insn_has_hvx_helper);
826 """))
827
828 class VRegNewSource(Register, Hvx, NewSource):
829 def decl_tcg(self, f, tag, regno):
830 self.decl_reg_num(f, regno)
831 if skip_qemu_helper(tag):
832 f.write(code_fmt(f"""\
833 const intptr_t {self.hvx_off()} =
834 ctx_future_vreg_off(ctx, {self.reg_num}, 1, true);
835 """))
836 def helper_hvx_desc(self, f):
837 f.write(code_fmt(f"""\
838 /* {self.reg_tcg()} is *(MMVector *)({self.helper_arg_name()}) */
839 """))
840 def analyze_read(self, f, regno):
841 f.write(code_fmt(f"""\
842 ctx_log_vreg_read_new(ctx, {self.reg_num}, insn_has_hvx_helper);
843 """))
844
845 class VRegReadWrite(Register, Hvx, ReadWrite):
846 def decl_tcg(self, f, tag, regno):
847 self.decl_reg_num(f, regno)
848 f.write(code_fmt(f"""\
849 const intptr_t {self.hvx_off()} =
850 {vreg_offset_func(tag)}(ctx, {self.reg_num}, 1, true);
851 tcg_gen_gvec_mov(MO_64, {self.hvx_off()},
852 vreg_src_off(ctx, {self.reg_num}),
853 sizeof(MMVector), sizeof(MMVector));
854 """))
855 if not skip_qemu_helper(tag):
856 f.write(code_fmt(f"""\
857 TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
858 tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
859 """))
860 def gen_zero(self, f):
861 f.write(code_fmt(f"""\
862 tcg_gen_gvec_dup_imm(MO_64, {self.hvx_off()},
863 sizeof(MMVector), sizeof(MMVector), 0);
864 """))
865 def gen_write(self, f, tag):
866 pass
867 def helper_hvx_desc(self, f):
868 f.write(code_fmt(f"""\
869 /* {self.reg_tcg()} is *(MMVector *)({self.helper_arg_name()}) */
870 """))
871 def analyze_read(self, f, regno):
872 f.write(code_fmt(f"""\
873 ctx_log_vreg_read(ctx, {self.reg_num}, insn_has_hvx_helper);
874 """))
875 def analyze_write(self, f, tag, regno):
876 newv = hvx_newv(tag)
877 predicated = "true" if is_predicated(tag) else "false"
878 f.write(code_fmt(f"""\
879 ctx_log_vreg_write(ctx, {self.reg_num}, {newv}, {predicated},
880 insn_has_hvx_helper);
881 """))
882
883 class VRegTmp(Register, Hvx, ReadWrite):
884 def decl_tcg(self, f, tag, regno):
885 self.decl_reg_num(f, regno)
886 f.write(code_fmt(f"""\
887 const intptr_t {self.hvx_off()} = offsetof(CPUHexagonState, vtmp);
888 """))
889 if not skip_qemu_helper(tag):
890 f.write(code_fmt(f"""\
891 TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
892 tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
893 tcg_gen_gvec_mov(MO_64, {self.hvx_off()},
894 vreg_src_off(ctx, {self.reg_num}),
895 sizeof(MMVector), sizeof(MMVector));
896 """))
897 def gen_zero(self, f):
898 f.write(code_fmt(f"""\
899 tcg_gen_gvec_dup_imm(MO_64, {self.hvx_off()},
900 sizeof(MMVector), sizeof(MMVector), 0);
901 """))
902 def gen_write(self, f, tag):
903 f.write(code_fmt(f"""\
904 gen_vreg_write(ctx, {self.hvx_off()}, {self.reg_num},
905 {hvx_newv(tag)});
906 """))
907 def helper_hvx_desc(self, f):
908 f.write(code_fmt(f"""\
909 /* {self.reg_tcg()} is *(MMVector *)({self.helper_arg_name()}) */
910 """))
911 def analyze_read(self, f, regno):
912 f.write(code_fmt(f"""\
913 ctx_log_vreg_read(ctx, {self.reg_num}, insn_has_hvx_helper);
914 """))
915 def analyze_write(self, f, tag, regno):
916 newv = hvx_newv(tag)
917 predicated = "true" if is_predicated(tag) else "false"
918 f.write(code_fmt(f"""\
919 ctx_log_vreg_write(ctx, {self.reg_num}, {newv}, {predicated},
920 insn_has_hvx_helper);
921 """))
922
923 class VRegPairDest(Register, Hvx, Dest):
924 def decl_tcg(self, f, tag, regno):
925 self.decl_reg_num(f, regno)
926 f.write(code_fmt(f"""\
927 const intptr_t {self.hvx_off()} =
928 {vreg_offset_func(tag)}(ctx, {self.reg_num}, 2, true);
929 """))
930 if not skip_qemu_helper(tag):
931 f.write(code_fmt(f"""\
932 TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
933 tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
934 """))
935 def gen_zero(self, f):
936 f.write(code_fmt(f"""\
937 tcg_gen_gvec_dup_imm(MO_64, {self.hvx_off()},
938 sizeof(MMVectorPair), sizeof(MMVectorPair), 0);
939 """))
940 def gen_write(self, f, tag):
941 pass
942 def helper_hvx_desc(self, f):
943 f.write(code_fmt(f"""\
944 /* {self.reg_tcg()} is *(MMVectorPair *)({self.helper_arg_name()}) */
945 """))
946 def analyze_write(self, f, tag, regno):
947 newv = hvx_newv(tag)
948 predicated = "true" if is_predicated(tag) else "false"
949 f.write(code_fmt(f"""\
950 ctx_log_vreg_write_pair(ctx, {self.reg_num}, {newv}, {predicated},
951 insn_has_hvx_helper);
952 """))
953
954 class VRegPairSource(Register, Hvx, OldSource):
955 def decl_tcg(self, f, tag, regno):
956 self.decl_reg_num(f, regno)
957 f.write(code_fmt(f"""\
958 const intptr_t {self.hvx_off()} =
959 offsetof(CPUHexagonState, {self.reg_tcg()});
960 tcg_gen_gvec_mov(MO_64, {self.hvx_off()},
961 vreg_src_off(ctx, {self.reg_num}),
962 sizeof(MMVector), sizeof(MMVector));
963 tcg_gen_gvec_mov(MO_64, {self.hvx_off()} + sizeof(MMVector),
964 vreg_src_off(ctx, {self.reg_num} ^ 1),
965 sizeof(MMVector), sizeof(MMVector));
966 """))
967 if not skip_qemu_helper(tag):
968 f.write(code_fmt(f"""\
969 TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
970 tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
971 """))
972 def helper_hvx_desc(self, f):
973 f.write(code_fmt(f"""\
974 /* {self.reg_tcg()} is *(MMVectorPair *)({self.helper_arg_name()}) */
975 """))
976 def analyze_read(self, f, regno):
977 f.write(code_fmt(f"""\
978 ctx_log_vreg_read_pair(ctx, {self.reg_num}, insn_has_hvx_helper);
979 """))
980
981 class VRegPairReadWrite(Register, Hvx, ReadWrite):
982 def decl_tcg(self, f, tag, regno):
983 self.decl_reg_num(f, regno)
984 f.write(code_fmt(f"""\
985 const intptr_t {self.hvx_off()} =
986 offsetof(CPUHexagonState, {self.reg_tcg()});
987 tcg_gen_gvec_mov(MO_64, {self.hvx_off()},
988 vreg_src_off(ctx, {self.reg_num}),
989 sizeof(MMVector), sizeof(MMVector));
990 tcg_gen_gvec_mov(MO_64, {self.hvx_off()} + sizeof(MMVector),
991 vreg_src_off(ctx, {self.reg_num} ^ 1),
992 sizeof(MMVector), sizeof(MMVector));
993 """))
994 if not skip_qemu_helper(tag):
995 f.write(code_fmt(f"""\
996 TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
997 tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
998 """))
999 def gen_zero(self, f):
1000 f.write(code_fmt(f"""\
1001 tcg_gen_gvec_dup_imm(MO_64, {self.hvx_off()},
1002 sizeof(MMVectorPair), sizeof(MMVectorPair), 0);
1003 """))
1004 def gen_write(self, f, tag):
1005 f.write(code_fmt(f"""\
1006 gen_vreg_write_pair(ctx, {self.hvx_off()}, {self.reg_num},
1007 {hvx_newv(tag)});
1008 """))
1009 def helper_hvx_desc(self, f):
1010 f.write(code_fmt(f"""\
1011 /* {self.reg_tcg()} is *(MMVectorPair *)({self.helper_arg_name()}) */
1012 """))
1013 def analyze_read(self, f, regno):
1014 f.write(code_fmt(f"""\
1015 ctx_log_vreg_read_pair(ctx, {self.reg_num}, insn_has_hvx_helper);
1016 """))
1017 def analyze_write(self, f, tag, regno):
1018 newv = hvx_newv(tag)
1019 predicated = "true" if is_predicated(tag) else "false"
1020 f.write(code_fmt(f"""\
1021 ctx_log_vreg_write_pair(ctx, {self.reg_num}, {newv}, {predicated},
1022 insn_has_hvx_helper);
1023 """))
1024
1025 class QRegDest(Register, Hvx, Dest):
1026 def decl_tcg(self, f, tag, regno):
1027 self.decl_reg_num(f, regno)
1028 f.write(code_fmt(f"""\
1029 const intptr_t {self.hvx_off()} =
1030 get_result_qreg(ctx, {self.reg_num});
1031 """))
1032 if not skip_qemu_helper(tag):
1033 f.write(code_fmt(f"""\
1034 TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
1035 tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
1036 """))
1037 def gen_write(self, f, tag):
1038 pass
1039 def helper_hvx_desc(self, f):
1040 f.write(code_fmt(f"""\
1041 /* {self.reg_tcg()} is *(MMQReg *)({self.helper_arg_name()}) */
1042 """))
1043 def analyze_write(self, f, tag, regno):
1044 f.write(code_fmt(f"""\
1045 ctx_log_qreg_write(ctx, {self.reg_num}, insn_has_hvx_helper);
1046 """))
1047
1048 class QRegSource(Register, Hvx, OldSource):
1049 def decl_tcg(self, f, tag, regno):
1050 self.decl_reg_num(f, regno)
1051 f.write(code_fmt(f"""\
1052 const intptr_t {self.hvx_off()} =
1053 offsetof(CPUHexagonState, QRegs[{self.reg_num}]);
1054 """))
1055 if not skip_qemu_helper(tag):
1056 f.write(code_fmt(f"""\
1057 TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
1058 tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
1059 """))
1060 def helper_hvx_desc(self, f):
1061 f.write(code_fmt(f"""\
1062 /* {self.reg_tcg()} is *(MMQReg *)({self.helper_arg_name()}) */
1063 """))
1064 def analyze_read(self, f, regno):
1065 f.write(code_fmt(f"""\
1066 ctx_log_qreg_read(ctx, {self.reg_num}, insn_has_hvx_helper);
1067 """))
1068
1069 class QRegReadWrite(Register, Hvx, ReadWrite):
1070 def decl_tcg(self, f, tag, regno):
1071 self.decl_reg_num(f, regno)
1072 f.write(code_fmt(f"""\
1073 const intptr_t {self.hvx_off()} =
1074 get_result_qreg(ctx, {self.reg_num});
1075 tcg_gen_gvec_mov(MO_64, {self.hvx_off()},
1076 offsetof(CPUHexagonState, QRegs[{self.reg_num}]),
1077 sizeof(MMQReg), sizeof(MMQReg));
1078 """))
1079 if not skip_qemu_helper(tag):
1080 f.write(code_fmt(f"""\
1081 TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
1082 tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
1083 """))
1084 def gen_write(self, f, tag):
1085 pass
1086 def helper_hvx_desc(self, f):
1087 f.write(code_fmt(f"""\
1088 /* {self.reg_tcg()} is *(MMQReg *)({self.helper_arg_name()}) */
1089 """))
1090 def analyze_read(self, f, regno):
1091 f.write(code_fmt(f"""\
1092 ctx_log_qreg_read(ctx, {self.reg_num}, insn_has_hvx_helper);
1093 """))
1094 def analyze_write(self, f, tag, regno):
1095 f.write(code_fmt(f"""\
1096 ctx_log_qreg_write(ctx, {self.reg_num}, insn_has_hvx_helper);
1097 """))
1098
1099 class GuestRegister(Register):
1100 pass
1101
1102 class GuestDest(GuestRegister, Single, Dest):
1103 def decl_tcg(self, f, tag, regno):
1104 self.decl_reg_num(f, regno)
1105 f.write(code_fmt(f"""\
1106 TCGv_i32 {self.reg_tcg()} = tcg_temp_new_i32();
1107 """))
1108 def gen_write(self, f, tag):
1109 f.write(code_fmt(f"""\
1110 gen_log_greg_write(ctx, {self.reg_num}, {self.reg_tcg()});
1111 """))
1112 def analyze_write(self, f, tag, regno):
1113 f.write(code_fmt(f"""\
1114 ctx_log_greg_write(ctx, {self.reg_num});
1115 """))
1116
1117 class GuestSource(GuestRegister, Single, OldSource):
1118 def decl_reg_num(self, f, regno):
1119 f.write(code_fmt(f"""\
1120 const int {self.reg_num} G_GNUC_UNUSED = insn->regno[{regno}];
1121 """))
1122 def decl_tcg(self, f, tag, regno):
1123 self.decl_reg_num(f, regno)
1124 f.write(code_fmt(f"""\
1125 TCGv_i32 {self.reg_tcg()} = tcg_temp_new_i32();
1126 gen_read_greg({self.reg_tcg()}, {self.reg_num});
1127 """))
1128 def analyze_read(self, f, regno):
1129 pass
1130
1131 class GuestPairDest(GuestRegister, Pair, Dest):
1132 def decl_tcg(self, f, tag, regno):
1133 self.decl_reg_num(f, regno)
1134 f.write(code_fmt(f"""\
1135 TCGv_i64 {self.reg_tcg()} = tcg_temp_new_i64();
1136 """))
1137 def gen_write(self, f, tag):
1138 f.write(code_fmt(f"""\
1139 gen_log_greg_write_pair(ctx, {self.reg_num}, {self.reg_tcg()});
1140 """))
1141 def analyze_write(self, f, tag, regno):
1142 f.write(code_fmt(f"""\
1143 ctx_log_greg_write_pair(ctx, {self.reg_num});
1144 """))
1145
1146 class GuestPairSource(GuestRegister, Pair, OldSource):
1147 def decl_reg_num(self, f, regno):
1148 f.write(code_fmt(f"""\
1149 const int {self.reg_num} G_GNUC_UNUSED = insn->regno[{regno}];
1150 """))
1151 def decl_tcg(self, f, tag, regno):
1152 self.decl_reg_num(f, regno)
1153 f.write(code_fmt(f"""\
1154 TCGv_i64 {self.reg_tcg()} = tcg_temp_new_i64();
1155 gen_read_greg_pair({self.reg_tcg()}, {self.reg_num});
1156 """))
1157 def analyze_read(self, f, regno):
1158 pass
1159
1160 class SystemDest(Register, Single, Dest):
1161 def decl_tcg(self, f, tag, regno):
1162 self.decl_reg_num(f, regno)
1163 f.write(code_fmt(f"""\
1164 TCGv_i32 {self.reg_tcg()} = tcg_temp_new_i32();
1165 """))
1166 def gen_write(self, f, tag):
1167 f.write(code_fmt(f"""\
1168 gen_log_sreg_write(ctx, {self.reg_num}, {self.reg_tcg()});
1169 """))
1170 def analyze_write(self, f, tag, regno):
1171 f.write(code_fmt(f"""\
1172 ctx_log_sreg_write(ctx, {self.reg_num});
1173 """))
1174
1175 class SystemSource(Register, Single, OldSource):
1176 def decl_reg_num(self, f, regno):
1177 f.write(code_fmt(f"""\
1178 const int {self.reg_num} G_GNUC_UNUSED = insn->regno[{regno}];
1179 """))
1180 def decl_tcg(self, f, tag, regno):
1181 self.decl_reg_num(f, regno)
1182 f.write(code_fmt(f"""\
1183 TCGv_i32 {self.reg_tcg()} = tcg_temp_new_i32();
1184 gen_read_sreg({self.reg_tcg()}, {self.reg_num});
1185 """))
1186 def analyze_read(self, f, regno):
1187 pass
1188
1189 class SystemPairDest(Register, Pair, Dest):
1190 def decl_tcg(self, f, tag, regno):
1191 self.decl_reg_num(f, regno)
1192 f.write(code_fmt(f"""\
1193 TCGv_i64 {self.reg_tcg()} = tcg_temp_new_i64();
1194 """))
1195 def gen_write(self, f, tag):
1196 f.write(code_fmt(f"""\
1197 gen_log_sreg_write_pair(ctx, {self.reg_num}, {self.reg_tcg()});
1198 """))
1199 def analyze_write(self, f, tag, regno):
1200 f.write(code_fmt(f"""\
1201 ctx_log_sreg_write_pair(ctx, {self.reg_num});
1202 """))
1203
1204 class SystemPairSource(Register, Pair, OldSource):
1205 def decl_reg_num(self, f, regno):
1206 f.write(code_fmt(f"""\
1207 const int {self.reg_num} G_GNUC_UNUSED = insn->regno[{regno}];
1208 """))
1209 def decl_tcg(self, f, tag, regno):
1210 self.decl_reg_num(f, regno)
1211 f.write(code_fmt(f"""\
1212 TCGv_i64 {self.reg_tcg()} = tcg_temp_new_i64();
1213 gen_read_sreg_pair({self.reg_tcg()}, {self.reg_num});
1214 """))
1215 def analyze_read(self, f, regno):
1216 pass
1217
1218 def init_registers():
1219 regs = {
1220 GprDest("R", "d"),
1221 GprDest("R", "e"),
1222 GprSource("R", "s"),
1223 GprSource("R", "t"),
1224 GprSource("R", "u"),
1225 GprSource("R", "v"),
1226 GprReadWrite("R", "x"),
1227 GprReadWrite("R", "y"),
1228 ControlDest("C", "d"),
1229 ControlSource("C", "s"),
1230 ModifierSource("M", "u"),
1231 PredDest("P", "d"),
1232 PredDest("P", "e"),
1233 PredSource("P", "s"),
1234 PredSource("P", "t"),
1235 PredSource("P", "u"),
1236 PredSource("P", "v"),
1237 PredReadWrite("P", "x"),
1238 PairDest("R", "dd"),
1239 PairDest("R", "ee"),
1240 PairSource("R", "ss"),
1241 PairSource("R", "tt"),
1242 PairReadWrite("R", "xx"),
1243 PairReadWrite("R", "yy"),
1244 ControlPairDest("C", "dd"),
1245 ControlPairSource("C", "ss"),
1246 VRegDest("V", "d"),
1247 VRegSource("V", "s"),
1248 VRegSource("V", "u"),
1249 VRegSource("V", "v"),
1250 VRegSource("V", "w"),
1251 VRegReadWrite("V", "x"),
1252 VRegTmp("V", "y"),
1253 VRegPairDest("V", "dd"),
1254 VRegPairSource("V", "uu"),
1255 VRegPairSource("V", "vv"),
1256 VRegPairReadWrite("V", "xx"),
1257 QRegDest("Q", "d"),
1258 QRegDest("Q", "e"),
1259 QRegSource("Q", "s"),
1260 QRegSource("Q", "t"),
1261 QRegSource("Q", "u"),
1262 QRegSource("Q", "v"),
1263 QRegReadWrite("Q", "x"),
1264
1265 # system regs
1266 GuestDest("G", "d"),
1267 GuestSource("G", "s"),
1268 GuestPairDest("G", "dd"),
1269 GuestPairSource("G", "ss"),
1270 SystemDest("S", "d"),
1271 SystemSource("S", "s"),
1272 SystemPairDest("S", "dd"),
1273 SystemPairSource("S", "ss"),
1274 }
1275 for reg in regs:
1276 registers[f"{reg.regtype}{reg.regid}"] = reg
1277
1278 new_regs = {
1279 GprNewSource("N", "s"),
1280 GprNewSource("N", "t"),
1281 PredNewSource("P", "t"),
1282 PredNewSource("P", "u"),
1283 PredNewSource("P", "v"),
1284 VRegNewSource("O", "s"),
1285 }
1286 for reg in new_regs:
1287 new_registers[f"{reg.regtype}{reg.regid}"] = reg
1288
1289 def is_new_reg(tag, regid):
1290 if regid[0] in "NO":
1291 return True
1292 return regid[0] == "P" and \
1293 f"{regid}N" in semdict[tag] and \
1294 f"{regid}V" not in semdict[tag]
1295
1296 def get_register(tag, regtype, regid, subtype=""):
1297 regid = f"{regtype}{regid}"
1298 is_new = is_new_reg(tag, regid)
1299 try:
1300 reg = new_registers[regid] if is_new else registers[regid]
1301 except KeyError:
1302 raise Exception(f"Unknown {'new ' if is_new else ''}register {regid}" +\
1303 f"from '{tag}' with syntax '{semdict[tag]}'") from None
1304 return reg
1305
1306 def helper_ret_type(tag, regs):
1307 ## If there is a scalar result, it is the return type
1308 return_type = HelperArg( "void", "void", "void")
1309 numscalarresults = 0
1310 for regtype, regid in regs:
1311 reg = get_register(tag, regtype, regid)
1312 if reg.is_written() and reg.is_scalar_reg():
1313 return_type = HelperArg(
1314 reg.helper_proto_type(),
1315 reg.reg_tcg(),
1316 reg.helper_arg_type()
1317 )
1318 if numscalarresults > 1:
1319 raise Exception("numscalarresults > 1")
1320 return return_type
1321
1322 def helper_args(tag, regs, imms):
1323 args = []
1324
1325 ## First argument is the CPU state
1326 if need_env(tag):
1327 args.append(HelperArg(
1328 "env",
1329 "tcg_env",
1330 "CPUHexagonState *env"
1331 ))
1332
1333 ## For predicated instructions, we pass in the destination register
1334 if is_predicated(tag):
1335 for regtype, regid in regs:
1336 reg = get_register(tag, regtype, regid)
1337 if reg.is_writeonly() and not reg.is_hvx_reg():
1338 args.append(reg.helper_arg())
1339
1340 ## Pass the HVX destination registers
1341 for regtype, regid in regs:
1342 reg = get_register(tag, regtype, regid)
1343 if reg.is_written() and reg.is_hvx_reg():
1344 args.append(reg.helper_arg())
1345
1346 ## Pass the source registers
1347 for regtype, regid in regs:
1348 reg = get_register(tag, regtype, regid)
1349 if reg.is_read() and not (reg.is_hvx_reg() and reg.is_readwrite()):
1350 args.append(reg.helper_arg())
1351
1352 ## Pass the immediates
1353 for immlett, bits, immshift in imms:
1354 args.append(HelperArg(
1355 "s32",
1356 f"tcg_constant_tl({imm_name(immlett)})",
1357 f"int32_t {imm_name(immlett)}"
1358 ))
1359
1360 ## Other stuff the helper might need
1361 if need_pkt_has_multi_cof(tag):
1362 args.append(HelperArg(
1363 "i32",
1364 "tcg_constant_tl(ctx->pkt.pkt_has_multi_cof)",
1365 "uint32_t pkt_has_multi_cof"
1366 ))
1367 if need_pkt_need_commit(tag):
1368 args.append(HelperArg(
1369 "i32",
1370 "tcg_constant_tl(ctx->need_commit)",
1371 "uint32_t pkt_need_commit"
1372 ))
1373 if need_PC(tag):
1374 args.append(HelperArg(
1375 "i32",
1376 "tcg_constant_tl(ctx->pkt.pc)",
1377 "target_ulong PC"
1378 ))
1379 if need_next_PC(tag):
1380 args.append(HelperArg(
1381 "i32",
1382 "tcg_constant_tl(ctx->next_PC)",
1383 "target_ulong next_PC"
1384 ))
1385 if need_p0(tag):
1386 args.append(HelperArg(
1387 "i32",
1388 "hex_pred[0]",
1389 "uint32_t P0"
1390 ))
1391 if need_sp(tag):
1392 args.append(HelperArg(
1393 "i32",
1394 "hex_gpr[HEX_REG_SP]",
1395 "uint32_t SP"
1396 ))
1397 if need_slot(tag):
1398 args.append(HelperArg(
1399 "i32",
1400 "gen_slotval(ctx)",
1401 "uint32_t slotval"
1402 ))
1403 if need_part1(tag):
1404 args.append(HelperArg(
1405 "i32",
1406 "tcg_constant_tl(insn->part1)"
1407 "uint32_t part1"
1408 ))
1409 return args
1410
1411
1412 def parse_common_args(desc):
1413 parser = argparse.ArgumentParser(desc)
1414 parser.add_argument("semantics", help="semantics file")
1415 parser.add_argument("overrides", help="overrides file")
1416 parser.add_argument("overrides_vec", help="vector overrides file")
1417 parser.add_argument("overrides_sys", help="system overrides file")
1418 parser.add_argument("out", help="output file")
1419 parser.add_argument("--idef-parser",
1420 help="file of instructions translated by idef-parser")
1421 args = parser.parse_args()
1422 read_semantics_file(args.semantics)
1423 read_overrides_file(args.overrides)
1424 read_overrides_file(args.overrides_vec)
1425 read_overrides_file(args.overrides_sys)
1426 if args.idef_parser:
1427 read_idef_parser_enabled_file(args.idef_parser)
1428 calculate_attribs()
1429 init_registers()
1430 return args