9e94b86d240e1517a4d7f3ea9e87d713fc4fc481
[gem5.git] / src / arch / arm / isa / insts / fp.isa
1 // -*- mode:c++ -*-
2
3 // Copyright (c) 2010-2013,2016,2018-2019 ARM Limited
4 // All rights reserved
5 //
6 // The license below extends only to copyright in the software and shall
7 // not be construed as granting a license to any other intellectual
8 // property including but not limited to intellectual property relating
9 // to a hardware implementation of the functionality of the software
10 // licensed hereunder. You may use the software subject to the license
11 // terms below provided that you ensure that this notice is replicated
12 // unmodified and in its entirety in all distributions of the software,
13 // modified or unmodified, in source code or in binary form.
14 //
15 // Redistribution and use in source and binary forms, with or without
16 // modification, are permitted provided that the following conditions are
17 // met: redistributions of source code must retain the above copyright
18 // notice, this list of conditions and the following disclaimer;
19 // redistributions in binary form must reproduce the above copyright
20 // notice, this list of conditions and the following disclaimer in the
21 // documentation and/or other materials provided with the distribution;
22 // neither the name of the copyright holders nor the names of its
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37
38 output header {{
39
40 template <class Micro>
41 class VfpMacroRegRegOp : public VfpMacroOp
42 {
43 public:
44 VfpMacroRegRegOp(ExtMachInst _machInst, IntRegIndex _dest,
45 IntRegIndex _op1, bool _wide) :
46 VfpMacroOp("VfpMacroRegRegOp", _machInst, No_OpClass, _wide)
47 {
48 numMicroops = machInst.fpscrLen + 1;
49 assert(numMicroops > 1);
50 microOps = new StaticInstPtr[numMicroops];
51 for (unsigned i = 0; i < numMicroops; i++) {
52 VfpMicroMode mode = VfpMicroop;
53 if (i == 0)
54 mode = VfpFirstMicroop;
55 else if (i == numMicroops - 1)
56 mode = VfpLastMicroop;
57 microOps[i] = new Micro(_machInst, _dest, _op1, mode);
58 nextIdxs(_dest, _op1);
59 }
60 }
61 };
62
63 template <class VfpOp>
64 StaticInstPtr
65 decodeVfpRegRegOp(ExtMachInst machInst,
66 IntRegIndex dest, IntRegIndex op1, bool wide)
67 {
68 if (machInst.fpscrLen == 0 || VfpMacroOp::inScalarBank(dest)) {
69 return new VfpOp(machInst, dest, op1);
70 } else {
71 return new VfpMacroRegRegOp<VfpOp>(machInst, dest, op1, wide);
72 }
73 }
74
75 template <class Micro>
76 class VfpMacroRegImmOp : public VfpMacroOp
77 {
78 public:
79 VfpMacroRegImmOp(ExtMachInst _machInst, IntRegIndex _dest, uint64_t _imm,
80 bool _wide) :
81 VfpMacroOp("VfpMacroRegImmOp", _machInst, No_OpClass, _wide)
82 {
83 numMicroops = machInst.fpscrLen + 1;
84 microOps = new StaticInstPtr[numMicroops];
85 for (unsigned i = 0; i < numMicroops; i++) {
86 VfpMicroMode mode = VfpMicroop;
87 if (i == 0)
88 mode = VfpFirstMicroop;
89 else if (i == numMicroops - 1)
90 mode = VfpLastMicroop;
91 microOps[i] = new Micro(_machInst, _dest, _imm, mode);
92 nextIdxs(_dest);
93 }
94 }
95 };
96
97 template <class VfpOp>
98 StaticInstPtr
99 decodeVfpRegImmOp(ExtMachInst machInst,
100 IntRegIndex dest, uint64_t imm, bool wide)
101 {
102 if (machInst.fpscrLen == 0 || VfpMacroOp::inScalarBank(dest)) {
103 return new VfpOp(machInst, dest, imm);
104 } else {
105 return new VfpMacroRegImmOp<VfpOp>(machInst, dest, imm, wide);
106 }
107 }
108
109 template <class Micro>
110 class VfpMacroRegRegImmOp : public VfpMacroOp
111 {
112 public:
113 VfpMacroRegRegImmOp(ExtMachInst _machInst, IntRegIndex _dest,
114 IntRegIndex _op1, uint64_t _imm, bool _wide) :
115 VfpMacroOp("VfpMacroRegRegImmOp", _machInst, No_OpClass, _wide)
116 {
117 numMicroops = machInst.fpscrLen + 1;
118 microOps = new StaticInstPtr[numMicroops];
119 for (unsigned i = 0; i < numMicroops; i++) {
120 VfpMicroMode mode = VfpMicroop;
121 if (i == 0)
122 mode = VfpFirstMicroop;
123 else if (i == numMicroops - 1)
124 mode = VfpLastMicroop;
125 microOps[i] = new Micro(_machInst, _dest, _op1, _imm, mode);
126 nextIdxs(_dest, _op1);
127 }
128 }
129 };
130
131 template <class VfpOp>
132 StaticInstPtr
133 decodeVfpRegRegImmOp(ExtMachInst machInst, IntRegIndex dest,
134 IntRegIndex op1, uint64_t imm, bool wide)
135 {
136 if (machInst.fpscrLen == 0 || VfpMacroOp::inScalarBank(dest)) {
137 return new VfpOp(machInst, dest, op1, imm);
138 } else {
139 return new VfpMacroRegRegImmOp<VfpOp>(machInst, dest, op1, imm, wide);
140 }
141 }
142
143 template <class Micro>
144 class VfpMacroRegRegRegOp : public VfpMacroOp
145 {
146 public:
147 VfpMacroRegRegRegOp(ExtMachInst _machInst, IntRegIndex _dest,
148 IntRegIndex _op1, IntRegIndex _op2, bool _wide) :
149 VfpMacroOp("VfpMacroRegRegRegOp", _machInst, No_OpClass, _wide)
150 {
151 numMicroops = machInst.fpscrLen + 1;
152 microOps = new StaticInstPtr[numMicroops];
153 for (unsigned i = 0; i < numMicroops; i++) {
154 VfpMicroMode mode = VfpMicroop;
155 if (i == 0)
156 mode = VfpFirstMicroop;
157 else if (i == numMicroops - 1)
158 mode = VfpLastMicroop;
159 microOps[i] = new Micro(_machInst, _dest, _op1, _op2, mode);
160 nextIdxs(_dest, _op1, _op2);
161 }
162 }
163 };
164
165 template <class VfpOp>
166 StaticInstPtr
167 decodeVfpRegRegRegOp(ExtMachInst machInst, IntRegIndex dest,
168 IntRegIndex op1, IntRegIndex op2, bool wide)
169 {
170 if (machInst.fpscrLen == 0 || VfpMacroOp::inScalarBank(dest)) {
171 return new VfpOp(machInst, dest, op1, op2);
172 } else {
173 return new VfpMacroRegRegRegOp<VfpOp>(machInst, dest, op1, op2, wide);
174 }
175 }
176 }};
177
178 let {{
179
180 header_output = ""
181 decoder_output = ""
182 exec_output = ""
183
184 vmsrCode = vmsrEnabledCheckCode + '''
185 MiscDest = Op1;
186 '''
187
188 vmsrIop = InstObjParams("vmsr", "Vmsr", "FpRegRegImmOp",
189 { "code": vmsrCode,
190 "predicate_test": predicateTest,
191 "op_class": "SimdFloatMiscOp" },
192 ["IsSerializeAfter","IsNonSpeculative"])
193 header_output += FpRegRegImmOpDeclare.subst(vmsrIop);
194 decoder_output += FpRegRegImmOpConstructor.subst(vmsrIop);
195 exec_output += PredOpExecute.subst(vmsrIop);
196
197 vmsrFpscrCode = vmsrEnabledCheckCode + '''
198 Fpscr = Op1 & ~FpCondCodesMask;
199 FpCondCodes = Op1 & FpCondCodesMask;
200 '''
201 vmsrFpscrIop = InstObjParams("vmsr", "VmsrFpscr", "FpRegRegOp",
202 { "code": vmsrFpscrCode,
203 "predicate_test": predicateTest,
204 "op_class": "SimdFloatMiscOp" },
205 ["IsSerializeAfter","IsNonSpeculative",
206 "IsSquashAfter"])
207 header_output += FpRegRegOpDeclare.subst(vmsrFpscrIop);
208 decoder_output += FpRegRegOpConstructor.subst(vmsrFpscrIop);
209 exec_output += PredOpExecute.subst(vmsrFpscrIop);
210
211 vmrsCode = vmrsEnabledCheckCode + '''
212 CPSR cpsr = Cpsr;
213 SCR scr = Scr;
214 if (!inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP)) {
215 HCR hcr = Hcr;
216 bool hypTrap = false;
217 switch(xc->tcBase()->flattenRegId(RegId(MiscRegClass, op1)).index()) {
218 case MISCREG_FPSID:
219 hypTrap = hcr.tid0;
220 break;
221 case MISCREG_MVFR0:
222 case MISCREG_MVFR1:
223 hypTrap = hcr.tid3;
224 break;
225 }
226 if (hypTrap) {
227 return std::make_shared<HypervisorTrap>(machInst, imm,
228 EC_TRAPPED_CP10_MRC_VMRS);
229 }
230 }
231 Dest = MiscOp1;
232 '''
233
234 vmrsIop = InstObjParams("vmrs", "Vmrs", "FpRegRegImmOp",
235 { "code": vmrsCode,
236 "predicate_test": predicateTest,
237 "op_class": "SimdFloatMiscOp" },
238 ["IsSerializeBefore"])
239 header_output += FpRegRegImmOpDeclare.subst(vmrsIop);
240 decoder_output += FpRegRegImmOpConstructor.subst(vmrsIop);
241 exec_output += PredOpExecute.subst(vmrsIop);
242
243 vmrsFpscrIop = InstObjParams("vmrs", "VmrsFpscr", "FpRegRegOp",
244 { "code": vmrsEnabledCheckCode + \
245 "Dest = Fpscr | FpCondCodes;",
246 "predicate_test": predicateTest,
247 "op_class": "SimdFloatMiscOp" },
248 ["IsSerializeBefore"])
249 header_output += FpRegRegOpDeclare.subst(vmrsFpscrIop);
250 decoder_output += FpRegRegOpConstructor.subst(vmrsFpscrIop);
251 exec_output += PredOpExecute.subst(vmrsFpscrIop);
252
253 vmrsApsrFpscrCode = vfpEnabledCheckCode + '''
254 FPSCR fpscr = FpCondCodes;
255 CondCodesNZ = (fpscr.n << 1) | fpscr.z;
256 CondCodesC = fpscr.c;
257 CondCodesV = fpscr.v;
258 '''
259 vmrsApsrFpscrIop = InstObjParams("vmrs", "VmrsApsrFpscr", "PredOp",
260 { "code": vmrsApsrFpscrCode,
261 "predicate_test": predicateTest,
262 "op_class": "SimdFloatMiscOp" })
263 header_output += BasicDeclare.subst(vmrsApsrFpscrIop);
264 decoder_output += BasicConstructor.subst(vmrsApsrFpscrIop);
265 exec_output += PredOpExecute.subst(vmrsApsrFpscrIop);
266
267 vmovImmSCode = vfpEnabledCheckCode + '''
268 FpDest_uw = bits(imm, 31, 0);
269 '''
270 vmovImmSIop = InstObjParams("vmov", "VmovImmS", "FpRegImmOp",
271 { "code": vmovImmSCode,
272 "predicate_test": predicateTest,
273 "op_class": "SimdFloatMiscOp" }, [])
274 header_output += FpRegImmOpDeclare.subst(vmovImmSIop);
275 decoder_output += FpRegImmOpConstructor.subst(vmovImmSIop);
276 exec_output += PredOpExecute.subst(vmovImmSIop);
277
278 vmovImmDCode = vfpEnabledCheckCode + '''
279 FpDestP0_uw = bits(imm, 31, 0);
280 FpDestP1_uw = bits(imm, 63, 32);
281 '''
282 vmovImmDIop = InstObjParams("vmov", "VmovImmD", "FpRegImmOp",
283 { "code": vmovImmDCode,
284 "predicate_test": predicateTest,
285 "op_class": "SimdFloatMiscOp" }, [])
286 header_output += FpRegImmOpDeclare.subst(vmovImmDIop);
287 decoder_output += FpRegImmOpConstructor.subst(vmovImmDIop);
288 exec_output += PredOpExecute.subst(vmovImmDIop);
289
290 vmovImmQCode = vfpEnabledCheckCode + '''
291 FpDestP0_uw = bits(imm, 31, 0);
292 FpDestP1_uw = bits(imm, 63, 32);
293 FpDestP2_uw = bits(imm, 31, 0);
294 FpDestP3_uw = bits(imm, 63, 32);
295 '''
296 vmovImmQIop = InstObjParams("vmov", "VmovImmQ", "FpRegImmOp",
297 { "code": vmovImmQCode,
298 "predicate_test": predicateTest,
299 "op_class": "SimdFloatMiscOp" }, [])
300 header_output += FpRegImmOpDeclare.subst(vmovImmQIop);
301 decoder_output += FpRegImmOpConstructor.subst(vmovImmQIop);
302 exec_output += PredOpExecute.subst(vmovImmQIop);
303
304 vmovRegSCode = vfpEnabledCheckCode + '''
305 FpDest_uw = FpOp1_uw;
306 '''
307 vmovRegSIop = InstObjParams("vmov", "VmovRegS", "FpRegRegOp",
308 { "code": vmovRegSCode,
309 "predicate_test": predicateTest,
310 "op_class": "SimdFloatMiscOp" }, [])
311 header_output += FpRegRegOpDeclare.subst(vmovRegSIop);
312 decoder_output += FpRegRegOpConstructor.subst(vmovRegSIop);
313 exec_output += PredOpExecute.subst(vmovRegSIop);
314
315 vmovRegDCode = vfpEnabledCheckCode + '''
316 FpDestP0_uw = FpOp1P0_uw;
317 FpDestP1_uw = FpOp1P1_uw;
318 '''
319 vmovRegDIop = InstObjParams("vmov", "VmovRegD", "FpRegRegOp",
320 { "code": vmovRegDCode,
321 "predicate_test": predicateTest,
322 "op_class": "SimdFloatMiscOp" }, [])
323 header_output += FpRegRegOpDeclare.subst(vmovRegDIop);
324 decoder_output += FpRegRegOpConstructor.subst(vmovRegDIop);
325 exec_output += PredOpExecute.subst(vmovRegDIop);
326
327 vmovRegQCode = vfpEnabledCheckCode + '''
328 FpDestP0_uw = FpOp1P0_uw;
329 FpDestP1_uw = FpOp1P1_uw;
330 FpDestP2_uw = FpOp1P2_uw;
331 FpDestP3_uw = FpOp1P3_uw;
332 '''
333 vmovRegQIop = InstObjParams("vmov", "VmovRegQ", "FpRegRegOp",
334 { "code": vmovRegQCode,
335 "predicate_test": predicateTest,
336 "op_class": "SimdFloatMiscOp" }, [])
337 header_output += FpRegRegOpDeclare.subst(vmovRegQIop);
338 decoder_output += FpRegRegOpConstructor.subst(vmovRegQIop);
339 exec_output += PredOpExecute.subst(vmovRegQIop);
340
341 vmovCoreRegBCode = simdEnabledCheckCode + '''
342 FpDest_uw = insertBits(FpDest_uw, imm * 8 + 7, imm * 8, Op1_ub);
343 '''
344 vmovCoreRegBIop = InstObjParams("vmov", "VmovCoreRegB", "FpRegRegImmOp",
345 { "code": vmovCoreRegBCode,
346 "predicate_test": predicateTest,
347 "op_class": "SimdFloatMiscOp" }, [])
348 header_output += FpRegRegImmOpDeclare.subst(vmovCoreRegBIop);
349 decoder_output += FpRegRegImmOpConstructor.subst(vmovCoreRegBIop);
350 exec_output += PredOpExecute.subst(vmovCoreRegBIop);
351
352 vmovCoreRegHCode = simdEnabledCheckCode + '''
353 FpDest_uw = insertBits(FpDest_uw, imm * 16 + 15, imm * 16, Op1_uh);
354 '''
355 vmovCoreRegHIop = InstObjParams("vmov", "VmovCoreRegH", "FpRegRegImmOp",
356 { "code": vmovCoreRegHCode,
357 "predicate_test": predicateTest,
358 "op_class": "SimdFloatMiscOp" }, [])
359 header_output += FpRegRegImmOpDeclare.subst(vmovCoreRegHIop);
360 decoder_output += FpRegRegImmOpConstructor.subst(vmovCoreRegHIop);
361 exec_output += PredOpExecute.subst(vmovCoreRegHIop);
362
363 vmovCoreRegWCode = vfpEnabledCheckCode + '''
364 FpDest_uw = Op1_uw;
365 '''
366 vmovCoreRegWIop = InstObjParams("vmov", "VmovCoreRegW", "FpRegRegOp",
367 { "code": vmovCoreRegWCode,
368 "predicate_test": predicateTest,
369 "op_class": "SimdFloatMiscOp" }, [])
370 header_output += FpRegRegOpDeclare.subst(vmovCoreRegWIop);
371 decoder_output += FpRegRegOpConstructor.subst(vmovCoreRegWIop);
372 exec_output += PredOpExecute.subst(vmovCoreRegWIop);
373
374 vmovRegCoreUBCode = vfpEnabledCheckCode + '''
375 assert(imm < 4);
376 Dest = bits(FpOp1_uw, imm * 8 + 7, imm * 8);
377 '''
378 vmovRegCoreUBIop = InstObjParams("vmov", "VmovRegCoreUB", "FpRegRegImmOp",
379 { "code": vmovRegCoreUBCode,
380 "predicate_test": predicateTest,
381 "op_class": "SimdFloatMiscOp" }, [])
382 header_output += FpRegRegImmOpDeclare.subst(vmovRegCoreUBIop);
383 decoder_output += FpRegRegImmOpConstructor.subst(vmovRegCoreUBIop);
384 exec_output += PredOpExecute.subst(vmovRegCoreUBIop);
385
386 vmovRegCoreUHCode = vfpEnabledCheckCode + '''
387 assert(imm < 2);
388 Dest = bits(FpOp1_uw, imm * 16 + 15, imm * 16);
389 '''
390 vmovRegCoreUHIop = InstObjParams("vmov", "VmovRegCoreUH", "FpRegRegImmOp",
391 { "code": vmovRegCoreUHCode,
392 "predicate_test": predicateTest,
393 "op_class": "SimdFloatMiscOp" }, [])
394 header_output += FpRegRegImmOpDeclare.subst(vmovRegCoreUHIop);
395 decoder_output += FpRegRegImmOpConstructor.subst(vmovRegCoreUHIop);
396 exec_output += PredOpExecute.subst(vmovRegCoreUHIop);
397
398 vmovRegCoreSBCode = vfpEnabledCheckCode + '''
399 assert(imm < 4);
400 Dest = sext<8>(bits(FpOp1_uw, imm * 8 + 7, imm * 8));
401 '''
402 vmovRegCoreSBIop = InstObjParams("vmov", "VmovRegCoreSB", "FpRegRegImmOp",
403 { "code": vmovRegCoreSBCode,
404 "predicate_test": predicateTest,
405 "op_class": "SimdFloatMiscOp" }, [])
406 header_output += FpRegRegImmOpDeclare.subst(vmovRegCoreSBIop);
407 decoder_output += FpRegRegImmOpConstructor.subst(vmovRegCoreSBIop);
408 exec_output += PredOpExecute.subst(vmovRegCoreSBIop);
409
410 vmovRegCoreSHCode = vfpEnabledCheckCode + '''
411 assert(imm < 2);
412 Dest = sext<16>(bits(FpOp1_uw, imm * 16 + 15, imm * 16));
413 '''
414 vmovRegCoreSHIop = InstObjParams("vmov", "VmovRegCoreSH", "FpRegRegImmOp",
415 { "code": vmovRegCoreSHCode,
416 "predicate_test": predicateTest,
417 "op_class": "SimdFloatMiscOp" }, [])
418 header_output += FpRegRegImmOpDeclare.subst(vmovRegCoreSHIop);
419 decoder_output += FpRegRegImmOpConstructor.subst(vmovRegCoreSHIop);
420 exec_output += PredOpExecute.subst(vmovRegCoreSHIop);
421
422 vmovRegCoreWCode = vfpEnabledCheckCode + '''
423 Dest = FpOp1_uw;
424 '''
425 vmovRegCoreWIop = InstObjParams("vmov", "VmovRegCoreW", "FpRegRegOp",
426 { "code": vmovRegCoreWCode,
427 "predicate_test": predicateTest,
428 "op_class": "SimdFloatMiscOp" }, [])
429 header_output += FpRegRegOpDeclare.subst(vmovRegCoreWIop);
430 decoder_output += FpRegRegOpConstructor.subst(vmovRegCoreWIop);
431 exec_output += PredOpExecute.subst(vmovRegCoreWIop);
432
433 vmov2Reg2CoreCode = vfpEnabledCheckCode + '''
434 FpDestP0_uw = Op1_uw;
435 FpDestP1_uw = Op2_uw;
436 '''
437 vmov2Reg2CoreIop = InstObjParams("vmov", "Vmov2Reg2Core", "FpRegRegRegOp",
438 { "code": vmov2Reg2CoreCode,
439 "predicate_test": predicateTest,
440 "op_class": "SimdFloatMiscOp" }, [])
441 header_output += FpRegRegRegOpDeclare.subst(vmov2Reg2CoreIop);
442 decoder_output += FpRegRegRegOpConstructor.subst(vmov2Reg2CoreIop);
443 exec_output += PredOpExecute.subst(vmov2Reg2CoreIop);
444
445 vmov2Core2RegCode = vfpEnabledCheckCode + '''
446 Dest_uw = FpOp2P0_uw;
447 Op1_uw = FpOp2P1_uw;
448 '''
449 vmov2Core2RegIop = InstObjParams("vmov", "Vmov2Core2Reg", "FpRegRegRegOp",
450 { "code": vmov2Core2RegCode,
451 "predicate_test": predicateTest,
452 "op_class": "SimdFloatMiscOp" }, [])
453 header_output += FpRegRegRegOpDeclare.subst(vmov2Core2RegIop);
454 decoder_output += FpRegRegRegOpConstructor.subst(vmov2Core2RegIop);
455 exec_output += PredOpExecute.subst(vmov2Core2RegIop);
456 }};
457
458 let {{
459
460 header_output = ""
461 decoder_output = ""
462 exec_output = ""
463
464 singleSimpleCode = vfpEnabledCheckCode + '''
465 FPSCR fpscr M5_VAR_USED = (FPSCR) FpscrExc;
466 FpDest = %(op)s;
467 '''
468 singleCode = singleSimpleCode + '''
469 FpscrExc = fpscr;
470 '''
471 singleTernOp = vfpEnabledCheckCode + '''
472 FPSCR fpscr = (FPSCR) FpscrExc;
473 VfpSavedState state = prepFpState(fpscr.rMode);
474 float cOp1 = FpOp1;
475 float cOp2 = FpOp2;
476 float cOp3 = FpDestP0;
477 FpDestP0 = ternaryOp(fpscr, %(palam)s, %(op)s,
478 fpscr.fz, fpscr.dn, fpscr.rMode);
479 finishVfp(fpscr, state, fpscr.fz);
480 FpscrExc = fpscr;
481 '''
482 singleBinOp = "binaryOp(fpscr, FpOp1, FpOp2," + \
483 "%(func)s, fpscr.fz, fpscr.dn, fpscr.rMode)"
484 singleUnaryOp = "unaryOp(fpscr, FpOp1, %(func)s, fpscr.fz, fpscr.rMode)"
485 doubleCode = vfpEnabledCheckCode + '''
486 FPSCR fpscr M5_VAR_USED = (FPSCR) FpscrExc;
487 double dest = %(op)s;
488 FpDestP0_uw = dblLow(dest);
489 FpDestP1_uw = dblHi(dest);
490 FpscrExc = fpscr;
491 '''
492 doubleTernOp = vfpEnabledCheckCode + '''
493 FPSCR fpscr = (FPSCR) FpscrExc;
494 VfpSavedState state = prepFpState(fpscr.rMode);
495 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
496 double cOp2 = dbl(FpOp2P0_uw, FpOp2P1_uw);
497 double cOp3 = dbl(FpDestP0_uw, FpDestP1_uw);
498 double cDest = ternaryOp(fpscr, %(palam)s, %(op)s,
499 fpscr.fz, fpscr.dn, fpscr.rMode);
500 FpDestP0_uw = dblLow(cDest);
501 FpDestP1_uw = dblHi(cDest);
502 finishVfp(fpscr, state, fpscr.fz);
503 FpscrExc = fpscr;
504 '''
505 doubleBinOp = '''
506 binaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw),
507 dbl(FpOp2P0_uw, FpOp2P1_uw),
508 %(func)s, fpscr.fz, fpscr.dn, fpscr.rMode);
509 '''
510 doubleUnaryOp = '''
511 unaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw), %(func)s,
512 fpscr.fz, fpscr.rMode)
513 '''
514
515 def buildTernaryFpOp(Name, base, opClass, singleOp, doubleOp, paramStr):
516 global header_output, decoder_output, exec_output
517
518 code = singleTernOp % { "op": singleOp, "palam": paramStr }
519 sIop = InstObjParams(Name.lower() + "s", Name + "S", base,
520 { "code": code,
521 "predicate_test": predicateTest,
522 "op_class": opClass }, [])
523 code = doubleTernOp % { "op": doubleOp, "palam": paramStr }
524 dIop = InstObjParams(Name.lower() + "d", Name + "D", base,
525 { "code": code,
526 "predicate_test": predicateTest,
527 "op_class": opClass }, [])
528
529 declareTempl = eval(base + "Declare");
530 constructorTempl = eval(base + "Constructor");
531
532 for iop in sIop, dIop:
533 header_output += declareTempl.subst(iop)
534 decoder_output += constructorTempl.subst(iop)
535 exec_output += PredOpExecute.subst(iop)
536
537 buildTernaryFpOp("Vfma", "FpRegRegRegOp", "SimdFloatMultAccOp",
538 "fpMulAdd<float>", "fpMulAdd<double>", " cOp1, cOp2, cOp3" )
539 buildTernaryFpOp("Vfms", "FpRegRegRegOp", "SimdFloatMultAccOp",
540 "fpMulAdd<float>", "fpMulAdd<double>", "-cOp1, cOp2, cOp3" )
541 buildTernaryFpOp("Vfnma", "FpRegRegRegOp", "SimdFloatMultAccOp",
542 "fpMulAdd<float>", "fpMulAdd<double>", "-cOp1, cOp2, -cOp3" )
543 buildTernaryFpOp("Vfnms", "FpRegRegRegOp", "SimdFloatMultAccOp",
544 "fpMulAdd<float>", "fpMulAdd<double>", " cOp1, cOp2, -cOp3" )
545
546 def buildBinFpOp(name, Name, base, opClass, singleOp, doubleOp):
547 global header_output, decoder_output, exec_output
548
549 code = singleCode % { "op": singleBinOp }
550 code = code % { "func": singleOp }
551 sIop = InstObjParams(name + "s", Name + "S", base,
552 { "code": code,
553 "predicate_test": predicateTest,
554 "op_class": opClass }, [])
555 code = doubleCode % { "op": doubleBinOp }
556 code = code % { "func": doubleOp }
557 dIop = InstObjParams(name + "d", Name + "D", base,
558 { "code": code,
559 "predicate_test": predicateTest,
560 "op_class": opClass }, [])
561
562 declareTempl = eval(base + "Declare");
563 constructorTempl = eval(base + "Constructor");
564
565 for iop in sIop, dIop:
566 header_output += declareTempl.subst(iop)
567 decoder_output += constructorTempl.subst(iop)
568 exec_output += PredOpExecute.subst(iop)
569
570 buildBinFpOp("vadd", "Vadd", "FpRegRegRegOp", "SimdFloatAddOp", "fpAddS",
571 "fpAddD")
572 buildBinFpOp("vsub", "Vsub", "FpRegRegRegOp", "SimdFloatAddOp", "fpSubS",
573 "fpSubD")
574 buildBinFpOp("vdiv", "Vdiv", "FpRegRegRegOp", "SimdFloatDivOp", "fpDivS",
575 "fpDivD")
576 buildBinFpOp("vmul", "Vmul", "FpRegRegRegOp", "SimdFloatMultOp", "fpMulS",
577 "fpMulD")
578
579 def buildBinOp(name, base, opClass, op):
580 '''
581 Create backported aarch64 instructions that use fplib.
582
583 Because they are backported, these instructions are unconditional.
584 '''
585 global header_output, decoder_output, exec_output
586 inst_datas = [
587 (
588 "s",
589 '''
590 FpDest_uw = fplib%(op)s<>(FpOp1_uw, FpOp2_uw, fpscr);
591 '''
592 ),
593 (
594 "d",
595 '''
596 uint64_t op1 = ((uint64_t)FpOp1P0_uw |
597 ((uint64_t)FpOp1P1_uw << 32));
598 uint64_t op2 = ((uint64_t)FpOp2P0_uw |
599 ((uint64_t)FpOp2P1_uw << 32));
600 uint64_t dest = fplib%(op)s<>(op1, op2, fpscr);
601 FpDestP0_uw = dest;
602 FpDestP1_uw = dest >> 32;
603 '''
604 )
605 ]
606 Name = name[0].upper() + name[1:]
607 declareTempl = eval(base + "Declare");
608 constructorTempl = eval(base + "Constructor");
609 for size_suffix, code in inst_datas:
610 code = (
611 '''
612 FPSCR fpscr = (FPSCR)FpscrExc;
613 ''' +
614 code +
615 '''
616 FpscrExc = fpscr;
617 '''
618 )
619 iop = InstObjParams(
620 name + size_suffix,
621 Name + size_suffix.upper(),
622 base,
623 {
624 "code": code % {"op": op},
625 "op_class": opClass
626 },
627 []
628 )
629 header_output += declareTempl.subst(iop)
630 decoder_output += constructorTempl.subst(iop)
631 exec_output += BasicExecute.subst(iop)
632 ops = [
633 ("vminnm", "FpRegRegRegOp", "SimdFloatCmpOp", "MinNum"),
634 ("vmaxnm", "FpRegRegRegOp", "SimdFloatCmpOp", "MaxNum"),
635 ]
636 for op in ops:
637 buildBinOp(*op)
638
639 def buildUnaryFpOp(name, Name, base, opClass, singleOp, doubleOp = None):
640 if doubleOp is None:
641 doubleOp = singleOp
642 global header_output, decoder_output, exec_output
643
644 code = singleCode % { "op": singleUnaryOp }
645 code = code % { "func": singleOp }
646 sIop = InstObjParams(name + "s", Name + "S", base,
647 { "code": code,
648 "predicate_test": predicateTest,
649 "op_class": opClass }, [])
650 code = doubleCode % { "op": doubleUnaryOp }
651 code = code % { "func": doubleOp }
652 dIop = InstObjParams(name + "d", Name + "D", base,
653 { "code": code,
654 "predicate_test": predicateTest,
655 "op_class": opClass }, [])
656
657 declareTempl = eval(base + "Declare");
658 constructorTempl = eval(base + "Constructor");
659
660 for iop in sIop, dIop:
661 header_output += declareTempl.subst(iop)
662 decoder_output += constructorTempl.subst(iop)
663 exec_output += PredOpExecute.subst(iop)
664
665 buildUnaryFpOp("vsqrt", "Vsqrt", "FpRegRegOp", "SimdFloatSqrtOp", "sqrtf",
666 "sqrt")
667
668 def buildSimpleUnaryFpOp(name, Name, base, opClass, singleOp,
669 doubleOp = None):
670 if doubleOp is None:
671 doubleOp = singleOp
672 global header_output, decoder_output, exec_output
673
674 sIop = InstObjParams(name + "s", Name + "S", base,
675 { "code": singleSimpleCode % { "op": singleOp },
676 "predicate_test": predicateTest,
677 "op_class": opClass }, [])
678 dIop = InstObjParams(name + "d", Name + "D", base,
679 { "code": doubleCode % { "op": doubleOp },
680 "predicate_test": predicateTest,
681 "op_class": opClass }, [])
682
683 declareTempl = eval(base + "Declare");
684 constructorTempl = eval(base + "Constructor");
685
686 for iop in sIop, dIop:
687 header_output += declareTempl.subst(iop)
688 decoder_output += constructorTempl.subst(iop)
689 exec_output += PredOpExecute.subst(iop)
690
691 buildSimpleUnaryFpOp("vneg", "Vneg", "FpRegRegOp", "SimdFloatMiscOp",
692 "-FpOp1", "-dbl(FpOp1P0_uw, FpOp1P1_uw)")
693 buildSimpleUnaryFpOp("vabs", "Vabs", "FpRegRegOp", "SimdFloatMiscOp",
694 "fabsf(FpOp1)", "fabs(dbl(FpOp1P0_uw, FpOp1P1_uw))")
695 buildSimpleUnaryFpOp("vrintp", "VRIntP", "FpRegRegOp", "SimdFloatMiscOp",
696 "fplibRoundInt<uint32_t>(FpOp1, FPRounding_POSINF, false, fpscr)",
697 "fplibRoundInt<uint64_t>(dbl(FpOp1P0_uw, FpOp1P1_uw), " \
698 "FPRounding_POSINF, false, fpscr)"
699 )
700 buildSimpleUnaryFpOp("vrintm", "VRIntM", "FpRegRegOp", "SimdFloatMiscOp",
701 "fplibRoundInt<uint32_t>(FpOp1, FPRounding_NEGINF, false, fpscr)",
702 "fplibRoundInt<uint64_t>(dbl(FpOp1P0_uw, FpOp1P1_uw), " \
703 "FPRounding_NEGINF, false, fpscr)"
704 )
705 buildSimpleUnaryFpOp("vrinta", "VRIntA", "FpRegRegOp", "SimdFloatMiscOp",
706 "fplibRoundInt<uint32_t>(FpOp1, FPRounding_TIEAWAY, false, fpscr)",
707 "fplibRoundInt<uint64_t>(dbl(FpOp1P0_uw, FpOp1P1_uw), " \
708 "FPRounding_TIEAWAY, false, fpscr)"
709 )
710 buildSimpleUnaryFpOp("vrintn", "VRIntN", "FpRegRegOp", "SimdFloatMiscOp",
711 "fplibRoundInt<uint32_t>(FpOp1, FPRounding_TIEEVEN, false, fpscr)",
712 "fplibRoundInt<uint64_t>(dbl(FpOp1P0_uw, FpOp1P1_uw), " \
713 "FPRounding_TIEEVEN, false, fpscr)"
714 )
715 }};
716
717 let {{
718
719 header_output = ""
720 decoder_output = ""
721 exec_output = ""
722
723 vmlaSCode = vfpEnabledCheckCode + '''
724 FPSCR fpscr = (FPSCR) FpscrExc;
725 float mid = binaryOp(fpscr, FpOp1, FpOp2,
726 fpMulS, fpscr.fz, fpscr.dn, fpscr.rMode);
727 FpDest = binaryOp(fpscr, FpDest, mid, fpAddS,
728 fpscr.fz, fpscr.dn, fpscr.rMode);
729 FpscrExc = fpscr;
730 '''
731 vmlaSIop = InstObjParams("vmlas", "VmlaS", "FpRegRegRegOp",
732 { "code": vmlaSCode,
733 "predicate_test": predicateTest,
734 "op_class": "SimdFloatMultAccOp" }, [])
735 header_output += FpRegRegRegOpDeclare.subst(vmlaSIop);
736 decoder_output += FpRegRegRegOpConstructor.subst(vmlaSIop);
737 exec_output += PredOpExecute.subst(vmlaSIop);
738
739 vmlaDCode = vfpEnabledCheckCode + '''
740 FPSCR fpscr = (FPSCR) FpscrExc;
741 double mid = binaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw),
742 dbl(FpOp2P0_uw, FpOp2P1_uw),
743 fpMulD, fpscr.fz, fpscr.dn, fpscr.rMode);
744 double dest = binaryOp(fpscr, dbl(FpDestP0_uw, FpDestP1_uw),
745 mid, fpAddD, fpscr.fz,
746 fpscr.dn, fpscr.rMode);
747 FpDestP0_uw = dblLow(dest);
748 FpDestP1_uw = dblHi(dest);
749 FpscrExc = fpscr;
750 '''
751 vmlaDIop = InstObjParams("vmlad", "VmlaD", "FpRegRegRegOp",
752 { "code": vmlaDCode,
753 "predicate_test": predicateTest,
754 "op_class": "SimdFloatMultAccOp" }, [])
755 header_output += FpRegRegRegOpDeclare.subst(vmlaDIop);
756 decoder_output += FpRegRegRegOpConstructor.subst(vmlaDIop);
757 exec_output += PredOpExecute.subst(vmlaDIop);
758
759 vmlsSCode = vfpEnabledCheckCode + '''
760 FPSCR fpscr = (FPSCR) FpscrExc;
761 float mid = binaryOp(fpscr, FpOp1, FpOp2,
762 fpMulS, fpscr.fz, fpscr.dn, fpscr.rMode);
763 FpDest = binaryOp(fpscr, FpDest, -mid, fpAddS,
764 fpscr.fz, fpscr.dn, fpscr.rMode);
765 FpscrExc = fpscr;
766 '''
767 vmlsSIop = InstObjParams("vmlss", "VmlsS", "FpRegRegRegOp",
768 { "code": vmlsSCode,
769 "predicate_test": predicateTest,
770 "op_class": "SimdFloatMultAccOp" }, [])
771 header_output += FpRegRegRegOpDeclare.subst(vmlsSIop);
772 decoder_output += FpRegRegRegOpConstructor.subst(vmlsSIop);
773 exec_output += PredOpExecute.subst(vmlsSIop);
774
775 vmlsDCode = vfpEnabledCheckCode + '''
776 FPSCR fpscr = (FPSCR) FpscrExc;
777 double mid = binaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw),
778 dbl(FpOp2P0_uw, FpOp2P1_uw),
779 fpMulD, fpscr.fz, fpscr.dn, fpscr.rMode);
780 double dest = binaryOp(fpscr, dbl(FpDestP0_uw, FpDestP1_uw),
781 -mid, fpAddD, fpscr.fz,
782 fpscr.dn, fpscr.rMode);
783 FpDestP0_uw = dblLow(dest);
784 FpDestP1_uw = dblHi(dest);
785 FpscrExc = fpscr;
786 '''
787 vmlsDIop = InstObjParams("vmlsd", "VmlsD", "FpRegRegRegOp",
788 { "code": vmlsDCode,
789 "predicate_test": predicateTest,
790 "op_class": "SimdFloatMultAccOp" }, [])
791 header_output += FpRegRegRegOpDeclare.subst(vmlsDIop);
792 decoder_output += FpRegRegRegOpConstructor.subst(vmlsDIop);
793 exec_output += PredOpExecute.subst(vmlsDIop);
794
795 vnmlaSCode = vfpEnabledCheckCode + '''
796 FPSCR fpscr = (FPSCR) FpscrExc;
797 float mid = binaryOp(fpscr, FpOp1, FpOp2,
798 fpMulS, fpscr.fz, fpscr.dn, fpscr.rMode);
799 FpDest = binaryOp(fpscr, -FpDest, -mid, fpAddS,
800 fpscr.fz, fpscr.dn, fpscr.rMode);
801 FpscrExc = fpscr;
802 '''
803 vnmlaSIop = InstObjParams("vnmlas", "VnmlaS", "FpRegRegRegOp",
804 { "code": vnmlaSCode,
805 "predicate_test": predicateTest,
806 "op_class": "SimdFloatMultAccOp" }, [])
807 header_output += FpRegRegRegOpDeclare.subst(vnmlaSIop);
808 decoder_output += FpRegRegRegOpConstructor.subst(vnmlaSIop);
809 exec_output += PredOpExecute.subst(vnmlaSIop);
810
811 vnmlaDCode = vfpEnabledCheckCode + '''
812 FPSCR fpscr = (FPSCR) FpscrExc;
813 double mid = binaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw),
814 dbl(FpOp2P0_uw, FpOp2P1_uw),
815 fpMulD, fpscr.fz, fpscr.dn, fpscr.rMode);
816 double dest = binaryOp(fpscr, -dbl(FpDestP0_uw, FpDestP1_uw),
817 -mid, fpAddD, fpscr.fz,
818 fpscr.dn, fpscr.rMode);
819 FpDestP0_uw = dblLow(dest);
820 FpDestP1_uw = dblHi(dest);
821 FpscrExc = fpscr;
822 '''
823 vnmlaDIop = InstObjParams("vnmlad", "VnmlaD", "FpRegRegRegOp",
824 { "code": vnmlaDCode,
825 "predicate_test": predicateTest,
826 "op_class": "SimdFloatMultAccOp" }, [])
827 header_output += FpRegRegRegOpDeclare.subst(vnmlaDIop);
828 decoder_output += FpRegRegRegOpConstructor.subst(vnmlaDIop);
829 exec_output += PredOpExecute.subst(vnmlaDIop);
830
831 vnmlsSCode = vfpEnabledCheckCode + '''
832 FPSCR fpscr = (FPSCR) FpscrExc;
833 float mid = binaryOp(fpscr, FpOp1, FpOp2,
834 fpMulS, fpscr.fz, fpscr.dn, fpscr.rMode);
835 FpDest = binaryOp(fpscr, -FpDest, mid, fpAddS,
836 fpscr.fz, fpscr.dn, fpscr.rMode);
837 FpscrExc = fpscr;
838 '''
839 vnmlsSIop = InstObjParams("vnmlss", "VnmlsS", "FpRegRegRegOp",
840 { "code": vnmlsSCode,
841 "predicate_test": predicateTest,
842 "op_class": "SimdFloatMultAccOp" }, [])
843 header_output += FpRegRegRegOpDeclare.subst(vnmlsSIop);
844 decoder_output += FpRegRegRegOpConstructor.subst(vnmlsSIop);
845 exec_output += PredOpExecute.subst(vnmlsSIop);
846
847 vnmlsDCode = vfpEnabledCheckCode + '''
848 FPSCR fpscr = (FPSCR) FpscrExc;
849 double mid = binaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw),
850 dbl(FpOp2P0_uw, FpOp2P1_uw),
851 fpMulD, fpscr.fz, fpscr.dn, fpscr.rMode);
852 double dest = binaryOp(fpscr, -dbl(FpDestP0_uw, FpDestP1_uw),
853 mid, fpAddD, fpscr.fz,
854 fpscr.dn, fpscr.rMode);
855 FpDestP0_uw = dblLow(dest);
856 FpDestP1_uw = dblHi(dest);
857 FpscrExc = fpscr;
858 '''
859 vnmlsDIop = InstObjParams("vnmlsd", "VnmlsD", "FpRegRegRegOp",
860 { "code": vnmlsDCode,
861 "predicate_test": predicateTest,
862 "op_class": "SimdFloatMultAccOp" }, [])
863 header_output += FpRegRegRegOpDeclare.subst(vnmlsDIop);
864 decoder_output += FpRegRegRegOpConstructor.subst(vnmlsDIop);
865 exec_output += PredOpExecute.subst(vnmlsDIop);
866
867 vnmulSCode = vfpEnabledCheckCode + '''
868 FPSCR fpscr = (FPSCR) FpscrExc;
869 FpDest = -binaryOp(fpscr, FpOp1, FpOp2, fpMulS,
870 fpscr.fz, fpscr.dn, fpscr.rMode);
871 FpscrExc = fpscr;
872 '''
873 vnmulSIop = InstObjParams("vnmuls", "VnmulS", "FpRegRegRegOp",
874 { "code": vnmulSCode,
875 "predicate_test": predicateTest,
876 "op_class": "SimdFloatMultOp" }, [])
877 header_output += FpRegRegRegOpDeclare.subst(vnmulSIop);
878 decoder_output += FpRegRegRegOpConstructor.subst(vnmulSIop);
879 exec_output += PredOpExecute.subst(vnmulSIop);
880
881 vnmulDCode = vfpEnabledCheckCode + '''
882 FPSCR fpscr = (FPSCR) FpscrExc;
883 double dest = -binaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw),
884 dbl(FpOp2P0_uw, FpOp2P1_uw),
885 fpMulD, fpscr.fz, fpscr.dn,
886 fpscr.rMode);
887 FpDestP0_uw = dblLow(dest);
888 FpDestP1_uw = dblHi(dest);
889 FpscrExc = fpscr;
890 '''
891 vnmulDIop = InstObjParams("vnmuld", "VnmulD", "FpRegRegRegOp",
892 { "code": vnmulDCode,
893 "predicate_test": predicateTest,
894 "op_class": "SimdFloatMultOp" }, [])
895 header_output += FpRegRegRegOpDeclare.subst(vnmulDIop);
896 decoder_output += FpRegRegRegOpConstructor.subst(vnmulDIop);
897 exec_output += PredOpExecute.subst(vnmulDIop);
898 }};
899
900 let {{
901
902 header_output = ""
903 decoder_output = ""
904 exec_output = ""
905
906 vcvtUIntFpSCode = vfpEnabledCheckCode + '''
907 FPSCR fpscr = (FPSCR) FpscrExc;
908 VfpSavedState state = prepFpState(fpscr.rMode);
909 __asm__ __volatile__("" : "=m" (FpOp1_uw) : "m" (FpOp1_uw));
910 FpDest = FpOp1_uw;
911 __asm__ __volatile__("" :: "m" (FpDest));
912 finishVfp(fpscr, state, fpscr.fz);
913 FpscrExc = fpscr;
914 '''
915 vcvtUIntFpSIop = InstObjParams("vcvt", "VcvtUIntFpS", "FpRegRegOp",
916 { "code": vcvtUIntFpSCode,
917 "predicate_test": predicateTest,
918 "op_class": "SimdFloatCvtOp" }, [])
919 header_output += FpRegRegOpDeclare.subst(vcvtUIntFpSIop);
920 decoder_output += FpRegRegOpConstructor.subst(vcvtUIntFpSIop);
921 exec_output += PredOpExecute.subst(vcvtUIntFpSIop);
922
923 vcvtUIntFpDCode = vfpEnabledCheckCode + '''
924 FPSCR fpscr = (FPSCR) FpscrExc;
925 VfpSavedState state = prepFpState(fpscr.rMode);
926 __asm__ __volatile__("" : "=m" (FpOp1P0_uw) : "m" (FpOp1P0_uw));
927 double cDest = (uint64_t)FpOp1P0_uw;
928 __asm__ __volatile__("" :: "m" (cDest));
929 finishVfp(fpscr, state, fpscr.fz);
930 FpDestP0_uw = dblLow(cDest);
931 FpDestP1_uw = dblHi(cDest);
932 FpscrExc = fpscr;
933 '''
934 vcvtUIntFpDIop = InstObjParams("vcvt", "VcvtUIntFpD", "FpRegRegOp",
935 { "code": vcvtUIntFpDCode,
936 "predicate_test": predicateTest,
937 "op_class": "SimdFloatCvtOp" }, [])
938 header_output += FpRegRegOpDeclare.subst(vcvtUIntFpDIop);
939 decoder_output += FpRegRegOpConstructor.subst(vcvtUIntFpDIop);
940 exec_output += PredOpExecute.subst(vcvtUIntFpDIop);
941
942 vcvtSIntFpSCode = vfpEnabledCheckCode + '''
943 FPSCR fpscr = (FPSCR) FpscrExc;
944 VfpSavedState state = prepFpState(fpscr.rMode);
945 __asm__ __volatile__("" : "=m" (FpOp1_sw) : "m" (FpOp1_sw));
946 FpDest = FpOp1_sw;
947 __asm__ __volatile__("" :: "m" (FpDest));
948 finishVfp(fpscr, state, fpscr.fz);
949 FpscrExc = fpscr;
950 '''
951 vcvtSIntFpSIop = InstObjParams("vcvt", "VcvtSIntFpS", "FpRegRegOp",
952 { "code": vcvtSIntFpSCode,
953 "predicate_test": predicateTest,
954 "op_class": "SimdFloatCvtOp" }, [])
955 header_output += FpRegRegOpDeclare.subst(vcvtSIntFpSIop);
956 decoder_output += FpRegRegOpConstructor.subst(vcvtSIntFpSIop);
957 exec_output += PredOpExecute.subst(vcvtSIntFpSIop);
958
959 vcvtSIntFpDCode = vfpEnabledCheckCode + '''
960 FPSCR fpscr = (FPSCR) FpscrExc;
961 VfpSavedState state = prepFpState(fpscr.rMode);
962 __asm__ __volatile__("" : "=m" (FpOp1P0_sw) : "m" (FpOp1P0_sw));
963 double cDest = FpOp1P0_sw;
964 __asm__ __volatile__("" :: "m" (cDest));
965 finishVfp(fpscr, state, fpscr.fz);
966 FpDestP0_uw = dblLow(cDest);
967 FpDestP1_uw = dblHi(cDest);
968 FpscrExc = fpscr;
969 '''
970 vcvtSIntFpDIop = InstObjParams("vcvt", "VcvtSIntFpD", "FpRegRegOp",
971 { "code": vcvtSIntFpDCode,
972 "predicate_test": predicateTest,
973 "op_class": "SimdFloatCvtOp" }, [])
974 header_output += FpRegRegOpDeclare.subst(vcvtSIntFpDIop);
975 decoder_output += FpRegRegOpConstructor.subst(vcvtSIntFpDIop);
976 exec_output += PredOpExecute.subst(vcvtSIntFpDIop);
977
978 vjcvtSFixedFpDCode = vfpEnabledCheckCode + '''
979 FPSCR fpscr = (FPSCR) FpscrExc;
980 VfpSavedState state = prepFpState(fpscr.rMode);
981 uint64_t cOp1 = ((uint64_t)FpOp1P0_uw | ((uint64_t)FpOp1P1_uw << 32));
982 uint8_t nz;
983 FpDest_uw = fplibFPToFixedJS(cOp1, fpscr, false, nz);
984 finishVfp(fpscr, state, fpscr.fz);
985 FpCondCodes = fpscr & FpCondCodesMask;
986 FpscrExc = fpscr;
987 '''
988 vjcvtSFixedFpDIop = InstObjParams("vjcvt", "VjcvtSFixedFpD", "FpRegRegOp",
989 { "code": vjcvtSFixedFpDCode,
990 "predicate_test": predicateTest,
991 "op_class": "SimdFloatCvtOp" }, [])
992 header_output += FpRegRegOpDeclare.subst(vjcvtSFixedFpDIop);
993 decoder_output += FpRegRegOpConstructor.subst(vjcvtSFixedFpDIop);
994 exec_output += PredOpExecute.subst(vjcvtSFixedFpDIop);
995
996 vcvtFpUIntSRCode = vfpEnabledCheckCode + '''
997 FPSCR fpscr = (FPSCR) FpscrExc;
998 VfpSavedState state = prepFpState(fpscr.rMode);
999 vfpFlushToZero(fpscr, FpOp1);
1000 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1001 FpDest_uw = vfpFpToFixed<float>(FpOp1, false, 32, 0, false);
1002 __asm__ __volatile__("" :: "m" (FpDest_uw));
1003 finishVfp(fpscr, state, fpscr.fz);
1004 FpscrExc = fpscr;
1005 '''
1006 vcvtFpUIntSRIop = InstObjParams("vcvt", "VcvtFpUIntSR", "FpRegRegOp",
1007 { "code": vcvtFpUIntSRCode,
1008 "predicate_test": predicateTest,
1009 "op_class": "SimdFloatCvtOp" }, [])
1010 header_output += FpRegRegOpDeclare.subst(vcvtFpUIntSRIop);
1011 decoder_output += FpRegRegOpConstructor.subst(vcvtFpUIntSRIop);
1012 exec_output += PredOpExecute.subst(vcvtFpUIntSRIop);
1013
1014 vcvtFpUIntDRCode = vfpEnabledCheckCode + '''
1015 FPSCR fpscr = (FPSCR) FpscrExc;
1016 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1017 vfpFlushToZero(fpscr, cOp1);
1018 VfpSavedState state = prepFpState(fpscr.rMode);
1019 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1020 uint64_t result = vfpFpToFixed<double>(cOp1, false, 32, 0, false);
1021 __asm__ __volatile__("" :: "m" (result));
1022 finishVfp(fpscr, state, fpscr.fz);
1023 FpDestP0_uw = result;
1024 FpscrExc = fpscr;
1025 '''
1026 vcvtFpUIntDRIop = InstObjParams("vcvtr", "VcvtFpUIntDR", "FpRegRegOp",
1027 { "code": vcvtFpUIntDRCode,
1028 "predicate_test": predicateTest,
1029 "op_class": "SimdFloatCvtOp" }, [])
1030 header_output += FpRegRegOpDeclare.subst(vcvtFpUIntDRIop);
1031 decoder_output += FpRegRegOpConstructor.subst(vcvtFpUIntDRIop);
1032 exec_output += PredOpExecute.subst(vcvtFpUIntDRIop);
1033
1034 vcvtFpSIntSRCode = vfpEnabledCheckCode + '''
1035 FPSCR fpscr = (FPSCR) FpscrExc;
1036 VfpSavedState state = prepFpState(fpscr.rMode);
1037 vfpFlushToZero(fpscr, FpOp1);
1038 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1039 FpDest_sw = vfpFpToFixed<float>(FpOp1, true, 32, 0, false);
1040 __asm__ __volatile__("" :: "m" (FpDest_sw));
1041 finishVfp(fpscr, state, fpscr.fz);
1042 FpscrExc = fpscr;
1043 '''
1044 vcvtFpSIntSRIop = InstObjParams("vcvtr", "VcvtFpSIntSR", "FpRegRegOp",
1045 { "code": vcvtFpSIntSRCode,
1046 "predicate_test": predicateTest,
1047 "op_class": "SimdFloatCvtOp" }, [])
1048 header_output += FpRegRegOpDeclare.subst(vcvtFpSIntSRIop);
1049 decoder_output += FpRegRegOpConstructor.subst(vcvtFpSIntSRIop);
1050 exec_output += PredOpExecute.subst(vcvtFpSIntSRIop);
1051
1052 vcvtFpSIntDRCode = vfpEnabledCheckCode + '''
1053 FPSCR fpscr = (FPSCR) FpscrExc;
1054 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1055 vfpFlushToZero(fpscr, cOp1);
1056 VfpSavedState state = prepFpState(fpscr.rMode);
1057 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1058 int64_t result = vfpFpToFixed<double>(cOp1, true, 32, 0, false);
1059 __asm__ __volatile__("" :: "m" (result));
1060 finishVfp(fpscr, state, fpscr.fz);
1061 FpDestP0_uw = result;
1062 FpscrExc = fpscr;
1063 '''
1064 vcvtFpSIntDRIop = InstObjParams("vcvtr", "VcvtFpSIntDR", "FpRegRegOp",
1065 { "code": vcvtFpSIntDRCode,
1066 "predicate_test": predicateTest,
1067 "op_class": "SimdFloatCvtOp" }, [])
1068 header_output += FpRegRegOpDeclare.subst(vcvtFpSIntDRIop);
1069 decoder_output += FpRegRegOpConstructor.subst(vcvtFpSIntDRIop);
1070 exec_output += PredOpExecute.subst(vcvtFpSIntDRIop);
1071
1072 round_mode_suffix_to_mode = {
1073 '': 'VfpRoundZero',
1074 'a': 'VfpRoundAway',
1075 'm': 'VfpRoundDown',
1076 'n': 'VfpRoundNearest',
1077 'p': 'VfpRoundUpward',
1078 }
1079
1080 def buildVcvt(code, className, roundModeSuffix):
1081 global header_output, decoder_output, exec_output, \
1082 vfpEnabledCheckCode, round_mode_suffix_to_mode
1083 full_code = vfpEnabledCheckCode + code.format(
1084 round_mode=round_mode_suffix_to_mode[roundModeSuffix],
1085 )
1086 iop = InstObjParams(
1087 "vcvt{}".format(roundModeSuffix),
1088 className.format(roundModeSuffix),
1089 "FpRegRegOp",
1090 { "code": full_code,
1091 "predicate_test": predicateTest,
1092 "op_class": "SimdFloatCvtOp" },
1093 []
1094 )
1095 header_output += FpRegRegOpDeclare.subst(iop);
1096 decoder_output += FpRegRegOpConstructor.subst(iop);
1097 exec_output += PredOpExecute.subst(iop);
1098
1099 code = '''
1100 FPSCR fpscr = (FPSCR) FpscrExc;
1101 vfpFlushToZero(fpscr, FpOp1);
1102 VfpSavedState state = prepFpState(fpscr.rMode);
1103 fesetround(FeRoundZero);
1104 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1105 FpDest_uw = vfpFpToFixed<float>(
1106 FpOp1, false, 32, 0, true, {round_mode});
1107 __asm__ __volatile__("" :: "m" (FpDest_uw));
1108 finishVfp(fpscr, state, fpscr.fz);
1109 FpscrExc = fpscr;
1110 '''
1111 for round_mode_suffix in round_mode_suffix_to_mode:
1112 buildVcvt(code, "Vcvt{}FpUIntS", round_mode_suffix)
1113
1114 code = '''
1115 FPSCR fpscr = (FPSCR) FpscrExc;
1116 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1117 vfpFlushToZero(fpscr, cOp1);
1118 VfpSavedState state = prepFpState(fpscr.rMode);
1119 fesetround(FeRoundZero);
1120 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1121 uint64_t result = vfpFpToFixed<double>(
1122 cOp1, false, 32, 0, true, {round_mode});
1123 __asm__ __volatile__("" :: "m" (result));
1124 finishVfp(fpscr, state, fpscr.fz);
1125 FpDestP0_uw = result;
1126 FpscrExc = fpscr;
1127 '''
1128 for round_mode_suffix in round_mode_suffix_to_mode:
1129 buildVcvt(code, "Vcvt{}FpUIntD", round_mode_suffix)
1130
1131 code = '''
1132 FPSCR fpscr = (FPSCR) FpscrExc;
1133 vfpFlushToZero(fpscr, FpOp1);
1134 VfpSavedState state = prepFpState(fpscr.rMode);
1135 fesetround(FeRoundZero);
1136 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1137 FpDest_sw = vfpFpToFixed<float>(
1138 FpOp1, true, 32, 0, true, {round_mode});
1139 __asm__ __volatile__("" :: "m" (FpDest_sw));
1140 finishVfp(fpscr, state, fpscr.fz);
1141 FpscrExc = fpscr;
1142 '''
1143 for round_mode_suffix in round_mode_suffix_to_mode:
1144 buildVcvt(code, "Vcvt{}FpSIntS", round_mode_suffix)
1145
1146 code = '''
1147 FPSCR fpscr = (FPSCR) FpscrExc;
1148 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1149 vfpFlushToZero(fpscr, cOp1);
1150 VfpSavedState state = prepFpState(fpscr.rMode);
1151 fesetround(FeRoundZero);
1152 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1153 int64_t result = vfpFpToFixed<double>(
1154 cOp1, true, 32, 0, true, {round_mode});
1155 __asm__ __volatile__("" :: "m" (result));
1156 finishVfp(fpscr, state, fpscr.fz);
1157 FpDestP0_uw = result;
1158 FpscrExc = fpscr;
1159 '''
1160 for round_mode_suffix in round_mode_suffix_to_mode:
1161 buildVcvt(code, "Vcvt{}FpSIntD", round_mode_suffix)
1162
1163 vcvtFpSFpDCode = vfpEnabledCheckCode + '''
1164 FPSCR fpscr = (FPSCR) FpscrExc;
1165 vfpFlushToZero(fpscr, FpOp1);
1166 VfpSavedState state = prepFpState(fpscr.rMode);
1167 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1168 double cDest = fixFpSFpDDest(FpscrExc, FpOp1);
1169 __asm__ __volatile__("" :: "m" (cDest));
1170 finishVfp(fpscr, state, fpscr.fz);
1171 FpDestP0_uw = dblLow(cDest);
1172 FpDestP1_uw = dblHi(cDest);
1173 FpscrExc = fpscr;
1174 '''
1175 vcvtFpSFpDIop = InstObjParams("vcvt", "VcvtFpSFpD", "FpRegRegOp",
1176 { "code": vcvtFpSFpDCode,
1177 "predicate_test": predicateTest,
1178 "op_class": "SimdFloatCvtOp" }, [])
1179 header_output += FpRegRegOpDeclare.subst(vcvtFpSFpDIop);
1180 decoder_output += FpRegRegOpConstructor.subst(vcvtFpSFpDIop);
1181 exec_output += PredOpExecute.subst(vcvtFpSFpDIop);
1182
1183 vcvtFpDFpSCode = vfpEnabledCheckCode + '''
1184 FPSCR fpscr = (FPSCR) FpscrExc;
1185 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1186 vfpFlushToZero(fpscr, cOp1);
1187 VfpSavedState state = prepFpState(fpscr.rMode);
1188 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1189 FpDest = fixFpDFpSDest(FpscrExc, cOp1);
1190 __asm__ __volatile__("" :: "m" (FpDest));
1191 finishVfp(fpscr, state, fpscr.fz);
1192 FpscrExc = fpscr;
1193 '''
1194 vcvtFpDFpSIop = InstObjParams("vcvt", "VcvtFpDFpS", "FpRegRegOp",
1195 { "code": vcvtFpDFpSCode,
1196 "predicate_test": predicateTest,
1197 "op_class": "SimdFloatCvtOp" }, [])
1198 header_output += FpRegRegOpDeclare.subst(vcvtFpDFpSIop);
1199 decoder_output += FpRegRegOpConstructor.subst(vcvtFpDFpSIop);
1200 exec_output += PredOpExecute.subst(vcvtFpDFpSIop);
1201
1202 vcvtFpHTFpSCode = vfpEnabledCheckCode + '''
1203 FPSCR fpscr = (FPSCR) FpscrExc;
1204 vfpFlushToZero(fpscr, FpOp1);
1205 VfpSavedState state = prepFpState(fpscr.rMode);
1206 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1207 FpDest = vcvtFpHFpS(fpscr, fpscr.dn, fpscr.ahp,
1208 bits(fpToBits(FpOp1), 31, 16));
1209 __asm__ __volatile__("" :: "m" (FpDest));
1210 finishVfp(fpscr, state, fpscr.fz);
1211 FpscrExc = fpscr;
1212 '''
1213 vcvtFpHTFpSIop = InstObjParams("vcvtt", "VcvtFpHTFpS", "FpRegRegOp",
1214 { "code": vcvtFpHTFpSCode,
1215 "predicate_test": predicateTest,
1216 "op_class": "SimdFloatCvtOp" }, [])
1217 header_output += FpRegRegOpDeclare.subst(vcvtFpHTFpSIop);
1218 decoder_output += FpRegRegOpConstructor.subst(vcvtFpHTFpSIop);
1219 exec_output += PredOpExecute.subst(vcvtFpHTFpSIop);
1220
1221 vcvtFpHBFpSCode = vfpEnabledCheckCode + '''
1222 FPSCR fpscr = (FPSCR) FpscrExc;
1223 VfpSavedState state = prepFpState(fpscr.rMode);
1224 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1225 FpDest = vcvtFpHFpS(fpscr, fpscr.dn, fpscr.ahp,
1226 bits(fpToBits(FpOp1), 15, 0));
1227 __asm__ __volatile__("" :: "m" (FpDest));
1228 finishVfp(fpscr, state, fpscr.fz);
1229 FpscrExc = fpscr;
1230 '''
1231 vcvtFpHBFpSIop = InstObjParams("vcvtb", "VcvtFpHBFpS", "FpRegRegOp",
1232 { "code": vcvtFpHBFpSCode,
1233 "predicate_test": predicateTest,
1234 "op_class": "SimdFloatCvtOp" }, [])
1235 header_output += FpRegRegOpDeclare.subst(vcvtFpHBFpSIop);
1236 decoder_output += FpRegRegOpConstructor.subst(vcvtFpHBFpSIop);
1237 exec_output += PredOpExecute.subst(vcvtFpHBFpSIop);
1238
1239 vcvtFpSFpHTCode = vfpEnabledCheckCode + '''
1240 FPSCR fpscr = (FPSCR) FpscrExc;
1241 vfpFlushToZero(fpscr, FpOp1);
1242 VfpSavedState state = prepFpState(fpscr.rMode);
1243 __asm__ __volatile__("" : "=m" (FpOp1), "=m" (FpDest_uw)
1244 : "m" (FpOp1), "m" (FpDest_uw));
1245 FpDest_uw = insertBits(FpDest_uw, 31, 16,,
1246 vcvtFpSFpH(fpscr, fpscr.fz, fpscr.dn,
1247 fpscr.rMode, fpscr.ahp, FpOp1));
1248 __asm__ __volatile__("" :: "m" (FpDest_uw));
1249 finishVfp(fpscr, state, fpscr.fz);
1250 FpscrExc = fpscr;
1251 '''
1252 vcvtFpSFpHTIop = InstObjParams("vcvtt", "VcvtFpSFpHT", "FpRegRegOp",
1253 { "code": vcvtFpHTFpSCode,
1254 "predicate_test": predicateTest,
1255 "op_class": "SimdFloatCvtOp" }, [])
1256 header_output += FpRegRegOpDeclare.subst(vcvtFpSFpHTIop);
1257 decoder_output += FpRegRegOpConstructor.subst(vcvtFpSFpHTIop);
1258 exec_output += PredOpExecute.subst(vcvtFpSFpHTIop);
1259
1260 vcvtFpSFpHBCode = vfpEnabledCheckCode + '''
1261 FPSCR fpscr = (FPSCR) FpscrExc;
1262 vfpFlushToZero(fpscr, FpOp1);
1263 VfpSavedState state = prepFpState(fpscr.rMode);
1264 __asm__ __volatile__("" : "=m" (FpOp1), "=m" (FpDest_uw)
1265 : "m" (FpOp1), "m" (FpDest_uw));
1266 FpDest_uw = insertBits(FpDest_uw, 15, 0,
1267 vcvtFpSFpH(fpscr, fpscr.fz, fpscr.dn,
1268 fpscr.rMode, fpscr.ahp, FpOp1));
1269 __asm__ __volatile__("" :: "m" (FpDest_uw));
1270 finishVfp(fpscr, state, fpscr.fz);
1271 FpscrExc = fpscr;
1272 '''
1273 vcvtFpSFpHBIop = InstObjParams("vcvtb", "VcvtFpSFpHB", "FpRegRegOp",
1274 { "code": vcvtFpSFpHBCode,
1275 "predicate_test": predicateTest,
1276 "op_class": "SimdFloatCvtOp" }, [])
1277 header_output += FpRegRegOpDeclare.subst(vcvtFpSFpHBIop);
1278 decoder_output += FpRegRegOpConstructor.subst(vcvtFpSFpHBIop);
1279 exec_output += PredOpExecute.subst(vcvtFpSFpHBIop);
1280
1281 vcmpSCode = vfpEnabledCheckCode + '''
1282 FPSCR fpscr = (FPSCR) FpscrExc;
1283 vfpFlushToZero(fpscr, FpDest, FpOp1);
1284 if (FpDest == FpOp1) {
1285 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1286 } else if (FpDest < FpOp1) {
1287 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1288 } else if (FpDest > FpOp1) {
1289 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1290 } else {
1291 const uint32_t qnan = 0x7fc00000;
1292 const bool nan1 = std::isnan(FpDest);
1293 const bool signal1 = nan1 && ((fpToBits(FpDest) & qnan) != qnan);
1294 const bool nan2 = std::isnan(FpOp1);
1295 const bool signal2 = nan2 && ((fpToBits(FpOp1) & qnan) != qnan);
1296 if (signal1 || signal2)
1297 fpscr.ioc = 1;
1298 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1299 }
1300 FpCondCodes = fpscr & FpCondCodesMask;
1301 FpscrExc = fpscr;
1302 '''
1303 vcmpSIop = InstObjParams("vcmps", "VcmpS", "FpRegRegOp",
1304 { "code": vcmpSCode,
1305 "predicate_test": predicateTest,
1306 "op_class": "SimdFloatCmpOp" }, [])
1307 header_output += FpRegRegOpDeclare.subst(vcmpSIop);
1308 decoder_output += FpRegRegOpConstructor.subst(vcmpSIop);
1309 exec_output += PredOpExecute.subst(vcmpSIop);
1310
1311 vcmpDCode = vfpEnabledCheckCode + '''
1312 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1313 double cDest = dbl(FpDestP0_uw, FpDestP1_uw);
1314 FPSCR fpscr = (FPSCR) FpscrExc;
1315 vfpFlushToZero(fpscr, cDest, cOp1);
1316 if (cDest == cOp1) {
1317 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1318 } else if (cDest < cOp1) {
1319 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1320 } else if (cDest > cOp1) {
1321 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1322 } else {
1323 const uint64_t qnan = ULL(0x7ff8000000000000);
1324 const bool nan1 = std::isnan(cDest);
1325 const bool signal1 = nan1 && ((fpToBits(cDest) & qnan) != qnan);
1326 const bool nan2 = std::isnan(cOp1);
1327 const bool signal2 = nan2 && ((fpToBits(cOp1) & qnan) != qnan);
1328 if (signal1 || signal2)
1329 fpscr.ioc = 1;
1330 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1331 }
1332 FpCondCodes = fpscr & FpCondCodesMask;
1333 FpscrExc = fpscr;
1334 '''
1335 vcmpDIop = InstObjParams("vcmpd", "VcmpD", "FpRegRegOp",
1336 { "code": vcmpDCode,
1337 "predicate_test": predicateTest,
1338 "op_class": "SimdFloatCmpOp" }, [])
1339 header_output += FpRegRegOpDeclare.subst(vcmpDIop);
1340 decoder_output += FpRegRegOpConstructor.subst(vcmpDIop);
1341 exec_output += PredOpExecute.subst(vcmpDIop);
1342
1343 vcmpZeroSCode = vfpEnabledCheckCode + '''
1344 FPSCR fpscr = (FPSCR) FpscrExc;
1345 vfpFlushToZero(fpscr, FpDest);
1346 // This only handles imm == 0 for now.
1347 assert(imm == 0);
1348 if (FpDest == imm) {
1349 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1350 } else if (FpDest < imm) {
1351 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1352 } else if (FpDest > imm) {
1353 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1354 } else {
1355 const uint32_t qnan = 0x7fc00000;
1356 const bool nan = std::isnan(FpDest);
1357 const bool signal = nan && ((fpToBits(FpDest) & qnan) != qnan);
1358 if (signal)
1359 fpscr.ioc = 1;
1360 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1361 }
1362 FpCondCodes = fpscr & FpCondCodesMask;
1363 FpscrExc = fpscr;
1364 '''
1365 vcmpZeroSIop = InstObjParams("vcmpZeros", "VcmpZeroS", "FpRegImmOp",
1366 { "code": vcmpZeroSCode,
1367 "predicate_test": predicateTest,
1368 "op_class": "SimdFloatCmpOp" }, [])
1369 header_output += FpRegImmOpDeclare.subst(vcmpZeroSIop);
1370 decoder_output += FpRegImmOpConstructor.subst(vcmpZeroSIop);
1371 exec_output += PredOpExecute.subst(vcmpZeroSIop);
1372
1373 vcmpZeroDCode = vfpEnabledCheckCode + '''
1374 // This only handles imm == 0 for now.
1375 assert(imm == 0);
1376 double cDest = dbl(FpDestP0_uw, FpDestP1_uw);
1377 FPSCR fpscr = (FPSCR) FpscrExc;
1378 vfpFlushToZero(fpscr, cDest);
1379 if (cDest == imm) {
1380 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1381 } else if (cDest < imm) {
1382 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1383 } else if (cDest > imm) {
1384 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1385 } else {
1386 const uint64_t qnan = ULL(0x7ff8000000000000);
1387 const bool nan = std::isnan(cDest);
1388 const bool signal = nan && ((fpToBits(cDest) & qnan) != qnan);
1389 if (signal)
1390 fpscr.ioc = 1;
1391 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1392 }
1393 FpCondCodes = fpscr & FpCondCodesMask;
1394 FpscrExc = fpscr;
1395 '''
1396 vcmpZeroDIop = InstObjParams("vcmpZerod", "VcmpZeroD", "FpRegImmOp",
1397 { "code": vcmpZeroDCode,
1398 "predicate_test": predicateTest,
1399 "op_class": "SimdFloatCmpOp" }, [])
1400 header_output += FpRegImmOpDeclare.subst(vcmpZeroDIop);
1401 decoder_output += FpRegImmOpConstructor.subst(vcmpZeroDIop);
1402 exec_output += PredOpExecute.subst(vcmpZeroDIop);
1403
1404 vcmpeSCode = vfpEnabledCheckCode + '''
1405 FPSCR fpscr = (FPSCR) FpscrExc;
1406 vfpFlushToZero(fpscr, FpDest, FpOp1);
1407 if (FpDest == FpOp1) {
1408 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1409 } else if (FpDest < FpOp1) {
1410 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1411 } else if (FpDest > FpOp1) {
1412 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1413 } else {
1414 fpscr.ioc = 1;
1415 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1416 }
1417 FpCondCodes = fpscr & FpCondCodesMask;
1418 FpscrExc = fpscr;
1419 '''
1420 vcmpeSIop = InstObjParams("vcmpes", "VcmpeS", "FpRegRegOp",
1421 { "code": vcmpeSCode,
1422 "predicate_test": predicateTest,
1423 "op_class": "SimdFloatCmpOp" }, [])
1424 header_output += FpRegRegOpDeclare.subst(vcmpeSIop);
1425 decoder_output += FpRegRegOpConstructor.subst(vcmpeSIop);
1426 exec_output += PredOpExecute.subst(vcmpeSIop);
1427
1428 vcmpeDCode = vfpEnabledCheckCode + '''
1429 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1430 double cDest = dbl(FpDestP0_uw, FpDestP1_uw);
1431 FPSCR fpscr = (FPSCR) FpscrExc;
1432 vfpFlushToZero(fpscr, cDest, cOp1);
1433 if (cDest == cOp1) {
1434 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1435 } else if (cDest < cOp1) {
1436 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1437 } else if (cDest > cOp1) {
1438 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1439 } else {
1440 fpscr.ioc = 1;
1441 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1442 }
1443 FpCondCodes = fpscr & FpCondCodesMask;
1444 FpscrExc = fpscr;
1445 '''
1446 vcmpeDIop = InstObjParams("vcmped", "VcmpeD", "FpRegRegOp",
1447 { "code": vcmpeDCode,
1448 "predicate_test": predicateTest,
1449 "op_class": "SimdFloatCmpOp" }, [])
1450 header_output += FpRegRegOpDeclare.subst(vcmpeDIop);
1451 decoder_output += FpRegRegOpConstructor.subst(vcmpeDIop);
1452 exec_output += PredOpExecute.subst(vcmpeDIop);
1453
1454 vcmpeZeroSCode = vfpEnabledCheckCode + '''
1455 FPSCR fpscr = (FPSCR) FpscrExc;
1456 vfpFlushToZero(fpscr, FpDest);
1457 if (FpDest == imm) {
1458 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1459 } else if (FpDest < imm) {
1460 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1461 } else if (FpDest > imm) {
1462 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1463 } else {
1464 fpscr.ioc = 1;
1465 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1466 }
1467 FpCondCodes = fpscr & FpCondCodesMask;
1468 FpscrExc = fpscr;
1469 '''
1470 vcmpeZeroSIop = InstObjParams("vcmpeZeros", "VcmpeZeroS", "FpRegImmOp",
1471 { "code": vcmpeZeroSCode,
1472 "predicate_test": predicateTest,
1473 "op_class": "SimdFloatCmpOp" }, [])
1474 header_output += FpRegImmOpDeclare.subst(vcmpeZeroSIop);
1475 decoder_output += FpRegImmOpConstructor.subst(vcmpeZeroSIop);
1476 exec_output += PredOpExecute.subst(vcmpeZeroSIop);
1477
1478 vcmpeZeroDCode = vfpEnabledCheckCode + '''
1479 double cDest = dbl(FpDestP0_uw, FpDestP1_uw);
1480 FPSCR fpscr = (FPSCR) FpscrExc;
1481 vfpFlushToZero(fpscr, cDest);
1482 if (cDest == imm) {
1483 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1484 } else if (cDest < imm) {
1485 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1486 } else if (cDest > imm) {
1487 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1488 } else {
1489 fpscr.ioc = 1;
1490 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1491 }
1492 FpCondCodes = fpscr & FpCondCodesMask;
1493 FpscrExc = fpscr;
1494 '''
1495 vcmpeZeroDIop = InstObjParams("vcmpeZerod", "VcmpeZeroD", "FpRegImmOp",
1496 { "code": vcmpeZeroDCode,
1497 "predicate_test": predicateTest,
1498 "op_class": "SimdFloatCmpOp" }, [])
1499 header_output += FpRegImmOpDeclare.subst(vcmpeZeroDIop);
1500 decoder_output += FpRegImmOpConstructor.subst(vcmpeZeroDIop);
1501 exec_output += PredOpExecute.subst(vcmpeZeroDIop);
1502 }};
1503
1504 let {{
1505
1506 header_output = ""
1507 decoder_output = ""
1508 exec_output = ""
1509
1510 vselSCode = vfpEnabledCheckCode + '''
1511 if (testPredicate(CondCodesNZ, CondCodesC, CondCodesV, cond)) {
1512 FpDest = FpOp1;
1513 } else {
1514 FpDest = FpOp2;
1515 } '''
1516
1517 vselSIop = InstObjParams("vsels", "VselS", "FpRegRegRegCondOp",
1518 { "code" : vselSCode,
1519 "predicate_test" : predicateTest,
1520 "op_class" : "SimdFloatCmpOp" }, [] )
1521 header_output += FpRegRegRegCondOpDeclare.subst(vselSIop);
1522 decoder_output += FpRegRegRegCondOpConstructor.subst(vselSIop);
1523 exec_output += PredOpExecute.subst(vselSIop);
1524
1525 vselDCode = vfpEnabledCheckCode + '''
1526 if (testPredicate(CondCodesNZ, CondCodesC, CondCodesV, cond)) {
1527 FpDestP0_uw = FpOp1P0_uw;
1528 FpDestP1_uw = FpOp1P1_uw;
1529 } else {
1530 FpDestP0_uw = FpOp2P0_uw;
1531 FpDestP1_uw = FpOp2P1_uw;
1532 } '''
1533
1534 vselDIop = InstObjParams("vseld", "VselD", "FpRegRegRegCondOp",
1535 { "code" : vselDCode,
1536 "predicate_test" : predicateTest,
1537 "op_class" : "SimdFloatCmpOp" }, [] )
1538 header_output += FpRegRegRegCondOpDeclare.subst(vselDIop);
1539 decoder_output += FpRegRegRegCondOpConstructor.subst(vselDIop);
1540 exec_output += PredOpExecute.subst(vselDIop);
1541 }};
1542
1543
1544 let {{
1545
1546 header_output = ""
1547 decoder_output = ""
1548 exec_output = ""
1549
1550 vcvtFpSFixedSCode = vfpEnabledCheckCode + '''
1551 FPSCR fpscr = (FPSCR) FpscrExc;
1552 vfpFlushToZero(fpscr, FpOp1);
1553 VfpSavedState state = prepFpState(fpscr.rMode);
1554 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1555 FpDest_sw = vfpFpToFixed<float>(FpOp1, true, 32, imm);
1556 __asm__ __volatile__("" :: "m" (FpDest_sw));
1557 finishVfp(fpscr, state, fpscr.fz);
1558 FpscrExc = fpscr;
1559 '''
1560 vcvtFpSFixedSIop = InstObjParams("vcvt", "VcvtFpSFixedS", "FpRegRegImmOp",
1561 { "code": vcvtFpSFixedSCode,
1562 "predicate_test": predicateTest,
1563 "op_class": "SimdFloatCvtOp" }, [])
1564 header_output += FpRegRegImmOpDeclare.subst(vcvtFpSFixedSIop);
1565 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSFixedSIop);
1566 exec_output += PredOpExecute.subst(vcvtFpSFixedSIop);
1567
1568 vcvtFpSFixedDCode = vfpEnabledCheckCode + '''
1569 FPSCR fpscr = (FPSCR) FpscrExc;
1570 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1571 vfpFlushToZero(fpscr, cOp1);
1572 VfpSavedState state = prepFpState(fpscr.rMode);
1573 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1574 uint64_t mid = vfpFpToFixed<double>(cOp1, true, 32, imm);
1575 __asm__ __volatile__("" :: "m" (mid));
1576 finishVfp(fpscr, state, fpscr.fz);
1577 FpDestP0_uw = mid;
1578 FpDestP1_uw = mid >> 32;
1579 FpscrExc = fpscr;
1580 '''
1581 vcvtFpSFixedDIop = InstObjParams("vcvt", "VcvtFpSFixedD", "FpRegRegImmOp",
1582 { "code": vcvtFpSFixedDCode,
1583 "predicate_test": predicateTest,
1584 "op_class": "SimdFloatCvtOp" }, [])
1585 header_output += FpRegRegImmOpDeclare.subst(vcvtFpSFixedDIop);
1586 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSFixedDIop);
1587 exec_output += PredOpExecute.subst(vcvtFpSFixedDIop);
1588
1589 vcvtFpUFixedSCode = vfpEnabledCheckCode + '''
1590 FPSCR fpscr = (FPSCR) FpscrExc;
1591 vfpFlushToZero(fpscr, FpOp1);
1592 VfpSavedState state = prepFpState(fpscr.rMode);
1593 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1594 FpDest_uw = vfpFpToFixed<float>(FpOp1, false, 32, imm);
1595 __asm__ __volatile__("" :: "m" (FpDest_uw));
1596 finishVfp(fpscr, state, fpscr.fz);
1597 FpscrExc = fpscr;
1598 '''
1599 vcvtFpUFixedSIop = InstObjParams("vcvt", "VcvtFpUFixedS", "FpRegRegImmOp",
1600 { "code": vcvtFpUFixedSCode,
1601 "predicate_test": predicateTest,
1602 "op_class": "SimdFloatCvtOp" }, [])
1603 header_output += FpRegRegImmOpDeclare.subst(vcvtFpUFixedSIop);
1604 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUFixedSIop);
1605 exec_output += PredOpExecute.subst(vcvtFpUFixedSIop);
1606
1607 vcvtFpUFixedDCode = vfpEnabledCheckCode + '''
1608 FPSCR fpscr = (FPSCR) FpscrExc;
1609 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1610 vfpFlushToZero(fpscr, cOp1);
1611 VfpSavedState state = prepFpState(fpscr.rMode);
1612 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1613 uint64_t mid = vfpFpToFixed<double>(cOp1, false, 32, imm);
1614 __asm__ __volatile__("" :: "m" (mid));
1615 finishVfp(fpscr, state, fpscr.fz);
1616 FpDestP0_uw = mid;
1617 FpDestP1_uw = mid >> 32;
1618 FpscrExc = fpscr;
1619 '''
1620 vcvtFpUFixedDIop = InstObjParams("vcvt", "VcvtFpUFixedD", "FpRegRegImmOp",
1621 { "code": vcvtFpUFixedDCode,
1622 "predicate_test": predicateTest,
1623 "op_class": "SimdFloatCvtOp" }, [])
1624 header_output += FpRegRegImmOpDeclare.subst(vcvtFpUFixedDIop);
1625 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUFixedDIop);
1626 exec_output += PredOpExecute.subst(vcvtFpUFixedDIop);
1627
1628 vcvtSFixedFpSCode = vfpEnabledCheckCode + '''
1629 FPSCR fpscr = (FPSCR) FpscrExc;
1630 VfpSavedState state = prepFpState(fpscr.rMode);
1631 __asm__ __volatile__("" : "=m" (FpOp1_sw) : "m" (FpOp1_sw));
1632 FpDest = vfpSFixedToFpS(fpscr.fz, fpscr.dn, FpOp1_sw, 32, imm);
1633 __asm__ __volatile__("" :: "m" (FpDest));
1634 finishVfp(fpscr, state, fpscr.fz);
1635 FpscrExc = fpscr;
1636 '''
1637 vcvtSFixedFpSIop = InstObjParams("vcvt", "VcvtSFixedFpS", "FpRegRegImmOp",
1638 { "code": vcvtSFixedFpSCode,
1639 "predicate_test": predicateTest,
1640 "op_class": "SimdFloatCvtOp" }, [])
1641 header_output += FpRegRegImmOpDeclare.subst(vcvtSFixedFpSIop);
1642 decoder_output += FpRegRegImmOpConstructor.subst(vcvtSFixedFpSIop);
1643 exec_output += PredOpExecute.subst(vcvtSFixedFpSIop);
1644
1645 vcvtSFixedFpDCode = vfpEnabledCheckCode + '''
1646 FPSCR fpscr = (FPSCR) FpscrExc;
1647 uint64_t mid = ((uint64_t)FpOp1P0_uw | ((uint64_t)FpOp1P1_uw << 32));
1648 VfpSavedState state = prepFpState(fpscr.rMode);
1649 __asm__ __volatile__("" : "=m" (mid) : "m" (mid));
1650 double cDest = vfpSFixedToFpD(fpscr.fz, fpscr.dn, mid, 32, imm);
1651 __asm__ __volatile__("" :: "m" (cDest));
1652 finishVfp(fpscr, state, fpscr.fz);
1653 FpDestP0_uw = dblLow(cDest);
1654 FpDestP1_uw = dblHi(cDest);
1655 FpscrExc = fpscr;
1656 '''
1657 vcvtSFixedFpDIop = InstObjParams("vcvt", "VcvtSFixedFpD", "FpRegRegImmOp",
1658 { "code": vcvtSFixedFpDCode,
1659 "predicate_test": predicateTest,
1660 "op_class": "SimdFloatCvtOp" }, [])
1661 header_output += FpRegRegImmOpDeclare.subst(vcvtSFixedFpDIop);
1662 decoder_output += FpRegRegImmOpConstructor.subst(vcvtSFixedFpDIop);
1663 exec_output += PredOpExecute.subst(vcvtSFixedFpDIop);
1664
1665 vcvtUFixedFpSCode = vfpEnabledCheckCode + '''
1666 FPSCR fpscr = (FPSCR) FpscrExc;
1667 VfpSavedState state = prepFpState(fpscr.rMode);
1668 __asm__ __volatile__("" : "=m" (FpOp1_uw) : "m" (FpOp1_uw));
1669 FpDest = vfpUFixedToFpS(fpscr.fz, fpscr.dn, FpOp1_uw, 32, imm);
1670 __asm__ __volatile__("" :: "m" (FpDest));
1671 finishVfp(fpscr, state, fpscr.fz);
1672 FpscrExc = fpscr;
1673 '''
1674 vcvtUFixedFpSIop = InstObjParams("vcvt", "VcvtUFixedFpS", "FpRegRegImmOp",
1675 { "code": vcvtUFixedFpSCode,
1676 "predicate_test": predicateTest,
1677 "op_class": "SimdFloatCvtOp" }, [])
1678 header_output += FpRegRegImmOpDeclare.subst(vcvtUFixedFpSIop);
1679 decoder_output += FpRegRegImmOpConstructor.subst(vcvtUFixedFpSIop);
1680 exec_output += PredOpExecute.subst(vcvtUFixedFpSIop);
1681
1682 vcvtUFixedFpDCode = vfpEnabledCheckCode + '''
1683 FPSCR fpscr = (FPSCR) FpscrExc;
1684 uint64_t mid = ((uint64_t)FpOp1P0_uw | ((uint64_t)FpOp1P1_uw << 32));
1685 VfpSavedState state = prepFpState(fpscr.rMode);
1686 __asm__ __volatile__("" : "=m" (mid) : "m" (mid));
1687 double cDest = vfpUFixedToFpD(fpscr.fz, fpscr.dn, mid, 32, imm);
1688 __asm__ __volatile__("" :: "m" (cDest));
1689 finishVfp(fpscr, state, fpscr.fz);
1690 FpDestP0_uw = dblLow(cDest);
1691 FpDestP1_uw = dblHi(cDest);
1692 FpscrExc = fpscr;
1693 '''
1694 vcvtUFixedFpDIop = InstObjParams("vcvt", "VcvtUFixedFpD", "FpRegRegImmOp",
1695 { "code": vcvtUFixedFpDCode,
1696 "predicate_test": predicateTest,
1697 "op_class": "SimdFloatCvtOp" }, [])
1698 header_output += FpRegRegImmOpDeclare.subst(vcvtUFixedFpDIop);
1699 decoder_output += FpRegRegImmOpConstructor.subst(vcvtUFixedFpDIop);
1700 exec_output += PredOpExecute.subst(vcvtUFixedFpDIop);
1701
1702 vcvtFpSHFixedSCode = vfpEnabledCheckCode + '''
1703 FPSCR fpscr = (FPSCR) FpscrExc;
1704 vfpFlushToZero(fpscr, FpOp1);
1705 VfpSavedState state = prepFpState(fpscr.rMode);
1706 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1707 FpDest_sh = vfpFpToFixed<float>(FpOp1, true, 16, imm);
1708 __asm__ __volatile__("" :: "m" (FpDest_sh));
1709 finishVfp(fpscr, state, fpscr.fz);
1710 FpscrExc = fpscr;
1711 '''
1712 vcvtFpSHFixedSIop = InstObjParams("vcvt", "VcvtFpSHFixedS",
1713 "FpRegRegImmOp",
1714 { "code": vcvtFpSHFixedSCode,
1715 "predicate_test": predicateTest,
1716 "op_class": "SimdFloatCvtOp" }, [])
1717 header_output += FpRegRegImmOpDeclare.subst(vcvtFpSHFixedSIop);
1718 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSHFixedSIop);
1719 exec_output += PredOpExecute.subst(vcvtFpSHFixedSIop);
1720
1721 vcvtFpSHFixedDCode = vfpEnabledCheckCode + '''
1722 FPSCR fpscr = (FPSCR) FpscrExc;
1723 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1724 vfpFlushToZero(fpscr, cOp1);
1725 VfpSavedState state = prepFpState(fpscr.rMode);
1726 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1727 uint64_t result = vfpFpToFixed<double>(cOp1, true, 16, imm);
1728 __asm__ __volatile__("" :: "m" (result));
1729 finishVfp(fpscr, state, fpscr.fz);
1730 FpDestP0_uw = result;
1731 FpDestP1_uw = result >> 32;
1732 FpscrExc = fpscr;
1733 '''
1734 vcvtFpSHFixedDIop = InstObjParams("vcvt", "VcvtFpSHFixedD",
1735 "FpRegRegImmOp",
1736 { "code": vcvtFpSHFixedDCode,
1737 "predicate_test": predicateTest,
1738 "op_class": "SimdFloatCvtOp" }, [])
1739 header_output += FpRegRegImmOpDeclare.subst(vcvtFpSHFixedDIop);
1740 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSHFixedDIop);
1741 exec_output += PredOpExecute.subst(vcvtFpSHFixedDIop);
1742
1743 vcvtFpUHFixedSCode = vfpEnabledCheckCode + '''
1744 FPSCR fpscr = (FPSCR) FpscrExc;
1745 vfpFlushToZero(fpscr, FpOp1);
1746 VfpSavedState state = prepFpState(fpscr.rMode);
1747 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1748 FpDest_uh = vfpFpToFixed<float>(FpOp1, false, 16, imm);
1749 __asm__ __volatile__("" :: "m" (FpDest_uh));
1750 finishVfp(fpscr, state, fpscr.fz);
1751 FpscrExc = fpscr;
1752 '''
1753 vcvtFpUHFixedSIop = InstObjParams("vcvt", "VcvtFpUHFixedS",
1754 "FpRegRegImmOp",
1755 { "code": vcvtFpUHFixedSCode,
1756 "predicate_test": predicateTest,
1757 "op_class": "SimdFloatCvtOp" }, [])
1758 header_output += FpRegRegImmOpDeclare.subst(vcvtFpUHFixedSIop);
1759 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUHFixedSIop);
1760 exec_output += PredOpExecute.subst(vcvtFpUHFixedSIop);
1761
1762 vcvtFpUHFixedDCode = vfpEnabledCheckCode + '''
1763 FPSCR fpscr = (FPSCR) FpscrExc;
1764 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1765 vfpFlushToZero(fpscr, cOp1);
1766 VfpSavedState state = prepFpState(fpscr.rMode);
1767 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1768 uint64_t mid = vfpFpToFixed<double>(cOp1, false, 16, imm);
1769 __asm__ __volatile__("" :: "m" (mid));
1770 finishVfp(fpscr, state, fpscr.fz);
1771 FpDestP0_uw = mid;
1772 FpDestP1_uw = mid >> 32;
1773 FpscrExc = fpscr;
1774 '''
1775 vcvtFpUHFixedDIop = InstObjParams("vcvt", "VcvtFpUHFixedD",
1776 "FpRegRegImmOp",
1777 { "code": vcvtFpUHFixedDCode,
1778 "predicate_test": predicateTest,
1779 "op_class": "SimdFloatCvtOp" }, [])
1780 header_output += FpRegRegImmOpDeclare.subst(vcvtFpUHFixedDIop);
1781 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUHFixedDIop);
1782 exec_output += PredOpExecute.subst(vcvtFpUHFixedDIop);
1783
1784 vcvtSHFixedFpSCode = vfpEnabledCheckCode + '''
1785 FPSCR fpscr = (FPSCR) FpscrExc;
1786 VfpSavedState state = prepFpState(fpscr.rMode);
1787 __asm__ __volatile__("" : "=m" (FpOp1_sh) : "m" (FpOp1_sh));
1788 FpDest = vfpSFixedToFpS(fpscr.fz, fpscr.dn, FpOp1_sh, 16, imm);
1789 __asm__ __volatile__("" :: "m" (FpDest));
1790 finishVfp(fpscr, state, fpscr.fz);
1791 FpscrExc = fpscr;
1792 '''
1793 vcvtSHFixedFpSIop = InstObjParams("vcvt", "VcvtSHFixedFpS",
1794 "FpRegRegImmOp",
1795 { "code": vcvtSHFixedFpSCode,
1796 "predicate_test": predicateTest,
1797 "op_class": "SimdFloatCvtOp" }, [])
1798 header_output += FpRegRegImmOpDeclare.subst(vcvtSHFixedFpSIop);
1799 decoder_output += FpRegRegImmOpConstructor.subst(vcvtSHFixedFpSIop);
1800 exec_output += PredOpExecute.subst(vcvtSHFixedFpSIop);
1801
1802 vcvtSHFixedFpDCode = vfpEnabledCheckCode + '''
1803 FPSCR fpscr = (FPSCR) FpscrExc;
1804 uint64_t mid = ((uint64_t)FpOp1P0_uw | ((uint64_t)FpOp1P1_uw << 32));
1805 VfpSavedState state = prepFpState(fpscr.rMode);
1806 __asm__ __volatile__("" : "=m" (mid) : "m" (mid));
1807 double cDest = vfpSFixedToFpD(fpscr.fz, fpscr.dn, mid, 16, imm);
1808 __asm__ __volatile__("" :: "m" (cDest));
1809 finishVfp(fpscr, state, fpscr.fz);
1810 FpDestP0_uw = dblLow(cDest);
1811 FpDestP1_uw = dblHi(cDest);
1812 FpscrExc = fpscr;
1813 '''
1814 vcvtSHFixedFpDIop = InstObjParams("vcvt", "VcvtSHFixedFpD",
1815 "FpRegRegImmOp",
1816 { "code": vcvtSHFixedFpDCode,
1817 "predicate_test": predicateTest,
1818 "op_class": "SimdFloatCvtOp" }, [])
1819 header_output += FpRegRegImmOpDeclare.subst(vcvtSHFixedFpDIop);
1820 decoder_output += FpRegRegImmOpConstructor.subst(vcvtSHFixedFpDIop);
1821 exec_output += PredOpExecute.subst(vcvtSHFixedFpDIop);
1822
1823 vcvtUHFixedFpSCode = vfpEnabledCheckCode + '''
1824 FPSCR fpscr = (FPSCR) FpscrExc;
1825 VfpSavedState state = prepFpState(fpscr.rMode);
1826 __asm__ __volatile__("" : "=m" (FpOp1_uh) : "m" (FpOp1_uh));
1827 FpDest = vfpUFixedToFpS(fpscr.fz, fpscr.dn, FpOp1_uh, 16, imm);
1828 __asm__ __volatile__("" :: "m" (FpDest));
1829 finishVfp(fpscr, state, fpscr.fz);
1830 FpscrExc = fpscr;
1831 '''
1832 vcvtUHFixedFpSIop = InstObjParams("vcvt", "VcvtUHFixedFpS",
1833 "FpRegRegImmOp",
1834 { "code": vcvtUHFixedFpSCode,
1835 "predicate_test": predicateTest,
1836 "op_class": "SimdFloatCvtOp" }, [])
1837 header_output += FpRegRegImmOpDeclare.subst(vcvtUHFixedFpSIop);
1838 decoder_output += FpRegRegImmOpConstructor.subst(vcvtUHFixedFpSIop);
1839 exec_output += PredOpExecute.subst(vcvtUHFixedFpSIop);
1840
1841 vcvtUHFixedFpDCode = vfpEnabledCheckCode + '''
1842 FPSCR fpscr = (FPSCR) FpscrExc;
1843 uint64_t mid = ((uint64_t)FpOp1P0_uw | ((uint64_t)FpOp1P1_uw << 32));
1844 VfpSavedState state = prepFpState(fpscr.rMode);
1845 __asm__ __volatile__("" : "=m" (mid) : "m" (mid));
1846 double cDest = vfpUFixedToFpD(fpscr.fz, fpscr.dn, mid, 16, imm);
1847 __asm__ __volatile__("" :: "m" (cDest));
1848 finishVfp(fpscr, state, fpscr.fz);
1849 FpDestP0_uw = dblLow(cDest);
1850 FpDestP1_uw = dblHi(cDest);
1851 FpscrExc = fpscr;
1852 '''
1853 vcvtUHFixedFpDIop = InstObjParams("vcvt", "VcvtUHFixedFpD",
1854 "FpRegRegImmOp",
1855 { "code": vcvtUHFixedFpDCode,
1856 "predicate_test": predicateTest,
1857 "op_class": "SimdFloatCvtOp" }, [])
1858 header_output += FpRegRegImmOpDeclare.subst(vcvtUHFixedFpDIop);
1859 decoder_output += FpRegRegImmOpConstructor.subst(vcvtUHFixedFpDIop);
1860 exec_output += PredOpExecute.subst(vcvtUHFixedFpDIop);
1861 }};