arch-arm: Implementing SecureEL2 feature for Armv8
[gem5.git] / src / arch / arm / isa / insts / fp.isa
1 // -*- mode:c++ -*-
2
3 // Copyright (c) 2010-2013,2016,2018-2019 ARM Limited
4 // All rights reserved
5 //
6 // The license below extends only to copyright in the software and shall
7 // not be construed as granting a license to any other intellectual
8 // property including but not limited to intellectual property relating
9 // to a hardware implementation of the functionality of the software
10 // licensed hereunder. You may use the software subject to the license
11 // terms below provided that you ensure that this notice is replicated
12 // unmodified and in its entirety in all distributions of the software,
13 // modified or unmodified, in source code or in binary form.
14 //
15 // Redistribution and use in source and binary forms, with or without
16 // modification, are permitted provided that the following conditions are
17 // met: redistributions of source code must retain the above copyright
18 // notice, this list of conditions and the following disclaimer;
19 // redistributions in binary form must reproduce the above copyright
20 // notice, this list of conditions and the following disclaimer in the
21 // documentation and/or other materials provided with the distribution;
22 // neither the name of the copyright holders nor the names of its
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37
38 output header {{
39
40 template <class Micro>
41 class VfpMacroRegRegOp : public VfpMacroOp
42 {
43 public:
44 VfpMacroRegRegOp(ExtMachInst _machInst, IntRegIndex _dest,
45 IntRegIndex _op1, bool _wide) :
46 VfpMacroOp("VfpMacroRegRegOp", _machInst, No_OpClass, _wide)
47 {
48 numMicroops = machInst.fpscrLen + 1;
49 assert(numMicroops > 1);
50 microOps = new StaticInstPtr[numMicroops];
51 for (unsigned i = 0; i < numMicroops; i++) {
52 VfpMicroMode mode = VfpMicroop;
53 if (i == 0)
54 mode = VfpFirstMicroop;
55 else if (i == numMicroops - 1)
56 mode = VfpLastMicroop;
57 microOps[i] = new Micro(_machInst, _dest, _op1, mode);
58 nextIdxs(_dest, _op1);
59 }
60 }
61 };
62
63 template <class VfpOp>
64 StaticInstPtr
65 decodeVfpRegRegOp(ExtMachInst machInst,
66 IntRegIndex dest, IntRegIndex op1, bool wide)
67 {
68 if (machInst.fpscrLen == 0 || VfpMacroOp::inScalarBank(dest)) {
69 return new VfpOp(machInst, dest, op1);
70 } else {
71 return new VfpMacroRegRegOp<VfpOp>(machInst, dest, op1, wide);
72 }
73 }
74
75 template <class Micro>
76 class VfpMacroRegImmOp : public VfpMacroOp
77 {
78 public:
79 VfpMacroRegImmOp(ExtMachInst _machInst, IntRegIndex _dest, uint64_t _imm,
80 bool _wide) :
81 VfpMacroOp("VfpMacroRegImmOp", _machInst, No_OpClass, _wide)
82 {
83 numMicroops = machInst.fpscrLen + 1;
84 microOps = new StaticInstPtr[numMicroops];
85 for (unsigned i = 0; i < numMicroops; i++) {
86 VfpMicroMode mode = VfpMicroop;
87 if (i == 0)
88 mode = VfpFirstMicroop;
89 else if (i == numMicroops - 1)
90 mode = VfpLastMicroop;
91 microOps[i] = new Micro(_machInst, _dest, _imm, mode);
92 nextIdxs(_dest);
93 }
94 }
95 };
96
97 template <class VfpOp>
98 StaticInstPtr
99 decodeVfpRegImmOp(ExtMachInst machInst,
100 IntRegIndex dest, uint64_t imm, bool wide)
101 {
102 if (machInst.fpscrLen == 0 || VfpMacroOp::inScalarBank(dest)) {
103 return new VfpOp(machInst, dest, imm);
104 } else {
105 return new VfpMacroRegImmOp<VfpOp>(machInst, dest, imm, wide);
106 }
107 }
108
109 template <class Micro>
110 class VfpMacroRegRegImmOp : public VfpMacroOp
111 {
112 public:
113 VfpMacroRegRegImmOp(ExtMachInst _machInst, IntRegIndex _dest,
114 IntRegIndex _op1, uint64_t _imm, bool _wide) :
115 VfpMacroOp("VfpMacroRegRegImmOp", _machInst, No_OpClass, _wide)
116 {
117 numMicroops = machInst.fpscrLen + 1;
118 microOps = new StaticInstPtr[numMicroops];
119 for (unsigned i = 0; i < numMicroops; i++) {
120 VfpMicroMode mode = VfpMicroop;
121 if (i == 0)
122 mode = VfpFirstMicroop;
123 else if (i == numMicroops - 1)
124 mode = VfpLastMicroop;
125 microOps[i] = new Micro(_machInst, _dest, _op1, _imm, mode);
126 nextIdxs(_dest, _op1);
127 }
128 }
129 };
130
131 template <class VfpOp>
132 StaticInstPtr
133 decodeVfpRegRegImmOp(ExtMachInst machInst, IntRegIndex dest,
134 IntRegIndex op1, uint64_t imm, bool wide)
135 {
136 if (machInst.fpscrLen == 0 || VfpMacroOp::inScalarBank(dest)) {
137 return new VfpOp(machInst, dest, op1, imm);
138 } else {
139 return new VfpMacroRegRegImmOp<VfpOp>(machInst, dest, op1, imm, wide);
140 }
141 }
142
143 template <class Micro>
144 class VfpMacroRegRegRegOp : public VfpMacroOp
145 {
146 public:
147 VfpMacroRegRegRegOp(ExtMachInst _machInst, IntRegIndex _dest,
148 IntRegIndex _op1, IntRegIndex _op2, bool _wide) :
149 VfpMacroOp("VfpMacroRegRegRegOp", _machInst, No_OpClass, _wide)
150 {
151 numMicroops = machInst.fpscrLen + 1;
152 microOps = new StaticInstPtr[numMicroops];
153 for (unsigned i = 0; i < numMicroops; i++) {
154 VfpMicroMode mode = VfpMicroop;
155 if (i == 0)
156 mode = VfpFirstMicroop;
157 else if (i == numMicroops - 1)
158 mode = VfpLastMicroop;
159 microOps[i] = new Micro(_machInst, _dest, _op1, _op2, mode);
160 nextIdxs(_dest, _op1, _op2);
161 }
162 }
163 };
164
165 template <class VfpOp>
166 StaticInstPtr
167 decodeVfpRegRegRegOp(ExtMachInst machInst, IntRegIndex dest,
168 IntRegIndex op1, IntRegIndex op2, bool wide)
169 {
170 if (machInst.fpscrLen == 0 || VfpMacroOp::inScalarBank(dest)) {
171 return new VfpOp(machInst, dest, op1, op2);
172 } else {
173 return new VfpMacroRegRegRegOp<VfpOp>(machInst, dest, op1, op2, wide);
174 }
175 }
176 }};
177
178 let {{
179
180 header_output = ""
181 decoder_output = ""
182 exec_output = ""
183
184 vmsrCode = vmsrEnabledCheckCode + '''
185 MiscDest = Op1;
186 '''
187
188 vmsrIop = InstObjParams("vmsr", "Vmsr", "FpRegRegImmOp",
189 { "code": vmsrCode,
190 "predicate_test": predicateTest,
191 "op_class": "SimdFloatMiscOp" },
192 ["IsSerializeAfter","IsNonSpeculative"])
193 header_output += FpRegRegImmOpDeclare.subst(vmsrIop);
194 decoder_output += FpRegRegImmOpConstructor.subst(vmsrIop);
195 exec_output += PredOpExecute.subst(vmsrIop);
196
197 vmsrFpscrCode = vmsrEnabledCheckCode + '''
198 Fpscr = Op1 & ~FpCondCodesMask;
199 FpCondCodes = Op1 & FpCondCodesMask;
200 '''
201 vmsrFpscrIop = InstObjParams("vmsr", "VmsrFpscr", "FpRegRegOp",
202 { "code": vmsrFpscrCode,
203 "predicate_test": predicateTest,
204 "op_class": "SimdFloatMiscOp" },
205 ["IsSerializeAfter","IsNonSpeculative",
206 "IsSquashAfter"])
207 header_output += FpRegRegOpDeclare.subst(vmsrFpscrIop);
208 decoder_output += FpRegRegOpConstructor.subst(vmsrFpscrIop);
209 exec_output += PredOpExecute.subst(vmsrFpscrIop);
210
211 vmrsCode = vmrsEnabledCheckCode + '''
212 CPSR cpsr = Cpsr;
213 if (!isSecure(xc->tcBase()) && (cpsr.mode != MODE_HYP)) {
214 HCR hcr = Hcr;
215 bool hypTrap = false;
216 switch(xc->tcBase()->flattenRegId(RegId(MiscRegClass, op1)).index()) {
217 case MISCREG_FPSID:
218 hypTrap = hcr.tid0;
219 break;
220 case MISCREG_MVFR0:
221 case MISCREG_MVFR1:
222 hypTrap = hcr.tid3;
223 break;
224 }
225 if (hypTrap) {
226 return std::make_shared<HypervisorTrap>(machInst, imm,
227 EC_TRAPPED_CP10_MRC_VMRS);
228 }
229 }
230 Dest = MiscOp1;
231 '''
232
233 vmrsIop = InstObjParams("vmrs", "Vmrs", "FpRegRegImmOp",
234 { "code": vmrsCode,
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);
241
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);
251
252 vmrsApsrFpscrCode = vfpEnabledCheckCode + '''
253 FPSCR fpscr = FpCondCodes;
254 CondCodesNZ = (fpscr.n << 1) | fpscr.z;
255 CondCodesC = fpscr.c;
256 CondCodesV = fpscr.v;
257 '''
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);
265
266 vmovImmSCode = vfpEnabledCheckCode + '''
267 FpDest_uw = bits(imm, 31, 0);
268 '''
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);
276
277 vmovImmDCode = vfpEnabledCheckCode + '''
278 FpDestP0_uw = bits(imm, 31, 0);
279 FpDestP1_uw = bits(imm, 63, 32);
280 '''
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);
288
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);
294 '''
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);
302
303 vmovRegSCode = vfpEnabledCheckCode + '''
304 FpDest_uw = FpOp1_uw;
305 '''
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);
313
314 vmovRegDCode = vfpEnabledCheckCode + '''
315 FpDestP0_uw = FpOp1P0_uw;
316 FpDestP1_uw = FpOp1P1_uw;
317 '''
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);
325
326 vmovRegQCode = vfpEnabledCheckCode + '''
327 FpDestP0_uw = FpOp1P0_uw;
328 FpDestP1_uw = FpOp1P1_uw;
329 FpDestP2_uw = FpOp1P2_uw;
330 FpDestP3_uw = FpOp1P3_uw;
331 '''
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);
339
340 vmovCoreRegBCode = simdEnabledCheckCode + '''
341 FpDest_uw = insertBits(FpDest_uw, imm * 8 + 7, imm * 8, Op1_ub);
342 '''
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);
350
351 vmovCoreRegHCode = simdEnabledCheckCode + '''
352 FpDest_uw = insertBits(FpDest_uw, imm * 16 + 15, imm * 16, Op1_uh);
353 '''
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);
361
362 vmovCoreRegWCode = vfpEnabledCheckCode + '''
363 FpDest_uw = Op1_uw;
364 '''
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);
372
373 vmovRegCoreUBCode = vfpEnabledCheckCode + '''
374 assert(imm < 4);
375 Dest = bits(FpOp1_uw, imm * 8 + 7, imm * 8);
376 '''
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);
384
385 vmovRegCoreUHCode = vfpEnabledCheckCode + '''
386 assert(imm < 2);
387 Dest = bits(FpOp1_uw, imm * 16 + 15, imm * 16);
388 '''
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);
396
397 vmovRegCoreSBCode = vfpEnabledCheckCode + '''
398 assert(imm < 4);
399 Dest = sext<8>(bits(FpOp1_uw, imm * 8 + 7, imm * 8));
400 '''
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);
408
409 vmovRegCoreSHCode = vfpEnabledCheckCode + '''
410 assert(imm < 2);
411 Dest = sext<16>(bits(FpOp1_uw, imm * 16 + 15, imm * 16));
412 '''
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);
420
421 vmovRegCoreWCode = vfpEnabledCheckCode + '''
422 Dest = FpOp1_uw;
423 '''
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);
431
432 vmov2Reg2CoreCode = vfpEnabledCheckCode + '''
433 FpDestP0_uw = Op1_uw;
434 FpDestP1_uw = Op2_uw;
435 '''
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);
443
444 vmov2Core2RegCode = vfpEnabledCheckCode + '''
445 Dest_uw = FpOp2P0_uw;
446 Op1_uw = FpOp2P1_uw;
447 '''
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);
455 }};
456
457 let {{
458
459 header_output = ""
460 decoder_output = ""
461 exec_output = ""
462
463 singleSimpleCode = vfpEnabledCheckCode + '''
464 FPSCR fpscr M5_VAR_USED = (FPSCR) FpscrExc;
465 FpDest = %(op)s;
466 '''
467 singleCode = singleSimpleCode + '''
468 FpscrExc = fpscr;
469 '''
470 singleTernOp = vfpEnabledCheckCode + '''
471 FPSCR fpscr = (FPSCR) FpscrExc;
472 VfpSavedState state = prepFpState(fpscr.rMode);
473 float cOp1 = FpOp1;
474 float cOp2 = FpOp2;
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);
479 FpscrExc = fpscr;
480 '''
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);
489 FpscrExc = fpscr;
490 '''
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);
502 FpscrExc = fpscr;
503 '''
504 doubleBinOp = '''
505 binaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw),
506 dbl(FpOp2P0_uw, FpOp2P1_uw),
507 %(func)s, fpscr.fz, fpscr.dn, fpscr.rMode);
508 '''
509 doubleUnaryOp = '''
510 unaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw), %(func)s,
511 fpscr.fz, fpscr.rMode)
512 '''
513
514 def buildTernaryFpOp(Name, base, opClass, singleOp, doubleOp, paramStr):
515 global header_output, decoder_output, exec_output
516
517 code = singleTernOp % { "op": singleOp, "palam": paramStr }
518 sIop = InstObjParams(Name.lower() + "s", Name + "S", base,
519 { "code": code,
520 "predicate_test": predicateTest,
521 "op_class": opClass }, [])
522 code = doubleTernOp % { "op": doubleOp, "palam": paramStr }
523 dIop = InstObjParams(Name.lower() + "d", Name + "D", base,
524 { "code": code,
525 "predicate_test": predicateTest,
526 "op_class": opClass }, [])
527
528 declareTempl = eval(base + "Declare");
529 constructorTempl = eval(base + "Constructor");
530
531 for iop in sIop, dIop:
532 header_output += declareTempl.subst(iop)
533 decoder_output += constructorTempl.subst(iop)
534 exec_output += PredOpExecute.subst(iop)
535
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" )
544
545 def buildBinFpOp(name, Name, base, opClass, singleOp, doubleOp):
546 global header_output, decoder_output, exec_output
547
548 code = singleCode % { "op": singleBinOp }
549 code = code % { "func": singleOp }
550 sIop = InstObjParams(name + "s", Name + "S", base,
551 { "code": code,
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,
557 { "code": code,
558 "predicate_test": predicateTest,
559 "op_class": opClass }, [])
560
561 declareTempl = eval(base + "Declare");
562 constructorTempl = eval(base + "Constructor");
563
564 for iop in sIop, dIop:
565 header_output += declareTempl.subst(iop)
566 decoder_output += constructorTempl.subst(iop)
567 exec_output += PredOpExecute.subst(iop)
568
569 buildBinFpOp("vadd", "Vadd", "FpRegRegRegOp", "SimdFloatAddOp", "fpAddS",
570 "fpAddD")
571 buildBinFpOp("vsub", "Vsub", "FpRegRegRegOp", "SimdFloatAddOp", "fpSubS",
572 "fpSubD")
573 buildBinFpOp("vdiv", "Vdiv", "FpRegRegRegOp", "SimdFloatDivOp", "fpDivS",
574 "fpDivD")
575 buildBinFpOp("vmul", "Vmul", "FpRegRegRegOp", "SimdFloatMultOp", "fpMulS",
576 "fpMulD")
577
578 def buildBinOp(name, base, opClass, op):
579 '''
580 Create backported aarch64 instructions that use fplib.
581
582 Because they are backported, these instructions are unconditional.
583 '''
584 global header_output, decoder_output, exec_output
585 inst_datas = [
586 (
587 "s",
588 '''
589 FpDest_uw = fplib%(op)s<>(FpOp1_uw, FpOp2_uw, fpscr);
590 '''
591 ),
592 (
593 "d",
594 '''
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);
600 FpDestP0_uw = dest;
601 FpDestP1_uw = dest >> 32;
602 '''
603 )
604 ]
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:
609 code = (
610 '''
611 FPSCR fpscr = (FPSCR)FpscrExc;
612 ''' +
613 code +
614 '''
615 FpscrExc = fpscr;
616 '''
617 )
618 iop = InstObjParams(
619 name + size_suffix,
620 Name + size_suffix.upper(),
621 base,
622 {
623 "code": code % {"op": op},
624 "op_class": opClass
625 },
626 []
627 )
628 header_output += declareTempl.subst(iop)
629 decoder_output += constructorTempl.subst(iop)
630 exec_output += BasicExecute.subst(iop)
631 ops = [
632 ("vminnm", "FpRegRegRegOp", "SimdFloatCmpOp", "MinNum"),
633 ("vmaxnm", "FpRegRegRegOp", "SimdFloatCmpOp", "MaxNum"),
634 ]
635 for op in ops:
636 buildBinOp(*op)
637
638 def buildUnaryFpOp(name, Name, base, opClass, singleOp, doubleOp = None):
639 if doubleOp is None:
640 doubleOp = singleOp
641 global header_output, decoder_output, exec_output
642
643 code = singleCode % { "op": singleUnaryOp }
644 code = code % { "func": singleOp }
645 sIop = InstObjParams(name + "s", Name + "S", base,
646 { "code": code,
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,
652 { "code": code,
653 "predicate_test": predicateTest,
654 "op_class": opClass }, [])
655
656 declareTempl = eval(base + "Declare");
657 constructorTempl = eval(base + "Constructor");
658
659 for iop in sIop, dIop:
660 header_output += declareTempl.subst(iop)
661 decoder_output += constructorTempl.subst(iop)
662 exec_output += PredOpExecute.subst(iop)
663
664 buildUnaryFpOp("vsqrt", "Vsqrt", "FpRegRegOp", "SimdFloatSqrtOp", "sqrtf",
665 "sqrt")
666
667 def buildSimpleUnaryFpOp(name, Name, base, opClass, singleOp,
668 doubleOp = None):
669 if doubleOp is None:
670 doubleOp = singleOp
671 global header_output, decoder_output, exec_output
672
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 }, [])
681
682 declareTempl = eval(base + "Declare");
683 constructorTempl = eval(base + "Constructor");
684
685 for iop in sIop, dIop:
686 header_output += declareTempl.subst(iop)
687 decoder_output += constructorTempl.subst(iop)
688 exec_output += PredOpExecute.subst(iop)
689
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)"
698 )
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)"
703 )
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)"
708 )
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)"
713 )
714 }};
715
716 let {{
717
718 header_output = ""
719 decoder_output = ""
720 exec_output = ""
721
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);
728 FpscrExc = fpscr;
729 '''
730 vmlaSIop = InstObjParams("vmlas", "VmlaS", "FpRegRegRegOp",
731 { "code": vmlaSCode,
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);
737
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);
748 FpscrExc = fpscr;
749 '''
750 vmlaDIop = InstObjParams("vmlad", "VmlaD", "FpRegRegRegOp",
751 { "code": vmlaDCode,
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);
757
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);
764 FpscrExc = fpscr;
765 '''
766 vmlsSIop = InstObjParams("vmlss", "VmlsS", "FpRegRegRegOp",
767 { "code": vmlsSCode,
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);
773
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);
784 FpscrExc = fpscr;
785 '''
786 vmlsDIop = InstObjParams("vmlsd", "VmlsD", "FpRegRegRegOp",
787 { "code": vmlsDCode,
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);
793
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);
800 FpscrExc = fpscr;
801 '''
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);
809
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);
820 FpscrExc = fpscr;
821 '''
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);
829
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);
836 FpscrExc = fpscr;
837 '''
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);
845
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);
856 FpscrExc = fpscr;
857 '''
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);
865
866 vnmulSCode = vfpEnabledCheckCode + '''
867 FPSCR fpscr = (FPSCR) FpscrExc;
868 FpDest = -binaryOp(fpscr, FpOp1, FpOp2, fpMulS,
869 fpscr.fz, fpscr.dn, fpscr.rMode);
870 FpscrExc = fpscr;
871 '''
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);
879
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,
885 fpscr.rMode);
886 FpDestP0_uw = dblLow(dest);
887 FpDestP1_uw = dblHi(dest);
888 FpscrExc = fpscr;
889 '''
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);
897 }};
898
899 let {{
900
901 header_output = ""
902 decoder_output = ""
903 exec_output = ""
904
905 vcvtUIntFpSCode = vfpEnabledCheckCode + '''
906 FPSCR fpscr = (FPSCR) FpscrExc;
907 VfpSavedState state = prepFpState(fpscr.rMode);
908 __asm__ __volatile__("" : "=m" (FpOp1_uw) : "m" (FpOp1_uw));
909 FpDest = FpOp1_uw;
910 __asm__ __volatile__("" :: "m" (FpDest));
911 finishVfp(fpscr, state, fpscr.fz);
912 FpscrExc = fpscr;
913 '''
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);
921
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);
931 FpscrExc = fpscr;
932 '''
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);
940
941 vcvtSIntFpSCode = vfpEnabledCheckCode + '''
942 FPSCR fpscr = (FPSCR) FpscrExc;
943 VfpSavedState state = prepFpState(fpscr.rMode);
944 __asm__ __volatile__("" : "=m" (FpOp1_sw) : "m" (FpOp1_sw));
945 FpDest = FpOp1_sw;
946 __asm__ __volatile__("" :: "m" (FpDest));
947 finishVfp(fpscr, state, fpscr.fz);
948 FpscrExc = fpscr;
949 '''
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);
957
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);
967 FpscrExc = fpscr;
968 '''
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);
976
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));
981 uint8_t nz;
982 FpDest_uw = fplibFPToFixedJS(cOp1, fpscr, false, nz);
983 finishVfp(fpscr, state, fpscr.fz);
984 FpCondCodes = fpscr & FpCondCodesMask;
985 FpscrExc = fpscr;
986 '''
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);
994
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);
1003 FpscrExc = fpscr;
1004 '''
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);
1012
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;
1023 FpscrExc = fpscr;
1024 '''
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);
1032
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);
1041 FpscrExc = fpscr;
1042 '''
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);
1050
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;
1061 FpscrExc = fpscr;
1062 '''
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);
1070
1071 round_mode_suffix_to_mode = {
1072 '': 'VfpRoundZero',
1073 'a': 'VfpRoundAway',
1074 'm': 'VfpRoundDown',
1075 'n': 'VfpRoundNearest',
1076 'p': 'VfpRoundUpward',
1077 }
1078
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],
1084 )
1085 iop = InstObjParams(
1086 "vcvt{}".format(roundModeSuffix),
1087 className.format(roundModeSuffix),
1088 "FpRegRegOp",
1089 { "code": full_code,
1090 "predicate_test": predicateTest,
1091 "op_class": "SimdFloatCvtOp" },
1092 []
1093 )
1094 header_output += FpRegRegOpDeclare.subst(iop);
1095 decoder_output += FpRegRegOpConstructor.subst(iop);
1096 exec_output += PredOpExecute.subst(iop);
1097
1098 code = '''
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);
1108 FpscrExc = fpscr;
1109 '''
1110 for round_mode_suffix in round_mode_suffix_to_mode:
1111 buildVcvt(code, "Vcvt{}FpUIntS", round_mode_suffix)
1112
1113 code = '''
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;
1125 FpscrExc = fpscr;
1126 '''
1127 for round_mode_suffix in round_mode_suffix_to_mode:
1128 buildVcvt(code, "Vcvt{}FpUIntD", round_mode_suffix)
1129
1130 code = '''
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);
1140 FpscrExc = fpscr;
1141 '''
1142 for round_mode_suffix in round_mode_suffix_to_mode:
1143 buildVcvt(code, "Vcvt{}FpSIntS", round_mode_suffix)
1144
1145 code = '''
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;
1157 FpscrExc = fpscr;
1158 '''
1159 for round_mode_suffix in round_mode_suffix_to_mode:
1160 buildVcvt(code, "Vcvt{}FpSIntD", round_mode_suffix)
1161
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);
1172 FpscrExc = fpscr;
1173 '''
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);
1181
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);
1191 FpscrExc = fpscr;
1192 '''
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);
1200
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);
1210 FpscrExc = fpscr;
1211 '''
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);
1219
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);
1228 FpscrExc = fpscr;
1229 '''
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);
1237
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);
1249 FpscrExc = fpscr;
1250 '''
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);
1258
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);
1270 FpscrExc = fpscr;
1271 '''
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);
1279
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;
1289 } else {
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)
1296 fpscr.ioc = 1;
1297 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1298 }
1299 FpCondCodes = fpscr & FpCondCodesMask;
1300 FpscrExc = fpscr;
1301 '''
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);
1309
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;
1321 } else {
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)
1328 fpscr.ioc = 1;
1329 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1330 }
1331 FpCondCodes = fpscr & FpCondCodesMask;
1332 FpscrExc = fpscr;
1333 '''
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);
1341
1342 vcmpZeroSCode = vfpEnabledCheckCode + '''
1343 FPSCR fpscr = (FPSCR) FpscrExc;
1344 vfpFlushToZero(fpscr, FpDest);
1345 // This only handles imm == 0 for now.
1346 assert(imm == 0);
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;
1353 } else {
1354 const uint32_t qnan = 0x7fc00000;
1355 const bool nan = std::isnan(FpDest);
1356 const bool signal = nan && ((fpToBits(FpDest) & qnan) != qnan);
1357 if (signal)
1358 fpscr.ioc = 1;
1359 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1360 }
1361 FpCondCodes = fpscr & FpCondCodesMask;
1362 FpscrExc = fpscr;
1363 '''
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);
1371
1372 vcmpZeroDCode = vfpEnabledCheckCode + '''
1373 // This only handles imm == 0 for now.
1374 assert(imm == 0);
1375 double cDest = dbl(FpDestP0_uw, FpDestP1_uw);
1376 FPSCR fpscr = (FPSCR) FpscrExc;
1377 vfpFlushToZero(fpscr, cDest);
1378 if (cDest == imm) {
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;
1384 } else {
1385 const uint64_t qnan = ULL(0x7ff8000000000000);
1386 const bool nan = std::isnan(cDest);
1387 const bool signal = nan && ((fpToBits(cDest) & qnan) != qnan);
1388 if (signal)
1389 fpscr.ioc = 1;
1390 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1391 }
1392 FpCondCodes = fpscr & FpCondCodesMask;
1393 FpscrExc = fpscr;
1394 '''
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);
1402
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;
1412 } else {
1413 fpscr.ioc = 1;
1414 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1415 }
1416 FpCondCodes = fpscr & FpCondCodesMask;
1417 FpscrExc = fpscr;
1418 '''
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);
1426
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;
1438 } else {
1439 fpscr.ioc = 1;
1440 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1441 }
1442 FpCondCodes = fpscr & FpCondCodesMask;
1443 FpscrExc = fpscr;
1444 '''
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);
1452
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;
1462 } else {
1463 fpscr.ioc = 1;
1464 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1465 }
1466 FpCondCodes = fpscr & FpCondCodesMask;
1467 FpscrExc = fpscr;
1468 '''
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);
1476
1477 vcmpeZeroDCode = vfpEnabledCheckCode + '''
1478 double cDest = dbl(FpDestP0_uw, FpDestP1_uw);
1479 FPSCR fpscr = (FPSCR) FpscrExc;
1480 vfpFlushToZero(fpscr, cDest);
1481 if (cDest == imm) {
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;
1487 } else {
1488 fpscr.ioc = 1;
1489 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1490 }
1491 FpCondCodes = fpscr & FpCondCodesMask;
1492 FpscrExc = fpscr;
1493 '''
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);
1501 }};
1502
1503 let {{
1504
1505 header_output = ""
1506 decoder_output = ""
1507 exec_output = ""
1508
1509 vselSCode = vfpEnabledCheckCode + '''
1510 if (testPredicate(CondCodesNZ, CondCodesC, CondCodesV, cond)) {
1511 FpDest = FpOp1;
1512 } else {
1513 FpDest = FpOp2;
1514 } '''
1515
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);
1523
1524 vselDCode = vfpEnabledCheckCode + '''
1525 if (testPredicate(CondCodesNZ, CondCodesC, CondCodesV, cond)) {
1526 FpDestP0_uw = FpOp1P0_uw;
1527 FpDestP1_uw = FpOp1P1_uw;
1528 } else {
1529 FpDestP0_uw = FpOp2P0_uw;
1530 FpDestP1_uw = FpOp2P1_uw;
1531 } '''
1532
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);
1540 }};
1541
1542
1543 let {{
1544
1545 header_output = ""
1546 decoder_output = ""
1547 exec_output = ""
1548
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);
1557 FpscrExc = fpscr;
1558 '''
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);
1566
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);
1576 FpDestP0_uw = mid;
1577 FpDestP1_uw = mid >> 32;
1578 FpscrExc = fpscr;
1579 '''
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);
1587
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);
1596 FpscrExc = fpscr;
1597 '''
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);
1605
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);
1615 FpDestP0_uw = mid;
1616 FpDestP1_uw = mid >> 32;
1617 FpscrExc = fpscr;
1618 '''
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);
1626
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);
1634 FpscrExc = fpscr;
1635 '''
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);
1643
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);
1654 FpscrExc = fpscr;
1655 '''
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);
1663
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);
1671 FpscrExc = fpscr;
1672 '''
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);
1680
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);
1691 FpscrExc = fpscr;
1692 '''
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);
1700
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);
1709 FpscrExc = fpscr;
1710 '''
1711 vcvtFpSHFixedSIop = InstObjParams("vcvt", "VcvtFpSHFixedS",
1712 "FpRegRegImmOp",
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);
1719
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;
1731 FpscrExc = fpscr;
1732 '''
1733 vcvtFpSHFixedDIop = InstObjParams("vcvt", "VcvtFpSHFixedD",
1734 "FpRegRegImmOp",
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);
1741
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);
1750 FpscrExc = fpscr;
1751 '''
1752 vcvtFpUHFixedSIop = InstObjParams("vcvt", "VcvtFpUHFixedS",
1753 "FpRegRegImmOp",
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);
1760
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);
1770 FpDestP0_uw = mid;
1771 FpDestP1_uw = mid >> 32;
1772 FpscrExc = fpscr;
1773 '''
1774 vcvtFpUHFixedDIop = InstObjParams("vcvt", "VcvtFpUHFixedD",
1775 "FpRegRegImmOp",
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);
1782
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);
1790 FpscrExc = fpscr;
1791 '''
1792 vcvtSHFixedFpSIop = InstObjParams("vcvt", "VcvtSHFixedFpS",
1793 "FpRegRegImmOp",
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);
1800
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);
1811 FpscrExc = fpscr;
1812 '''
1813 vcvtSHFixedFpDIop = InstObjParams("vcvt", "VcvtSHFixedFpD",
1814 "FpRegRegImmOp",
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);
1821
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);
1829 FpscrExc = fpscr;
1830 '''
1831 vcvtUHFixedFpSIop = InstObjParams("vcvt", "VcvtUHFixedFpS",
1832 "FpRegRegImmOp",
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);
1839
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);
1850 FpscrExc = fpscr;
1851 '''
1852 vcvtUHFixedFpDIop = InstObjParams("vcvt", "VcvtUHFixedFpD",
1853 "FpRegRegImmOp",
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);
1860 }};