3 // Copyright (c) 2010-2013,2016,2018-2019 ARM Limited
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.
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.
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.
40 template <class Micro>
41 class VfpMacroRegRegOp : public VfpMacroOp
44 VfpMacroRegRegOp(ExtMachInst _machInst, IntRegIndex _dest,
45 IntRegIndex _op1, bool _wide) :
46 VfpMacroOp("VfpMacroRegRegOp", _machInst, No_OpClass, _wide)
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;
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);
63 template <class VfpOp>
65 decodeVfpRegRegOp(ExtMachInst machInst,
66 IntRegIndex dest, IntRegIndex op1, bool wide)
68 if (machInst.fpscrLen == 0 || VfpMacroOp::inScalarBank(dest)) {
69 return new VfpOp(machInst, dest, op1);
71 return new VfpMacroRegRegOp<VfpOp>(machInst, dest, op1, wide);
75 template <class Micro>
76 class VfpMacroRegImmOp : public VfpMacroOp
79 VfpMacroRegImmOp(ExtMachInst _machInst, IntRegIndex _dest, uint64_t _imm,
81 VfpMacroOp("VfpMacroRegImmOp", _machInst, No_OpClass, _wide)
83 numMicroops = machInst.fpscrLen + 1;
84 microOps = new StaticInstPtr[numMicroops];
85 for (unsigned i = 0; i < numMicroops; i++) {
86 VfpMicroMode mode = VfpMicroop;
88 mode = VfpFirstMicroop;
89 else if (i == numMicroops - 1)
90 mode = VfpLastMicroop;
91 microOps[i] = new Micro(_machInst, _dest, _imm, mode);
97 template <class VfpOp>
99 decodeVfpRegImmOp(ExtMachInst machInst,
100 IntRegIndex dest, uint64_t imm, bool wide)
102 if (machInst.fpscrLen == 0 || VfpMacroOp::inScalarBank(dest)) {
103 return new VfpOp(machInst, dest, imm);
105 return new VfpMacroRegImmOp<VfpOp>(machInst, dest, imm, wide);
109 template <class Micro>
110 class VfpMacroRegRegImmOp : public VfpMacroOp
113 VfpMacroRegRegImmOp(ExtMachInst _machInst, IntRegIndex _dest,
114 IntRegIndex _op1, uint64_t _imm, bool _wide) :
115 VfpMacroOp("VfpMacroRegRegImmOp", _machInst, No_OpClass, _wide)
117 numMicroops = machInst.fpscrLen + 1;
118 microOps = new StaticInstPtr[numMicroops];
119 for (unsigned i = 0; i < numMicroops; i++) {
120 VfpMicroMode mode = VfpMicroop;
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);
131 template <class VfpOp>
133 decodeVfpRegRegImmOp(ExtMachInst machInst, IntRegIndex dest,
134 IntRegIndex op1, uint64_t imm, bool wide)
136 if (machInst.fpscrLen == 0 || VfpMacroOp::inScalarBank(dest)) {
137 return new VfpOp(machInst, dest, op1, imm);
139 return new VfpMacroRegRegImmOp<VfpOp>(machInst, dest, op1, imm, wide);
143 template <class Micro>
144 class VfpMacroRegRegRegOp : public VfpMacroOp
147 VfpMacroRegRegRegOp(ExtMachInst _machInst, IntRegIndex _dest,
148 IntRegIndex _op1, IntRegIndex _op2, bool _wide) :
149 VfpMacroOp("VfpMacroRegRegRegOp", _machInst, No_OpClass, _wide)
151 numMicroops = machInst.fpscrLen + 1;
152 microOps = new StaticInstPtr[numMicroops];
153 for (unsigned i = 0; i < numMicroops; i++) {
154 VfpMicroMode mode = VfpMicroop;
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);
165 template <class VfpOp>
167 decodeVfpRegRegRegOp(ExtMachInst machInst, IntRegIndex dest,
168 IntRegIndex op1, IntRegIndex op2, bool wide)
170 if (machInst.fpscrLen == 0 || VfpMacroOp::inScalarBank(dest)) {
171 return new VfpOp(machInst, dest, op1, op2);
173 return new VfpMacroRegRegRegOp<VfpOp>(machInst, dest, op1, op2, wide);
184 vmsrCode = vmsrEnabledCheckCode + '''
188 vmsrIop = InstObjParams("vmsr", "Vmsr", "FpRegRegImmOp",
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);
197 vmsrFpscrCode = vmsrEnabledCheckCode + '''
198 Fpscr = Op1 & ~FpCondCodesMask;
199 FpCondCodes = Op1 & FpCondCodesMask;
201 vmsrFpscrIop = InstObjParams("vmsr", "VmsrFpscr", "FpRegRegOp",
202 { "code": vmsrFpscrCode,
203 "predicate_test": predicateTest,
204 "op_class": "SimdFloatMiscOp" },
205 ["IsSerializeAfter","IsNonSpeculative",
207 header_output += FpRegRegOpDeclare.subst(vmsrFpscrIop);
208 decoder_output += FpRegRegOpConstructor.subst(vmsrFpscrIop);
209 exec_output += PredOpExecute.subst(vmsrFpscrIop);
211 vmrsCode = vmrsEnabledCheckCode + '''
214 if (!inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP)) {
216 bool hypTrap = false;
217 switch(xc->tcBase()->flattenRegId(RegId(MiscRegClass, op1)).index()) {
227 return std::make_shared<HypervisorTrap>(machInst, imm,
228 EC_TRAPPED_CP10_MRC_VMRS);
234 vmrsIop = InstObjParams("vmrs", "Vmrs", "FpRegRegImmOp",
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);
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);
253 vmrsApsrFpscrCode = vfpEnabledCheckCode + '''
254 FPSCR fpscr = FpCondCodes;
255 CondCodesNZ = (fpscr.n << 1) | fpscr.z;
256 CondCodesC = fpscr.c;
257 CondCodesV = fpscr.v;
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);
267 vmovImmSCode = vfpEnabledCheckCode + '''
268 FpDest_uw = bits(imm, 31, 0);
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);
278 vmovImmDCode = vfpEnabledCheckCode + '''
279 FpDestP0_uw = bits(imm, 31, 0);
280 FpDestP1_uw = bits(imm, 63, 32);
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);
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);
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);
304 vmovRegSCode = vfpEnabledCheckCode + '''
305 FpDest_uw = FpOp1_uw;
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);
315 vmovRegDCode = vfpEnabledCheckCode + '''
316 FpDestP0_uw = FpOp1P0_uw;
317 FpDestP1_uw = FpOp1P1_uw;
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);
327 vmovRegQCode = vfpEnabledCheckCode + '''
328 FpDestP0_uw = FpOp1P0_uw;
329 FpDestP1_uw = FpOp1P1_uw;
330 FpDestP2_uw = FpOp1P2_uw;
331 FpDestP3_uw = FpOp1P3_uw;
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);
341 vmovCoreRegBCode = simdEnabledCheckCode + '''
342 FpDest_uw = insertBits(FpDest_uw, imm * 8 + 7, imm * 8, Op1_ub);
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);
352 vmovCoreRegHCode = simdEnabledCheckCode + '''
353 FpDest_uw = insertBits(FpDest_uw, imm * 16 + 15, imm * 16, Op1_uh);
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);
363 vmovCoreRegWCode = vfpEnabledCheckCode + '''
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);
374 vmovRegCoreUBCode = vfpEnabledCheckCode + '''
376 Dest = bits(FpOp1_uw, imm * 8 + 7, imm * 8);
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);
386 vmovRegCoreUHCode = vfpEnabledCheckCode + '''
388 Dest = bits(FpOp1_uw, imm * 16 + 15, imm * 16);
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);
398 vmovRegCoreSBCode = vfpEnabledCheckCode + '''
400 Dest = sext<8>(bits(FpOp1_uw, imm * 8 + 7, imm * 8));
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);
410 vmovRegCoreSHCode = vfpEnabledCheckCode + '''
412 Dest = sext<16>(bits(FpOp1_uw, imm * 16 + 15, imm * 16));
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);
422 vmovRegCoreWCode = vfpEnabledCheckCode + '''
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);
433 vmov2Reg2CoreCode = vfpEnabledCheckCode + '''
434 FpDestP0_uw = Op1_uw;
435 FpDestP1_uw = Op2_uw;
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);
445 vmov2Core2RegCode = vfpEnabledCheckCode + '''
446 Dest_uw = FpOp2P0_uw;
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);
464 singleSimpleCode = vfpEnabledCheckCode + '''
465 FPSCR fpscr M5_VAR_USED = (FPSCR) FpscrExc;
468 singleCode = singleSimpleCode + '''
471 singleTernOp = vfpEnabledCheckCode + '''
472 FPSCR fpscr = (FPSCR) FpscrExc;
473 VfpSavedState state = prepFpState(fpscr.rMode);
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);
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);
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);
506 binaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw),
507 dbl(FpOp2P0_uw, FpOp2P1_uw),
508 %(func)s, fpscr.fz, fpscr.dn, fpscr.rMode);
511 unaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw), %(func)s,
512 fpscr.fz, fpscr.rMode)
515 def buildTernaryFpOp(Name, base, opClass, singleOp, doubleOp, paramStr):
516 global header_output, decoder_output, exec_output
518 code = singleTernOp % { "op": singleOp, "palam": paramStr }
519 sIop = InstObjParams(Name.lower() + "s", Name + "S", base,
521 "predicate_test": predicateTest,
522 "op_class": opClass }, [])
523 code = doubleTernOp % { "op": doubleOp, "palam": paramStr }
524 dIop = InstObjParams(Name.lower() + "d", Name + "D", base,
526 "predicate_test": predicateTest,
527 "op_class": opClass }, [])
529 declareTempl = eval(base + "Declare");
530 constructorTempl = eval(base + "Constructor");
532 for iop in sIop, dIop:
533 header_output += declareTempl.subst(iop)
534 decoder_output += constructorTempl.subst(iop)
535 exec_output += PredOpExecute.subst(iop)
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" )
546 def buildBinFpOp(name, Name, base, opClass, singleOp, doubleOp):
547 global header_output, decoder_output, exec_output
549 code = singleCode % { "op": singleBinOp }
550 code = code % { "func": singleOp }
551 sIop = InstObjParams(name + "s", Name + "S", base,
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,
559 "predicate_test": predicateTest,
560 "op_class": opClass }, [])
562 declareTempl = eval(base + "Declare");
563 constructorTempl = eval(base + "Constructor");
565 for iop in sIop, dIop:
566 header_output += declareTempl.subst(iop)
567 decoder_output += constructorTempl.subst(iop)
568 exec_output += PredOpExecute.subst(iop)
570 buildBinFpOp("vadd", "Vadd", "FpRegRegRegOp", "SimdFloatAddOp", "fpAddS",
572 buildBinFpOp("vsub", "Vsub", "FpRegRegRegOp", "SimdFloatAddOp", "fpSubS",
574 buildBinFpOp("vdiv", "Vdiv", "FpRegRegRegOp", "SimdFloatDivOp", "fpDivS",
576 buildBinFpOp("vmul", "Vmul", "FpRegRegRegOp", "SimdFloatMultOp", "fpMulS",
579 def buildBinOp(name, base, opClass, op):
581 Create backported aarch64 instructions that use fplib.
583 Because they are backported, these instructions are unconditional.
585 global header_output, decoder_output, exec_output
590 FpDest_uw = fplib%(op)s<>(FpOp1_uw, FpOp2_uw, fpscr);
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);
602 FpDestP1_uw = dest >> 32;
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:
612 FPSCR fpscr = (FPSCR)FpscrExc;
621 Name + size_suffix.upper(),
624 "code": code % {"op": op},
629 header_output += declareTempl.subst(iop)
630 decoder_output += constructorTempl.subst(iop)
631 exec_output += BasicExecute.subst(iop)
633 ("vminnm", "FpRegRegRegOp", "SimdFloatCmpOp", "MinNum"),
634 ("vmaxnm", "FpRegRegRegOp", "SimdFloatCmpOp", "MaxNum"),
639 def buildUnaryFpOp(name, Name, base, opClass, singleOp, doubleOp = None):
642 global header_output, decoder_output, exec_output
644 code = singleCode % { "op": singleUnaryOp }
645 code = code % { "func": singleOp }
646 sIop = InstObjParams(name + "s", Name + "S", base,
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,
654 "predicate_test": predicateTest,
655 "op_class": opClass }, [])
657 declareTempl = eval(base + "Declare");
658 constructorTempl = eval(base + "Constructor");
660 for iop in sIop, dIop:
661 header_output += declareTempl.subst(iop)
662 decoder_output += constructorTempl.subst(iop)
663 exec_output += PredOpExecute.subst(iop)
665 buildUnaryFpOp("vsqrt", "Vsqrt", "FpRegRegOp", "SimdFloatSqrtOp", "sqrtf",
668 def buildSimpleUnaryFpOp(name, Name, base, opClass, singleOp,
672 global header_output, decoder_output, exec_output
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 }, [])
683 declareTempl = eval(base + "Declare");
684 constructorTempl = eval(base + "Constructor");
686 for iop in sIop, dIop:
687 header_output += declareTempl.subst(iop)
688 decoder_output += constructorTempl.subst(iop)
689 exec_output += PredOpExecute.subst(iop)
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)"
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)"
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)"
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)"
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);
731 vmlaSIop = InstObjParams("vmlas", "VmlaS", "FpRegRegRegOp",
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);
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);
751 vmlaDIop = InstObjParams("vmlad", "VmlaD", "FpRegRegRegOp",
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);
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);
767 vmlsSIop = InstObjParams("vmlss", "VmlsS", "FpRegRegRegOp",
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);
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);
787 vmlsDIop = InstObjParams("vmlsd", "VmlsD", "FpRegRegRegOp",
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);
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);
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);
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);
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);
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);
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);
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);
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);
867 vnmulSCode = vfpEnabledCheckCode + '''
868 FPSCR fpscr = (FPSCR) FpscrExc;
869 FpDest = -binaryOp(fpscr, FpOp1, FpOp2, fpMulS,
870 fpscr.fz, fpscr.dn, fpscr.rMode);
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);
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,
887 FpDestP0_uw = dblLow(dest);
888 FpDestP1_uw = dblHi(dest);
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);
906 vcvtUIntFpSCode = vfpEnabledCheckCode + '''
907 FPSCR fpscr = (FPSCR) FpscrExc;
908 VfpSavedState state = prepFpState(fpscr.rMode);
909 __asm__ __volatile__("" : "=m" (FpOp1_uw) : "m" (FpOp1_uw));
911 __asm__ __volatile__("" :: "m" (FpDest));
912 finishVfp(fpscr, state, fpscr.fz);
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);
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);
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);
942 vcvtSIntFpSCode = vfpEnabledCheckCode + '''
943 FPSCR fpscr = (FPSCR) FpscrExc;
944 VfpSavedState state = prepFpState(fpscr.rMode);
945 __asm__ __volatile__("" : "=m" (FpOp1_sw) : "m" (FpOp1_sw));
947 __asm__ __volatile__("" :: "m" (FpDest));
948 finishVfp(fpscr, state, fpscr.fz);
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);
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);
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);
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));
983 FpDest_uw = fplibFPToFixedJS(cOp1, fpscr, false, nz);
984 finishVfp(fpscr, state, fpscr.fz);
985 FpCondCodes = fpscr & FpCondCodesMask;
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);
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);
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);
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;
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);
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);
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);
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;
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);
1072 round_mode_suffix_to_mode = {
1074 'a': 'VfpRoundAway',
1075 'm': 'VfpRoundDown',
1076 'n': 'VfpRoundNearest',
1077 'p': 'VfpRoundUpward',
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],
1086 iop = InstObjParams(
1087 "vcvt{}".format(roundModeSuffix),
1088 className.format(roundModeSuffix),
1090 { "code": full_code,
1091 "predicate_test": predicateTest,
1092 "op_class": "SimdFloatCvtOp" },
1095 header_output += FpRegRegOpDeclare.subst(iop);
1096 decoder_output += FpRegRegOpConstructor.subst(iop);
1097 exec_output += PredOpExecute.subst(iop);
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);
1111 for round_mode_suffix in round_mode_suffix_to_mode:
1112 buildVcvt(code, "Vcvt{}FpUIntS", round_mode_suffix)
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;
1128 for round_mode_suffix in round_mode_suffix_to_mode:
1129 buildVcvt(code, "Vcvt{}FpUIntD", round_mode_suffix)
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);
1143 for round_mode_suffix in round_mode_suffix_to_mode:
1144 buildVcvt(code, "Vcvt{}FpSIntS", round_mode_suffix)
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;
1160 for round_mode_suffix in round_mode_suffix_to_mode:
1161 buildVcvt(code, "Vcvt{}FpSIntD", round_mode_suffix)
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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;
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)
1298 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1300 FpCondCodes = fpscr & FpCondCodesMask;
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);
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;
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)
1330 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1332 FpCondCodes = fpscr & FpCondCodesMask;
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);
1343 vcmpZeroSCode = vfpEnabledCheckCode + '''
1344 FPSCR fpscr = (FPSCR) FpscrExc;
1345 vfpFlushToZero(fpscr, FpDest);
1346 // This only handles imm == 0 for now.
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;
1355 const uint32_t qnan = 0x7fc00000;
1356 const bool nan = std::isnan(FpDest);
1357 const bool signal = nan && ((fpToBits(FpDest) & qnan) != qnan);
1360 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1362 FpCondCodes = fpscr & FpCondCodesMask;
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);
1373 vcmpZeroDCode = vfpEnabledCheckCode + '''
1374 // This only handles imm == 0 for now.
1376 double cDest = dbl(FpDestP0_uw, FpDestP1_uw);
1377 FPSCR fpscr = (FPSCR) FpscrExc;
1378 vfpFlushToZero(fpscr, cDest);
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;
1386 const uint64_t qnan = ULL(0x7ff8000000000000);
1387 const bool nan = std::isnan(cDest);
1388 const bool signal = nan && ((fpToBits(cDest) & qnan) != qnan);
1391 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1393 FpCondCodes = fpscr & FpCondCodesMask;
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);
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;
1415 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1417 FpCondCodes = fpscr & FpCondCodesMask;
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);
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;
1441 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1443 FpCondCodes = fpscr & FpCondCodesMask;
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);
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;
1465 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1467 FpCondCodes = fpscr & FpCondCodesMask;
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);
1478 vcmpeZeroDCode = vfpEnabledCheckCode + '''
1479 double cDest = dbl(FpDestP0_uw, FpDestP1_uw);
1480 FPSCR fpscr = (FPSCR) FpscrExc;
1481 vfpFlushToZero(fpscr, cDest);
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;
1490 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1492 FpCondCodes = fpscr & FpCondCodesMask;
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);
1510 vselSCode = vfpEnabledCheckCode + '''
1511 if (testPredicate(CondCodesNZ, CondCodesC, CondCodesV, cond)) {
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);
1525 vselDCode = vfpEnabledCheckCode + '''
1526 if (testPredicate(CondCodesNZ, CondCodesC, CondCodesV, cond)) {
1527 FpDestP0_uw = FpOp1P0_uw;
1528 FpDestP1_uw = FpOp1P1_uw;
1530 FpDestP0_uw = FpOp2P0_uw;
1531 FpDestP1_uw = FpOp2P1_uw;
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);
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);
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);
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);
1578 FpDestP1_uw = mid >> 32;
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);
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);
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);
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);
1617 FpDestP1_uw = mid >> 32;
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
1712 vcvtFpSHFixedSIop = InstObjParams("vcvt", "VcvtFpSHFixedS",
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);
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;
1734 vcvtFpSHFixedDIop = InstObjParams("vcvt", "VcvtFpSHFixedD",
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);
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);
1753 vcvtFpUHFixedSIop = InstObjParams("vcvt", "VcvtFpUHFixedS",
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);
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);
1772 FpDestP1_uw = mid >> 32;
1775 vcvtFpUHFixedDIop = InstObjParams("vcvt", "VcvtFpUHFixedD",
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);
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);
1793 vcvtSHFixedFpSIop = InstObjParams("vcvt", "VcvtSHFixedFpS",
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);
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);
1814 vcvtSHFixedFpDIop = InstObjParams("vcvt", "VcvtSHFixedFpD",
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);
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);
1832 vcvtUHFixedFpSIop = InstObjParams("vcvt", "VcvtUHFixedFpS",
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);
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);
1853 vcvtUHFixedFpDIop = InstObjParams("vcvt", "VcvtUHFixedFpD",
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);