]>
Commit | Line | Data |
---|---|---|
10849c26 TS |
1 | #!/usr/bin/env python3 |
2 | ||
3 | ## | |
4 | ## Copyright(c) 2022-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 | ||
5bb322e2 | 25 | |
10849c26 TS |
26 | ## |
27 | ## Helpers for gen_analyze_func | |
28 | ## | |
29 | def is_predicated(tag): | |
5bb322e2 ML |
30 | return "A_CONDEXEC" in hex_common.attribdict[tag] |
31 | ||
10849c26 TS |
32 | |
33 | def analyze_opn_old(f, tag, regtype, regid, regno): | |
cd6c4edf | 34 | regN = f"{regtype}{regid}N" |
10849c26 | 35 | predicated = "true" if is_predicated(tag) else "false" |
5bb322e2 ML |
36 | if regtype == "R": |
37 | if regid in {"ss", "tt"}: | |
b9f0326b TS |
38 | f.write(f" const int {regN} = insn->regno[{regno}];\n") |
39 | f.write(f" ctx_log_reg_read_pair(ctx, {regN});\n") | |
5bb322e2 | 40 | elif regid in {"dd", "ee", "xx", "yy"}: |
cd6c4edf ML |
41 | f.write(f" const int {regN} = insn->regno[{regno}];\n") |
42 | f.write(f" ctx_log_reg_write_pair(ctx, {regN}, {predicated});\n") | |
5bb322e2 | 43 | elif regid in {"s", "t", "u", "v"}: |
b9f0326b TS |
44 | f.write(f" const int {regN} = insn->regno[{regno}];\n") |
45 | f.write(f" ctx_log_reg_read(ctx, {regN});\n") | |
5bb322e2 | 46 | elif regid in {"d", "e", "x", "y"}: |
cd6c4edf ML |
47 | f.write(f" const int {regN} = insn->regno[{regno}];\n") |
48 | f.write(f" ctx_log_reg_write(ctx, {regN}, {predicated});\n") | |
10849c26 | 49 | else: |
c3199390 | 50 | hex_common.bad_register(regtype, regid) |
5bb322e2 ML |
51 | elif regtype == "P": |
52 | if regid in {"s", "t", "u", "v"}: | |
b9f0326b TS |
53 | f.write(f" const int {regN} = insn->regno[{regno}];\n") |
54 | f.write(f" ctx_log_pred_read(ctx, {regN});\n") | |
5bb322e2 | 55 | elif regid in {"d", "e", "x"}: |
cd6c4edf ML |
56 | f.write(f" const int {regN} = insn->regno[{regno}];\n") |
57 | f.write(f" ctx_log_pred_write(ctx, {regN});\n") | |
10849c26 | 58 | else: |
c3199390 | 59 | hex_common.bad_register(regtype, regid) |
5bb322e2 ML |
60 | elif regtype == "C": |
61 | if regid == "ss": | |
62 | f.write( | |
b9f0326b TS |
63 | f" const int {regN} = insn->regno[{regno}] " |
64 | "+ HEX_REG_SA0;\n" | |
5bb322e2 | 65 | ) |
b9f0326b | 66 | f.write(f" ctx_log_reg_read_pair(ctx, {regN});\n") |
5bb322e2 ML |
67 | elif regid == "dd": |
68 | f.write(f" const int {regN} = insn->regno[{regno}] " "+ HEX_REG_SA0;\n") | |
cd6c4edf | 69 | f.write(f" ctx_log_reg_write_pair(ctx, {regN}, {predicated});\n") |
5bb322e2 ML |
70 | elif regid == "s": |
71 | f.write( | |
b9f0326b TS |
72 | f" const int {regN} = insn->regno[{regno}] " |
73 | "+ HEX_REG_SA0;\n" | |
5bb322e2 | 74 | ) |
b9f0326b | 75 | f.write(f" ctx_log_reg_read(ctx, {regN});\n") |
5bb322e2 ML |
76 | elif regid == "d": |
77 | f.write(f" const int {regN} = insn->regno[{regno}] " "+ HEX_REG_SA0;\n") | |
cd6c4edf | 78 | f.write(f" ctx_log_reg_write(ctx, {regN}, {predicated});\n") |
10849c26 | 79 | else: |
c3199390 | 80 | hex_common.bad_register(regtype, regid) |
5bb322e2 ML |
81 | elif regtype == "M": |
82 | if regid == "u": | |
b9f0326b TS |
83 | f.write(f" const int {regN} = insn->regno[{regno}];\n") |
84 | f.write(f" ctx_log_reg_read(ctx, {regN});\n") | |
10849c26 | 85 | else: |
c3199390 | 86 | hex_common.bad_register(regtype, regid) |
5bb322e2 | 87 | elif regtype == "V": |
4d6f8420 | 88 | newv = "EXT_DFL" |
5bb322e2 | 89 | if hex_common.is_new_result(tag): |
4d6f8420 | 90 | newv = "EXT_NEW" |
5bb322e2 | 91 | elif hex_common.is_tmp_result(tag): |
4d6f8420 | 92 | newv = "EXT_TMP" |
5bb322e2 | 93 | if regid in {"dd", "xx"}: |
cd6c4edf | 94 | f.write(f" const int {regN} = insn->regno[{regno}];\n") |
5bb322e2 ML |
95 | f.write( |
96 | f" ctx_log_vreg_write_pair(ctx, {regN}, {newv}, " f"{predicated});\n" | |
97 | ) | |
98 | elif regid in {"uu", "vv"}: | |
b9f0326b TS |
99 | f.write(f" const int {regN} = insn->regno[{regno}];\n") |
100 | f.write(f" ctx_log_vreg_read_pair(ctx, {regN});\n") | |
5bb322e2 | 101 | elif regid in {"s", "u", "v", "w"}: |
b9f0326b TS |
102 | f.write(f" const int {regN} = insn->regno[{regno}];\n") |
103 | f.write(f" ctx_log_vreg_read(ctx, {regN});\n") | |
5bb322e2 | 104 | elif regid in {"d", "x", "y"}: |
cd6c4edf | 105 | f.write(f" const int {regN} = insn->regno[{regno}];\n") |
5bb322e2 | 106 | f.write(f" ctx_log_vreg_write(ctx, {regN}, {newv}, " f"{predicated});\n") |
10849c26 | 107 | else: |
c3199390 | 108 | hex_common.bad_register(regtype, regid) |
5bb322e2 ML |
109 | elif regtype == "Q": |
110 | if regid in {"d", "e", "x"}: | |
cd6c4edf ML |
111 | f.write(f" const int {regN} = insn->regno[{regno}];\n") |
112 | f.write(f" ctx_log_qreg_write(ctx, {regN});\n") | |
5bb322e2 | 113 | elif regid in {"s", "t", "u", "v"}: |
b9f0326b TS |
114 | f.write(f" const int {regN} = insn->regno[{regno}];\n") |
115 | f.write(f" ctx_log_qreg_read(ctx, {regN});\n") | |
10849c26 | 116 | else: |
c3199390 | 117 | hex_common.bad_register(regtype, regid) |
5bb322e2 ML |
118 | elif regtype == "G": |
119 | if regid in {"dd"}: | |
cd6c4edf | 120 | f.write(f"// const int {regN} = insn->regno[{regno}];\n") |
5bb322e2 | 121 | elif regid in {"d"}: |
cd6c4edf | 122 | f.write(f"// const int {regN} = insn->regno[{regno}];\n") |
5bb322e2 | 123 | elif regid in {"ss"}: |
cd6c4edf | 124 | f.write(f"// const int {regN} = insn->regno[{regno}];\n") |
5bb322e2 | 125 | elif regid in {"s"}: |
cd6c4edf | 126 | f.write(f"// const int {regN} = insn->regno[{regno}];\n") |
10849c26 | 127 | else: |
c3199390 | 128 | hex_common.bad_register(regtype, regid) |
5bb322e2 ML |
129 | elif regtype == "S": |
130 | if regid in {"dd"}: | |
cd6c4edf | 131 | f.write(f"// const int {regN} = insn->regno[{regno}];\n") |
5bb322e2 | 132 | elif regid in {"d"}: |
cd6c4edf | 133 | f.write(f"// const int {regN} = insn->regno[{regno}];\n") |
5bb322e2 | 134 | elif regid in {"ss"}: |
cd6c4edf | 135 | f.write(f"// const int {regN} = insn->regno[{regno}];\n") |
5bb322e2 | 136 | elif regid in {"s"}: |
cd6c4edf | 137 | f.write(f"// const int {regN} = insn->regno[{regno}];\n") |
10849c26 | 138 | else: |
c3199390 | 139 | hex_common.bad_register(regtype, regid) |
10849c26 | 140 | else: |
c3199390 | 141 | hex_common.bad_register(regtype, regid) |
10849c26 | 142 | |
5bb322e2 | 143 | |
10849c26 | 144 | def analyze_opn_new(f, tag, regtype, regid, regno): |
cd6c4edf | 145 | regN = f"{regtype}{regid}N" |
5bb322e2 ML |
146 | if regtype == "N": |
147 | if regid in {"s", "t"}: | |
b9f0326b TS |
148 | f.write(f" const int {regN} = insn->regno[{regno}];\n") |
149 | f.write(f" ctx_log_reg_read(ctx, {regN});\n") | |
10849c26 | 150 | else: |
c3199390 | 151 | hex_common.bad_register(regtype, regid) |
5bb322e2 ML |
152 | elif regtype == "P": |
153 | if regid in {"t", "u", "v"}: | |
b9f0326b TS |
154 | f.write(f" const int {regN} = insn->regno[{regno}];\n") |
155 | f.write(f" ctx_log_pred_read(ctx, {regN});\n") | |
10849c26 | 156 | else: |
c3199390 | 157 | hex_common.bad_register(regtype, regid) |
5bb322e2 ML |
158 | elif regtype == "O": |
159 | if regid == "s": | |
b9f0326b TS |
160 | f.write(f" const int {regN} = insn->regno[{regno}];\n") |
161 | f.write(f" ctx_log_vreg_read(ctx, {regN});\n") | |
10849c26 | 162 | else: |
c3199390 | 163 | hex_common.bad_register(regtype, regid) |
10849c26 | 164 | else: |
c3199390 | 165 | hex_common.bad_register(regtype, regid) |
10849c26 | 166 | |
5bb322e2 | 167 | |
3608c241 | 168 | def analyze_opn(f, tag, regtype, regid, i): |
5bb322e2 | 169 | if hex_common.is_pair(regid): |
10849c26 | 170 | analyze_opn_old(f, tag, regtype, regid, i) |
5bb322e2 | 171 | elif hex_common.is_single(regid): |
10849c26 | 172 | if hex_common.is_old_val(regtype, regid, tag): |
5bb322e2 | 173 | analyze_opn_old(f, tag, regtype, regid, i) |
10849c26 TS |
174 | elif hex_common.is_new_val(regtype, regid, tag): |
175 | analyze_opn_new(f, tag, regtype, regid, i) | |
176 | else: | |
3608c241 | 177 | hex_common.bad_register(regtype, regid) |
10849c26 | 178 | else: |
3608c241 | 179 | hex_common.bad_register(regtype, regid) |
10849c26 | 180 | |
5bb322e2 | 181 | |
10849c26 TS |
182 | ## |
183 | ## Generate the code to analyze the instruction | |
184 | ## For A2_add: Rd32=add(Rs32,Rt32), { RdV=RsV+RtV;} | |
185 | ## We produce: | |
186 | ## static void analyze_A2_add(DisasContext *ctx) | |
187 | ## { | |
188 | ## Insn *insn G_GNUC_UNUSED = ctx->insn; | |
189 | ## const int RdN = insn->regno[0]; | |
190 | ## ctx_log_reg_write(ctx, RdN, false); | |
b9f0326b TS |
191 | ## const int RsN = insn->regno[1]; |
192 | ## ctx_log_reg_read(ctx, RsN); | |
193 | ## const int RtN = insn->regno[2]; | |
194 | ## ctx_log_reg_read(ctx, RtN); | |
10849c26 TS |
195 | ## } |
196 | ## | |
197 | def gen_analyze_func(f, tag, regs, imms): | |
cd6c4edf | 198 | f.write(f"static void analyze_{tag}(DisasContext *ctx)\n") |
5bb322e2 | 199 | f.write("{\n") |
10849c26 TS |
200 | |
201 | f.write(" Insn *insn G_GNUC_UNUSED = ctx->insn;\n") | |
202 | ||
5bb322e2 | 203 | i = 0 |
10849c26 | 204 | ## Analyze all the registers |
3608c241 MTB |
205 | for regtype, regid in regs: |
206 | analyze_opn(f, tag, regtype, regid, i) | |
10849c26 TS |
207 | i += 1 |
208 | ||
5bb322e2 ML |
209 | has_generated_helper = not hex_common.skip_qemu_helper( |
210 | tag | |
211 | ) and not hex_common.is_idef_parser_enabled(tag) | |
10849c26 | 212 | |
d05d5eeb TS |
213 | ## Mark HVX instructions with generated helpers |
214 | if (has_generated_helper and | |
215 | "A_CVI" in hex_common.attribdict[tag]): | |
216 | f.write(" ctx->has_hvx_helper = true;\n") | |
217 | ||
10849c26 TS |
218 | f.write("}\n\n") |
219 | ||
5bb322e2 | 220 | |
10849c26 TS |
221 | def main(): |
222 | hex_common.read_semantics_file(sys.argv[1]) | |
223 | hex_common.read_attribs_file(sys.argv[2]) | |
224 | hex_common.read_overrides_file(sys.argv[3]) | |
225 | hex_common.read_overrides_file(sys.argv[4]) | |
226 | ## Whether or not idef-parser is enabled is | |
227 | ## determined by the number of arguments to | |
228 | ## this script: | |
229 | ## | |
230 | ## 5 args. -> not enabled, | |
231 | ## 6 args. -> idef-parser enabled. | |
232 | ## | |
233 | ## The 6:th arg. then holds a list of the successfully | |
234 | ## parsed instructions. | |
235 | is_idef_parser_enabled = len(sys.argv) > 6 | |
236 | if is_idef_parser_enabled: | |
237 | hex_common.read_idef_parser_enabled_file(sys.argv[5]) | |
238 | hex_common.calculate_attribs() | |
239 | tagregs = hex_common.get_tagregs() | |
240 | tagimms = hex_common.get_tagimms() | |
241 | ||
5bb322e2 | 242 | with open(sys.argv[-1], "w") as f: |
10849c26 TS |
243 | f.write("#ifndef HEXAGON_TCG_FUNCS_H\n") |
244 | f.write("#define HEXAGON_TCG_FUNCS_H\n\n") | |
245 | ||
246 | for tag in hex_common.tags: | |
247 | gen_analyze_func(f, tag, tagregs[tag], tagimms[tag]) | |
248 | ||
249 | f.write("#endif /* HEXAGON_TCG_FUNCS_H */\n") | |
250 | ||
5bb322e2 | 251 | |
10849c26 TS |
252 | if __name__ == "__main__": |
253 | main() |