fp.isa revision 13738:84439021dcf6
1// -*- mode:c++ -*-
2
3// Copyright (c) 2010-2013,2016,2018-2019 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    round_mode_suffix_to_mode = {
997        '': 'VfpRoundZero',
998        'a': 'VfpRoundAway',
999        'm': 'VfpRoundDown',
1000        'n': 'VfpRoundNearest',
1001        'p': 'VfpRoundUpward',
1002    }
1003
1004    def buildVcvt(code, className, roundModeSuffix):
1005        global header_output, decoder_output, exec_output, \
1006            vfpEnabledCheckCode, round_mode_suffix_to_mode
1007        full_code = vfpEnabledCheckCode + code.format(
1008            round_mode=round_mode_suffix_to_mode[roundModeSuffix],
1009        )
1010        iop = InstObjParams(
1011            "vcvt{}".format(roundModeSuffix),
1012            className.format(roundModeSuffix),
1013            "FpRegRegOp",
1014            { "code": full_code,
1015              "predicate_test": predicateTest,
1016              "op_class": "SimdFloatCvtOp" },
1017            []
1018        )
1019        header_output += FpRegRegOpDeclare.subst(iop);
1020        decoder_output += FpRegRegOpConstructor.subst(iop);
1021        exec_output += PredOpExecute.subst(iop);
1022
1023    code = '''
1024        FPSCR fpscr = (FPSCR) FpscrExc;
1025        vfpFlushToZero(fpscr, FpOp1);
1026        VfpSavedState state = prepFpState(fpscr.rMode);
1027        fesetround(FeRoundZero);
1028        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1029        FpDest_uw = vfpFpToFixed<float>(
1030            FpOp1, false, 32, 0, true, {round_mode});
1031        __asm__ __volatile__("" :: "m" (FpDest_uw));
1032        finishVfp(fpscr, state, fpscr.fz);
1033        FpscrExc = fpscr;
1034    '''
1035    for round_mode_suffix in round_mode_suffix_to_mode:
1036        buildVcvt(code, "Vcvt{}FpUIntS", round_mode_suffix)
1037
1038    code = '''
1039        FPSCR fpscr = (FPSCR) FpscrExc;
1040        double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1041        vfpFlushToZero(fpscr, cOp1);
1042        VfpSavedState state = prepFpState(fpscr.rMode);
1043        fesetround(FeRoundZero);
1044        __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1045        uint64_t result = vfpFpToFixed<double>(
1046            cOp1, false, 32, 0, true, {round_mode});
1047        __asm__ __volatile__("" :: "m" (result));
1048        finishVfp(fpscr, state, fpscr.fz);
1049        FpDestP0_uw = result;
1050        FpscrExc = fpscr;
1051    '''
1052    for round_mode_suffix in round_mode_suffix_to_mode:
1053        buildVcvt(code, "Vcvt{}FpUIntD", round_mode_suffix)
1054
1055    code = '''
1056        FPSCR fpscr = (FPSCR) FpscrExc;
1057        vfpFlushToZero(fpscr, FpOp1);
1058        VfpSavedState state = prepFpState(fpscr.rMode);
1059        fesetround(FeRoundZero);
1060        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1061        FpDest_sw = vfpFpToFixed<float>(
1062            FpOp1, true, 32, 0, true, {round_mode});
1063        __asm__ __volatile__("" :: "m" (FpDest_sw));
1064        finishVfp(fpscr, state, fpscr.fz);
1065        FpscrExc = fpscr;
1066    '''
1067    for round_mode_suffix in round_mode_suffix_to_mode:
1068        buildVcvt(code, "Vcvt{}FpSIntS", round_mode_suffix)
1069
1070    code = '''
1071        FPSCR fpscr = (FPSCR) FpscrExc;
1072        double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1073        vfpFlushToZero(fpscr, cOp1);
1074        VfpSavedState state = prepFpState(fpscr.rMode);
1075        fesetround(FeRoundZero);
1076        __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1077        int64_t result = vfpFpToFixed<double>(
1078            cOp1, true, 32, 0, true, {round_mode});
1079        __asm__ __volatile__("" :: "m" (result));
1080        finishVfp(fpscr, state, fpscr.fz);
1081        FpDestP0_uw = result;
1082        FpscrExc = fpscr;
1083    '''
1084    for round_mode_suffix in round_mode_suffix_to_mode:
1085        buildVcvt(code, "Vcvt{}FpSIntD", round_mode_suffix)
1086
1087    vcvtFpSFpDCode = vfpEnabledCheckCode + '''
1088        FPSCR fpscr = (FPSCR) FpscrExc;
1089        vfpFlushToZero(fpscr, FpOp1);
1090        VfpSavedState state = prepFpState(fpscr.rMode);
1091        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1092        double cDest = fixFpSFpDDest(FpscrExc, FpOp1);
1093        __asm__ __volatile__("" :: "m" (cDest));
1094        finishVfp(fpscr, state, fpscr.fz);
1095        FpDestP0_uw = dblLow(cDest);
1096        FpDestP1_uw = dblHi(cDest);
1097        FpscrExc = fpscr;
1098    '''
1099    vcvtFpSFpDIop = InstObjParams("vcvt", "VcvtFpSFpD", "FpRegRegOp",
1100                                     { "code": vcvtFpSFpDCode,
1101                                       "predicate_test": predicateTest,
1102                                       "op_class": "SimdFloatCvtOp" }, [])
1103    header_output += FpRegRegOpDeclare.subst(vcvtFpSFpDIop);
1104    decoder_output += FpRegRegOpConstructor.subst(vcvtFpSFpDIop);
1105    exec_output += PredOpExecute.subst(vcvtFpSFpDIop);
1106
1107    vcvtFpDFpSCode = vfpEnabledCheckCode + '''
1108        FPSCR fpscr = (FPSCR) FpscrExc;
1109        double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1110        vfpFlushToZero(fpscr, cOp1);
1111        VfpSavedState state = prepFpState(fpscr.rMode);
1112        __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1113        FpDest = fixFpDFpSDest(FpscrExc, cOp1);
1114        __asm__ __volatile__("" :: "m" (FpDest));
1115        finishVfp(fpscr, state, fpscr.fz);
1116        FpscrExc = fpscr;
1117    '''
1118    vcvtFpDFpSIop = InstObjParams("vcvt", "VcvtFpDFpS", "FpRegRegOp",
1119                                     { "code": vcvtFpDFpSCode,
1120                                       "predicate_test": predicateTest,
1121                                       "op_class": "SimdFloatCvtOp" }, [])
1122    header_output += FpRegRegOpDeclare.subst(vcvtFpDFpSIop);
1123    decoder_output += FpRegRegOpConstructor.subst(vcvtFpDFpSIop);
1124    exec_output += PredOpExecute.subst(vcvtFpDFpSIop);
1125
1126    vcvtFpHTFpSCode = vfpEnabledCheckCode + '''
1127        FPSCR fpscr = (FPSCR) FpscrExc;
1128        vfpFlushToZero(fpscr, FpOp1);
1129        VfpSavedState state = prepFpState(fpscr.rMode);
1130        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1131        FpDest = vcvtFpHFpS(fpscr, fpscr.dn, fpscr.ahp,
1132                            bits(fpToBits(FpOp1), 31, 16));
1133        __asm__ __volatile__("" :: "m" (FpDest));
1134        finishVfp(fpscr, state, fpscr.fz);
1135        FpscrExc = fpscr;
1136    '''
1137    vcvtFpHTFpSIop = InstObjParams("vcvtt", "VcvtFpHTFpS", "FpRegRegOp",
1138                                   { "code": vcvtFpHTFpSCode,
1139                                     "predicate_test": predicateTest,
1140                                     "op_class": "SimdFloatCvtOp" }, [])
1141    header_output += FpRegRegOpDeclare.subst(vcvtFpHTFpSIop);
1142    decoder_output += FpRegRegOpConstructor.subst(vcvtFpHTFpSIop);
1143    exec_output += PredOpExecute.subst(vcvtFpHTFpSIop);
1144
1145    vcvtFpHBFpSCode = vfpEnabledCheckCode + '''
1146        FPSCR fpscr = (FPSCR) FpscrExc;
1147        VfpSavedState state = prepFpState(fpscr.rMode);
1148        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1149        FpDest = vcvtFpHFpS(fpscr, fpscr.dn, fpscr.ahp,
1150                            bits(fpToBits(FpOp1), 15, 0));
1151        __asm__ __volatile__("" :: "m" (FpDest));
1152        finishVfp(fpscr, state, fpscr.fz);
1153        FpscrExc = fpscr;
1154    '''
1155    vcvtFpHBFpSIop = InstObjParams("vcvtb", "VcvtFpHBFpS", "FpRegRegOp",
1156                                   { "code": vcvtFpHBFpSCode,
1157                                     "predicate_test": predicateTest,
1158                                     "op_class": "SimdFloatCvtOp" }, [])
1159    header_output += FpRegRegOpDeclare.subst(vcvtFpHBFpSIop);
1160    decoder_output += FpRegRegOpConstructor.subst(vcvtFpHBFpSIop);
1161    exec_output += PredOpExecute.subst(vcvtFpHBFpSIop);
1162
1163    vcvtFpSFpHTCode = vfpEnabledCheckCode + '''
1164        FPSCR fpscr = (FPSCR) FpscrExc;
1165        vfpFlushToZero(fpscr, FpOp1);
1166        VfpSavedState state = prepFpState(fpscr.rMode);
1167        __asm__ __volatile__("" : "=m" (FpOp1), "=m" (FpDest_uw)
1168                                : "m" (FpOp1), "m" (FpDest_uw));
1169        FpDest_uw = insertBits(FpDest_uw, 31, 16,,
1170                               vcvtFpSFpH(fpscr, fpscr.fz, fpscr.dn,
1171                               fpscr.rMode, fpscr.ahp, FpOp1));
1172        __asm__ __volatile__("" :: "m" (FpDest_uw));
1173        finishVfp(fpscr, state, fpscr.fz);
1174        FpscrExc = fpscr;
1175    '''
1176    vcvtFpSFpHTIop = InstObjParams("vcvtt", "VcvtFpSFpHT", "FpRegRegOp",
1177                                    { "code": vcvtFpHTFpSCode,
1178                                      "predicate_test": predicateTest,
1179                                      "op_class": "SimdFloatCvtOp" }, [])
1180    header_output += FpRegRegOpDeclare.subst(vcvtFpSFpHTIop);
1181    decoder_output += FpRegRegOpConstructor.subst(vcvtFpSFpHTIop);
1182    exec_output += PredOpExecute.subst(vcvtFpSFpHTIop);
1183
1184    vcvtFpSFpHBCode = vfpEnabledCheckCode + '''
1185        FPSCR fpscr = (FPSCR) FpscrExc;
1186        vfpFlushToZero(fpscr, FpOp1);
1187        VfpSavedState state = prepFpState(fpscr.rMode);
1188        __asm__ __volatile__("" : "=m" (FpOp1), "=m" (FpDest_uw)
1189                                : "m" (FpOp1), "m" (FpDest_uw));
1190        FpDest_uw = insertBits(FpDest_uw, 15, 0,
1191                               vcvtFpSFpH(fpscr, fpscr.fz, fpscr.dn,
1192                               fpscr.rMode, fpscr.ahp, FpOp1));
1193        __asm__ __volatile__("" :: "m" (FpDest_uw));
1194        finishVfp(fpscr, state, fpscr.fz);
1195        FpscrExc = fpscr;
1196    '''
1197    vcvtFpSFpHBIop = InstObjParams("vcvtb", "VcvtFpSFpHB", "FpRegRegOp",
1198                                   { "code": vcvtFpSFpHBCode,
1199                                     "predicate_test": predicateTest,
1200                                     "op_class": "SimdFloatCvtOp" }, [])
1201    header_output += FpRegRegOpDeclare.subst(vcvtFpSFpHBIop);
1202    decoder_output += FpRegRegOpConstructor.subst(vcvtFpSFpHBIop);
1203    exec_output += PredOpExecute.subst(vcvtFpSFpHBIop);
1204
1205    vcmpSCode = vfpEnabledCheckCode + '''
1206        FPSCR fpscr = (FPSCR) FpscrExc;
1207        vfpFlushToZero(fpscr, FpDest, FpOp1);
1208        if (FpDest == FpOp1) {
1209            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1210        } else if (FpDest < FpOp1) {
1211            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1212        } else if (FpDest > FpOp1) {
1213            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1214        } else {
1215            const uint32_t qnan = 0x7fc00000;
1216            const bool nan1 = std::isnan(FpDest);
1217            const bool signal1 = nan1 && ((fpToBits(FpDest) & qnan) != qnan);
1218            const bool nan2 = std::isnan(FpOp1);
1219            const bool signal2 = nan2 && ((fpToBits(FpOp1) & qnan) != qnan);
1220            if (signal1 || signal2)
1221                fpscr.ioc = 1;
1222            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1223        }
1224        FpCondCodes = fpscr & FpCondCodesMask;
1225        FpscrExc = fpscr;
1226    '''
1227    vcmpSIop = InstObjParams("vcmps", "VcmpS", "FpRegRegOp",
1228                                     { "code": vcmpSCode,
1229                                       "predicate_test": predicateTest,
1230                                       "op_class": "SimdFloatCmpOp" }, [])
1231    header_output += FpRegRegOpDeclare.subst(vcmpSIop);
1232    decoder_output += FpRegRegOpConstructor.subst(vcmpSIop);
1233    exec_output += PredOpExecute.subst(vcmpSIop);
1234
1235    vcmpDCode = vfpEnabledCheckCode + '''
1236        double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1237        double cDest = dbl(FpDestP0_uw, FpDestP1_uw);
1238        FPSCR fpscr = (FPSCR) FpscrExc;
1239        vfpFlushToZero(fpscr, cDest, cOp1);
1240        if (cDest == cOp1) {
1241            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1242        } else if (cDest < cOp1) {
1243            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1244        } else if (cDest > cOp1) {
1245            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1246        } else {
1247            const uint64_t qnan = ULL(0x7ff8000000000000);
1248            const bool nan1 = std::isnan(cDest);
1249            const bool signal1 = nan1 && ((fpToBits(cDest) & qnan) != qnan);
1250            const bool nan2 = std::isnan(cOp1);
1251            const bool signal2 = nan2 && ((fpToBits(cOp1) & qnan) != qnan);
1252            if (signal1 || signal2)
1253                fpscr.ioc = 1;
1254            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1255        }
1256        FpCondCodes = fpscr & FpCondCodesMask;
1257        FpscrExc = fpscr;
1258    '''
1259    vcmpDIop = InstObjParams("vcmpd", "VcmpD", "FpRegRegOp",
1260                                     { "code": vcmpDCode,
1261                                       "predicate_test": predicateTest,
1262                                       "op_class": "SimdFloatCmpOp" }, [])
1263    header_output += FpRegRegOpDeclare.subst(vcmpDIop);
1264    decoder_output += FpRegRegOpConstructor.subst(vcmpDIop);
1265    exec_output += PredOpExecute.subst(vcmpDIop);
1266
1267    vcmpZeroSCode = vfpEnabledCheckCode + '''
1268        FPSCR fpscr = (FPSCR) FpscrExc;
1269        vfpFlushToZero(fpscr, FpDest);
1270        // This only handles imm == 0 for now.
1271        assert(imm == 0);
1272        if (FpDest == imm) {
1273            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1274        } else if (FpDest < imm) {
1275            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1276        } else if (FpDest > imm) {
1277            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1278        } else {
1279            const uint32_t qnan = 0x7fc00000;
1280            const bool nan = std::isnan(FpDest);
1281            const bool signal = nan && ((fpToBits(FpDest) & qnan) != qnan);
1282            if (signal)
1283                fpscr.ioc = 1;
1284            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1285        }
1286        FpCondCodes = fpscr & FpCondCodesMask;
1287        FpscrExc = fpscr;
1288    '''
1289    vcmpZeroSIop = InstObjParams("vcmpZeros", "VcmpZeroS", "FpRegImmOp",
1290                                     { "code": vcmpZeroSCode,
1291                                       "predicate_test": predicateTest,
1292                                       "op_class": "SimdFloatCmpOp" }, [])
1293    header_output += FpRegImmOpDeclare.subst(vcmpZeroSIop);
1294    decoder_output += FpRegImmOpConstructor.subst(vcmpZeroSIop);
1295    exec_output += PredOpExecute.subst(vcmpZeroSIop);
1296
1297    vcmpZeroDCode = vfpEnabledCheckCode + '''
1298        // This only handles imm == 0 for now.
1299        assert(imm == 0);
1300        double cDest = dbl(FpDestP0_uw, FpDestP1_uw);
1301        FPSCR fpscr = (FPSCR) FpscrExc;
1302        vfpFlushToZero(fpscr, cDest);
1303        if (cDest == imm) {
1304            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1305        } else if (cDest < imm) {
1306            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1307        } else if (cDest > imm) {
1308            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1309        } else {
1310            const uint64_t qnan = ULL(0x7ff8000000000000);
1311            const bool nan = std::isnan(cDest);
1312            const bool signal = nan && ((fpToBits(cDest) & qnan) != qnan);
1313            if (signal)
1314                fpscr.ioc = 1;
1315            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1316        }
1317        FpCondCodes = fpscr & FpCondCodesMask;
1318        FpscrExc = fpscr;
1319    '''
1320    vcmpZeroDIop = InstObjParams("vcmpZerod", "VcmpZeroD", "FpRegImmOp",
1321                                     { "code": vcmpZeroDCode,
1322                                       "predicate_test": predicateTest,
1323                                       "op_class": "SimdFloatCmpOp" }, [])
1324    header_output += FpRegImmOpDeclare.subst(vcmpZeroDIop);
1325    decoder_output += FpRegImmOpConstructor.subst(vcmpZeroDIop);
1326    exec_output += PredOpExecute.subst(vcmpZeroDIop);
1327
1328    vcmpeSCode = vfpEnabledCheckCode + '''
1329        FPSCR fpscr = (FPSCR) FpscrExc;
1330        vfpFlushToZero(fpscr, FpDest, FpOp1);
1331        if (FpDest == FpOp1) {
1332            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1333        } else if (FpDest < FpOp1) {
1334            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1335        } else if (FpDest > FpOp1) {
1336            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1337        } else {
1338            fpscr.ioc = 1;
1339            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1340        }
1341        FpCondCodes = fpscr & FpCondCodesMask;
1342        FpscrExc = fpscr;
1343    '''
1344    vcmpeSIop = InstObjParams("vcmpes", "VcmpeS", "FpRegRegOp",
1345                                     { "code": vcmpeSCode,
1346                                       "predicate_test": predicateTest,
1347                                       "op_class": "SimdFloatCmpOp" }, [])
1348    header_output += FpRegRegOpDeclare.subst(vcmpeSIop);
1349    decoder_output += FpRegRegOpConstructor.subst(vcmpeSIop);
1350    exec_output += PredOpExecute.subst(vcmpeSIop);
1351
1352    vcmpeDCode = vfpEnabledCheckCode + '''
1353        double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1354        double cDest = dbl(FpDestP0_uw, FpDestP1_uw);
1355        FPSCR fpscr = (FPSCR) FpscrExc;
1356        vfpFlushToZero(fpscr, cDest, cOp1);
1357        if (cDest == cOp1) {
1358            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1359        } else if (cDest < cOp1) {
1360            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1361        } else if (cDest > cOp1) {
1362            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1363        } else {
1364            fpscr.ioc = 1;
1365            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1366        }
1367        FpCondCodes = fpscr & FpCondCodesMask;
1368        FpscrExc = fpscr;
1369    '''
1370    vcmpeDIop = InstObjParams("vcmped", "VcmpeD", "FpRegRegOp",
1371                                     { "code": vcmpeDCode,
1372                                       "predicate_test": predicateTest,
1373                                       "op_class": "SimdFloatCmpOp" }, [])
1374    header_output += FpRegRegOpDeclare.subst(vcmpeDIop);
1375    decoder_output += FpRegRegOpConstructor.subst(vcmpeDIop);
1376    exec_output += PredOpExecute.subst(vcmpeDIop);
1377
1378    vcmpeZeroSCode = vfpEnabledCheckCode + '''
1379        FPSCR fpscr = (FPSCR) FpscrExc;
1380        vfpFlushToZero(fpscr, FpDest);
1381        if (FpDest == imm) {
1382            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1383        } else if (FpDest < imm) {
1384            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1385        } else if (FpDest > imm) {
1386            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1387        } else {
1388            fpscr.ioc = 1;
1389            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1390        }
1391        FpCondCodes = fpscr & FpCondCodesMask;
1392        FpscrExc = fpscr;
1393    '''
1394    vcmpeZeroSIop = InstObjParams("vcmpeZeros", "VcmpeZeroS", "FpRegImmOp",
1395                                     { "code": vcmpeZeroSCode,
1396                                       "predicate_test": predicateTest,
1397                                       "op_class": "SimdFloatCmpOp" }, [])
1398    header_output += FpRegImmOpDeclare.subst(vcmpeZeroSIop);
1399    decoder_output += FpRegImmOpConstructor.subst(vcmpeZeroSIop);
1400    exec_output += PredOpExecute.subst(vcmpeZeroSIop);
1401
1402    vcmpeZeroDCode = vfpEnabledCheckCode + '''
1403        double cDest = dbl(FpDestP0_uw, FpDestP1_uw);
1404        FPSCR fpscr = (FPSCR) FpscrExc;
1405        vfpFlushToZero(fpscr, cDest);
1406        if (cDest == imm) {
1407            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1408        } else if (cDest < imm) {
1409            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1410        } else if (cDest > imm) {
1411            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1412        } else {
1413            fpscr.ioc = 1;
1414            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1415        }
1416        FpCondCodes = fpscr & FpCondCodesMask;
1417        FpscrExc = fpscr;
1418    '''
1419    vcmpeZeroDIop = InstObjParams("vcmpeZerod", "VcmpeZeroD", "FpRegImmOp",
1420                                     { "code": vcmpeZeroDCode,
1421                                       "predicate_test": predicateTest,
1422                                       "op_class": "SimdFloatCmpOp" }, [])
1423    header_output += FpRegImmOpDeclare.subst(vcmpeZeroDIop);
1424    decoder_output += FpRegImmOpConstructor.subst(vcmpeZeroDIop);
1425    exec_output += PredOpExecute.subst(vcmpeZeroDIop);
1426}};
1427
1428let {{
1429
1430    header_output = ""
1431    decoder_output = ""
1432    exec_output = ""
1433
1434    vselSCode = vfpEnabledCheckCode + '''
1435        if (testPredicate(CondCodesNZ, CondCodesC, CondCodesV, cond)) {
1436            FpDest = FpOp1;
1437        } else {
1438            FpDest = FpOp2;
1439        } '''
1440
1441    vselSIop = InstObjParams("vsels", "VselS", "FpRegRegRegCondOp",
1442                             { "code" : vselSCode,
1443                               "predicate_test" : predicateTest,
1444                               "op_class" : "SimdFloatCmpOp" }, [] )
1445    header_output += FpRegRegRegCondOpDeclare.subst(vselSIop);
1446    decoder_output += FpRegRegRegCondOpConstructor.subst(vselSIop);
1447    exec_output +=  PredOpExecute.subst(vselSIop);
1448
1449    vselDCode = vfpEnabledCheckCode + '''
1450        if (testPredicate(CondCodesNZ, CondCodesC, CondCodesV, cond)) {
1451            FpDestP0_uw = FpOp1P0_uw;
1452            FpDestP1_uw = FpOp1P1_uw;
1453        } else {
1454            FpDestP0_uw = FpOp2P0_uw;
1455            FpDestP1_uw = FpOp2P1_uw;
1456        } '''
1457
1458    vselDIop = InstObjParams("vseld", "VselD", "FpRegRegRegCondOp",
1459                             { "code" : vselDCode,
1460                               "predicate_test" : predicateTest,
1461                               "op_class" : "SimdFloatCmpOp" }, [] )
1462    header_output += FpRegRegRegCondOpDeclare.subst(vselDIop);
1463    decoder_output += FpRegRegRegCondOpConstructor.subst(vselDIop);
1464    exec_output +=  PredOpExecute.subst(vselDIop);
1465}};
1466
1467
1468let {{
1469
1470    header_output = ""
1471    decoder_output = ""
1472    exec_output = ""
1473
1474    vcvtFpSFixedSCode = vfpEnabledCheckCode + '''
1475        FPSCR fpscr = (FPSCR) FpscrExc;
1476        vfpFlushToZero(fpscr, FpOp1);
1477        VfpSavedState state = prepFpState(fpscr.rMode);
1478        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1479        FpDest_sw = vfpFpToFixed<float>(FpOp1, true, 32, imm);
1480        __asm__ __volatile__("" :: "m" (FpDest_sw));
1481        finishVfp(fpscr, state, fpscr.fz);
1482        FpscrExc = fpscr;
1483    '''
1484    vcvtFpSFixedSIop = InstObjParams("vcvt", "VcvtFpSFixedS", "FpRegRegImmOp",
1485                                     { "code": vcvtFpSFixedSCode,
1486                                       "predicate_test": predicateTest,
1487                                       "op_class": "SimdFloatCvtOp" }, [])
1488    header_output += FpRegRegImmOpDeclare.subst(vcvtFpSFixedSIop);
1489    decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSFixedSIop);
1490    exec_output += PredOpExecute.subst(vcvtFpSFixedSIop);
1491
1492    vcvtFpSFixedDCode = vfpEnabledCheckCode + '''
1493        FPSCR fpscr = (FPSCR) FpscrExc;
1494        double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1495        vfpFlushToZero(fpscr, cOp1);
1496        VfpSavedState state = prepFpState(fpscr.rMode);
1497        __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1498        uint64_t mid = vfpFpToFixed<double>(cOp1, true, 32, imm);
1499        __asm__ __volatile__("" :: "m" (mid));
1500        finishVfp(fpscr, state, fpscr.fz);
1501        FpDestP0_uw = mid;
1502        FpDestP1_uw = mid >> 32;
1503        FpscrExc = fpscr;
1504    '''
1505    vcvtFpSFixedDIop = InstObjParams("vcvt", "VcvtFpSFixedD", "FpRegRegImmOp",
1506                                     { "code": vcvtFpSFixedDCode,
1507                                       "predicate_test": predicateTest,
1508                                       "op_class": "SimdFloatCvtOp" }, [])
1509    header_output += FpRegRegImmOpDeclare.subst(vcvtFpSFixedDIop);
1510    decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSFixedDIop);
1511    exec_output += PredOpExecute.subst(vcvtFpSFixedDIop);
1512
1513    vcvtFpUFixedSCode = vfpEnabledCheckCode + '''
1514        FPSCR fpscr = (FPSCR) FpscrExc;
1515        vfpFlushToZero(fpscr, FpOp1);
1516        VfpSavedState state = prepFpState(fpscr.rMode);
1517        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1518        FpDest_uw = vfpFpToFixed<float>(FpOp1, false, 32, imm);
1519        __asm__ __volatile__("" :: "m" (FpDest_uw));
1520        finishVfp(fpscr, state, fpscr.fz);
1521        FpscrExc = fpscr;
1522    '''
1523    vcvtFpUFixedSIop = InstObjParams("vcvt", "VcvtFpUFixedS", "FpRegRegImmOp",
1524                                     { "code": vcvtFpUFixedSCode,
1525                                       "predicate_test": predicateTest,
1526                                       "op_class": "SimdFloatCvtOp" }, [])
1527    header_output += FpRegRegImmOpDeclare.subst(vcvtFpUFixedSIop);
1528    decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUFixedSIop);
1529    exec_output += PredOpExecute.subst(vcvtFpUFixedSIop);
1530
1531    vcvtFpUFixedDCode = vfpEnabledCheckCode + '''
1532        FPSCR fpscr = (FPSCR) FpscrExc;
1533        double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1534        vfpFlushToZero(fpscr, cOp1);
1535        VfpSavedState state = prepFpState(fpscr.rMode);
1536        __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1537        uint64_t mid = vfpFpToFixed<double>(cOp1, false, 32, imm);
1538        __asm__ __volatile__("" :: "m" (mid));
1539        finishVfp(fpscr, state, fpscr.fz);
1540        FpDestP0_uw = mid;
1541        FpDestP1_uw = mid >> 32;
1542        FpscrExc = fpscr;
1543    '''
1544    vcvtFpUFixedDIop = InstObjParams("vcvt", "VcvtFpUFixedD", "FpRegRegImmOp",
1545                                     { "code": vcvtFpUFixedDCode,
1546                                       "predicate_test": predicateTest,
1547                                       "op_class": "SimdFloatCvtOp" }, [])
1548    header_output += FpRegRegImmOpDeclare.subst(vcvtFpUFixedDIop);
1549    decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUFixedDIop);
1550    exec_output += PredOpExecute.subst(vcvtFpUFixedDIop);
1551
1552    vcvtSFixedFpSCode = vfpEnabledCheckCode + '''
1553        FPSCR fpscr = (FPSCR) FpscrExc;
1554        VfpSavedState state = prepFpState(fpscr.rMode);
1555        __asm__ __volatile__("" : "=m" (FpOp1_sw) : "m" (FpOp1_sw));
1556        FpDest = vfpSFixedToFpS(fpscr.fz, fpscr.dn, FpOp1_sw, 32, imm);
1557        __asm__ __volatile__("" :: "m" (FpDest));
1558        finishVfp(fpscr, state, fpscr.fz);
1559        FpscrExc = fpscr;
1560    '''
1561    vcvtSFixedFpSIop = InstObjParams("vcvt", "VcvtSFixedFpS", "FpRegRegImmOp",
1562                                     { "code": vcvtSFixedFpSCode,
1563                                       "predicate_test": predicateTest,
1564                                       "op_class": "SimdFloatCvtOp" }, [])
1565    header_output += FpRegRegImmOpDeclare.subst(vcvtSFixedFpSIop);
1566    decoder_output += FpRegRegImmOpConstructor.subst(vcvtSFixedFpSIop);
1567    exec_output += PredOpExecute.subst(vcvtSFixedFpSIop);
1568
1569    vcvtSFixedFpDCode = vfpEnabledCheckCode + '''
1570        FPSCR fpscr = (FPSCR) FpscrExc;
1571        uint64_t mid = ((uint64_t)FpOp1P0_uw | ((uint64_t)FpOp1P1_uw << 32));
1572        VfpSavedState state = prepFpState(fpscr.rMode);
1573        __asm__ __volatile__("" : "=m" (mid) : "m" (mid));
1574        double cDest = vfpSFixedToFpD(fpscr.fz, fpscr.dn, mid, 32, imm);
1575        __asm__ __volatile__("" :: "m" (cDest));
1576        finishVfp(fpscr, state, fpscr.fz);
1577        FpDestP0_uw = dblLow(cDest);
1578        FpDestP1_uw = dblHi(cDest);
1579        FpscrExc = fpscr;
1580    '''
1581    vcvtSFixedFpDIop = InstObjParams("vcvt", "VcvtSFixedFpD", "FpRegRegImmOp",
1582                                     { "code": vcvtSFixedFpDCode,
1583                                       "predicate_test": predicateTest,
1584                                       "op_class": "SimdFloatCvtOp" }, [])
1585    header_output += FpRegRegImmOpDeclare.subst(vcvtSFixedFpDIop);
1586    decoder_output += FpRegRegImmOpConstructor.subst(vcvtSFixedFpDIop);
1587    exec_output += PredOpExecute.subst(vcvtSFixedFpDIop);
1588
1589    vcvtUFixedFpSCode = vfpEnabledCheckCode + '''
1590        FPSCR fpscr = (FPSCR) FpscrExc;
1591        VfpSavedState state = prepFpState(fpscr.rMode);
1592        __asm__ __volatile__("" : "=m" (FpOp1_uw) : "m" (FpOp1_uw));
1593        FpDest = vfpUFixedToFpS(fpscr.fz, fpscr.dn, FpOp1_uw, 32, imm);
1594        __asm__ __volatile__("" :: "m" (FpDest));
1595        finishVfp(fpscr, state, fpscr.fz);
1596        FpscrExc = fpscr;
1597    '''
1598    vcvtUFixedFpSIop = InstObjParams("vcvt", "VcvtUFixedFpS", "FpRegRegImmOp",
1599                                     { "code": vcvtUFixedFpSCode,
1600                                       "predicate_test": predicateTest,
1601                                       "op_class": "SimdFloatCvtOp" }, [])
1602    header_output += FpRegRegImmOpDeclare.subst(vcvtUFixedFpSIop);
1603    decoder_output += FpRegRegImmOpConstructor.subst(vcvtUFixedFpSIop);
1604    exec_output += PredOpExecute.subst(vcvtUFixedFpSIop);
1605
1606    vcvtUFixedFpDCode = vfpEnabledCheckCode + '''
1607        FPSCR fpscr = (FPSCR) FpscrExc;
1608        uint64_t mid = ((uint64_t)FpOp1P0_uw | ((uint64_t)FpOp1P1_uw << 32));
1609        VfpSavedState state = prepFpState(fpscr.rMode);
1610        __asm__ __volatile__("" : "=m" (mid) : "m" (mid));
1611        double cDest = vfpUFixedToFpD(fpscr.fz, fpscr.dn, mid, 32, imm);
1612        __asm__ __volatile__("" :: "m" (cDest));
1613        finishVfp(fpscr, state, fpscr.fz);
1614        FpDestP0_uw = dblLow(cDest);
1615        FpDestP1_uw = dblHi(cDest);
1616        FpscrExc = fpscr;
1617    '''
1618    vcvtUFixedFpDIop = InstObjParams("vcvt", "VcvtUFixedFpD", "FpRegRegImmOp",
1619                                     { "code": vcvtUFixedFpDCode,
1620                                       "predicate_test": predicateTest,
1621                                       "op_class": "SimdFloatCvtOp" }, [])
1622    header_output += FpRegRegImmOpDeclare.subst(vcvtUFixedFpDIop);
1623    decoder_output += FpRegRegImmOpConstructor.subst(vcvtUFixedFpDIop);
1624    exec_output += PredOpExecute.subst(vcvtUFixedFpDIop);
1625
1626    vcvtFpSHFixedSCode = vfpEnabledCheckCode + '''
1627        FPSCR fpscr = (FPSCR) FpscrExc;
1628        vfpFlushToZero(fpscr, FpOp1);
1629        VfpSavedState state = prepFpState(fpscr.rMode);
1630        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1631        FpDest_sh = vfpFpToFixed<float>(FpOp1, true, 16, imm);
1632        __asm__ __volatile__("" :: "m" (FpDest_sh));
1633        finishVfp(fpscr, state, fpscr.fz);
1634        FpscrExc = fpscr;
1635    '''
1636    vcvtFpSHFixedSIop = InstObjParams("vcvt", "VcvtFpSHFixedS",
1637                                      "FpRegRegImmOp",
1638                                     { "code": vcvtFpSHFixedSCode,
1639                                       "predicate_test": predicateTest,
1640                                       "op_class": "SimdFloatCvtOp" }, [])
1641    header_output += FpRegRegImmOpDeclare.subst(vcvtFpSHFixedSIop);
1642    decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSHFixedSIop);
1643    exec_output += PredOpExecute.subst(vcvtFpSHFixedSIop);
1644
1645    vcvtFpSHFixedDCode = vfpEnabledCheckCode + '''
1646        FPSCR fpscr = (FPSCR) FpscrExc;
1647        double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1648        vfpFlushToZero(fpscr, cOp1);
1649        VfpSavedState state = prepFpState(fpscr.rMode);
1650        __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1651        uint64_t result = vfpFpToFixed<double>(cOp1, true, 16, imm);
1652        __asm__ __volatile__("" :: "m" (result));
1653        finishVfp(fpscr, state, fpscr.fz);
1654        FpDestP0_uw = result;
1655        FpDestP1_uw = result >> 32;
1656        FpscrExc = fpscr;
1657    '''
1658    vcvtFpSHFixedDIop = InstObjParams("vcvt", "VcvtFpSHFixedD",
1659                                      "FpRegRegImmOp",
1660                                     { "code": vcvtFpSHFixedDCode,
1661                                       "predicate_test": predicateTest,
1662                                       "op_class": "SimdFloatCvtOp" }, [])
1663    header_output += FpRegRegImmOpDeclare.subst(vcvtFpSHFixedDIop);
1664    decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSHFixedDIop);
1665    exec_output += PredOpExecute.subst(vcvtFpSHFixedDIop);
1666
1667    vcvtFpUHFixedSCode = vfpEnabledCheckCode + '''
1668        FPSCR fpscr = (FPSCR) FpscrExc;
1669        vfpFlushToZero(fpscr, FpOp1);
1670        VfpSavedState state = prepFpState(fpscr.rMode);
1671        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1672        FpDest_uh = vfpFpToFixed<float>(FpOp1, false, 16, imm);
1673        __asm__ __volatile__("" :: "m" (FpDest_uh));
1674        finishVfp(fpscr, state, fpscr.fz);
1675        FpscrExc = fpscr;
1676    '''
1677    vcvtFpUHFixedSIop = InstObjParams("vcvt", "VcvtFpUHFixedS",
1678                                      "FpRegRegImmOp",
1679                                     { "code": vcvtFpUHFixedSCode,
1680                                       "predicate_test": predicateTest,
1681                                       "op_class": "SimdFloatCvtOp" }, [])
1682    header_output += FpRegRegImmOpDeclare.subst(vcvtFpUHFixedSIop);
1683    decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUHFixedSIop);
1684    exec_output += PredOpExecute.subst(vcvtFpUHFixedSIop);
1685
1686    vcvtFpUHFixedDCode = vfpEnabledCheckCode + '''
1687        FPSCR fpscr = (FPSCR) FpscrExc;
1688        double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw);
1689        vfpFlushToZero(fpscr, cOp1);
1690        VfpSavedState state = prepFpState(fpscr.rMode);
1691        __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1));
1692        uint64_t mid = vfpFpToFixed<double>(cOp1, false, 16, imm);
1693        __asm__ __volatile__("" :: "m" (mid));
1694        finishVfp(fpscr, state, fpscr.fz);
1695        FpDestP0_uw = mid;
1696        FpDestP1_uw = mid >> 32;
1697        FpscrExc = fpscr;
1698    '''
1699    vcvtFpUHFixedDIop = InstObjParams("vcvt", "VcvtFpUHFixedD",
1700                                      "FpRegRegImmOp",
1701                                     { "code": vcvtFpUHFixedDCode,
1702                                       "predicate_test": predicateTest,
1703                                       "op_class": "SimdFloatCvtOp" }, [])
1704    header_output += FpRegRegImmOpDeclare.subst(vcvtFpUHFixedDIop);
1705    decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUHFixedDIop);
1706    exec_output += PredOpExecute.subst(vcvtFpUHFixedDIop);
1707
1708    vcvtSHFixedFpSCode = vfpEnabledCheckCode + '''
1709        FPSCR fpscr = (FPSCR) FpscrExc;
1710        VfpSavedState state = prepFpState(fpscr.rMode);
1711        __asm__ __volatile__("" : "=m" (FpOp1_sh) : "m" (FpOp1_sh));
1712        FpDest = vfpSFixedToFpS(fpscr.fz, fpscr.dn, FpOp1_sh, 16, imm);
1713        __asm__ __volatile__("" :: "m" (FpDest));
1714        finishVfp(fpscr, state, fpscr.fz);
1715        FpscrExc = fpscr;
1716    '''
1717    vcvtSHFixedFpSIop = InstObjParams("vcvt", "VcvtSHFixedFpS",
1718                                      "FpRegRegImmOp",
1719                                     { "code": vcvtSHFixedFpSCode,
1720                                       "predicate_test": predicateTest,
1721                                       "op_class": "SimdFloatCvtOp" }, [])
1722    header_output += FpRegRegImmOpDeclare.subst(vcvtSHFixedFpSIop);
1723    decoder_output += FpRegRegImmOpConstructor.subst(vcvtSHFixedFpSIop);
1724    exec_output += PredOpExecute.subst(vcvtSHFixedFpSIop);
1725
1726    vcvtSHFixedFpDCode = vfpEnabledCheckCode + '''
1727        FPSCR fpscr = (FPSCR) FpscrExc;
1728        uint64_t mid = ((uint64_t)FpOp1P0_uw | ((uint64_t)FpOp1P1_uw << 32));
1729        VfpSavedState state = prepFpState(fpscr.rMode);
1730        __asm__ __volatile__("" : "=m" (mid) : "m" (mid));
1731        double cDest = vfpSFixedToFpD(fpscr.fz, fpscr.dn, mid, 16, imm);
1732        __asm__ __volatile__("" :: "m" (cDest));
1733        finishVfp(fpscr, state, fpscr.fz);
1734        FpDestP0_uw = dblLow(cDest);
1735        FpDestP1_uw = dblHi(cDest);
1736        FpscrExc = fpscr;
1737    '''
1738    vcvtSHFixedFpDIop = InstObjParams("vcvt", "VcvtSHFixedFpD",
1739                                      "FpRegRegImmOp",
1740                                     { "code": vcvtSHFixedFpDCode,
1741                                       "predicate_test": predicateTest,
1742                                       "op_class": "SimdFloatCvtOp" }, [])
1743    header_output += FpRegRegImmOpDeclare.subst(vcvtSHFixedFpDIop);
1744    decoder_output += FpRegRegImmOpConstructor.subst(vcvtSHFixedFpDIop);
1745    exec_output += PredOpExecute.subst(vcvtSHFixedFpDIop);
1746
1747    vcvtUHFixedFpSCode = vfpEnabledCheckCode + '''
1748        FPSCR fpscr = (FPSCR) FpscrExc;
1749        VfpSavedState state = prepFpState(fpscr.rMode);
1750        __asm__ __volatile__("" : "=m" (FpOp1_uh) : "m" (FpOp1_uh));
1751        FpDest = vfpUFixedToFpS(fpscr.fz, fpscr.dn, FpOp1_uh, 16, imm);
1752        __asm__ __volatile__("" :: "m" (FpDest));
1753        finishVfp(fpscr, state, fpscr.fz);
1754        FpscrExc = fpscr;
1755    '''
1756    vcvtUHFixedFpSIop = InstObjParams("vcvt", "VcvtUHFixedFpS",
1757                                      "FpRegRegImmOp",
1758                                     { "code": vcvtUHFixedFpSCode,
1759                                       "predicate_test": predicateTest,
1760                                       "op_class": "SimdFloatCvtOp" }, [])
1761    header_output += FpRegRegImmOpDeclare.subst(vcvtUHFixedFpSIop);
1762    decoder_output += FpRegRegImmOpConstructor.subst(vcvtUHFixedFpSIop);
1763    exec_output += PredOpExecute.subst(vcvtUHFixedFpSIop);
1764
1765    vcvtUHFixedFpDCode = vfpEnabledCheckCode + '''
1766        FPSCR fpscr = (FPSCR) FpscrExc;
1767        uint64_t mid = ((uint64_t)FpOp1P0_uw | ((uint64_t)FpOp1P1_uw << 32));
1768        VfpSavedState state = prepFpState(fpscr.rMode);
1769        __asm__ __volatile__("" : "=m" (mid) : "m" (mid));
1770        double cDest = vfpUFixedToFpD(fpscr.fz, fpscr.dn, mid, 16, imm);
1771        __asm__ __volatile__("" :: "m" (cDest));
1772        finishVfp(fpscr, state, fpscr.fz);
1773        FpDestP0_uw = dblLow(cDest);
1774        FpDestP1_uw = dblHi(cDest);
1775        FpscrExc = fpscr;
1776    '''
1777    vcvtUHFixedFpDIop = InstObjParams("vcvt", "VcvtUHFixedFpD",
1778                                      "FpRegRegImmOp",
1779                                     { "code": vcvtUHFixedFpDCode,
1780                                       "predicate_test": predicateTest,
1781                                       "op_class": "SimdFloatCvtOp" }, [])
1782    header_output += FpRegRegImmOpDeclare.subst(vcvtUHFixedFpDIop);
1783    decoder_output += FpRegRegImmOpConstructor.subst(vcvtUHFixedFpDIop);
1784    exec_output += PredOpExecute.subst(vcvtUHFixedFpDIop);
1785}};
1786