4 ## Copyright (c) 2024 Taylor Simpson <ltaylorsimpson@gmail.com>
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/>.
29 tag
: "".join(reversed(iset
.iset
[tag
]["enc"].replace(" ", "")))
31 if iset
.iset
[tag
]["enc"] != "MISSING ENCODING"
35 regre
= re
.compile(r
"((?<!DUP)[MNORCPQXSGVZA])([stuvwxyzdefg]+)([.]?[LlHh]?)(\d+S?)")
36 immre
= re
.compile(r
"[#]([rRsSuUm])(\d+)(?:[:](\d+))?")
39 def ordered_unique(l
):
40 return sorted(set(l
), key
=l
.index
)
44 return textwrap
.indent(textwrap
.dedent(txt
), " ")
49 def mark_which_imm_extended(f
, tag
):
50 immre
= re
.compile(r
"IMMEXT\([rRsSuUm]")
51 imm
= immre
.findall(hex_common
.semdict
[tag
])
53 # No extended operand found
55 letter
= re
.split("\\(", imm
[0])[1]
56 f
.write(code_fmt(f
"""\
57 insn->which_extended = {0 if letter.islower() else 1};
61 ## Generate the QEMU decodetree trans_<tag> function for each instruction
62 ## For A2_add: Rd32=add(Rs32,Rt32)
64 ## static bool trans_A2_add(DisasContext *ctx, arg_A2_add *args)
66 ## Insn *insn = ctx->insn;
67 ## insn->opcode = A2_add;
68 ## insn->regno[0] = args->Rd;
69 ## insn->regno[1] = args->Rs;
70 ## insn->regno[2] = args->Rt;
71 ## insn->new_read_idx = -1;
72 ## insn->dest_idx = 0;
73 ## insn->has_pred_dest = false;
77 def gen_trans_funcs(f
):
78 f
.write(f
"/* DO NOT MODIFY - This file is generated by {sys.argv[0]} */\n\n")
79 for tag
in sorted(encs
.keys(), key
=iset
.tags
.index
):
80 regs
= ordered_unique(regre
.findall(iset
.iset
[tag
]["syntax"]))
81 imms
= ordered_unique(immre
.findall(iset
.iset
[tag
]["syntax"]))
83 f
.write(textwrap
.dedent(f
"""\
84 static bool trans_{tag}(DisasContext *ctx, arg_{tag} *args)
86 Insn *insn = ctx->insn;
92 has_pred_dest
= "false"
93 for regno
, (reg_type
, reg_id
, *_
) in enumerate(regs
):
94 reg
= hex_common
.get_register(tag
, reg_type
, reg_id
)
95 f
.write(code_fmt(f
"""\
96 insn->regno[{regno}] = args->{reg_type}{reg_id};
98 if reg
.is_read() and reg
.is_new():
100 # dest_idx should be the first destination, so check for -1
101 if reg
.is_written() and dest_idx
== -1:
103 if reg_type
== "P" and reg
.is_written() and not reg
.is_read():
104 has_pred_dest
= "true"
107 mark_which_imm_extended(f
, tag
)
111 imm_letter
= "i" if imm_type
.islower() else "I"
112 immno
= 0 if imm_type
.islower() else 1
113 imm_shift
= int(imm
[2]) if imm
[2] else 0
115 f
.write(code_fmt(f
"""\
116 insn->immed[{immno}] =
117 shift_left(ctx, args->{imm_type}{imm_letter},
118 {imm_shift}, {immno});
121 f
.write(code_fmt(f
"""\
122 insn->immed[{immno}] = args->{imm_type}{imm_letter};
125 f
.write(code_fmt(f
"""\
126 insn->new_read_idx = {new_read_idx};
127 insn->dest_idx = {dest_idx};
128 insn->has_pred_dest = {has_pred_dest};
130 f
.write(textwrap
.dedent(f
"""\
136 if __name__
== "__main__":
137 hex_common
.read_semantics_file(sys
.argv
[1])
138 hex_common
.init_registers()
139 with
open(sys
.argv
[2], "w") as f
: