]> git.proxmox.com Git - mirror_qemu.git/blame - target/hexagon/gen_analyze_funcs.py
Hexagon (target/hexagon) Improve code gen for predicated HVX instructions
[mirror_qemu.git] / target / hexagon / gen_analyze_funcs.py
CommitLineData
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
20import sys
21import re
22import string
23import hex_common
24
25##
26## Helpers for gen_analyze_func
27##
28def is_predicated(tag):
29 return 'A_CONDEXEC' in hex_common.attribdict[tag]
30
31def analyze_opn_old(f, tag, regtype, regid, regno):
32 regN = "%s%sN" % (regtype, regid)
33 predicated = "true" if is_predicated(tag) else "false"
34 if (regtype == "R"):
35 if (regid in {"ss", "tt"}):
36 f.write("// const int %s = insn->regno[%d];\n" % \
37 (regN, regno))
38 elif (regid in {"dd", "ee", "xx", "yy"}):
39 f.write(" const int %s = insn->regno[%d];\n" % (regN, regno))
40 f.write(" ctx_log_reg_write_pair(ctx, %s, %s);\n" % \
41 (regN, predicated))
42 elif (regid in {"s", "t", "u", "v"}):
43 f.write("// const int %s = insn->regno[%d];\n" % \
44 (regN, regno))
45 elif (regid in {"d", "e", "x", "y"}):
46 f.write(" const int %s = insn->regno[%d];\n" % (regN, regno))
47 f.write(" ctx_log_reg_write(ctx, %s, %s);\n" % \
48 (regN, predicated))
49 else:
50 print("Bad register parse: ", regtype, regid)
51 elif (regtype == "P"):
52 if (regid in {"s", "t", "u", "v"}):
53 f.write("// const int %s = insn->regno[%d];\n" % \
54 (regN, regno))
55 elif (regid in {"d", "e", "x"}):
56 f.write(" const int %s = insn->regno[%d];\n" % (regN, regno))
57 f.write(" ctx_log_pred_write(ctx, %s);\n" % (regN))
58 else:
59 print("Bad register parse: ", regtype, regid)
60 elif (regtype == "C"):
61 if (regid == "ss"):
62 f.write("// const int %s = insn->regno[%d] + HEX_REG_SA0;\n" % \
63 (regN, regno))
64 elif (regid == "dd"):
65 f.write(" const int %s = insn->regno[%d] + HEX_REG_SA0;\n" % \
66 (regN, regno))
67 f.write(" ctx_log_reg_write_pair(ctx, %s, %s);\n" % \
68 (regN, predicated))
69 elif (regid == "s"):
70 f.write("// const int %s = insn->regno[%d] + HEX_REG_SA0;\n" % \
71 (regN, regno))
72 elif (regid == "d"):
73 f.write(" const int %s = insn->regno[%d] + HEX_REG_SA0;\n" % \
74 (regN, regno))
75 f.write(" ctx_log_reg_write(ctx, %s, %s);\n" % \
76 (regN, predicated))
77 else:
78 print("Bad register parse: ", regtype, regid)
79 elif (regtype == "M"):
80 if (regid == "u"):
81 f.write("// const int %s = insn->regno[%d];\n"% \
82 (regN, regno))
83 else:
84 print("Bad register parse: ", regtype, regid)
85 elif (regtype == "V"):
4d6f8420
TS
86 newv = "EXT_DFL"
87 if (hex_common.is_new_result(tag)):
88 newv = "EXT_NEW"
89 elif (hex_common.is_tmp_result(tag)):
90 newv = "EXT_TMP"
10849c26 91 if (regid in {"dd", "xx"}):
4d6f8420 92 f.write(" const int %s = insn->regno[%d];\n" %\
10849c26 93 (regN, regno))
4d6f8420
TS
94 f.write(" ctx_log_vreg_write_pair(ctx, %s, %s, %s);\n" % \
95 (regN, newv, predicated))
10849c26
TS
96 elif (regid in {"uu", "vv"}):
97 f.write("// const int %s = insn->regno[%d];\n" % \
98 (regN, regno))
99 elif (regid in {"s", "u", "v", "w"}):
100 f.write("// const int %s = insn->regno[%d];\n" % \
101 (regN, regno))
102 elif (regid in {"d", "x", "y"}):
4d6f8420 103 f.write(" const int %s = insn->regno[%d];\n" % \
10849c26 104 (regN, regno))
4d6f8420
TS
105 f.write(" ctx_log_vreg_write(ctx, %s, %s, %s);\n" % \
106 (regN, newv, predicated))
10849c26
TS
107 else:
108 print("Bad register parse: ", regtype, regid)
109 elif (regtype == "Q"):
110 if (regid in {"d", "e", "x"}):
4d6f8420 111 f.write(" const int %s = insn->regno[%d];\n" % \
10849c26 112 (regN, regno))
c2b33d0b 113 f.write(" ctx_log_qreg_write(ctx, %s);\n" % (regN))
10849c26
TS
114 elif (regid in {"s", "t", "u", "v"}):
115 f.write("// const int %s = insn->regno[%d];\n" % \
116 (regN, regno))
117 else:
118 print("Bad register parse: ", regtype, regid)
119 elif (regtype == "G"):
120 if (regid in {"dd"}):
121 f.write("// const int %s = insn->regno[%d];\n" % \
122 (regN, regno))
123 elif (regid in {"d"}):
124 f.write("// const int %s = insn->regno[%d];\n" % \
125 (regN, regno))
126 elif (regid in {"ss"}):
127 f.write("// const int %s = insn->regno[%d];\n" % \
128 (regN, regno))
129 elif (regid in {"s"}):
130 f.write("// const int %s = insn->regno[%d];\n" % \
131 (regN, regno))
132 else:
133 print("Bad register parse: ", regtype, regid)
134 elif (regtype == "S"):
135 if (regid in {"dd"}):
136 f.write("// const int %s = insn->regno[%d];\n" % \
137 (regN, regno))
138 elif (regid in {"d"}):
139 f.write("// const int %s = insn->regno[%d];\n" % \
140 (regN, regno))
141 elif (regid in {"ss"}):
142 f.write("// const int %s = insn->regno[%d];\n" % \
143 (regN, regno))
144 elif (regid in {"s"}):
145 f.write("// const int %s = insn->regno[%d];\n" % \
146 (regN, regno))
147 else:
148 print("Bad register parse: ", regtype, regid)
149 else:
150 print("Bad register parse: ", regtype, regid)
151
152def analyze_opn_new(f, tag, regtype, regid, regno):
153 regN = "%s%sN" % (regtype, regid)
154 if (regtype == "N"):
155 if (regid in {"s", "t"}):
156 f.write("// const int %s = insn->regno[%d];\n" % \
157 (regN, regno))
158 else:
159 print("Bad register parse: ", regtype, regid)
160 elif (regtype == "P"):
161 if (regid in {"t", "u", "v"}):
162 f.write("// const int %s = insn->regno[%d];\n" % \
163 (regN, regno))
164 else:
165 print("Bad register parse: ", regtype, regid)
166 elif (regtype == "O"):
167 if (regid == "s"):
168 f.write("// const int %s = insn->regno[%d];\n" % \
169 (regN, regno))
170 else:
171 print("Bad register parse: ", regtype, regid)
172 else:
173 print("Bad register parse: ", regtype, regid)
174
175def analyze_opn(f, tag, regtype, regid, toss, numregs, i):
176 if (hex_common.is_pair(regid)):
177 analyze_opn_old(f, tag, regtype, regid, i)
178 elif (hex_common.is_single(regid)):
179 if hex_common.is_old_val(regtype, regid, tag):
180 analyze_opn_old(f,tag, regtype, regid, i)
181 elif hex_common.is_new_val(regtype, regid, tag):
182 analyze_opn_new(f, tag, regtype, regid, i)
183 else:
184 print("Bad register parse: ", regtype, regid, toss, numregs)
185 else:
186 print("Bad register parse: ", regtype, regid, toss, numregs)
187
188##
189## Generate the code to analyze the instruction
190## For A2_add: Rd32=add(Rs32,Rt32), { RdV=RsV+RtV;}
191## We produce:
192## static void analyze_A2_add(DisasContext *ctx)
193## {
194## Insn *insn G_GNUC_UNUSED = ctx->insn;
195## const int RdN = insn->regno[0];
196## ctx_log_reg_write(ctx, RdN, false);
197## // const int RsN = insn->regno[1];
198## // const int RtN = insn->regno[2];
199## }
200##
201def gen_analyze_func(f, tag, regs, imms):
202 f.write("static void analyze_%s(DisasContext *ctx)\n" %tag)
203 f.write('{\n')
204
205 f.write(" Insn *insn G_GNUC_UNUSED = ctx->insn;\n")
206
207 i=0
208 ## Analyze all the registers
209 for regtype, regid, toss, numregs in regs:
210 analyze_opn(f, tag, regtype, regid, toss, numregs, i)
211 i += 1
212
4d13bb51
TS
213 has_generated_helper = (not hex_common.skip_qemu_helper(tag) and
214 not hex_common.is_idef_parser_enabled(tag))
215 if (has_generated_helper and
216 'A_SCALAR_LOAD' in hex_common.attribdict[tag]):
217 f.write(" ctx->need_pkt_has_store_s1 = true;\n")
10849c26
TS
218
219 f.write("}\n\n")
220
221def 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
242 with open(sys.argv[-1], 'w') as f:
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
251if __name__ == "__main__":
252 main()