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