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