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