fp.isa revision 7397:cbd950459a29
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        FPSCR fpscr = Fpscr;
664        VfpSavedState state = prepFpState(fpscr.rMode);
665        __asm__ __volatile__("" : "=m" (FpOp1.uw) : "m" (FpOp1.uw));
666        FpDest = FpOp1.uw;
667        __asm__ __volatile__("" :: "m" (FpDest));
668        finishVfp(fpscr, state);
669        Fpscr = fpscr;
670    '''
671    vcvtUIntFpSIop = InstObjParams("vcvt", "VcvtUIntFpS", "FpRegRegOp",
672                                     { "code": vcvtUIntFpSCode,
673                                       "predicate_test": predicateTest }, [])
674    header_output += FpRegRegOpDeclare.subst(vcvtUIntFpSIop);
675    decoder_output += FpRegRegOpConstructor.subst(vcvtUIntFpSIop);
676    exec_output += PredOpExecute.subst(vcvtUIntFpSIop);
677
678    vcvtUIntFpDCode = '''
679        FPSCR fpscr = Fpscr;
680        VfpSavedState state = prepFpState(fpscr.rMode);
681        __asm__ __volatile__("" : "=m" (FpOp1P0.uw) : "m" (FpOp1P0.uw));
682        double cDest = (uint64_t)FpOp1P0.uw;
683        __asm__ __volatile__("" :: "m" (cDest));
684        finishVfp(fpscr, state);
685        Fpscr = fpscr;
686        FpDestP0.uw = dblLow(cDest);
687        FpDestP1.uw = dblHi(cDest);
688    '''
689    vcvtUIntFpDIop = InstObjParams("vcvt", "VcvtUIntFpD", "FpRegRegOp",
690                                     { "code": vcvtUIntFpDCode,
691                                       "predicate_test": predicateTest }, [])
692    header_output += FpRegRegOpDeclare.subst(vcvtUIntFpDIop);
693    decoder_output += FpRegRegOpConstructor.subst(vcvtUIntFpDIop);
694    exec_output += PredOpExecute.subst(vcvtUIntFpDIop);
695
696    vcvtSIntFpSCode = '''
697        FPSCR fpscr = Fpscr;
698        VfpSavedState state = prepFpState(fpscr.rMode);
699        __asm__ __volatile__("" : "=m" (FpOp1.sw) : "m" (FpOp1.sw));
700        FpDest = FpOp1.sw;
701        __asm__ __volatile__("" :: "m" (FpDest));
702        finishVfp(fpscr, state);
703        Fpscr = fpscr;
704    '''
705    vcvtSIntFpSIop = InstObjParams("vcvt", "VcvtSIntFpS", "FpRegRegOp",
706                                     { "code": vcvtSIntFpSCode,
707                                       "predicate_test": predicateTest }, [])
708    header_output += FpRegRegOpDeclare.subst(vcvtSIntFpSIop);
709    decoder_output += FpRegRegOpConstructor.subst(vcvtSIntFpSIop);
710    exec_output += PredOpExecute.subst(vcvtSIntFpSIop);
711
712    vcvtSIntFpDCode = '''
713        FPSCR fpscr = Fpscr;
714        VfpSavedState state = prepFpState(fpscr.rMode);
715        __asm__ __volatile__("" : "=m" (FpOp1P0.sw) : "m" (FpOp1P0.sw));
716        double cDest = FpOp1P0.sw;
717        __asm__ __volatile__("" :: "m" (cDest));
718        finishVfp(fpscr, state);
719        Fpscr = fpscr;
720        FpDestP0.uw = dblLow(cDest);
721        FpDestP1.uw = dblHi(cDest);
722    '''
723    vcvtSIntFpDIop = InstObjParams("vcvt", "VcvtSIntFpD", "FpRegRegOp",
724                                     { "code": vcvtSIntFpDCode,
725                                       "predicate_test": predicateTest }, [])
726    header_output += FpRegRegOpDeclare.subst(vcvtSIntFpDIop);
727    decoder_output += FpRegRegOpConstructor.subst(vcvtSIntFpDIop);
728    exec_output += PredOpExecute.subst(vcvtSIntFpDIop);
729
730    vcvtFpUIntSRCode = '''
731        FPSCR fpscr = Fpscr;
732        VfpSavedState state = prepFpState(fpscr.rMode);
733        vfpFlushToZero(fpscr, FpOp1);
734        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
735        FpDest.uw = vfpFpSToFixed(FpOp1, false, false, 0, false);
736        __asm__ __volatile__("" :: "m" (FpDest.uw));
737        finishVfp(fpscr, state);
738        Fpscr = fpscr;
739    '''
740    vcvtFpUIntSRIop = InstObjParams("vcvt", "VcvtFpUIntSR", "FpRegRegOp",
741                                     { "code": vcvtFpUIntSRCode,
742                                       "predicate_test": predicateTest }, [])
743    header_output += FpRegRegOpDeclare.subst(vcvtFpUIntSRIop);
744    decoder_output += FpRegRegOpConstructor.subst(vcvtFpUIntSRIop);
745    exec_output += PredOpExecute.subst(vcvtFpUIntSRIop);
746
747    vcvtFpUIntDRCode = '''
748        FPSCR fpscr = Fpscr;
749        double cOp1 = dbl(FpOp1P0.uw, FpOp1P1.uw);
750        vfpFlushToZero(fpscr, cOp1);
751        VfpSavedState state = prepFpState(fpscr.rMode);
752        __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
753        uint64_t result = vfpFpDToFixed(cOp1, false, false, 0, false);
754        __asm__ __volatile__("" :: "m" (result));
755        finishVfp(fpscr, state);
756        Fpscr = fpscr;
757        FpDestP0.uw = result;
758    '''
759    vcvtFpUIntDRIop = InstObjParams("vcvtr", "VcvtFpUIntDR", "FpRegRegOp",
760                                     { "code": vcvtFpUIntDRCode,
761                                       "predicate_test": predicateTest }, [])
762    header_output += FpRegRegOpDeclare.subst(vcvtFpUIntDRIop);
763    decoder_output += FpRegRegOpConstructor.subst(vcvtFpUIntDRIop);
764    exec_output += PredOpExecute.subst(vcvtFpUIntDRIop);
765
766    vcvtFpSIntSRCode = '''
767        FPSCR fpscr = Fpscr;
768        VfpSavedState state = prepFpState(fpscr.rMode);
769        vfpFlushToZero(fpscr, FpOp1);
770        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
771        FpDest.sw = vfpFpSToFixed(FpOp1, true, false, 0, false);
772        __asm__ __volatile__("" :: "m" (FpDest.sw));
773        finishVfp(fpscr, state);
774        Fpscr = fpscr;
775    '''
776    vcvtFpSIntSRIop = InstObjParams("vcvtr", "VcvtFpSIntSR", "FpRegRegOp",
777                                     { "code": vcvtFpSIntSRCode,
778                                       "predicate_test": predicateTest }, [])
779    header_output += FpRegRegOpDeclare.subst(vcvtFpSIntSRIop);
780    decoder_output += FpRegRegOpConstructor.subst(vcvtFpSIntSRIop);
781    exec_output += PredOpExecute.subst(vcvtFpSIntSRIop);
782
783    vcvtFpSIntDRCode = '''
784        FPSCR fpscr = Fpscr;
785        double cOp1 = dbl(FpOp1P0.uw, FpOp1P1.uw);
786        vfpFlushToZero(fpscr, cOp1);
787        VfpSavedState state = prepFpState(fpscr.rMode);
788        __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
789        int64_t result = vfpFpDToFixed(cOp1, true, false, 0, false);
790        __asm__ __volatile__("" :: "m" (result));
791        finishVfp(fpscr, state);
792        Fpscr = fpscr;
793        FpDestP0.uw = result;
794    '''
795    vcvtFpSIntDRIop = InstObjParams("vcvtr", "VcvtFpSIntDR", "FpRegRegOp",
796                                     { "code": vcvtFpSIntDRCode,
797                                       "predicate_test": predicateTest }, [])
798    header_output += FpRegRegOpDeclare.subst(vcvtFpSIntDRIop);
799    decoder_output += FpRegRegOpConstructor.subst(vcvtFpSIntDRIop);
800    exec_output += PredOpExecute.subst(vcvtFpSIntDRIop);
801
802    vcvtFpUIntSCode = '''
803        FPSCR fpscr = Fpscr;
804        vfpFlushToZero(fpscr, FpOp1);
805        VfpSavedState state = prepFpState(fpscr.rMode);
806        fesetround(FeRoundZero);
807        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
808        FpDest.uw = vfpFpSToFixed(FpOp1, false, false, 0);
809        __asm__ __volatile__("" :: "m" (FpDest.uw));
810        finishVfp(fpscr, state);
811        Fpscr = fpscr;
812    '''
813    vcvtFpUIntSIop = InstObjParams("vcvt", "VcvtFpUIntS", "FpRegRegOp",
814                                     { "code": vcvtFpUIntSCode,
815                                       "predicate_test": predicateTest }, [])
816    header_output += FpRegRegOpDeclare.subst(vcvtFpUIntSIop);
817    decoder_output += FpRegRegOpConstructor.subst(vcvtFpUIntSIop);
818    exec_output += PredOpExecute.subst(vcvtFpUIntSIop);
819
820    vcvtFpUIntDCode = '''
821        FPSCR fpscr = Fpscr;
822        double cOp1 = dbl(FpOp1P0.uw, FpOp1P1.uw);
823        vfpFlushToZero(fpscr, cOp1);
824        VfpSavedState state = prepFpState(fpscr.rMode);
825        fesetround(FeRoundZero);
826        __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
827        uint64_t result = vfpFpDToFixed(cOp1, false, false, 0);
828        __asm__ __volatile__("" :: "m" (result));
829        finishVfp(fpscr, state);
830        Fpscr = fpscr;
831        FpDestP0.uw = result;
832    '''
833    vcvtFpUIntDIop = InstObjParams("vcvt", "VcvtFpUIntD", "FpRegRegOp",
834                                     { "code": vcvtFpUIntDCode,
835                                       "predicate_test": predicateTest }, [])
836    header_output += FpRegRegOpDeclare.subst(vcvtFpUIntDIop);
837    decoder_output += FpRegRegOpConstructor.subst(vcvtFpUIntDIop);
838    exec_output += PredOpExecute.subst(vcvtFpUIntDIop);
839
840    vcvtFpSIntSCode = '''
841        FPSCR fpscr = Fpscr;
842        vfpFlushToZero(fpscr, FpOp1);
843        VfpSavedState state = prepFpState(fpscr.rMode);
844        fesetround(FeRoundZero);
845        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
846        FpDest.sw = vfpFpSToFixed(FpOp1, true, false, 0);
847        __asm__ __volatile__("" :: "m" (FpDest.sw));
848        finishVfp(fpscr, state);
849        Fpscr = fpscr;
850    '''
851    vcvtFpSIntSIop = InstObjParams("vcvt", "VcvtFpSIntS", "FpRegRegOp",
852                                     { "code": vcvtFpSIntSCode,
853                                       "predicate_test": predicateTest }, [])
854    header_output += FpRegRegOpDeclare.subst(vcvtFpSIntSIop);
855    decoder_output += FpRegRegOpConstructor.subst(vcvtFpSIntSIop);
856    exec_output += PredOpExecute.subst(vcvtFpSIntSIop);
857
858    vcvtFpSIntDCode = '''
859        FPSCR fpscr = Fpscr;
860        double cOp1 = dbl(FpOp1P0.uw, FpOp1P1.uw);
861        vfpFlushToZero(fpscr, cOp1);
862        VfpSavedState state = prepFpState(fpscr.rMode);
863        fesetround(FeRoundZero);
864        __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
865        int64_t result = vfpFpDToFixed(cOp1, true, false, 0);
866        __asm__ __volatile__("" :: "m" (result));
867        finishVfp(fpscr, state);
868        Fpscr = fpscr;
869        FpDestP0.uw = result;
870    '''
871    vcvtFpSIntDIop = InstObjParams("vcvt", "VcvtFpSIntD", "FpRegRegOp",
872                                     { "code": vcvtFpSIntDCode,
873                                       "predicate_test": predicateTest }, [])
874    header_output += FpRegRegOpDeclare.subst(vcvtFpSIntDIop);
875    decoder_output += FpRegRegOpConstructor.subst(vcvtFpSIntDIop);
876    exec_output += PredOpExecute.subst(vcvtFpSIntDIop);
877
878    vcvtFpSFpDCode = '''
879        FPSCR fpscr = Fpscr;
880        vfpFlushToZero(fpscr, FpOp1);
881        VfpSavedState state = prepFpState(fpscr.rMode);
882        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
883        double cDest = fixFpSFpDDest(Fpscr, FpOp1);
884        __asm__ __volatile__("" :: "m" (cDest));
885        finishVfp(fpscr, state);
886        Fpscr = fpscr;
887        FpDestP0.uw = dblLow(cDest);
888        FpDestP1.uw = dblHi(cDest);
889    '''
890    vcvtFpSFpDIop = InstObjParams("vcvt", "VcvtFpSFpD", "FpRegRegOp",
891                                     { "code": vcvtFpSFpDCode,
892                                       "predicate_test": predicateTest }, [])
893    header_output += FpRegRegOpDeclare.subst(vcvtFpSFpDIop);
894    decoder_output += FpRegRegOpConstructor.subst(vcvtFpSFpDIop);
895    exec_output += PredOpExecute.subst(vcvtFpSFpDIop);
896
897    vcvtFpDFpSCode = '''
898        FPSCR fpscr = Fpscr;
899        double cOp1 = dbl(FpOp1P0.uw, FpOp1P1.uw);
900        vfpFlushToZero(fpscr, cOp1);
901        VfpSavedState state = prepFpState(fpscr.rMode);
902        __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
903        FpDest = fixFpDFpSDest(Fpscr, cOp1);
904        __asm__ __volatile__("" :: "m" (FpDest));
905        finishVfp(fpscr, state);
906        Fpscr = fpscr;
907    '''
908    vcvtFpDFpSIop = InstObjParams("vcvt", "VcvtFpDFpS", "FpRegRegOp",
909                                     { "code": vcvtFpDFpSCode,
910                                       "predicate_test": predicateTest }, [])
911    header_output += FpRegRegOpDeclare.subst(vcvtFpDFpSIop);
912    decoder_output += FpRegRegOpConstructor.subst(vcvtFpDFpSIop);
913    exec_output += PredOpExecute.subst(vcvtFpDFpSIop);
914
915    vcmpSCode = '''
916        FPSCR fpscr = Fpscr;
917        vfpFlushToZero(fpscr, FpDest, FpOp1);
918        if (FpDest == FpOp1) {
919            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
920        } else if (FpDest < FpOp1) {
921            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
922        } else if (FpDest > FpOp1) {
923            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
924        } else {
925            const uint32_t qnan = 0x7fc00000;
926            const bool nan1 = std::isnan(FpDest);
927            const bool signal1 = nan1 && ((fpToBits(FpDest) & qnan) != qnan);
928            const bool nan2 = std::isnan(FpOp1);
929            const bool signal2 = nan2 && ((fpToBits(FpOp1) & qnan) != qnan);
930            if (signal1 || signal2)
931                fpscr.ioc = 1;
932            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
933        }
934        Fpscr = fpscr;
935    '''
936    vcmpSIop = InstObjParams("vcmps", "VcmpS", "FpRegRegOp",
937                                     { "code": vcmpSCode,
938                                       "predicate_test": predicateTest }, [])
939    header_output += FpRegRegOpDeclare.subst(vcmpSIop);
940    decoder_output += FpRegRegOpConstructor.subst(vcmpSIop);
941    exec_output += PredOpExecute.subst(vcmpSIop);
942
943    vcmpDCode = '''
944        double cOp1 = dbl(FpOp1P0.uw, FpOp1P1.uw);
945        double cDest = dbl(FpDestP0.uw, FpDestP1.uw);
946        FPSCR fpscr = Fpscr;
947        vfpFlushToZero(fpscr, cDest, cOp1);
948        if (cDest == cOp1) {
949            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
950        } else if (cDest < cOp1) {
951            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
952        } else if (cDest > cOp1) {
953            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
954        } else {
955            const uint64_t qnan = ULL(0x7ff8000000000000);
956            const bool nan1 = std::isnan(cDest);
957            const bool signal1 = nan1 && ((fpToBits(cDest) & qnan) != qnan);
958            const bool nan2 = std::isnan(cOp1);
959            const bool signal2 = nan2 && ((fpToBits(cOp1) & qnan) != qnan);
960            if (signal1 || signal2)
961                fpscr.ioc = 1;
962            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
963        }
964        Fpscr = fpscr;
965    '''
966    vcmpDIop = InstObjParams("vcmpd", "VcmpD", "FpRegRegOp",
967                                     { "code": vcmpDCode,
968                                       "predicate_test": predicateTest }, [])
969    header_output += FpRegRegOpDeclare.subst(vcmpDIop);
970    decoder_output += FpRegRegOpConstructor.subst(vcmpDIop);
971    exec_output += PredOpExecute.subst(vcmpDIop);
972
973    vcmpZeroSCode = '''
974        FPSCR fpscr = Fpscr;
975        vfpFlushToZero(fpscr, FpDest);
976        // This only handles imm == 0 for now.
977        assert(imm == 0);
978        if (FpDest == imm) {
979            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
980        } else if (FpDest < imm) {
981            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
982        } else if (FpDest > imm) {
983            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
984        } else {
985            const uint32_t qnan = 0x7fc00000;
986            const bool nan = std::isnan(FpDest);
987            const bool signal = nan && ((fpToBits(FpDest) & qnan) != qnan);
988            if (signal)
989                fpscr.ioc = 1;
990            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
991        }
992        Fpscr = fpscr;
993    '''
994    vcmpZeroSIop = InstObjParams("vcmpZeros", "VcmpZeroS", "FpRegImmOp",
995                                     { "code": vcmpZeroSCode,
996                                       "predicate_test": predicateTest }, [])
997    header_output += FpRegImmOpDeclare.subst(vcmpZeroSIop);
998    decoder_output += FpRegImmOpConstructor.subst(vcmpZeroSIop);
999    exec_output += PredOpExecute.subst(vcmpZeroSIop);
1000
1001    vcmpZeroDCode = '''
1002        // This only handles imm == 0 for now.
1003        assert(imm == 0);
1004        double cDest = dbl(FpDestP0.uw, FpDestP1.uw);
1005        FPSCR fpscr = Fpscr;
1006        vfpFlushToZero(fpscr, cDest);
1007        if (cDest == imm) {
1008            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1009        } else if (cDest < imm) {
1010            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1011        } else if (cDest > imm) {
1012            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1013        } else {
1014            const uint64_t qnan = ULL(0x7ff8000000000000);
1015            const bool nan = std::isnan(cDest);
1016            const bool signal = nan && ((fpToBits(cDest) & qnan) != qnan);
1017            if (signal)
1018                fpscr.ioc = 1;
1019            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1020        }
1021        Fpscr = fpscr;
1022    '''
1023    vcmpZeroDIop = InstObjParams("vcmpZerod", "VcmpZeroD", "FpRegImmOp",
1024                                     { "code": vcmpZeroDCode,
1025                                       "predicate_test": predicateTest }, [])
1026    header_output += FpRegImmOpDeclare.subst(vcmpZeroDIop);
1027    decoder_output += FpRegImmOpConstructor.subst(vcmpZeroDIop);
1028    exec_output += PredOpExecute.subst(vcmpZeroDIop);
1029
1030    vcmpeSCode = '''
1031        FPSCR fpscr = Fpscr;
1032        vfpFlushToZero(fpscr, FpDest, FpOp1);
1033        if (FpDest == FpOp1) {
1034            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1035        } else if (FpDest < FpOp1) {
1036            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1037        } else if (FpDest > FpOp1) {
1038            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1039        } else {
1040            fpscr.ioc = 1;
1041            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1042        }
1043        Fpscr = fpscr;
1044    '''
1045    vcmpeSIop = InstObjParams("vcmpes", "VcmpeS", "FpRegRegOp",
1046                                     { "code": vcmpeSCode,
1047                                       "predicate_test": predicateTest }, [])
1048    header_output += FpRegRegOpDeclare.subst(vcmpeSIop);
1049    decoder_output += FpRegRegOpConstructor.subst(vcmpeSIop);
1050    exec_output += PredOpExecute.subst(vcmpeSIop);
1051
1052    vcmpeDCode = '''
1053        double cOp1 = dbl(FpOp1P0.uw, FpOp1P1.uw);
1054        double cDest = dbl(FpDestP0.uw, FpDestP1.uw);
1055        FPSCR fpscr = Fpscr;
1056        vfpFlushToZero(fpscr, cDest, cOp1);
1057        if (cDest == cOp1) {
1058            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1059        } else if (cDest < cOp1) {
1060            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1061        } else if (cDest > cOp1) {
1062            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1063        } else {
1064            fpscr.ioc = 1;
1065            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1066        }
1067        Fpscr = fpscr;
1068    '''
1069    vcmpeDIop = InstObjParams("vcmped", "VcmpeD", "FpRegRegOp",
1070                                     { "code": vcmpeDCode,
1071                                       "predicate_test": predicateTest }, [])
1072    header_output += FpRegRegOpDeclare.subst(vcmpeDIop);
1073    decoder_output += FpRegRegOpConstructor.subst(vcmpeDIop);
1074    exec_output += PredOpExecute.subst(vcmpeDIop);
1075
1076    vcmpeZeroSCode = '''
1077        FPSCR fpscr = Fpscr;
1078        vfpFlushToZero(fpscr, FpDest);
1079        if (FpDest == imm) {
1080            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1081        } else if (FpDest < imm) {
1082            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1083        } else if (FpDest > imm) {
1084            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1085        } else {
1086            fpscr.ioc = 1;
1087            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1088        }
1089        Fpscr = fpscr;
1090    '''
1091    vcmpeZeroSIop = InstObjParams("vcmpeZeros", "VcmpeZeroS", "FpRegImmOp",
1092                                     { "code": vcmpeZeroSCode,
1093                                       "predicate_test": predicateTest }, [])
1094    header_output += FpRegImmOpDeclare.subst(vcmpeZeroSIop);
1095    decoder_output += FpRegImmOpConstructor.subst(vcmpeZeroSIop);
1096    exec_output += PredOpExecute.subst(vcmpeZeroSIop);
1097
1098    vcmpeZeroDCode = '''
1099        double cDest = dbl(FpDestP0.uw, FpDestP1.uw);
1100        FPSCR fpscr = Fpscr;
1101        vfpFlushToZero(fpscr, cDest);
1102        if (cDest == imm) {
1103            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1104        } else if (cDest < imm) {
1105            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1106        } else if (cDest > imm) {
1107            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1108        } else {
1109            fpscr.ioc = 1;
1110            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1111        }
1112        Fpscr = fpscr;
1113    '''
1114    vcmpeZeroDIop = InstObjParams("vcmpeZerod", "VcmpeZeroD", "FpRegImmOp",
1115                                     { "code": vcmpeZeroDCode,
1116                                       "predicate_test": predicateTest }, [])
1117    header_output += FpRegImmOpDeclare.subst(vcmpeZeroDIop);
1118    decoder_output += FpRegImmOpConstructor.subst(vcmpeZeroDIop);
1119    exec_output += PredOpExecute.subst(vcmpeZeroDIop);
1120}};
1121
1122let {{
1123
1124    header_output = ""
1125    decoder_output = ""
1126    exec_output = ""
1127
1128    vcvtFpSFixedSCode = '''
1129        FPSCR fpscr = Fpscr;
1130        vfpFlushToZero(fpscr, FpOp1);
1131        VfpSavedState state = prepFpState(fpscr.rMode);
1132        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1133        FpDest.sw = vfpFpSToFixed(FpOp1, true, false, imm);
1134        __asm__ __volatile__("" :: "m" (FpDest.sw));
1135        finishVfp(fpscr, state);
1136        Fpscr = fpscr;
1137    '''
1138    vcvtFpSFixedSIop = InstObjParams("vcvt", "VcvtFpSFixedS", "FpRegRegImmOp",
1139                                     { "code": vcvtFpSFixedSCode,
1140                                       "predicate_test": predicateTest }, [])
1141    header_output += FpRegRegImmOpDeclare.subst(vcvtFpSFixedSIop);
1142    decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSFixedSIop);
1143    exec_output += PredOpExecute.subst(vcvtFpSFixedSIop);
1144
1145    vcvtFpSFixedDCode = '''
1146        FPSCR fpscr = Fpscr;
1147        double cOp1 = dbl(FpOp1P0.uw, FpOp1P1.uw);
1148        vfpFlushToZero(fpscr, cOp1);
1149        VfpSavedState state = prepFpState(fpscr.rMode);
1150        __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1151        uint64_t mid = vfpFpDToFixed(cOp1, true, false, imm);
1152        __asm__ __volatile__("" :: "m" (mid));
1153        finishVfp(fpscr, state);
1154        Fpscr = fpscr;
1155        FpDestP0.uw = mid;
1156        FpDestP1.uw = mid >> 32;
1157    '''
1158    vcvtFpSFixedDIop = InstObjParams("vcvt", "VcvtFpSFixedD", "FpRegRegImmOp",
1159                                     { "code": vcvtFpSFixedDCode,
1160                                       "predicate_test": predicateTest }, [])
1161    header_output += FpRegRegImmOpDeclare.subst(vcvtFpSFixedDIop);
1162    decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSFixedDIop);
1163    exec_output += PredOpExecute.subst(vcvtFpSFixedDIop);
1164
1165    vcvtFpUFixedSCode = '''
1166        FPSCR fpscr = Fpscr;
1167        vfpFlushToZero(fpscr, FpOp1);
1168        VfpSavedState state = prepFpState(fpscr.rMode);
1169        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1170        FpDest.uw = vfpFpSToFixed(FpOp1, false, false, imm);
1171        __asm__ __volatile__("" :: "m" (FpDest.uw));
1172        finishVfp(fpscr, state);
1173        Fpscr = fpscr;
1174    '''
1175    vcvtFpUFixedSIop = InstObjParams("vcvt", "VcvtFpUFixedS", "FpRegRegImmOp",
1176                                     { "code": vcvtFpUFixedSCode,
1177                                       "predicate_test": predicateTest }, [])
1178    header_output += FpRegRegImmOpDeclare.subst(vcvtFpUFixedSIop);
1179    decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUFixedSIop);
1180    exec_output += PredOpExecute.subst(vcvtFpUFixedSIop);
1181
1182    vcvtFpUFixedDCode = '''
1183        FPSCR fpscr = Fpscr;
1184        double cOp1 = dbl(FpOp1P0.uw, FpOp1P1.uw);
1185        vfpFlushToZero(fpscr, cOp1);
1186        VfpSavedState state = prepFpState(fpscr.rMode);
1187        __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1188        uint64_t mid = vfpFpDToFixed(cOp1, false, false, imm);
1189        __asm__ __volatile__("" :: "m" (mid));
1190        finishVfp(fpscr, state);
1191        Fpscr = fpscr;
1192        FpDestP0.uw = mid;
1193        FpDestP1.uw = mid >> 32;
1194    '''
1195    vcvtFpUFixedDIop = InstObjParams("vcvt", "VcvtFpUFixedD", "FpRegRegImmOp",
1196                                     { "code": vcvtFpUFixedDCode,
1197                                       "predicate_test": predicateTest }, [])
1198    header_output += FpRegRegImmOpDeclare.subst(vcvtFpUFixedDIop);
1199    decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUFixedDIop);
1200    exec_output += PredOpExecute.subst(vcvtFpUFixedDIop);
1201
1202    vcvtSFixedFpSCode = '''
1203        FPSCR fpscr = Fpscr;
1204        VfpSavedState state = prepFpState(fpscr.rMode);
1205        __asm__ __volatile__("" : "=m" (FpOp1.sw) : "m" (FpOp1.sw));
1206        FpDest = vfpSFixedToFpS(Fpscr, FpOp1.sw, false, imm);
1207        __asm__ __volatile__("" :: "m" (FpDest));
1208        finishVfp(fpscr, state);
1209        Fpscr = fpscr;
1210    '''
1211    vcvtSFixedFpSIop = InstObjParams("vcvt", "VcvtSFixedFpS", "FpRegRegImmOp",
1212                                     { "code": vcvtSFixedFpSCode,
1213                                       "predicate_test": predicateTest }, [])
1214    header_output += FpRegRegImmOpDeclare.subst(vcvtSFixedFpSIop);
1215    decoder_output += FpRegRegImmOpConstructor.subst(vcvtSFixedFpSIop);
1216    exec_output += PredOpExecute.subst(vcvtSFixedFpSIop);
1217
1218    vcvtSFixedFpDCode = '''
1219        FPSCR fpscr = Fpscr;
1220        uint64_t mid = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
1221        VfpSavedState state = prepFpState(fpscr.rMode);
1222        __asm__ __volatile__("" : "=m" (mid) : "m" (mid));
1223        double cDest = vfpSFixedToFpD(Fpscr, mid, false, imm);
1224        __asm__ __volatile__("" :: "m" (cDest));
1225        finishVfp(fpscr, state);
1226        Fpscr = fpscr;
1227        FpDestP0.uw = dblLow(cDest);
1228        FpDestP1.uw = dblHi(cDest);
1229    '''
1230    vcvtSFixedFpDIop = InstObjParams("vcvt", "VcvtSFixedFpD", "FpRegRegImmOp",
1231                                     { "code": vcvtSFixedFpDCode,
1232                                       "predicate_test": predicateTest }, [])
1233    header_output += FpRegRegImmOpDeclare.subst(vcvtSFixedFpDIop);
1234    decoder_output += FpRegRegImmOpConstructor.subst(vcvtSFixedFpDIop);
1235    exec_output += PredOpExecute.subst(vcvtSFixedFpDIop);
1236
1237    vcvtUFixedFpSCode = '''
1238        FPSCR fpscr = Fpscr;
1239        VfpSavedState state = prepFpState(fpscr.rMode);
1240        __asm__ __volatile__("" : "=m" (FpOp1.uw) : "m" (FpOp1.uw));
1241        FpDest = vfpUFixedToFpS(Fpscr, FpOp1.uw, false, imm);
1242        __asm__ __volatile__("" :: "m" (FpDest));
1243        finishVfp(fpscr, state);
1244        Fpscr = fpscr;
1245    '''
1246    vcvtUFixedFpSIop = InstObjParams("vcvt", "VcvtUFixedFpS", "FpRegRegImmOp",
1247                                     { "code": vcvtUFixedFpSCode,
1248                                       "predicate_test": predicateTest }, [])
1249    header_output += FpRegRegImmOpDeclare.subst(vcvtUFixedFpSIop);
1250    decoder_output += FpRegRegImmOpConstructor.subst(vcvtUFixedFpSIop);
1251    exec_output += PredOpExecute.subst(vcvtUFixedFpSIop);
1252
1253    vcvtUFixedFpDCode = '''
1254        FPSCR fpscr = Fpscr;
1255        uint64_t mid = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
1256        VfpSavedState state = prepFpState(fpscr.rMode);
1257        __asm__ __volatile__("" : "=m" (mid) : "m" (mid));
1258        double cDest = vfpUFixedToFpD(Fpscr, mid, false, imm);
1259        __asm__ __volatile__("" :: "m" (cDest));
1260        finishVfp(fpscr, state);
1261        Fpscr = fpscr;
1262        FpDestP0.uw = dblLow(cDest);
1263        FpDestP1.uw = dblHi(cDest);
1264    '''
1265    vcvtUFixedFpDIop = InstObjParams("vcvt", "VcvtUFixedFpD", "FpRegRegImmOp",
1266                                     { "code": vcvtUFixedFpDCode,
1267                                       "predicate_test": predicateTest }, [])
1268    header_output += FpRegRegImmOpDeclare.subst(vcvtUFixedFpDIop);
1269    decoder_output += FpRegRegImmOpConstructor.subst(vcvtUFixedFpDIop);
1270    exec_output += PredOpExecute.subst(vcvtUFixedFpDIop);
1271
1272    vcvtFpSHFixedSCode = '''
1273        FPSCR fpscr = Fpscr;
1274        vfpFlushToZero(fpscr, FpOp1);
1275        VfpSavedState state = prepFpState(fpscr.rMode);
1276        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1277        FpDest.sh = vfpFpSToFixed(FpOp1, true, true, imm);
1278        __asm__ __volatile__("" :: "m" (FpDest.sh));
1279        finishVfp(fpscr, state);
1280        Fpscr = fpscr;
1281    '''
1282    vcvtFpSHFixedSIop = InstObjParams("vcvt", "VcvtFpSHFixedS",
1283                                      "FpRegRegImmOp",
1284                                     { "code": vcvtFpSHFixedSCode,
1285                                       "predicate_test": predicateTest }, [])
1286    header_output += FpRegRegImmOpDeclare.subst(vcvtFpSHFixedSIop);
1287    decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSHFixedSIop);
1288    exec_output += PredOpExecute.subst(vcvtFpSHFixedSIop);
1289
1290    vcvtFpSHFixedDCode = '''
1291        FPSCR fpscr = Fpscr;
1292        double cOp1 = dbl(FpOp1P0.uw, FpOp1P1.uw);
1293        vfpFlushToZero(fpscr, cOp1);
1294        VfpSavedState state = prepFpState(fpscr.rMode);
1295        __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1296        uint64_t result = vfpFpDToFixed(cOp1, true, true, imm);
1297        __asm__ __volatile__("" :: "m" (result));
1298        finishVfp(fpscr, state);
1299        Fpscr = fpscr;
1300        FpDestP0.uw = result;
1301        FpDestP1.uw = result >> 32;
1302    '''
1303    vcvtFpSHFixedDIop = InstObjParams("vcvt", "VcvtFpSHFixedD",
1304                                      "FpRegRegImmOp",
1305                                     { "code": vcvtFpSHFixedDCode,
1306                                       "predicate_test": predicateTest }, [])
1307    header_output += FpRegRegImmOpDeclare.subst(vcvtFpSHFixedDIop);
1308    decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSHFixedDIop);
1309    exec_output += PredOpExecute.subst(vcvtFpSHFixedDIop);
1310
1311    vcvtFpUHFixedSCode = '''
1312        FPSCR fpscr = Fpscr;
1313        vfpFlushToZero(fpscr, FpOp1);
1314        VfpSavedState state = prepFpState(fpscr.rMode);
1315        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1316        FpDest.uh = vfpFpSToFixed(FpOp1, false, true, imm);
1317        __asm__ __volatile__("" :: "m" (FpDest.uh));
1318        finishVfp(fpscr, state);
1319        Fpscr = fpscr;
1320    '''
1321    vcvtFpUHFixedSIop = InstObjParams("vcvt", "VcvtFpUHFixedS",
1322                                      "FpRegRegImmOp",
1323                                     { "code": vcvtFpUHFixedSCode,
1324                                       "predicate_test": predicateTest }, [])
1325    header_output += FpRegRegImmOpDeclare.subst(vcvtFpUHFixedSIop);
1326    decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUHFixedSIop);
1327    exec_output += PredOpExecute.subst(vcvtFpUHFixedSIop);
1328
1329    vcvtFpUHFixedDCode = '''
1330        FPSCR fpscr = Fpscr;
1331        double cOp1 = dbl(FpOp1P0.uw, FpOp1P1.uw);
1332        vfpFlushToZero(fpscr, cOp1);
1333        VfpSavedState state = prepFpState(fpscr.rMode);
1334        __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1335        uint64_t mid = vfpFpDToFixed(cOp1, false, true, imm);
1336        __asm__ __volatile__("" :: "m" (mid));
1337        finishVfp(fpscr, state);
1338        Fpscr = fpscr;
1339        FpDestP0.uw = mid;
1340        FpDestP1.uw = mid >> 32;
1341    '''
1342    vcvtFpUHFixedDIop = InstObjParams("vcvt", "VcvtFpUHFixedD",
1343                                      "FpRegRegImmOp",
1344                                     { "code": vcvtFpUHFixedDCode,
1345                                       "predicate_test": predicateTest }, [])
1346    header_output += FpRegRegImmOpDeclare.subst(vcvtFpUHFixedDIop);
1347    decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUHFixedDIop);
1348    exec_output += PredOpExecute.subst(vcvtFpUHFixedDIop);
1349
1350    vcvtSHFixedFpSCode = '''
1351        FPSCR fpscr = Fpscr;
1352        VfpSavedState state = prepFpState(fpscr.rMode);
1353        __asm__ __volatile__("" : "=m" (FpOp1.sh) : "m" (FpOp1.sh));
1354        FpDest = vfpSFixedToFpS(Fpscr, FpOp1.sh, true, imm);
1355        __asm__ __volatile__("" :: "m" (FpDest));
1356        finishVfp(fpscr, state);
1357        Fpscr = fpscr;
1358    '''
1359    vcvtSHFixedFpSIop = InstObjParams("vcvt", "VcvtSHFixedFpS",
1360                                      "FpRegRegImmOp",
1361                                     { "code": vcvtSHFixedFpSCode,
1362                                       "predicate_test": predicateTest }, [])
1363    header_output += FpRegRegImmOpDeclare.subst(vcvtSHFixedFpSIop);
1364    decoder_output += FpRegRegImmOpConstructor.subst(vcvtSHFixedFpSIop);
1365    exec_output += PredOpExecute.subst(vcvtSHFixedFpSIop);
1366
1367    vcvtSHFixedFpDCode = '''
1368        FPSCR fpscr = Fpscr;
1369        uint64_t mid = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
1370        VfpSavedState state = prepFpState(fpscr.rMode);
1371        __asm__ __volatile__("" : "=m" (mid) : "m" (mid));
1372        double cDest = vfpSFixedToFpD(Fpscr, mid, true, imm);
1373        __asm__ __volatile__("" :: "m" (cDest));
1374        finishVfp(fpscr, state);
1375        Fpscr = fpscr;
1376        FpDestP0.uw = dblLow(cDest);
1377        FpDestP1.uw = dblHi(cDest);
1378    '''
1379    vcvtSHFixedFpDIop = InstObjParams("vcvt", "VcvtSHFixedFpD",
1380                                      "FpRegRegImmOp",
1381                                     { "code": vcvtSHFixedFpDCode,
1382                                       "predicate_test": predicateTest }, [])
1383    header_output += FpRegRegImmOpDeclare.subst(vcvtSHFixedFpDIop);
1384    decoder_output += FpRegRegImmOpConstructor.subst(vcvtSHFixedFpDIop);
1385    exec_output += PredOpExecute.subst(vcvtSHFixedFpDIop);
1386
1387    vcvtUHFixedFpSCode = '''
1388        FPSCR fpscr = Fpscr;
1389        VfpSavedState state = prepFpState(fpscr.rMode);
1390        __asm__ __volatile__("" : "=m" (FpOp1.uh) : "m" (FpOp1.uh));
1391        FpDest = vfpUFixedToFpS(Fpscr, FpOp1.uh, true, imm);
1392        __asm__ __volatile__("" :: "m" (FpDest));
1393        finishVfp(fpscr, state);
1394        Fpscr = fpscr;
1395    '''
1396    vcvtUHFixedFpSIop = InstObjParams("vcvt", "VcvtUHFixedFpS",
1397                                      "FpRegRegImmOp",
1398                                     { "code": vcvtUHFixedFpSCode,
1399                                       "predicate_test": predicateTest }, [])
1400    header_output += FpRegRegImmOpDeclare.subst(vcvtUHFixedFpSIop);
1401    decoder_output += FpRegRegImmOpConstructor.subst(vcvtUHFixedFpSIop);
1402    exec_output += PredOpExecute.subst(vcvtUHFixedFpSIop);
1403
1404    vcvtUHFixedFpDCode = '''
1405        FPSCR fpscr = Fpscr;
1406        uint64_t mid = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
1407        VfpSavedState state = prepFpState(fpscr.rMode);
1408        __asm__ __volatile__("" : "=m" (mid) : "m" (mid));
1409        double cDest = vfpUFixedToFpD(Fpscr, mid, true, imm);
1410        __asm__ __volatile__("" :: "m" (cDest));
1411        finishVfp(fpscr, state);
1412        Fpscr = fpscr;
1413        FpDestP0.uw = dblLow(cDest);
1414        FpDestP1.uw = dblHi(cDest);
1415    '''
1416    vcvtUHFixedFpDIop = InstObjParams("vcvt", "VcvtUHFixedFpD",
1417                                      "FpRegRegImmOp",
1418                                     { "code": vcvtUHFixedFpDCode,
1419                                       "predicate_test": predicateTest }, [])
1420    header_output += FpRegRegImmOpDeclare.subst(vcvtUHFixedFpDIop);
1421    decoder_output += FpRegRegImmOpConstructor.subst(vcvtUHFixedFpDIop);
1422    exec_output += PredOpExecute.subst(vcvtUHFixedFpDIop);
1423}};
1424