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