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