fp.isa revision 7398:063002e7106b
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    vcvtFpHTFpSCode = '''
916        FPSCR fpscr = Fpscr;
917        vfpFlushToZero(fpscr, FpOp1);
918        VfpSavedState state = prepFpState(fpscr.rMode);
919        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
920        FpDest = vcvtFpHFpS(fpscr, FpOp1, true);
921        __asm__ __volatile__("" :: "m" (FpDest));
922        finishVfp(fpscr, state);
923        Fpscr = fpscr;
924    '''
925    vcvtFpHTFpSIop = InstObjParams("vcvtt", "VcvtFpHTFpS", "FpRegRegOp",
926                                   { "code": vcvtFpHTFpSCode,
927                                     "predicate_test": predicateTest }, [])
928    header_output += FpRegRegOpDeclare.subst(vcvtFpHTFpSIop);
929    decoder_output += FpRegRegOpConstructor.subst(vcvtFpHTFpSIop);
930    exec_output += PredOpExecute.subst(vcvtFpHTFpSIop);
931
932    vcvtFpHBFpSCode = '''
933        FPSCR fpscr = Fpscr;
934        VfpSavedState state = prepFpState(fpscr.rMode);
935        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
936        FpDest = vcvtFpHFpS(fpscr, FpOp1, false);
937        __asm__ __volatile__("" :: "m" (FpDest));
938        finishVfp(fpscr, state);
939        Fpscr = fpscr;
940    '''
941    vcvtFpHBFpSIop = InstObjParams("vcvtb", "VcvtFpHBFpS", "FpRegRegOp",
942                                   { "code": vcvtFpHBFpSCode,
943                                     "predicate_test": predicateTest }, [])
944    header_output += FpRegRegOpDeclare.subst(vcvtFpHBFpSIop);
945    decoder_output += FpRegRegOpConstructor.subst(vcvtFpHBFpSIop);
946    exec_output += PredOpExecute.subst(vcvtFpHBFpSIop);
947
948    vcvtFpSFpHTCode = '''
949        FPSCR fpscr = Fpscr;
950        vfpFlushToZero(fpscr, FpOp1);
951        VfpSavedState state = prepFpState(fpscr.rMode);
952        __asm__ __volatile__("" : "=m" (FpOp1), "=m" (FpDest)
953                                : "m" (FpOp1), "m" (FpDest));
954        FpDest = vcvtFpSFpH(fpscr, FpOp1, FpDest, true);
955        __asm__ __volatile__("" :: "m" (FpDest));
956        finishVfp(fpscr, state);
957        Fpscr = fpscr;
958    '''
959    vcvtFpSFpHTIop = InstObjParams("vcvtt", "VcvtFpSFpHT", "FpRegRegOp",
960                                    { "code": vcvtFpHTFpSCode,
961                                      "predicate_test": predicateTest }, [])
962    header_output += FpRegRegOpDeclare.subst(vcvtFpSFpHTIop);
963    decoder_output += FpRegRegOpConstructor.subst(vcvtFpSFpHTIop);
964    exec_output += PredOpExecute.subst(vcvtFpSFpHTIop);
965
966    vcvtFpSFpHBCode = '''
967        FPSCR fpscr = Fpscr;
968        vfpFlushToZero(fpscr, FpOp1);
969        VfpSavedState state = prepFpState(fpscr.rMode);
970        __asm__ __volatile__("" : "=m" (FpOp1), "=m" (FpDest)
971                                : "m" (FpOp1), "m" (FpDest));
972        FpDest = vcvtFpSFpH(fpscr, FpOp1, FpDest, false);
973        __asm__ __volatile__("" :: "m" (FpDest));
974        finishVfp(fpscr, state);
975        Fpscr = fpscr;
976    '''
977    vcvtFpSFpHBIop = InstObjParams("vcvtb", "VcvtFpSFpHB", "FpRegRegOp",
978                                   { "code": vcvtFpSFpHBCode,
979                                     "predicate_test": predicateTest }, [])
980    header_output += FpRegRegOpDeclare.subst(vcvtFpSFpHBIop);
981    decoder_output += FpRegRegOpConstructor.subst(vcvtFpSFpHBIop);
982    exec_output += PredOpExecute.subst(vcvtFpSFpHBIop);
983
984    vcmpSCode = '''
985        FPSCR fpscr = Fpscr;
986        vfpFlushToZero(fpscr, FpDest, FpOp1);
987        if (FpDest == FpOp1) {
988            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
989        } else if (FpDest < FpOp1) {
990            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
991        } else if (FpDest > FpOp1) {
992            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
993        } else {
994            const uint32_t qnan = 0x7fc00000;
995            const bool nan1 = std::isnan(FpDest);
996            const bool signal1 = nan1 && ((fpToBits(FpDest) & qnan) != qnan);
997            const bool nan2 = std::isnan(FpOp1);
998            const bool signal2 = nan2 && ((fpToBits(FpOp1) & qnan) != qnan);
999            if (signal1 || signal2)
1000                fpscr.ioc = 1;
1001            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1002        }
1003        Fpscr = fpscr;
1004    '''
1005    vcmpSIop = InstObjParams("vcmps", "VcmpS", "FpRegRegOp",
1006                                     { "code": vcmpSCode,
1007                                       "predicate_test": predicateTest }, [])
1008    header_output += FpRegRegOpDeclare.subst(vcmpSIop);
1009    decoder_output += FpRegRegOpConstructor.subst(vcmpSIop);
1010    exec_output += PredOpExecute.subst(vcmpSIop);
1011
1012    vcmpDCode = '''
1013        double cOp1 = dbl(FpOp1P0.uw, FpOp1P1.uw);
1014        double cDest = dbl(FpDestP0.uw, FpDestP1.uw);
1015        FPSCR fpscr = Fpscr;
1016        vfpFlushToZero(fpscr, cDest, cOp1);
1017        if (cDest == cOp1) {
1018            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1019        } else if (cDest < cOp1) {
1020            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1021        } else if (cDest > cOp1) {
1022            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1023        } else {
1024            const uint64_t qnan = ULL(0x7ff8000000000000);
1025            const bool nan1 = std::isnan(cDest);
1026            const bool signal1 = nan1 && ((fpToBits(cDest) & qnan) != qnan);
1027            const bool nan2 = std::isnan(cOp1);
1028            const bool signal2 = nan2 && ((fpToBits(cOp1) & qnan) != qnan);
1029            if (signal1 || signal2)
1030                fpscr.ioc = 1;
1031            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1032        }
1033        Fpscr = fpscr;
1034    '''
1035    vcmpDIop = InstObjParams("vcmpd", "VcmpD", "FpRegRegOp",
1036                                     { "code": vcmpDCode,
1037                                       "predicate_test": predicateTest }, [])
1038    header_output += FpRegRegOpDeclare.subst(vcmpDIop);
1039    decoder_output += FpRegRegOpConstructor.subst(vcmpDIop);
1040    exec_output += PredOpExecute.subst(vcmpDIop);
1041
1042    vcmpZeroSCode = '''
1043        FPSCR fpscr = Fpscr;
1044        vfpFlushToZero(fpscr, FpDest);
1045        // This only handles imm == 0 for now.
1046        assert(imm == 0);
1047        if (FpDest == imm) {
1048            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1049        } else if (FpDest < imm) {
1050            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1051        } else if (FpDest > imm) {
1052            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1053        } else {
1054            const uint32_t qnan = 0x7fc00000;
1055            const bool nan = std::isnan(FpDest);
1056            const bool signal = nan && ((fpToBits(FpDest) & qnan) != qnan);
1057            if (signal)
1058                fpscr.ioc = 1;
1059            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1060        }
1061        Fpscr = fpscr;
1062    '''
1063    vcmpZeroSIop = InstObjParams("vcmpZeros", "VcmpZeroS", "FpRegImmOp",
1064                                     { "code": vcmpZeroSCode,
1065                                       "predicate_test": predicateTest }, [])
1066    header_output += FpRegImmOpDeclare.subst(vcmpZeroSIop);
1067    decoder_output += FpRegImmOpConstructor.subst(vcmpZeroSIop);
1068    exec_output += PredOpExecute.subst(vcmpZeroSIop);
1069
1070    vcmpZeroDCode = '''
1071        // This only handles imm == 0 for now.
1072        assert(imm == 0);
1073        double cDest = dbl(FpDestP0.uw, FpDestP1.uw);
1074        FPSCR fpscr = Fpscr;
1075        vfpFlushToZero(fpscr, cDest);
1076        if (cDest == imm) {
1077            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1078        } else if (cDest < imm) {
1079            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1080        } else if (cDest > imm) {
1081            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1082        } else {
1083            const uint64_t qnan = ULL(0x7ff8000000000000);
1084            const bool nan = std::isnan(cDest);
1085            const bool signal = nan && ((fpToBits(cDest) & qnan) != qnan);
1086            if (signal)
1087                fpscr.ioc = 1;
1088            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1089        }
1090        Fpscr = fpscr;
1091    '''
1092    vcmpZeroDIop = InstObjParams("vcmpZerod", "VcmpZeroD", "FpRegImmOp",
1093                                     { "code": vcmpZeroDCode,
1094                                       "predicate_test": predicateTest }, [])
1095    header_output += FpRegImmOpDeclare.subst(vcmpZeroDIop);
1096    decoder_output += FpRegImmOpConstructor.subst(vcmpZeroDIop);
1097    exec_output += PredOpExecute.subst(vcmpZeroDIop);
1098
1099    vcmpeSCode = '''
1100        FPSCR fpscr = Fpscr;
1101        vfpFlushToZero(fpscr, FpDest, FpOp1);
1102        if (FpDest == FpOp1) {
1103            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1104        } else if (FpDest < FpOp1) {
1105            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1106        } else if (FpDest > FpOp1) {
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    vcmpeSIop = InstObjParams("vcmpes", "VcmpeS", "FpRegRegOp",
1115                                     { "code": vcmpeSCode,
1116                                       "predicate_test": predicateTest }, [])
1117    header_output += FpRegRegOpDeclare.subst(vcmpeSIop);
1118    decoder_output += FpRegRegOpConstructor.subst(vcmpeSIop);
1119    exec_output += PredOpExecute.subst(vcmpeSIop);
1120
1121    vcmpeDCode = '''
1122        double cOp1 = dbl(FpOp1P0.uw, FpOp1P1.uw);
1123        double cDest = dbl(FpDestP0.uw, FpDestP1.uw);
1124        FPSCR fpscr = Fpscr;
1125        vfpFlushToZero(fpscr, cDest, cOp1);
1126        if (cDest == cOp1) {
1127            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1128        } else if (cDest < cOp1) {
1129            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1130        } else if (cDest > cOp1) {
1131            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1132        } else {
1133            fpscr.ioc = 1;
1134            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1135        }
1136        Fpscr = fpscr;
1137    '''
1138    vcmpeDIop = InstObjParams("vcmped", "VcmpeD", "FpRegRegOp",
1139                                     { "code": vcmpeDCode,
1140                                       "predicate_test": predicateTest }, [])
1141    header_output += FpRegRegOpDeclare.subst(vcmpeDIop);
1142    decoder_output += FpRegRegOpConstructor.subst(vcmpeDIop);
1143    exec_output += PredOpExecute.subst(vcmpeDIop);
1144
1145    vcmpeZeroSCode = '''
1146        FPSCR fpscr = Fpscr;
1147        vfpFlushToZero(fpscr, FpDest);
1148        if (FpDest == imm) {
1149            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1150        } else if (FpDest < imm) {
1151            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1152        } else if (FpDest > imm) {
1153            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1154        } else {
1155            fpscr.ioc = 1;
1156            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1157        }
1158        Fpscr = fpscr;
1159    '''
1160    vcmpeZeroSIop = InstObjParams("vcmpeZeros", "VcmpeZeroS", "FpRegImmOp",
1161                                     { "code": vcmpeZeroSCode,
1162                                       "predicate_test": predicateTest }, [])
1163    header_output += FpRegImmOpDeclare.subst(vcmpeZeroSIop);
1164    decoder_output += FpRegImmOpConstructor.subst(vcmpeZeroSIop);
1165    exec_output += PredOpExecute.subst(vcmpeZeroSIop);
1166
1167    vcmpeZeroDCode = '''
1168        double cDest = dbl(FpDestP0.uw, FpDestP1.uw);
1169        FPSCR fpscr = Fpscr;
1170        vfpFlushToZero(fpscr, cDest);
1171        if (cDest == imm) {
1172            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1173        } else if (cDest < imm) {
1174            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1175        } else if (cDest > imm) {
1176            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1177        } else {
1178            fpscr.ioc = 1;
1179            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1180        }
1181        Fpscr = fpscr;
1182    '''
1183    vcmpeZeroDIop = InstObjParams("vcmpeZerod", "VcmpeZeroD", "FpRegImmOp",
1184                                     { "code": vcmpeZeroDCode,
1185                                       "predicate_test": predicateTest }, [])
1186    header_output += FpRegImmOpDeclare.subst(vcmpeZeroDIop);
1187    decoder_output += FpRegImmOpConstructor.subst(vcmpeZeroDIop);
1188    exec_output += PredOpExecute.subst(vcmpeZeroDIop);
1189}};
1190
1191let {{
1192
1193    header_output = ""
1194    decoder_output = ""
1195    exec_output = ""
1196
1197    vcvtFpSFixedSCode = '''
1198        FPSCR fpscr = Fpscr;
1199        vfpFlushToZero(fpscr, FpOp1);
1200        VfpSavedState state = prepFpState(fpscr.rMode);
1201        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1202        FpDest.sw = vfpFpSToFixed(FpOp1, true, false, imm);
1203        __asm__ __volatile__("" :: "m" (FpDest.sw));
1204        finishVfp(fpscr, state);
1205        Fpscr = fpscr;
1206    '''
1207    vcvtFpSFixedSIop = InstObjParams("vcvt", "VcvtFpSFixedS", "FpRegRegImmOp",
1208                                     { "code": vcvtFpSFixedSCode,
1209                                       "predicate_test": predicateTest }, [])
1210    header_output += FpRegRegImmOpDeclare.subst(vcvtFpSFixedSIop);
1211    decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSFixedSIop);
1212    exec_output += PredOpExecute.subst(vcvtFpSFixedSIop);
1213
1214    vcvtFpSFixedDCode = '''
1215        FPSCR fpscr = Fpscr;
1216        double cOp1 = dbl(FpOp1P0.uw, FpOp1P1.uw);
1217        vfpFlushToZero(fpscr, cOp1);
1218        VfpSavedState state = prepFpState(fpscr.rMode);
1219        __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1220        uint64_t mid = vfpFpDToFixed(cOp1, true, false, imm);
1221        __asm__ __volatile__("" :: "m" (mid));
1222        finishVfp(fpscr, state);
1223        Fpscr = fpscr;
1224        FpDestP0.uw = mid;
1225        FpDestP1.uw = mid >> 32;
1226    '''
1227    vcvtFpSFixedDIop = InstObjParams("vcvt", "VcvtFpSFixedD", "FpRegRegImmOp",
1228                                     { "code": vcvtFpSFixedDCode,
1229                                       "predicate_test": predicateTest }, [])
1230    header_output += FpRegRegImmOpDeclare.subst(vcvtFpSFixedDIop);
1231    decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSFixedDIop);
1232    exec_output += PredOpExecute.subst(vcvtFpSFixedDIop);
1233
1234    vcvtFpUFixedSCode = '''
1235        FPSCR fpscr = Fpscr;
1236        vfpFlushToZero(fpscr, FpOp1);
1237        VfpSavedState state = prepFpState(fpscr.rMode);
1238        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1239        FpDest.uw = vfpFpSToFixed(FpOp1, false, false, imm);
1240        __asm__ __volatile__("" :: "m" (FpDest.uw));
1241        finishVfp(fpscr, state);
1242        Fpscr = fpscr;
1243    '''
1244    vcvtFpUFixedSIop = InstObjParams("vcvt", "VcvtFpUFixedS", "FpRegRegImmOp",
1245                                     { "code": vcvtFpUFixedSCode,
1246                                       "predicate_test": predicateTest }, [])
1247    header_output += FpRegRegImmOpDeclare.subst(vcvtFpUFixedSIop);
1248    decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUFixedSIop);
1249    exec_output += PredOpExecute.subst(vcvtFpUFixedSIop);
1250
1251    vcvtFpUFixedDCode = '''
1252        FPSCR fpscr = Fpscr;
1253        double cOp1 = dbl(FpOp1P0.uw, FpOp1P1.uw);
1254        vfpFlushToZero(fpscr, cOp1);
1255        VfpSavedState state = prepFpState(fpscr.rMode);
1256        __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1257        uint64_t mid = vfpFpDToFixed(cOp1, false, false, imm);
1258        __asm__ __volatile__("" :: "m" (mid));
1259        finishVfp(fpscr, state);
1260        Fpscr = fpscr;
1261        FpDestP0.uw = mid;
1262        FpDestP1.uw = mid >> 32;
1263    '''
1264    vcvtFpUFixedDIop = InstObjParams("vcvt", "VcvtFpUFixedD", "FpRegRegImmOp",
1265                                     { "code": vcvtFpUFixedDCode,
1266                                       "predicate_test": predicateTest }, [])
1267    header_output += FpRegRegImmOpDeclare.subst(vcvtFpUFixedDIop);
1268    decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUFixedDIop);
1269    exec_output += PredOpExecute.subst(vcvtFpUFixedDIop);
1270
1271    vcvtSFixedFpSCode = '''
1272        FPSCR fpscr = Fpscr;
1273        VfpSavedState state = prepFpState(fpscr.rMode);
1274        __asm__ __volatile__("" : "=m" (FpOp1.sw) : "m" (FpOp1.sw));
1275        FpDest = vfpSFixedToFpS(Fpscr, FpOp1.sw, false, imm);
1276        __asm__ __volatile__("" :: "m" (FpDest));
1277        finishVfp(fpscr, state);
1278        Fpscr = fpscr;
1279    '''
1280    vcvtSFixedFpSIop = InstObjParams("vcvt", "VcvtSFixedFpS", "FpRegRegImmOp",
1281                                     { "code": vcvtSFixedFpSCode,
1282                                       "predicate_test": predicateTest }, [])
1283    header_output += FpRegRegImmOpDeclare.subst(vcvtSFixedFpSIop);
1284    decoder_output += FpRegRegImmOpConstructor.subst(vcvtSFixedFpSIop);
1285    exec_output += PredOpExecute.subst(vcvtSFixedFpSIop);
1286
1287    vcvtSFixedFpDCode = '''
1288        FPSCR fpscr = Fpscr;
1289        uint64_t mid = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
1290        VfpSavedState state = prepFpState(fpscr.rMode);
1291        __asm__ __volatile__("" : "=m" (mid) : "m" (mid));
1292        double cDest = vfpSFixedToFpD(Fpscr, mid, false, imm);
1293        __asm__ __volatile__("" :: "m" (cDest));
1294        finishVfp(fpscr, state);
1295        Fpscr = fpscr;
1296        FpDestP0.uw = dblLow(cDest);
1297        FpDestP1.uw = dblHi(cDest);
1298    '''
1299    vcvtSFixedFpDIop = InstObjParams("vcvt", "VcvtSFixedFpD", "FpRegRegImmOp",
1300                                     { "code": vcvtSFixedFpDCode,
1301                                       "predicate_test": predicateTest }, [])
1302    header_output += FpRegRegImmOpDeclare.subst(vcvtSFixedFpDIop);
1303    decoder_output += FpRegRegImmOpConstructor.subst(vcvtSFixedFpDIop);
1304    exec_output += PredOpExecute.subst(vcvtSFixedFpDIop);
1305
1306    vcvtUFixedFpSCode = '''
1307        FPSCR fpscr = Fpscr;
1308        VfpSavedState state = prepFpState(fpscr.rMode);
1309        __asm__ __volatile__("" : "=m" (FpOp1.uw) : "m" (FpOp1.uw));
1310        FpDest = vfpUFixedToFpS(Fpscr, FpOp1.uw, false, imm);
1311        __asm__ __volatile__("" :: "m" (FpDest));
1312        finishVfp(fpscr, state);
1313        Fpscr = fpscr;
1314    '''
1315    vcvtUFixedFpSIop = InstObjParams("vcvt", "VcvtUFixedFpS", "FpRegRegImmOp",
1316                                     { "code": vcvtUFixedFpSCode,
1317                                       "predicate_test": predicateTest }, [])
1318    header_output += FpRegRegImmOpDeclare.subst(vcvtUFixedFpSIop);
1319    decoder_output += FpRegRegImmOpConstructor.subst(vcvtUFixedFpSIop);
1320    exec_output += PredOpExecute.subst(vcvtUFixedFpSIop);
1321
1322    vcvtUFixedFpDCode = '''
1323        FPSCR fpscr = Fpscr;
1324        uint64_t mid = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
1325        VfpSavedState state = prepFpState(fpscr.rMode);
1326        __asm__ __volatile__("" : "=m" (mid) : "m" (mid));
1327        double cDest = vfpUFixedToFpD(Fpscr, mid, false, imm);
1328        __asm__ __volatile__("" :: "m" (cDest));
1329        finishVfp(fpscr, state);
1330        Fpscr = fpscr;
1331        FpDestP0.uw = dblLow(cDest);
1332        FpDestP1.uw = dblHi(cDest);
1333    '''
1334    vcvtUFixedFpDIop = InstObjParams("vcvt", "VcvtUFixedFpD", "FpRegRegImmOp",
1335                                     { "code": vcvtUFixedFpDCode,
1336                                       "predicate_test": predicateTest }, [])
1337    header_output += FpRegRegImmOpDeclare.subst(vcvtUFixedFpDIop);
1338    decoder_output += FpRegRegImmOpConstructor.subst(vcvtUFixedFpDIop);
1339    exec_output += PredOpExecute.subst(vcvtUFixedFpDIop);
1340
1341    vcvtFpSHFixedSCode = '''
1342        FPSCR fpscr = Fpscr;
1343        vfpFlushToZero(fpscr, FpOp1);
1344        VfpSavedState state = prepFpState(fpscr.rMode);
1345        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1346        FpDest.sh = vfpFpSToFixed(FpOp1, true, true, imm);
1347        __asm__ __volatile__("" :: "m" (FpDest.sh));
1348        finishVfp(fpscr, state);
1349        Fpscr = fpscr;
1350    '''
1351    vcvtFpSHFixedSIop = InstObjParams("vcvt", "VcvtFpSHFixedS",
1352                                      "FpRegRegImmOp",
1353                                     { "code": vcvtFpSHFixedSCode,
1354                                       "predicate_test": predicateTest }, [])
1355    header_output += FpRegRegImmOpDeclare.subst(vcvtFpSHFixedSIop);
1356    decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSHFixedSIop);
1357    exec_output += PredOpExecute.subst(vcvtFpSHFixedSIop);
1358
1359    vcvtFpSHFixedDCode = '''
1360        FPSCR fpscr = Fpscr;
1361        double cOp1 = dbl(FpOp1P0.uw, FpOp1P1.uw);
1362        vfpFlushToZero(fpscr, cOp1);
1363        VfpSavedState state = prepFpState(fpscr.rMode);
1364        __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1365        uint64_t result = vfpFpDToFixed(cOp1, true, true, imm);
1366        __asm__ __volatile__("" :: "m" (result));
1367        finishVfp(fpscr, state);
1368        Fpscr = fpscr;
1369        FpDestP0.uw = result;
1370        FpDestP1.uw = result >> 32;
1371    '''
1372    vcvtFpSHFixedDIop = InstObjParams("vcvt", "VcvtFpSHFixedD",
1373                                      "FpRegRegImmOp",
1374                                     { "code": vcvtFpSHFixedDCode,
1375                                       "predicate_test": predicateTest }, [])
1376    header_output += FpRegRegImmOpDeclare.subst(vcvtFpSHFixedDIop);
1377    decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSHFixedDIop);
1378    exec_output += PredOpExecute.subst(vcvtFpSHFixedDIop);
1379
1380    vcvtFpUHFixedSCode = '''
1381        FPSCR fpscr = Fpscr;
1382        vfpFlushToZero(fpscr, FpOp1);
1383        VfpSavedState state = prepFpState(fpscr.rMode);
1384        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1385        FpDest.uh = vfpFpSToFixed(FpOp1, false, true, imm);
1386        __asm__ __volatile__("" :: "m" (FpDest.uh));
1387        finishVfp(fpscr, state);
1388        Fpscr = fpscr;
1389    '''
1390    vcvtFpUHFixedSIop = InstObjParams("vcvt", "VcvtFpUHFixedS",
1391                                      "FpRegRegImmOp",
1392                                     { "code": vcvtFpUHFixedSCode,
1393                                       "predicate_test": predicateTest }, [])
1394    header_output += FpRegRegImmOpDeclare.subst(vcvtFpUHFixedSIop);
1395    decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUHFixedSIop);
1396    exec_output += PredOpExecute.subst(vcvtFpUHFixedSIop);
1397
1398    vcvtFpUHFixedDCode = '''
1399        FPSCR fpscr = Fpscr;
1400        double cOp1 = dbl(FpOp1P0.uw, FpOp1P1.uw);
1401        vfpFlushToZero(fpscr, cOp1);
1402        VfpSavedState state = prepFpState(fpscr.rMode);
1403        __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1404        uint64_t mid = vfpFpDToFixed(cOp1, false, true, imm);
1405        __asm__ __volatile__("" :: "m" (mid));
1406        finishVfp(fpscr, state);
1407        Fpscr = fpscr;
1408        FpDestP0.uw = mid;
1409        FpDestP1.uw = mid >> 32;
1410    '''
1411    vcvtFpUHFixedDIop = InstObjParams("vcvt", "VcvtFpUHFixedD",
1412                                      "FpRegRegImmOp",
1413                                     { "code": vcvtFpUHFixedDCode,
1414                                       "predicate_test": predicateTest }, [])
1415    header_output += FpRegRegImmOpDeclare.subst(vcvtFpUHFixedDIop);
1416    decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUHFixedDIop);
1417    exec_output += PredOpExecute.subst(vcvtFpUHFixedDIop);
1418
1419    vcvtSHFixedFpSCode = '''
1420        FPSCR fpscr = Fpscr;
1421        VfpSavedState state = prepFpState(fpscr.rMode);
1422        __asm__ __volatile__("" : "=m" (FpOp1.sh) : "m" (FpOp1.sh));
1423        FpDest = vfpSFixedToFpS(Fpscr, FpOp1.sh, true, imm);
1424        __asm__ __volatile__("" :: "m" (FpDest));
1425        finishVfp(fpscr, state);
1426        Fpscr = fpscr;
1427    '''
1428    vcvtSHFixedFpSIop = InstObjParams("vcvt", "VcvtSHFixedFpS",
1429                                      "FpRegRegImmOp",
1430                                     { "code": vcvtSHFixedFpSCode,
1431                                       "predicate_test": predicateTest }, [])
1432    header_output += FpRegRegImmOpDeclare.subst(vcvtSHFixedFpSIop);
1433    decoder_output += FpRegRegImmOpConstructor.subst(vcvtSHFixedFpSIop);
1434    exec_output += PredOpExecute.subst(vcvtSHFixedFpSIop);
1435
1436    vcvtSHFixedFpDCode = '''
1437        FPSCR fpscr = Fpscr;
1438        uint64_t mid = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
1439        VfpSavedState state = prepFpState(fpscr.rMode);
1440        __asm__ __volatile__("" : "=m" (mid) : "m" (mid));
1441        double cDest = vfpSFixedToFpD(Fpscr, mid, true, imm);
1442        __asm__ __volatile__("" :: "m" (cDest));
1443        finishVfp(fpscr, state);
1444        Fpscr = fpscr;
1445        FpDestP0.uw = dblLow(cDest);
1446        FpDestP1.uw = dblHi(cDest);
1447    '''
1448    vcvtSHFixedFpDIop = InstObjParams("vcvt", "VcvtSHFixedFpD",
1449                                      "FpRegRegImmOp",
1450                                     { "code": vcvtSHFixedFpDCode,
1451                                       "predicate_test": predicateTest }, [])
1452    header_output += FpRegRegImmOpDeclare.subst(vcvtSHFixedFpDIop);
1453    decoder_output += FpRegRegImmOpConstructor.subst(vcvtSHFixedFpDIop);
1454    exec_output += PredOpExecute.subst(vcvtSHFixedFpDIop);
1455
1456    vcvtUHFixedFpSCode = '''
1457        FPSCR fpscr = Fpscr;
1458        VfpSavedState state = prepFpState(fpscr.rMode);
1459        __asm__ __volatile__("" : "=m" (FpOp1.uh) : "m" (FpOp1.uh));
1460        FpDest = vfpUFixedToFpS(Fpscr, FpOp1.uh, true, imm);
1461        __asm__ __volatile__("" :: "m" (FpDest));
1462        finishVfp(fpscr, state);
1463        Fpscr = fpscr;
1464    '''
1465    vcvtUHFixedFpSIop = InstObjParams("vcvt", "VcvtUHFixedFpS",
1466                                      "FpRegRegImmOp",
1467                                     { "code": vcvtUHFixedFpSCode,
1468                                       "predicate_test": predicateTest }, [])
1469    header_output += FpRegRegImmOpDeclare.subst(vcvtUHFixedFpSIop);
1470    decoder_output += FpRegRegImmOpConstructor.subst(vcvtUHFixedFpSIop);
1471    exec_output += PredOpExecute.subst(vcvtUHFixedFpSIop);
1472
1473    vcvtUHFixedFpDCode = '''
1474        FPSCR fpscr = Fpscr;
1475        uint64_t mid = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
1476        VfpSavedState state = prepFpState(fpscr.rMode);
1477        __asm__ __volatile__("" : "=m" (mid) : "m" (mid));
1478        double cDest = vfpUFixedToFpD(Fpscr, mid, true, imm);
1479        __asm__ __volatile__("" :: "m" (cDest));
1480        finishVfp(fpscr, state);
1481        Fpscr = fpscr;
1482        FpDestP0.uw = dblLow(cDest);
1483        FpDestP1.uw = dblHi(cDest);
1484    '''
1485    vcvtUHFixedFpDIop = InstObjParams("vcvt", "VcvtUHFixedFpD",
1486                                      "FpRegRegImmOp",
1487                                     { "code": vcvtUHFixedFpDCode,
1488                                       "predicate_test": predicateTest }, [])
1489    header_output += FpRegRegImmOpDeclare.subst(vcvtUHFixedFpDIop);
1490    decoder_output += FpRegRegImmOpConstructor.subst(vcvtUHFixedFpDIop);
1491    exec_output += PredOpExecute.subst(vcvtUHFixedFpDIop);
1492}};
1493