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