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