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