fp.isa revision 12106:7784fac1b159
1// -*- mode:c++ -*-
2
3// Copyright (c) 2010-2013,2016 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>
68StaticInstPtr
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>
104StaticInstPtr
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>
140StaticInstPtr
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>
176StaticInstPtr
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()->flattenRegId(RegId(MiscRegClass, op1)).index()) {
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 = vfpEnabledCheckCode + '''
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    buildSimpleUnaryFpOp("vrintp", "VRIntP", "FpRegRegOp", "SimdFloatMiscOp",
646        "fplibRoundInt<uint32_t>(FpOp1, FPRounding_POSINF, false, fpscr)",
647        "fplibRoundInt<uint64_t>(dbl(FpOp1P0_uw, FpOp1P1_uw), " \
648        "FPRounding_POSINF, false, fpscr)"
649        )
650    buildSimpleUnaryFpOp("vrintm", "VRIntM", "FpRegRegOp", "SimdFloatMiscOp",
651        "fplibRoundInt<uint32_t>(FpOp1, FPRounding_NEGINF, false, fpscr)",
652        "fplibRoundInt<uint64_t>(dbl(FpOp1P0_uw, FpOp1P1_uw), " \
653        "FPRounding_NEGINF, false, fpscr)"
654        )
655    buildSimpleUnaryFpOp("vrinta", "VRIntA", "FpRegRegOp", "SimdFloatMiscOp",
656        "fplibRoundInt<uint32_t>(FpOp1, FPRounding_TIEAWAY, false, fpscr)",
657        "fplibRoundInt<uint64_t>(dbl(FpOp1P0_uw, FpOp1P1_uw), " \
658        "FPRounding_TIEAWAY, false, fpscr)"
659        )
660    buildSimpleUnaryFpOp("vrintn", "VRIntN", "FpRegRegOp", "SimdFloatMiscOp",
661        "fplibRoundInt<uint32_t>(FpOp1, FPRounding_TIEEVEN, false, fpscr)",
662        "fplibRoundInt<uint64_t>(dbl(FpOp1P0_uw, FpOp1P1_uw), " \
663        "FPRounding_TIEEVEN, false, fpscr)"
664        )
665}};
666
667let {{
668
669    header_output = ""
670    decoder_output = ""
671    exec_output = ""
672
673    vmlaSCode = vfpEnabledCheckCode + '''
674        FPSCR fpscr = (FPSCR) FpscrExc;
675        float mid = binaryOp(fpscr, FpOp1, FpOp2,
676                fpMulS, fpscr.fz, fpscr.dn, fpscr.rMode);
677        FpDest = binaryOp(fpscr, FpDest, mid, fpAddS,
678                fpscr.fz, fpscr.dn, fpscr.rMode);
679        FpscrExc = fpscr;
680    '''
681    vmlaSIop = InstObjParams("vmlas", "VmlaS", "FpRegRegRegOp",
682                                     { "code": vmlaSCode,
683                                       "predicate_test": predicateTest,
684                                       "op_class": "SimdFloatMultAccOp" }, [])
685    header_output  += FpRegRegRegOpDeclare.subst(vmlaSIop);
686    decoder_output  += FpRegRegRegOpConstructor.subst(vmlaSIop);
687    exec_output += PredOpExecute.subst(vmlaSIop);
688
689    vmlaDCode = vfpEnabledCheckCode + '''
690        FPSCR fpscr = (FPSCR) FpscrExc;
691        double mid = binaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw),
692                                     dbl(FpOp2P0_uw, FpOp2P1_uw),
693                                     fpMulD, fpscr.fz, fpscr.dn, fpscr.rMode);
694        double dest = binaryOp(fpscr, dbl(FpDestP0_uw, FpDestP1_uw),
695                                      mid, fpAddD, fpscr.fz,
696                                      fpscr.dn, fpscr.rMode);
697        FpDestP0_uw = dblLow(dest);
698        FpDestP1_uw = dblHi(dest);
699        FpscrExc = fpscr;
700    '''
701    vmlaDIop = InstObjParams("vmlad", "VmlaD", "FpRegRegRegOp",
702                                     { "code": vmlaDCode,
703                                       "predicate_test": predicateTest,
704                                       "op_class": "SimdFloatMultAccOp" }, [])
705    header_output  += FpRegRegRegOpDeclare.subst(vmlaDIop);
706    decoder_output  += FpRegRegRegOpConstructor.subst(vmlaDIop);
707    exec_output += PredOpExecute.subst(vmlaDIop);
708
709    vmlsSCode = vfpEnabledCheckCode + '''
710        FPSCR fpscr = (FPSCR) FpscrExc;
711        float mid = binaryOp(fpscr, FpOp1, FpOp2,
712                fpMulS, fpscr.fz, fpscr.dn, fpscr.rMode);
713        FpDest = binaryOp(fpscr, FpDest, -mid, fpAddS,
714                fpscr.fz, fpscr.dn, fpscr.rMode);
715        FpscrExc = fpscr;
716    '''
717    vmlsSIop = InstObjParams("vmlss", "VmlsS", "FpRegRegRegOp",
718                                     { "code": vmlsSCode,
719                                       "predicate_test": predicateTest,
720                                       "op_class": "SimdFloatMultAccOp" }, [])
721    header_output  += FpRegRegRegOpDeclare.subst(vmlsSIop);
722    decoder_output  += FpRegRegRegOpConstructor.subst(vmlsSIop);
723    exec_output += PredOpExecute.subst(vmlsSIop);
724
725    vmlsDCode = vfpEnabledCheckCode + '''
726        FPSCR fpscr = (FPSCR) FpscrExc;
727        double mid = binaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw),
728                                     dbl(FpOp2P0_uw, FpOp2P1_uw),
729                                     fpMulD, fpscr.fz, fpscr.dn, fpscr.rMode);
730        double dest = binaryOp(fpscr, dbl(FpDestP0_uw, FpDestP1_uw),
731                                      -mid, fpAddD, fpscr.fz,
732                                      fpscr.dn, fpscr.rMode);
733        FpDestP0_uw = dblLow(dest);
734        FpDestP1_uw = dblHi(dest);
735        FpscrExc = fpscr;
736    '''
737    vmlsDIop = InstObjParams("vmlsd", "VmlsD", "FpRegRegRegOp",
738                                     { "code": vmlsDCode,
739                                       "predicate_test": predicateTest,
740                                       "op_class": "SimdFloatMultAccOp" }, [])
741    header_output  += FpRegRegRegOpDeclare.subst(vmlsDIop);
742    decoder_output  += FpRegRegRegOpConstructor.subst(vmlsDIop);
743    exec_output += PredOpExecute.subst(vmlsDIop);
744
745    vnmlaSCode = vfpEnabledCheckCode + '''
746        FPSCR fpscr = (FPSCR) FpscrExc;
747        float mid = binaryOp(fpscr, FpOp1, FpOp2,
748                fpMulS, fpscr.fz, fpscr.dn, fpscr.rMode);
749        FpDest = binaryOp(fpscr, -FpDest, -mid, fpAddS,
750                fpscr.fz, fpscr.dn, fpscr.rMode);
751        FpscrExc = fpscr;
752    '''
753    vnmlaSIop = InstObjParams("vnmlas", "VnmlaS", "FpRegRegRegOp",
754                                     { "code": vnmlaSCode,
755                                       "predicate_test": predicateTest,
756                                       "op_class": "SimdFloatMultAccOp" }, [])
757    header_output  += FpRegRegRegOpDeclare.subst(vnmlaSIop);
758    decoder_output  += FpRegRegRegOpConstructor.subst(vnmlaSIop);
759    exec_output += PredOpExecute.subst(vnmlaSIop);
760
761    vnmlaDCode = vfpEnabledCheckCode + '''
762        FPSCR fpscr = (FPSCR) FpscrExc;
763        double mid = binaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw),
764                                     dbl(FpOp2P0_uw, FpOp2P1_uw),
765                                     fpMulD, fpscr.fz, fpscr.dn, fpscr.rMode);
766        double dest = binaryOp(fpscr, -dbl(FpDestP0_uw, FpDestP1_uw),
767                                      -mid, fpAddD, fpscr.fz,
768                                      fpscr.dn, fpscr.rMode);
769        FpDestP0_uw = dblLow(dest);
770        FpDestP1_uw = dblHi(dest);
771        FpscrExc = fpscr;
772    '''
773    vnmlaDIop = InstObjParams("vnmlad", "VnmlaD", "FpRegRegRegOp",
774                                     { "code": vnmlaDCode,
775                                       "predicate_test": predicateTest,
776                                       "op_class": "SimdFloatMultAccOp" }, [])
777    header_output  += FpRegRegRegOpDeclare.subst(vnmlaDIop);
778    decoder_output  += FpRegRegRegOpConstructor.subst(vnmlaDIop);
779    exec_output += PredOpExecute.subst(vnmlaDIop);
780
781    vnmlsSCode = vfpEnabledCheckCode + '''
782        FPSCR fpscr = (FPSCR) FpscrExc;
783        float mid = binaryOp(fpscr, FpOp1, FpOp2,
784                fpMulS, fpscr.fz, fpscr.dn, fpscr.rMode);
785        FpDest = binaryOp(fpscr, -FpDest, mid, fpAddS,
786                fpscr.fz, fpscr.dn, fpscr.rMode);
787        FpscrExc = fpscr;
788    '''
789    vnmlsSIop = InstObjParams("vnmlss", "VnmlsS", "FpRegRegRegOp",
790                              { "code": vnmlsSCode,
791                                "predicate_test": predicateTest,
792                                "op_class": "SimdFloatMultAccOp" }, [])
793    header_output  += FpRegRegRegOpDeclare.subst(vnmlsSIop);
794    decoder_output  += FpRegRegRegOpConstructor.subst(vnmlsSIop);
795    exec_output += PredOpExecute.subst(vnmlsSIop);
796
797    vnmlsDCode = vfpEnabledCheckCode + '''
798        FPSCR fpscr = (FPSCR) FpscrExc;
799        double mid = binaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw),
800                                     dbl(FpOp2P0_uw, FpOp2P1_uw),
801                                     fpMulD, fpscr.fz, fpscr.dn, fpscr.rMode);
802        double dest = binaryOp(fpscr, -dbl(FpDestP0_uw, FpDestP1_uw),
803                                      mid, fpAddD, fpscr.fz,
804                                      fpscr.dn, fpscr.rMode);
805        FpDestP0_uw = dblLow(dest);
806        FpDestP1_uw = dblHi(dest);
807        FpscrExc = fpscr;
808    '''
809    vnmlsDIop = InstObjParams("vnmlsd", "VnmlsD", "FpRegRegRegOp",
810                              { "code": vnmlsDCode,
811                                "predicate_test": predicateTest,
812                                "op_class": "SimdFloatMultAccOp" }, [])
813    header_output  += FpRegRegRegOpDeclare.subst(vnmlsDIop);
814    decoder_output  += FpRegRegRegOpConstructor.subst(vnmlsDIop);
815    exec_output += PredOpExecute.subst(vnmlsDIop);
816
817    vnmulSCode = vfpEnabledCheckCode + '''
818        FPSCR fpscr = (FPSCR) FpscrExc;
819        FpDest = -binaryOp(fpscr, FpOp1, FpOp2, fpMulS,
820                fpscr.fz, fpscr.dn, fpscr.rMode);
821        FpscrExc = fpscr;
822    '''
823    vnmulSIop = InstObjParams("vnmuls", "VnmulS", "FpRegRegRegOp",
824                              { "code": vnmulSCode,
825                                "predicate_test": predicateTest,
826                                "op_class": "SimdFloatMultOp" }, [])
827    header_output  += FpRegRegRegOpDeclare.subst(vnmulSIop);
828    decoder_output  += FpRegRegRegOpConstructor.subst(vnmulSIop);
829    exec_output += PredOpExecute.subst(vnmulSIop);
830
831    vnmulDCode = vfpEnabledCheckCode + '''
832        FPSCR fpscr = (FPSCR) FpscrExc;
833        double dest = -binaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw),
834                                       dbl(FpOp2P0_uw, FpOp2P1_uw),
835                                       fpMulD, fpscr.fz, fpscr.dn,
836                                       fpscr.rMode);
837        FpDestP0_uw = dblLow(dest);
838        FpDestP1_uw = dblHi(dest);
839        FpscrExc = fpscr;
840    '''
841    vnmulDIop = InstObjParams("vnmuld", "VnmulD", "FpRegRegRegOp",
842                                     { "code": vnmulDCode,
843                                       "predicate_test": predicateTest,
844                                       "op_class": "SimdFloatMultOp" }, [])
845    header_output += FpRegRegRegOpDeclare.subst(vnmulDIop);
846    decoder_output += FpRegRegRegOpConstructor.subst(vnmulDIop);
847    exec_output += PredOpExecute.subst(vnmulDIop);
848}};
849
850let {{
851
852    header_output = ""
853    decoder_output = ""
854    exec_output = ""
855
856    vcvtUIntFpSCode = vfpEnabledCheckCode + '''
857        FPSCR fpscr = (FPSCR) FpscrExc;
858        VfpSavedState state = prepFpState(fpscr.rMode);
859        __asm__ __volatile__("" : "=m" (FpOp1_uw) : "m" (FpOp1_uw));
860        FpDest = FpOp1_uw;
861        __asm__ __volatile__("" :: "m" (FpDest));
862        finishVfp(fpscr, state, fpscr.fz);
863        FpscrExc = fpscr;
864    '''
865    vcvtUIntFpSIop = InstObjParams("vcvt", "VcvtUIntFpS", "FpRegRegOp",
866                                     { "code": vcvtUIntFpSCode,
867                                       "predicate_test": predicateTest,
868                                       "op_class": "SimdFloatCvtOp" }, [])
869    header_output += FpRegRegOpDeclare.subst(vcvtUIntFpSIop);
870    decoder_output += FpRegRegOpConstructor.subst(vcvtUIntFpSIop);
871    exec_output += PredOpExecute.subst(vcvtUIntFpSIop);
872
873    vcvtUIntFpDCode = vfpEnabledCheckCode + '''
874        FPSCR fpscr = (FPSCR) FpscrExc;
875        VfpSavedState state = prepFpState(fpscr.rMode);
876        __asm__ __volatile__("" : "=m" (FpOp1P0_uw) : "m" (FpOp1P0_uw));
877        double cDest = (uint64_t)FpOp1P0_uw;
878        __asm__ __volatile__("" :: "m" (cDest));
879        finishVfp(fpscr, state, fpscr.fz);
880        FpDestP0_uw = dblLow(cDest);
881        FpDestP1_uw = dblHi(cDest);
882        FpscrExc = fpscr;
883    '''
884    vcvtUIntFpDIop = InstObjParams("vcvt", "VcvtUIntFpD", "FpRegRegOp",
885                                     { "code": vcvtUIntFpDCode,
886                                       "predicate_test": predicateTest,
887                                       "op_class": "SimdFloatCvtOp" }, [])
888    header_output += FpRegRegOpDeclare.subst(vcvtUIntFpDIop);
889    decoder_output += FpRegRegOpConstructor.subst(vcvtUIntFpDIop);
890    exec_output += PredOpExecute.subst(vcvtUIntFpDIop);
891
892    vcvtSIntFpSCode = vfpEnabledCheckCode + '''
893        FPSCR fpscr = (FPSCR) FpscrExc;
894        VfpSavedState state = prepFpState(fpscr.rMode);
895        __asm__ __volatile__("" : "=m" (FpOp1_sw) : "m" (FpOp1_sw));
896        FpDest = FpOp1_sw;
897        __asm__ __volatile__("" :: "m" (FpDest));
898        finishVfp(fpscr, state, fpscr.fz);
899        FpscrExc = fpscr;
900    '''
901    vcvtSIntFpSIop = InstObjParams("vcvt", "VcvtSIntFpS", "FpRegRegOp",
902                                     { "code": vcvtSIntFpSCode,
903                                       "predicate_test": predicateTest,
904                                       "op_class": "SimdFloatCvtOp" }, [])
905    header_output += FpRegRegOpDeclare.subst(vcvtSIntFpSIop);
906    decoder_output += FpRegRegOpConstructor.subst(vcvtSIntFpSIop);
907    exec_output += PredOpExecute.subst(vcvtSIntFpSIop);
908
909    vcvtSIntFpDCode = vfpEnabledCheckCode + '''
910        FPSCR fpscr = (FPSCR) FpscrExc;
911        VfpSavedState state = prepFpState(fpscr.rMode);
912        __asm__ __volatile__("" : "=m" (FpOp1P0_sw) : "m" (FpOp1P0_sw));
913        double cDest = FpOp1P0_sw;
914        __asm__ __volatile__("" :: "m" (cDest));
915        finishVfp(fpscr, state, fpscr.fz);
916        FpDestP0_uw = dblLow(cDest);
917        FpDestP1_uw = dblHi(cDest);
918        FpscrExc = fpscr;
919    '''
920    vcvtSIntFpDIop = InstObjParams("vcvt", "VcvtSIntFpD", "FpRegRegOp",
921                                     { "code": vcvtSIntFpDCode,
922                                       "predicate_test": predicateTest,
923                                       "op_class": "SimdFloatCvtOp" }, [])
924    header_output += FpRegRegOpDeclare.subst(vcvtSIntFpDIop);
925    decoder_output += FpRegRegOpConstructor.subst(vcvtSIntFpDIop);
926    exec_output += PredOpExecute.subst(vcvtSIntFpDIop);
927
928    vcvtFpUIntSRCode = vfpEnabledCheckCode + '''
929        FPSCR fpscr = (FPSCR) FpscrExc;
930        VfpSavedState state = prepFpState(fpscr.rMode);
931        vfpFlushToZero(fpscr, FpOp1);
932        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
933        FpDest_uw = vfpFpToFixed<float>(FpOp1, false, 32, 0, false);
934        __asm__ __volatile__("" :: "m" (FpDest_uw));
935        finishVfp(fpscr, state, fpscr.fz);
936        FpscrExc = fpscr;
937    '''
938    vcvtFpUIntSRIop = InstObjParams("vcvt", "VcvtFpUIntSR", "FpRegRegOp",
939                                     { "code": vcvtFpUIntSRCode,
940                                       "predicate_test": predicateTest,
941                                       "op_class": "SimdFloatCvtOp" }, [])
942    header_output += FpRegRegOpDeclare.subst(vcvtFpUIntSRIop);
943    decoder_output += FpRegRegOpConstructor.subst(vcvtFpUIntSRIop);
944    exec_output += PredOpExecute.subst(vcvtFpUIntSRIop);
945
946    vcvtFpUIntDRCode = vfpEnabledCheckCode + '''
947        FPSCR fpscr = (FPSCR) FpscrExc;
948        double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
949        vfpFlushToZero(fpscr, cOp1);
950        VfpSavedState state = prepFpState(fpscr.rMode);
951        __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
952        uint64_t result = vfpFpToFixed<double>(cOp1, false, 32, 0, false);
953        __asm__ __volatile__("" :: "m" (result));
954        finishVfp(fpscr, state, fpscr.fz);
955        FpDestP0_uw = result;
956        FpscrExc = fpscr;
957    '''
958    vcvtFpUIntDRIop = InstObjParams("vcvtr", "VcvtFpUIntDR", "FpRegRegOp",
959                                     { "code": vcvtFpUIntDRCode,
960                                       "predicate_test": predicateTest,
961                                       "op_class": "SimdFloatCvtOp" }, [])
962    header_output += FpRegRegOpDeclare.subst(vcvtFpUIntDRIop);
963    decoder_output += FpRegRegOpConstructor.subst(vcvtFpUIntDRIop);
964    exec_output += PredOpExecute.subst(vcvtFpUIntDRIop);
965
966    vcvtFpSIntSRCode = vfpEnabledCheckCode + '''
967        FPSCR fpscr = (FPSCR) FpscrExc;
968        VfpSavedState state = prepFpState(fpscr.rMode);
969        vfpFlushToZero(fpscr, FpOp1);
970        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
971        FpDest_sw = vfpFpToFixed<float>(FpOp1, true, 32, 0, false);
972        __asm__ __volatile__("" :: "m" (FpDest_sw));
973        finishVfp(fpscr, state, fpscr.fz);
974        FpscrExc = fpscr;
975    '''
976    vcvtFpSIntSRIop = InstObjParams("vcvtr", "VcvtFpSIntSR", "FpRegRegOp",
977                                     { "code": vcvtFpSIntSRCode,
978                                        "predicate_test": predicateTest,
979                                        "op_class": "SimdFloatCvtOp" }, [])
980    header_output += FpRegRegOpDeclare.subst(vcvtFpSIntSRIop);
981    decoder_output += FpRegRegOpConstructor.subst(vcvtFpSIntSRIop);
982    exec_output += PredOpExecute.subst(vcvtFpSIntSRIop);
983
984    vcvtFpSIntDRCode = vfpEnabledCheckCode + '''
985        FPSCR fpscr = (FPSCR) FpscrExc;
986        double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
987        vfpFlushToZero(fpscr, cOp1);
988        VfpSavedState state = prepFpState(fpscr.rMode);
989        __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
990        int64_t result = vfpFpToFixed<double>(cOp1, true, 32, 0, false);
991        __asm__ __volatile__("" :: "m" (result));
992        finishVfp(fpscr, state, fpscr.fz);
993        FpDestP0_uw = result;
994        FpscrExc = fpscr;
995    '''
996    vcvtFpSIntDRIop = InstObjParams("vcvtr", "VcvtFpSIntDR", "FpRegRegOp",
997                                     { "code": vcvtFpSIntDRCode,
998                                       "predicate_test": predicateTest,
999                                       "op_class": "SimdFloatCvtOp" }, [])
1000    header_output += FpRegRegOpDeclare.subst(vcvtFpSIntDRIop);
1001    decoder_output += FpRegRegOpConstructor.subst(vcvtFpSIntDRIop);
1002    exec_output += PredOpExecute.subst(vcvtFpSIntDRIop);
1003
1004    vcvtFpUIntSCode = vfpEnabledCheckCode + '''
1005        FPSCR fpscr = (FPSCR) FpscrExc;
1006        vfpFlushToZero(fpscr, FpOp1);
1007        VfpSavedState state = prepFpState(fpscr.rMode);
1008        fesetround(FeRoundZero);
1009        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1010        FpDest_uw = vfpFpToFixed<float>(FpOp1, false, 32, 0);
1011        __asm__ __volatile__("" :: "m" (FpDest_uw));
1012        finishVfp(fpscr, state, fpscr.fz);
1013        FpscrExc = fpscr;
1014    '''
1015    vcvtFpUIntSIop = InstObjParams("vcvt", "VcvtFpUIntS", "FpRegRegOp",
1016                                     { "code": vcvtFpUIntSCode,
1017                                       "predicate_test": predicateTest,
1018                                       "op_class": "SimdFloatCvtOp" }, [])
1019    header_output += FpRegRegOpDeclare.subst(vcvtFpUIntSIop);
1020    decoder_output += FpRegRegOpConstructor.subst(vcvtFpUIntSIop);
1021    exec_output += PredOpExecute.subst(vcvtFpUIntSIop);
1022
1023    vcvtFpUIntDCode = vfpEnabledCheckCode + '''
1024        FPSCR fpscr = (FPSCR) FpscrExc;
1025        double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1026        vfpFlushToZero(fpscr, cOp1);
1027        VfpSavedState state = prepFpState(fpscr.rMode);
1028        fesetround(FeRoundZero);
1029        __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1030        uint64_t result = vfpFpToFixed<double>(cOp1, false, 32, 0);
1031        __asm__ __volatile__("" :: "m" (result));
1032        finishVfp(fpscr, state, fpscr.fz);
1033        FpDestP0_uw = result;
1034        FpscrExc = fpscr;
1035    '''
1036    vcvtFpUIntDIop = InstObjParams("vcvt", "VcvtFpUIntD", "FpRegRegOp",
1037                                     { "code": vcvtFpUIntDCode,
1038                                       "predicate_test": predicateTest,
1039                                       "op_class": "SimdFloatCvtOp" }, [])
1040    header_output += FpRegRegOpDeclare.subst(vcvtFpUIntDIop);
1041    decoder_output += FpRegRegOpConstructor.subst(vcvtFpUIntDIop);
1042    exec_output += PredOpExecute.subst(vcvtFpUIntDIop);
1043
1044    vcvtFpSIntSCode = vfpEnabledCheckCode + '''
1045        FPSCR fpscr = (FPSCR) FpscrExc;
1046        vfpFlushToZero(fpscr, FpOp1);
1047        VfpSavedState state = prepFpState(fpscr.rMode);
1048        fesetround(FeRoundZero);
1049        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1050        FpDest_sw = vfpFpToFixed<float>(FpOp1, true, 32, 0);
1051        __asm__ __volatile__("" :: "m" (FpDest_sw));
1052        finishVfp(fpscr, state, fpscr.fz);
1053        FpscrExc = fpscr;
1054    '''
1055    vcvtFpSIntSIop = InstObjParams("vcvt", "VcvtFpSIntS", "FpRegRegOp",
1056                                     { "code": vcvtFpSIntSCode,
1057                                       "predicate_test": predicateTest,
1058                                       "op_class": "SimdFloatCvtOp" }, [])
1059    header_output += FpRegRegOpDeclare.subst(vcvtFpSIntSIop);
1060    decoder_output += FpRegRegOpConstructor.subst(vcvtFpSIntSIop);
1061    exec_output += PredOpExecute.subst(vcvtFpSIntSIop);
1062
1063    vcvtFpSIntDCode = vfpEnabledCheckCode + '''
1064        FPSCR fpscr = (FPSCR) FpscrExc;
1065        double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1066        vfpFlushToZero(fpscr, cOp1);
1067        VfpSavedState state = prepFpState(fpscr.rMode);
1068        fesetround(FeRoundZero);
1069        __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1070        int64_t result = vfpFpToFixed<double>(cOp1, true, 32, 0);
1071        __asm__ __volatile__("" :: "m" (result));
1072        finishVfp(fpscr, state, fpscr.fz);
1073        FpDestP0_uw = result;
1074        FpscrExc = fpscr;
1075    '''
1076    vcvtFpSIntDIop = InstObjParams("vcvt", "VcvtFpSIntD", "FpRegRegOp",
1077                                     { "code": vcvtFpSIntDCode,
1078                                       "predicate_test": predicateTest,
1079                                       "op_class": "SimdFloatCvtOp" }, [])
1080    header_output += FpRegRegOpDeclare.subst(vcvtFpSIntDIop);
1081    decoder_output += FpRegRegOpConstructor.subst(vcvtFpSIntDIop);
1082    exec_output += PredOpExecute.subst(vcvtFpSIntDIop);
1083
1084    vcvtFpSFpDCode = vfpEnabledCheckCode + '''
1085        FPSCR fpscr = (FPSCR) FpscrExc;
1086        vfpFlushToZero(fpscr, FpOp1);
1087        VfpSavedState state = prepFpState(fpscr.rMode);
1088        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1089        double cDest = fixFpSFpDDest(FpscrExc, FpOp1);
1090        __asm__ __volatile__("" :: "m" (cDest));
1091        finishVfp(fpscr, state, fpscr.fz);
1092        FpDestP0_uw = dblLow(cDest);
1093        FpDestP1_uw = dblHi(cDest);
1094        FpscrExc = fpscr;
1095    '''
1096    vcvtFpSFpDIop = InstObjParams("vcvt", "VcvtFpSFpD", "FpRegRegOp",
1097                                     { "code": vcvtFpSFpDCode,
1098                                       "predicate_test": predicateTest,
1099                                       "op_class": "SimdFloatCvtOp" }, [])
1100    header_output += FpRegRegOpDeclare.subst(vcvtFpSFpDIop);
1101    decoder_output += FpRegRegOpConstructor.subst(vcvtFpSFpDIop);
1102    exec_output += PredOpExecute.subst(vcvtFpSFpDIop);
1103
1104    vcvtFpDFpSCode = vfpEnabledCheckCode + '''
1105        FPSCR fpscr = (FPSCR) FpscrExc;
1106        double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1107        vfpFlushToZero(fpscr, cOp1);
1108        VfpSavedState state = prepFpState(fpscr.rMode);
1109        __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1110        FpDest = fixFpDFpSDest(FpscrExc, cOp1);
1111        __asm__ __volatile__("" :: "m" (FpDest));
1112        finishVfp(fpscr, state, fpscr.fz);
1113        FpscrExc = fpscr;
1114    '''
1115    vcvtFpDFpSIop = InstObjParams("vcvt", "VcvtFpDFpS", "FpRegRegOp",
1116                                     { "code": vcvtFpDFpSCode,
1117                                       "predicate_test": predicateTest,
1118                                       "op_class": "SimdFloatCvtOp" }, [])
1119    header_output += FpRegRegOpDeclare.subst(vcvtFpDFpSIop);
1120    decoder_output += FpRegRegOpConstructor.subst(vcvtFpDFpSIop);
1121    exec_output += PredOpExecute.subst(vcvtFpDFpSIop);
1122
1123    vcvtFpHTFpSCode = vfpEnabledCheckCode + '''
1124        FPSCR fpscr = (FPSCR) FpscrExc;
1125        vfpFlushToZero(fpscr, FpOp1);
1126        VfpSavedState state = prepFpState(fpscr.rMode);
1127        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1128        FpDest = vcvtFpHFpS(fpscr, fpscr.dn, fpscr.ahp,
1129                            bits(fpToBits(FpOp1), 31, 16));
1130        __asm__ __volatile__("" :: "m" (FpDest));
1131        finishVfp(fpscr, state, fpscr.fz);
1132        FpscrExc = fpscr;
1133    '''
1134    vcvtFpHTFpSIop = InstObjParams("vcvtt", "VcvtFpHTFpS", "FpRegRegOp",
1135                                   { "code": vcvtFpHTFpSCode,
1136                                     "predicate_test": predicateTest,
1137                                     "op_class": "SimdFloatCvtOp" }, [])
1138    header_output += FpRegRegOpDeclare.subst(vcvtFpHTFpSIop);
1139    decoder_output += FpRegRegOpConstructor.subst(vcvtFpHTFpSIop);
1140    exec_output += PredOpExecute.subst(vcvtFpHTFpSIop);
1141
1142    vcvtFpHBFpSCode = vfpEnabledCheckCode + '''
1143        FPSCR fpscr = (FPSCR) FpscrExc;
1144        VfpSavedState state = prepFpState(fpscr.rMode);
1145        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1146        FpDest = vcvtFpHFpS(fpscr, fpscr.dn, fpscr.ahp,
1147                            bits(fpToBits(FpOp1), 15, 0));
1148        __asm__ __volatile__("" :: "m" (FpDest));
1149        finishVfp(fpscr, state, fpscr.fz);
1150        FpscrExc = fpscr;
1151    '''
1152    vcvtFpHBFpSIop = InstObjParams("vcvtb", "VcvtFpHBFpS", "FpRegRegOp",
1153                                   { "code": vcvtFpHBFpSCode,
1154                                     "predicate_test": predicateTest,
1155                                     "op_class": "SimdFloatCvtOp" }, [])
1156    header_output += FpRegRegOpDeclare.subst(vcvtFpHBFpSIop);
1157    decoder_output += FpRegRegOpConstructor.subst(vcvtFpHBFpSIop);
1158    exec_output += PredOpExecute.subst(vcvtFpHBFpSIop);
1159
1160    vcvtFpSFpHTCode = vfpEnabledCheckCode + '''
1161        FPSCR fpscr = (FPSCR) FpscrExc;
1162        vfpFlushToZero(fpscr, FpOp1);
1163        VfpSavedState state = prepFpState(fpscr.rMode);
1164        __asm__ __volatile__("" : "=m" (FpOp1), "=m" (FpDest_uw)
1165                                : "m" (FpOp1), "m" (FpDest_uw));
1166        FpDest_uw = insertBits(FpDest_uw, 31, 16,,
1167                               vcvtFpSFpH(fpscr, fpscr.fz, fpscr.dn,
1168                               fpscr.rMode, fpscr.ahp, FpOp1));
1169        __asm__ __volatile__("" :: "m" (FpDest_uw));
1170        finishVfp(fpscr, state, fpscr.fz);
1171        FpscrExc = fpscr;
1172    '''
1173    vcvtFpSFpHTIop = InstObjParams("vcvtt", "VcvtFpSFpHT", "FpRegRegOp",
1174                                    { "code": vcvtFpHTFpSCode,
1175                                      "predicate_test": predicateTest,
1176                                      "op_class": "SimdFloatCvtOp" }, [])
1177    header_output += FpRegRegOpDeclare.subst(vcvtFpSFpHTIop);
1178    decoder_output += FpRegRegOpConstructor.subst(vcvtFpSFpHTIop);
1179    exec_output += PredOpExecute.subst(vcvtFpSFpHTIop);
1180
1181    vcvtFpSFpHBCode = vfpEnabledCheckCode + '''
1182        FPSCR fpscr = (FPSCR) FpscrExc;
1183        vfpFlushToZero(fpscr, FpOp1);
1184        VfpSavedState state = prepFpState(fpscr.rMode);
1185        __asm__ __volatile__("" : "=m" (FpOp1), "=m" (FpDest_uw)
1186                                : "m" (FpOp1), "m" (FpDest_uw));
1187        FpDest_uw = insertBits(FpDest_uw, 15, 0,
1188                               vcvtFpSFpH(fpscr, fpscr.fz, fpscr.dn,
1189                               fpscr.rMode, fpscr.ahp, FpOp1));
1190        __asm__ __volatile__("" :: "m" (FpDest_uw));
1191        finishVfp(fpscr, state, fpscr.fz);
1192        FpscrExc = fpscr;
1193    '''
1194    vcvtFpSFpHBIop = InstObjParams("vcvtb", "VcvtFpSFpHB", "FpRegRegOp",
1195                                   { "code": vcvtFpSFpHBCode,
1196                                     "predicate_test": predicateTest,
1197                                     "op_class": "SimdFloatCvtOp" }, [])
1198    header_output += FpRegRegOpDeclare.subst(vcvtFpSFpHBIop);
1199    decoder_output += FpRegRegOpConstructor.subst(vcvtFpSFpHBIop);
1200    exec_output += PredOpExecute.subst(vcvtFpSFpHBIop);
1201
1202    vcmpSCode = vfpEnabledCheckCode + '''
1203        FPSCR fpscr = (FPSCR) FpscrExc;
1204        vfpFlushToZero(fpscr, FpDest, FpOp1);
1205        if (FpDest == FpOp1) {
1206            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1207        } else if (FpDest < FpOp1) {
1208            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1209        } else if (FpDest > FpOp1) {
1210            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1211        } else {
1212            const uint32_t qnan = 0x7fc00000;
1213            const bool nan1 = std::isnan(FpDest);
1214            const bool signal1 = nan1 && ((fpToBits(FpDest) & qnan) != qnan);
1215            const bool nan2 = std::isnan(FpOp1);
1216            const bool signal2 = nan2 && ((fpToBits(FpOp1) & qnan) != qnan);
1217            if (signal1 || signal2)
1218                fpscr.ioc = 1;
1219            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1220        }
1221        FpCondCodes = fpscr & FpCondCodesMask;
1222        FpscrExc = fpscr;
1223    '''
1224    vcmpSIop = InstObjParams("vcmps", "VcmpS", "FpRegRegOp",
1225                                     { "code": vcmpSCode,
1226                                       "predicate_test": predicateTest,
1227                                       "op_class": "SimdFloatCmpOp" }, [])
1228    header_output += FpRegRegOpDeclare.subst(vcmpSIop);
1229    decoder_output += FpRegRegOpConstructor.subst(vcmpSIop);
1230    exec_output += PredOpExecute.subst(vcmpSIop);
1231
1232    vcmpDCode = vfpEnabledCheckCode + '''
1233        double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1234        double cDest = dbl(FpDestP0_uw, FpDestP1_uw);
1235        FPSCR fpscr = (FPSCR) FpscrExc;
1236        vfpFlushToZero(fpscr, cDest, cOp1);
1237        if (cDest == cOp1) {
1238            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1239        } else if (cDest < cOp1) {
1240            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1241        } else if (cDest > cOp1) {
1242            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1243        } else {
1244            const uint64_t qnan = ULL(0x7ff8000000000000);
1245            const bool nan1 = std::isnan(cDest);
1246            const bool signal1 = nan1 && ((fpToBits(cDest) & qnan) != qnan);
1247            const bool nan2 = std::isnan(cOp1);
1248            const bool signal2 = nan2 && ((fpToBits(cOp1) & qnan) != qnan);
1249            if (signal1 || signal2)
1250                fpscr.ioc = 1;
1251            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1252        }
1253        FpCondCodes = fpscr & FpCondCodesMask;
1254        FpscrExc = fpscr;
1255    '''
1256    vcmpDIop = InstObjParams("vcmpd", "VcmpD", "FpRegRegOp",
1257                                     { "code": vcmpDCode,
1258                                       "predicate_test": predicateTest,
1259                                       "op_class": "SimdFloatCmpOp" }, [])
1260    header_output += FpRegRegOpDeclare.subst(vcmpDIop);
1261    decoder_output += FpRegRegOpConstructor.subst(vcmpDIop);
1262    exec_output += PredOpExecute.subst(vcmpDIop);
1263
1264    vcmpZeroSCode = vfpEnabledCheckCode + '''
1265        FPSCR fpscr = (FPSCR) FpscrExc;
1266        vfpFlushToZero(fpscr, FpDest);
1267        // This only handles imm == 0 for now.
1268        assert(imm == 0);
1269        if (FpDest == imm) {
1270            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1271        } else if (FpDest < imm) {
1272            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1273        } else if (FpDest > imm) {
1274            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1275        } else {
1276            const uint32_t qnan = 0x7fc00000;
1277            const bool nan = std::isnan(FpDest);
1278            const bool signal = nan && ((fpToBits(FpDest) & qnan) != qnan);
1279            if (signal)
1280                fpscr.ioc = 1;
1281            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1282        }
1283        FpCondCodes = fpscr & FpCondCodesMask;
1284        FpscrExc = fpscr;
1285    '''
1286    vcmpZeroSIop = InstObjParams("vcmpZeros", "VcmpZeroS", "FpRegImmOp",
1287                                     { "code": vcmpZeroSCode,
1288                                       "predicate_test": predicateTest,
1289                                       "op_class": "SimdFloatCmpOp" }, [])
1290    header_output += FpRegImmOpDeclare.subst(vcmpZeroSIop);
1291    decoder_output += FpRegImmOpConstructor.subst(vcmpZeroSIop);
1292    exec_output += PredOpExecute.subst(vcmpZeroSIop);
1293
1294    vcmpZeroDCode = vfpEnabledCheckCode + '''
1295        // This only handles imm == 0 for now.
1296        assert(imm == 0);
1297        double cDest = dbl(FpDestP0_uw, FpDestP1_uw);
1298        FPSCR fpscr = (FPSCR) FpscrExc;
1299        vfpFlushToZero(fpscr, cDest);
1300        if (cDest == imm) {
1301            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1302        } else if (cDest < imm) {
1303            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1304        } else if (cDest > imm) {
1305            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1306        } else {
1307            const uint64_t qnan = ULL(0x7ff8000000000000);
1308            const bool nan = std::isnan(cDest);
1309            const bool signal = nan && ((fpToBits(cDest) & qnan) != qnan);
1310            if (signal)
1311                fpscr.ioc = 1;
1312            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1313        }
1314        FpCondCodes = fpscr & FpCondCodesMask;
1315        FpscrExc = fpscr;
1316    '''
1317    vcmpZeroDIop = InstObjParams("vcmpZerod", "VcmpZeroD", "FpRegImmOp",
1318                                     { "code": vcmpZeroDCode,
1319                                       "predicate_test": predicateTest,
1320                                       "op_class": "SimdFloatCmpOp" }, [])
1321    header_output += FpRegImmOpDeclare.subst(vcmpZeroDIop);
1322    decoder_output += FpRegImmOpConstructor.subst(vcmpZeroDIop);
1323    exec_output += PredOpExecute.subst(vcmpZeroDIop);
1324
1325    vcmpeSCode = vfpEnabledCheckCode + '''
1326        FPSCR fpscr = (FPSCR) FpscrExc;
1327        vfpFlushToZero(fpscr, FpDest, FpOp1);
1328        if (FpDest == FpOp1) {
1329            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1330        } else if (FpDest < FpOp1) {
1331            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1332        } else if (FpDest > FpOp1) {
1333            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1334        } else {
1335            fpscr.ioc = 1;
1336            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1337        }
1338        FpCondCodes = fpscr & FpCondCodesMask;
1339        FpscrExc = fpscr;
1340    '''
1341    vcmpeSIop = InstObjParams("vcmpes", "VcmpeS", "FpRegRegOp",
1342                                     { "code": vcmpeSCode,
1343                                       "predicate_test": predicateTest,
1344                                       "op_class": "SimdFloatCmpOp" }, [])
1345    header_output += FpRegRegOpDeclare.subst(vcmpeSIop);
1346    decoder_output += FpRegRegOpConstructor.subst(vcmpeSIop);
1347    exec_output += PredOpExecute.subst(vcmpeSIop);
1348
1349    vcmpeDCode = vfpEnabledCheckCode + '''
1350        double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1351        double cDest = dbl(FpDestP0_uw, FpDestP1_uw);
1352        FPSCR fpscr = (FPSCR) FpscrExc;
1353        vfpFlushToZero(fpscr, cDest, cOp1);
1354        if (cDest == cOp1) {
1355            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1356        } else if (cDest < cOp1) {
1357            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1358        } else if (cDest > cOp1) {
1359            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1360        } else {
1361            fpscr.ioc = 1;
1362            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1363        }
1364        FpCondCodes = fpscr & FpCondCodesMask;
1365        FpscrExc = fpscr;
1366    '''
1367    vcmpeDIop = InstObjParams("vcmped", "VcmpeD", "FpRegRegOp",
1368                                     { "code": vcmpeDCode,
1369                                       "predicate_test": predicateTest,
1370                                       "op_class": "SimdFloatCmpOp" }, [])
1371    header_output += FpRegRegOpDeclare.subst(vcmpeDIop);
1372    decoder_output += FpRegRegOpConstructor.subst(vcmpeDIop);
1373    exec_output += PredOpExecute.subst(vcmpeDIop);
1374
1375    vcmpeZeroSCode = vfpEnabledCheckCode + '''
1376        FPSCR fpscr = (FPSCR) FpscrExc;
1377        vfpFlushToZero(fpscr, FpDest);
1378        if (FpDest == imm) {
1379            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1380        } else if (FpDest < imm) {
1381            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1382        } else if (FpDest > imm) {
1383            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1384        } else {
1385            fpscr.ioc = 1;
1386            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1387        }
1388        FpCondCodes = fpscr & FpCondCodesMask;
1389        FpscrExc = fpscr;
1390    '''
1391    vcmpeZeroSIop = InstObjParams("vcmpeZeros", "VcmpeZeroS", "FpRegImmOp",
1392                                     { "code": vcmpeZeroSCode,
1393                                       "predicate_test": predicateTest,
1394                                       "op_class": "SimdFloatCmpOp" }, [])
1395    header_output += FpRegImmOpDeclare.subst(vcmpeZeroSIop);
1396    decoder_output += FpRegImmOpConstructor.subst(vcmpeZeroSIop);
1397    exec_output += PredOpExecute.subst(vcmpeZeroSIop);
1398
1399    vcmpeZeroDCode = vfpEnabledCheckCode + '''
1400        double cDest = dbl(FpDestP0_uw, FpDestP1_uw);
1401        FPSCR fpscr = (FPSCR) FpscrExc;
1402        vfpFlushToZero(fpscr, cDest);
1403        if (cDest == imm) {
1404            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1405        } else if (cDest < imm) {
1406            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1407        } else if (cDest > imm) {
1408            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1409        } else {
1410            fpscr.ioc = 1;
1411            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1412        }
1413        FpCondCodes = fpscr & FpCondCodesMask;
1414        FpscrExc = fpscr;
1415    '''
1416    vcmpeZeroDIop = InstObjParams("vcmpeZerod", "VcmpeZeroD", "FpRegImmOp",
1417                                     { "code": vcmpeZeroDCode,
1418                                       "predicate_test": predicateTest,
1419                                       "op_class": "SimdFloatCmpOp" }, [])
1420    header_output += FpRegImmOpDeclare.subst(vcmpeZeroDIop);
1421    decoder_output += FpRegImmOpConstructor.subst(vcmpeZeroDIop);
1422    exec_output += PredOpExecute.subst(vcmpeZeroDIop);
1423}};
1424
1425let {{
1426
1427    header_output = ""
1428    decoder_output = ""
1429    exec_output = ""
1430
1431    vselSCode = vfpEnabledCheckCode + '''
1432        if (testPredicate(CondCodesNZ, CondCodesC, CondCodesV, cond)) {
1433            FpDest = FpOp1;
1434        } else {
1435            FpDest = FpOp2;
1436        } '''
1437
1438    vselSIop = InstObjParams("vsels", "VselS", "FpRegRegRegCondOp",
1439                             { "code" : vselSCode,
1440                               "predicate_test" : predicateTest,
1441                               "op_class" : "SimdFloatCmpOp" }, [] )
1442    header_output += FpRegRegRegCondOpDeclare.subst(vselSIop);
1443    decoder_output += FpRegRegRegCondOpConstructor.subst(vselSIop);
1444    exec_output +=  PredOpExecute.subst(vselSIop);
1445
1446    vselDCode = vfpEnabledCheckCode + '''
1447        if (testPredicate(CondCodesNZ, CondCodesC, CondCodesV, cond)) {
1448            FpDestP0_uw = FpOp1P0_uw;
1449            FpDestP1_uw = FpOp1P1_uw;
1450        } else {
1451            FpDestP0_uw = FpOp2P0_uw;
1452            FpDestP1_uw = FpOp2P1_uw;
1453        } '''
1454
1455    vselDIop = InstObjParams("vseld", "VselD", "FpRegRegRegCondOp",
1456                             { "code" : vselDCode,
1457                               "predicate_test" : predicateTest,
1458                               "op_class" : "SimdFloatCmpOp" }, [] )
1459    header_output += FpRegRegRegCondOpDeclare.subst(vselDIop);
1460    decoder_output += FpRegRegRegCondOpConstructor.subst(vselDIop);
1461    exec_output +=  PredOpExecute.subst(vselDIop);
1462}};
1463
1464
1465let {{
1466
1467    header_output = ""
1468    decoder_output = ""
1469    exec_output = ""
1470
1471    vcvtFpSFixedSCode = vfpEnabledCheckCode + '''
1472        FPSCR fpscr = (FPSCR) FpscrExc;
1473        vfpFlushToZero(fpscr, FpOp1);
1474        VfpSavedState state = prepFpState(fpscr.rMode);
1475        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1476        FpDest_sw = vfpFpToFixed<float>(FpOp1, true, 32, imm);
1477        __asm__ __volatile__("" :: "m" (FpDest_sw));
1478        finishVfp(fpscr, state, fpscr.fz);
1479        FpscrExc = fpscr;
1480    '''
1481    vcvtFpSFixedSIop = InstObjParams("vcvt", "VcvtFpSFixedS", "FpRegRegImmOp",
1482                                     { "code": vcvtFpSFixedSCode,
1483                                       "predicate_test": predicateTest,
1484                                       "op_class": "SimdFloatCvtOp" }, [])
1485    header_output += FpRegRegImmOpDeclare.subst(vcvtFpSFixedSIop);
1486    decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSFixedSIop);
1487    exec_output += PredOpExecute.subst(vcvtFpSFixedSIop);
1488
1489    vcvtFpSFixedDCode = vfpEnabledCheckCode + '''
1490        FPSCR fpscr = (FPSCR) FpscrExc;
1491        double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1492        vfpFlushToZero(fpscr, cOp1);
1493        VfpSavedState state = prepFpState(fpscr.rMode);
1494        __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1495        uint64_t mid = vfpFpToFixed<double>(cOp1, true, 32, imm);
1496        __asm__ __volatile__("" :: "m" (mid));
1497        finishVfp(fpscr, state, fpscr.fz);
1498        FpDestP0_uw = mid;
1499        FpDestP1_uw = mid >> 32;
1500        FpscrExc = fpscr;
1501    '''
1502    vcvtFpSFixedDIop = InstObjParams("vcvt", "VcvtFpSFixedD", "FpRegRegImmOp",
1503                                     { "code": vcvtFpSFixedDCode,
1504                                       "predicate_test": predicateTest,
1505                                       "op_class": "SimdFloatCvtOp" }, [])
1506    header_output += FpRegRegImmOpDeclare.subst(vcvtFpSFixedDIop);
1507    decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSFixedDIop);
1508    exec_output += PredOpExecute.subst(vcvtFpSFixedDIop);
1509
1510    vcvtFpUFixedSCode = vfpEnabledCheckCode + '''
1511        FPSCR fpscr = (FPSCR) FpscrExc;
1512        vfpFlushToZero(fpscr, FpOp1);
1513        VfpSavedState state = prepFpState(fpscr.rMode);
1514        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1515        FpDest_uw = vfpFpToFixed<float>(FpOp1, false, 32, imm);
1516        __asm__ __volatile__("" :: "m" (FpDest_uw));
1517        finishVfp(fpscr, state, fpscr.fz);
1518        FpscrExc = fpscr;
1519    '''
1520    vcvtFpUFixedSIop = InstObjParams("vcvt", "VcvtFpUFixedS", "FpRegRegImmOp",
1521                                     { "code": vcvtFpUFixedSCode,
1522                                       "predicate_test": predicateTest,
1523                                       "op_class": "SimdFloatCvtOp" }, [])
1524    header_output += FpRegRegImmOpDeclare.subst(vcvtFpUFixedSIop);
1525    decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUFixedSIop);
1526    exec_output += PredOpExecute.subst(vcvtFpUFixedSIop);
1527
1528    vcvtFpUFixedDCode = vfpEnabledCheckCode + '''
1529        FPSCR fpscr = (FPSCR) FpscrExc;
1530        double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1531        vfpFlushToZero(fpscr, cOp1);
1532        VfpSavedState state = prepFpState(fpscr.rMode);
1533        __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1534        uint64_t mid = vfpFpToFixed<double>(cOp1, false, 32, imm);
1535        __asm__ __volatile__("" :: "m" (mid));
1536        finishVfp(fpscr, state, fpscr.fz);
1537        FpDestP0_uw = mid;
1538        FpDestP1_uw = mid >> 32;
1539        FpscrExc = fpscr;
1540    '''
1541    vcvtFpUFixedDIop = InstObjParams("vcvt", "VcvtFpUFixedD", "FpRegRegImmOp",
1542                                     { "code": vcvtFpUFixedDCode,
1543                                       "predicate_test": predicateTest,
1544                                       "op_class": "SimdFloatCvtOp" }, [])
1545    header_output += FpRegRegImmOpDeclare.subst(vcvtFpUFixedDIop);
1546    decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUFixedDIop);
1547    exec_output += PredOpExecute.subst(vcvtFpUFixedDIop);
1548
1549    vcvtSFixedFpSCode = vfpEnabledCheckCode + '''
1550        FPSCR fpscr = (FPSCR) FpscrExc;
1551        VfpSavedState state = prepFpState(fpscr.rMode);
1552        __asm__ __volatile__("" : "=m" (FpOp1_sw) : "m" (FpOp1_sw));
1553        FpDest = vfpSFixedToFpS(fpscr.fz, fpscr.dn, FpOp1_sw, 32, imm);
1554        __asm__ __volatile__("" :: "m" (FpDest));
1555        finishVfp(fpscr, state, fpscr.fz);
1556        FpscrExc = fpscr;
1557    '''
1558    vcvtSFixedFpSIop = InstObjParams("vcvt", "VcvtSFixedFpS", "FpRegRegImmOp",
1559                                     { "code": vcvtSFixedFpSCode,
1560                                       "predicate_test": predicateTest,
1561                                       "op_class": "SimdFloatCvtOp" }, [])
1562    header_output += FpRegRegImmOpDeclare.subst(vcvtSFixedFpSIop);
1563    decoder_output += FpRegRegImmOpConstructor.subst(vcvtSFixedFpSIop);
1564    exec_output += PredOpExecute.subst(vcvtSFixedFpSIop);
1565
1566    vcvtSFixedFpDCode = vfpEnabledCheckCode + '''
1567        FPSCR fpscr = (FPSCR) FpscrExc;
1568        uint64_t mid = ((uint64_t)FpOp1P0_uw | ((uint64_t)FpOp1P1_uw << 32));
1569        VfpSavedState state = prepFpState(fpscr.rMode);
1570        __asm__ __volatile__("" : "=m" (mid) : "m" (mid));
1571        double cDest = vfpSFixedToFpD(fpscr.fz, fpscr.dn, mid, 32, imm);
1572        __asm__ __volatile__("" :: "m" (cDest));
1573        finishVfp(fpscr, state, fpscr.fz);
1574        FpDestP0_uw = dblLow(cDest);
1575        FpDestP1_uw = dblHi(cDest);
1576        FpscrExc = fpscr;
1577    '''
1578    vcvtSFixedFpDIop = InstObjParams("vcvt", "VcvtSFixedFpD", "FpRegRegImmOp",
1579                                     { "code": vcvtSFixedFpDCode,
1580                                       "predicate_test": predicateTest,
1581                                       "op_class": "SimdFloatCvtOp" }, [])
1582    header_output += FpRegRegImmOpDeclare.subst(vcvtSFixedFpDIop);
1583    decoder_output += FpRegRegImmOpConstructor.subst(vcvtSFixedFpDIop);
1584    exec_output += PredOpExecute.subst(vcvtSFixedFpDIop);
1585
1586    vcvtUFixedFpSCode = vfpEnabledCheckCode + '''
1587        FPSCR fpscr = (FPSCR) FpscrExc;
1588        VfpSavedState state = prepFpState(fpscr.rMode);
1589        __asm__ __volatile__("" : "=m" (FpOp1_uw) : "m" (FpOp1_uw));
1590        FpDest = vfpUFixedToFpS(fpscr.fz, fpscr.dn, FpOp1_uw, 32, imm);
1591        __asm__ __volatile__("" :: "m" (FpDest));
1592        finishVfp(fpscr, state, fpscr.fz);
1593        FpscrExc = fpscr;
1594    '''
1595    vcvtUFixedFpSIop = InstObjParams("vcvt", "VcvtUFixedFpS", "FpRegRegImmOp",
1596                                     { "code": vcvtUFixedFpSCode,
1597                                       "predicate_test": predicateTest,
1598                                       "op_class": "SimdFloatCvtOp" }, [])
1599    header_output += FpRegRegImmOpDeclare.subst(vcvtUFixedFpSIop);
1600    decoder_output += FpRegRegImmOpConstructor.subst(vcvtUFixedFpSIop);
1601    exec_output += PredOpExecute.subst(vcvtUFixedFpSIop);
1602
1603    vcvtUFixedFpDCode = vfpEnabledCheckCode + '''
1604        FPSCR fpscr = (FPSCR) FpscrExc;
1605        uint64_t mid = ((uint64_t)FpOp1P0_uw | ((uint64_t)FpOp1P1_uw << 32));
1606        VfpSavedState state = prepFpState(fpscr.rMode);
1607        __asm__ __volatile__("" : "=m" (mid) : "m" (mid));
1608        double cDest = vfpUFixedToFpD(fpscr.fz, fpscr.dn, mid, 32, imm);
1609        __asm__ __volatile__("" :: "m" (cDest));
1610        finishVfp(fpscr, state, fpscr.fz);
1611        FpDestP0_uw = dblLow(cDest);
1612        FpDestP1_uw = dblHi(cDest);
1613        FpscrExc = fpscr;
1614    '''
1615    vcvtUFixedFpDIop = InstObjParams("vcvt", "VcvtUFixedFpD", "FpRegRegImmOp",
1616                                     { "code": vcvtUFixedFpDCode,
1617                                       "predicate_test": predicateTest,
1618                                       "op_class": "SimdFloatCvtOp" }, [])
1619    header_output += FpRegRegImmOpDeclare.subst(vcvtUFixedFpDIop);
1620    decoder_output += FpRegRegImmOpConstructor.subst(vcvtUFixedFpDIop);
1621    exec_output += PredOpExecute.subst(vcvtUFixedFpDIop);
1622
1623    vcvtFpSHFixedSCode = vfpEnabledCheckCode + '''
1624        FPSCR fpscr = (FPSCR) FpscrExc;
1625        vfpFlushToZero(fpscr, FpOp1);
1626        VfpSavedState state = prepFpState(fpscr.rMode);
1627        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1628        FpDest_sh = vfpFpToFixed<float>(FpOp1, true, 16, imm);
1629        __asm__ __volatile__("" :: "m" (FpDest_sh));
1630        finishVfp(fpscr, state, fpscr.fz);
1631        FpscrExc = fpscr;
1632    '''
1633    vcvtFpSHFixedSIop = InstObjParams("vcvt", "VcvtFpSHFixedS",
1634                                      "FpRegRegImmOp",
1635                                     { "code": vcvtFpSHFixedSCode,
1636                                       "predicate_test": predicateTest,
1637                                       "op_class": "SimdFloatCvtOp" }, [])
1638    header_output += FpRegRegImmOpDeclare.subst(vcvtFpSHFixedSIop);
1639    decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSHFixedSIop);
1640    exec_output += PredOpExecute.subst(vcvtFpSHFixedSIop);
1641
1642    vcvtFpSHFixedDCode = vfpEnabledCheckCode + '''
1643        FPSCR fpscr = (FPSCR) FpscrExc;
1644        double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1645        vfpFlushToZero(fpscr, cOp1);
1646        VfpSavedState state = prepFpState(fpscr.rMode);
1647        __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1648        uint64_t result = vfpFpToFixed<double>(cOp1, true, 16, imm);
1649        __asm__ __volatile__("" :: "m" (result));
1650        finishVfp(fpscr, state, fpscr.fz);
1651        FpDestP0_uw = result;
1652        FpDestP1_uw = result >> 32;
1653        FpscrExc = fpscr;
1654    '''
1655    vcvtFpSHFixedDIop = InstObjParams("vcvt", "VcvtFpSHFixedD",
1656                                      "FpRegRegImmOp",
1657                                     { "code": vcvtFpSHFixedDCode,
1658                                       "predicate_test": predicateTest,
1659                                       "op_class": "SimdFloatCvtOp" }, [])
1660    header_output += FpRegRegImmOpDeclare.subst(vcvtFpSHFixedDIop);
1661    decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSHFixedDIop);
1662    exec_output += PredOpExecute.subst(vcvtFpSHFixedDIop);
1663
1664    vcvtFpUHFixedSCode = vfpEnabledCheckCode + '''
1665        FPSCR fpscr = (FPSCR) FpscrExc;
1666        vfpFlushToZero(fpscr, FpOp1);
1667        VfpSavedState state = prepFpState(fpscr.rMode);
1668        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1669        FpDest_uh = vfpFpToFixed<float>(FpOp1, false, 16, imm);
1670        __asm__ __volatile__("" :: "m" (FpDest_uh));
1671        finishVfp(fpscr, state, fpscr.fz);
1672        FpscrExc = fpscr;
1673    '''
1674    vcvtFpUHFixedSIop = InstObjParams("vcvt", "VcvtFpUHFixedS",
1675                                      "FpRegRegImmOp",
1676                                     { "code": vcvtFpUHFixedSCode,
1677                                       "predicate_test": predicateTest,
1678                                       "op_class": "SimdFloatCvtOp" }, [])
1679    header_output += FpRegRegImmOpDeclare.subst(vcvtFpUHFixedSIop);
1680    decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUHFixedSIop);
1681    exec_output += PredOpExecute.subst(vcvtFpUHFixedSIop);
1682
1683    vcvtFpUHFixedDCode = vfpEnabledCheckCode + '''
1684        FPSCR fpscr = (FPSCR) FpscrExc;
1685        double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1686        vfpFlushToZero(fpscr, cOp1);
1687        VfpSavedState state = prepFpState(fpscr.rMode);
1688        __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1689        uint64_t mid = vfpFpToFixed<double>(cOp1, false, 16, imm);
1690        __asm__ __volatile__("" :: "m" (mid));
1691        finishVfp(fpscr, state, fpscr.fz);
1692        FpDestP0_uw = mid;
1693        FpDestP1_uw = mid >> 32;
1694        FpscrExc = fpscr;
1695    '''
1696    vcvtFpUHFixedDIop = InstObjParams("vcvt", "VcvtFpUHFixedD",
1697                                      "FpRegRegImmOp",
1698                                     { "code": vcvtFpUHFixedDCode,
1699                                       "predicate_test": predicateTest,
1700                                       "op_class": "SimdFloatCvtOp" }, [])
1701    header_output += FpRegRegImmOpDeclare.subst(vcvtFpUHFixedDIop);
1702    decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUHFixedDIop);
1703    exec_output += PredOpExecute.subst(vcvtFpUHFixedDIop);
1704
1705    vcvtSHFixedFpSCode = vfpEnabledCheckCode + '''
1706        FPSCR fpscr = (FPSCR) FpscrExc;
1707        VfpSavedState state = prepFpState(fpscr.rMode);
1708        __asm__ __volatile__("" : "=m" (FpOp1_sh) : "m" (FpOp1_sh));
1709        FpDest = vfpSFixedToFpS(fpscr.fz, fpscr.dn, FpOp1_sh, 16, imm);
1710        __asm__ __volatile__("" :: "m" (FpDest));
1711        finishVfp(fpscr, state, fpscr.fz);
1712        FpscrExc = fpscr;
1713    '''
1714    vcvtSHFixedFpSIop = InstObjParams("vcvt", "VcvtSHFixedFpS",
1715                                      "FpRegRegImmOp",
1716                                     { "code": vcvtSHFixedFpSCode,
1717                                       "predicate_test": predicateTest,
1718                                       "op_class": "SimdFloatCvtOp" }, [])
1719    header_output += FpRegRegImmOpDeclare.subst(vcvtSHFixedFpSIop);
1720    decoder_output += FpRegRegImmOpConstructor.subst(vcvtSHFixedFpSIop);
1721    exec_output += PredOpExecute.subst(vcvtSHFixedFpSIop);
1722
1723    vcvtSHFixedFpDCode = vfpEnabledCheckCode + '''
1724        FPSCR fpscr = (FPSCR) FpscrExc;
1725        uint64_t mid = ((uint64_t)FpOp1P0_uw | ((uint64_t)FpOp1P1_uw << 32));
1726        VfpSavedState state = prepFpState(fpscr.rMode);
1727        __asm__ __volatile__("" : "=m" (mid) : "m" (mid));
1728        double cDest = vfpSFixedToFpD(fpscr.fz, fpscr.dn, mid, 16, imm);
1729        __asm__ __volatile__("" :: "m" (cDest));
1730        finishVfp(fpscr, state, fpscr.fz);
1731        FpDestP0_uw = dblLow(cDest);
1732        FpDestP1_uw = dblHi(cDest);
1733        FpscrExc = fpscr;
1734    '''
1735    vcvtSHFixedFpDIop = InstObjParams("vcvt", "VcvtSHFixedFpD",
1736                                      "FpRegRegImmOp",
1737                                     { "code": vcvtSHFixedFpDCode,
1738                                       "predicate_test": predicateTest,
1739                                       "op_class": "SimdFloatCvtOp" }, [])
1740    header_output += FpRegRegImmOpDeclare.subst(vcvtSHFixedFpDIop);
1741    decoder_output += FpRegRegImmOpConstructor.subst(vcvtSHFixedFpDIop);
1742    exec_output += PredOpExecute.subst(vcvtSHFixedFpDIop);
1743
1744    vcvtUHFixedFpSCode = vfpEnabledCheckCode + '''
1745        FPSCR fpscr = (FPSCR) FpscrExc;
1746        VfpSavedState state = prepFpState(fpscr.rMode);
1747        __asm__ __volatile__("" : "=m" (FpOp1_uh) : "m" (FpOp1_uh));
1748        FpDest = vfpUFixedToFpS(fpscr.fz, fpscr.dn, FpOp1_uh, 16, imm);
1749        __asm__ __volatile__("" :: "m" (FpDest));
1750        finishVfp(fpscr, state, fpscr.fz);
1751        FpscrExc = fpscr;
1752    '''
1753    vcvtUHFixedFpSIop = InstObjParams("vcvt", "VcvtUHFixedFpS",
1754                                      "FpRegRegImmOp",
1755                                     { "code": vcvtUHFixedFpSCode,
1756                                       "predicate_test": predicateTest,
1757                                       "op_class": "SimdFloatCvtOp" }, [])
1758    header_output += FpRegRegImmOpDeclare.subst(vcvtUHFixedFpSIop);
1759    decoder_output += FpRegRegImmOpConstructor.subst(vcvtUHFixedFpSIop);
1760    exec_output += PredOpExecute.subst(vcvtUHFixedFpSIop);
1761
1762    vcvtUHFixedFpDCode = vfpEnabledCheckCode + '''
1763        FPSCR fpscr = (FPSCR) FpscrExc;
1764        uint64_t mid = ((uint64_t)FpOp1P0_uw | ((uint64_t)FpOp1P1_uw << 32));
1765        VfpSavedState state = prepFpState(fpscr.rMode);
1766        __asm__ __volatile__("" : "=m" (mid) : "m" (mid));
1767        double cDest = vfpUFixedToFpD(fpscr.fz, fpscr.dn, mid, 16, imm);
1768        __asm__ __volatile__("" :: "m" (cDest));
1769        finishVfp(fpscr, state, fpscr.fz);
1770        FpDestP0_uw = dblLow(cDest);
1771        FpDestP1_uw = dblHi(cDest);
1772        FpscrExc = fpscr;
1773    '''
1774    vcvtUHFixedFpDIop = InstObjParams("vcvt", "VcvtUHFixedFpD",
1775                                      "FpRegRegImmOp",
1776                                     { "code": vcvtUHFixedFpDCode,
1777                                       "predicate_test": predicateTest,
1778                                       "op_class": "SimdFloatCvtOp" }, [])
1779    header_output += FpRegRegImmOpDeclare.subst(vcvtUHFixedFpDIop);
1780    decoder_output += FpRegRegImmOpConstructor.subst(vcvtUHFixedFpDIop);
1781    exec_output += PredOpExecute.subst(vcvtUHFixedFpDIop);
1782}};
1783