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