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