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