fp.isa revision 8301:858384f3af1c
1// -*- mode:c++ -*-
2
3// Copyright (c) 2010 ARM Limited
4// All rights reserved
5//
6// The license below extends only to copyright in the software and shall
7// not be construed as granting a license to any other intellectual
8// property including but not limited to intellectual property relating
9// to a hardware implementation of the functionality of the software
10// licensed hereunder.  You may use the software subject to the license
11// terms below provided that you ensure that this notice is replicated
12// unmodified and in its entirety in all distributions of the software,
13// modified or unmodified, in source code or in binary form.
14//
15// Redistribution and use in source and binary forms, with or without
16// modification, are permitted provided that the following conditions are
17// met: redistributions of source code must retain the above copyright
18// notice, this list of conditions and the following disclaimer;
19// redistributions in binary form must reproduce the above copyright
20// notice, this list of conditions and the following disclaimer in the
21// documentation and/or other materials provided with the distribution;
22// neither the name of the copyright holders nor the names of its
23// contributors may be used to endorse or promote products derived from
24// this software without specific prior written permission.
25//
26// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37//
38// Authors: Gabe Black
39
40output header {{
41
42template <class Micro>
43class VfpMacroRegRegOp : public VfpMacroOp
44{
45  public:
46    VfpMacroRegRegOp(ExtMachInst _machInst, IntRegIndex _dest,
47                     IntRegIndex _op1, bool _wide) :
48        VfpMacroOp("VfpMacroRegRegOp", _machInst, No_OpClass, _wide)
49    {
50        numMicroops = machInst.fpscrLen + 1;
51        assert(numMicroops > 1);
52        microOps = new StaticInstPtr[numMicroops];
53        for (unsigned i = 0; i < numMicroops; i++) {
54            VfpMicroMode mode = VfpMicroop;
55            if (i == 0)
56                mode = VfpFirstMicroop;
57            else if (i == numMicroops - 1)
58                mode = VfpLastMicroop;
59            microOps[i] = new Micro(_machInst, _dest, _op1, mode);
60            nextIdxs(_dest, _op1);
61        }
62    }
63
64    %(BasicExecPanic)s
65};
66
67template <class VfpOp>
68static StaticInstPtr
69decodeVfpRegRegOp(ExtMachInst machInst,
70        IntRegIndex dest, IntRegIndex op1, bool wide)
71{
72    if (machInst.fpscrLen == 0 || VfpMacroOp::inScalarBank(dest)) {
73        return new VfpOp(machInst, dest, op1);
74    } else {
75        return new VfpMacroRegRegOp<VfpOp>(machInst, dest, op1, wide);
76    }
77}
78
79template <class Micro>
80class VfpMacroRegImmOp : public VfpMacroOp
81{
82  public:
83    VfpMacroRegImmOp(ExtMachInst _machInst, IntRegIndex _dest, uint64_t _imm,
84                     bool _wide) :
85        VfpMacroOp("VfpMacroRegImmOp", _machInst, No_OpClass, _wide)
86    {
87        numMicroops = machInst.fpscrLen + 1;
88        microOps = new StaticInstPtr[numMicroops];
89        for (unsigned i = 0; i < numMicroops; i++) {
90            VfpMicroMode mode = VfpMicroop;
91            if (i == 0)
92                mode = VfpFirstMicroop;
93            else if (i == numMicroops - 1)
94                mode = VfpLastMicroop;
95            microOps[i] = new Micro(_machInst, _dest, _imm, mode);
96            nextIdxs(_dest);
97        }
98    }
99
100    %(BasicExecPanic)s
101};
102
103template <class VfpOp>
104static StaticInstPtr
105decodeVfpRegImmOp(ExtMachInst machInst,
106        IntRegIndex dest, uint64_t imm, bool wide)
107{
108    if (machInst.fpscrLen == 0 || VfpMacroOp::inScalarBank(dest)) {
109        return new VfpOp(machInst, dest, imm);
110    } else {
111        return new VfpMacroRegImmOp<VfpOp>(machInst, dest, imm, wide);
112    }
113}
114
115template <class Micro>
116class VfpMacroRegRegImmOp : public VfpMacroOp
117{
118  public:
119    VfpMacroRegRegImmOp(ExtMachInst _machInst, IntRegIndex _dest,
120                        IntRegIndex _op1, uint64_t _imm, bool _wide) :
121        VfpMacroOp("VfpMacroRegRegImmOp", _machInst, No_OpClass, _wide)
122    {
123        numMicroops = machInst.fpscrLen + 1;
124        microOps = new StaticInstPtr[numMicroops];
125        for (unsigned i = 0; i < numMicroops; i++) {
126            VfpMicroMode mode = VfpMicroop;
127            if (i == 0)
128                mode = VfpFirstMicroop;
129            else if (i == numMicroops - 1)
130                mode = VfpLastMicroop;
131            microOps[i] = new Micro(_machInst, _dest, _op1, _imm, mode);
132            nextIdxs(_dest, _op1);
133        }
134    }
135
136    %(BasicExecPanic)s
137};
138
139template <class VfpOp>
140static StaticInstPtr
141decodeVfpRegRegImmOp(ExtMachInst machInst, IntRegIndex dest,
142                     IntRegIndex op1, uint64_t imm, bool wide)
143{
144    if (machInst.fpscrLen == 0 || VfpMacroOp::inScalarBank(dest)) {
145        return new VfpOp(machInst, dest, op1, imm);
146    } else {
147        return new VfpMacroRegRegImmOp<VfpOp>(machInst, dest, op1, imm, wide);
148    }
149}
150
151template <class Micro>
152class VfpMacroRegRegRegOp : public VfpMacroOp
153{
154  public:
155    VfpMacroRegRegRegOp(ExtMachInst _machInst, IntRegIndex _dest,
156                        IntRegIndex _op1, IntRegIndex _op2, bool _wide) :
157        VfpMacroOp("VfpMacroRegRegRegOp", _machInst, No_OpClass, _wide)
158    {
159        numMicroops = machInst.fpscrLen + 1;
160        microOps = new StaticInstPtr[numMicroops];
161        for (unsigned i = 0; i < numMicroops; i++) {
162            VfpMicroMode mode = VfpMicroop;
163            if (i == 0)
164                mode = VfpFirstMicroop;
165            else if (i == numMicroops - 1)
166                mode = VfpLastMicroop;
167            microOps[i] = new Micro(_machInst, _dest, _op1, _op2, mode);
168            nextIdxs(_dest, _op1, _op2);
169        }
170    }
171
172    %(BasicExecPanic)s
173};
174
175template <class VfpOp>
176static StaticInstPtr
177decodeVfpRegRegRegOp(ExtMachInst machInst, IntRegIndex dest,
178                     IntRegIndex op1, IntRegIndex op2, bool wide)
179{
180    if (machInst.fpscrLen == 0 || VfpMacroOp::inScalarBank(dest)) {
181        return new VfpOp(machInst, dest, op1, op2);
182    } else {
183        return new VfpMacroRegRegRegOp<VfpOp>(machInst, dest, op1, op2, wide);
184    }
185}
186}};
187
188let {{
189
190    header_output = ""
191    decoder_output = ""
192    exec_output = ""
193
194    vmsrIop = InstObjParams("vmsr", "Vmsr", "FpRegRegOp",
195                            { "code": vmsrEnabledCheckCode + \
196                                      "MiscDest = Op1;",
197                              "predicate_test": predicateTest,
198                              "op_class": "SimdFloatMiscOp" },
199                             ["IsSerializeAfter","IsNonSpeculative"])
200    header_output += FpRegRegOpDeclare.subst(vmsrIop);
201    decoder_output += FpRegRegOpConstructor.subst(vmsrIop);
202    exec_output += PredOpExecute.subst(vmsrIop);
203
204    vmsrFpscrCode = vmsrEnabledCheckCode + '''
205    Fpscr = Op1 & ~FpCondCodesMask;
206    FpCondCodes = Op1 & FpCondCodesMask;
207    '''
208    vmsrFpscrIop = InstObjParams("vmsr", "VmsrFpscr", "FpRegRegOp",
209                                 { "code": vmsrFpscrCode,
210                                   "predicate_test": predicateTest,
211                                   "op_class": "SimdFloatMiscOp" },
212                                 ["IsSerializeAfter","IsNonSpeculative",
213                                  "IsSquashAfter"])
214    header_output += FpRegRegOpDeclare.subst(vmsrFpscrIop);
215    decoder_output += FpRegRegOpConstructor.subst(vmsrFpscrIop);
216    exec_output += PredOpExecute.subst(vmsrFpscrIop);
217
218    vmrsIop = InstObjParams("vmrs", "Vmrs", "FpRegRegOp",
219                            { "code": vmrsEnabledCheckCode + \
220                                    "Dest = MiscOp1;",
221                              "predicate_test": predicateTest,
222                              "op_class": "SimdFloatMiscOp" },
223                            ["IsSerializeBefore"])
224    header_output += FpRegRegOpDeclare.subst(vmrsIop);
225    decoder_output += FpRegRegOpConstructor.subst(vmrsIop);
226    exec_output += PredOpExecute.subst(vmrsIop);
227
228    vmrsFpscrIop = InstObjParams("vmrs", "VmrsFpscr", "FpRegRegOp",
229                                 { "code": vmrsEnabledCheckCode + \
230                                           "Dest = Fpscr | FpCondCodes;",
231                                   "predicate_test": predicateTest,
232                                   "op_class": "SimdFloatMiscOp" },
233                                 ["IsSerializeBefore"])
234    header_output += FpRegRegOpDeclare.subst(vmrsFpscrIop);
235    decoder_output += FpRegRegOpConstructor.subst(vmrsFpscrIop);
236    exec_output += PredOpExecute.subst(vmrsFpscrIop);
237
238    vmrsApsrFpscrCode = vmrsEnabledCheckCode + '''
239        Dest = FpCondCodes & FpCondCodesMask;
240    '''
241    vmrsApsrFpscrIop = InstObjParams("vmrs", "VmrsApsrFpscr", "FpRegRegImmOp",
242                                     { "code": vmrsApsrFpscrCode,
243                                       "predicate_test": predicateTest,
244                                       "op_class": "SimdFloatMiscOp" },
245                                     ["IsSerializeBefore"])
246    header_output += FpRegRegImmOpDeclare.subst(vmrsApsrFpscrIop);
247    decoder_output += FpRegRegImmOpConstructor.subst(vmrsApsrFpscrIop);
248    exec_output += PredOpExecute.subst(vmrsApsrFpscrIop);
249
250    vmovImmSCode = vfpEnabledCheckCode + '''
251        FpDest.uw = bits(imm, 31, 0);
252    '''
253    vmovImmSIop = InstObjParams("vmov", "VmovImmS", "FpRegImmOp",
254                                { "code": vmovImmSCode,
255                                  "predicate_test": predicateTest,
256                                  "op_class": "SimdFloatMiscOp" }, [])
257    header_output += FpRegImmOpDeclare.subst(vmovImmSIop);
258    decoder_output += FpRegImmOpConstructor.subst(vmovImmSIop);
259    exec_output += PredOpExecute.subst(vmovImmSIop);
260
261    vmovImmDCode = vfpEnabledCheckCode + '''
262        FpDestP0.uw = bits(imm, 31, 0);
263        FpDestP1.uw = bits(imm, 63, 32);
264    '''
265    vmovImmDIop = InstObjParams("vmov", "VmovImmD", "FpRegImmOp",
266                                { "code": vmovImmDCode,
267                                  "predicate_test": predicateTest,
268                                  "op_class": "SimdFloatMiscOp" }, [])
269    header_output += FpRegImmOpDeclare.subst(vmovImmDIop);
270    decoder_output += FpRegImmOpConstructor.subst(vmovImmDIop);
271    exec_output += PredOpExecute.subst(vmovImmDIop);
272
273    vmovImmQCode = vfpEnabledCheckCode + '''
274        FpDestP0.uw = bits(imm, 31, 0);
275        FpDestP1.uw = bits(imm, 63, 32);
276        FpDestP2.uw = bits(imm, 31, 0);
277        FpDestP3.uw = bits(imm, 63, 32);
278    '''
279    vmovImmQIop = InstObjParams("vmov", "VmovImmQ", "FpRegImmOp",
280                                { "code": vmovImmQCode,
281                                  "predicate_test": predicateTest,
282                                  "op_class": "SimdFloatMiscOp" }, [])
283    header_output += FpRegImmOpDeclare.subst(vmovImmQIop);
284    decoder_output += FpRegImmOpConstructor.subst(vmovImmQIop);
285    exec_output += PredOpExecute.subst(vmovImmQIop);
286
287    vmovRegSCode = vfpEnabledCheckCode + '''
288        FpDest.uw = FpOp1.uw;
289    '''
290    vmovRegSIop = InstObjParams("vmov", "VmovRegS", "FpRegRegOp",
291                                { "code": vmovRegSCode,
292                                  "predicate_test": predicateTest,
293                                  "op_class": "SimdFloatMiscOp" }, [])
294    header_output += FpRegRegOpDeclare.subst(vmovRegSIop);
295    decoder_output += FpRegRegOpConstructor.subst(vmovRegSIop);
296    exec_output += PredOpExecute.subst(vmovRegSIop);
297
298    vmovRegDCode = vfpEnabledCheckCode + '''
299        FpDestP0.uw = FpOp1P0.uw;
300        FpDestP1.uw = FpOp1P1.uw;
301    '''
302    vmovRegDIop = InstObjParams("vmov", "VmovRegD", "FpRegRegOp",
303                                { "code": vmovRegDCode,
304                                  "predicate_test": predicateTest,
305                                  "op_class": "SimdFloatMiscOp" }, [])
306    header_output += FpRegRegOpDeclare.subst(vmovRegDIop);
307    decoder_output += FpRegRegOpConstructor.subst(vmovRegDIop);
308    exec_output += PredOpExecute.subst(vmovRegDIop);
309
310    vmovRegQCode = vfpEnabledCheckCode + '''
311        FpDestP0.uw = FpOp1P0.uw;
312        FpDestP1.uw = FpOp1P1.uw;
313        FpDestP2.uw = FpOp1P2.uw;
314        FpDestP3.uw = FpOp1P3.uw;
315    '''
316    vmovRegQIop = InstObjParams("vmov", "VmovRegQ", "FpRegRegOp",
317                                { "code": vmovRegQCode,
318                                  "predicate_test": predicateTest,
319                                  "op_class": "SimdFloatMiscOp" }, [])
320    header_output  += FpRegRegOpDeclare.subst(vmovRegQIop);
321    decoder_output  += FpRegRegOpConstructor.subst(vmovRegQIop);
322    exec_output += PredOpExecute.subst(vmovRegQIop);
323
324    vmovCoreRegBCode = vfpEnabledCheckCode + '''
325        FpDest.uw = insertBits(FpDest.uw, imm * 8 + 7, imm * 8, Op1.ub);
326    '''
327    vmovCoreRegBIop = InstObjParams("vmov", "VmovCoreRegB", "FpRegRegImmOp",
328                                    { "code": vmovCoreRegBCode,
329                                      "predicate_test": predicateTest,
330                                      "op_class": "SimdFloatMiscOp" }, [])
331    header_output  += FpRegRegImmOpDeclare.subst(vmovCoreRegBIop);
332    decoder_output  += FpRegRegImmOpConstructor.subst(vmovCoreRegBIop);
333    exec_output += PredOpExecute.subst(vmovCoreRegBIop);
334
335    vmovCoreRegHCode = vfpEnabledCheckCode + '''
336        FpDest.uw = insertBits(FpDest.uw, imm * 16 + 15, imm * 16, Op1.uh);
337    '''
338    vmovCoreRegHIop = InstObjParams("vmov", "VmovCoreRegH", "FpRegRegImmOp",
339                                    { "code": vmovCoreRegHCode,
340                                      "predicate_test": predicateTest,
341                                      "op_class": "SimdFloatMiscOp" }, [])
342    header_output  += FpRegRegImmOpDeclare.subst(vmovCoreRegHIop);
343    decoder_output  += FpRegRegImmOpConstructor.subst(vmovCoreRegHIop);
344    exec_output += PredOpExecute.subst(vmovCoreRegHIop);
345
346    vmovCoreRegWCode = vfpEnabledCheckCode + '''
347        FpDest.uw = Op1.uw;
348    '''
349    vmovCoreRegWIop = InstObjParams("vmov", "VmovCoreRegW", "FpRegRegOp",
350                                    { "code": vmovCoreRegWCode,
351                                      "predicate_test": predicateTest,
352                                      "op_class": "SimdFloatMiscOp" }, [])
353    header_output  += FpRegRegOpDeclare.subst(vmovCoreRegWIop);
354    decoder_output  += FpRegRegOpConstructor.subst(vmovCoreRegWIop);
355    exec_output += PredOpExecute.subst(vmovCoreRegWIop);
356
357    vmovRegCoreUBCode = vfpEnabledCheckCode + '''
358        assert(imm < 4);
359        Dest = bits(FpOp1.uw, imm * 8 + 7, imm * 8);
360    '''
361    vmovRegCoreUBIop = InstObjParams("vmov", "VmovRegCoreUB", "FpRegRegImmOp",
362                                     { "code": vmovRegCoreUBCode,
363                                       "predicate_test": predicateTest,
364                                       "op_class": "SimdFloatMiscOp" }, [])
365    header_output  += FpRegRegImmOpDeclare.subst(vmovRegCoreUBIop);
366    decoder_output  += FpRegRegImmOpConstructor.subst(vmovRegCoreUBIop);
367    exec_output += PredOpExecute.subst(vmovRegCoreUBIop);
368
369    vmovRegCoreUHCode = vfpEnabledCheckCode + '''
370        assert(imm < 2);
371        Dest = bits(FpOp1.uw, imm * 16 + 15, imm * 16);
372    '''
373    vmovRegCoreUHIop = InstObjParams("vmov", "VmovRegCoreUH", "FpRegRegImmOp",
374                                     { "code": vmovRegCoreUHCode,
375                                       "predicate_test": predicateTest,
376                                       "op_class": "SimdFloatMiscOp" }, [])
377    header_output  += FpRegRegImmOpDeclare.subst(vmovRegCoreUHIop);
378    decoder_output  += FpRegRegImmOpConstructor.subst(vmovRegCoreUHIop);
379    exec_output += PredOpExecute.subst(vmovRegCoreUHIop);
380
381    vmovRegCoreSBCode = vfpEnabledCheckCode + '''
382        assert(imm < 4);
383        Dest = sext<8>(bits(FpOp1.uw, imm * 8 + 7, imm * 8));
384    '''
385    vmovRegCoreSBIop = InstObjParams("vmov", "VmovRegCoreSB", "FpRegRegImmOp",
386                                     { "code": vmovRegCoreSBCode,
387                                       "predicate_test": predicateTest,
388                                       "op_class": "SimdFloatMiscOp" }, [])
389    header_output  += FpRegRegImmOpDeclare.subst(vmovRegCoreSBIop);
390    decoder_output  += FpRegRegImmOpConstructor.subst(vmovRegCoreSBIop);
391    exec_output += PredOpExecute.subst(vmovRegCoreSBIop);
392
393    vmovRegCoreSHCode = vfpEnabledCheckCode + '''
394        assert(imm < 2);
395        Dest = sext<16>(bits(FpOp1.uw, imm * 16 + 15, imm * 16));
396    '''
397    vmovRegCoreSHIop = InstObjParams("vmov", "VmovRegCoreSH", "FpRegRegImmOp",
398                                     { "code": vmovRegCoreSHCode,
399                                       "predicate_test": predicateTest,
400                                       "op_class": "SimdFloatMiscOp" }, [])
401    header_output  += FpRegRegImmOpDeclare.subst(vmovRegCoreSHIop);
402    decoder_output  += FpRegRegImmOpConstructor.subst(vmovRegCoreSHIop);
403    exec_output += PredOpExecute.subst(vmovRegCoreSHIop);
404
405    vmovRegCoreWCode = vfpEnabledCheckCode + '''
406        Dest = FpOp1.uw;
407    '''
408    vmovRegCoreWIop = InstObjParams("vmov", "VmovRegCoreW", "FpRegRegOp",
409                                     { "code": vmovRegCoreWCode,
410                                       "predicate_test": predicateTest,
411                                       "op_class": "SimdFloatMiscOp" }, [])
412    header_output  += FpRegRegOpDeclare.subst(vmovRegCoreWIop);
413    decoder_output  += FpRegRegOpConstructor.subst(vmovRegCoreWIop);
414    exec_output += PredOpExecute.subst(vmovRegCoreWIop);
415
416    vmov2Reg2CoreCode = vfpEnabledCheckCode + '''
417        FpDestP0.uw = Op1.uw;
418        FpDestP1.uw = Op2.uw;
419    '''
420    vmov2Reg2CoreIop = InstObjParams("vmov", "Vmov2Reg2Core", "FpRegRegRegOp",
421                                     { "code": vmov2Reg2CoreCode,
422                                       "predicate_test": predicateTest,
423                                       "op_class": "SimdFloatMiscOp" }, [])
424    header_output  += FpRegRegRegOpDeclare.subst(vmov2Reg2CoreIop);
425    decoder_output  += FpRegRegRegOpConstructor.subst(vmov2Reg2CoreIop);
426    exec_output += PredOpExecute.subst(vmov2Reg2CoreIop);
427
428    vmov2Core2RegCode = vfpEnabledCheckCode + '''
429        Dest.uw = FpOp2P0.uw;
430        Op1.uw = FpOp2P1.uw;
431    '''
432    vmov2Core2RegIop = InstObjParams("vmov", "Vmov2Core2Reg", "FpRegRegRegOp",
433                                     { "code": vmov2Core2RegCode,
434                                       "predicate_test": predicateTest,
435                                       "op_class": "SimdFloatMiscOp" }, [])
436    header_output  += FpRegRegRegOpDeclare.subst(vmov2Core2RegIop);
437    decoder_output  += FpRegRegRegOpConstructor.subst(vmov2Core2RegIop);
438    exec_output += PredOpExecute.subst(vmov2Core2RegIop);
439}};
440
441let {{
442
443    header_output = ""
444    decoder_output = ""
445    exec_output = ""
446
447    singleSimpleCode = vfpEnabledCheckCode + '''
448        FPSCR fpscr = (FPSCR) FpscrExc;
449        FpDest = %(op)s;
450    '''
451    singleCode = singleSimpleCode + '''
452        FpscrExc = fpscr;
453    '''
454    singleBinOp = "binaryOp(fpscr, FpOp1, FpOp2," + \
455                "%(func)s, fpscr.fz, fpscr.dn, fpscr.rMode)"
456    singleUnaryOp = "unaryOp(fpscr, FpOp1, %(func)s, fpscr.fz, fpscr.rMode)"
457    doubleCode = vfpEnabledCheckCode + '''
458        FPSCR fpscr = (FPSCR) FpscrExc;
459        double dest = %(op)s;
460        FpDestP0.uw = dblLow(dest);
461        FpDestP1.uw = dblHi(dest);
462        FpscrExc = fpscr;
463    '''
464    doubleBinOp = '''
465        binaryOp(fpscr, dbl(FpOp1P0.uw, FpOp1P1.uw),
466                        dbl(FpOp2P0.uw, FpOp2P1.uw),
467                        %(func)s, fpscr.fz, fpscr.dn, fpscr.rMode);
468    '''
469    doubleUnaryOp = '''
470        unaryOp(fpscr, dbl(FpOp1P0.uw, FpOp1P1.uw), %(func)s,
471                fpscr.fz, fpscr.rMode)
472    '''
473
474    def buildBinFpOp(name, Name, base, opClass, singleOp, doubleOp):
475        global header_output, decoder_output, exec_output
476
477        code = singleCode % { "op": singleBinOp }
478        code = code % { "func": singleOp }
479        sIop = InstObjParams(name + "s", Name + "S", base,
480                { "code": code,
481                  "predicate_test": predicateTest,
482                  "op_class": opClass }, [])
483        code = doubleCode % { "op": doubleBinOp }
484        code = code % { "func": doubleOp }
485        dIop = InstObjParams(name + "d", Name + "D", base,
486                { "code": code,
487                  "predicate_test": predicateTest,
488                  "op_class": opClass }, [])
489
490        declareTempl = eval(base + "Declare");
491        constructorTempl = eval(base + "Constructor");
492
493        for iop in sIop, dIop:
494            header_output += declareTempl.subst(iop)
495            decoder_output += constructorTempl.subst(iop)
496            exec_output += PredOpExecute.subst(iop)
497
498    buildBinFpOp("vadd", "Vadd", "FpRegRegRegOp", "SimdFloatAddOp", "fpAddS",
499                 "fpAddD")
500    buildBinFpOp("vsub", "Vsub", "FpRegRegRegOp", "SimdFloatAddOp", "fpSubS",
501                 "fpSubD")
502    buildBinFpOp("vdiv", "Vdiv", "FpRegRegRegOp", "SimdFloatDivOp", "fpDivS",
503                 "fpDivD")
504    buildBinFpOp("vmul", "Vmul", "FpRegRegRegOp", "SimdFloatMultOp", "fpMulS",
505                 "fpMulD")
506
507    def buildUnaryFpOp(name, Name, base, opClass, singleOp, doubleOp = None):
508        if doubleOp is None:
509            doubleOp = singleOp
510        global header_output, decoder_output, exec_output
511
512        code = singleCode % { "op": singleUnaryOp }
513        code = code % { "func": singleOp }
514        sIop = InstObjParams(name + "s", Name + "S", base,
515                { "code": code,
516                  "predicate_test": predicateTest,
517                  "op_class": opClass }, [])
518        code = doubleCode % { "op": doubleUnaryOp }
519        code = code % { "func": doubleOp }
520        dIop = InstObjParams(name + "d", Name + "D", base,
521                { "code": code,
522                  "predicate_test": predicateTest,
523                  "op_class": opClass }, [])
524
525        declareTempl = eval(base + "Declare");
526        constructorTempl = eval(base + "Constructor");
527
528        for iop in sIop, dIop:
529            header_output += declareTempl.subst(iop)
530            decoder_output += constructorTempl.subst(iop)
531            exec_output += PredOpExecute.subst(iop)
532
533    buildUnaryFpOp("vsqrt", "Vsqrt", "FpRegRegOp", "SimdFloatSqrtOp", "sqrtf",
534                   "sqrt")
535
536    def buildSimpleUnaryFpOp(name, Name, base, opClass, singleOp,
537                             doubleOp = None):
538        if doubleOp is None:
539            doubleOp = singleOp
540        global header_output, decoder_output, exec_output
541
542        sIop = InstObjParams(name + "s", Name + "S", base,
543                { "code": singleSimpleCode % { "op": singleOp },
544                  "predicate_test": predicateTest,
545                  "op_class": opClass }, [])
546        dIop = InstObjParams(name + "d", Name + "D", base,
547                { "code": doubleCode % { "op": doubleOp },
548                  "predicate_test": predicateTest,
549                  "op_class": opClass }, [])
550
551        declareTempl = eval(base + "Declare");
552        constructorTempl = eval(base + "Constructor");
553
554        for iop in sIop, dIop:
555            header_output += declareTempl.subst(iop)
556            decoder_output += constructorTempl.subst(iop)
557            exec_output += PredOpExecute.subst(iop)
558
559    buildSimpleUnaryFpOp("vneg", "Vneg", "FpRegRegOp", "SimdFloatMiscOp",
560                         "-FpOp1", "-dbl(FpOp1P0.uw, FpOp1P1.uw)")
561    buildSimpleUnaryFpOp("vabs", "Vabs", "FpRegRegOp", "SimdFloatMiscOp",
562                         "fabsf(FpOp1)", "fabs(dbl(FpOp1P0.uw, FpOp1P1.uw))")
563}};
564
565let {{
566
567    header_output = ""
568    decoder_output = ""
569    exec_output = ""
570
571    vmlaSCode = vfpEnabledCheckCode + '''
572        FPSCR fpscr = (FPSCR) FpscrExc;
573        float mid = binaryOp(fpscr, FpOp1, FpOp2,
574                fpMulS, fpscr.fz, fpscr.dn, fpscr.rMode);
575        FpDest = binaryOp(fpscr, FpDest, mid, fpAddS,
576                fpscr.fz, fpscr.dn, fpscr.rMode);
577        FpscrExc = fpscr;
578    '''
579    vmlaSIop = InstObjParams("vmlas", "VmlaS", "FpRegRegRegOp",
580                                     { "code": vmlaSCode,
581                                       "predicate_test": predicateTest,
582                                       "op_class": "SimdFloatMultAccOp" }, [])
583    header_output  += FpRegRegRegOpDeclare.subst(vmlaSIop);
584    decoder_output  += FpRegRegRegOpConstructor.subst(vmlaSIop);
585    exec_output += PredOpExecute.subst(vmlaSIop);
586
587    vmlaDCode = vfpEnabledCheckCode + '''
588        FPSCR fpscr = (FPSCR) FpscrExc;
589        double mid = binaryOp(fpscr, dbl(FpOp1P0.uw, FpOp1P1.uw),
590                                     dbl(FpOp2P0.uw, FpOp2P1.uw),
591                                     fpMulD, fpscr.fz, fpscr.dn, fpscr.rMode);
592        double dest = binaryOp(fpscr, dbl(FpDestP0.uw, FpDestP1.uw),
593                                      mid, fpAddD, fpscr.fz,
594                                      fpscr.dn, fpscr.rMode);
595        FpDestP0.uw = dblLow(dest);
596        FpDestP1.uw = dblHi(dest);
597        FpscrExc = fpscr;
598    '''
599    vmlaDIop = InstObjParams("vmlad", "VmlaD", "FpRegRegRegOp",
600                                     { "code": vmlaDCode,
601                                       "predicate_test": predicateTest,
602                                       "op_class": "SimdFloatMultAccOp" }, [])
603    header_output  += FpRegRegRegOpDeclare.subst(vmlaDIop);
604    decoder_output  += FpRegRegRegOpConstructor.subst(vmlaDIop);
605    exec_output += PredOpExecute.subst(vmlaDIop);
606
607    vmlsSCode = vfpEnabledCheckCode + '''
608        FPSCR fpscr = (FPSCR) FpscrExc;
609        float mid = binaryOp(fpscr, FpOp1, FpOp2,
610                fpMulS, fpscr.fz, fpscr.dn, fpscr.rMode);
611        FpDest = binaryOp(fpscr, FpDest, -mid, fpAddS,
612                fpscr.fz, fpscr.dn, fpscr.rMode);
613        FpscrExc = fpscr;
614    '''
615    vmlsSIop = InstObjParams("vmlss", "VmlsS", "FpRegRegRegOp",
616                                     { "code": vmlsSCode,
617                                       "predicate_test": predicateTest,
618                                       "op_class": "SimdFloatMultAccOp" }, [])
619    header_output  += FpRegRegRegOpDeclare.subst(vmlsSIop);
620    decoder_output  += FpRegRegRegOpConstructor.subst(vmlsSIop);
621    exec_output += PredOpExecute.subst(vmlsSIop);
622
623    vmlsDCode = vfpEnabledCheckCode + '''
624        FPSCR fpscr = (FPSCR) FpscrExc;
625        double mid = binaryOp(fpscr, dbl(FpOp1P0.uw, FpOp1P1.uw),
626                                     dbl(FpOp2P0.uw, FpOp2P1.uw),
627                                     fpMulD, fpscr.fz, fpscr.dn, fpscr.rMode);
628        double dest = binaryOp(fpscr, dbl(FpDestP0.uw, FpDestP1.uw),
629                                      -mid, fpAddD, fpscr.fz,
630                                      fpscr.dn, fpscr.rMode);
631        FpDestP0.uw = dblLow(dest);
632        FpDestP1.uw = dblHi(dest);
633        FpscrExc = fpscr;
634    '''
635    vmlsDIop = InstObjParams("vmlsd", "VmlsD", "FpRegRegRegOp",
636                                     { "code": vmlsDCode,
637                                       "predicate_test": predicateTest,
638                                       "op_class": "SimdFloatMultAccOp" }, [])
639    header_output  += FpRegRegRegOpDeclare.subst(vmlsDIop);
640    decoder_output  += FpRegRegRegOpConstructor.subst(vmlsDIop);
641    exec_output += PredOpExecute.subst(vmlsDIop);
642
643    vnmlaSCode = vfpEnabledCheckCode + '''
644        FPSCR fpscr = (FPSCR) FpscrExc;
645        float mid = binaryOp(fpscr, FpOp1, FpOp2,
646                fpMulS, fpscr.fz, fpscr.dn, fpscr.rMode);
647        FpDest = binaryOp(fpscr, -FpDest, -mid, fpAddS,
648                fpscr.fz, fpscr.dn, fpscr.rMode);
649        FpscrExc = fpscr;
650    '''
651    vnmlaSIop = InstObjParams("vnmlas", "VnmlaS", "FpRegRegRegOp",
652                                     { "code": vnmlaSCode,
653                                       "predicate_test": predicateTest,
654                                       "op_class": "SimdFloatMultAccOp" }, [])
655    header_output  += FpRegRegRegOpDeclare.subst(vnmlaSIop);
656    decoder_output  += FpRegRegRegOpConstructor.subst(vnmlaSIop);
657    exec_output += PredOpExecute.subst(vnmlaSIop);
658
659    vnmlaDCode = vfpEnabledCheckCode + '''
660        FPSCR fpscr = (FPSCR) FpscrExc;
661        double mid = binaryOp(fpscr, dbl(FpOp1P0.uw, FpOp1P1.uw),
662                                     dbl(FpOp2P0.uw, FpOp2P1.uw),
663                                     fpMulD, fpscr.fz, fpscr.dn, fpscr.rMode);
664        double dest = binaryOp(fpscr, -dbl(FpDestP0.uw, FpDestP1.uw),
665                                      -mid, fpAddD, fpscr.fz,
666                                      fpscr.dn, fpscr.rMode);
667        FpDestP0.uw = dblLow(dest);
668        FpDestP1.uw = dblHi(dest);
669        FpscrExc = fpscr;
670    '''
671    vnmlaDIop = InstObjParams("vnmlad", "VnmlaD", "FpRegRegRegOp",
672                                     { "code": vnmlaDCode,
673                                       "predicate_test": predicateTest,
674                                       "op_class": "SimdFloatMultAccOp" }, [])
675    header_output  += FpRegRegRegOpDeclare.subst(vnmlaDIop);
676    decoder_output  += FpRegRegRegOpConstructor.subst(vnmlaDIop);
677    exec_output += PredOpExecute.subst(vnmlaDIop);
678
679    vnmlsSCode = vfpEnabledCheckCode + '''
680        FPSCR fpscr = (FPSCR) FpscrExc;
681        float mid = binaryOp(fpscr, FpOp1, FpOp2,
682                fpMulS, fpscr.fz, fpscr.dn, fpscr.rMode);
683        FpDest = binaryOp(fpscr, -FpDest, mid, fpAddS,
684                fpscr.fz, fpscr.dn, fpscr.rMode);
685        FpscrExc = fpscr;
686    '''
687    vnmlsSIop = InstObjParams("vnmlss", "VnmlsS", "FpRegRegRegOp",
688                              { "code": vnmlsSCode,
689                                "predicate_test": predicateTest,
690                                "op_class": "SimdFloatMultAccOp" }, [])
691    header_output  += FpRegRegRegOpDeclare.subst(vnmlsSIop);
692    decoder_output  += FpRegRegRegOpConstructor.subst(vnmlsSIop);
693    exec_output += PredOpExecute.subst(vnmlsSIop);
694
695    vnmlsDCode = vfpEnabledCheckCode + '''
696        FPSCR fpscr = (FPSCR) FpscrExc;
697        double mid = binaryOp(fpscr, dbl(FpOp1P0.uw, FpOp1P1.uw),
698                                     dbl(FpOp2P0.uw, FpOp2P1.uw),
699                                     fpMulD, fpscr.fz, fpscr.dn, fpscr.rMode);
700        double dest = binaryOp(fpscr, -dbl(FpDestP0.uw, FpDestP1.uw),
701                                      mid, fpAddD, fpscr.fz,
702                                      fpscr.dn, fpscr.rMode);
703        FpDestP0.uw = dblLow(dest);
704        FpDestP1.uw = dblHi(dest);
705        FpscrExc = fpscr;
706    '''
707    vnmlsDIop = InstObjParams("vnmlsd", "VnmlsD", "FpRegRegRegOp",
708                              { "code": vnmlsDCode,
709                                "predicate_test": predicateTest,
710                                "op_class": "SimdFloatMultAccOp" }, [])
711    header_output  += FpRegRegRegOpDeclare.subst(vnmlsDIop);
712    decoder_output  += FpRegRegRegOpConstructor.subst(vnmlsDIop);
713    exec_output += PredOpExecute.subst(vnmlsDIop);
714
715    vnmulSCode = vfpEnabledCheckCode + '''
716        FPSCR fpscr = (FPSCR) FpscrExc;
717        FpDest = -binaryOp(fpscr, FpOp1, FpOp2, fpMulS,
718                fpscr.fz, fpscr.dn, fpscr.rMode);
719        FpscrExc = fpscr;
720    '''
721    vnmulSIop = InstObjParams("vnmuls", "VnmulS", "FpRegRegRegOp",
722                              { "code": vnmulSCode,
723                                "predicate_test": predicateTest,
724                                "op_class": "SimdFloatMultOp" }, [])
725    header_output  += FpRegRegRegOpDeclare.subst(vnmulSIop);
726    decoder_output  += FpRegRegRegOpConstructor.subst(vnmulSIop);
727    exec_output += PredOpExecute.subst(vnmulSIop);
728
729    vnmulDCode = vfpEnabledCheckCode + '''
730        FPSCR fpscr = (FPSCR) FpscrExc;
731        double dest = -binaryOp(fpscr, dbl(FpOp1P0.uw, FpOp1P1.uw),
732                                       dbl(FpOp2P0.uw, FpOp2P1.uw),
733                                       fpMulD, fpscr.fz, fpscr.dn,
734                                       fpscr.rMode);
735        FpDestP0.uw = dblLow(dest);
736        FpDestP1.uw = dblHi(dest);
737        FpscrExc = fpscr;
738    '''
739    vnmulDIop = InstObjParams("vnmuld", "VnmulD", "FpRegRegRegOp",
740                                     { "code": vnmulDCode,
741                                       "predicate_test": predicateTest,
742                                       "op_class": "SimdFloatMultOp" }, [])
743    header_output += FpRegRegRegOpDeclare.subst(vnmulDIop);
744    decoder_output += FpRegRegRegOpConstructor.subst(vnmulDIop);
745    exec_output += PredOpExecute.subst(vnmulDIop);
746}};
747
748let {{
749
750    header_output = ""
751    decoder_output = ""
752    exec_output = ""
753
754    vcvtUIntFpSCode = vfpEnabledCheckCode + '''
755        FPSCR fpscr = (FPSCR) FpscrExc;
756        VfpSavedState state = prepFpState(fpscr.rMode);
757        __asm__ __volatile__("" : "=m" (FpOp1.uw) : "m" (FpOp1.uw));
758        FpDest = FpOp1.uw;
759        __asm__ __volatile__("" :: "m" (FpDest));
760        finishVfp(fpscr, state, fpscr.fz);
761        FpscrExc = fpscr;
762    '''
763    vcvtUIntFpSIop = InstObjParams("vcvt", "VcvtUIntFpS", "FpRegRegOp",
764                                     { "code": vcvtUIntFpSCode,
765                                       "predicate_test": predicateTest,
766                                       "op_class": "SimdFloatCvtOp" }, [])
767    header_output += FpRegRegOpDeclare.subst(vcvtUIntFpSIop);
768    decoder_output += FpRegRegOpConstructor.subst(vcvtUIntFpSIop);
769    exec_output += PredOpExecute.subst(vcvtUIntFpSIop);
770
771    vcvtUIntFpDCode = vfpEnabledCheckCode + '''
772        FPSCR fpscr = (FPSCR) FpscrExc;
773        VfpSavedState state = prepFpState(fpscr.rMode);
774        __asm__ __volatile__("" : "=m" (FpOp1P0.uw) : "m" (FpOp1P0.uw));
775        double cDest = (uint64_t)FpOp1P0.uw;
776        __asm__ __volatile__("" :: "m" (cDest));
777        finishVfp(fpscr, state, fpscr.fz);
778        FpDestP0.uw = dblLow(cDest);
779        FpDestP1.uw = dblHi(cDest);
780        FpscrExc = fpscr;
781    '''
782    vcvtUIntFpDIop = InstObjParams("vcvt", "VcvtUIntFpD", "FpRegRegOp",
783                                     { "code": vcvtUIntFpDCode,
784                                       "predicate_test": predicateTest,
785                                       "op_class": "SimdFloatCvtOp" }, [])
786    header_output += FpRegRegOpDeclare.subst(vcvtUIntFpDIop);
787    decoder_output += FpRegRegOpConstructor.subst(vcvtUIntFpDIop);
788    exec_output += PredOpExecute.subst(vcvtUIntFpDIop);
789
790    vcvtSIntFpSCode = vfpEnabledCheckCode + '''
791        FPSCR fpscr = (FPSCR) FpscrExc;
792        VfpSavedState state = prepFpState(fpscr.rMode);
793        __asm__ __volatile__("" : "=m" (FpOp1.sw) : "m" (FpOp1.sw));
794        FpDest = FpOp1.sw;
795        __asm__ __volatile__("" :: "m" (FpDest));
796        finishVfp(fpscr, state, fpscr.fz);
797        FpscrExc = fpscr;
798    '''
799    vcvtSIntFpSIop = InstObjParams("vcvt", "VcvtSIntFpS", "FpRegRegOp",
800                                     { "code": vcvtSIntFpSCode,
801                                       "predicate_test": predicateTest,
802                                       "op_class": "SimdFloatCvtOp" }, [])
803    header_output += FpRegRegOpDeclare.subst(vcvtSIntFpSIop);
804    decoder_output += FpRegRegOpConstructor.subst(vcvtSIntFpSIop);
805    exec_output += PredOpExecute.subst(vcvtSIntFpSIop);
806
807    vcvtSIntFpDCode = vfpEnabledCheckCode + '''
808        FPSCR fpscr = (FPSCR) FpscrExc;
809        VfpSavedState state = prepFpState(fpscr.rMode);
810        __asm__ __volatile__("" : "=m" (FpOp1P0.sw) : "m" (FpOp1P0.sw));
811        double cDest = FpOp1P0.sw;
812        __asm__ __volatile__("" :: "m" (cDest));
813        finishVfp(fpscr, state, fpscr.fz);
814        FpDestP0.uw = dblLow(cDest);
815        FpDestP1.uw = dblHi(cDest);
816        FpscrExc = fpscr;
817    '''
818    vcvtSIntFpDIop = InstObjParams("vcvt", "VcvtSIntFpD", "FpRegRegOp",
819                                     { "code": vcvtSIntFpDCode,
820                                       "predicate_test": predicateTest,
821                                       "op_class": "SimdFloatCvtOp" }, [])
822    header_output += FpRegRegOpDeclare.subst(vcvtSIntFpDIop);
823    decoder_output += FpRegRegOpConstructor.subst(vcvtSIntFpDIop);
824    exec_output += PredOpExecute.subst(vcvtSIntFpDIop);
825
826    vcvtFpUIntSRCode = vfpEnabledCheckCode + '''
827        FPSCR fpscr = (FPSCR) FpscrExc;
828        VfpSavedState state = prepFpState(fpscr.rMode);
829        vfpFlushToZero(fpscr, FpOp1);
830        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
831        FpDest.uw = vfpFpSToFixed(FpOp1, false, false, 0, false);
832        __asm__ __volatile__("" :: "m" (FpDest.uw));
833        finishVfp(fpscr, state, fpscr.fz);
834        FpscrExc = fpscr;
835    '''
836    vcvtFpUIntSRIop = InstObjParams("vcvt", "VcvtFpUIntSR", "FpRegRegOp",
837                                     { "code": vcvtFpUIntSRCode,
838                                       "predicate_test": predicateTest,
839                                       "op_class": "SimdFloatCvtOp" }, [])
840    header_output += FpRegRegOpDeclare.subst(vcvtFpUIntSRIop);
841    decoder_output += FpRegRegOpConstructor.subst(vcvtFpUIntSRIop);
842    exec_output += PredOpExecute.subst(vcvtFpUIntSRIop);
843
844    vcvtFpUIntDRCode = vfpEnabledCheckCode + '''
845        FPSCR fpscr = (FPSCR) FpscrExc;
846        double cOp1 = dbl(FpOp1P0.uw, FpOp1P1.uw);
847        vfpFlushToZero(fpscr, cOp1);
848        VfpSavedState state = prepFpState(fpscr.rMode);
849        __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
850        uint64_t result = vfpFpDToFixed(cOp1, false, false, 0, false);
851        __asm__ __volatile__("" :: "m" (result));
852        finishVfp(fpscr, state, fpscr.fz);
853        FpDestP0.uw = result;
854        FpscrExc = fpscr;
855    '''
856    vcvtFpUIntDRIop = InstObjParams("vcvtr", "VcvtFpUIntDR", "FpRegRegOp",
857                                     { "code": vcvtFpUIntDRCode,
858                                       "predicate_test": predicateTest,
859                                       "op_class": "SimdFloatCvtOp" }, [])
860    header_output += FpRegRegOpDeclare.subst(vcvtFpUIntDRIop);
861    decoder_output += FpRegRegOpConstructor.subst(vcvtFpUIntDRIop);
862    exec_output += PredOpExecute.subst(vcvtFpUIntDRIop);
863
864    vcvtFpSIntSRCode = vfpEnabledCheckCode + '''
865        FPSCR fpscr = (FPSCR) FpscrExc;
866        VfpSavedState state = prepFpState(fpscr.rMode);
867        vfpFlushToZero(fpscr, FpOp1);
868        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
869        FpDest.sw = vfpFpSToFixed(FpOp1, true, false, 0, false);
870        __asm__ __volatile__("" :: "m" (FpDest.sw));
871        finishVfp(fpscr, state, fpscr.fz);
872        FpscrExc = fpscr;
873    '''
874    vcvtFpSIntSRIop = InstObjParams("vcvtr", "VcvtFpSIntSR", "FpRegRegOp",
875                                     { "code": vcvtFpSIntSRCode,
876                                        "predicate_test": predicateTest,
877                                        "op_class": "SimdFloatCvtOp" }, [])
878    header_output += FpRegRegOpDeclare.subst(vcvtFpSIntSRIop);
879    decoder_output += FpRegRegOpConstructor.subst(vcvtFpSIntSRIop);
880    exec_output += PredOpExecute.subst(vcvtFpSIntSRIop);
881
882    vcvtFpSIntDRCode = vfpEnabledCheckCode + '''
883        FPSCR fpscr = (FPSCR) FpscrExc;
884        double cOp1 = dbl(FpOp1P0.uw, FpOp1P1.uw);
885        vfpFlushToZero(fpscr, cOp1);
886        VfpSavedState state = prepFpState(fpscr.rMode);
887        __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
888        int64_t result = vfpFpDToFixed(cOp1, true, false, 0, false);
889        __asm__ __volatile__("" :: "m" (result));
890        finishVfp(fpscr, state, fpscr.fz);
891        FpDestP0.uw = result;
892        FpscrExc = fpscr;
893    '''
894    vcvtFpSIntDRIop = InstObjParams("vcvtr", "VcvtFpSIntDR", "FpRegRegOp",
895                                     { "code": vcvtFpSIntDRCode,
896                                       "predicate_test": predicateTest,
897                                       "op_class": "SimdFloatCvtOp" }, [])
898    header_output += FpRegRegOpDeclare.subst(vcvtFpSIntDRIop);
899    decoder_output += FpRegRegOpConstructor.subst(vcvtFpSIntDRIop);
900    exec_output += PredOpExecute.subst(vcvtFpSIntDRIop);
901
902    vcvtFpUIntSCode = vfpEnabledCheckCode + '''
903        FPSCR fpscr = (FPSCR) FpscrExc;
904        vfpFlushToZero(fpscr, FpOp1);
905        VfpSavedState state = prepFpState(fpscr.rMode);
906        fesetround(FeRoundZero);
907        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
908        FpDest.uw = vfpFpSToFixed(FpOp1, false, false, 0);
909        __asm__ __volatile__("" :: "m" (FpDest.uw));
910        finishVfp(fpscr, state, fpscr.fz);
911        FpscrExc = fpscr;
912    '''
913    vcvtFpUIntSIop = InstObjParams("vcvt", "VcvtFpUIntS", "FpRegRegOp",
914                                     { "code": vcvtFpUIntSCode,
915                                       "predicate_test": predicateTest,
916                                       "op_class": "SimdFloatCvtOp" }, [])
917    header_output += FpRegRegOpDeclare.subst(vcvtFpUIntSIop);
918    decoder_output += FpRegRegOpConstructor.subst(vcvtFpUIntSIop);
919    exec_output += PredOpExecute.subst(vcvtFpUIntSIop);
920
921    vcvtFpUIntDCode = vfpEnabledCheckCode + '''
922        FPSCR fpscr = (FPSCR) FpscrExc;
923        double cOp1 = dbl(FpOp1P0.uw, FpOp1P1.uw);
924        vfpFlushToZero(fpscr, cOp1);
925        VfpSavedState state = prepFpState(fpscr.rMode);
926        fesetround(FeRoundZero);
927        __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
928        uint64_t result = vfpFpDToFixed(cOp1, false, false, 0);
929        __asm__ __volatile__("" :: "m" (result));
930        finishVfp(fpscr, state, fpscr.fz);
931        FpDestP0.uw = result;
932        FpscrExc = fpscr;
933    '''
934    vcvtFpUIntDIop = InstObjParams("vcvt", "VcvtFpUIntD", "FpRegRegOp",
935                                     { "code": vcvtFpUIntDCode,
936                                       "predicate_test": predicateTest,
937                                       "op_class": "SimdFloatCvtOp" }, [])
938    header_output += FpRegRegOpDeclare.subst(vcvtFpUIntDIop);
939    decoder_output += FpRegRegOpConstructor.subst(vcvtFpUIntDIop);
940    exec_output += PredOpExecute.subst(vcvtFpUIntDIop);
941
942    vcvtFpSIntSCode = vfpEnabledCheckCode + '''
943        FPSCR fpscr = (FPSCR) FpscrExc;
944        vfpFlushToZero(fpscr, FpOp1);
945        VfpSavedState state = prepFpState(fpscr.rMode);
946        fesetround(FeRoundZero);
947        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
948        FpDest.sw = vfpFpSToFixed(FpOp1, true, false, 0);
949        __asm__ __volatile__("" :: "m" (FpDest.sw));
950        finishVfp(fpscr, state, fpscr.fz);
951        FpscrExc = fpscr;
952    '''
953    vcvtFpSIntSIop = InstObjParams("vcvt", "VcvtFpSIntS", "FpRegRegOp",
954                                     { "code": vcvtFpSIntSCode,
955                                       "predicate_test": predicateTest,
956                                       "op_class": "SimdFloatCvtOp" }, [])
957    header_output += FpRegRegOpDeclare.subst(vcvtFpSIntSIop);
958    decoder_output += FpRegRegOpConstructor.subst(vcvtFpSIntSIop);
959    exec_output += PredOpExecute.subst(vcvtFpSIntSIop);
960
961    vcvtFpSIntDCode = vfpEnabledCheckCode + '''
962        FPSCR fpscr = (FPSCR) FpscrExc;
963        double cOp1 = dbl(FpOp1P0.uw, FpOp1P1.uw);
964        vfpFlushToZero(fpscr, cOp1);
965        VfpSavedState state = prepFpState(fpscr.rMode);
966        fesetround(FeRoundZero);
967        __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
968        int64_t result = vfpFpDToFixed(cOp1, true, false, 0);
969        __asm__ __volatile__("" :: "m" (result));
970        finishVfp(fpscr, state, fpscr.fz);
971        FpDestP0.uw = result;
972        FpscrExc = fpscr;
973    '''
974    vcvtFpSIntDIop = InstObjParams("vcvt", "VcvtFpSIntD", "FpRegRegOp",
975                                     { "code": vcvtFpSIntDCode,
976                                       "predicate_test": predicateTest,
977                                       "op_class": "SimdFloatCvtOp" }, [])
978    header_output += FpRegRegOpDeclare.subst(vcvtFpSIntDIop);
979    decoder_output += FpRegRegOpConstructor.subst(vcvtFpSIntDIop);
980    exec_output += PredOpExecute.subst(vcvtFpSIntDIop);
981
982    vcvtFpSFpDCode = vfpEnabledCheckCode + '''
983        FPSCR fpscr = (FPSCR) FpscrExc;
984        vfpFlushToZero(fpscr, FpOp1);
985        VfpSavedState state = prepFpState(fpscr.rMode);
986        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
987        double cDest = fixFpSFpDDest(FpscrExc, FpOp1);
988        __asm__ __volatile__("" :: "m" (cDest));
989        finishVfp(fpscr, state, fpscr.fz);
990        FpDestP0.uw = dblLow(cDest);
991        FpDestP1.uw = dblHi(cDest);
992        FpscrExc = fpscr;
993    '''
994    vcvtFpSFpDIop = InstObjParams("vcvt", "VcvtFpSFpD", "FpRegRegOp",
995                                     { "code": vcvtFpSFpDCode,
996                                       "predicate_test": predicateTest,
997                                       "op_class": "SimdFloatCvtOp" }, [])
998    header_output += FpRegRegOpDeclare.subst(vcvtFpSFpDIop);
999    decoder_output += FpRegRegOpConstructor.subst(vcvtFpSFpDIop);
1000    exec_output += PredOpExecute.subst(vcvtFpSFpDIop);
1001
1002    vcvtFpDFpSCode = vfpEnabledCheckCode + '''
1003        FPSCR fpscr = (FPSCR) FpscrExc;
1004        double cOp1 = dbl(FpOp1P0.uw, FpOp1P1.uw);
1005        vfpFlushToZero(fpscr, cOp1);
1006        VfpSavedState state = prepFpState(fpscr.rMode);
1007        __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1008        FpDest = fixFpDFpSDest(FpscrExc, cOp1);
1009        __asm__ __volatile__("" :: "m" (FpDest));
1010        finishVfp(fpscr, state, fpscr.fz);
1011        FpscrExc = fpscr;
1012    '''
1013    vcvtFpDFpSIop = InstObjParams("vcvt", "VcvtFpDFpS", "FpRegRegOp",
1014                                     { "code": vcvtFpDFpSCode,
1015                                       "predicate_test": predicateTest,
1016                                       "op_class": "SimdFloatCvtOp" }, [])
1017    header_output += FpRegRegOpDeclare.subst(vcvtFpDFpSIop);
1018    decoder_output += FpRegRegOpConstructor.subst(vcvtFpDFpSIop);
1019    exec_output += PredOpExecute.subst(vcvtFpDFpSIop);
1020
1021    vcvtFpHTFpSCode = vfpEnabledCheckCode + '''
1022        FPSCR fpscr = (FPSCR) FpscrExc;
1023        vfpFlushToZero(fpscr, FpOp1);
1024        VfpSavedState state = prepFpState(fpscr.rMode);
1025        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1026        FpDest = vcvtFpHFpS(fpscr, fpscr.dn, fpscr.ahp,
1027                            bits(fpToBits(FpOp1), 31, 16));
1028        __asm__ __volatile__("" :: "m" (FpDest));
1029        finishVfp(fpscr, state, fpscr.fz);
1030        FpscrExc = fpscr;
1031    '''
1032    vcvtFpHTFpSIop = InstObjParams("vcvtt", "VcvtFpHTFpS", "FpRegRegOp",
1033                                   { "code": vcvtFpHTFpSCode,
1034                                     "predicate_test": predicateTest,
1035                                     "op_class": "SimdFloatCvtOp" }, [])
1036    header_output += FpRegRegOpDeclare.subst(vcvtFpHTFpSIop);
1037    decoder_output += FpRegRegOpConstructor.subst(vcvtFpHTFpSIop);
1038    exec_output += PredOpExecute.subst(vcvtFpHTFpSIop);
1039
1040    vcvtFpHBFpSCode = vfpEnabledCheckCode + '''
1041        FPSCR fpscr = (FPSCR) FpscrExc;
1042        VfpSavedState state = prepFpState(fpscr.rMode);
1043        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1044        FpDest = vcvtFpHFpS(fpscr, fpscr.dn, fpscr.ahp,
1045                            bits(fpToBits(FpOp1), 15, 0));
1046        __asm__ __volatile__("" :: "m" (FpDest));
1047        finishVfp(fpscr, state, fpscr.fz);
1048        FpscrExc = fpscr;
1049    '''
1050    vcvtFpHBFpSIop = InstObjParams("vcvtb", "VcvtFpHBFpS", "FpRegRegOp",
1051                                   { "code": vcvtFpHBFpSCode,
1052                                     "predicate_test": predicateTest,
1053                                     "op_class": "SimdFloatCvtOp" }, [])
1054    header_output += FpRegRegOpDeclare.subst(vcvtFpHBFpSIop);
1055    decoder_output += FpRegRegOpConstructor.subst(vcvtFpHBFpSIop);
1056    exec_output += PredOpExecute.subst(vcvtFpHBFpSIop);
1057
1058    vcvtFpSFpHTCode = vfpEnabledCheckCode + '''
1059        FPSCR fpscr = (FPSCR) FpscrExc;
1060        vfpFlushToZero(fpscr, FpOp1);
1061        VfpSavedState state = prepFpState(fpscr.rMode);
1062        __asm__ __volatile__("" : "=m" (FpOp1), "=m" (FpDest.uw)
1063                                : "m" (FpOp1), "m" (FpDest.uw));
1064        FpDest.uw = insertBits(FpDest.uw, 31, 16,,
1065                               vcvtFpSFpH(fpscr, fpscr.fz, fpscr.dn,
1066                               fpscr.rMode, fpscr.ahp, FpOp1));
1067        __asm__ __volatile__("" :: "m" (FpDest.uw));
1068        finishVfp(fpscr, state, fpscr.fz);
1069        FpscrExc = fpscr;
1070    '''
1071    vcvtFpSFpHTIop = InstObjParams("vcvtt", "VcvtFpSFpHT", "FpRegRegOp",
1072                                    { "code": vcvtFpHTFpSCode,
1073                                      "predicate_test": predicateTest,
1074                                      "op_class": "SimdFloatCvtOp" }, [])
1075    header_output += FpRegRegOpDeclare.subst(vcvtFpSFpHTIop);
1076    decoder_output += FpRegRegOpConstructor.subst(vcvtFpSFpHTIop);
1077    exec_output += PredOpExecute.subst(vcvtFpSFpHTIop);
1078
1079    vcvtFpSFpHBCode = vfpEnabledCheckCode + '''
1080        FPSCR fpscr = (FPSCR) FpscrExc;
1081        vfpFlushToZero(fpscr, FpOp1);
1082        VfpSavedState state = prepFpState(fpscr.rMode);
1083        __asm__ __volatile__("" : "=m" (FpOp1), "=m" (FpDest.uw)
1084                                : "m" (FpOp1), "m" (FpDest.uw));
1085        FpDest.uw = insertBits(FpDest.uw, 15, 0,
1086                               vcvtFpSFpH(fpscr, fpscr.fz, fpscr.dn,
1087                               fpscr.rMode, fpscr.ahp, FpOp1));
1088        __asm__ __volatile__("" :: "m" (FpDest.uw));
1089        finishVfp(fpscr, state, fpscr.fz);
1090        FpscrExc = fpscr;
1091    '''
1092    vcvtFpSFpHBIop = InstObjParams("vcvtb", "VcvtFpSFpHB", "FpRegRegOp",
1093                                   { "code": vcvtFpSFpHBCode,
1094                                     "predicate_test": predicateTest,
1095                                     "op_class": "SimdFloatCvtOp" }, [])
1096    header_output += FpRegRegOpDeclare.subst(vcvtFpSFpHBIop);
1097    decoder_output += FpRegRegOpConstructor.subst(vcvtFpSFpHBIop);
1098    exec_output += PredOpExecute.subst(vcvtFpSFpHBIop);
1099
1100    vcmpSCode = vfpEnabledCheckCode + '''
1101        FPSCR fpscr = (FPSCR) FpscrExc;
1102        vfpFlushToZero(fpscr, FpDest, FpOp1);
1103        if (FpDest == FpOp1) {
1104            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1105        } else if (FpDest < FpOp1) {
1106            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1107        } else if (FpDest > FpOp1) {
1108            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1109        } else {
1110            const uint32_t qnan = 0x7fc00000;
1111            const bool nan1 = std::isnan(FpDest);
1112            const bool signal1 = nan1 && ((fpToBits(FpDest) & qnan) != qnan);
1113            const bool nan2 = std::isnan(FpOp1);
1114            const bool signal2 = nan2 && ((fpToBits(FpOp1) & qnan) != qnan);
1115            if (signal1 || signal2)
1116                fpscr.ioc = 1;
1117            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1118        }
1119        FpCondCodes = fpscr & FpCondCodesMask;
1120        FpscrExc = fpscr;
1121    '''
1122    vcmpSIop = InstObjParams("vcmps", "VcmpS", "FpRegRegOp",
1123                                     { "code": vcmpSCode,
1124                                       "predicate_test": predicateTest,
1125                                       "op_class": "SimdFloatCmpOp" }, [])
1126    header_output += FpRegRegOpDeclare.subst(vcmpSIop);
1127    decoder_output += FpRegRegOpConstructor.subst(vcmpSIop);
1128    exec_output += PredOpExecute.subst(vcmpSIop);
1129
1130    vcmpDCode = vfpEnabledCheckCode + '''
1131        double cOp1 = dbl(FpOp1P0.uw, FpOp1P1.uw);
1132        double cDest = dbl(FpDestP0.uw, FpDestP1.uw);
1133        FPSCR fpscr = (FPSCR) FpscrExc;
1134        vfpFlushToZero(fpscr, cDest, cOp1);
1135        if (cDest == cOp1) {
1136            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1137        } else if (cDest < cOp1) {
1138            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1139        } else if (cDest > cOp1) {
1140            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1141        } else {
1142            const uint64_t qnan = ULL(0x7ff8000000000000);
1143            const bool nan1 = std::isnan(cDest);
1144            const bool signal1 = nan1 && ((fpToBits(cDest) & qnan) != qnan);
1145            const bool nan2 = std::isnan(cOp1);
1146            const bool signal2 = nan2 && ((fpToBits(cOp1) & qnan) != qnan);
1147            if (signal1 || signal2)
1148                fpscr.ioc = 1;
1149            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1150        }
1151        FpCondCodes = fpscr & FpCondCodesMask;
1152        FpscrExc = fpscr;
1153    '''
1154    vcmpDIop = InstObjParams("vcmpd", "VcmpD", "FpRegRegOp",
1155                                     { "code": vcmpDCode,
1156                                       "predicate_test": predicateTest,
1157                                       "op_class": "SimdFloatCmpOp" }, [])
1158    header_output += FpRegRegOpDeclare.subst(vcmpDIop);
1159    decoder_output += FpRegRegOpConstructor.subst(vcmpDIop);
1160    exec_output += PredOpExecute.subst(vcmpDIop);
1161
1162    vcmpZeroSCode = vfpEnabledCheckCode + '''
1163        FPSCR fpscr = (FPSCR) FpscrExc;
1164        vfpFlushToZero(fpscr, FpDest);
1165        // This only handles imm == 0 for now.
1166        assert(imm == 0);
1167        if (FpDest == imm) {
1168            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1169        } else if (FpDest < imm) {
1170            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1171        } else if (FpDest > imm) {
1172            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1173        } else {
1174            const uint32_t qnan = 0x7fc00000;
1175            const bool nan = std::isnan(FpDest);
1176            const bool signal = nan && ((fpToBits(FpDest) & qnan) != qnan);
1177            if (signal)
1178                fpscr.ioc = 1;
1179            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1180        }
1181        FpCondCodes = fpscr & FpCondCodesMask;
1182        FpscrExc = fpscr;
1183    '''
1184    vcmpZeroSIop = InstObjParams("vcmpZeros", "VcmpZeroS", "FpRegImmOp",
1185                                     { "code": vcmpZeroSCode,
1186                                       "predicate_test": predicateTest,
1187                                       "op_class": "SimdFloatCmpOp" }, [])
1188    header_output += FpRegImmOpDeclare.subst(vcmpZeroSIop);
1189    decoder_output += FpRegImmOpConstructor.subst(vcmpZeroSIop);
1190    exec_output += PredOpExecute.subst(vcmpZeroSIop);
1191
1192    vcmpZeroDCode = vfpEnabledCheckCode + '''
1193        // This only handles imm == 0 for now.
1194        assert(imm == 0);
1195        double cDest = dbl(FpDestP0.uw, FpDestP1.uw);
1196        FPSCR fpscr = (FPSCR) FpscrExc;
1197        vfpFlushToZero(fpscr, cDest);
1198        if (cDest == imm) {
1199            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1200        } else if (cDest < imm) {
1201            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1202        } else if (cDest > imm) {
1203            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1204        } else {
1205            const uint64_t qnan = ULL(0x7ff8000000000000);
1206            const bool nan = std::isnan(cDest);
1207            const bool signal = nan && ((fpToBits(cDest) & qnan) != qnan);
1208            if (signal)
1209                fpscr.ioc = 1;
1210            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1211        }
1212        FpCondCodes = fpscr & FpCondCodesMask;
1213        FpscrExc = fpscr;
1214    '''
1215    vcmpZeroDIop = InstObjParams("vcmpZerod", "VcmpZeroD", "FpRegImmOp",
1216                                     { "code": vcmpZeroDCode,
1217                                       "predicate_test": predicateTest,
1218                                       "op_class": "SimdFloatCmpOp" }, [])
1219    header_output += FpRegImmOpDeclare.subst(vcmpZeroDIop);
1220    decoder_output += FpRegImmOpConstructor.subst(vcmpZeroDIop);
1221    exec_output += PredOpExecute.subst(vcmpZeroDIop);
1222
1223    vcmpeSCode = vfpEnabledCheckCode + '''
1224        FPSCR fpscr = (FPSCR) FpscrExc;
1225        vfpFlushToZero(fpscr, FpDest, FpOp1);
1226        if (FpDest == FpOp1) {
1227            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1228        } else if (FpDest < FpOp1) {
1229            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1230        } else if (FpDest > FpOp1) {
1231            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1232        } else {
1233            fpscr.ioc = 1;
1234            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1235        }
1236        FpCondCodes = fpscr & FpCondCodesMask;
1237        FpscrExc = fpscr;
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) FpscrExc;
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        FpscrExc = fpscr;
1264    '''
1265    vcmpeDIop = InstObjParams("vcmped", "VcmpeD", "FpRegRegOp",
1266                                     { "code": vcmpeDCode,
1267                                       "predicate_test": predicateTest,
1268                                       "op_class": "SimdFloatCmpOp" }, [])
1269    header_output += FpRegRegOpDeclare.subst(vcmpeDIop);
1270    decoder_output += FpRegRegOpConstructor.subst(vcmpeDIop);
1271    exec_output += PredOpExecute.subst(vcmpeDIop);
1272
1273    vcmpeZeroSCode = vfpEnabledCheckCode + '''
1274        FPSCR fpscr = (FPSCR) FpscrExc;
1275        vfpFlushToZero(fpscr, FpDest);
1276        if (FpDest == imm) {
1277            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1278        } else if (FpDest < imm) {
1279            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1280        } else if (FpDest > imm) {
1281            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1282        } else {
1283            fpscr.ioc = 1;
1284            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1285        }
1286        FpCondCodes = fpscr & FpCondCodesMask;
1287        FpscrExc = fpscr;
1288    '''
1289    vcmpeZeroSIop = InstObjParams("vcmpeZeros", "VcmpeZeroS", "FpRegImmOp",
1290                                     { "code": vcmpeZeroSCode,
1291                                       "predicate_test": predicateTest,
1292                                       "op_class": "SimdFloatCmpOp" }, [])
1293    header_output += FpRegImmOpDeclare.subst(vcmpeZeroSIop);
1294    decoder_output += FpRegImmOpConstructor.subst(vcmpeZeroSIop);
1295    exec_output += PredOpExecute.subst(vcmpeZeroSIop);
1296
1297    vcmpeZeroDCode = vfpEnabledCheckCode + '''
1298        double cDest = dbl(FpDestP0.uw, FpDestP1.uw);
1299        FPSCR fpscr = (FPSCR) FpscrExc;
1300        vfpFlushToZero(fpscr, cDest);
1301        if (cDest == imm) {
1302            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1303        } else if (cDest < imm) {
1304            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1305        } else if (cDest > imm) {
1306            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1307        } else {
1308            fpscr.ioc = 1;
1309            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1310        }
1311        FpCondCodes = fpscr & FpCondCodesMask;
1312        FpscrExc = fpscr;
1313    '''
1314    vcmpeZeroDIop = InstObjParams("vcmpeZerod", "VcmpeZeroD", "FpRegImmOp",
1315                                     { "code": vcmpeZeroDCode,
1316                                       "predicate_test": predicateTest,
1317                                       "op_class": "SimdFloatCmpOp" }, [])
1318    header_output += FpRegImmOpDeclare.subst(vcmpeZeroDIop);
1319    decoder_output += FpRegImmOpConstructor.subst(vcmpeZeroDIop);
1320    exec_output += PredOpExecute.subst(vcmpeZeroDIop);
1321}};
1322
1323let {{
1324
1325    header_output = ""
1326    decoder_output = ""
1327    exec_output = ""
1328
1329    vcvtFpSFixedSCode = vfpEnabledCheckCode + '''
1330        FPSCR fpscr = (FPSCR) FpscrExc;
1331        vfpFlushToZero(fpscr, FpOp1);
1332        VfpSavedState state = prepFpState(fpscr.rMode);
1333        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1334        FpDest.sw = vfpFpSToFixed(FpOp1, true, false, imm);
1335        __asm__ __volatile__("" :: "m" (FpDest.sw));
1336        finishVfp(fpscr, state, fpscr.fz);
1337        FpscrExc = fpscr;
1338    '''
1339    vcvtFpSFixedSIop = InstObjParams("vcvt", "VcvtFpSFixedS", "FpRegRegImmOp",
1340                                     { "code": vcvtFpSFixedSCode,
1341                                       "predicate_test": predicateTest,
1342                                       "op_class": "SimdFloatCvtOp" }, [])
1343    header_output += FpRegRegImmOpDeclare.subst(vcvtFpSFixedSIop);
1344    decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSFixedSIop);
1345    exec_output += PredOpExecute.subst(vcvtFpSFixedSIop);
1346
1347    vcvtFpSFixedDCode = vfpEnabledCheckCode + '''
1348        FPSCR fpscr = (FPSCR) FpscrExc;
1349        double cOp1 = dbl(FpOp1P0.uw, FpOp1P1.uw);
1350        vfpFlushToZero(fpscr, cOp1);
1351        VfpSavedState state = prepFpState(fpscr.rMode);
1352        __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1353        uint64_t mid = vfpFpDToFixed(cOp1, true, false, imm);
1354        __asm__ __volatile__("" :: "m" (mid));
1355        finishVfp(fpscr, state, fpscr.fz);
1356        FpDestP0.uw = mid;
1357        FpDestP1.uw = mid >> 32;
1358        FpscrExc = fpscr;
1359    '''
1360    vcvtFpSFixedDIop = InstObjParams("vcvt", "VcvtFpSFixedD", "FpRegRegImmOp",
1361                                     { "code": vcvtFpSFixedDCode,
1362                                       "predicate_test": predicateTest,
1363                                       "op_class": "SimdFloatCvtOp" }, [])
1364    header_output += FpRegRegImmOpDeclare.subst(vcvtFpSFixedDIop);
1365    decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSFixedDIop);
1366    exec_output += PredOpExecute.subst(vcvtFpSFixedDIop);
1367
1368    vcvtFpUFixedSCode = vfpEnabledCheckCode + '''
1369        FPSCR fpscr = (FPSCR) FpscrExc;
1370        vfpFlushToZero(fpscr, FpOp1);
1371        VfpSavedState state = prepFpState(fpscr.rMode);
1372        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1373        FpDest.uw = vfpFpSToFixed(FpOp1, false, false, imm);
1374        __asm__ __volatile__("" :: "m" (FpDest.uw));
1375        finishVfp(fpscr, state, fpscr.fz);
1376        FpscrExc = fpscr;
1377    '''
1378    vcvtFpUFixedSIop = InstObjParams("vcvt", "VcvtFpUFixedS", "FpRegRegImmOp",
1379                                     { "code": vcvtFpUFixedSCode,
1380                                       "predicate_test": predicateTest,
1381                                       "op_class": "SimdFloatCvtOp" }, [])
1382    header_output += FpRegRegImmOpDeclare.subst(vcvtFpUFixedSIop);
1383    decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUFixedSIop);
1384    exec_output += PredOpExecute.subst(vcvtFpUFixedSIop);
1385
1386    vcvtFpUFixedDCode = vfpEnabledCheckCode + '''
1387        FPSCR fpscr = (FPSCR) FpscrExc;
1388        double cOp1 = dbl(FpOp1P0.uw, FpOp1P1.uw);
1389        vfpFlushToZero(fpscr, cOp1);
1390        VfpSavedState state = prepFpState(fpscr.rMode);
1391        __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1392        uint64_t mid = vfpFpDToFixed(cOp1, false, false, imm);
1393        __asm__ __volatile__("" :: "m" (mid));
1394        finishVfp(fpscr, state, fpscr.fz);
1395        FpDestP0.uw = mid;
1396        FpDestP1.uw = mid >> 32;
1397        FpscrExc = fpscr;
1398    '''
1399    vcvtFpUFixedDIop = InstObjParams("vcvt", "VcvtFpUFixedD", "FpRegRegImmOp",
1400                                     { "code": vcvtFpUFixedDCode,
1401                                       "predicate_test": predicateTest,
1402                                       "op_class": "SimdFloatCvtOp" }, [])
1403    header_output += FpRegRegImmOpDeclare.subst(vcvtFpUFixedDIop);
1404    decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUFixedDIop);
1405    exec_output += PredOpExecute.subst(vcvtFpUFixedDIop);
1406
1407    vcvtSFixedFpSCode = vfpEnabledCheckCode + '''
1408        FPSCR fpscr = (FPSCR) FpscrExc;
1409        VfpSavedState state = prepFpState(fpscr.rMode);
1410        __asm__ __volatile__("" : "=m" (FpOp1.sw) : "m" (FpOp1.sw));
1411        FpDest = vfpSFixedToFpS(fpscr.fz, fpscr.dn, FpOp1.sw, false, imm);
1412        __asm__ __volatile__("" :: "m" (FpDest));
1413        finishVfp(fpscr, state, fpscr.fz);
1414        FpscrExc = fpscr;
1415    '''
1416    vcvtSFixedFpSIop = InstObjParams("vcvt", "VcvtSFixedFpS", "FpRegRegImmOp",
1417                                     { "code": vcvtSFixedFpSCode,
1418                                       "predicate_test": predicateTest,
1419                                       "op_class": "SimdFloatCvtOp" }, [])
1420    header_output += FpRegRegImmOpDeclare.subst(vcvtSFixedFpSIop);
1421    decoder_output += FpRegRegImmOpConstructor.subst(vcvtSFixedFpSIop);
1422    exec_output += PredOpExecute.subst(vcvtSFixedFpSIop);
1423
1424    vcvtSFixedFpDCode = vfpEnabledCheckCode + '''
1425        FPSCR fpscr = (FPSCR) FpscrExc;
1426        uint64_t mid = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
1427        VfpSavedState state = prepFpState(fpscr.rMode);
1428        __asm__ __volatile__("" : "=m" (mid) : "m" (mid));
1429        double cDest = vfpSFixedToFpD(fpscr.fz, fpscr.dn, mid, false, imm);
1430        __asm__ __volatile__("" :: "m" (cDest));
1431        finishVfp(fpscr, state, fpscr.fz);
1432        FpDestP0.uw = dblLow(cDest);
1433        FpDestP1.uw = dblHi(cDest);
1434        FpscrExc = fpscr;
1435    '''
1436    vcvtSFixedFpDIop = InstObjParams("vcvt", "VcvtSFixedFpD", "FpRegRegImmOp",
1437                                     { "code": vcvtSFixedFpDCode,
1438                                       "predicate_test": predicateTest,
1439                                       "op_class": "SimdFloatCvtOp" }, [])
1440    header_output += FpRegRegImmOpDeclare.subst(vcvtSFixedFpDIop);
1441    decoder_output += FpRegRegImmOpConstructor.subst(vcvtSFixedFpDIop);
1442    exec_output += PredOpExecute.subst(vcvtSFixedFpDIop);
1443
1444    vcvtUFixedFpSCode = vfpEnabledCheckCode + '''
1445        FPSCR fpscr = (FPSCR) FpscrExc;
1446        VfpSavedState state = prepFpState(fpscr.rMode);
1447        __asm__ __volatile__("" : "=m" (FpOp1.uw) : "m" (FpOp1.uw));
1448        FpDest = vfpUFixedToFpS(fpscr.fz, fpscr.dn, FpOp1.uw, false, imm);
1449        __asm__ __volatile__("" :: "m" (FpDest));
1450        finishVfp(fpscr, state, fpscr.fz);
1451        FpscrExc = fpscr;
1452    '''
1453    vcvtUFixedFpSIop = InstObjParams("vcvt", "VcvtUFixedFpS", "FpRegRegImmOp",
1454                                     { "code": vcvtUFixedFpSCode,
1455                                       "predicate_test": predicateTest,
1456                                       "op_class": "SimdFloatCvtOp" }, [])
1457    header_output += FpRegRegImmOpDeclare.subst(vcvtUFixedFpSIop);
1458    decoder_output += FpRegRegImmOpConstructor.subst(vcvtUFixedFpSIop);
1459    exec_output += PredOpExecute.subst(vcvtUFixedFpSIop);
1460
1461    vcvtUFixedFpDCode = vfpEnabledCheckCode + '''
1462        FPSCR fpscr = (FPSCR) FpscrExc;
1463        uint64_t mid = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
1464        VfpSavedState state = prepFpState(fpscr.rMode);
1465        __asm__ __volatile__("" : "=m" (mid) : "m" (mid));
1466        double cDest = vfpUFixedToFpD(fpscr.fz, fpscr.dn, mid, false, imm);
1467        __asm__ __volatile__("" :: "m" (cDest));
1468        finishVfp(fpscr, state, fpscr.fz);
1469        FpDestP0.uw = dblLow(cDest);
1470        FpDestP1.uw = dblHi(cDest);
1471        FpscrExc = fpscr;
1472    '''
1473    vcvtUFixedFpDIop = InstObjParams("vcvt", "VcvtUFixedFpD", "FpRegRegImmOp",
1474                                     { "code": vcvtUFixedFpDCode,
1475                                       "predicate_test": predicateTest,
1476                                       "op_class": "SimdFloatCvtOp" }, [])
1477    header_output += FpRegRegImmOpDeclare.subst(vcvtUFixedFpDIop);
1478    decoder_output += FpRegRegImmOpConstructor.subst(vcvtUFixedFpDIop);
1479    exec_output += PredOpExecute.subst(vcvtUFixedFpDIop);
1480
1481    vcvtFpSHFixedSCode = vfpEnabledCheckCode + '''
1482        FPSCR fpscr = (FPSCR) FpscrExc;
1483        vfpFlushToZero(fpscr, FpOp1);
1484        VfpSavedState state = prepFpState(fpscr.rMode);
1485        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1486        FpDest.sh = vfpFpSToFixed(FpOp1, true, true, imm);
1487        __asm__ __volatile__("" :: "m" (FpDest.sh));
1488        finishVfp(fpscr, state, fpscr.fz);
1489        FpscrExc = fpscr;
1490    '''
1491    vcvtFpSHFixedSIop = InstObjParams("vcvt", "VcvtFpSHFixedS",
1492                                      "FpRegRegImmOp",
1493                                     { "code": vcvtFpSHFixedSCode,
1494                                       "predicate_test": predicateTest,
1495                                       "op_class": "SimdFloatCvtOp" }, [])
1496    header_output += FpRegRegImmOpDeclare.subst(vcvtFpSHFixedSIop);
1497    decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSHFixedSIop);
1498    exec_output += PredOpExecute.subst(vcvtFpSHFixedSIop);
1499
1500    vcvtFpSHFixedDCode = vfpEnabledCheckCode + '''
1501        FPSCR fpscr = (FPSCR) FpscrExc;
1502        double cOp1 = dbl(FpOp1P0.uw, FpOp1P1.uw);
1503        vfpFlushToZero(fpscr, cOp1);
1504        VfpSavedState state = prepFpState(fpscr.rMode);
1505        __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1506        uint64_t result = vfpFpDToFixed(cOp1, true, true, imm);
1507        __asm__ __volatile__("" :: "m" (result));
1508        finishVfp(fpscr, state, fpscr.fz);
1509        FpDestP0.uw = result;
1510        FpDestP1.uw = result >> 32;
1511        FpscrExc = fpscr;
1512    '''
1513    vcvtFpSHFixedDIop = InstObjParams("vcvt", "VcvtFpSHFixedD",
1514                                      "FpRegRegImmOp",
1515                                     { "code": vcvtFpSHFixedDCode,
1516                                       "predicate_test": predicateTest,
1517                                       "op_class": "SimdFloatCvtOp" }, [])
1518    header_output += FpRegRegImmOpDeclare.subst(vcvtFpSHFixedDIop);
1519    decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSHFixedDIop);
1520    exec_output += PredOpExecute.subst(vcvtFpSHFixedDIop);
1521
1522    vcvtFpUHFixedSCode = vfpEnabledCheckCode + '''
1523        FPSCR fpscr = (FPSCR) FpscrExc;
1524        vfpFlushToZero(fpscr, FpOp1);
1525        VfpSavedState state = prepFpState(fpscr.rMode);
1526        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1527        FpDest.uh = vfpFpSToFixed(FpOp1, false, true, imm);
1528        __asm__ __volatile__("" :: "m" (FpDest.uh));
1529        finishVfp(fpscr, state, fpscr.fz);
1530        FpscrExc = fpscr;
1531    '''
1532    vcvtFpUHFixedSIop = InstObjParams("vcvt", "VcvtFpUHFixedS",
1533                                      "FpRegRegImmOp",
1534                                     { "code": vcvtFpUHFixedSCode,
1535                                       "predicate_test": predicateTest,
1536                                       "op_class": "SimdFloatCvtOp" }, [])
1537    header_output += FpRegRegImmOpDeclare.subst(vcvtFpUHFixedSIop);
1538    decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUHFixedSIop);
1539    exec_output += PredOpExecute.subst(vcvtFpUHFixedSIop);
1540
1541    vcvtFpUHFixedDCode = vfpEnabledCheckCode + '''
1542        FPSCR fpscr = (FPSCR) FpscrExc;
1543        double cOp1 = dbl(FpOp1P0.uw, FpOp1P1.uw);
1544        vfpFlushToZero(fpscr, cOp1);
1545        VfpSavedState state = prepFpState(fpscr.rMode);
1546        __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1547        uint64_t mid = vfpFpDToFixed(cOp1, false, true, imm);
1548        __asm__ __volatile__("" :: "m" (mid));
1549        finishVfp(fpscr, state, fpscr.fz);
1550        FpDestP0.uw = mid;
1551        FpDestP1.uw = mid >> 32;
1552        FpscrExc = fpscr;
1553    '''
1554    vcvtFpUHFixedDIop = InstObjParams("vcvt", "VcvtFpUHFixedD",
1555                                      "FpRegRegImmOp",
1556                                     { "code": vcvtFpUHFixedDCode,
1557                                       "predicate_test": predicateTest,
1558                                       "op_class": "SimdFloatCvtOp" }, [])
1559    header_output += FpRegRegImmOpDeclare.subst(vcvtFpUHFixedDIop);
1560    decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUHFixedDIop);
1561    exec_output += PredOpExecute.subst(vcvtFpUHFixedDIop);
1562
1563    vcvtSHFixedFpSCode = vfpEnabledCheckCode + '''
1564        FPSCR fpscr = (FPSCR) FpscrExc;
1565        VfpSavedState state = prepFpState(fpscr.rMode);
1566        __asm__ __volatile__("" : "=m" (FpOp1.sh) : "m" (FpOp1.sh));
1567        FpDest = vfpSFixedToFpS(fpscr.fz, fpscr.dn, FpOp1.sh, true, imm);
1568        __asm__ __volatile__("" :: "m" (FpDest));
1569        finishVfp(fpscr, state, fpscr.fz);
1570        FpscrExc = fpscr;
1571    '''
1572    vcvtSHFixedFpSIop = InstObjParams("vcvt", "VcvtSHFixedFpS",
1573                                      "FpRegRegImmOp",
1574                                     { "code": vcvtSHFixedFpSCode,
1575                                       "predicate_test": predicateTest,
1576                                       "op_class": "SimdFloatCvtOp" }, [])
1577    header_output += FpRegRegImmOpDeclare.subst(vcvtSHFixedFpSIop);
1578    decoder_output += FpRegRegImmOpConstructor.subst(vcvtSHFixedFpSIop);
1579    exec_output += PredOpExecute.subst(vcvtSHFixedFpSIop);
1580
1581    vcvtSHFixedFpDCode = vfpEnabledCheckCode + '''
1582        FPSCR fpscr = (FPSCR) FpscrExc;
1583        uint64_t mid = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
1584        VfpSavedState state = prepFpState(fpscr.rMode);
1585        __asm__ __volatile__("" : "=m" (mid) : "m" (mid));
1586        double cDest = vfpSFixedToFpD(fpscr.fz, fpscr.dn, mid, true, imm);
1587        __asm__ __volatile__("" :: "m" (cDest));
1588        finishVfp(fpscr, state, fpscr.fz);
1589        FpDestP0.uw = dblLow(cDest);
1590        FpDestP1.uw = dblHi(cDest);
1591        FpscrExc = fpscr;
1592    '''
1593    vcvtSHFixedFpDIop = InstObjParams("vcvt", "VcvtSHFixedFpD",
1594                                      "FpRegRegImmOp",
1595                                     { "code": vcvtSHFixedFpDCode,
1596                                       "predicate_test": predicateTest,
1597                                       "op_class": "SimdFloatCvtOp" }, [])
1598    header_output += FpRegRegImmOpDeclare.subst(vcvtSHFixedFpDIop);
1599    decoder_output += FpRegRegImmOpConstructor.subst(vcvtSHFixedFpDIop);
1600    exec_output += PredOpExecute.subst(vcvtSHFixedFpDIop);
1601
1602    vcvtUHFixedFpSCode = vfpEnabledCheckCode + '''
1603        FPSCR fpscr = (FPSCR) FpscrExc;
1604        VfpSavedState state = prepFpState(fpscr.rMode);
1605        __asm__ __volatile__("" : "=m" (FpOp1.uh) : "m" (FpOp1.uh));
1606        FpDest = vfpUFixedToFpS(fpscr.fz, fpscr.dn, FpOp1.uh, true, imm);
1607        __asm__ __volatile__("" :: "m" (FpDest));
1608        finishVfp(fpscr, state, fpscr.fz);
1609        FpscrExc = fpscr;
1610    '''
1611    vcvtUHFixedFpSIop = InstObjParams("vcvt", "VcvtUHFixedFpS",
1612                                      "FpRegRegImmOp",
1613                                     { "code": vcvtUHFixedFpSCode,
1614                                       "predicate_test": predicateTest,
1615                                       "op_class": "SimdFloatCvtOp" }, [])
1616    header_output += FpRegRegImmOpDeclare.subst(vcvtUHFixedFpSIop);
1617    decoder_output += FpRegRegImmOpConstructor.subst(vcvtUHFixedFpSIop);
1618    exec_output += PredOpExecute.subst(vcvtUHFixedFpSIop);
1619
1620    vcvtUHFixedFpDCode = vfpEnabledCheckCode + '''
1621        FPSCR fpscr = (FPSCR) FpscrExc;
1622        uint64_t mid = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
1623        VfpSavedState state = prepFpState(fpscr.rMode);
1624        __asm__ __volatile__("" : "=m" (mid) : "m" (mid));
1625        double cDest = vfpUFixedToFpD(fpscr.fz, fpscr.dn, mid, true, imm);
1626        __asm__ __volatile__("" :: "m" (cDest));
1627        finishVfp(fpscr, state, fpscr.fz);
1628        FpDestP0.uw = dblLow(cDest);
1629        FpDestP1.uw = dblHi(cDest);
1630        FpscrExc = fpscr;
1631    '''
1632    vcvtUHFixedFpDIop = InstObjParams("vcvt", "VcvtUHFixedFpD",
1633                                      "FpRegRegImmOp",
1634                                     { "code": vcvtUHFixedFpDCode,
1635                                       "predicate_test": predicateTest,
1636                                       "op_class": "SimdFloatCvtOp" }, [])
1637    header_output += FpRegRegImmOpDeclare.subst(vcvtUHFixedFpDIop);
1638    decoder_output += FpRegRegImmOpConstructor.subst(vcvtUHFixedFpDIop);
1639    exec_output += PredOpExecute.subst(vcvtUHFixedFpDIop);
1640}};
1641