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