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