4 ## Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved.
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/>.
26 ## Helpers for gen_helper_function
29 f
.write(" uint32_t EA;\n")
31 def gen_helper_return_type(f
,regtype
,regid
,regno
):
32 if regno
> 1 : f
.write(", ")
35 def gen_helper_return_type_pair(f
,regtype
,regid
,regno
):
36 if regno
> 1 : f
.write(", ")
39 def gen_helper_arg(f
,regtype
,regid
,regno
):
40 if regno
> 0 : f
.write(", " )
41 f
.write("int32_t %s%sV" % (regtype
,regid
))
43 def gen_helper_arg_new(f
,regtype
,regid
,regno
):
44 if regno
>= 0 : f
.write(", " )
45 f
.write("int32_t %s%sN" % (regtype
,regid
))
47 def gen_helper_arg_pair(f
,regtype
,regid
,regno
):
48 if regno
>= 0 : f
.write(", ")
49 f
.write("int64_t %s%sV" % (regtype
,regid
))
51 def gen_helper_arg_ext(f
,regtype
,regid
,regno
):
52 if regno
> 0 : f
.write(", ")
53 f
.write("void *%s%sV_void" % (regtype
,regid
))
55 def gen_helper_arg_ext_pair(f
,regtype
,regid
,regno
):
56 if regno
> 0 : f
.write(", ")
57 f
.write("void *%s%sV_void" % (regtype
,regid
))
59 def gen_helper_arg_opn(f
,regtype
,regid
,i
,tag
):
60 if (hex_common
.is_pair(regid
)):
61 if (hex_common
.is_hvx_reg(regtype
)):
62 gen_helper_arg_ext_pair(f
,regtype
,regid
,i
)
64 gen_helper_arg_pair(f
,regtype
,regid
,i
)
65 elif (hex_common
.is_single(regid
)):
66 if hex_common
.is_old_val(regtype
, regid
, tag
):
67 if (hex_common
.is_hvx_reg(regtype
)):
68 gen_helper_arg_ext(f
,regtype
,regid
,i
)
70 gen_helper_arg(f
,regtype
,regid
,i
)
71 elif hex_common
.is_new_val(regtype
, regid
, tag
):
72 gen_helper_arg_new(f
,regtype
,regid
,i
)
74 print("Bad register parse: ",regtype
,regid
,toss
,numregs
)
76 print("Bad register parse: ",regtype
,regid
,toss
,numregs
)
78 def gen_helper_arg_imm(f
,immlett
):
79 f
.write(", int32_t %s" % (hex_common
.imm_name(immlett
)))
81 def gen_helper_dest_decl(f
,regtype
,regid
,regno
,subfield
=""):
82 f
.write(" int32_t %s%sV%s = 0;\n" % \
83 (regtype
,regid
,subfield
))
85 def gen_helper_dest_decl_pair(f
,regtype
,regid
,regno
,subfield
=""):
86 f
.write(" int64_t %s%sV%s = 0;\n" % \
87 (regtype
,regid
,subfield
))
89 def gen_helper_dest_decl_ext(f
,regtype
,regid
):
91 f
.write(" /* %s%sV is *(MMQReg *)(%s%sV_void) */\n" % \
92 (regtype
,regid
,regtype
,regid
))
94 f
.write(" /* %s%sV is *(MMVector *)(%s%sV_void) */\n" % \
95 (regtype
,regid
,regtype
,regid
))
97 def gen_helper_dest_decl_ext_pair(f
,regtype
,regid
,regno
):
98 f
.write(" /* %s%sV is *(MMVectorPair *))%s%sV_void) */\n" % \
99 (regtype
,regid
,regtype
, regid
))
101 def gen_helper_dest_decl_opn(f
,regtype
,regid
,i
):
102 if (hex_common
.is_pair(regid
)):
103 if (hex_common
.is_hvx_reg(regtype
)):
104 gen_helper_dest_decl_ext_pair(f
,regtype
,regid
, i
)
106 gen_helper_dest_decl_pair(f
,regtype
,regid
,i
)
107 elif (hex_common
.is_single(regid
)):
108 if (hex_common
.is_hvx_reg(regtype
)):
109 gen_helper_dest_decl_ext(f
,regtype
,regid
)
111 gen_helper_dest_decl(f
,regtype
,regid
,i
)
113 print("Bad register parse: ",regtype
,regid
,toss
,numregs
)
115 def gen_helper_src_var_ext(f
,regtype
,regid
):
117 f
.write(" /* %s%sV is *(MMQReg *)(%s%sV_void) */\n" % \
118 (regtype
,regid
,regtype
,regid
))
120 f
.write(" /* %s%sV is *(MMVector *)(%s%sV_void) */\n" % \
121 (regtype
,regid
,regtype
,regid
))
123 def gen_helper_src_var_ext_pair(f
,regtype
,regid
,regno
):
124 f
.write(" /* %s%sV%s is *(MMVectorPair *)(%s%sV%s_void) */\n" % \
125 (regtype
,regid
,regno
,regtype
,regid
,regno
))
127 def gen_helper_return(f
,regtype
,regid
,regno
):
128 f
.write(" return %s%sV;\n" % (regtype
,regid
))
130 def gen_helper_return_pair(f
,regtype
,regid
,regno
):
131 f
.write(" return %s%sV;\n" % (regtype
,regid
))
133 def gen_helper_dst_write_ext(f
,regtype
,regid
):
136 def gen_helper_dst_write_ext_pair(f
,regtype
,regid
):
139 def gen_helper_return_opn(f
, regtype
, regid
, i
):
140 if (hex_common
.is_pair(regid
)):
141 if (hex_common
.is_hvx_reg(regtype
)):
142 gen_helper_dst_write_ext_pair(f
,regtype
,regid
)
144 gen_helper_return_pair(f
,regtype
,regid
,i
)
145 elif (hex_common
.is_single(regid
)):
146 if (hex_common
.is_hvx_reg(regtype
)):
147 gen_helper_dst_write_ext(f
,regtype
,regid
)
149 gen_helper_return(f
,regtype
,regid
,i
)
151 print("Bad register parse: ",regtype
,regid
,toss
,numregs
)
154 ## Generate the TCG code to call the helper
155 ## For A2_add: Rd32=add(Rs32,Rt32), { RdV=RsV+RtV;}
157 ## int32_t HELPER(A2_add)(CPUHexagonState *env, int32_t RsV, int32_t RtV)
159 ## uint32_t slot __attribute__(unused)) = 4;
162 ## COUNT_HELPER(A2_add);
166 def gen_helper_function(f
, tag
, tagregs
, tagimms
):
172 numscalarreadwrite
= 0
173 for regtype
,regid
,toss
,numregs
in regs
:
174 if (hex_common
.is_written(regid
)):
176 if (hex_common
.is_scalar_reg(regtype
)):
177 numscalarresults
+= 1
178 if (hex_common
.is_readwrite(regid
)):
179 if (hex_common
.is_scalar_reg(regtype
)):
180 numscalarreadwrite
+= 1
182 if (numscalarresults
> 1):
183 ## The helper is bogus when there is more than one result
184 f
.write("void HELPER(%s)(CPUHexagonState *env) { BOGUS_HELPER(%s); }\n"
187 ## The return type of the function is the type of the destination
188 ## register (if scalar)
190 for regtype
,regid
,toss
,numregs
in regs
:
191 if (hex_common
.is_written(regid
)):
192 if (hex_common
.is_pair(regid
)):
193 if (hex_common
.is_hvx_reg(regtype
)):
196 gen_helper_return_type_pair(f
,regtype
,regid
,i
)
197 elif (hex_common
.is_single(regid
)):
198 if (hex_common
.is_hvx_reg(regtype
)):
201 gen_helper_return_type(f
,regtype
,regid
,i
)
203 print("Bad register parse: ",regtype
,regid
,toss
,numregs
)
206 if (numscalarresults
== 0):
208 f
.write(" HELPER(%s)(CPUHexagonState *env" % tag
)
210 ## Arguments include the vector destination operands
212 for regtype
,regid
,toss
,numregs
in regs
:
213 if (hex_common
.is_written(regid
)):
214 if (hex_common
.is_pair(regid
)):
215 if (hex_common
.is_hvx_reg(regtype
)):
216 gen_helper_arg_ext_pair(f
,regtype
,regid
,i
)
219 elif (hex_common
.is_single(regid
)):
220 if (hex_common
.is_hvx_reg(regtype
)):
221 gen_helper_arg_ext(f
,regtype
,regid
,i
)
223 # This is the return value of the function
226 print("Bad register parse: ",regtype
,regid
,toss
,numregs
)
229 ## Arguments to the helper function are the source regs and immediates
230 for regtype
,regid
,toss
,numregs
in regs
:
231 if (hex_common
.is_read(regid
)):
232 if (hex_common
.is_hvx_reg(regtype
) and
233 hex_common
.is_readwrite(regid
)):
235 gen_helper_arg_opn(f
,regtype
,regid
,i
,tag
)
237 for immlett
,bits
,immshift
in imms
:
238 gen_helper_arg_imm(f
,immlett
)
241 if hex_common
.need_slot(tag
):
242 if i
> 0: f
.write(", ")
243 f
.write("uint32_t slot")
245 if hex_common
.need_part1(tag
):
246 if i
> 0: f
.write(", ")
247 f
.write("uint32_t part1")
249 if (not hex_common
.need_slot(tag
)):
250 f
.write(" uint32_t slot __attribute__((unused)) = 4;\n" )
251 if hex_common
.need_ea(tag
): gen_decl_ea(f
)
252 ## Declare the return variable
254 for regtype
,regid
,toss
,numregs
in regs
:
255 if (hex_common
.is_writeonly(regid
)):
256 gen_helper_dest_decl_opn(f
,regtype
,regid
,i
)
259 for regtype
,regid
,toss
,numregs
in regs
:
260 if (hex_common
.is_read(regid
)):
261 if (hex_common
.is_pair(regid
)):
262 if (hex_common
.is_hvx_reg(regtype
)):
263 gen_helper_src_var_ext_pair(f
,regtype
,regid
,i
)
264 elif (hex_common
.is_single(regid
)):
265 if (hex_common
.is_hvx_reg(regtype
)):
266 gen_helper_src_var_ext(f
,regtype
,regid
)
268 print("Bad register parse: ",regtype
,regid
,toss
,numregs
)
270 if 'A_FPOP' in hex_common
.attribdict
[tag
]:
271 f
.write(' arch_fpop_start(env);\n');
273 f
.write(" %s\n" % hex_common
.semdict
[tag
])
275 if 'A_FPOP' in hex_common
.attribdict
[tag
]:
276 f
.write(' arch_fpop_end(env);\n');
278 ## Save/return the return variable
279 for regtype
,regid
,toss
,numregs
in regs
:
280 if (hex_common
.is_written(regid
)):
281 gen_helper_return_opn(f
, regtype
, regid
, i
)
283 ## End of the helper definition
286 hex_common
.read_semantics_file(sys
.argv
[1])
287 hex_common
.read_attribs_file(sys
.argv
[2])
288 hex_common
.read_overrides_file(sys
.argv
[3])
289 hex_common
.read_overrides_file(sys
.argv
[4])
290 hex_common
.calculate_attribs()
291 tagregs
= hex_common
.get_tagregs()
292 tagimms
= hex_common
.get_tagimms()
294 with
open(sys
.argv
[5], 'w') as f
:
295 for tag
in hex_common
.tags
:
296 ## Skip the priv instructions
297 if ( "A_PRIV" in hex_common
.attribdict
[tag
] ) :
299 ## Skip the guest instructions
300 if ( "A_GUEST" in hex_common
.attribdict
[tag
] ) :
302 ## Skip the diag instructions
303 if ( tag
== "Y6_diag" ) :
305 if ( tag
== "Y6_diag0" ) :
307 if ( tag
== "Y6_diag1" ) :
309 if ( hex_common
.skip_qemu_helper(tag
) ):
312 gen_helper_function(f
, tag
, tagregs
, tagimms
)
314 if __name__
== "__main__":