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