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