fp.isa (12236:126ac9da6050) fp.isa (13738:84439021dcf6)
1// -*- mode:c++ -*-
2
1// -*- mode:c++ -*-
2
3// Copyright (c) 2010-2013,2016 ARM Limited
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 buildUnaryFpOp(name, Name, base, opClass, singleOp, doubleOp = None):
582 if doubleOp is None:
583 doubleOp = singleOp
584 global header_output, decoder_output, exec_output
585
586 code = singleCode % { "op": singleUnaryOp }
587 code = code % { "func": singleOp }
588 sIop = InstObjParams(name + "s", Name + "S", base,
589 { "code": code,
590 "predicate_test": predicateTest,
591 "op_class": opClass }, [])
592 code = doubleCode % { "op": doubleUnaryOp }
593 code = code % { "func": doubleOp }
594 dIop = InstObjParams(name + "d", Name + "D", base,
595 { "code": code,
596 "predicate_test": predicateTest,
597 "op_class": opClass }, [])
598
599 declareTempl = eval(base + "Declare");
600 constructorTempl = eval(base + "Constructor");
601
602 for iop in sIop, dIop:
603 header_output += declareTempl.subst(iop)
604 decoder_output += constructorTempl.subst(iop)
605 exec_output += PredOpExecute.subst(iop)
606
607 buildUnaryFpOp("vsqrt", "Vsqrt", "FpRegRegOp", "SimdFloatSqrtOp", "sqrtf",
608 "sqrt")
609
610 def buildSimpleUnaryFpOp(name, Name, base, opClass, singleOp,
611 doubleOp = None):
612 if doubleOp is None:
613 doubleOp = singleOp
614 global header_output, decoder_output, exec_output
615
616 sIop = InstObjParams(name + "s", Name + "S", base,
617 { "code": singleSimpleCode % { "op": singleOp },
618 "predicate_test": predicateTest,
619 "op_class": opClass }, [])
620 dIop = InstObjParams(name + "d", Name + "D", base,
621 { "code": doubleCode % { "op": doubleOp },
622 "predicate_test": predicateTest,
623 "op_class": opClass }, [])
624
625 declareTempl = eval(base + "Declare");
626 constructorTempl = eval(base + "Constructor");
627
628 for iop in sIop, dIop:
629 header_output += declareTempl.subst(iop)
630 decoder_output += constructorTempl.subst(iop)
631 exec_output += PredOpExecute.subst(iop)
632
633 buildSimpleUnaryFpOp("vneg", "Vneg", "FpRegRegOp", "SimdFloatMiscOp",
634 "-FpOp1", "-dbl(FpOp1P0_uw, FpOp1P1_uw)")
635 buildSimpleUnaryFpOp("vabs", "Vabs", "FpRegRegOp", "SimdFloatMiscOp",
636 "fabsf(FpOp1)", "fabs(dbl(FpOp1P0_uw, FpOp1P1_uw))")
637 buildSimpleUnaryFpOp("vrintp", "VRIntP", "FpRegRegOp", "SimdFloatMiscOp",
638 "fplibRoundInt<uint32_t>(FpOp1, FPRounding_POSINF, false, fpscr)",
639 "fplibRoundInt<uint64_t>(dbl(FpOp1P0_uw, FpOp1P1_uw), " \
640 "FPRounding_POSINF, false, fpscr)"
641 )
642 buildSimpleUnaryFpOp("vrintm", "VRIntM", "FpRegRegOp", "SimdFloatMiscOp",
643 "fplibRoundInt<uint32_t>(FpOp1, FPRounding_NEGINF, false, fpscr)",
644 "fplibRoundInt<uint64_t>(dbl(FpOp1P0_uw, FpOp1P1_uw), " \
645 "FPRounding_NEGINF, false, fpscr)"
646 )
647 buildSimpleUnaryFpOp("vrinta", "VRIntA", "FpRegRegOp", "SimdFloatMiscOp",
648 "fplibRoundInt<uint32_t>(FpOp1, FPRounding_TIEAWAY, false, fpscr)",
649 "fplibRoundInt<uint64_t>(dbl(FpOp1P0_uw, FpOp1P1_uw), " \
650 "FPRounding_TIEAWAY, false, fpscr)"
651 )
652 buildSimpleUnaryFpOp("vrintn", "VRIntN", "FpRegRegOp", "SimdFloatMiscOp",
653 "fplibRoundInt<uint32_t>(FpOp1, FPRounding_TIEEVEN, false, fpscr)",
654 "fplibRoundInt<uint64_t>(dbl(FpOp1P0_uw, FpOp1P1_uw), " \
655 "FPRounding_TIEEVEN, false, fpscr)"
656 )
657}};
658
659let {{
660
661 header_output = ""
662 decoder_output = ""
663 exec_output = ""
664
665 vmlaSCode = vfpEnabledCheckCode + '''
666 FPSCR fpscr = (FPSCR) FpscrExc;
667 float mid = binaryOp(fpscr, FpOp1, FpOp2,
668 fpMulS, fpscr.fz, fpscr.dn, fpscr.rMode);
669 FpDest = binaryOp(fpscr, FpDest, mid, fpAddS,
670 fpscr.fz, fpscr.dn, fpscr.rMode);
671 FpscrExc = fpscr;
672 '''
673 vmlaSIop = InstObjParams("vmlas", "VmlaS", "FpRegRegRegOp",
674 { "code": vmlaSCode,
675 "predicate_test": predicateTest,
676 "op_class": "SimdFloatMultAccOp" }, [])
677 header_output += FpRegRegRegOpDeclare.subst(vmlaSIop);
678 decoder_output += FpRegRegRegOpConstructor.subst(vmlaSIop);
679 exec_output += PredOpExecute.subst(vmlaSIop);
680
681 vmlaDCode = vfpEnabledCheckCode + '''
682 FPSCR fpscr = (FPSCR) FpscrExc;
683 double mid = binaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw),
684 dbl(FpOp2P0_uw, FpOp2P1_uw),
685 fpMulD, fpscr.fz, fpscr.dn, fpscr.rMode);
686 double dest = binaryOp(fpscr, dbl(FpDestP0_uw, FpDestP1_uw),
687 mid, fpAddD, fpscr.fz,
688 fpscr.dn, fpscr.rMode);
689 FpDestP0_uw = dblLow(dest);
690 FpDestP1_uw = dblHi(dest);
691 FpscrExc = fpscr;
692 '''
693 vmlaDIop = InstObjParams("vmlad", "VmlaD", "FpRegRegRegOp",
694 { "code": vmlaDCode,
695 "predicate_test": predicateTest,
696 "op_class": "SimdFloatMultAccOp" }, [])
697 header_output += FpRegRegRegOpDeclare.subst(vmlaDIop);
698 decoder_output += FpRegRegRegOpConstructor.subst(vmlaDIop);
699 exec_output += PredOpExecute.subst(vmlaDIop);
700
701 vmlsSCode = vfpEnabledCheckCode + '''
702 FPSCR fpscr = (FPSCR) FpscrExc;
703 float mid = binaryOp(fpscr, FpOp1, FpOp2,
704 fpMulS, fpscr.fz, fpscr.dn, fpscr.rMode);
705 FpDest = binaryOp(fpscr, FpDest, -mid, fpAddS,
706 fpscr.fz, fpscr.dn, fpscr.rMode);
707 FpscrExc = fpscr;
708 '''
709 vmlsSIop = InstObjParams("vmlss", "VmlsS", "FpRegRegRegOp",
710 { "code": vmlsSCode,
711 "predicate_test": predicateTest,
712 "op_class": "SimdFloatMultAccOp" }, [])
713 header_output += FpRegRegRegOpDeclare.subst(vmlsSIop);
714 decoder_output += FpRegRegRegOpConstructor.subst(vmlsSIop);
715 exec_output += PredOpExecute.subst(vmlsSIop);
716
717 vmlsDCode = vfpEnabledCheckCode + '''
718 FPSCR fpscr = (FPSCR) FpscrExc;
719 double mid = binaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw),
720 dbl(FpOp2P0_uw, FpOp2P1_uw),
721 fpMulD, fpscr.fz, fpscr.dn, fpscr.rMode);
722 double dest = binaryOp(fpscr, dbl(FpDestP0_uw, FpDestP1_uw),
723 -mid, fpAddD, fpscr.fz,
724 fpscr.dn, fpscr.rMode);
725 FpDestP0_uw = dblLow(dest);
726 FpDestP1_uw = dblHi(dest);
727 FpscrExc = fpscr;
728 '''
729 vmlsDIop = InstObjParams("vmlsd", "VmlsD", "FpRegRegRegOp",
730 { "code": vmlsDCode,
731 "predicate_test": predicateTest,
732 "op_class": "SimdFloatMultAccOp" }, [])
733 header_output += FpRegRegRegOpDeclare.subst(vmlsDIop);
734 decoder_output += FpRegRegRegOpConstructor.subst(vmlsDIop);
735 exec_output += PredOpExecute.subst(vmlsDIop);
736
737 vnmlaSCode = vfpEnabledCheckCode + '''
738 FPSCR fpscr = (FPSCR) FpscrExc;
739 float mid = binaryOp(fpscr, FpOp1, FpOp2,
740 fpMulS, fpscr.fz, fpscr.dn, fpscr.rMode);
741 FpDest = binaryOp(fpscr, -FpDest, -mid, fpAddS,
742 fpscr.fz, fpscr.dn, fpscr.rMode);
743 FpscrExc = fpscr;
744 '''
745 vnmlaSIop = InstObjParams("vnmlas", "VnmlaS", "FpRegRegRegOp",
746 { "code": vnmlaSCode,
747 "predicate_test": predicateTest,
748 "op_class": "SimdFloatMultAccOp" }, [])
749 header_output += FpRegRegRegOpDeclare.subst(vnmlaSIop);
750 decoder_output += FpRegRegRegOpConstructor.subst(vnmlaSIop);
751 exec_output += PredOpExecute.subst(vnmlaSIop);
752
753 vnmlaDCode = vfpEnabledCheckCode + '''
754 FPSCR fpscr = (FPSCR) FpscrExc;
755 double mid = binaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw),
756 dbl(FpOp2P0_uw, FpOp2P1_uw),
757 fpMulD, fpscr.fz, fpscr.dn, fpscr.rMode);
758 double dest = binaryOp(fpscr, -dbl(FpDestP0_uw, FpDestP1_uw),
759 -mid, fpAddD, fpscr.fz,
760 fpscr.dn, fpscr.rMode);
761 FpDestP0_uw = dblLow(dest);
762 FpDestP1_uw = dblHi(dest);
763 FpscrExc = fpscr;
764 '''
765 vnmlaDIop = InstObjParams("vnmlad", "VnmlaD", "FpRegRegRegOp",
766 { "code": vnmlaDCode,
767 "predicate_test": predicateTest,
768 "op_class": "SimdFloatMultAccOp" }, [])
769 header_output += FpRegRegRegOpDeclare.subst(vnmlaDIop);
770 decoder_output += FpRegRegRegOpConstructor.subst(vnmlaDIop);
771 exec_output += PredOpExecute.subst(vnmlaDIop);
772
773 vnmlsSCode = vfpEnabledCheckCode + '''
774 FPSCR fpscr = (FPSCR) FpscrExc;
775 float mid = binaryOp(fpscr, FpOp1, FpOp2,
776 fpMulS, fpscr.fz, fpscr.dn, fpscr.rMode);
777 FpDest = binaryOp(fpscr, -FpDest, mid, fpAddS,
778 fpscr.fz, fpscr.dn, fpscr.rMode);
779 FpscrExc = fpscr;
780 '''
781 vnmlsSIop = InstObjParams("vnmlss", "VnmlsS", "FpRegRegRegOp",
782 { "code": vnmlsSCode,
783 "predicate_test": predicateTest,
784 "op_class": "SimdFloatMultAccOp" }, [])
785 header_output += FpRegRegRegOpDeclare.subst(vnmlsSIop);
786 decoder_output += FpRegRegRegOpConstructor.subst(vnmlsSIop);
787 exec_output += PredOpExecute.subst(vnmlsSIop);
788
789 vnmlsDCode = vfpEnabledCheckCode + '''
790 FPSCR fpscr = (FPSCR) FpscrExc;
791 double mid = binaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw),
792 dbl(FpOp2P0_uw, FpOp2P1_uw),
793 fpMulD, fpscr.fz, fpscr.dn, fpscr.rMode);
794 double dest = binaryOp(fpscr, -dbl(FpDestP0_uw, FpDestP1_uw),
795 mid, fpAddD, fpscr.fz,
796 fpscr.dn, fpscr.rMode);
797 FpDestP0_uw = dblLow(dest);
798 FpDestP1_uw = dblHi(dest);
799 FpscrExc = fpscr;
800 '''
801 vnmlsDIop = InstObjParams("vnmlsd", "VnmlsD", "FpRegRegRegOp",
802 { "code": vnmlsDCode,
803 "predicate_test": predicateTest,
804 "op_class": "SimdFloatMultAccOp" }, [])
805 header_output += FpRegRegRegOpDeclare.subst(vnmlsDIop);
806 decoder_output += FpRegRegRegOpConstructor.subst(vnmlsDIop);
807 exec_output += PredOpExecute.subst(vnmlsDIop);
808
809 vnmulSCode = vfpEnabledCheckCode + '''
810 FPSCR fpscr = (FPSCR) FpscrExc;
811 FpDest = -binaryOp(fpscr, FpOp1, FpOp2, fpMulS,
812 fpscr.fz, fpscr.dn, fpscr.rMode);
813 FpscrExc = fpscr;
814 '''
815 vnmulSIop = InstObjParams("vnmuls", "VnmulS", "FpRegRegRegOp",
816 { "code": vnmulSCode,
817 "predicate_test": predicateTest,
818 "op_class": "SimdFloatMultOp" }, [])
819 header_output += FpRegRegRegOpDeclare.subst(vnmulSIop);
820 decoder_output += FpRegRegRegOpConstructor.subst(vnmulSIop);
821 exec_output += PredOpExecute.subst(vnmulSIop);
822
823 vnmulDCode = vfpEnabledCheckCode + '''
824 FPSCR fpscr = (FPSCR) FpscrExc;
825 double dest = -binaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw),
826 dbl(FpOp2P0_uw, FpOp2P1_uw),
827 fpMulD, fpscr.fz, fpscr.dn,
828 fpscr.rMode);
829 FpDestP0_uw = dblLow(dest);
830 FpDestP1_uw = dblHi(dest);
831 FpscrExc = fpscr;
832 '''
833 vnmulDIop = InstObjParams("vnmuld", "VnmulD", "FpRegRegRegOp",
834 { "code": vnmulDCode,
835 "predicate_test": predicateTest,
836 "op_class": "SimdFloatMultOp" }, [])
837 header_output += FpRegRegRegOpDeclare.subst(vnmulDIop);
838 decoder_output += FpRegRegRegOpConstructor.subst(vnmulDIop);
839 exec_output += PredOpExecute.subst(vnmulDIop);
840}};
841
842let {{
843
844 header_output = ""
845 decoder_output = ""
846 exec_output = ""
847
848 vcvtUIntFpSCode = vfpEnabledCheckCode + '''
849 FPSCR fpscr = (FPSCR) FpscrExc;
850 VfpSavedState state = prepFpState(fpscr.rMode);
851 __asm__ __volatile__("" : "=m" (FpOp1_uw) : "m" (FpOp1_uw));
852 FpDest = FpOp1_uw;
853 __asm__ __volatile__("" :: "m" (FpDest));
854 finishVfp(fpscr, state, fpscr.fz);
855 FpscrExc = fpscr;
856 '''
857 vcvtUIntFpSIop = InstObjParams("vcvt", "VcvtUIntFpS", "FpRegRegOp",
858 { "code": vcvtUIntFpSCode,
859 "predicate_test": predicateTest,
860 "op_class": "SimdFloatCvtOp" }, [])
861 header_output += FpRegRegOpDeclare.subst(vcvtUIntFpSIop);
862 decoder_output += FpRegRegOpConstructor.subst(vcvtUIntFpSIop);
863 exec_output += PredOpExecute.subst(vcvtUIntFpSIop);
864
865 vcvtUIntFpDCode = vfpEnabledCheckCode + '''
866 FPSCR fpscr = (FPSCR) FpscrExc;
867 VfpSavedState state = prepFpState(fpscr.rMode);
868 __asm__ __volatile__("" : "=m" (FpOp1P0_uw) : "m" (FpOp1P0_uw));
869 double cDest = (uint64_t)FpOp1P0_uw;
870 __asm__ __volatile__("" :: "m" (cDest));
871 finishVfp(fpscr, state, fpscr.fz);
872 FpDestP0_uw = dblLow(cDest);
873 FpDestP1_uw = dblHi(cDest);
874 FpscrExc = fpscr;
875 '''
876 vcvtUIntFpDIop = InstObjParams("vcvt", "VcvtUIntFpD", "FpRegRegOp",
877 { "code": vcvtUIntFpDCode,
878 "predicate_test": predicateTest,
879 "op_class": "SimdFloatCvtOp" }, [])
880 header_output += FpRegRegOpDeclare.subst(vcvtUIntFpDIop);
881 decoder_output += FpRegRegOpConstructor.subst(vcvtUIntFpDIop);
882 exec_output += PredOpExecute.subst(vcvtUIntFpDIop);
883
884 vcvtSIntFpSCode = vfpEnabledCheckCode + '''
885 FPSCR fpscr = (FPSCR) FpscrExc;
886 VfpSavedState state = prepFpState(fpscr.rMode);
887 __asm__ __volatile__("" : "=m" (FpOp1_sw) : "m" (FpOp1_sw));
888 FpDest = FpOp1_sw;
889 __asm__ __volatile__("" :: "m" (FpDest));
890 finishVfp(fpscr, state, fpscr.fz);
891 FpscrExc = fpscr;
892 '''
893 vcvtSIntFpSIop = InstObjParams("vcvt", "VcvtSIntFpS", "FpRegRegOp",
894 { "code": vcvtSIntFpSCode,
895 "predicate_test": predicateTest,
896 "op_class": "SimdFloatCvtOp" }, [])
897 header_output += FpRegRegOpDeclare.subst(vcvtSIntFpSIop);
898 decoder_output += FpRegRegOpConstructor.subst(vcvtSIntFpSIop);
899 exec_output += PredOpExecute.subst(vcvtSIntFpSIop);
900
901 vcvtSIntFpDCode = vfpEnabledCheckCode + '''
902 FPSCR fpscr = (FPSCR) FpscrExc;
903 VfpSavedState state = prepFpState(fpscr.rMode);
904 __asm__ __volatile__("" : "=m" (FpOp1P0_sw) : "m" (FpOp1P0_sw));
905 double cDest = FpOp1P0_sw;
906 __asm__ __volatile__("" :: "m" (cDest));
907 finishVfp(fpscr, state, fpscr.fz);
908 FpDestP0_uw = dblLow(cDest);
909 FpDestP1_uw = dblHi(cDest);
910 FpscrExc = fpscr;
911 '''
912 vcvtSIntFpDIop = InstObjParams("vcvt", "VcvtSIntFpD", "FpRegRegOp",
913 { "code": vcvtSIntFpDCode,
914 "predicate_test": predicateTest,
915 "op_class": "SimdFloatCvtOp" }, [])
916 header_output += FpRegRegOpDeclare.subst(vcvtSIntFpDIop);
917 decoder_output += FpRegRegOpConstructor.subst(vcvtSIntFpDIop);
918 exec_output += PredOpExecute.subst(vcvtSIntFpDIop);
919
920 vcvtFpUIntSRCode = vfpEnabledCheckCode + '''
921 FPSCR fpscr = (FPSCR) FpscrExc;
922 VfpSavedState state = prepFpState(fpscr.rMode);
923 vfpFlushToZero(fpscr, FpOp1);
924 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
925 FpDest_uw = vfpFpToFixed<float>(FpOp1, false, 32, 0, false);
926 __asm__ __volatile__("" :: "m" (FpDest_uw));
927 finishVfp(fpscr, state, fpscr.fz);
928 FpscrExc = fpscr;
929 '''
930 vcvtFpUIntSRIop = InstObjParams("vcvt", "VcvtFpUIntSR", "FpRegRegOp",
931 { "code": vcvtFpUIntSRCode,
932 "predicate_test": predicateTest,
933 "op_class": "SimdFloatCvtOp" }, [])
934 header_output += FpRegRegOpDeclare.subst(vcvtFpUIntSRIop);
935 decoder_output += FpRegRegOpConstructor.subst(vcvtFpUIntSRIop);
936 exec_output += PredOpExecute.subst(vcvtFpUIntSRIop);
937
938 vcvtFpUIntDRCode = vfpEnabledCheckCode + '''
939 FPSCR fpscr = (FPSCR) FpscrExc;
940 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
941 vfpFlushToZero(fpscr, cOp1);
942 VfpSavedState state = prepFpState(fpscr.rMode);
943 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
944 uint64_t result = vfpFpToFixed<double>(cOp1, false, 32, 0, false);
945 __asm__ __volatile__("" :: "m" (result));
946 finishVfp(fpscr, state, fpscr.fz);
947 FpDestP0_uw = result;
948 FpscrExc = fpscr;
949 '''
950 vcvtFpUIntDRIop = InstObjParams("vcvtr", "VcvtFpUIntDR", "FpRegRegOp",
951 { "code": vcvtFpUIntDRCode,
952 "predicate_test": predicateTest,
953 "op_class": "SimdFloatCvtOp" }, [])
954 header_output += FpRegRegOpDeclare.subst(vcvtFpUIntDRIop);
955 decoder_output += FpRegRegOpConstructor.subst(vcvtFpUIntDRIop);
956 exec_output += PredOpExecute.subst(vcvtFpUIntDRIop);
957
958 vcvtFpSIntSRCode = vfpEnabledCheckCode + '''
959 FPSCR fpscr = (FPSCR) FpscrExc;
960 VfpSavedState state = prepFpState(fpscr.rMode);
961 vfpFlushToZero(fpscr, FpOp1);
962 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
963 FpDest_sw = vfpFpToFixed<float>(FpOp1, true, 32, 0, false);
964 __asm__ __volatile__("" :: "m" (FpDest_sw));
965 finishVfp(fpscr, state, fpscr.fz);
966 FpscrExc = fpscr;
967 '''
968 vcvtFpSIntSRIop = InstObjParams("vcvtr", "VcvtFpSIntSR", "FpRegRegOp",
969 { "code": vcvtFpSIntSRCode,
970 "predicate_test": predicateTest,
971 "op_class": "SimdFloatCvtOp" }, [])
972 header_output += FpRegRegOpDeclare.subst(vcvtFpSIntSRIop);
973 decoder_output += FpRegRegOpConstructor.subst(vcvtFpSIntSRIop);
974 exec_output += PredOpExecute.subst(vcvtFpSIntSRIop);
975
976 vcvtFpSIntDRCode = vfpEnabledCheckCode + '''
977 FPSCR fpscr = (FPSCR) FpscrExc;
978 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
979 vfpFlushToZero(fpscr, cOp1);
980 VfpSavedState state = prepFpState(fpscr.rMode);
981 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
982 int64_t result = vfpFpToFixed<double>(cOp1, true, 32, 0, false);
983 __asm__ __volatile__("" :: "m" (result));
984 finishVfp(fpscr, state, fpscr.fz);
985 FpDestP0_uw = result;
986 FpscrExc = fpscr;
987 '''
988 vcvtFpSIntDRIop = InstObjParams("vcvtr", "VcvtFpSIntDR", "FpRegRegOp",
989 { "code": vcvtFpSIntDRCode,
990 "predicate_test": predicateTest,
991 "op_class": "SimdFloatCvtOp" }, [])
992 header_output += FpRegRegOpDeclare.subst(vcvtFpSIntDRIop);
993 decoder_output += FpRegRegOpConstructor.subst(vcvtFpSIntDRIop);
994 exec_output += PredOpExecute.subst(vcvtFpSIntDRIop);
995
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 buildUnaryFpOp(name, Name, base, opClass, singleOp, doubleOp = None):
582 if doubleOp is None:
583 doubleOp = singleOp
584 global header_output, decoder_output, exec_output
585
586 code = singleCode % { "op": singleUnaryOp }
587 code = code % { "func": singleOp }
588 sIop = InstObjParams(name + "s", Name + "S", base,
589 { "code": code,
590 "predicate_test": predicateTest,
591 "op_class": opClass }, [])
592 code = doubleCode % { "op": doubleUnaryOp }
593 code = code % { "func": doubleOp }
594 dIop = InstObjParams(name + "d", Name + "D", base,
595 { "code": code,
596 "predicate_test": predicateTest,
597 "op_class": opClass }, [])
598
599 declareTempl = eval(base + "Declare");
600 constructorTempl = eval(base + "Constructor");
601
602 for iop in sIop, dIop:
603 header_output += declareTempl.subst(iop)
604 decoder_output += constructorTempl.subst(iop)
605 exec_output += PredOpExecute.subst(iop)
606
607 buildUnaryFpOp("vsqrt", "Vsqrt", "FpRegRegOp", "SimdFloatSqrtOp", "sqrtf",
608 "sqrt")
609
610 def buildSimpleUnaryFpOp(name, Name, base, opClass, singleOp,
611 doubleOp = None):
612 if doubleOp is None:
613 doubleOp = singleOp
614 global header_output, decoder_output, exec_output
615
616 sIop = InstObjParams(name + "s", Name + "S", base,
617 { "code": singleSimpleCode % { "op": singleOp },
618 "predicate_test": predicateTest,
619 "op_class": opClass }, [])
620 dIop = InstObjParams(name + "d", Name + "D", base,
621 { "code": doubleCode % { "op": doubleOp },
622 "predicate_test": predicateTest,
623 "op_class": opClass }, [])
624
625 declareTempl = eval(base + "Declare");
626 constructorTempl = eval(base + "Constructor");
627
628 for iop in sIop, dIop:
629 header_output += declareTempl.subst(iop)
630 decoder_output += constructorTempl.subst(iop)
631 exec_output += PredOpExecute.subst(iop)
632
633 buildSimpleUnaryFpOp("vneg", "Vneg", "FpRegRegOp", "SimdFloatMiscOp",
634 "-FpOp1", "-dbl(FpOp1P0_uw, FpOp1P1_uw)")
635 buildSimpleUnaryFpOp("vabs", "Vabs", "FpRegRegOp", "SimdFloatMiscOp",
636 "fabsf(FpOp1)", "fabs(dbl(FpOp1P0_uw, FpOp1P1_uw))")
637 buildSimpleUnaryFpOp("vrintp", "VRIntP", "FpRegRegOp", "SimdFloatMiscOp",
638 "fplibRoundInt<uint32_t>(FpOp1, FPRounding_POSINF, false, fpscr)",
639 "fplibRoundInt<uint64_t>(dbl(FpOp1P0_uw, FpOp1P1_uw), " \
640 "FPRounding_POSINF, false, fpscr)"
641 )
642 buildSimpleUnaryFpOp("vrintm", "VRIntM", "FpRegRegOp", "SimdFloatMiscOp",
643 "fplibRoundInt<uint32_t>(FpOp1, FPRounding_NEGINF, false, fpscr)",
644 "fplibRoundInt<uint64_t>(dbl(FpOp1P0_uw, FpOp1P1_uw), " \
645 "FPRounding_NEGINF, false, fpscr)"
646 )
647 buildSimpleUnaryFpOp("vrinta", "VRIntA", "FpRegRegOp", "SimdFloatMiscOp",
648 "fplibRoundInt<uint32_t>(FpOp1, FPRounding_TIEAWAY, false, fpscr)",
649 "fplibRoundInt<uint64_t>(dbl(FpOp1P0_uw, FpOp1P1_uw), " \
650 "FPRounding_TIEAWAY, false, fpscr)"
651 )
652 buildSimpleUnaryFpOp("vrintn", "VRIntN", "FpRegRegOp", "SimdFloatMiscOp",
653 "fplibRoundInt<uint32_t>(FpOp1, FPRounding_TIEEVEN, false, fpscr)",
654 "fplibRoundInt<uint64_t>(dbl(FpOp1P0_uw, FpOp1P1_uw), " \
655 "FPRounding_TIEEVEN, false, fpscr)"
656 )
657}};
658
659let {{
660
661 header_output = ""
662 decoder_output = ""
663 exec_output = ""
664
665 vmlaSCode = vfpEnabledCheckCode + '''
666 FPSCR fpscr = (FPSCR) FpscrExc;
667 float mid = binaryOp(fpscr, FpOp1, FpOp2,
668 fpMulS, fpscr.fz, fpscr.dn, fpscr.rMode);
669 FpDest = binaryOp(fpscr, FpDest, mid, fpAddS,
670 fpscr.fz, fpscr.dn, fpscr.rMode);
671 FpscrExc = fpscr;
672 '''
673 vmlaSIop = InstObjParams("vmlas", "VmlaS", "FpRegRegRegOp",
674 { "code": vmlaSCode,
675 "predicate_test": predicateTest,
676 "op_class": "SimdFloatMultAccOp" }, [])
677 header_output += FpRegRegRegOpDeclare.subst(vmlaSIop);
678 decoder_output += FpRegRegRegOpConstructor.subst(vmlaSIop);
679 exec_output += PredOpExecute.subst(vmlaSIop);
680
681 vmlaDCode = vfpEnabledCheckCode + '''
682 FPSCR fpscr = (FPSCR) FpscrExc;
683 double mid = binaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw),
684 dbl(FpOp2P0_uw, FpOp2P1_uw),
685 fpMulD, fpscr.fz, fpscr.dn, fpscr.rMode);
686 double dest = binaryOp(fpscr, dbl(FpDestP0_uw, FpDestP1_uw),
687 mid, fpAddD, fpscr.fz,
688 fpscr.dn, fpscr.rMode);
689 FpDestP0_uw = dblLow(dest);
690 FpDestP1_uw = dblHi(dest);
691 FpscrExc = fpscr;
692 '''
693 vmlaDIop = InstObjParams("vmlad", "VmlaD", "FpRegRegRegOp",
694 { "code": vmlaDCode,
695 "predicate_test": predicateTest,
696 "op_class": "SimdFloatMultAccOp" }, [])
697 header_output += FpRegRegRegOpDeclare.subst(vmlaDIop);
698 decoder_output += FpRegRegRegOpConstructor.subst(vmlaDIop);
699 exec_output += PredOpExecute.subst(vmlaDIop);
700
701 vmlsSCode = vfpEnabledCheckCode + '''
702 FPSCR fpscr = (FPSCR) FpscrExc;
703 float mid = binaryOp(fpscr, FpOp1, FpOp2,
704 fpMulS, fpscr.fz, fpscr.dn, fpscr.rMode);
705 FpDest = binaryOp(fpscr, FpDest, -mid, fpAddS,
706 fpscr.fz, fpscr.dn, fpscr.rMode);
707 FpscrExc = fpscr;
708 '''
709 vmlsSIop = InstObjParams("vmlss", "VmlsS", "FpRegRegRegOp",
710 { "code": vmlsSCode,
711 "predicate_test": predicateTest,
712 "op_class": "SimdFloatMultAccOp" }, [])
713 header_output += FpRegRegRegOpDeclare.subst(vmlsSIop);
714 decoder_output += FpRegRegRegOpConstructor.subst(vmlsSIop);
715 exec_output += PredOpExecute.subst(vmlsSIop);
716
717 vmlsDCode = vfpEnabledCheckCode + '''
718 FPSCR fpscr = (FPSCR) FpscrExc;
719 double mid = binaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw),
720 dbl(FpOp2P0_uw, FpOp2P1_uw),
721 fpMulD, fpscr.fz, fpscr.dn, fpscr.rMode);
722 double dest = binaryOp(fpscr, dbl(FpDestP0_uw, FpDestP1_uw),
723 -mid, fpAddD, fpscr.fz,
724 fpscr.dn, fpscr.rMode);
725 FpDestP0_uw = dblLow(dest);
726 FpDestP1_uw = dblHi(dest);
727 FpscrExc = fpscr;
728 '''
729 vmlsDIop = InstObjParams("vmlsd", "VmlsD", "FpRegRegRegOp",
730 { "code": vmlsDCode,
731 "predicate_test": predicateTest,
732 "op_class": "SimdFloatMultAccOp" }, [])
733 header_output += FpRegRegRegOpDeclare.subst(vmlsDIop);
734 decoder_output += FpRegRegRegOpConstructor.subst(vmlsDIop);
735 exec_output += PredOpExecute.subst(vmlsDIop);
736
737 vnmlaSCode = vfpEnabledCheckCode + '''
738 FPSCR fpscr = (FPSCR) FpscrExc;
739 float mid = binaryOp(fpscr, FpOp1, FpOp2,
740 fpMulS, fpscr.fz, fpscr.dn, fpscr.rMode);
741 FpDest = binaryOp(fpscr, -FpDest, -mid, fpAddS,
742 fpscr.fz, fpscr.dn, fpscr.rMode);
743 FpscrExc = fpscr;
744 '''
745 vnmlaSIop = InstObjParams("vnmlas", "VnmlaS", "FpRegRegRegOp",
746 { "code": vnmlaSCode,
747 "predicate_test": predicateTest,
748 "op_class": "SimdFloatMultAccOp" }, [])
749 header_output += FpRegRegRegOpDeclare.subst(vnmlaSIop);
750 decoder_output += FpRegRegRegOpConstructor.subst(vnmlaSIop);
751 exec_output += PredOpExecute.subst(vnmlaSIop);
752
753 vnmlaDCode = vfpEnabledCheckCode + '''
754 FPSCR fpscr = (FPSCR) FpscrExc;
755 double mid = binaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw),
756 dbl(FpOp2P0_uw, FpOp2P1_uw),
757 fpMulD, fpscr.fz, fpscr.dn, fpscr.rMode);
758 double dest = binaryOp(fpscr, -dbl(FpDestP0_uw, FpDestP1_uw),
759 -mid, fpAddD, fpscr.fz,
760 fpscr.dn, fpscr.rMode);
761 FpDestP0_uw = dblLow(dest);
762 FpDestP1_uw = dblHi(dest);
763 FpscrExc = fpscr;
764 '''
765 vnmlaDIop = InstObjParams("vnmlad", "VnmlaD", "FpRegRegRegOp",
766 { "code": vnmlaDCode,
767 "predicate_test": predicateTest,
768 "op_class": "SimdFloatMultAccOp" }, [])
769 header_output += FpRegRegRegOpDeclare.subst(vnmlaDIop);
770 decoder_output += FpRegRegRegOpConstructor.subst(vnmlaDIop);
771 exec_output += PredOpExecute.subst(vnmlaDIop);
772
773 vnmlsSCode = vfpEnabledCheckCode + '''
774 FPSCR fpscr = (FPSCR) FpscrExc;
775 float mid = binaryOp(fpscr, FpOp1, FpOp2,
776 fpMulS, fpscr.fz, fpscr.dn, fpscr.rMode);
777 FpDest = binaryOp(fpscr, -FpDest, mid, fpAddS,
778 fpscr.fz, fpscr.dn, fpscr.rMode);
779 FpscrExc = fpscr;
780 '''
781 vnmlsSIop = InstObjParams("vnmlss", "VnmlsS", "FpRegRegRegOp",
782 { "code": vnmlsSCode,
783 "predicate_test": predicateTest,
784 "op_class": "SimdFloatMultAccOp" }, [])
785 header_output += FpRegRegRegOpDeclare.subst(vnmlsSIop);
786 decoder_output += FpRegRegRegOpConstructor.subst(vnmlsSIop);
787 exec_output += PredOpExecute.subst(vnmlsSIop);
788
789 vnmlsDCode = vfpEnabledCheckCode + '''
790 FPSCR fpscr = (FPSCR) FpscrExc;
791 double mid = binaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw),
792 dbl(FpOp2P0_uw, FpOp2P1_uw),
793 fpMulD, fpscr.fz, fpscr.dn, fpscr.rMode);
794 double dest = binaryOp(fpscr, -dbl(FpDestP0_uw, FpDestP1_uw),
795 mid, fpAddD, fpscr.fz,
796 fpscr.dn, fpscr.rMode);
797 FpDestP0_uw = dblLow(dest);
798 FpDestP1_uw = dblHi(dest);
799 FpscrExc = fpscr;
800 '''
801 vnmlsDIop = InstObjParams("vnmlsd", "VnmlsD", "FpRegRegRegOp",
802 { "code": vnmlsDCode,
803 "predicate_test": predicateTest,
804 "op_class": "SimdFloatMultAccOp" }, [])
805 header_output += FpRegRegRegOpDeclare.subst(vnmlsDIop);
806 decoder_output += FpRegRegRegOpConstructor.subst(vnmlsDIop);
807 exec_output += PredOpExecute.subst(vnmlsDIop);
808
809 vnmulSCode = vfpEnabledCheckCode + '''
810 FPSCR fpscr = (FPSCR) FpscrExc;
811 FpDest = -binaryOp(fpscr, FpOp1, FpOp2, fpMulS,
812 fpscr.fz, fpscr.dn, fpscr.rMode);
813 FpscrExc = fpscr;
814 '''
815 vnmulSIop = InstObjParams("vnmuls", "VnmulS", "FpRegRegRegOp",
816 { "code": vnmulSCode,
817 "predicate_test": predicateTest,
818 "op_class": "SimdFloatMultOp" }, [])
819 header_output += FpRegRegRegOpDeclare.subst(vnmulSIop);
820 decoder_output += FpRegRegRegOpConstructor.subst(vnmulSIop);
821 exec_output += PredOpExecute.subst(vnmulSIop);
822
823 vnmulDCode = vfpEnabledCheckCode + '''
824 FPSCR fpscr = (FPSCR) FpscrExc;
825 double dest = -binaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw),
826 dbl(FpOp2P0_uw, FpOp2P1_uw),
827 fpMulD, fpscr.fz, fpscr.dn,
828 fpscr.rMode);
829 FpDestP0_uw = dblLow(dest);
830 FpDestP1_uw = dblHi(dest);
831 FpscrExc = fpscr;
832 '''
833 vnmulDIop = InstObjParams("vnmuld", "VnmulD", "FpRegRegRegOp",
834 { "code": vnmulDCode,
835 "predicate_test": predicateTest,
836 "op_class": "SimdFloatMultOp" }, [])
837 header_output += FpRegRegRegOpDeclare.subst(vnmulDIop);
838 decoder_output += FpRegRegRegOpConstructor.subst(vnmulDIop);
839 exec_output += PredOpExecute.subst(vnmulDIop);
840}};
841
842let {{
843
844 header_output = ""
845 decoder_output = ""
846 exec_output = ""
847
848 vcvtUIntFpSCode = vfpEnabledCheckCode + '''
849 FPSCR fpscr = (FPSCR) FpscrExc;
850 VfpSavedState state = prepFpState(fpscr.rMode);
851 __asm__ __volatile__("" : "=m" (FpOp1_uw) : "m" (FpOp1_uw));
852 FpDest = FpOp1_uw;
853 __asm__ __volatile__("" :: "m" (FpDest));
854 finishVfp(fpscr, state, fpscr.fz);
855 FpscrExc = fpscr;
856 '''
857 vcvtUIntFpSIop = InstObjParams("vcvt", "VcvtUIntFpS", "FpRegRegOp",
858 { "code": vcvtUIntFpSCode,
859 "predicate_test": predicateTest,
860 "op_class": "SimdFloatCvtOp" }, [])
861 header_output += FpRegRegOpDeclare.subst(vcvtUIntFpSIop);
862 decoder_output += FpRegRegOpConstructor.subst(vcvtUIntFpSIop);
863 exec_output += PredOpExecute.subst(vcvtUIntFpSIop);
864
865 vcvtUIntFpDCode = vfpEnabledCheckCode + '''
866 FPSCR fpscr = (FPSCR) FpscrExc;
867 VfpSavedState state = prepFpState(fpscr.rMode);
868 __asm__ __volatile__("" : "=m" (FpOp1P0_uw) : "m" (FpOp1P0_uw));
869 double cDest = (uint64_t)FpOp1P0_uw;
870 __asm__ __volatile__("" :: "m" (cDest));
871 finishVfp(fpscr, state, fpscr.fz);
872 FpDestP0_uw = dblLow(cDest);
873 FpDestP1_uw = dblHi(cDest);
874 FpscrExc = fpscr;
875 '''
876 vcvtUIntFpDIop = InstObjParams("vcvt", "VcvtUIntFpD", "FpRegRegOp",
877 { "code": vcvtUIntFpDCode,
878 "predicate_test": predicateTest,
879 "op_class": "SimdFloatCvtOp" }, [])
880 header_output += FpRegRegOpDeclare.subst(vcvtUIntFpDIop);
881 decoder_output += FpRegRegOpConstructor.subst(vcvtUIntFpDIop);
882 exec_output += PredOpExecute.subst(vcvtUIntFpDIop);
883
884 vcvtSIntFpSCode = vfpEnabledCheckCode + '''
885 FPSCR fpscr = (FPSCR) FpscrExc;
886 VfpSavedState state = prepFpState(fpscr.rMode);
887 __asm__ __volatile__("" : "=m" (FpOp1_sw) : "m" (FpOp1_sw));
888 FpDest = FpOp1_sw;
889 __asm__ __volatile__("" :: "m" (FpDest));
890 finishVfp(fpscr, state, fpscr.fz);
891 FpscrExc = fpscr;
892 '''
893 vcvtSIntFpSIop = InstObjParams("vcvt", "VcvtSIntFpS", "FpRegRegOp",
894 { "code": vcvtSIntFpSCode,
895 "predicate_test": predicateTest,
896 "op_class": "SimdFloatCvtOp" }, [])
897 header_output += FpRegRegOpDeclare.subst(vcvtSIntFpSIop);
898 decoder_output += FpRegRegOpConstructor.subst(vcvtSIntFpSIop);
899 exec_output += PredOpExecute.subst(vcvtSIntFpSIop);
900
901 vcvtSIntFpDCode = vfpEnabledCheckCode + '''
902 FPSCR fpscr = (FPSCR) FpscrExc;
903 VfpSavedState state = prepFpState(fpscr.rMode);
904 __asm__ __volatile__("" : "=m" (FpOp1P0_sw) : "m" (FpOp1P0_sw));
905 double cDest = FpOp1P0_sw;
906 __asm__ __volatile__("" :: "m" (cDest));
907 finishVfp(fpscr, state, fpscr.fz);
908 FpDestP0_uw = dblLow(cDest);
909 FpDestP1_uw = dblHi(cDest);
910 FpscrExc = fpscr;
911 '''
912 vcvtSIntFpDIop = InstObjParams("vcvt", "VcvtSIntFpD", "FpRegRegOp",
913 { "code": vcvtSIntFpDCode,
914 "predicate_test": predicateTest,
915 "op_class": "SimdFloatCvtOp" }, [])
916 header_output += FpRegRegOpDeclare.subst(vcvtSIntFpDIop);
917 decoder_output += FpRegRegOpConstructor.subst(vcvtSIntFpDIop);
918 exec_output += PredOpExecute.subst(vcvtSIntFpDIop);
919
920 vcvtFpUIntSRCode = vfpEnabledCheckCode + '''
921 FPSCR fpscr = (FPSCR) FpscrExc;
922 VfpSavedState state = prepFpState(fpscr.rMode);
923 vfpFlushToZero(fpscr, FpOp1);
924 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
925 FpDest_uw = vfpFpToFixed<float>(FpOp1, false, 32, 0, false);
926 __asm__ __volatile__("" :: "m" (FpDest_uw));
927 finishVfp(fpscr, state, fpscr.fz);
928 FpscrExc = fpscr;
929 '''
930 vcvtFpUIntSRIop = InstObjParams("vcvt", "VcvtFpUIntSR", "FpRegRegOp",
931 { "code": vcvtFpUIntSRCode,
932 "predicate_test": predicateTest,
933 "op_class": "SimdFloatCvtOp" }, [])
934 header_output += FpRegRegOpDeclare.subst(vcvtFpUIntSRIop);
935 decoder_output += FpRegRegOpConstructor.subst(vcvtFpUIntSRIop);
936 exec_output += PredOpExecute.subst(vcvtFpUIntSRIop);
937
938 vcvtFpUIntDRCode = vfpEnabledCheckCode + '''
939 FPSCR fpscr = (FPSCR) FpscrExc;
940 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
941 vfpFlushToZero(fpscr, cOp1);
942 VfpSavedState state = prepFpState(fpscr.rMode);
943 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
944 uint64_t result = vfpFpToFixed<double>(cOp1, false, 32, 0, false);
945 __asm__ __volatile__("" :: "m" (result));
946 finishVfp(fpscr, state, fpscr.fz);
947 FpDestP0_uw = result;
948 FpscrExc = fpscr;
949 '''
950 vcvtFpUIntDRIop = InstObjParams("vcvtr", "VcvtFpUIntDR", "FpRegRegOp",
951 { "code": vcvtFpUIntDRCode,
952 "predicate_test": predicateTest,
953 "op_class": "SimdFloatCvtOp" }, [])
954 header_output += FpRegRegOpDeclare.subst(vcvtFpUIntDRIop);
955 decoder_output += FpRegRegOpConstructor.subst(vcvtFpUIntDRIop);
956 exec_output += PredOpExecute.subst(vcvtFpUIntDRIop);
957
958 vcvtFpSIntSRCode = vfpEnabledCheckCode + '''
959 FPSCR fpscr = (FPSCR) FpscrExc;
960 VfpSavedState state = prepFpState(fpscr.rMode);
961 vfpFlushToZero(fpscr, FpOp1);
962 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
963 FpDest_sw = vfpFpToFixed<float>(FpOp1, true, 32, 0, false);
964 __asm__ __volatile__("" :: "m" (FpDest_sw));
965 finishVfp(fpscr, state, fpscr.fz);
966 FpscrExc = fpscr;
967 '''
968 vcvtFpSIntSRIop = InstObjParams("vcvtr", "VcvtFpSIntSR", "FpRegRegOp",
969 { "code": vcvtFpSIntSRCode,
970 "predicate_test": predicateTest,
971 "op_class": "SimdFloatCvtOp" }, [])
972 header_output += FpRegRegOpDeclare.subst(vcvtFpSIntSRIop);
973 decoder_output += FpRegRegOpConstructor.subst(vcvtFpSIntSRIop);
974 exec_output += PredOpExecute.subst(vcvtFpSIntSRIop);
975
976 vcvtFpSIntDRCode = vfpEnabledCheckCode + '''
977 FPSCR fpscr = (FPSCR) FpscrExc;
978 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
979 vfpFlushToZero(fpscr, cOp1);
980 VfpSavedState state = prepFpState(fpscr.rMode);
981 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
982 int64_t result = vfpFpToFixed<double>(cOp1, true, 32, 0, false);
983 __asm__ __volatile__("" :: "m" (result));
984 finishVfp(fpscr, state, fpscr.fz);
985 FpDestP0_uw = result;
986 FpscrExc = fpscr;
987 '''
988 vcvtFpSIntDRIop = InstObjParams("vcvtr", "VcvtFpSIntDR", "FpRegRegOp",
989 { "code": vcvtFpSIntDRCode,
990 "predicate_test": predicateTest,
991 "op_class": "SimdFloatCvtOp" }, [])
992 header_output += FpRegRegOpDeclare.subst(vcvtFpSIntDRIop);
993 decoder_output += FpRegRegOpConstructor.subst(vcvtFpSIntDRIop);
994 exec_output += PredOpExecute.subst(vcvtFpSIntDRIop);
995
996 vcvtFpUIntSCode = vfpEnabledCheckCode + '''
996 round_mode_suffix_to_mode = {
997 '': 'VfpRoundZero',
998 'a': 'VfpRoundAway',
999 'm': 'VfpRoundDown',
1000 'n': 'VfpRoundNearest',
1001 'p': 'VfpRoundUpward',
1002 }
1003
1004 def buildVcvt(code, className, roundModeSuffix):
1005 global header_output, decoder_output, exec_output, \
1006 vfpEnabledCheckCode, round_mode_suffix_to_mode
1007 full_code = vfpEnabledCheckCode + code.format(
1008 round_mode=round_mode_suffix_to_mode[roundModeSuffix],
1009 )
1010 iop = InstObjParams(
1011 "vcvt{}".format(roundModeSuffix),
1012 className.format(roundModeSuffix),
1013 "FpRegRegOp",
1014 { "code": full_code,
1015 "predicate_test": predicateTest,
1016 "op_class": "SimdFloatCvtOp" },
1017 []
1018 )
1019 header_output += FpRegRegOpDeclare.subst(iop);
1020 decoder_output += FpRegRegOpConstructor.subst(iop);
1021 exec_output += PredOpExecute.subst(iop);
1022
1023 code = '''
997 FPSCR fpscr = (FPSCR) FpscrExc;
998 vfpFlushToZero(fpscr, FpOp1);
999 VfpSavedState state = prepFpState(fpscr.rMode);
1000 fesetround(FeRoundZero);
1001 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1024 FPSCR fpscr = (FPSCR) FpscrExc;
1025 vfpFlushToZero(fpscr, FpOp1);
1026 VfpSavedState state = prepFpState(fpscr.rMode);
1027 fesetround(FeRoundZero);
1028 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1002 FpDest_uw = vfpFpToFixed<float>(FpOp1, false, 32, 0);
1029 FpDest_uw = vfpFpToFixed(
1030 FpOp1, false, 32, 0, true, {round_mode});
1003 __asm__ __volatile__("" :: "m" (FpDest_uw));
1004 finishVfp(fpscr, state, fpscr.fz);
1005 FpscrExc = fpscr;
1006 '''
1031 __asm__ __volatile__("" :: "m" (FpDest_uw));
1032 finishVfp(fpscr, state, fpscr.fz);
1033 FpscrExc = fpscr;
1034 '''
1007 vcvtFpUIntSIop = InstObjParams("vcvt", "VcvtFpUIntS", "FpRegRegOp",
1008 { "code": vcvtFpUIntSCode,
1009 "predicate_test": predicateTest,
1010 "op_class": "SimdFloatCvtOp" }, [])
1011 header_output += FpRegRegOpDeclare.subst(vcvtFpUIntSIop);
1012 decoder_output += FpRegRegOpConstructor.subst(vcvtFpUIntSIop);
1013 exec_output += PredOpExecute.subst(vcvtFpUIntSIop);
1035 for round_mode_suffix in round_mode_suffix_to_mode:
1036 buildVcvt(code, "Vcvt{}FpUIntS", round_mode_suffix)
1014
1037
1015 vcvtFpUIntDCode = vfpEnabledCheckCode + '''
1038 code = '''
1016 FPSCR fpscr = (FPSCR) FpscrExc;
1017 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1018 vfpFlushToZero(fpscr, cOp1);
1019 VfpSavedState state = prepFpState(fpscr.rMode);
1020 fesetround(FeRoundZero);
1021 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1039 FPSCR fpscr = (FPSCR) FpscrExc;
1040 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1041 vfpFlushToZero(fpscr, cOp1);
1042 VfpSavedState state = prepFpState(fpscr.rMode);
1043 fesetround(FeRoundZero);
1044 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1022 uint64_t result = vfpFpToFixed<double>(cOp1, false, 32, 0);
1045 uint64_t result = vfpFpToFixed(
1046 cOp1, false, 32, 0, true, {round_mode});
1023 __asm__ __volatile__("" :: "m" (result));
1024 finishVfp(fpscr, state, fpscr.fz);
1025 FpDestP0_uw = result;
1026 FpscrExc = fpscr;
1027 '''
1047 __asm__ __volatile__("" :: "m" (result));
1048 finishVfp(fpscr, state, fpscr.fz);
1049 FpDestP0_uw = result;
1050 FpscrExc = fpscr;
1051 '''
1028 vcvtFpUIntDIop = InstObjParams("vcvt", "VcvtFpUIntD", "FpRegRegOp",
1029 { "code": vcvtFpUIntDCode,
1030 "predicate_test": predicateTest,
1031 "op_class": "SimdFloatCvtOp" }, [])
1032 header_output += FpRegRegOpDeclare.subst(vcvtFpUIntDIop);
1033 decoder_output += FpRegRegOpConstructor.subst(vcvtFpUIntDIop);
1034 exec_output += PredOpExecute.subst(vcvtFpUIntDIop);
1052 for round_mode_suffix in round_mode_suffix_to_mode:
1053 buildVcvt(code, "Vcvt{}FpUIntD", round_mode_suffix)
1035
1054
1036 vcvtFpSIntSCode = vfpEnabledCheckCode + '''
1055 code = '''
1037 FPSCR fpscr = (FPSCR) FpscrExc;
1038 vfpFlushToZero(fpscr, FpOp1);
1039 VfpSavedState state = prepFpState(fpscr.rMode);
1040 fesetround(FeRoundZero);
1041 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1056 FPSCR fpscr = (FPSCR) FpscrExc;
1057 vfpFlushToZero(fpscr, FpOp1);
1058 VfpSavedState state = prepFpState(fpscr.rMode);
1059 fesetround(FeRoundZero);
1060 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1042 FpDest_sw = vfpFpToFixed<float>(FpOp1, true, 32, 0);
1061 FpDest_sw = vfpFpToFixed(
1062 FpOp1, true, 32, 0, true, {round_mode});
1043 __asm__ __volatile__("" :: "m" (FpDest_sw));
1044 finishVfp(fpscr, state, fpscr.fz);
1045 FpscrExc = fpscr;
1046 '''
1063 __asm__ __volatile__("" :: "m" (FpDest_sw));
1064 finishVfp(fpscr, state, fpscr.fz);
1065 FpscrExc = fpscr;
1066 '''
1047 vcvtFpSIntSIop = InstObjParams("vcvt", "VcvtFpSIntS", "FpRegRegOp",
1048 { "code": vcvtFpSIntSCode,
1049 "predicate_test": predicateTest,
1050 "op_class": "SimdFloatCvtOp" }, [])
1051 header_output += FpRegRegOpDeclare.subst(vcvtFpSIntSIop);
1052 decoder_output += FpRegRegOpConstructor.subst(vcvtFpSIntSIop);
1053 exec_output += PredOpExecute.subst(vcvtFpSIntSIop);
1067 for round_mode_suffix in round_mode_suffix_to_mode:
1068 buildVcvt(code, "Vcvt{}FpSIntS", round_mode_suffix)
1054
1069
1055 vcvtFpSIntDCode = vfpEnabledCheckCode + '''
1070 code = '''
1056 FPSCR fpscr = (FPSCR) FpscrExc;
1057 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1058 vfpFlushToZero(fpscr, cOp1);
1059 VfpSavedState state = prepFpState(fpscr.rMode);
1060 fesetround(FeRoundZero);
1061 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1071 FPSCR fpscr = (FPSCR) FpscrExc;
1072 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1073 vfpFlushToZero(fpscr, cOp1);
1074 VfpSavedState state = prepFpState(fpscr.rMode);
1075 fesetround(FeRoundZero);
1076 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1062 int64_t result = vfpFpToFixed<double>(cOp1, true, 32, 0);
1077 int64_t result = vfpFpToFixed(
1078 cOp1, true, 32, 0, true, {round_mode});
1063 __asm__ __volatile__("" :: "m" (result));
1064 finishVfp(fpscr, state, fpscr.fz);
1065 FpDestP0_uw = result;
1066 FpscrExc = fpscr;
1067 '''
1079 __asm__ __volatile__("" :: "m" (result));
1080 finishVfp(fpscr, state, fpscr.fz);
1081 FpDestP0_uw = result;
1082 FpscrExc = fpscr;
1083 '''
1068 vcvtFpSIntDIop = InstObjParams("vcvt", "VcvtFpSIntD", "FpRegRegOp",
1069 { "code": vcvtFpSIntDCode,
1070 "predicate_test": predicateTest,
1071 "op_class": "SimdFloatCvtOp" }, [])
1072 header_output += FpRegRegOpDeclare.subst(vcvtFpSIntDIop);
1073 decoder_output += FpRegRegOpConstructor.subst(vcvtFpSIntDIop);
1074 exec_output += PredOpExecute.subst(vcvtFpSIntDIop);
1084 for round_mode_suffix in round_mode_suffix_to_mode:
1085 buildVcvt(code, "Vcvt{}FpSIntD", round_mode_suffix)
1075
1076 vcvtFpSFpDCode = vfpEnabledCheckCode + '''
1077 FPSCR fpscr = (FPSCR) FpscrExc;
1078 vfpFlushToZero(fpscr, FpOp1);
1079 VfpSavedState state = prepFpState(fpscr.rMode);
1080 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1081 double cDest = fixFpSFpDDest(FpscrExc, FpOp1);
1082 __asm__ __volatile__("" :: "m" (cDest));
1083 finishVfp(fpscr, state, fpscr.fz);
1084 FpDestP0_uw = dblLow(cDest);
1085 FpDestP1_uw = dblHi(cDest);
1086 FpscrExc = fpscr;
1087 '''
1088 vcvtFpSFpDIop = InstObjParams("vcvt", "VcvtFpSFpD", "FpRegRegOp",
1089 { "code": vcvtFpSFpDCode,
1090 "predicate_test": predicateTest,
1091 "op_class": "SimdFloatCvtOp" }, [])
1092 header_output += FpRegRegOpDeclare.subst(vcvtFpSFpDIop);
1093 decoder_output += FpRegRegOpConstructor.subst(vcvtFpSFpDIop);
1094 exec_output += PredOpExecute.subst(vcvtFpSFpDIop);
1095
1096 vcvtFpDFpSCode = vfpEnabledCheckCode + '''
1097 FPSCR fpscr = (FPSCR) FpscrExc;
1098 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1099 vfpFlushToZero(fpscr, cOp1);
1100 VfpSavedState state = prepFpState(fpscr.rMode);
1101 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1102 FpDest = fixFpDFpSDest(FpscrExc, cOp1);
1103 __asm__ __volatile__("" :: "m" (FpDest));
1104 finishVfp(fpscr, state, fpscr.fz);
1105 FpscrExc = fpscr;
1106 '''
1107 vcvtFpDFpSIop = InstObjParams("vcvt", "VcvtFpDFpS", "FpRegRegOp",
1108 { "code": vcvtFpDFpSCode,
1109 "predicate_test": predicateTest,
1110 "op_class": "SimdFloatCvtOp" }, [])
1111 header_output += FpRegRegOpDeclare.subst(vcvtFpDFpSIop);
1112 decoder_output += FpRegRegOpConstructor.subst(vcvtFpDFpSIop);
1113 exec_output += PredOpExecute.subst(vcvtFpDFpSIop);
1114
1115 vcvtFpHTFpSCode = vfpEnabledCheckCode + '''
1116 FPSCR fpscr = (FPSCR) FpscrExc;
1117 vfpFlushToZero(fpscr, FpOp1);
1118 VfpSavedState state = prepFpState(fpscr.rMode);
1119 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1120 FpDest = vcvtFpHFpS(fpscr, fpscr.dn, fpscr.ahp,
1121 bits(fpToBits(FpOp1), 31, 16));
1122 __asm__ __volatile__("" :: "m" (FpDest));
1123 finishVfp(fpscr, state, fpscr.fz);
1124 FpscrExc = fpscr;
1125 '''
1126 vcvtFpHTFpSIop = InstObjParams("vcvtt", "VcvtFpHTFpS", "FpRegRegOp",
1127 { "code": vcvtFpHTFpSCode,
1128 "predicate_test": predicateTest,
1129 "op_class": "SimdFloatCvtOp" }, [])
1130 header_output += FpRegRegOpDeclare.subst(vcvtFpHTFpSIop);
1131 decoder_output += FpRegRegOpConstructor.subst(vcvtFpHTFpSIop);
1132 exec_output += PredOpExecute.subst(vcvtFpHTFpSIop);
1133
1134 vcvtFpHBFpSCode = vfpEnabledCheckCode + '''
1135 FPSCR fpscr = (FPSCR) FpscrExc;
1136 VfpSavedState state = prepFpState(fpscr.rMode);
1137 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1138 FpDest = vcvtFpHFpS(fpscr, fpscr.dn, fpscr.ahp,
1139 bits(fpToBits(FpOp1), 15, 0));
1140 __asm__ __volatile__("" :: "m" (FpDest));
1141 finishVfp(fpscr, state, fpscr.fz);
1142 FpscrExc = fpscr;
1143 '''
1144 vcvtFpHBFpSIop = InstObjParams("vcvtb", "VcvtFpHBFpS", "FpRegRegOp",
1145 { "code": vcvtFpHBFpSCode,
1146 "predicate_test": predicateTest,
1147 "op_class": "SimdFloatCvtOp" }, [])
1148 header_output += FpRegRegOpDeclare.subst(vcvtFpHBFpSIop);
1149 decoder_output += FpRegRegOpConstructor.subst(vcvtFpHBFpSIop);
1150 exec_output += PredOpExecute.subst(vcvtFpHBFpSIop);
1151
1152 vcvtFpSFpHTCode = vfpEnabledCheckCode + '''
1153 FPSCR fpscr = (FPSCR) FpscrExc;
1154 vfpFlushToZero(fpscr, FpOp1);
1155 VfpSavedState state = prepFpState(fpscr.rMode);
1156 __asm__ __volatile__("" : "=m" (FpOp1), "=m" (FpDest_uw)
1157 : "m" (FpOp1), "m" (FpDest_uw));
1158 FpDest_uw = insertBits(FpDest_uw, 31, 16,,
1159 vcvtFpSFpH(fpscr, fpscr.fz, fpscr.dn,
1160 fpscr.rMode, fpscr.ahp, FpOp1));
1161 __asm__ __volatile__("" :: "m" (FpDest_uw));
1162 finishVfp(fpscr, state, fpscr.fz);
1163 FpscrExc = fpscr;
1164 '''
1165 vcvtFpSFpHTIop = InstObjParams("vcvtt", "VcvtFpSFpHT", "FpRegRegOp",
1166 { "code": vcvtFpHTFpSCode,
1167 "predicate_test": predicateTest,
1168 "op_class": "SimdFloatCvtOp" }, [])
1169 header_output += FpRegRegOpDeclare.subst(vcvtFpSFpHTIop);
1170 decoder_output += FpRegRegOpConstructor.subst(vcvtFpSFpHTIop);
1171 exec_output += PredOpExecute.subst(vcvtFpSFpHTIop);
1172
1173 vcvtFpSFpHBCode = vfpEnabledCheckCode + '''
1174 FPSCR fpscr = (FPSCR) FpscrExc;
1175 vfpFlushToZero(fpscr, FpOp1);
1176 VfpSavedState state = prepFpState(fpscr.rMode);
1177 __asm__ __volatile__("" : "=m" (FpOp1), "=m" (FpDest_uw)
1178 : "m" (FpOp1), "m" (FpDest_uw));
1179 FpDest_uw = insertBits(FpDest_uw, 15, 0,
1180 vcvtFpSFpH(fpscr, fpscr.fz, fpscr.dn,
1181 fpscr.rMode, fpscr.ahp, FpOp1));
1182 __asm__ __volatile__("" :: "m" (FpDest_uw));
1183 finishVfp(fpscr, state, fpscr.fz);
1184 FpscrExc = fpscr;
1185 '''
1186 vcvtFpSFpHBIop = InstObjParams("vcvtb", "VcvtFpSFpHB", "FpRegRegOp",
1187 { "code": vcvtFpSFpHBCode,
1188 "predicate_test": predicateTest,
1189 "op_class": "SimdFloatCvtOp" }, [])
1190 header_output += FpRegRegOpDeclare.subst(vcvtFpSFpHBIop);
1191 decoder_output += FpRegRegOpConstructor.subst(vcvtFpSFpHBIop);
1192 exec_output += PredOpExecute.subst(vcvtFpSFpHBIop);
1193
1194 vcmpSCode = vfpEnabledCheckCode + '''
1195 FPSCR fpscr = (FPSCR) FpscrExc;
1196 vfpFlushToZero(fpscr, FpDest, FpOp1);
1197 if (FpDest == FpOp1) {
1198 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1199 } else if (FpDest < FpOp1) {
1200 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1201 } else if (FpDest > FpOp1) {
1202 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1203 } else {
1204 const uint32_t qnan = 0x7fc00000;
1205 const bool nan1 = std::isnan(FpDest);
1206 const bool signal1 = nan1 && ((fpToBits(FpDest) & qnan) != qnan);
1207 const bool nan2 = std::isnan(FpOp1);
1208 const bool signal2 = nan2 && ((fpToBits(FpOp1) & qnan) != qnan);
1209 if (signal1 || signal2)
1210 fpscr.ioc = 1;
1211 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1212 }
1213 FpCondCodes = fpscr & FpCondCodesMask;
1214 FpscrExc = fpscr;
1215 '''
1216 vcmpSIop = InstObjParams("vcmps", "VcmpS", "FpRegRegOp",
1217 { "code": vcmpSCode,
1218 "predicate_test": predicateTest,
1219 "op_class": "SimdFloatCmpOp" }, [])
1220 header_output += FpRegRegOpDeclare.subst(vcmpSIop);
1221 decoder_output += FpRegRegOpConstructor.subst(vcmpSIop);
1222 exec_output += PredOpExecute.subst(vcmpSIop);
1223
1224 vcmpDCode = vfpEnabledCheckCode + '''
1225 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1226 double cDest = dbl(FpDestP0_uw, FpDestP1_uw);
1227 FPSCR fpscr = (FPSCR) FpscrExc;
1228 vfpFlushToZero(fpscr, cDest, cOp1);
1229 if (cDest == cOp1) {
1230 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1231 } else if (cDest < cOp1) {
1232 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1233 } else if (cDest > cOp1) {
1234 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1235 } else {
1236 const uint64_t qnan = ULL(0x7ff8000000000000);
1237 const bool nan1 = std::isnan(cDest);
1238 const bool signal1 = nan1 && ((fpToBits(cDest) & qnan) != qnan);
1239 const bool nan2 = std::isnan(cOp1);
1240 const bool signal2 = nan2 && ((fpToBits(cOp1) & qnan) != qnan);
1241 if (signal1 || signal2)
1242 fpscr.ioc = 1;
1243 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1244 }
1245 FpCondCodes = fpscr & FpCondCodesMask;
1246 FpscrExc = fpscr;
1247 '''
1248 vcmpDIop = InstObjParams("vcmpd", "VcmpD", "FpRegRegOp",
1249 { "code": vcmpDCode,
1250 "predicate_test": predicateTest,
1251 "op_class": "SimdFloatCmpOp" }, [])
1252 header_output += FpRegRegOpDeclare.subst(vcmpDIop);
1253 decoder_output += FpRegRegOpConstructor.subst(vcmpDIop);
1254 exec_output += PredOpExecute.subst(vcmpDIop);
1255
1256 vcmpZeroSCode = vfpEnabledCheckCode + '''
1257 FPSCR fpscr = (FPSCR) FpscrExc;
1258 vfpFlushToZero(fpscr, FpDest);
1259 // This only handles imm == 0 for now.
1260 assert(imm == 0);
1261 if (FpDest == imm) {
1262 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1263 } else if (FpDest < imm) {
1264 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1265 } else if (FpDest > imm) {
1266 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1267 } else {
1268 const uint32_t qnan = 0x7fc00000;
1269 const bool nan = std::isnan(FpDest);
1270 const bool signal = nan && ((fpToBits(FpDest) & qnan) != qnan);
1271 if (signal)
1272 fpscr.ioc = 1;
1273 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1274 }
1275 FpCondCodes = fpscr & FpCondCodesMask;
1276 FpscrExc = fpscr;
1277 '''
1278 vcmpZeroSIop = InstObjParams("vcmpZeros", "VcmpZeroS", "FpRegImmOp",
1279 { "code": vcmpZeroSCode,
1280 "predicate_test": predicateTest,
1281 "op_class": "SimdFloatCmpOp" }, [])
1282 header_output += FpRegImmOpDeclare.subst(vcmpZeroSIop);
1283 decoder_output += FpRegImmOpConstructor.subst(vcmpZeroSIop);
1284 exec_output += PredOpExecute.subst(vcmpZeroSIop);
1285
1286 vcmpZeroDCode = vfpEnabledCheckCode + '''
1287 // This only handles imm == 0 for now.
1288 assert(imm == 0);
1289 double cDest = dbl(FpDestP0_uw, FpDestP1_uw);
1290 FPSCR fpscr = (FPSCR) FpscrExc;
1291 vfpFlushToZero(fpscr, cDest);
1292 if (cDest == imm) {
1293 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1294 } else if (cDest < imm) {
1295 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1296 } else if (cDest > imm) {
1297 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1298 } else {
1299 const uint64_t qnan = ULL(0x7ff8000000000000);
1300 const bool nan = std::isnan(cDest);
1301 const bool signal = nan && ((fpToBits(cDest) & qnan) != qnan);
1302 if (signal)
1303 fpscr.ioc = 1;
1304 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1305 }
1306 FpCondCodes = fpscr & FpCondCodesMask;
1307 FpscrExc = fpscr;
1308 '''
1309 vcmpZeroDIop = InstObjParams("vcmpZerod", "VcmpZeroD", "FpRegImmOp",
1310 { "code": vcmpZeroDCode,
1311 "predicate_test": predicateTest,
1312 "op_class": "SimdFloatCmpOp" }, [])
1313 header_output += FpRegImmOpDeclare.subst(vcmpZeroDIop);
1314 decoder_output += FpRegImmOpConstructor.subst(vcmpZeroDIop);
1315 exec_output += PredOpExecute.subst(vcmpZeroDIop);
1316
1317 vcmpeSCode = vfpEnabledCheckCode + '''
1318 FPSCR fpscr = (FPSCR) FpscrExc;
1319 vfpFlushToZero(fpscr, FpDest, FpOp1);
1320 if (FpDest == FpOp1) {
1321 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1322 } else if (FpDest < FpOp1) {
1323 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1324 } else if (FpDest > FpOp1) {
1325 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1326 } else {
1327 fpscr.ioc = 1;
1328 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1329 }
1330 FpCondCodes = fpscr & FpCondCodesMask;
1331 FpscrExc = fpscr;
1332 '''
1333 vcmpeSIop = InstObjParams("vcmpes", "VcmpeS", "FpRegRegOp",
1334 { "code": vcmpeSCode,
1335 "predicate_test": predicateTest,
1336 "op_class": "SimdFloatCmpOp" }, [])
1337 header_output += FpRegRegOpDeclare.subst(vcmpeSIop);
1338 decoder_output += FpRegRegOpConstructor.subst(vcmpeSIop);
1339 exec_output += PredOpExecute.subst(vcmpeSIop);
1340
1341 vcmpeDCode = vfpEnabledCheckCode + '''
1342 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1343 double cDest = dbl(FpDestP0_uw, FpDestP1_uw);
1344 FPSCR fpscr = (FPSCR) FpscrExc;
1345 vfpFlushToZero(fpscr, cDest, cOp1);
1346 if (cDest == cOp1) {
1347 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1348 } else if (cDest < cOp1) {
1349 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1350 } else if (cDest > cOp1) {
1351 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1352 } else {
1353 fpscr.ioc = 1;
1354 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1355 }
1356 FpCondCodes = fpscr & FpCondCodesMask;
1357 FpscrExc = fpscr;
1358 '''
1359 vcmpeDIop = InstObjParams("vcmped", "VcmpeD", "FpRegRegOp",
1360 { "code": vcmpeDCode,
1361 "predicate_test": predicateTest,
1362 "op_class": "SimdFloatCmpOp" }, [])
1363 header_output += FpRegRegOpDeclare.subst(vcmpeDIop);
1364 decoder_output += FpRegRegOpConstructor.subst(vcmpeDIop);
1365 exec_output += PredOpExecute.subst(vcmpeDIop);
1366
1367 vcmpeZeroSCode = vfpEnabledCheckCode + '''
1368 FPSCR fpscr = (FPSCR) FpscrExc;
1369 vfpFlushToZero(fpscr, FpDest);
1370 if (FpDest == imm) {
1371 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1372 } else if (FpDest < imm) {
1373 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1374 } else if (FpDest > imm) {
1375 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1376 } else {
1377 fpscr.ioc = 1;
1378 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1379 }
1380 FpCondCodes = fpscr & FpCondCodesMask;
1381 FpscrExc = fpscr;
1382 '''
1383 vcmpeZeroSIop = InstObjParams("vcmpeZeros", "VcmpeZeroS", "FpRegImmOp",
1384 { "code": vcmpeZeroSCode,
1385 "predicate_test": predicateTest,
1386 "op_class": "SimdFloatCmpOp" }, [])
1387 header_output += FpRegImmOpDeclare.subst(vcmpeZeroSIop);
1388 decoder_output += FpRegImmOpConstructor.subst(vcmpeZeroSIop);
1389 exec_output += PredOpExecute.subst(vcmpeZeroSIop);
1390
1391 vcmpeZeroDCode = vfpEnabledCheckCode + '''
1392 double cDest = dbl(FpDestP0_uw, FpDestP1_uw);
1393 FPSCR fpscr = (FPSCR) FpscrExc;
1394 vfpFlushToZero(fpscr, cDest);
1395 if (cDest == imm) {
1396 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1397 } else if (cDest < imm) {
1398 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1399 } else if (cDest > imm) {
1400 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1401 } else {
1402 fpscr.ioc = 1;
1403 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1404 }
1405 FpCondCodes = fpscr & FpCondCodesMask;
1406 FpscrExc = fpscr;
1407 '''
1408 vcmpeZeroDIop = InstObjParams("vcmpeZerod", "VcmpeZeroD", "FpRegImmOp",
1409 { "code": vcmpeZeroDCode,
1410 "predicate_test": predicateTest,
1411 "op_class": "SimdFloatCmpOp" }, [])
1412 header_output += FpRegImmOpDeclare.subst(vcmpeZeroDIop);
1413 decoder_output += FpRegImmOpConstructor.subst(vcmpeZeroDIop);
1414 exec_output += PredOpExecute.subst(vcmpeZeroDIop);
1415}};
1416
1417let {{
1418
1419 header_output = ""
1420 decoder_output = ""
1421 exec_output = ""
1422
1423 vselSCode = vfpEnabledCheckCode + '''
1424 if (testPredicate(CondCodesNZ, CondCodesC, CondCodesV, cond)) {
1425 FpDest = FpOp1;
1426 } else {
1427 FpDest = FpOp2;
1428 } '''
1429
1430 vselSIop = InstObjParams("vsels", "VselS", "FpRegRegRegCondOp",
1431 { "code" : vselSCode,
1432 "predicate_test" : predicateTest,
1433 "op_class" : "SimdFloatCmpOp" }, [] )
1434 header_output += FpRegRegRegCondOpDeclare.subst(vselSIop);
1435 decoder_output += FpRegRegRegCondOpConstructor.subst(vselSIop);
1436 exec_output += PredOpExecute.subst(vselSIop);
1437
1438 vselDCode = vfpEnabledCheckCode + '''
1439 if (testPredicate(CondCodesNZ, CondCodesC, CondCodesV, cond)) {
1440 FpDestP0_uw = FpOp1P0_uw;
1441 FpDestP1_uw = FpOp1P1_uw;
1442 } else {
1443 FpDestP0_uw = FpOp2P0_uw;
1444 FpDestP1_uw = FpOp2P1_uw;
1445 } '''
1446
1447 vselDIop = InstObjParams("vseld", "VselD", "FpRegRegRegCondOp",
1448 { "code" : vselDCode,
1449 "predicate_test" : predicateTest,
1450 "op_class" : "SimdFloatCmpOp" }, [] )
1451 header_output += FpRegRegRegCondOpDeclare.subst(vselDIop);
1452 decoder_output += FpRegRegRegCondOpConstructor.subst(vselDIop);
1453 exec_output += PredOpExecute.subst(vselDIop);
1454}};
1455
1456
1457let {{
1458
1459 header_output = ""
1460 decoder_output = ""
1461 exec_output = ""
1462
1463 vcvtFpSFixedSCode = vfpEnabledCheckCode + '''
1464 FPSCR fpscr = (FPSCR) FpscrExc;
1465 vfpFlushToZero(fpscr, FpOp1);
1466 VfpSavedState state = prepFpState(fpscr.rMode);
1467 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1468 FpDest_sw = vfpFpToFixed<float>(FpOp1, true, 32, imm);
1469 __asm__ __volatile__("" :: "m" (FpDest_sw));
1470 finishVfp(fpscr, state, fpscr.fz);
1471 FpscrExc = fpscr;
1472 '''
1473 vcvtFpSFixedSIop = InstObjParams("vcvt", "VcvtFpSFixedS", "FpRegRegImmOp",
1474 { "code": vcvtFpSFixedSCode,
1475 "predicate_test": predicateTest,
1476 "op_class": "SimdFloatCvtOp" }, [])
1477 header_output += FpRegRegImmOpDeclare.subst(vcvtFpSFixedSIop);
1478 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSFixedSIop);
1479 exec_output += PredOpExecute.subst(vcvtFpSFixedSIop);
1480
1481 vcvtFpSFixedDCode = vfpEnabledCheckCode + '''
1482 FPSCR fpscr = (FPSCR) FpscrExc;
1483 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1484 vfpFlushToZero(fpscr, cOp1);
1485 VfpSavedState state = prepFpState(fpscr.rMode);
1486 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1487 uint64_t mid = vfpFpToFixed<double>(cOp1, true, 32, imm);
1488 __asm__ __volatile__("" :: "m" (mid));
1489 finishVfp(fpscr, state, fpscr.fz);
1490 FpDestP0_uw = mid;
1491 FpDestP1_uw = mid >> 32;
1492 FpscrExc = fpscr;
1493 '''
1494 vcvtFpSFixedDIop = InstObjParams("vcvt", "VcvtFpSFixedD", "FpRegRegImmOp",
1495 { "code": vcvtFpSFixedDCode,
1496 "predicate_test": predicateTest,
1497 "op_class": "SimdFloatCvtOp" }, [])
1498 header_output += FpRegRegImmOpDeclare.subst(vcvtFpSFixedDIop);
1499 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSFixedDIop);
1500 exec_output += PredOpExecute.subst(vcvtFpSFixedDIop);
1501
1502 vcvtFpUFixedSCode = vfpEnabledCheckCode + '''
1503 FPSCR fpscr = (FPSCR) FpscrExc;
1504 vfpFlushToZero(fpscr, FpOp1);
1505 VfpSavedState state = prepFpState(fpscr.rMode);
1506 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1507 FpDest_uw = vfpFpToFixed<float>(FpOp1, false, 32, imm);
1508 __asm__ __volatile__("" :: "m" (FpDest_uw));
1509 finishVfp(fpscr, state, fpscr.fz);
1510 FpscrExc = fpscr;
1511 '''
1512 vcvtFpUFixedSIop = InstObjParams("vcvt", "VcvtFpUFixedS", "FpRegRegImmOp",
1513 { "code": vcvtFpUFixedSCode,
1514 "predicate_test": predicateTest,
1515 "op_class": "SimdFloatCvtOp" }, [])
1516 header_output += FpRegRegImmOpDeclare.subst(vcvtFpUFixedSIop);
1517 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUFixedSIop);
1518 exec_output += PredOpExecute.subst(vcvtFpUFixedSIop);
1519
1520 vcvtFpUFixedDCode = vfpEnabledCheckCode + '''
1521 FPSCR fpscr = (FPSCR) FpscrExc;
1522 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1523 vfpFlushToZero(fpscr, cOp1);
1524 VfpSavedState state = prepFpState(fpscr.rMode);
1525 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1526 uint64_t mid = vfpFpToFixed<double>(cOp1, false, 32, imm);
1527 __asm__ __volatile__("" :: "m" (mid));
1528 finishVfp(fpscr, state, fpscr.fz);
1529 FpDestP0_uw = mid;
1530 FpDestP1_uw = mid >> 32;
1531 FpscrExc = fpscr;
1532 '''
1533 vcvtFpUFixedDIop = InstObjParams("vcvt", "VcvtFpUFixedD", "FpRegRegImmOp",
1534 { "code": vcvtFpUFixedDCode,
1535 "predicate_test": predicateTest,
1536 "op_class": "SimdFloatCvtOp" }, [])
1537 header_output += FpRegRegImmOpDeclare.subst(vcvtFpUFixedDIop);
1538 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUFixedDIop);
1539 exec_output += PredOpExecute.subst(vcvtFpUFixedDIop);
1540
1541 vcvtSFixedFpSCode = vfpEnabledCheckCode + '''
1542 FPSCR fpscr = (FPSCR) FpscrExc;
1543 VfpSavedState state = prepFpState(fpscr.rMode);
1544 __asm__ __volatile__("" : "=m" (FpOp1_sw) : "m" (FpOp1_sw));
1545 FpDest = vfpSFixedToFpS(fpscr.fz, fpscr.dn, FpOp1_sw, 32, imm);
1546 __asm__ __volatile__("" :: "m" (FpDest));
1547 finishVfp(fpscr, state, fpscr.fz);
1548 FpscrExc = fpscr;
1549 '''
1550 vcvtSFixedFpSIop = InstObjParams("vcvt", "VcvtSFixedFpS", "FpRegRegImmOp",
1551 { "code": vcvtSFixedFpSCode,
1552 "predicate_test": predicateTest,
1553 "op_class": "SimdFloatCvtOp" }, [])
1554 header_output += FpRegRegImmOpDeclare.subst(vcvtSFixedFpSIop);
1555 decoder_output += FpRegRegImmOpConstructor.subst(vcvtSFixedFpSIop);
1556 exec_output += PredOpExecute.subst(vcvtSFixedFpSIop);
1557
1558 vcvtSFixedFpDCode = vfpEnabledCheckCode + '''
1559 FPSCR fpscr = (FPSCR) FpscrExc;
1560 uint64_t mid = ((uint64_t)FpOp1P0_uw | ((uint64_t)FpOp1P1_uw << 32));
1561 VfpSavedState state = prepFpState(fpscr.rMode);
1562 __asm__ __volatile__("" : "=m" (mid) : "m" (mid));
1563 double cDest = vfpSFixedToFpD(fpscr.fz, fpscr.dn, mid, 32, imm);
1564 __asm__ __volatile__("" :: "m" (cDest));
1565 finishVfp(fpscr, state, fpscr.fz);
1566 FpDestP0_uw = dblLow(cDest);
1567 FpDestP1_uw = dblHi(cDest);
1568 FpscrExc = fpscr;
1569 '''
1570 vcvtSFixedFpDIop = InstObjParams("vcvt", "VcvtSFixedFpD", "FpRegRegImmOp",
1571 { "code": vcvtSFixedFpDCode,
1572 "predicate_test": predicateTest,
1573 "op_class": "SimdFloatCvtOp" }, [])
1574 header_output += FpRegRegImmOpDeclare.subst(vcvtSFixedFpDIop);
1575 decoder_output += FpRegRegImmOpConstructor.subst(vcvtSFixedFpDIop);
1576 exec_output += PredOpExecute.subst(vcvtSFixedFpDIop);
1577
1578 vcvtUFixedFpSCode = vfpEnabledCheckCode + '''
1579 FPSCR fpscr = (FPSCR) FpscrExc;
1580 VfpSavedState state = prepFpState(fpscr.rMode);
1581 __asm__ __volatile__("" : "=m" (FpOp1_uw) : "m" (FpOp1_uw));
1582 FpDest = vfpUFixedToFpS(fpscr.fz, fpscr.dn, FpOp1_uw, 32, imm);
1583 __asm__ __volatile__("" :: "m" (FpDest));
1584 finishVfp(fpscr, state, fpscr.fz);
1585 FpscrExc = fpscr;
1586 '''
1587 vcvtUFixedFpSIop = InstObjParams("vcvt", "VcvtUFixedFpS", "FpRegRegImmOp",
1588 { "code": vcvtUFixedFpSCode,
1589 "predicate_test": predicateTest,
1590 "op_class": "SimdFloatCvtOp" }, [])
1591 header_output += FpRegRegImmOpDeclare.subst(vcvtUFixedFpSIop);
1592 decoder_output += FpRegRegImmOpConstructor.subst(vcvtUFixedFpSIop);
1593 exec_output += PredOpExecute.subst(vcvtUFixedFpSIop);
1594
1595 vcvtUFixedFpDCode = vfpEnabledCheckCode + '''
1596 FPSCR fpscr = (FPSCR) FpscrExc;
1597 uint64_t mid = ((uint64_t)FpOp1P0_uw | ((uint64_t)FpOp1P1_uw << 32));
1598 VfpSavedState state = prepFpState(fpscr.rMode);
1599 __asm__ __volatile__("" : "=m" (mid) : "m" (mid));
1600 double cDest = vfpUFixedToFpD(fpscr.fz, fpscr.dn, mid, 32, imm);
1601 __asm__ __volatile__("" :: "m" (cDest));
1602 finishVfp(fpscr, state, fpscr.fz);
1603 FpDestP0_uw = dblLow(cDest);
1604 FpDestP1_uw = dblHi(cDest);
1605 FpscrExc = fpscr;
1606 '''
1607 vcvtUFixedFpDIop = InstObjParams("vcvt", "VcvtUFixedFpD", "FpRegRegImmOp",
1608 { "code": vcvtUFixedFpDCode,
1609 "predicate_test": predicateTest,
1610 "op_class": "SimdFloatCvtOp" }, [])
1611 header_output += FpRegRegImmOpDeclare.subst(vcvtUFixedFpDIop);
1612 decoder_output += FpRegRegImmOpConstructor.subst(vcvtUFixedFpDIop);
1613 exec_output += PredOpExecute.subst(vcvtUFixedFpDIop);
1614
1615 vcvtFpSHFixedSCode = vfpEnabledCheckCode + '''
1616 FPSCR fpscr = (FPSCR) FpscrExc;
1617 vfpFlushToZero(fpscr, FpOp1);
1618 VfpSavedState state = prepFpState(fpscr.rMode);
1619 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1620 FpDest_sh = vfpFpToFixed<float>(FpOp1, true, 16, imm);
1621 __asm__ __volatile__("" :: "m" (FpDest_sh));
1622 finishVfp(fpscr, state, fpscr.fz);
1623 FpscrExc = fpscr;
1624 '''
1625 vcvtFpSHFixedSIop = InstObjParams("vcvt", "VcvtFpSHFixedS",
1626 "FpRegRegImmOp",
1627 { "code": vcvtFpSHFixedSCode,
1628 "predicate_test": predicateTest,
1629 "op_class": "SimdFloatCvtOp" }, [])
1630 header_output += FpRegRegImmOpDeclare.subst(vcvtFpSHFixedSIop);
1631 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSHFixedSIop);
1632 exec_output += PredOpExecute.subst(vcvtFpSHFixedSIop);
1633
1634 vcvtFpSHFixedDCode = vfpEnabledCheckCode + '''
1635 FPSCR fpscr = (FPSCR) FpscrExc;
1636 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1637 vfpFlushToZero(fpscr, cOp1);
1638 VfpSavedState state = prepFpState(fpscr.rMode);
1639 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1640 uint64_t result = vfpFpToFixed<double>(cOp1, true, 16, imm);
1641 __asm__ __volatile__("" :: "m" (result));
1642 finishVfp(fpscr, state, fpscr.fz);
1643 FpDestP0_uw = result;
1644 FpDestP1_uw = result >> 32;
1645 FpscrExc = fpscr;
1646 '''
1647 vcvtFpSHFixedDIop = InstObjParams("vcvt", "VcvtFpSHFixedD",
1648 "FpRegRegImmOp",
1649 { "code": vcvtFpSHFixedDCode,
1650 "predicate_test": predicateTest,
1651 "op_class": "SimdFloatCvtOp" }, [])
1652 header_output += FpRegRegImmOpDeclare.subst(vcvtFpSHFixedDIop);
1653 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSHFixedDIop);
1654 exec_output += PredOpExecute.subst(vcvtFpSHFixedDIop);
1655
1656 vcvtFpUHFixedSCode = vfpEnabledCheckCode + '''
1657 FPSCR fpscr = (FPSCR) FpscrExc;
1658 vfpFlushToZero(fpscr, FpOp1);
1659 VfpSavedState state = prepFpState(fpscr.rMode);
1660 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1661 FpDest_uh = vfpFpToFixed<float>(FpOp1, false, 16, imm);
1662 __asm__ __volatile__("" :: "m" (FpDest_uh));
1663 finishVfp(fpscr, state, fpscr.fz);
1664 FpscrExc = fpscr;
1665 '''
1666 vcvtFpUHFixedSIop = InstObjParams("vcvt", "VcvtFpUHFixedS",
1667 "FpRegRegImmOp",
1668 { "code": vcvtFpUHFixedSCode,
1669 "predicate_test": predicateTest,
1670 "op_class": "SimdFloatCvtOp" }, [])
1671 header_output += FpRegRegImmOpDeclare.subst(vcvtFpUHFixedSIop);
1672 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUHFixedSIop);
1673 exec_output += PredOpExecute.subst(vcvtFpUHFixedSIop);
1674
1675 vcvtFpUHFixedDCode = vfpEnabledCheckCode + '''
1676 FPSCR fpscr = (FPSCR) FpscrExc;
1677 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1678 vfpFlushToZero(fpscr, cOp1);
1679 VfpSavedState state = prepFpState(fpscr.rMode);
1680 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1681 uint64_t mid = vfpFpToFixed<double>(cOp1, false, 16, imm);
1682 __asm__ __volatile__("" :: "m" (mid));
1683 finishVfp(fpscr, state, fpscr.fz);
1684 FpDestP0_uw = mid;
1685 FpDestP1_uw = mid >> 32;
1686 FpscrExc = fpscr;
1687 '''
1688 vcvtFpUHFixedDIop = InstObjParams("vcvt", "VcvtFpUHFixedD",
1689 "FpRegRegImmOp",
1690 { "code": vcvtFpUHFixedDCode,
1691 "predicate_test": predicateTest,
1692 "op_class": "SimdFloatCvtOp" }, [])
1693 header_output += FpRegRegImmOpDeclare.subst(vcvtFpUHFixedDIop);
1694 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUHFixedDIop);
1695 exec_output += PredOpExecute.subst(vcvtFpUHFixedDIop);
1696
1697 vcvtSHFixedFpSCode = vfpEnabledCheckCode + '''
1698 FPSCR fpscr = (FPSCR) FpscrExc;
1699 VfpSavedState state = prepFpState(fpscr.rMode);
1700 __asm__ __volatile__("" : "=m" (FpOp1_sh) : "m" (FpOp1_sh));
1701 FpDest = vfpSFixedToFpS(fpscr.fz, fpscr.dn, FpOp1_sh, 16, imm);
1702 __asm__ __volatile__("" :: "m" (FpDest));
1703 finishVfp(fpscr, state, fpscr.fz);
1704 FpscrExc = fpscr;
1705 '''
1706 vcvtSHFixedFpSIop = InstObjParams("vcvt", "VcvtSHFixedFpS",
1707 "FpRegRegImmOp",
1708 { "code": vcvtSHFixedFpSCode,
1709 "predicate_test": predicateTest,
1710 "op_class": "SimdFloatCvtOp" }, [])
1711 header_output += FpRegRegImmOpDeclare.subst(vcvtSHFixedFpSIop);
1712 decoder_output += FpRegRegImmOpConstructor.subst(vcvtSHFixedFpSIop);
1713 exec_output += PredOpExecute.subst(vcvtSHFixedFpSIop);
1714
1715 vcvtSHFixedFpDCode = vfpEnabledCheckCode + '''
1716 FPSCR fpscr = (FPSCR) FpscrExc;
1717 uint64_t mid = ((uint64_t)FpOp1P0_uw | ((uint64_t)FpOp1P1_uw << 32));
1718 VfpSavedState state = prepFpState(fpscr.rMode);
1719 __asm__ __volatile__("" : "=m" (mid) : "m" (mid));
1720 double cDest = vfpSFixedToFpD(fpscr.fz, fpscr.dn, mid, 16, imm);
1721 __asm__ __volatile__("" :: "m" (cDest));
1722 finishVfp(fpscr, state, fpscr.fz);
1723 FpDestP0_uw = dblLow(cDest);
1724 FpDestP1_uw = dblHi(cDest);
1725 FpscrExc = fpscr;
1726 '''
1727 vcvtSHFixedFpDIop = InstObjParams("vcvt", "VcvtSHFixedFpD",
1728 "FpRegRegImmOp",
1729 { "code": vcvtSHFixedFpDCode,
1730 "predicate_test": predicateTest,
1731 "op_class": "SimdFloatCvtOp" }, [])
1732 header_output += FpRegRegImmOpDeclare.subst(vcvtSHFixedFpDIop);
1733 decoder_output += FpRegRegImmOpConstructor.subst(vcvtSHFixedFpDIop);
1734 exec_output += PredOpExecute.subst(vcvtSHFixedFpDIop);
1735
1736 vcvtUHFixedFpSCode = vfpEnabledCheckCode + '''
1737 FPSCR fpscr = (FPSCR) FpscrExc;
1738 VfpSavedState state = prepFpState(fpscr.rMode);
1739 __asm__ __volatile__("" : "=m" (FpOp1_uh) : "m" (FpOp1_uh));
1740 FpDest = vfpUFixedToFpS(fpscr.fz, fpscr.dn, FpOp1_uh, 16, imm);
1741 __asm__ __volatile__("" :: "m" (FpDest));
1742 finishVfp(fpscr, state, fpscr.fz);
1743 FpscrExc = fpscr;
1744 '''
1745 vcvtUHFixedFpSIop = InstObjParams("vcvt", "VcvtUHFixedFpS",
1746 "FpRegRegImmOp",
1747 { "code": vcvtUHFixedFpSCode,
1748 "predicate_test": predicateTest,
1749 "op_class": "SimdFloatCvtOp" }, [])
1750 header_output += FpRegRegImmOpDeclare.subst(vcvtUHFixedFpSIop);
1751 decoder_output += FpRegRegImmOpConstructor.subst(vcvtUHFixedFpSIop);
1752 exec_output += PredOpExecute.subst(vcvtUHFixedFpSIop);
1753
1754 vcvtUHFixedFpDCode = vfpEnabledCheckCode + '''
1755 FPSCR fpscr = (FPSCR) FpscrExc;
1756 uint64_t mid = ((uint64_t)FpOp1P0_uw | ((uint64_t)FpOp1P1_uw << 32));
1757 VfpSavedState state = prepFpState(fpscr.rMode);
1758 __asm__ __volatile__("" : "=m" (mid) : "m" (mid));
1759 double cDest = vfpUFixedToFpD(fpscr.fz, fpscr.dn, mid, 16, imm);
1760 __asm__ __volatile__("" :: "m" (cDest));
1761 finishVfp(fpscr, state, fpscr.fz);
1762 FpDestP0_uw = dblLow(cDest);
1763 FpDestP1_uw = dblHi(cDest);
1764 FpscrExc = fpscr;
1765 '''
1766 vcvtUHFixedFpDIop = InstObjParams("vcvt", "VcvtUHFixedFpD",
1767 "FpRegRegImmOp",
1768 { "code": vcvtUHFixedFpDCode,
1769 "predicate_test": predicateTest,
1770 "op_class": "SimdFloatCvtOp" }, [])
1771 header_output += FpRegRegImmOpDeclare.subst(vcvtUHFixedFpDIop);
1772 decoder_output += FpRegRegImmOpConstructor.subst(vcvtUHFixedFpDIop);
1773 exec_output += PredOpExecute.subst(vcvtUHFixedFpDIop);
1774}};
1086
1087 vcvtFpSFpDCode = vfpEnabledCheckCode + '''
1088 FPSCR fpscr = (FPSCR) FpscrExc;
1089 vfpFlushToZero(fpscr, FpOp1);
1090 VfpSavedState state = prepFpState(fpscr.rMode);
1091 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1092 double cDest = fixFpSFpDDest(FpscrExc, FpOp1);
1093 __asm__ __volatile__("" :: "m" (cDest));
1094 finishVfp(fpscr, state, fpscr.fz);
1095 FpDestP0_uw = dblLow(cDest);
1096 FpDestP1_uw = dblHi(cDest);
1097 FpscrExc = fpscr;
1098 '''
1099 vcvtFpSFpDIop = InstObjParams("vcvt", "VcvtFpSFpD", "FpRegRegOp",
1100 { "code": vcvtFpSFpDCode,
1101 "predicate_test": predicateTest,
1102 "op_class": "SimdFloatCvtOp" }, [])
1103 header_output += FpRegRegOpDeclare.subst(vcvtFpSFpDIop);
1104 decoder_output += FpRegRegOpConstructor.subst(vcvtFpSFpDIop);
1105 exec_output += PredOpExecute.subst(vcvtFpSFpDIop);
1106
1107 vcvtFpDFpSCode = vfpEnabledCheckCode + '''
1108 FPSCR fpscr = (FPSCR) FpscrExc;
1109 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1110 vfpFlushToZero(fpscr, cOp1);
1111 VfpSavedState state = prepFpState(fpscr.rMode);
1112 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1113 FpDest = fixFpDFpSDest(FpscrExc, cOp1);
1114 __asm__ __volatile__("" :: "m" (FpDest));
1115 finishVfp(fpscr, state, fpscr.fz);
1116 FpscrExc = fpscr;
1117 '''
1118 vcvtFpDFpSIop = InstObjParams("vcvt", "VcvtFpDFpS", "FpRegRegOp",
1119 { "code": vcvtFpDFpSCode,
1120 "predicate_test": predicateTest,
1121 "op_class": "SimdFloatCvtOp" }, [])
1122 header_output += FpRegRegOpDeclare.subst(vcvtFpDFpSIop);
1123 decoder_output += FpRegRegOpConstructor.subst(vcvtFpDFpSIop);
1124 exec_output += PredOpExecute.subst(vcvtFpDFpSIop);
1125
1126 vcvtFpHTFpSCode = vfpEnabledCheckCode + '''
1127 FPSCR fpscr = (FPSCR) FpscrExc;
1128 vfpFlushToZero(fpscr, FpOp1);
1129 VfpSavedState state = prepFpState(fpscr.rMode);
1130 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1131 FpDest = vcvtFpHFpS(fpscr, fpscr.dn, fpscr.ahp,
1132 bits(fpToBits(FpOp1), 31, 16));
1133 __asm__ __volatile__("" :: "m" (FpDest));
1134 finishVfp(fpscr, state, fpscr.fz);
1135 FpscrExc = fpscr;
1136 '''
1137 vcvtFpHTFpSIop = InstObjParams("vcvtt", "VcvtFpHTFpS", "FpRegRegOp",
1138 { "code": vcvtFpHTFpSCode,
1139 "predicate_test": predicateTest,
1140 "op_class": "SimdFloatCvtOp" }, [])
1141 header_output += FpRegRegOpDeclare.subst(vcvtFpHTFpSIop);
1142 decoder_output += FpRegRegOpConstructor.subst(vcvtFpHTFpSIop);
1143 exec_output += PredOpExecute.subst(vcvtFpHTFpSIop);
1144
1145 vcvtFpHBFpSCode = vfpEnabledCheckCode + '''
1146 FPSCR fpscr = (FPSCR) FpscrExc;
1147 VfpSavedState state = prepFpState(fpscr.rMode);
1148 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1149 FpDest = vcvtFpHFpS(fpscr, fpscr.dn, fpscr.ahp,
1150 bits(fpToBits(FpOp1), 15, 0));
1151 __asm__ __volatile__("" :: "m" (FpDest));
1152 finishVfp(fpscr, state, fpscr.fz);
1153 FpscrExc = fpscr;
1154 '''
1155 vcvtFpHBFpSIop = InstObjParams("vcvtb", "VcvtFpHBFpS", "FpRegRegOp",
1156 { "code": vcvtFpHBFpSCode,
1157 "predicate_test": predicateTest,
1158 "op_class": "SimdFloatCvtOp" }, [])
1159 header_output += FpRegRegOpDeclare.subst(vcvtFpHBFpSIop);
1160 decoder_output += FpRegRegOpConstructor.subst(vcvtFpHBFpSIop);
1161 exec_output += PredOpExecute.subst(vcvtFpHBFpSIop);
1162
1163 vcvtFpSFpHTCode = vfpEnabledCheckCode + '''
1164 FPSCR fpscr = (FPSCR) FpscrExc;
1165 vfpFlushToZero(fpscr, FpOp1);
1166 VfpSavedState state = prepFpState(fpscr.rMode);
1167 __asm__ __volatile__("" : "=m" (FpOp1), "=m" (FpDest_uw)
1168 : "m" (FpOp1), "m" (FpDest_uw));
1169 FpDest_uw = insertBits(FpDest_uw, 31, 16,,
1170 vcvtFpSFpH(fpscr, fpscr.fz, fpscr.dn,
1171 fpscr.rMode, fpscr.ahp, FpOp1));
1172 __asm__ __volatile__("" :: "m" (FpDest_uw));
1173 finishVfp(fpscr, state, fpscr.fz);
1174 FpscrExc = fpscr;
1175 '''
1176 vcvtFpSFpHTIop = InstObjParams("vcvtt", "VcvtFpSFpHT", "FpRegRegOp",
1177 { "code": vcvtFpHTFpSCode,
1178 "predicate_test": predicateTest,
1179 "op_class": "SimdFloatCvtOp" }, [])
1180 header_output += FpRegRegOpDeclare.subst(vcvtFpSFpHTIop);
1181 decoder_output += FpRegRegOpConstructor.subst(vcvtFpSFpHTIop);
1182 exec_output += PredOpExecute.subst(vcvtFpSFpHTIop);
1183
1184 vcvtFpSFpHBCode = vfpEnabledCheckCode + '''
1185 FPSCR fpscr = (FPSCR) FpscrExc;
1186 vfpFlushToZero(fpscr, FpOp1);
1187 VfpSavedState state = prepFpState(fpscr.rMode);
1188 __asm__ __volatile__("" : "=m" (FpOp1), "=m" (FpDest_uw)
1189 : "m" (FpOp1), "m" (FpDest_uw));
1190 FpDest_uw = insertBits(FpDest_uw, 15, 0,
1191 vcvtFpSFpH(fpscr, fpscr.fz, fpscr.dn,
1192 fpscr.rMode, fpscr.ahp, FpOp1));
1193 __asm__ __volatile__("" :: "m" (FpDest_uw));
1194 finishVfp(fpscr, state, fpscr.fz);
1195 FpscrExc = fpscr;
1196 '''
1197 vcvtFpSFpHBIop = InstObjParams("vcvtb", "VcvtFpSFpHB", "FpRegRegOp",
1198 { "code": vcvtFpSFpHBCode,
1199 "predicate_test": predicateTest,
1200 "op_class": "SimdFloatCvtOp" }, [])
1201 header_output += FpRegRegOpDeclare.subst(vcvtFpSFpHBIop);
1202 decoder_output += FpRegRegOpConstructor.subst(vcvtFpSFpHBIop);
1203 exec_output += PredOpExecute.subst(vcvtFpSFpHBIop);
1204
1205 vcmpSCode = vfpEnabledCheckCode + '''
1206 FPSCR fpscr = (FPSCR) FpscrExc;
1207 vfpFlushToZero(fpscr, FpDest, FpOp1);
1208 if (FpDest == FpOp1) {
1209 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1210 } else if (FpDest < FpOp1) {
1211 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1212 } else if (FpDest > FpOp1) {
1213 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1214 } else {
1215 const uint32_t qnan = 0x7fc00000;
1216 const bool nan1 = std::isnan(FpDest);
1217 const bool signal1 = nan1 && ((fpToBits(FpDest) & qnan) != qnan);
1218 const bool nan2 = std::isnan(FpOp1);
1219 const bool signal2 = nan2 && ((fpToBits(FpOp1) & qnan) != qnan);
1220 if (signal1 || signal2)
1221 fpscr.ioc = 1;
1222 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1223 }
1224 FpCondCodes = fpscr & FpCondCodesMask;
1225 FpscrExc = fpscr;
1226 '''
1227 vcmpSIop = InstObjParams("vcmps", "VcmpS", "FpRegRegOp",
1228 { "code": vcmpSCode,
1229 "predicate_test": predicateTest,
1230 "op_class": "SimdFloatCmpOp" }, [])
1231 header_output += FpRegRegOpDeclare.subst(vcmpSIop);
1232 decoder_output += FpRegRegOpConstructor.subst(vcmpSIop);
1233 exec_output += PredOpExecute.subst(vcmpSIop);
1234
1235 vcmpDCode = vfpEnabledCheckCode + '''
1236 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1237 double cDest = dbl(FpDestP0_uw, FpDestP1_uw);
1238 FPSCR fpscr = (FPSCR) FpscrExc;
1239 vfpFlushToZero(fpscr, cDest, cOp1);
1240 if (cDest == cOp1) {
1241 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1242 } else if (cDest < cOp1) {
1243 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1244 } else if (cDest > cOp1) {
1245 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1246 } else {
1247 const uint64_t qnan = ULL(0x7ff8000000000000);
1248 const bool nan1 = std::isnan(cDest);
1249 const bool signal1 = nan1 && ((fpToBits(cDest) & qnan) != qnan);
1250 const bool nan2 = std::isnan(cOp1);
1251 const bool signal2 = nan2 && ((fpToBits(cOp1) & qnan) != qnan);
1252 if (signal1 || signal2)
1253 fpscr.ioc = 1;
1254 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1255 }
1256 FpCondCodes = fpscr & FpCondCodesMask;
1257 FpscrExc = fpscr;
1258 '''
1259 vcmpDIop = InstObjParams("vcmpd", "VcmpD", "FpRegRegOp",
1260 { "code": vcmpDCode,
1261 "predicate_test": predicateTest,
1262 "op_class": "SimdFloatCmpOp" }, [])
1263 header_output += FpRegRegOpDeclare.subst(vcmpDIop);
1264 decoder_output += FpRegRegOpConstructor.subst(vcmpDIop);
1265 exec_output += PredOpExecute.subst(vcmpDIop);
1266
1267 vcmpZeroSCode = vfpEnabledCheckCode + '''
1268 FPSCR fpscr = (FPSCR) FpscrExc;
1269 vfpFlushToZero(fpscr, FpDest);
1270 // This only handles imm == 0 for now.
1271 assert(imm == 0);
1272 if (FpDest == imm) {
1273 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1274 } else if (FpDest < imm) {
1275 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1276 } else if (FpDest > imm) {
1277 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1278 } else {
1279 const uint32_t qnan = 0x7fc00000;
1280 const bool nan = std::isnan(FpDest);
1281 const bool signal = nan && ((fpToBits(FpDest) & qnan) != qnan);
1282 if (signal)
1283 fpscr.ioc = 1;
1284 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1285 }
1286 FpCondCodes = fpscr & FpCondCodesMask;
1287 FpscrExc = fpscr;
1288 '''
1289 vcmpZeroSIop = InstObjParams("vcmpZeros", "VcmpZeroS", "FpRegImmOp",
1290 { "code": vcmpZeroSCode,
1291 "predicate_test": predicateTest,
1292 "op_class": "SimdFloatCmpOp" }, [])
1293 header_output += FpRegImmOpDeclare.subst(vcmpZeroSIop);
1294 decoder_output += FpRegImmOpConstructor.subst(vcmpZeroSIop);
1295 exec_output += PredOpExecute.subst(vcmpZeroSIop);
1296
1297 vcmpZeroDCode = vfpEnabledCheckCode + '''
1298 // This only handles imm == 0 for now.
1299 assert(imm == 0);
1300 double cDest = dbl(FpDestP0_uw, FpDestP1_uw);
1301 FPSCR fpscr = (FPSCR) FpscrExc;
1302 vfpFlushToZero(fpscr, cDest);
1303 if (cDest == imm) {
1304 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1305 } else if (cDest < imm) {
1306 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1307 } else if (cDest > imm) {
1308 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1309 } else {
1310 const uint64_t qnan = ULL(0x7ff8000000000000);
1311 const bool nan = std::isnan(cDest);
1312 const bool signal = nan && ((fpToBits(cDest) & qnan) != qnan);
1313 if (signal)
1314 fpscr.ioc = 1;
1315 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1316 }
1317 FpCondCodes = fpscr & FpCondCodesMask;
1318 FpscrExc = fpscr;
1319 '''
1320 vcmpZeroDIop = InstObjParams("vcmpZerod", "VcmpZeroD", "FpRegImmOp",
1321 { "code": vcmpZeroDCode,
1322 "predicate_test": predicateTest,
1323 "op_class": "SimdFloatCmpOp" }, [])
1324 header_output += FpRegImmOpDeclare.subst(vcmpZeroDIop);
1325 decoder_output += FpRegImmOpConstructor.subst(vcmpZeroDIop);
1326 exec_output += PredOpExecute.subst(vcmpZeroDIop);
1327
1328 vcmpeSCode = vfpEnabledCheckCode + '''
1329 FPSCR fpscr = (FPSCR) FpscrExc;
1330 vfpFlushToZero(fpscr, FpDest, FpOp1);
1331 if (FpDest == FpOp1) {
1332 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1333 } else if (FpDest < FpOp1) {
1334 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1335 } else if (FpDest > FpOp1) {
1336 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1337 } else {
1338 fpscr.ioc = 1;
1339 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1340 }
1341 FpCondCodes = fpscr & FpCondCodesMask;
1342 FpscrExc = fpscr;
1343 '''
1344 vcmpeSIop = InstObjParams("vcmpes", "VcmpeS", "FpRegRegOp",
1345 { "code": vcmpeSCode,
1346 "predicate_test": predicateTest,
1347 "op_class": "SimdFloatCmpOp" }, [])
1348 header_output += FpRegRegOpDeclare.subst(vcmpeSIop);
1349 decoder_output += FpRegRegOpConstructor.subst(vcmpeSIop);
1350 exec_output += PredOpExecute.subst(vcmpeSIop);
1351
1352 vcmpeDCode = vfpEnabledCheckCode + '''
1353 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1354 double cDest = dbl(FpDestP0_uw, FpDestP1_uw);
1355 FPSCR fpscr = (FPSCR) FpscrExc;
1356 vfpFlushToZero(fpscr, cDest, cOp1);
1357 if (cDest == cOp1) {
1358 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1359 } else if (cDest < cOp1) {
1360 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1361 } else if (cDest > cOp1) {
1362 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1363 } else {
1364 fpscr.ioc = 1;
1365 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1366 }
1367 FpCondCodes = fpscr & FpCondCodesMask;
1368 FpscrExc = fpscr;
1369 '''
1370 vcmpeDIop = InstObjParams("vcmped", "VcmpeD", "FpRegRegOp",
1371 { "code": vcmpeDCode,
1372 "predicate_test": predicateTest,
1373 "op_class": "SimdFloatCmpOp" }, [])
1374 header_output += FpRegRegOpDeclare.subst(vcmpeDIop);
1375 decoder_output += FpRegRegOpConstructor.subst(vcmpeDIop);
1376 exec_output += PredOpExecute.subst(vcmpeDIop);
1377
1378 vcmpeZeroSCode = vfpEnabledCheckCode + '''
1379 FPSCR fpscr = (FPSCR) FpscrExc;
1380 vfpFlushToZero(fpscr, FpDest);
1381 if (FpDest == imm) {
1382 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1383 } else if (FpDest < imm) {
1384 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1385 } else if (FpDest > imm) {
1386 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1387 } else {
1388 fpscr.ioc = 1;
1389 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1390 }
1391 FpCondCodes = fpscr & FpCondCodesMask;
1392 FpscrExc = fpscr;
1393 '''
1394 vcmpeZeroSIop = InstObjParams("vcmpeZeros", "VcmpeZeroS", "FpRegImmOp",
1395 { "code": vcmpeZeroSCode,
1396 "predicate_test": predicateTest,
1397 "op_class": "SimdFloatCmpOp" }, [])
1398 header_output += FpRegImmOpDeclare.subst(vcmpeZeroSIop);
1399 decoder_output += FpRegImmOpConstructor.subst(vcmpeZeroSIop);
1400 exec_output += PredOpExecute.subst(vcmpeZeroSIop);
1401
1402 vcmpeZeroDCode = vfpEnabledCheckCode + '''
1403 double cDest = dbl(FpDestP0_uw, FpDestP1_uw);
1404 FPSCR fpscr = (FPSCR) FpscrExc;
1405 vfpFlushToZero(fpscr, cDest);
1406 if (cDest == imm) {
1407 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1408 } else if (cDest < imm) {
1409 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1410 } else if (cDest > imm) {
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 vcmpeZeroDIop = InstObjParams("vcmpeZerod", "VcmpeZeroD", "FpRegImmOp",
1420 { "code": vcmpeZeroDCode,
1421 "predicate_test": predicateTest,
1422 "op_class": "SimdFloatCmpOp" }, [])
1423 header_output += FpRegImmOpDeclare.subst(vcmpeZeroDIop);
1424 decoder_output += FpRegImmOpConstructor.subst(vcmpeZeroDIop);
1425 exec_output += PredOpExecute.subst(vcmpeZeroDIop);
1426}};
1427
1428let {{
1429
1430 header_output = ""
1431 decoder_output = ""
1432 exec_output = ""
1433
1434 vselSCode = vfpEnabledCheckCode + '''
1435 if (testPredicate(CondCodesNZ, CondCodesC, CondCodesV, cond)) {
1436 FpDest = FpOp1;
1437 } else {
1438 FpDest = FpOp2;
1439 } '''
1440
1441 vselSIop = InstObjParams("vsels", "VselS", "FpRegRegRegCondOp",
1442 { "code" : vselSCode,
1443 "predicate_test" : predicateTest,
1444 "op_class" : "SimdFloatCmpOp" }, [] )
1445 header_output += FpRegRegRegCondOpDeclare.subst(vselSIop);
1446 decoder_output += FpRegRegRegCondOpConstructor.subst(vselSIop);
1447 exec_output += PredOpExecute.subst(vselSIop);
1448
1449 vselDCode = vfpEnabledCheckCode + '''
1450 if (testPredicate(CondCodesNZ, CondCodesC, CondCodesV, cond)) {
1451 FpDestP0_uw = FpOp1P0_uw;
1452 FpDestP1_uw = FpOp1P1_uw;
1453 } else {
1454 FpDestP0_uw = FpOp2P0_uw;
1455 FpDestP1_uw = FpOp2P1_uw;
1456 } '''
1457
1458 vselDIop = InstObjParams("vseld", "VselD", "FpRegRegRegCondOp",
1459 { "code" : vselDCode,
1460 "predicate_test" : predicateTest,
1461 "op_class" : "SimdFloatCmpOp" }, [] )
1462 header_output += FpRegRegRegCondOpDeclare.subst(vselDIop);
1463 decoder_output += FpRegRegRegCondOpConstructor.subst(vselDIop);
1464 exec_output += PredOpExecute.subst(vselDIop);
1465}};
1466
1467
1468let {{
1469
1470 header_output = ""
1471 decoder_output = ""
1472 exec_output = ""
1473
1474 vcvtFpSFixedSCode = vfpEnabledCheckCode + '''
1475 FPSCR fpscr = (FPSCR) FpscrExc;
1476 vfpFlushToZero(fpscr, FpOp1);
1477 VfpSavedState state = prepFpState(fpscr.rMode);
1478 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1479 FpDest_sw = vfpFpToFixed<float>(FpOp1, true, 32, imm);
1480 __asm__ __volatile__("" :: "m" (FpDest_sw));
1481 finishVfp(fpscr, state, fpscr.fz);
1482 FpscrExc = fpscr;
1483 '''
1484 vcvtFpSFixedSIop = InstObjParams("vcvt", "VcvtFpSFixedS", "FpRegRegImmOp",
1485 { "code": vcvtFpSFixedSCode,
1486 "predicate_test": predicateTest,
1487 "op_class": "SimdFloatCvtOp" }, [])
1488 header_output += FpRegRegImmOpDeclare.subst(vcvtFpSFixedSIop);
1489 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSFixedSIop);
1490 exec_output += PredOpExecute.subst(vcvtFpSFixedSIop);
1491
1492 vcvtFpSFixedDCode = vfpEnabledCheckCode + '''
1493 FPSCR fpscr = (FPSCR) FpscrExc;
1494 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1495 vfpFlushToZero(fpscr, cOp1);
1496 VfpSavedState state = prepFpState(fpscr.rMode);
1497 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1498 uint64_t mid = vfpFpToFixed<double>(cOp1, true, 32, imm);
1499 __asm__ __volatile__("" :: "m" (mid));
1500 finishVfp(fpscr, state, fpscr.fz);
1501 FpDestP0_uw = mid;
1502 FpDestP1_uw = mid >> 32;
1503 FpscrExc = fpscr;
1504 '''
1505 vcvtFpSFixedDIop = InstObjParams("vcvt", "VcvtFpSFixedD", "FpRegRegImmOp",
1506 { "code": vcvtFpSFixedDCode,
1507 "predicate_test": predicateTest,
1508 "op_class": "SimdFloatCvtOp" }, [])
1509 header_output += FpRegRegImmOpDeclare.subst(vcvtFpSFixedDIop);
1510 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSFixedDIop);
1511 exec_output += PredOpExecute.subst(vcvtFpSFixedDIop);
1512
1513 vcvtFpUFixedSCode = vfpEnabledCheckCode + '''
1514 FPSCR fpscr = (FPSCR) FpscrExc;
1515 vfpFlushToZero(fpscr, FpOp1);
1516 VfpSavedState state = prepFpState(fpscr.rMode);
1517 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1518 FpDest_uw = vfpFpToFixed<float>(FpOp1, false, 32, imm);
1519 __asm__ __volatile__("" :: "m" (FpDest_uw));
1520 finishVfp(fpscr, state, fpscr.fz);
1521 FpscrExc = fpscr;
1522 '''
1523 vcvtFpUFixedSIop = InstObjParams("vcvt", "VcvtFpUFixedS", "FpRegRegImmOp",
1524 { "code": vcvtFpUFixedSCode,
1525 "predicate_test": predicateTest,
1526 "op_class": "SimdFloatCvtOp" }, [])
1527 header_output += FpRegRegImmOpDeclare.subst(vcvtFpUFixedSIop);
1528 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUFixedSIop);
1529 exec_output += PredOpExecute.subst(vcvtFpUFixedSIop);
1530
1531 vcvtFpUFixedDCode = vfpEnabledCheckCode + '''
1532 FPSCR fpscr = (FPSCR) FpscrExc;
1533 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1534 vfpFlushToZero(fpscr, cOp1);
1535 VfpSavedState state = prepFpState(fpscr.rMode);
1536 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1537 uint64_t mid = vfpFpToFixed<double>(cOp1, false, 32, imm);
1538 __asm__ __volatile__("" :: "m" (mid));
1539 finishVfp(fpscr, state, fpscr.fz);
1540 FpDestP0_uw = mid;
1541 FpDestP1_uw = mid >> 32;
1542 FpscrExc = fpscr;
1543 '''
1544 vcvtFpUFixedDIop = InstObjParams("vcvt", "VcvtFpUFixedD", "FpRegRegImmOp",
1545 { "code": vcvtFpUFixedDCode,
1546 "predicate_test": predicateTest,
1547 "op_class": "SimdFloatCvtOp" }, [])
1548 header_output += FpRegRegImmOpDeclare.subst(vcvtFpUFixedDIop);
1549 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUFixedDIop);
1550 exec_output += PredOpExecute.subst(vcvtFpUFixedDIop);
1551
1552 vcvtSFixedFpSCode = vfpEnabledCheckCode + '''
1553 FPSCR fpscr = (FPSCR) FpscrExc;
1554 VfpSavedState state = prepFpState(fpscr.rMode);
1555 __asm__ __volatile__("" : "=m" (FpOp1_sw) : "m" (FpOp1_sw));
1556 FpDest = vfpSFixedToFpS(fpscr.fz, fpscr.dn, FpOp1_sw, 32, imm);
1557 __asm__ __volatile__("" :: "m" (FpDest));
1558 finishVfp(fpscr, state, fpscr.fz);
1559 FpscrExc = fpscr;
1560 '''
1561 vcvtSFixedFpSIop = InstObjParams("vcvt", "VcvtSFixedFpS", "FpRegRegImmOp",
1562 { "code": vcvtSFixedFpSCode,
1563 "predicate_test": predicateTest,
1564 "op_class": "SimdFloatCvtOp" }, [])
1565 header_output += FpRegRegImmOpDeclare.subst(vcvtSFixedFpSIop);
1566 decoder_output += FpRegRegImmOpConstructor.subst(vcvtSFixedFpSIop);
1567 exec_output += PredOpExecute.subst(vcvtSFixedFpSIop);
1568
1569 vcvtSFixedFpDCode = vfpEnabledCheckCode + '''
1570 FPSCR fpscr = (FPSCR) FpscrExc;
1571 uint64_t mid = ((uint64_t)FpOp1P0_uw | ((uint64_t)FpOp1P1_uw << 32));
1572 VfpSavedState state = prepFpState(fpscr.rMode);
1573 __asm__ __volatile__("" : "=m" (mid) : "m" (mid));
1574 double cDest = vfpSFixedToFpD(fpscr.fz, fpscr.dn, mid, 32, imm);
1575 __asm__ __volatile__("" :: "m" (cDest));
1576 finishVfp(fpscr, state, fpscr.fz);
1577 FpDestP0_uw = dblLow(cDest);
1578 FpDestP1_uw = dblHi(cDest);
1579 FpscrExc = fpscr;
1580 '''
1581 vcvtSFixedFpDIop = InstObjParams("vcvt", "VcvtSFixedFpD", "FpRegRegImmOp",
1582 { "code": vcvtSFixedFpDCode,
1583 "predicate_test": predicateTest,
1584 "op_class": "SimdFloatCvtOp" }, [])
1585 header_output += FpRegRegImmOpDeclare.subst(vcvtSFixedFpDIop);
1586 decoder_output += FpRegRegImmOpConstructor.subst(vcvtSFixedFpDIop);
1587 exec_output += PredOpExecute.subst(vcvtSFixedFpDIop);
1588
1589 vcvtUFixedFpSCode = vfpEnabledCheckCode + '''
1590 FPSCR fpscr = (FPSCR) FpscrExc;
1591 VfpSavedState state = prepFpState(fpscr.rMode);
1592 __asm__ __volatile__("" : "=m" (FpOp1_uw) : "m" (FpOp1_uw));
1593 FpDest = vfpUFixedToFpS(fpscr.fz, fpscr.dn, FpOp1_uw, 32, imm);
1594 __asm__ __volatile__("" :: "m" (FpDest));
1595 finishVfp(fpscr, state, fpscr.fz);
1596 FpscrExc = fpscr;
1597 '''
1598 vcvtUFixedFpSIop = InstObjParams("vcvt", "VcvtUFixedFpS", "FpRegRegImmOp",
1599 { "code": vcvtUFixedFpSCode,
1600 "predicate_test": predicateTest,
1601 "op_class": "SimdFloatCvtOp" }, [])
1602 header_output += FpRegRegImmOpDeclare.subst(vcvtUFixedFpSIop);
1603 decoder_output += FpRegRegImmOpConstructor.subst(vcvtUFixedFpSIop);
1604 exec_output += PredOpExecute.subst(vcvtUFixedFpSIop);
1605
1606 vcvtUFixedFpDCode = vfpEnabledCheckCode + '''
1607 FPSCR fpscr = (FPSCR) FpscrExc;
1608 uint64_t mid = ((uint64_t)FpOp1P0_uw | ((uint64_t)FpOp1P1_uw << 32));
1609 VfpSavedState state = prepFpState(fpscr.rMode);
1610 __asm__ __volatile__("" : "=m" (mid) : "m" (mid));
1611 double cDest = vfpUFixedToFpD(fpscr.fz, fpscr.dn, mid, 32, imm);
1612 __asm__ __volatile__("" :: "m" (cDest));
1613 finishVfp(fpscr, state, fpscr.fz);
1614 FpDestP0_uw = dblLow(cDest);
1615 FpDestP1_uw = dblHi(cDest);
1616 FpscrExc = fpscr;
1617 '''
1618 vcvtUFixedFpDIop = InstObjParams("vcvt", "VcvtUFixedFpD", "FpRegRegImmOp",
1619 { "code": vcvtUFixedFpDCode,
1620 "predicate_test": predicateTest,
1621 "op_class": "SimdFloatCvtOp" }, [])
1622 header_output += FpRegRegImmOpDeclare.subst(vcvtUFixedFpDIop);
1623 decoder_output += FpRegRegImmOpConstructor.subst(vcvtUFixedFpDIop);
1624 exec_output += PredOpExecute.subst(vcvtUFixedFpDIop);
1625
1626 vcvtFpSHFixedSCode = vfpEnabledCheckCode + '''
1627 FPSCR fpscr = (FPSCR) FpscrExc;
1628 vfpFlushToZero(fpscr, FpOp1);
1629 VfpSavedState state = prepFpState(fpscr.rMode);
1630 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1631 FpDest_sh = vfpFpToFixed<float>(FpOp1, true, 16, imm);
1632 __asm__ __volatile__("" :: "m" (FpDest_sh));
1633 finishVfp(fpscr, state, fpscr.fz);
1634 FpscrExc = fpscr;
1635 '''
1636 vcvtFpSHFixedSIop = InstObjParams("vcvt", "VcvtFpSHFixedS",
1637 "FpRegRegImmOp",
1638 { "code": vcvtFpSHFixedSCode,
1639 "predicate_test": predicateTest,
1640 "op_class": "SimdFloatCvtOp" }, [])
1641 header_output += FpRegRegImmOpDeclare.subst(vcvtFpSHFixedSIop);
1642 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSHFixedSIop);
1643 exec_output += PredOpExecute.subst(vcvtFpSHFixedSIop);
1644
1645 vcvtFpSHFixedDCode = vfpEnabledCheckCode + '''
1646 FPSCR fpscr = (FPSCR) FpscrExc;
1647 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1648 vfpFlushToZero(fpscr, cOp1);
1649 VfpSavedState state = prepFpState(fpscr.rMode);
1650 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1651 uint64_t result = vfpFpToFixed<double>(cOp1, true, 16, imm);
1652 __asm__ __volatile__("" :: "m" (result));
1653 finishVfp(fpscr, state, fpscr.fz);
1654 FpDestP0_uw = result;
1655 FpDestP1_uw = result >> 32;
1656 FpscrExc = fpscr;
1657 '''
1658 vcvtFpSHFixedDIop = InstObjParams("vcvt", "VcvtFpSHFixedD",
1659 "FpRegRegImmOp",
1660 { "code": vcvtFpSHFixedDCode,
1661 "predicate_test": predicateTest,
1662 "op_class": "SimdFloatCvtOp" }, [])
1663 header_output += FpRegRegImmOpDeclare.subst(vcvtFpSHFixedDIop);
1664 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSHFixedDIop);
1665 exec_output += PredOpExecute.subst(vcvtFpSHFixedDIop);
1666
1667 vcvtFpUHFixedSCode = vfpEnabledCheckCode + '''
1668 FPSCR fpscr = (FPSCR) FpscrExc;
1669 vfpFlushToZero(fpscr, FpOp1);
1670 VfpSavedState state = prepFpState(fpscr.rMode);
1671 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1672 FpDest_uh = vfpFpToFixed<float>(FpOp1, false, 16, imm);
1673 __asm__ __volatile__("" :: "m" (FpDest_uh));
1674 finishVfp(fpscr, state, fpscr.fz);
1675 FpscrExc = fpscr;
1676 '''
1677 vcvtFpUHFixedSIop = InstObjParams("vcvt", "VcvtFpUHFixedS",
1678 "FpRegRegImmOp",
1679 { "code": vcvtFpUHFixedSCode,
1680 "predicate_test": predicateTest,
1681 "op_class": "SimdFloatCvtOp" }, [])
1682 header_output += FpRegRegImmOpDeclare.subst(vcvtFpUHFixedSIop);
1683 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUHFixedSIop);
1684 exec_output += PredOpExecute.subst(vcvtFpUHFixedSIop);
1685
1686 vcvtFpUHFixedDCode = vfpEnabledCheckCode + '''
1687 FPSCR fpscr = (FPSCR) FpscrExc;
1688 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1689 vfpFlushToZero(fpscr, cOp1);
1690 VfpSavedState state = prepFpState(fpscr.rMode);
1691 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1692 uint64_t mid = vfpFpToFixed<double>(cOp1, false, 16, imm);
1693 __asm__ __volatile__("" :: "m" (mid));
1694 finishVfp(fpscr, state, fpscr.fz);
1695 FpDestP0_uw = mid;
1696 FpDestP1_uw = mid >> 32;
1697 FpscrExc = fpscr;
1698 '''
1699 vcvtFpUHFixedDIop = InstObjParams("vcvt", "VcvtFpUHFixedD",
1700 "FpRegRegImmOp",
1701 { "code": vcvtFpUHFixedDCode,
1702 "predicate_test": predicateTest,
1703 "op_class": "SimdFloatCvtOp" }, [])
1704 header_output += FpRegRegImmOpDeclare.subst(vcvtFpUHFixedDIop);
1705 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUHFixedDIop);
1706 exec_output += PredOpExecute.subst(vcvtFpUHFixedDIop);
1707
1708 vcvtSHFixedFpSCode = vfpEnabledCheckCode + '''
1709 FPSCR fpscr = (FPSCR) FpscrExc;
1710 VfpSavedState state = prepFpState(fpscr.rMode);
1711 __asm__ __volatile__("" : "=m" (FpOp1_sh) : "m" (FpOp1_sh));
1712 FpDest = vfpSFixedToFpS(fpscr.fz, fpscr.dn, FpOp1_sh, 16, imm);
1713 __asm__ __volatile__("" :: "m" (FpDest));
1714 finishVfp(fpscr, state, fpscr.fz);
1715 FpscrExc = fpscr;
1716 '''
1717 vcvtSHFixedFpSIop = InstObjParams("vcvt", "VcvtSHFixedFpS",
1718 "FpRegRegImmOp",
1719 { "code": vcvtSHFixedFpSCode,
1720 "predicate_test": predicateTest,
1721 "op_class": "SimdFloatCvtOp" }, [])
1722 header_output += FpRegRegImmOpDeclare.subst(vcvtSHFixedFpSIop);
1723 decoder_output += FpRegRegImmOpConstructor.subst(vcvtSHFixedFpSIop);
1724 exec_output += PredOpExecute.subst(vcvtSHFixedFpSIop);
1725
1726 vcvtSHFixedFpDCode = vfpEnabledCheckCode + '''
1727 FPSCR fpscr = (FPSCR) FpscrExc;
1728 uint64_t mid = ((uint64_t)FpOp1P0_uw | ((uint64_t)FpOp1P1_uw << 32));
1729 VfpSavedState state = prepFpState(fpscr.rMode);
1730 __asm__ __volatile__("" : "=m" (mid) : "m" (mid));
1731 double cDest = vfpSFixedToFpD(fpscr.fz, fpscr.dn, mid, 16, imm);
1732 __asm__ __volatile__("" :: "m" (cDest));
1733 finishVfp(fpscr, state, fpscr.fz);
1734 FpDestP0_uw = dblLow(cDest);
1735 FpDestP1_uw = dblHi(cDest);
1736 FpscrExc = fpscr;
1737 '''
1738 vcvtSHFixedFpDIop = InstObjParams("vcvt", "VcvtSHFixedFpD",
1739 "FpRegRegImmOp",
1740 { "code": vcvtSHFixedFpDCode,
1741 "predicate_test": predicateTest,
1742 "op_class": "SimdFloatCvtOp" }, [])
1743 header_output += FpRegRegImmOpDeclare.subst(vcvtSHFixedFpDIop);
1744 decoder_output += FpRegRegImmOpConstructor.subst(vcvtSHFixedFpDIop);
1745 exec_output += PredOpExecute.subst(vcvtSHFixedFpDIop);
1746
1747 vcvtUHFixedFpSCode = vfpEnabledCheckCode + '''
1748 FPSCR fpscr = (FPSCR) FpscrExc;
1749 VfpSavedState state = prepFpState(fpscr.rMode);
1750 __asm__ __volatile__("" : "=m" (FpOp1_uh) : "m" (FpOp1_uh));
1751 FpDest = vfpUFixedToFpS(fpscr.fz, fpscr.dn, FpOp1_uh, 16, imm);
1752 __asm__ __volatile__("" :: "m" (FpDest));
1753 finishVfp(fpscr, state, fpscr.fz);
1754 FpscrExc = fpscr;
1755 '''
1756 vcvtUHFixedFpSIop = InstObjParams("vcvt", "VcvtUHFixedFpS",
1757 "FpRegRegImmOp",
1758 { "code": vcvtUHFixedFpSCode,
1759 "predicate_test": predicateTest,
1760 "op_class": "SimdFloatCvtOp" }, [])
1761 header_output += FpRegRegImmOpDeclare.subst(vcvtUHFixedFpSIop);
1762 decoder_output += FpRegRegImmOpConstructor.subst(vcvtUHFixedFpSIop);
1763 exec_output += PredOpExecute.subst(vcvtUHFixedFpSIop);
1764
1765 vcvtUHFixedFpDCode = vfpEnabledCheckCode + '''
1766 FPSCR fpscr = (FPSCR) FpscrExc;
1767 uint64_t mid = ((uint64_t)FpOp1P0_uw | ((uint64_t)FpOp1P1_uw << 32));
1768 VfpSavedState state = prepFpState(fpscr.rMode);
1769 __asm__ __volatile__("" : "=m" (mid) : "m" (mid));
1770 double cDest = vfpUFixedToFpD(fpscr.fz, fpscr.dn, mid, 16, imm);
1771 __asm__ __volatile__("" :: "m" (cDest));
1772 finishVfp(fpscr, state, fpscr.fz);
1773 FpDestP0_uw = dblLow(cDest);
1774 FpDestP1_uw = dblHi(cDest);
1775 FpscrExc = fpscr;
1776 '''
1777 vcvtUHFixedFpDIop = InstObjParams("vcvt", "VcvtUHFixedFpD",
1778 "FpRegRegImmOp",
1779 { "code": vcvtUHFixedFpDCode,
1780 "predicate_test": predicateTest,
1781 "op_class": "SimdFloatCvtOp" }, [])
1782 header_output += FpRegRegImmOpDeclare.subst(vcvtUHFixedFpDIop);
1783 decoder_output += FpRegRegImmOpConstructor.subst(vcvtUHFixedFpDIop);
1784 exec_output += PredOpExecute.subst(vcvtUHFixedFpDIop);
1785}};