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