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