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