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 + '''
213 if (!isSecure(xc->tcBase()) && (cpsr.mode != MODE_HYP)) {
215 bool hypTrap = false;
216 switch(xc->tcBase()->flattenRegId(RegId(MiscRegClass, op1)).index()) {
226 return std::make_shared<HypervisorTrap>(machInst, imm,
227 EC_TRAPPED_CP10_MRC_VMRS);
233 vmrsIop = InstObjParams("vmrs", "Vmrs", "FpRegRegImmOp",
235 "predicate_test": predicateTest,
236 "op_class": "SimdFloatMiscOp" },
237 ["IsSerializeBefore"])
238 header_output += FpRegRegImmOpDeclare.subst(vmrsIop);
239 decoder_output += FpRegRegImmOpConstructor.subst(vmrsIop);
240 exec_output += PredOpExecute.subst(vmrsIop);
242 vmrsFpscrIop = InstObjParams("vmrs", "VmrsFpscr", "FpRegRegOp",
243 { "code": vmrsEnabledCheckCode + \
244 "Dest = Fpscr | FpCondCodes;",
245 "predicate_test": predicateTest,
246 "op_class": "SimdFloatMiscOp" },
247 ["IsSerializeBefore"])
248 header_output += FpRegRegOpDeclare.subst(vmrsFpscrIop);
249 decoder_output += FpRegRegOpConstructor.subst(vmrsFpscrIop);
250 exec_output += PredOpExecute.subst(vmrsFpscrIop);
252 vmrsApsrFpscrCode = vfpEnabledCheckCode + '''
253 FPSCR fpscr = FpCondCodes;
254 CondCodesNZ = (fpscr.n << 1) | fpscr.z;
255 CondCodesC = fpscr.c;
256 CondCodesV = fpscr.v;
258 vmrsApsrFpscrIop = InstObjParams("vmrs", "VmrsApsrFpscr", "PredOp",
259 { "code": vmrsApsrFpscrCode,
260 "predicate_test": predicateTest,
261 "op_class": "SimdFloatMiscOp" })
262 header_output += BasicDeclare.subst(vmrsApsrFpscrIop);
263 decoder_output += BasicConstructor.subst(vmrsApsrFpscrIop);
264 exec_output += PredOpExecute.subst(vmrsApsrFpscrIop);
266 vmovImmSCode = vfpEnabledCheckCode + '''
267 FpDest_uw = bits(imm, 31, 0);
269 vmovImmSIop = InstObjParams("vmov", "VmovImmS", "FpRegImmOp",
270 { "code": vmovImmSCode,
271 "predicate_test": predicateTest,
272 "op_class": "SimdFloatMiscOp" }, [])
273 header_output += FpRegImmOpDeclare.subst(vmovImmSIop);
274 decoder_output += FpRegImmOpConstructor.subst(vmovImmSIop);
275 exec_output += PredOpExecute.subst(vmovImmSIop);
277 vmovImmDCode = vfpEnabledCheckCode + '''
278 FpDestP0_uw = bits(imm, 31, 0);
279 FpDestP1_uw = bits(imm, 63, 32);
281 vmovImmDIop = InstObjParams("vmov", "VmovImmD", "FpRegImmOp",
282 { "code": vmovImmDCode,
283 "predicate_test": predicateTest,
284 "op_class": "SimdFloatMiscOp" }, [])
285 header_output += FpRegImmOpDeclare.subst(vmovImmDIop);
286 decoder_output += FpRegImmOpConstructor.subst(vmovImmDIop);
287 exec_output += PredOpExecute.subst(vmovImmDIop);
289 vmovImmQCode = vfpEnabledCheckCode + '''
290 FpDestP0_uw = bits(imm, 31, 0);
291 FpDestP1_uw = bits(imm, 63, 32);
292 FpDestP2_uw = bits(imm, 31, 0);
293 FpDestP3_uw = bits(imm, 63, 32);
295 vmovImmQIop = InstObjParams("vmov", "VmovImmQ", "FpRegImmOp",
296 { "code": vmovImmQCode,
297 "predicate_test": predicateTest,
298 "op_class": "SimdFloatMiscOp" }, [])
299 header_output += FpRegImmOpDeclare.subst(vmovImmQIop);
300 decoder_output += FpRegImmOpConstructor.subst(vmovImmQIop);
301 exec_output += PredOpExecute.subst(vmovImmQIop);
303 vmovRegSCode = vfpEnabledCheckCode + '''
304 FpDest_uw = FpOp1_uw;
306 vmovRegSIop = InstObjParams("vmov", "VmovRegS", "FpRegRegOp",
307 { "code": vmovRegSCode,
308 "predicate_test": predicateTest,
309 "op_class": "SimdFloatMiscOp" }, [])
310 header_output += FpRegRegOpDeclare.subst(vmovRegSIop);
311 decoder_output += FpRegRegOpConstructor.subst(vmovRegSIop);
312 exec_output += PredOpExecute.subst(vmovRegSIop);
314 vmovRegDCode = vfpEnabledCheckCode + '''
315 FpDestP0_uw = FpOp1P0_uw;
316 FpDestP1_uw = FpOp1P1_uw;
318 vmovRegDIop = InstObjParams("vmov", "VmovRegD", "FpRegRegOp",
319 { "code": vmovRegDCode,
320 "predicate_test": predicateTest,
321 "op_class": "SimdFloatMiscOp" }, [])
322 header_output += FpRegRegOpDeclare.subst(vmovRegDIop);
323 decoder_output += FpRegRegOpConstructor.subst(vmovRegDIop);
324 exec_output += PredOpExecute.subst(vmovRegDIop);
326 vmovRegQCode = vfpEnabledCheckCode + '''
327 FpDestP0_uw = FpOp1P0_uw;
328 FpDestP1_uw = FpOp1P1_uw;
329 FpDestP2_uw = FpOp1P2_uw;
330 FpDestP3_uw = FpOp1P3_uw;
332 vmovRegQIop = InstObjParams("vmov", "VmovRegQ", "FpRegRegOp",
333 { "code": vmovRegQCode,
334 "predicate_test": predicateTest,
335 "op_class": "SimdFloatMiscOp" }, [])
336 header_output += FpRegRegOpDeclare.subst(vmovRegQIop);
337 decoder_output += FpRegRegOpConstructor.subst(vmovRegQIop);
338 exec_output += PredOpExecute.subst(vmovRegQIop);
340 vmovCoreRegBCode = simdEnabledCheckCode + '''
341 FpDest_uw = insertBits(FpDest_uw, imm * 8 + 7, imm * 8, Op1_ub);
343 vmovCoreRegBIop = InstObjParams("vmov", "VmovCoreRegB", "FpRegRegImmOp",
344 { "code": vmovCoreRegBCode,
345 "predicate_test": predicateTest,
346 "op_class": "SimdFloatMiscOp" }, [])
347 header_output += FpRegRegImmOpDeclare.subst(vmovCoreRegBIop);
348 decoder_output += FpRegRegImmOpConstructor.subst(vmovCoreRegBIop);
349 exec_output += PredOpExecute.subst(vmovCoreRegBIop);
351 vmovCoreRegHCode = simdEnabledCheckCode + '''
352 FpDest_uw = insertBits(FpDest_uw, imm * 16 + 15, imm * 16, Op1_uh);
354 vmovCoreRegHIop = InstObjParams("vmov", "VmovCoreRegH", "FpRegRegImmOp",
355 { "code": vmovCoreRegHCode,
356 "predicate_test": predicateTest,
357 "op_class": "SimdFloatMiscOp" }, [])
358 header_output += FpRegRegImmOpDeclare.subst(vmovCoreRegHIop);
359 decoder_output += FpRegRegImmOpConstructor.subst(vmovCoreRegHIop);
360 exec_output += PredOpExecute.subst(vmovCoreRegHIop);
362 vmovCoreRegWCode = vfpEnabledCheckCode + '''
365 vmovCoreRegWIop = InstObjParams("vmov", "VmovCoreRegW", "FpRegRegOp",
366 { "code": vmovCoreRegWCode,
367 "predicate_test": predicateTest,
368 "op_class": "SimdFloatMiscOp" }, [])
369 header_output += FpRegRegOpDeclare.subst(vmovCoreRegWIop);
370 decoder_output += FpRegRegOpConstructor.subst(vmovCoreRegWIop);
371 exec_output += PredOpExecute.subst(vmovCoreRegWIop);
373 vmovRegCoreUBCode = vfpEnabledCheckCode + '''
375 Dest = bits(FpOp1_uw, imm * 8 + 7, imm * 8);
377 vmovRegCoreUBIop = InstObjParams("vmov", "VmovRegCoreUB", "FpRegRegImmOp",
378 { "code": vmovRegCoreUBCode,
379 "predicate_test": predicateTest,
380 "op_class": "SimdFloatMiscOp" }, [])
381 header_output += FpRegRegImmOpDeclare.subst(vmovRegCoreUBIop);
382 decoder_output += FpRegRegImmOpConstructor.subst(vmovRegCoreUBIop);
383 exec_output += PredOpExecute.subst(vmovRegCoreUBIop);
385 vmovRegCoreUHCode = vfpEnabledCheckCode + '''
387 Dest = bits(FpOp1_uw, imm * 16 + 15, imm * 16);
389 vmovRegCoreUHIop = InstObjParams("vmov", "VmovRegCoreUH", "FpRegRegImmOp",
390 { "code": vmovRegCoreUHCode,
391 "predicate_test": predicateTest,
392 "op_class": "SimdFloatMiscOp" }, [])
393 header_output += FpRegRegImmOpDeclare.subst(vmovRegCoreUHIop);
394 decoder_output += FpRegRegImmOpConstructor.subst(vmovRegCoreUHIop);
395 exec_output += PredOpExecute.subst(vmovRegCoreUHIop);
397 vmovRegCoreSBCode = vfpEnabledCheckCode + '''
399 Dest = sext<8>(bits(FpOp1_uw, imm * 8 + 7, imm * 8));
401 vmovRegCoreSBIop = InstObjParams("vmov", "VmovRegCoreSB", "FpRegRegImmOp",
402 { "code": vmovRegCoreSBCode,
403 "predicate_test": predicateTest,
404 "op_class": "SimdFloatMiscOp" }, [])
405 header_output += FpRegRegImmOpDeclare.subst(vmovRegCoreSBIop);
406 decoder_output += FpRegRegImmOpConstructor.subst(vmovRegCoreSBIop);
407 exec_output += PredOpExecute.subst(vmovRegCoreSBIop);
409 vmovRegCoreSHCode = vfpEnabledCheckCode + '''
411 Dest = sext<16>(bits(FpOp1_uw, imm * 16 + 15, imm * 16));
413 vmovRegCoreSHIop = InstObjParams("vmov", "VmovRegCoreSH", "FpRegRegImmOp",
414 { "code": vmovRegCoreSHCode,
415 "predicate_test": predicateTest,
416 "op_class": "SimdFloatMiscOp" }, [])
417 header_output += FpRegRegImmOpDeclare.subst(vmovRegCoreSHIop);
418 decoder_output += FpRegRegImmOpConstructor.subst(vmovRegCoreSHIop);
419 exec_output += PredOpExecute.subst(vmovRegCoreSHIop);
421 vmovRegCoreWCode = vfpEnabledCheckCode + '''
424 vmovRegCoreWIop = InstObjParams("vmov", "VmovRegCoreW", "FpRegRegOp",
425 { "code": vmovRegCoreWCode,
426 "predicate_test": predicateTest,
427 "op_class": "SimdFloatMiscOp" }, [])
428 header_output += FpRegRegOpDeclare.subst(vmovRegCoreWIop);
429 decoder_output += FpRegRegOpConstructor.subst(vmovRegCoreWIop);
430 exec_output += PredOpExecute.subst(vmovRegCoreWIop);
432 vmov2Reg2CoreCode = vfpEnabledCheckCode + '''
433 FpDestP0_uw = Op1_uw;
434 FpDestP1_uw = Op2_uw;
436 vmov2Reg2CoreIop = InstObjParams("vmov", "Vmov2Reg2Core", "FpRegRegRegOp",
437 { "code": vmov2Reg2CoreCode,
438 "predicate_test": predicateTest,
439 "op_class": "SimdFloatMiscOp" }, [])
440 header_output += FpRegRegRegOpDeclare.subst(vmov2Reg2CoreIop);
441 decoder_output += FpRegRegRegOpConstructor.subst(vmov2Reg2CoreIop);
442 exec_output += PredOpExecute.subst(vmov2Reg2CoreIop);
444 vmov2Core2RegCode = vfpEnabledCheckCode + '''
445 Dest_uw = FpOp2P0_uw;
448 vmov2Core2RegIop = InstObjParams("vmov", "Vmov2Core2Reg", "FpRegRegRegOp",
449 { "code": vmov2Core2RegCode,
450 "predicate_test": predicateTest,
451 "op_class": "SimdFloatMiscOp" }, [])
452 header_output += FpRegRegRegOpDeclare.subst(vmov2Core2RegIop);
453 decoder_output += FpRegRegRegOpConstructor.subst(vmov2Core2RegIop);
454 exec_output += PredOpExecute.subst(vmov2Core2RegIop);
463 singleSimpleCode = vfpEnabledCheckCode + '''
464 FPSCR fpscr M5_VAR_USED = (FPSCR) FpscrExc;
467 singleCode = singleSimpleCode + '''
470 singleTernOp = vfpEnabledCheckCode + '''
471 FPSCR fpscr = (FPSCR) FpscrExc;
472 VfpSavedState state = prepFpState(fpscr.rMode);
475 float cOp3 = FpDestP0;
476 FpDestP0 = ternaryOp(fpscr, %(palam)s, %(op)s,
477 fpscr.fz, fpscr.dn, fpscr.rMode);
478 finishVfp(fpscr, state, fpscr.fz);
481 singleBinOp = "binaryOp(fpscr, FpOp1, FpOp2," + \
482 "%(func)s, fpscr.fz, fpscr.dn, fpscr.rMode)"
483 singleUnaryOp = "unaryOp(fpscr, FpOp1, %(func)s, fpscr.fz, fpscr.rMode)"
484 doubleCode = vfpEnabledCheckCode + '''
485 FPSCR fpscr M5_VAR_USED = (FPSCR) FpscrExc;
486 double dest = %(op)s;
487 FpDestP0_uw = dblLow(dest);
488 FpDestP1_uw = dblHi(dest);
491 doubleTernOp = vfpEnabledCheckCode + '''
492 FPSCR fpscr = (FPSCR) FpscrExc;
493 VfpSavedState state = prepFpState(fpscr.rMode);
494 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
495 double cOp2 = dbl(FpOp2P0_uw, FpOp2P1_uw);
496 double cOp3 = dbl(FpDestP0_uw, FpDestP1_uw);
497 double cDest = ternaryOp(fpscr, %(palam)s, %(op)s,
498 fpscr.fz, fpscr.dn, fpscr.rMode);
499 FpDestP0_uw = dblLow(cDest);
500 FpDestP1_uw = dblHi(cDest);
501 finishVfp(fpscr, state, fpscr.fz);
505 binaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw),
506 dbl(FpOp2P0_uw, FpOp2P1_uw),
507 %(func)s, fpscr.fz, fpscr.dn, fpscr.rMode);
510 unaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw), %(func)s,
511 fpscr.fz, fpscr.rMode)
514 def buildTernaryFpOp(Name, base, opClass, singleOp, doubleOp, paramStr):
515 global header_output, decoder_output, exec_output
517 code = singleTernOp % { "op": singleOp, "palam": paramStr }
518 sIop = InstObjParams(Name.lower() + "s", Name + "S", base,
520 "predicate_test": predicateTest,
521 "op_class": opClass }, [])
522 code = doubleTernOp % { "op": doubleOp, "palam": paramStr }
523 dIop = InstObjParams(Name.lower() + "d", Name + "D", base,
525 "predicate_test": predicateTest,
526 "op_class": opClass }, [])
528 declareTempl = eval(base + "Declare");
529 constructorTempl = eval(base + "Constructor");
531 for iop in sIop, dIop:
532 header_output += declareTempl.subst(iop)
533 decoder_output += constructorTempl.subst(iop)
534 exec_output += PredOpExecute.subst(iop)
536 buildTernaryFpOp("Vfma", "FpRegRegRegOp", "SimdFloatMultAccOp",
537 "fpMulAdd<float>", "fpMulAdd<double>", " cOp1, cOp2, cOp3" )
538 buildTernaryFpOp("Vfms", "FpRegRegRegOp", "SimdFloatMultAccOp",
539 "fpMulAdd<float>", "fpMulAdd<double>", "-cOp1, cOp2, cOp3" )
540 buildTernaryFpOp("Vfnma", "FpRegRegRegOp", "SimdFloatMultAccOp",
541 "fpMulAdd<float>", "fpMulAdd<double>", "-cOp1, cOp2, -cOp3" )
542 buildTernaryFpOp("Vfnms", "FpRegRegRegOp", "SimdFloatMultAccOp",
543 "fpMulAdd<float>", "fpMulAdd<double>", " cOp1, cOp2, -cOp3" )
545 def buildBinFpOp(name, Name, base, opClass, singleOp, doubleOp):
546 global header_output, decoder_output, exec_output
548 code = singleCode % { "op": singleBinOp }
549 code = code % { "func": singleOp }
550 sIop = InstObjParams(name + "s", Name + "S", base,
552 "predicate_test": predicateTest,
553 "op_class": opClass }, [])
554 code = doubleCode % { "op": doubleBinOp }
555 code = code % { "func": doubleOp }
556 dIop = InstObjParams(name + "d", Name + "D", base,
558 "predicate_test": predicateTest,
559 "op_class": opClass }, [])
561 declareTempl = eval(base + "Declare");
562 constructorTempl = eval(base + "Constructor");
564 for iop in sIop, dIop:
565 header_output += declareTempl.subst(iop)
566 decoder_output += constructorTempl.subst(iop)
567 exec_output += PredOpExecute.subst(iop)
569 buildBinFpOp("vadd", "Vadd", "FpRegRegRegOp", "SimdFloatAddOp", "fpAddS",
571 buildBinFpOp("vsub", "Vsub", "FpRegRegRegOp", "SimdFloatAddOp", "fpSubS",
573 buildBinFpOp("vdiv", "Vdiv", "FpRegRegRegOp", "SimdFloatDivOp", "fpDivS",
575 buildBinFpOp("vmul", "Vmul", "FpRegRegRegOp", "SimdFloatMultOp", "fpMulS",
578 def buildBinOp(name, base, opClass, op):
580 Create backported aarch64 instructions that use fplib.
582 Because they are backported, these instructions are unconditional.
584 global header_output, decoder_output, exec_output
589 FpDest_uw = fplib%(op)s<>(FpOp1_uw, FpOp2_uw, fpscr);
595 uint64_t op1 = ((uint64_t)FpOp1P0_uw |
596 ((uint64_t)FpOp1P1_uw << 32));
597 uint64_t op2 = ((uint64_t)FpOp2P0_uw |
598 ((uint64_t)FpOp2P1_uw << 32));
599 uint64_t dest = fplib%(op)s<>(op1, op2, fpscr);
601 FpDestP1_uw = dest >> 32;
605 Name = name[0].upper() + name[1:]
606 declareTempl = eval(base + "Declare");
607 constructorTempl = eval(base + "Constructor");
608 for size_suffix, code in inst_datas:
611 FPSCR fpscr = (FPSCR)FpscrExc;
620 Name + size_suffix.upper(),
623 "code": code % {"op": op},
628 header_output += declareTempl.subst(iop)
629 decoder_output += constructorTempl.subst(iop)
630 exec_output += BasicExecute.subst(iop)
632 ("vminnm", "FpRegRegRegOp", "SimdFloatCmpOp", "MinNum"),
633 ("vmaxnm", "FpRegRegRegOp", "SimdFloatCmpOp", "MaxNum"),
638 def buildUnaryFpOp(name, Name, base, opClass, singleOp, doubleOp = None):
641 global header_output, decoder_output, exec_output
643 code = singleCode % { "op": singleUnaryOp }
644 code = code % { "func": singleOp }
645 sIop = InstObjParams(name + "s", Name + "S", base,
647 "predicate_test": predicateTest,
648 "op_class": opClass }, [])
649 code = doubleCode % { "op": doubleUnaryOp }
650 code = code % { "func": doubleOp }
651 dIop = InstObjParams(name + "d", Name + "D", base,
653 "predicate_test": predicateTest,
654 "op_class": opClass }, [])
656 declareTempl = eval(base + "Declare");
657 constructorTempl = eval(base + "Constructor");
659 for iop in sIop, dIop:
660 header_output += declareTempl.subst(iop)
661 decoder_output += constructorTempl.subst(iop)
662 exec_output += PredOpExecute.subst(iop)
664 buildUnaryFpOp("vsqrt", "Vsqrt", "FpRegRegOp", "SimdFloatSqrtOp", "sqrtf",
667 def buildSimpleUnaryFpOp(name, Name, base, opClass, singleOp,
671 global header_output, decoder_output, exec_output
673 sIop = InstObjParams(name + "s", Name + "S", base,
674 { "code": singleSimpleCode % { "op": singleOp },
675 "predicate_test": predicateTest,
676 "op_class": opClass }, [])
677 dIop = InstObjParams(name + "d", Name + "D", base,
678 { "code": doubleCode % { "op": doubleOp },
679 "predicate_test": predicateTest,
680 "op_class": opClass }, [])
682 declareTempl = eval(base + "Declare");
683 constructorTempl = eval(base + "Constructor");
685 for iop in sIop, dIop:
686 header_output += declareTempl.subst(iop)
687 decoder_output += constructorTempl.subst(iop)
688 exec_output += PredOpExecute.subst(iop)
690 buildSimpleUnaryFpOp("vneg", "Vneg", "FpRegRegOp", "SimdFloatMiscOp",
691 "-FpOp1", "-dbl(FpOp1P0_uw, FpOp1P1_uw)")
692 buildSimpleUnaryFpOp("vabs", "Vabs", "FpRegRegOp", "SimdFloatMiscOp",
693 "fabsf(FpOp1)", "fabs(dbl(FpOp1P0_uw, FpOp1P1_uw))")
694 buildSimpleUnaryFpOp("vrintp", "VRIntP", "FpRegRegOp", "SimdFloatMiscOp",
695 "fplibRoundInt<uint32_t>(FpOp1, FPRounding_POSINF, false, fpscr)",
696 "fplibRoundInt<uint64_t>(dbl(FpOp1P0_uw, FpOp1P1_uw), " \
697 "FPRounding_POSINF, false, fpscr)"
699 buildSimpleUnaryFpOp("vrintm", "VRIntM", "FpRegRegOp", "SimdFloatMiscOp",
700 "fplibRoundInt<uint32_t>(FpOp1, FPRounding_NEGINF, false, fpscr)",
701 "fplibRoundInt<uint64_t>(dbl(FpOp1P0_uw, FpOp1P1_uw), " \
702 "FPRounding_NEGINF, false, fpscr)"
704 buildSimpleUnaryFpOp("vrinta", "VRIntA", "FpRegRegOp", "SimdFloatMiscOp",
705 "fplibRoundInt<uint32_t>(FpOp1, FPRounding_TIEAWAY, false, fpscr)",
706 "fplibRoundInt<uint64_t>(dbl(FpOp1P0_uw, FpOp1P1_uw), " \
707 "FPRounding_TIEAWAY, false, fpscr)"
709 buildSimpleUnaryFpOp("vrintn", "VRIntN", "FpRegRegOp", "SimdFloatMiscOp",
710 "fplibRoundInt<uint32_t>(FpOp1, FPRounding_TIEEVEN, false, fpscr)",
711 "fplibRoundInt<uint64_t>(dbl(FpOp1P0_uw, FpOp1P1_uw), " \
712 "FPRounding_TIEEVEN, false, fpscr)"
722 vmlaSCode = vfpEnabledCheckCode + '''
723 FPSCR fpscr = (FPSCR) FpscrExc;
724 float mid = binaryOp(fpscr, FpOp1, FpOp2,
725 fpMulS, fpscr.fz, fpscr.dn, fpscr.rMode);
726 FpDest = binaryOp(fpscr, FpDest, mid, fpAddS,
727 fpscr.fz, fpscr.dn, fpscr.rMode);
730 vmlaSIop = InstObjParams("vmlas", "VmlaS", "FpRegRegRegOp",
732 "predicate_test": predicateTest,
733 "op_class": "SimdFloatMultAccOp" }, [])
734 header_output += FpRegRegRegOpDeclare.subst(vmlaSIop);
735 decoder_output += FpRegRegRegOpConstructor.subst(vmlaSIop);
736 exec_output += PredOpExecute.subst(vmlaSIop);
738 vmlaDCode = vfpEnabledCheckCode + '''
739 FPSCR fpscr = (FPSCR) FpscrExc;
740 double mid = binaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw),
741 dbl(FpOp2P0_uw, FpOp2P1_uw),
742 fpMulD, fpscr.fz, fpscr.dn, fpscr.rMode);
743 double dest = binaryOp(fpscr, dbl(FpDestP0_uw, FpDestP1_uw),
744 mid, fpAddD, fpscr.fz,
745 fpscr.dn, fpscr.rMode);
746 FpDestP0_uw = dblLow(dest);
747 FpDestP1_uw = dblHi(dest);
750 vmlaDIop = InstObjParams("vmlad", "VmlaD", "FpRegRegRegOp",
752 "predicate_test": predicateTest,
753 "op_class": "SimdFloatMultAccOp" }, [])
754 header_output += FpRegRegRegOpDeclare.subst(vmlaDIop);
755 decoder_output += FpRegRegRegOpConstructor.subst(vmlaDIop);
756 exec_output += PredOpExecute.subst(vmlaDIop);
758 vmlsSCode = vfpEnabledCheckCode + '''
759 FPSCR fpscr = (FPSCR) FpscrExc;
760 float mid = binaryOp(fpscr, FpOp1, FpOp2,
761 fpMulS, fpscr.fz, fpscr.dn, fpscr.rMode);
762 FpDest = binaryOp(fpscr, FpDest, -mid, fpAddS,
763 fpscr.fz, fpscr.dn, fpscr.rMode);
766 vmlsSIop = InstObjParams("vmlss", "VmlsS", "FpRegRegRegOp",
768 "predicate_test": predicateTest,
769 "op_class": "SimdFloatMultAccOp" }, [])
770 header_output += FpRegRegRegOpDeclare.subst(vmlsSIop);
771 decoder_output += FpRegRegRegOpConstructor.subst(vmlsSIop);
772 exec_output += PredOpExecute.subst(vmlsSIop);
774 vmlsDCode = vfpEnabledCheckCode + '''
775 FPSCR fpscr = (FPSCR) FpscrExc;
776 double mid = binaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw),
777 dbl(FpOp2P0_uw, FpOp2P1_uw),
778 fpMulD, fpscr.fz, fpscr.dn, fpscr.rMode);
779 double dest = binaryOp(fpscr, dbl(FpDestP0_uw, FpDestP1_uw),
780 -mid, fpAddD, fpscr.fz,
781 fpscr.dn, fpscr.rMode);
782 FpDestP0_uw = dblLow(dest);
783 FpDestP1_uw = dblHi(dest);
786 vmlsDIop = InstObjParams("vmlsd", "VmlsD", "FpRegRegRegOp",
788 "predicate_test": predicateTest,
789 "op_class": "SimdFloatMultAccOp" }, [])
790 header_output += FpRegRegRegOpDeclare.subst(vmlsDIop);
791 decoder_output += FpRegRegRegOpConstructor.subst(vmlsDIop);
792 exec_output += PredOpExecute.subst(vmlsDIop);
794 vnmlaSCode = vfpEnabledCheckCode + '''
795 FPSCR fpscr = (FPSCR) FpscrExc;
796 float mid = binaryOp(fpscr, FpOp1, FpOp2,
797 fpMulS, fpscr.fz, fpscr.dn, fpscr.rMode);
798 FpDest = binaryOp(fpscr, -FpDest, -mid, fpAddS,
799 fpscr.fz, fpscr.dn, fpscr.rMode);
802 vnmlaSIop = InstObjParams("vnmlas", "VnmlaS", "FpRegRegRegOp",
803 { "code": vnmlaSCode,
804 "predicate_test": predicateTest,
805 "op_class": "SimdFloatMultAccOp" }, [])
806 header_output += FpRegRegRegOpDeclare.subst(vnmlaSIop);
807 decoder_output += FpRegRegRegOpConstructor.subst(vnmlaSIop);
808 exec_output += PredOpExecute.subst(vnmlaSIop);
810 vnmlaDCode = vfpEnabledCheckCode + '''
811 FPSCR fpscr = (FPSCR) FpscrExc;
812 double mid = binaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw),
813 dbl(FpOp2P0_uw, FpOp2P1_uw),
814 fpMulD, fpscr.fz, fpscr.dn, fpscr.rMode);
815 double dest = binaryOp(fpscr, -dbl(FpDestP0_uw, FpDestP1_uw),
816 -mid, fpAddD, fpscr.fz,
817 fpscr.dn, fpscr.rMode);
818 FpDestP0_uw = dblLow(dest);
819 FpDestP1_uw = dblHi(dest);
822 vnmlaDIop = InstObjParams("vnmlad", "VnmlaD", "FpRegRegRegOp",
823 { "code": vnmlaDCode,
824 "predicate_test": predicateTest,
825 "op_class": "SimdFloatMultAccOp" }, [])
826 header_output += FpRegRegRegOpDeclare.subst(vnmlaDIop);
827 decoder_output += FpRegRegRegOpConstructor.subst(vnmlaDIop);
828 exec_output += PredOpExecute.subst(vnmlaDIop);
830 vnmlsSCode = vfpEnabledCheckCode + '''
831 FPSCR fpscr = (FPSCR) FpscrExc;
832 float mid = binaryOp(fpscr, FpOp1, FpOp2,
833 fpMulS, fpscr.fz, fpscr.dn, fpscr.rMode);
834 FpDest = binaryOp(fpscr, -FpDest, mid, fpAddS,
835 fpscr.fz, fpscr.dn, fpscr.rMode);
838 vnmlsSIop = InstObjParams("vnmlss", "VnmlsS", "FpRegRegRegOp",
839 { "code": vnmlsSCode,
840 "predicate_test": predicateTest,
841 "op_class": "SimdFloatMultAccOp" }, [])
842 header_output += FpRegRegRegOpDeclare.subst(vnmlsSIop);
843 decoder_output += FpRegRegRegOpConstructor.subst(vnmlsSIop);
844 exec_output += PredOpExecute.subst(vnmlsSIop);
846 vnmlsDCode = vfpEnabledCheckCode + '''
847 FPSCR fpscr = (FPSCR) FpscrExc;
848 double mid = binaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw),
849 dbl(FpOp2P0_uw, FpOp2P1_uw),
850 fpMulD, fpscr.fz, fpscr.dn, fpscr.rMode);
851 double dest = binaryOp(fpscr, -dbl(FpDestP0_uw, FpDestP1_uw),
852 mid, fpAddD, fpscr.fz,
853 fpscr.dn, fpscr.rMode);
854 FpDestP0_uw = dblLow(dest);
855 FpDestP1_uw = dblHi(dest);
858 vnmlsDIop = InstObjParams("vnmlsd", "VnmlsD", "FpRegRegRegOp",
859 { "code": vnmlsDCode,
860 "predicate_test": predicateTest,
861 "op_class": "SimdFloatMultAccOp" }, [])
862 header_output += FpRegRegRegOpDeclare.subst(vnmlsDIop);
863 decoder_output += FpRegRegRegOpConstructor.subst(vnmlsDIop);
864 exec_output += PredOpExecute.subst(vnmlsDIop);
866 vnmulSCode = vfpEnabledCheckCode + '''
867 FPSCR fpscr = (FPSCR) FpscrExc;
868 FpDest = -binaryOp(fpscr, FpOp1, FpOp2, fpMulS,
869 fpscr.fz, fpscr.dn, fpscr.rMode);
872 vnmulSIop = InstObjParams("vnmuls", "VnmulS", "FpRegRegRegOp",
873 { "code": vnmulSCode,
874 "predicate_test": predicateTest,
875 "op_class": "SimdFloatMultOp" }, [])
876 header_output += FpRegRegRegOpDeclare.subst(vnmulSIop);
877 decoder_output += FpRegRegRegOpConstructor.subst(vnmulSIop);
878 exec_output += PredOpExecute.subst(vnmulSIop);
880 vnmulDCode = vfpEnabledCheckCode + '''
881 FPSCR fpscr = (FPSCR) FpscrExc;
882 double dest = -binaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw),
883 dbl(FpOp2P0_uw, FpOp2P1_uw),
884 fpMulD, fpscr.fz, fpscr.dn,
886 FpDestP0_uw = dblLow(dest);
887 FpDestP1_uw = dblHi(dest);
890 vnmulDIop = InstObjParams("vnmuld", "VnmulD", "FpRegRegRegOp",
891 { "code": vnmulDCode,
892 "predicate_test": predicateTest,
893 "op_class": "SimdFloatMultOp" }, [])
894 header_output += FpRegRegRegOpDeclare.subst(vnmulDIop);
895 decoder_output += FpRegRegRegOpConstructor.subst(vnmulDIop);
896 exec_output += PredOpExecute.subst(vnmulDIop);
905 vcvtUIntFpSCode = vfpEnabledCheckCode + '''
906 FPSCR fpscr = (FPSCR) FpscrExc;
907 VfpSavedState state = prepFpState(fpscr.rMode);
908 __asm__ __volatile__("" : "=m" (FpOp1_uw) : "m" (FpOp1_uw));
910 __asm__ __volatile__("" :: "m" (FpDest));
911 finishVfp(fpscr, state, fpscr.fz);
914 vcvtUIntFpSIop = InstObjParams("vcvt", "VcvtUIntFpS", "FpRegRegOp",
915 { "code": vcvtUIntFpSCode,
916 "predicate_test": predicateTest,
917 "op_class": "SimdFloatCvtOp" }, [])
918 header_output += FpRegRegOpDeclare.subst(vcvtUIntFpSIop);
919 decoder_output += FpRegRegOpConstructor.subst(vcvtUIntFpSIop);
920 exec_output += PredOpExecute.subst(vcvtUIntFpSIop);
922 vcvtUIntFpDCode = vfpEnabledCheckCode + '''
923 FPSCR fpscr = (FPSCR) FpscrExc;
924 VfpSavedState state = prepFpState(fpscr.rMode);
925 __asm__ __volatile__("" : "=m" (FpOp1P0_uw) : "m" (FpOp1P0_uw));
926 double cDest = (uint64_t)FpOp1P0_uw;
927 __asm__ __volatile__("" :: "m" (cDest));
928 finishVfp(fpscr, state, fpscr.fz);
929 FpDestP0_uw = dblLow(cDest);
930 FpDestP1_uw = dblHi(cDest);
933 vcvtUIntFpDIop = InstObjParams("vcvt", "VcvtUIntFpD", "FpRegRegOp",
934 { "code": vcvtUIntFpDCode,
935 "predicate_test": predicateTest,
936 "op_class": "SimdFloatCvtOp" }, [])
937 header_output += FpRegRegOpDeclare.subst(vcvtUIntFpDIop);
938 decoder_output += FpRegRegOpConstructor.subst(vcvtUIntFpDIop);
939 exec_output += PredOpExecute.subst(vcvtUIntFpDIop);
941 vcvtSIntFpSCode = vfpEnabledCheckCode + '''
942 FPSCR fpscr = (FPSCR) FpscrExc;
943 VfpSavedState state = prepFpState(fpscr.rMode);
944 __asm__ __volatile__("" : "=m" (FpOp1_sw) : "m" (FpOp1_sw));
946 __asm__ __volatile__("" :: "m" (FpDest));
947 finishVfp(fpscr, state, fpscr.fz);
950 vcvtSIntFpSIop = InstObjParams("vcvt", "VcvtSIntFpS", "FpRegRegOp",
951 { "code": vcvtSIntFpSCode,
952 "predicate_test": predicateTest,
953 "op_class": "SimdFloatCvtOp" }, [])
954 header_output += FpRegRegOpDeclare.subst(vcvtSIntFpSIop);
955 decoder_output += FpRegRegOpConstructor.subst(vcvtSIntFpSIop);
956 exec_output += PredOpExecute.subst(vcvtSIntFpSIop);
958 vcvtSIntFpDCode = vfpEnabledCheckCode + '''
959 FPSCR fpscr = (FPSCR) FpscrExc;
960 VfpSavedState state = prepFpState(fpscr.rMode);
961 __asm__ __volatile__("" : "=m" (FpOp1P0_sw) : "m" (FpOp1P0_sw));
962 double cDest = FpOp1P0_sw;
963 __asm__ __volatile__("" :: "m" (cDest));
964 finishVfp(fpscr, state, fpscr.fz);
965 FpDestP0_uw = dblLow(cDest);
966 FpDestP1_uw = dblHi(cDest);
969 vcvtSIntFpDIop = InstObjParams("vcvt", "VcvtSIntFpD", "FpRegRegOp",
970 { "code": vcvtSIntFpDCode,
971 "predicate_test": predicateTest,
972 "op_class": "SimdFloatCvtOp" }, [])
973 header_output += FpRegRegOpDeclare.subst(vcvtSIntFpDIop);
974 decoder_output += FpRegRegOpConstructor.subst(vcvtSIntFpDIop);
975 exec_output += PredOpExecute.subst(vcvtSIntFpDIop);
977 vjcvtSFixedFpDCode = vfpEnabledCheckCode + '''
978 FPSCR fpscr = (FPSCR) FpscrExc;
979 VfpSavedState state = prepFpState(fpscr.rMode);
980 uint64_t cOp1 = ((uint64_t)FpOp1P0_uw | ((uint64_t)FpOp1P1_uw << 32));
982 FpDest_uw = fplibFPToFixedJS(cOp1, fpscr, false, nz);
983 finishVfp(fpscr, state, fpscr.fz);
984 FpCondCodes = fpscr & FpCondCodesMask;
987 vjcvtSFixedFpDIop = InstObjParams("vjcvt", "VjcvtSFixedFpD", "FpRegRegOp",
988 { "code": vjcvtSFixedFpDCode,
989 "predicate_test": predicateTest,
990 "op_class": "SimdFloatCvtOp" }, [])
991 header_output += FpRegRegOpDeclare.subst(vjcvtSFixedFpDIop);
992 decoder_output += FpRegRegOpConstructor.subst(vjcvtSFixedFpDIop);
993 exec_output += PredOpExecute.subst(vjcvtSFixedFpDIop);
995 vcvtFpUIntSRCode = vfpEnabledCheckCode + '''
996 FPSCR fpscr = (FPSCR) FpscrExc;
997 VfpSavedState state = prepFpState(fpscr.rMode);
998 vfpFlushToZero(fpscr, FpOp1);
999 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1000 FpDest_uw = vfpFpToFixed<float>(FpOp1, false, 32, 0, false);
1001 __asm__ __volatile__("" :: "m" (FpDest_uw));
1002 finishVfp(fpscr, state, fpscr.fz);
1005 vcvtFpUIntSRIop = InstObjParams("vcvt", "VcvtFpUIntSR", "FpRegRegOp",
1006 { "code": vcvtFpUIntSRCode,
1007 "predicate_test": predicateTest,
1008 "op_class": "SimdFloatCvtOp" }, [])
1009 header_output += FpRegRegOpDeclare.subst(vcvtFpUIntSRIop);
1010 decoder_output += FpRegRegOpConstructor.subst(vcvtFpUIntSRIop);
1011 exec_output += PredOpExecute.subst(vcvtFpUIntSRIop);
1013 vcvtFpUIntDRCode = vfpEnabledCheckCode + '''
1014 FPSCR fpscr = (FPSCR) FpscrExc;
1015 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1016 vfpFlushToZero(fpscr, cOp1);
1017 VfpSavedState state = prepFpState(fpscr.rMode);
1018 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1019 uint64_t result = vfpFpToFixed<double>(cOp1, false, 32, 0, false);
1020 __asm__ __volatile__("" :: "m" (result));
1021 finishVfp(fpscr, state, fpscr.fz);
1022 FpDestP0_uw = result;
1025 vcvtFpUIntDRIop = InstObjParams("vcvtr", "VcvtFpUIntDR", "FpRegRegOp",
1026 { "code": vcvtFpUIntDRCode,
1027 "predicate_test": predicateTest,
1028 "op_class": "SimdFloatCvtOp" }, [])
1029 header_output += FpRegRegOpDeclare.subst(vcvtFpUIntDRIop);
1030 decoder_output += FpRegRegOpConstructor.subst(vcvtFpUIntDRIop);
1031 exec_output += PredOpExecute.subst(vcvtFpUIntDRIop);
1033 vcvtFpSIntSRCode = vfpEnabledCheckCode + '''
1034 FPSCR fpscr = (FPSCR) FpscrExc;
1035 VfpSavedState state = prepFpState(fpscr.rMode);
1036 vfpFlushToZero(fpscr, FpOp1);
1037 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1038 FpDest_sw = vfpFpToFixed<float>(FpOp1, true, 32, 0, false);
1039 __asm__ __volatile__("" :: "m" (FpDest_sw));
1040 finishVfp(fpscr, state, fpscr.fz);
1043 vcvtFpSIntSRIop = InstObjParams("vcvtr", "VcvtFpSIntSR", "FpRegRegOp",
1044 { "code": vcvtFpSIntSRCode,
1045 "predicate_test": predicateTest,
1046 "op_class": "SimdFloatCvtOp" }, [])
1047 header_output += FpRegRegOpDeclare.subst(vcvtFpSIntSRIop);
1048 decoder_output += FpRegRegOpConstructor.subst(vcvtFpSIntSRIop);
1049 exec_output += PredOpExecute.subst(vcvtFpSIntSRIop);
1051 vcvtFpSIntDRCode = vfpEnabledCheckCode + '''
1052 FPSCR fpscr = (FPSCR) FpscrExc;
1053 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1054 vfpFlushToZero(fpscr, cOp1);
1055 VfpSavedState state = prepFpState(fpscr.rMode);
1056 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1057 int64_t result = vfpFpToFixed<double>(cOp1, true, 32, 0, false);
1058 __asm__ __volatile__("" :: "m" (result));
1059 finishVfp(fpscr, state, fpscr.fz);
1060 FpDestP0_uw = result;
1063 vcvtFpSIntDRIop = InstObjParams("vcvtr", "VcvtFpSIntDR", "FpRegRegOp",
1064 { "code": vcvtFpSIntDRCode,
1065 "predicate_test": predicateTest,
1066 "op_class": "SimdFloatCvtOp" }, [])
1067 header_output += FpRegRegOpDeclare.subst(vcvtFpSIntDRIop);
1068 decoder_output += FpRegRegOpConstructor.subst(vcvtFpSIntDRIop);
1069 exec_output += PredOpExecute.subst(vcvtFpSIntDRIop);
1071 round_mode_suffix_to_mode = {
1073 'a': 'VfpRoundAway',
1074 'm': 'VfpRoundDown',
1075 'n': 'VfpRoundNearest',
1076 'p': 'VfpRoundUpward',
1079 def buildVcvt(code, className, roundModeSuffix):
1080 global header_output, decoder_output, exec_output, \
1081 vfpEnabledCheckCode, round_mode_suffix_to_mode
1082 full_code = vfpEnabledCheckCode + code.format(
1083 round_mode=round_mode_suffix_to_mode[roundModeSuffix],
1085 iop = InstObjParams(
1086 "vcvt{}".format(roundModeSuffix),
1087 className.format(roundModeSuffix),
1089 { "code": full_code,
1090 "predicate_test": predicateTest,
1091 "op_class": "SimdFloatCvtOp" },
1094 header_output += FpRegRegOpDeclare.subst(iop);
1095 decoder_output += FpRegRegOpConstructor.subst(iop);
1096 exec_output += PredOpExecute.subst(iop);
1099 FPSCR fpscr = (FPSCR) FpscrExc;
1100 vfpFlushToZero(fpscr, FpOp1);
1101 VfpSavedState state = prepFpState(fpscr.rMode);
1102 fesetround(FeRoundZero);
1103 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1104 FpDest_uw = vfpFpToFixed<float>(
1105 FpOp1, false, 32, 0, true, {round_mode});
1106 __asm__ __volatile__("" :: "m" (FpDest_uw));
1107 finishVfp(fpscr, state, fpscr.fz);
1110 for round_mode_suffix in round_mode_suffix_to_mode:
1111 buildVcvt(code, "Vcvt{}FpUIntS", round_mode_suffix)
1114 FPSCR fpscr = (FPSCR) FpscrExc;
1115 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1116 vfpFlushToZero(fpscr, cOp1);
1117 VfpSavedState state = prepFpState(fpscr.rMode);
1118 fesetround(FeRoundZero);
1119 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1120 uint64_t result = vfpFpToFixed<double>(
1121 cOp1, false, 32, 0, true, {round_mode});
1122 __asm__ __volatile__("" :: "m" (result));
1123 finishVfp(fpscr, state, fpscr.fz);
1124 FpDestP0_uw = result;
1127 for round_mode_suffix in round_mode_suffix_to_mode:
1128 buildVcvt(code, "Vcvt{}FpUIntD", round_mode_suffix)
1131 FPSCR fpscr = (FPSCR) FpscrExc;
1132 vfpFlushToZero(fpscr, FpOp1);
1133 VfpSavedState state = prepFpState(fpscr.rMode);
1134 fesetround(FeRoundZero);
1135 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1136 FpDest_sw = vfpFpToFixed<float>(
1137 FpOp1, true, 32, 0, true, {round_mode});
1138 __asm__ __volatile__("" :: "m" (FpDest_sw));
1139 finishVfp(fpscr, state, fpscr.fz);
1142 for round_mode_suffix in round_mode_suffix_to_mode:
1143 buildVcvt(code, "Vcvt{}FpSIntS", round_mode_suffix)
1146 FPSCR fpscr = (FPSCR) FpscrExc;
1147 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1148 vfpFlushToZero(fpscr, cOp1);
1149 VfpSavedState state = prepFpState(fpscr.rMode);
1150 fesetround(FeRoundZero);
1151 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1152 int64_t result = vfpFpToFixed<double>(
1153 cOp1, true, 32, 0, true, {round_mode});
1154 __asm__ __volatile__("" :: "m" (result));
1155 finishVfp(fpscr, state, fpscr.fz);
1156 FpDestP0_uw = result;
1159 for round_mode_suffix in round_mode_suffix_to_mode:
1160 buildVcvt(code, "Vcvt{}FpSIntD", round_mode_suffix)
1162 vcvtFpSFpDCode = vfpEnabledCheckCode + '''
1163 FPSCR fpscr = (FPSCR) FpscrExc;
1164 vfpFlushToZero(fpscr, FpOp1);
1165 VfpSavedState state = prepFpState(fpscr.rMode);
1166 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1167 double cDest = fixFpSFpDDest(FpscrExc, FpOp1);
1168 __asm__ __volatile__("" :: "m" (cDest));
1169 finishVfp(fpscr, state, fpscr.fz);
1170 FpDestP0_uw = dblLow(cDest);
1171 FpDestP1_uw = dblHi(cDest);
1174 vcvtFpSFpDIop = InstObjParams("vcvt", "VcvtFpSFpD", "FpRegRegOp",
1175 { "code": vcvtFpSFpDCode,
1176 "predicate_test": predicateTest,
1177 "op_class": "SimdFloatCvtOp" }, [])
1178 header_output += FpRegRegOpDeclare.subst(vcvtFpSFpDIop);
1179 decoder_output += FpRegRegOpConstructor.subst(vcvtFpSFpDIop);
1180 exec_output += PredOpExecute.subst(vcvtFpSFpDIop);
1182 vcvtFpDFpSCode = vfpEnabledCheckCode + '''
1183 FPSCR fpscr = (FPSCR) FpscrExc;
1184 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1185 vfpFlushToZero(fpscr, cOp1);
1186 VfpSavedState state = prepFpState(fpscr.rMode);
1187 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1188 FpDest = fixFpDFpSDest(FpscrExc, cOp1);
1189 __asm__ __volatile__("" :: "m" (FpDest));
1190 finishVfp(fpscr, state, fpscr.fz);
1193 vcvtFpDFpSIop = InstObjParams("vcvt", "VcvtFpDFpS", "FpRegRegOp",
1194 { "code": vcvtFpDFpSCode,
1195 "predicate_test": predicateTest,
1196 "op_class": "SimdFloatCvtOp" }, [])
1197 header_output += FpRegRegOpDeclare.subst(vcvtFpDFpSIop);
1198 decoder_output += FpRegRegOpConstructor.subst(vcvtFpDFpSIop);
1199 exec_output += PredOpExecute.subst(vcvtFpDFpSIop);
1201 vcvtFpHTFpSCode = vfpEnabledCheckCode + '''
1202 FPSCR fpscr = (FPSCR) FpscrExc;
1203 vfpFlushToZero(fpscr, FpOp1);
1204 VfpSavedState state = prepFpState(fpscr.rMode);
1205 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1206 FpDest = vcvtFpHFpS(fpscr, fpscr.dn, fpscr.ahp,
1207 bits(fpToBits(FpOp1), 31, 16));
1208 __asm__ __volatile__("" :: "m" (FpDest));
1209 finishVfp(fpscr, state, fpscr.fz);
1212 vcvtFpHTFpSIop = InstObjParams("vcvtt", "VcvtFpHTFpS", "FpRegRegOp",
1213 { "code": vcvtFpHTFpSCode,
1214 "predicate_test": predicateTest,
1215 "op_class": "SimdFloatCvtOp" }, [])
1216 header_output += FpRegRegOpDeclare.subst(vcvtFpHTFpSIop);
1217 decoder_output += FpRegRegOpConstructor.subst(vcvtFpHTFpSIop);
1218 exec_output += PredOpExecute.subst(vcvtFpHTFpSIop);
1220 vcvtFpHBFpSCode = vfpEnabledCheckCode + '''
1221 FPSCR fpscr = (FPSCR) FpscrExc;
1222 VfpSavedState state = prepFpState(fpscr.rMode);
1223 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1224 FpDest = vcvtFpHFpS(fpscr, fpscr.dn, fpscr.ahp,
1225 bits(fpToBits(FpOp1), 15, 0));
1226 __asm__ __volatile__("" :: "m" (FpDest));
1227 finishVfp(fpscr, state, fpscr.fz);
1230 vcvtFpHBFpSIop = InstObjParams("vcvtb", "VcvtFpHBFpS", "FpRegRegOp",
1231 { "code": vcvtFpHBFpSCode,
1232 "predicate_test": predicateTest,
1233 "op_class": "SimdFloatCvtOp" }, [])
1234 header_output += FpRegRegOpDeclare.subst(vcvtFpHBFpSIop);
1235 decoder_output += FpRegRegOpConstructor.subst(vcvtFpHBFpSIop);
1236 exec_output += PredOpExecute.subst(vcvtFpHBFpSIop);
1238 vcvtFpSFpHTCode = vfpEnabledCheckCode + '''
1239 FPSCR fpscr = (FPSCR) FpscrExc;
1240 vfpFlushToZero(fpscr, FpOp1);
1241 VfpSavedState state = prepFpState(fpscr.rMode);
1242 __asm__ __volatile__("" : "=m" (FpOp1), "=m" (FpDest_uw)
1243 : "m" (FpOp1), "m" (FpDest_uw));
1244 FpDest_uw = insertBits(FpDest_uw, 31, 16,,
1245 vcvtFpSFpH(fpscr, fpscr.fz, fpscr.dn,
1246 fpscr.rMode, fpscr.ahp, FpOp1));
1247 __asm__ __volatile__("" :: "m" (FpDest_uw));
1248 finishVfp(fpscr, state, fpscr.fz);
1251 vcvtFpSFpHTIop = InstObjParams("vcvtt", "VcvtFpSFpHT", "FpRegRegOp",
1252 { "code": vcvtFpHTFpSCode,
1253 "predicate_test": predicateTest,
1254 "op_class": "SimdFloatCvtOp" }, [])
1255 header_output += FpRegRegOpDeclare.subst(vcvtFpSFpHTIop);
1256 decoder_output += FpRegRegOpConstructor.subst(vcvtFpSFpHTIop);
1257 exec_output += PredOpExecute.subst(vcvtFpSFpHTIop);
1259 vcvtFpSFpHBCode = vfpEnabledCheckCode + '''
1260 FPSCR fpscr = (FPSCR) FpscrExc;
1261 vfpFlushToZero(fpscr, FpOp1);
1262 VfpSavedState state = prepFpState(fpscr.rMode);
1263 __asm__ __volatile__("" : "=m" (FpOp1), "=m" (FpDest_uw)
1264 : "m" (FpOp1), "m" (FpDest_uw));
1265 FpDest_uw = insertBits(FpDest_uw, 15, 0,
1266 vcvtFpSFpH(fpscr, fpscr.fz, fpscr.dn,
1267 fpscr.rMode, fpscr.ahp, FpOp1));
1268 __asm__ __volatile__("" :: "m" (FpDest_uw));
1269 finishVfp(fpscr, state, fpscr.fz);
1272 vcvtFpSFpHBIop = InstObjParams("vcvtb", "VcvtFpSFpHB", "FpRegRegOp",
1273 { "code": vcvtFpSFpHBCode,
1274 "predicate_test": predicateTest,
1275 "op_class": "SimdFloatCvtOp" }, [])
1276 header_output += FpRegRegOpDeclare.subst(vcvtFpSFpHBIop);
1277 decoder_output += FpRegRegOpConstructor.subst(vcvtFpSFpHBIop);
1278 exec_output += PredOpExecute.subst(vcvtFpSFpHBIop);
1280 vcmpSCode = vfpEnabledCheckCode + '''
1281 FPSCR fpscr = (FPSCR) FpscrExc;
1282 vfpFlushToZero(fpscr, FpDest, FpOp1);
1283 if (FpDest == FpOp1) {
1284 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1285 } else if (FpDest < FpOp1) {
1286 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1287 } else if (FpDest > FpOp1) {
1288 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1290 const uint32_t qnan = 0x7fc00000;
1291 const bool nan1 = std::isnan(FpDest);
1292 const bool signal1 = nan1 && ((fpToBits(FpDest) & qnan) != qnan);
1293 const bool nan2 = std::isnan(FpOp1);
1294 const bool signal2 = nan2 && ((fpToBits(FpOp1) & qnan) != qnan);
1295 if (signal1 || signal2)
1297 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1299 FpCondCodes = fpscr & FpCondCodesMask;
1302 vcmpSIop = InstObjParams("vcmps", "VcmpS", "FpRegRegOp",
1303 { "code": vcmpSCode,
1304 "predicate_test": predicateTest,
1305 "op_class": "SimdFloatCmpOp" }, [])
1306 header_output += FpRegRegOpDeclare.subst(vcmpSIop);
1307 decoder_output += FpRegRegOpConstructor.subst(vcmpSIop);
1308 exec_output += PredOpExecute.subst(vcmpSIop);
1310 vcmpDCode = vfpEnabledCheckCode + '''
1311 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1312 double cDest = dbl(FpDestP0_uw, FpDestP1_uw);
1313 FPSCR fpscr = (FPSCR) FpscrExc;
1314 vfpFlushToZero(fpscr, cDest, cOp1);
1315 if (cDest == cOp1) {
1316 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1317 } else if (cDest < cOp1) {
1318 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1319 } else if (cDest > cOp1) {
1320 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1322 const uint64_t qnan = ULL(0x7ff8000000000000);
1323 const bool nan1 = std::isnan(cDest);
1324 const bool signal1 = nan1 && ((fpToBits(cDest) & qnan) != qnan);
1325 const bool nan2 = std::isnan(cOp1);
1326 const bool signal2 = nan2 && ((fpToBits(cOp1) & qnan) != qnan);
1327 if (signal1 || signal2)
1329 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1331 FpCondCodes = fpscr & FpCondCodesMask;
1334 vcmpDIop = InstObjParams("vcmpd", "VcmpD", "FpRegRegOp",
1335 { "code": vcmpDCode,
1336 "predicate_test": predicateTest,
1337 "op_class": "SimdFloatCmpOp" }, [])
1338 header_output += FpRegRegOpDeclare.subst(vcmpDIop);
1339 decoder_output += FpRegRegOpConstructor.subst(vcmpDIop);
1340 exec_output += PredOpExecute.subst(vcmpDIop);
1342 vcmpZeroSCode = vfpEnabledCheckCode + '''
1343 FPSCR fpscr = (FPSCR) FpscrExc;
1344 vfpFlushToZero(fpscr, FpDest);
1345 // This only handles imm == 0 for now.
1347 if (FpDest == imm) {
1348 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1349 } else if (FpDest < imm) {
1350 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1351 } else if (FpDest > imm) {
1352 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1354 const uint32_t qnan = 0x7fc00000;
1355 const bool nan = std::isnan(FpDest);
1356 const bool signal = nan && ((fpToBits(FpDest) & qnan) != qnan);
1359 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1361 FpCondCodes = fpscr & FpCondCodesMask;
1364 vcmpZeroSIop = InstObjParams("vcmpZeros", "VcmpZeroS", "FpRegImmOp",
1365 { "code": vcmpZeroSCode,
1366 "predicate_test": predicateTest,
1367 "op_class": "SimdFloatCmpOp" }, [])
1368 header_output += FpRegImmOpDeclare.subst(vcmpZeroSIop);
1369 decoder_output += FpRegImmOpConstructor.subst(vcmpZeroSIop);
1370 exec_output += PredOpExecute.subst(vcmpZeroSIop);
1372 vcmpZeroDCode = vfpEnabledCheckCode + '''
1373 // This only handles imm == 0 for now.
1375 double cDest = dbl(FpDestP0_uw, FpDestP1_uw);
1376 FPSCR fpscr = (FPSCR) FpscrExc;
1377 vfpFlushToZero(fpscr, cDest);
1379 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1380 } else if (cDest < imm) {
1381 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1382 } else if (cDest > imm) {
1383 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1385 const uint64_t qnan = ULL(0x7ff8000000000000);
1386 const bool nan = std::isnan(cDest);
1387 const bool signal = nan && ((fpToBits(cDest) & qnan) != qnan);
1390 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1392 FpCondCodes = fpscr & FpCondCodesMask;
1395 vcmpZeroDIop = InstObjParams("vcmpZerod", "VcmpZeroD", "FpRegImmOp",
1396 { "code": vcmpZeroDCode,
1397 "predicate_test": predicateTest,
1398 "op_class": "SimdFloatCmpOp" }, [])
1399 header_output += FpRegImmOpDeclare.subst(vcmpZeroDIop);
1400 decoder_output += FpRegImmOpConstructor.subst(vcmpZeroDIop);
1401 exec_output += PredOpExecute.subst(vcmpZeroDIop);
1403 vcmpeSCode = vfpEnabledCheckCode + '''
1404 FPSCR fpscr = (FPSCR) FpscrExc;
1405 vfpFlushToZero(fpscr, FpDest, FpOp1);
1406 if (FpDest == FpOp1) {
1407 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1408 } else if (FpDest < FpOp1) {
1409 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1410 } else if (FpDest > FpOp1) {
1411 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1414 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1416 FpCondCodes = fpscr & FpCondCodesMask;
1419 vcmpeSIop = InstObjParams("vcmpes", "VcmpeS", "FpRegRegOp",
1420 { "code": vcmpeSCode,
1421 "predicate_test": predicateTest,
1422 "op_class": "SimdFloatCmpOp" }, [])
1423 header_output += FpRegRegOpDeclare.subst(vcmpeSIop);
1424 decoder_output += FpRegRegOpConstructor.subst(vcmpeSIop);
1425 exec_output += PredOpExecute.subst(vcmpeSIop);
1427 vcmpeDCode = vfpEnabledCheckCode + '''
1428 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1429 double cDest = dbl(FpDestP0_uw, FpDestP1_uw);
1430 FPSCR fpscr = (FPSCR) FpscrExc;
1431 vfpFlushToZero(fpscr, cDest, cOp1);
1432 if (cDest == cOp1) {
1433 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1434 } else if (cDest < cOp1) {
1435 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1436 } else if (cDest > cOp1) {
1437 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1440 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1442 FpCondCodes = fpscr & FpCondCodesMask;
1445 vcmpeDIop = InstObjParams("vcmped", "VcmpeD", "FpRegRegOp",
1446 { "code": vcmpeDCode,
1447 "predicate_test": predicateTest,
1448 "op_class": "SimdFloatCmpOp" }, [])
1449 header_output += FpRegRegOpDeclare.subst(vcmpeDIop);
1450 decoder_output += FpRegRegOpConstructor.subst(vcmpeDIop);
1451 exec_output += PredOpExecute.subst(vcmpeDIop);
1453 vcmpeZeroSCode = vfpEnabledCheckCode + '''
1454 FPSCR fpscr = (FPSCR) FpscrExc;
1455 vfpFlushToZero(fpscr, FpDest);
1456 if (FpDest == imm) {
1457 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1458 } else if (FpDest < imm) {
1459 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1460 } else if (FpDest > imm) {
1461 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1464 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1466 FpCondCodes = fpscr & FpCondCodesMask;
1469 vcmpeZeroSIop = InstObjParams("vcmpeZeros", "VcmpeZeroS", "FpRegImmOp",
1470 { "code": vcmpeZeroSCode,
1471 "predicate_test": predicateTest,
1472 "op_class": "SimdFloatCmpOp" }, [])
1473 header_output += FpRegImmOpDeclare.subst(vcmpeZeroSIop);
1474 decoder_output += FpRegImmOpConstructor.subst(vcmpeZeroSIop);
1475 exec_output += PredOpExecute.subst(vcmpeZeroSIop);
1477 vcmpeZeroDCode = vfpEnabledCheckCode + '''
1478 double cDest = dbl(FpDestP0_uw, FpDestP1_uw);
1479 FPSCR fpscr = (FPSCR) FpscrExc;
1480 vfpFlushToZero(fpscr, cDest);
1482 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1483 } else if (cDest < imm) {
1484 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1485 } else if (cDest > imm) {
1486 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1489 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1491 FpCondCodes = fpscr & FpCondCodesMask;
1494 vcmpeZeroDIop = InstObjParams("vcmpeZerod", "VcmpeZeroD", "FpRegImmOp",
1495 { "code": vcmpeZeroDCode,
1496 "predicate_test": predicateTest,
1497 "op_class": "SimdFloatCmpOp" }, [])
1498 header_output += FpRegImmOpDeclare.subst(vcmpeZeroDIop);
1499 decoder_output += FpRegImmOpConstructor.subst(vcmpeZeroDIop);
1500 exec_output += PredOpExecute.subst(vcmpeZeroDIop);
1509 vselSCode = vfpEnabledCheckCode + '''
1510 if (testPredicate(CondCodesNZ, CondCodesC, CondCodesV, cond)) {
1516 vselSIop = InstObjParams("vsels", "VselS", "FpRegRegRegCondOp",
1517 { "code" : vselSCode,
1518 "predicate_test" : predicateTest,
1519 "op_class" : "SimdFloatCmpOp" }, [] )
1520 header_output += FpRegRegRegCondOpDeclare.subst(vselSIop);
1521 decoder_output += FpRegRegRegCondOpConstructor.subst(vselSIop);
1522 exec_output += PredOpExecute.subst(vselSIop);
1524 vselDCode = vfpEnabledCheckCode + '''
1525 if (testPredicate(CondCodesNZ, CondCodesC, CondCodesV, cond)) {
1526 FpDestP0_uw = FpOp1P0_uw;
1527 FpDestP1_uw = FpOp1P1_uw;
1529 FpDestP0_uw = FpOp2P0_uw;
1530 FpDestP1_uw = FpOp2P1_uw;
1533 vselDIop = InstObjParams("vseld", "VselD", "FpRegRegRegCondOp",
1534 { "code" : vselDCode,
1535 "predicate_test" : predicateTest,
1536 "op_class" : "SimdFloatCmpOp" }, [] )
1537 header_output += FpRegRegRegCondOpDeclare.subst(vselDIop);
1538 decoder_output += FpRegRegRegCondOpConstructor.subst(vselDIop);
1539 exec_output += PredOpExecute.subst(vselDIop);
1549 vcvtFpSFixedSCode = vfpEnabledCheckCode + '''
1550 FPSCR fpscr = (FPSCR) FpscrExc;
1551 vfpFlushToZero(fpscr, FpOp1);
1552 VfpSavedState state = prepFpState(fpscr.rMode);
1553 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1554 FpDest_sw = vfpFpToFixed<float>(FpOp1, true, 32, imm);
1555 __asm__ __volatile__("" :: "m" (FpDest_sw));
1556 finishVfp(fpscr, state, fpscr.fz);
1559 vcvtFpSFixedSIop = InstObjParams("vcvt", "VcvtFpSFixedS", "FpRegRegImmOp",
1560 { "code": vcvtFpSFixedSCode,
1561 "predicate_test": predicateTest,
1562 "op_class": "SimdFloatCvtOp" }, [])
1563 header_output += FpRegRegImmOpDeclare.subst(vcvtFpSFixedSIop);
1564 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSFixedSIop);
1565 exec_output += PredOpExecute.subst(vcvtFpSFixedSIop);
1567 vcvtFpSFixedDCode = vfpEnabledCheckCode + '''
1568 FPSCR fpscr = (FPSCR) FpscrExc;
1569 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1570 vfpFlushToZero(fpscr, cOp1);
1571 VfpSavedState state = prepFpState(fpscr.rMode);
1572 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1573 uint64_t mid = vfpFpToFixed<double>(cOp1, true, 32, imm);
1574 __asm__ __volatile__("" :: "m" (mid));
1575 finishVfp(fpscr, state, fpscr.fz);
1577 FpDestP1_uw = mid >> 32;
1580 vcvtFpSFixedDIop = InstObjParams("vcvt", "VcvtFpSFixedD", "FpRegRegImmOp",
1581 { "code": vcvtFpSFixedDCode,
1582 "predicate_test": predicateTest,
1583 "op_class": "SimdFloatCvtOp" }, [])
1584 header_output += FpRegRegImmOpDeclare.subst(vcvtFpSFixedDIop);
1585 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSFixedDIop);
1586 exec_output += PredOpExecute.subst(vcvtFpSFixedDIop);
1588 vcvtFpUFixedSCode = vfpEnabledCheckCode + '''
1589 FPSCR fpscr = (FPSCR) FpscrExc;
1590 vfpFlushToZero(fpscr, FpOp1);
1591 VfpSavedState state = prepFpState(fpscr.rMode);
1592 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1593 FpDest_uw = vfpFpToFixed<float>(FpOp1, false, 32, imm);
1594 __asm__ __volatile__("" :: "m" (FpDest_uw));
1595 finishVfp(fpscr, state, fpscr.fz);
1598 vcvtFpUFixedSIop = InstObjParams("vcvt", "VcvtFpUFixedS", "FpRegRegImmOp",
1599 { "code": vcvtFpUFixedSCode,
1600 "predicate_test": predicateTest,
1601 "op_class": "SimdFloatCvtOp" }, [])
1602 header_output += FpRegRegImmOpDeclare.subst(vcvtFpUFixedSIop);
1603 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUFixedSIop);
1604 exec_output += PredOpExecute.subst(vcvtFpUFixedSIop);
1606 vcvtFpUFixedDCode = vfpEnabledCheckCode + '''
1607 FPSCR fpscr = (FPSCR) FpscrExc;
1608 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1609 vfpFlushToZero(fpscr, cOp1);
1610 VfpSavedState state = prepFpState(fpscr.rMode);
1611 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1612 uint64_t mid = vfpFpToFixed<double>(cOp1, false, 32, imm);
1613 __asm__ __volatile__("" :: "m" (mid));
1614 finishVfp(fpscr, state, fpscr.fz);
1616 FpDestP1_uw = mid >> 32;
1619 vcvtFpUFixedDIop = InstObjParams("vcvt", "VcvtFpUFixedD", "FpRegRegImmOp",
1620 { "code": vcvtFpUFixedDCode,
1621 "predicate_test": predicateTest,
1622 "op_class": "SimdFloatCvtOp" }, [])
1623 header_output += FpRegRegImmOpDeclare.subst(vcvtFpUFixedDIop);
1624 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUFixedDIop);
1625 exec_output += PredOpExecute.subst(vcvtFpUFixedDIop);
1627 vcvtSFixedFpSCode = vfpEnabledCheckCode + '''
1628 FPSCR fpscr = (FPSCR) FpscrExc;
1629 VfpSavedState state = prepFpState(fpscr.rMode);
1630 __asm__ __volatile__("" : "=m" (FpOp1_sw) : "m" (FpOp1_sw));
1631 FpDest = vfpSFixedToFpS(fpscr.fz, fpscr.dn, FpOp1_sw, 32, imm);
1632 __asm__ __volatile__("" :: "m" (FpDest));
1633 finishVfp(fpscr, state, fpscr.fz);
1636 vcvtSFixedFpSIop = InstObjParams("vcvt", "VcvtSFixedFpS", "FpRegRegImmOp",
1637 { "code": vcvtSFixedFpSCode,
1638 "predicate_test": predicateTest,
1639 "op_class": "SimdFloatCvtOp" }, [])
1640 header_output += FpRegRegImmOpDeclare.subst(vcvtSFixedFpSIop);
1641 decoder_output += FpRegRegImmOpConstructor.subst(vcvtSFixedFpSIop);
1642 exec_output += PredOpExecute.subst(vcvtSFixedFpSIop);
1644 vcvtSFixedFpDCode = vfpEnabledCheckCode + '''
1645 FPSCR fpscr = (FPSCR) FpscrExc;
1646 uint64_t mid = ((uint64_t)FpOp1P0_uw | ((uint64_t)FpOp1P1_uw << 32));
1647 VfpSavedState state = prepFpState(fpscr.rMode);
1648 __asm__ __volatile__("" : "=m" (mid) : "m" (mid));
1649 double cDest = vfpSFixedToFpD(fpscr.fz, fpscr.dn, mid, 32, imm);
1650 __asm__ __volatile__("" :: "m" (cDest));
1651 finishVfp(fpscr, state, fpscr.fz);
1652 FpDestP0_uw = dblLow(cDest);
1653 FpDestP1_uw = dblHi(cDest);
1656 vcvtSFixedFpDIop = InstObjParams("vcvt", "VcvtSFixedFpD", "FpRegRegImmOp",
1657 { "code": vcvtSFixedFpDCode,
1658 "predicate_test": predicateTest,
1659 "op_class": "SimdFloatCvtOp" }, [])
1660 header_output += FpRegRegImmOpDeclare.subst(vcvtSFixedFpDIop);
1661 decoder_output += FpRegRegImmOpConstructor.subst(vcvtSFixedFpDIop);
1662 exec_output += PredOpExecute.subst(vcvtSFixedFpDIop);
1664 vcvtUFixedFpSCode = vfpEnabledCheckCode + '''
1665 FPSCR fpscr = (FPSCR) FpscrExc;
1666 VfpSavedState state = prepFpState(fpscr.rMode);
1667 __asm__ __volatile__("" : "=m" (FpOp1_uw) : "m" (FpOp1_uw));
1668 FpDest = vfpUFixedToFpS(fpscr.fz, fpscr.dn, FpOp1_uw, 32, imm);
1669 __asm__ __volatile__("" :: "m" (FpDest));
1670 finishVfp(fpscr, state, fpscr.fz);
1673 vcvtUFixedFpSIop = InstObjParams("vcvt", "VcvtUFixedFpS", "FpRegRegImmOp",
1674 { "code": vcvtUFixedFpSCode,
1675 "predicate_test": predicateTest,
1676 "op_class": "SimdFloatCvtOp" }, [])
1677 header_output += FpRegRegImmOpDeclare.subst(vcvtUFixedFpSIop);
1678 decoder_output += FpRegRegImmOpConstructor.subst(vcvtUFixedFpSIop);
1679 exec_output += PredOpExecute.subst(vcvtUFixedFpSIop);
1681 vcvtUFixedFpDCode = vfpEnabledCheckCode + '''
1682 FPSCR fpscr = (FPSCR) FpscrExc;
1683 uint64_t mid = ((uint64_t)FpOp1P0_uw | ((uint64_t)FpOp1P1_uw << 32));
1684 VfpSavedState state = prepFpState(fpscr.rMode);
1685 __asm__ __volatile__("" : "=m" (mid) : "m" (mid));
1686 double cDest = vfpUFixedToFpD(fpscr.fz, fpscr.dn, mid, 32, imm);
1687 __asm__ __volatile__("" :: "m" (cDest));
1688 finishVfp(fpscr, state, fpscr.fz);
1689 FpDestP0_uw = dblLow(cDest);
1690 FpDestP1_uw = dblHi(cDest);
1693 vcvtUFixedFpDIop = InstObjParams("vcvt", "VcvtUFixedFpD", "FpRegRegImmOp",
1694 { "code": vcvtUFixedFpDCode,
1695 "predicate_test": predicateTest,
1696 "op_class": "SimdFloatCvtOp" }, [])
1697 header_output += FpRegRegImmOpDeclare.subst(vcvtUFixedFpDIop);
1698 decoder_output += FpRegRegImmOpConstructor.subst(vcvtUFixedFpDIop);
1699 exec_output += PredOpExecute.subst(vcvtUFixedFpDIop);
1701 vcvtFpSHFixedSCode = vfpEnabledCheckCode + '''
1702 FPSCR fpscr = (FPSCR) FpscrExc;
1703 vfpFlushToZero(fpscr, FpOp1);
1704 VfpSavedState state = prepFpState(fpscr.rMode);
1705 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1706 FpDest_sh = vfpFpToFixed<float>(FpOp1, true, 16, imm);
1707 __asm__ __volatile__("" :: "m" (FpDest_sh));
1708 finishVfp(fpscr, state, fpscr.fz);
1711 vcvtFpSHFixedSIop = InstObjParams("vcvt", "VcvtFpSHFixedS",
1713 { "code": vcvtFpSHFixedSCode,
1714 "predicate_test": predicateTest,
1715 "op_class": "SimdFloatCvtOp" }, [])
1716 header_output += FpRegRegImmOpDeclare.subst(vcvtFpSHFixedSIop);
1717 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSHFixedSIop);
1718 exec_output += PredOpExecute.subst(vcvtFpSHFixedSIop);
1720 vcvtFpSHFixedDCode = vfpEnabledCheckCode + '''
1721 FPSCR fpscr = (FPSCR) FpscrExc;
1722 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1723 vfpFlushToZero(fpscr, cOp1);
1724 VfpSavedState state = prepFpState(fpscr.rMode);
1725 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1726 uint64_t result = vfpFpToFixed<double>(cOp1, true, 16, imm);
1727 __asm__ __volatile__("" :: "m" (result));
1728 finishVfp(fpscr, state, fpscr.fz);
1729 FpDestP0_uw = result;
1730 FpDestP1_uw = result >> 32;
1733 vcvtFpSHFixedDIop = InstObjParams("vcvt", "VcvtFpSHFixedD",
1735 { "code": vcvtFpSHFixedDCode,
1736 "predicate_test": predicateTest,
1737 "op_class": "SimdFloatCvtOp" }, [])
1738 header_output += FpRegRegImmOpDeclare.subst(vcvtFpSHFixedDIop);
1739 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSHFixedDIop);
1740 exec_output += PredOpExecute.subst(vcvtFpSHFixedDIop);
1742 vcvtFpUHFixedSCode = vfpEnabledCheckCode + '''
1743 FPSCR fpscr = (FPSCR) FpscrExc;
1744 vfpFlushToZero(fpscr, FpOp1);
1745 VfpSavedState state = prepFpState(fpscr.rMode);
1746 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1747 FpDest_uh = vfpFpToFixed<float>(FpOp1, false, 16, imm);
1748 __asm__ __volatile__("" :: "m" (FpDest_uh));
1749 finishVfp(fpscr, state, fpscr.fz);
1752 vcvtFpUHFixedSIop = InstObjParams("vcvt", "VcvtFpUHFixedS",
1754 { "code": vcvtFpUHFixedSCode,
1755 "predicate_test": predicateTest,
1756 "op_class": "SimdFloatCvtOp" }, [])
1757 header_output += FpRegRegImmOpDeclare.subst(vcvtFpUHFixedSIop);
1758 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUHFixedSIop);
1759 exec_output += PredOpExecute.subst(vcvtFpUHFixedSIop);
1761 vcvtFpUHFixedDCode = vfpEnabledCheckCode + '''
1762 FPSCR fpscr = (FPSCR) FpscrExc;
1763 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1764 vfpFlushToZero(fpscr, cOp1);
1765 VfpSavedState state = prepFpState(fpscr.rMode);
1766 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1767 uint64_t mid = vfpFpToFixed<double>(cOp1, false, 16, imm);
1768 __asm__ __volatile__("" :: "m" (mid));
1769 finishVfp(fpscr, state, fpscr.fz);
1771 FpDestP1_uw = mid >> 32;
1774 vcvtFpUHFixedDIop = InstObjParams("vcvt", "VcvtFpUHFixedD",
1776 { "code": vcvtFpUHFixedDCode,
1777 "predicate_test": predicateTest,
1778 "op_class": "SimdFloatCvtOp" }, [])
1779 header_output += FpRegRegImmOpDeclare.subst(vcvtFpUHFixedDIop);
1780 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUHFixedDIop);
1781 exec_output += PredOpExecute.subst(vcvtFpUHFixedDIop);
1783 vcvtSHFixedFpSCode = vfpEnabledCheckCode + '''
1784 FPSCR fpscr = (FPSCR) FpscrExc;
1785 VfpSavedState state = prepFpState(fpscr.rMode);
1786 __asm__ __volatile__("" : "=m" (FpOp1_sh) : "m" (FpOp1_sh));
1787 FpDest = vfpSFixedToFpS(fpscr.fz, fpscr.dn, FpOp1_sh, 16, imm);
1788 __asm__ __volatile__("" :: "m" (FpDest));
1789 finishVfp(fpscr, state, fpscr.fz);
1792 vcvtSHFixedFpSIop = InstObjParams("vcvt", "VcvtSHFixedFpS",
1794 { "code": vcvtSHFixedFpSCode,
1795 "predicate_test": predicateTest,
1796 "op_class": "SimdFloatCvtOp" }, [])
1797 header_output += FpRegRegImmOpDeclare.subst(vcvtSHFixedFpSIop);
1798 decoder_output += FpRegRegImmOpConstructor.subst(vcvtSHFixedFpSIop);
1799 exec_output += PredOpExecute.subst(vcvtSHFixedFpSIop);
1801 vcvtSHFixedFpDCode = vfpEnabledCheckCode + '''
1802 FPSCR fpscr = (FPSCR) FpscrExc;
1803 uint64_t mid = ((uint64_t)FpOp1P0_uw | ((uint64_t)FpOp1P1_uw << 32));
1804 VfpSavedState state = prepFpState(fpscr.rMode);
1805 __asm__ __volatile__("" : "=m" (mid) : "m" (mid));
1806 double cDest = vfpSFixedToFpD(fpscr.fz, fpscr.dn, mid, 16, imm);
1807 __asm__ __volatile__("" :: "m" (cDest));
1808 finishVfp(fpscr, state, fpscr.fz);
1809 FpDestP0_uw = dblLow(cDest);
1810 FpDestP1_uw = dblHi(cDest);
1813 vcvtSHFixedFpDIop = InstObjParams("vcvt", "VcvtSHFixedFpD",
1815 { "code": vcvtSHFixedFpDCode,
1816 "predicate_test": predicateTest,
1817 "op_class": "SimdFloatCvtOp" }, [])
1818 header_output += FpRegRegImmOpDeclare.subst(vcvtSHFixedFpDIop);
1819 decoder_output += FpRegRegImmOpConstructor.subst(vcvtSHFixedFpDIop);
1820 exec_output += PredOpExecute.subst(vcvtSHFixedFpDIop);
1822 vcvtUHFixedFpSCode = vfpEnabledCheckCode + '''
1823 FPSCR fpscr = (FPSCR) FpscrExc;
1824 VfpSavedState state = prepFpState(fpscr.rMode);
1825 __asm__ __volatile__("" : "=m" (FpOp1_uh) : "m" (FpOp1_uh));
1826 FpDest = vfpUFixedToFpS(fpscr.fz, fpscr.dn, FpOp1_uh, 16, imm);
1827 __asm__ __volatile__("" :: "m" (FpDest));
1828 finishVfp(fpscr, state, fpscr.fz);
1831 vcvtUHFixedFpSIop = InstObjParams("vcvt", "VcvtUHFixedFpS",
1833 { "code": vcvtUHFixedFpSCode,
1834 "predicate_test": predicateTest,
1835 "op_class": "SimdFloatCvtOp" }, [])
1836 header_output += FpRegRegImmOpDeclare.subst(vcvtUHFixedFpSIop);
1837 decoder_output += FpRegRegImmOpConstructor.subst(vcvtUHFixedFpSIop);
1838 exec_output += PredOpExecute.subst(vcvtUHFixedFpSIop);
1840 vcvtUHFixedFpDCode = vfpEnabledCheckCode + '''
1841 FPSCR fpscr = (FPSCR) FpscrExc;
1842 uint64_t mid = ((uint64_t)FpOp1P0_uw | ((uint64_t)FpOp1P1_uw << 32));
1843 VfpSavedState state = prepFpState(fpscr.rMode);
1844 __asm__ __volatile__("" : "=m" (mid) : "m" (mid));
1845 double cDest = vfpUFixedToFpD(fpscr.fz, fpscr.dn, mid, 16, imm);
1846 __asm__ __volatile__("" :: "m" (cDest));
1847 finishVfp(fpscr, state, fpscr.fz);
1848 FpDestP0_uw = dblLow(cDest);
1849 FpDestP1_uw = dblHi(cDest);
1852 vcvtUHFixedFpDIop = InstObjParams("vcvt", "VcvtUHFixedFpD",
1854 { "code": vcvtUHFixedFpDCode,
1855 "predicate_test": predicateTest,
1856 "op_class": "SimdFloatCvtOp" }, [])
1857 header_output += FpRegRegImmOpDeclare.subst(vcvtUHFixedFpDIop);
1858 decoder_output += FpRegRegImmOpConstructor.subst(vcvtUHFixedFpDIop);
1859 exec_output += PredOpExecute.subst(vcvtUHFixedFpDIop);