fp.isa revision 7379:92ef7238d230
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", "VfpRegRegOp",
195                            { "code": "MiscDest = Op1;",
196                              "predicate_test": predicateTest }, [])
197    header_output += VfpRegRegOpDeclare.subst(vmsrIop);
198    decoder_output += VfpRegRegOpConstructor.subst(vmsrIop);
199    exec_output += PredOpExecute.subst(vmsrIop);
200
201    vmrsIop = InstObjParams("vmrs", "Vmrs", "VfpRegRegOp",
202                            { "code": "Dest = MiscOp1;",
203                              "predicate_test": predicateTest }, [])
204    header_output += VfpRegRegOpDeclare.subst(vmrsIop);
205    decoder_output += VfpRegRegOpConstructor.subst(vmrsIop);
206    exec_output += PredOpExecute.subst(vmrsIop);
207
208    vmovImmSCode = '''
209        FpDest.uw = bits(imm, 31, 0);
210    '''
211    vmovImmSIop = InstObjParams("vmov", "VmovImmS", "VfpRegImmOp",
212                                { "code": vmovImmSCode,
213                                  "predicate_test": predicateTest }, [])
214    header_output += VfpRegImmOpDeclare.subst(vmovImmSIop);
215    decoder_output += VfpRegImmOpConstructor.subst(vmovImmSIop);
216    exec_output += PredOpExecute.subst(vmovImmSIop);
217
218    vmovImmDCode = '''
219        FpDestP0.uw = bits(imm, 31, 0);
220        FpDestP1.uw = bits(imm, 63, 32);
221    '''
222    vmovImmDIop = InstObjParams("vmov", "VmovImmD", "VfpRegImmOp",
223                                { "code": vmovImmDCode,
224                                  "predicate_test": predicateTest }, [])
225    header_output += VfpRegImmOpDeclare.subst(vmovImmDIop);
226    decoder_output += VfpRegImmOpConstructor.subst(vmovImmDIop);
227    exec_output += PredOpExecute.subst(vmovImmDIop);
228
229    vmovImmQCode = '''
230        FpDestP0.uw = bits(imm, 31, 0);
231        FpDestP1.uw = bits(imm, 63, 32);
232        FpDestP2.uw = bits(imm, 31, 0);
233        FpDestP3.uw = bits(imm, 63, 32);
234    '''
235    vmovImmQIop = InstObjParams("vmov", "VmovImmQ", "VfpRegImmOp",
236                                { "code": vmovImmQCode,
237                                  "predicate_test": predicateTest }, [])
238    header_output += VfpRegImmOpDeclare.subst(vmovImmQIop);
239    decoder_output += VfpRegImmOpConstructor.subst(vmovImmQIop);
240    exec_output += PredOpExecute.subst(vmovImmQIop);
241
242    vmovRegSCode = '''
243        FpDest.uw = FpOp1.uw;
244    '''
245    vmovRegSIop = InstObjParams("vmov", "VmovRegS", "VfpRegRegOp",
246                                { "code": vmovRegSCode,
247                                  "predicate_test": predicateTest }, [])
248    header_output += VfpRegRegOpDeclare.subst(vmovRegSIop);
249    decoder_output += VfpRegRegOpConstructor.subst(vmovRegSIop);
250    exec_output += PredOpExecute.subst(vmovRegSIop);
251
252    vmovRegDCode = '''
253        FpDestP0.uw = FpOp1P0.uw;
254        FpDestP1.uw = FpOp1P1.uw;
255    '''
256    vmovRegDIop = InstObjParams("vmov", "VmovRegD", "VfpRegRegOp",
257                                { "code": vmovRegDCode,
258                                  "predicate_test": predicateTest }, [])
259    header_output += VfpRegRegOpDeclare.subst(vmovRegDIop);
260    decoder_output += VfpRegRegOpConstructor.subst(vmovRegDIop);
261    exec_output += PredOpExecute.subst(vmovRegDIop);
262
263    vmovRegQCode = '''
264        FpDestP0.uw = FpOp1P0.uw;
265        FpDestP1.uw = FpOp1P1.uw;
266        FpDestP2.uw = FpOp1P2.uw;
267        FpDestP3.uw = FpOp1P3.uw;
268    '''
269    vmovRegQIop = InstObjParams("vmov", "VmovRegQ", "VfpRegRegOp",
270                                { "code": vmovRegQCode,
271                                  "predicate_test": predicateTest }, [])
272    header_output  += VfpRegRegOpDeclare.subst(vmovRegQIop);
273    decoder_output  += VfpRegRegOpConstructor.subst(vmovRegQIop);
274    exec_output += PredOpExecute.subst(vmovRegQIop);
275
276    vmovCoreRegBCode = '''
277        FpDest.uw = insertBits(FpDest.uw, imm * 8, imm * 8 + 7, Op1.ub);
278    '''
279    vmovCoreRegBIop = InstObjParams("vmov", "VmovCoreRegB", "VfpRegRegImmOp",
280                                    { "code": vmovCoreRegBCode,
281                                      "predicate_test": predicateTest }, [])
282    header_output  += VfpRegRegImmOpDeclare.subst(vmovCoreRegBIop);
283    decoder_output  += VfpRegRegImmOpConstructor.subst(vmovCoreRegBIop);
284    exec_output += PredOpExecute.subst(vmovCoreRegBIop);
285
286    vmovCoreRegHCode = '''
287        FpDest.uw = insertBits(FpDest.uw, imm * 16, imm * 16 + 15, Op1.uh);
288    '''
289    vmovCoreRegHIop = InstObjParams("vmov", "VmovCoreRegH", "VfpRegRegImmOp",
290                                    { "code": vmovCoreRegHCode,
291                                      "predicate_test": predicateTest }, [])
292    header_output  += VfpRegRegImmOpDeclare.subst(vmovCoreRegHIop);
293    decoder_output  += VfpRegRegImmOpConstructor.subst(vmovCoreRegHIop);
294    exec_output += PredOpExecute.subst(vmovCoreRegHIop);
295
296    vmovCoreRegWCode = '''
297        FpDest.uw = Op1.uw;
298    '''
299    vmovCoreRegWIop = InstObjParams("vmov", "VmovCoreRegW", "VfpRegRegOp",
300                                    { "code": vmovCoreRegWCode,
301                                      "predicate_test": predicateTest }, [])
302    header_output  += VfpRegRegOpDeclare.subst(vmovCoreRegWIop);
303    decoder_output  += VfpRegRegOpConstructor.subst(vmovCoreRegWIop);
304    exec_output += PredOpExecute.subst(vmovCoreRegWIop);
305
306    vmovRegCoreUBCode = '''
307        Dest = bits(FpOp1.uw, imm * 8, imm * 8 + 7);
308    '''
309    vmovRegCoreUBIop = InstObjParams("vmov", "VmovRegCoreUB", "VfpRegRegImmOp",
310                                     { "code": vmovRegCoreUBCode,
311                                       "predicate_test": predicateTest }, [])
312    header_output  += VfpRegRegImmOpDeclare.subst(vmovRegCoreUBIop);
313    decoder_output  += VfpRegRegImmOpConstructor.subst(vmovRegCoreUBIop);
314    exec_output += PredOpExecute.subst(vmovRegCoreUBIop);
315
316    vmovRegCoreUHCode = '''
317        Dest = bits(FpOp1.uw, imm * 16, imm * 16 + 15);
318    '''
319    vmovRegCoreUHIop = InstObjParams("vmov", "VmovRegCoreUH", "VfpRegRegImmOp",
320                                     { "code": vmovRegCoreUHCode,
321                                       "predicate_test": predicateTest }, [])
322    header_output  += VfpRegRegImmOpDeclare.subst(vmovRegCoreUHIop);
323    decoder_output  += VfpRegRegImmOpConstructor.subst(vmovRegCoreUHIop);
324    exec_output += PredOpExecute.subst(vmovRegCoreUHIop);
325
326    vmovRegCoreSBCode = '''
327        Dest = sext<8>(bits(FpOp1.uw, imm * 8, imm * 8 + 7));
328    '''
329    vmovRegCoreSBIop = InstObjParams("vmov", "VmovRegCoreSB", "VfpRegRegImmOp",
330                                     { "code": vmovRegCoreSBCode,
331                                       "predicate_test": predicateTest }, [])
332    header_output  += VfpRegRegImmOpDeclare.subst(vmovRegCoreSBIop);
333    decoder_output  += VfpRegRegImmOpConstructor.subst(vmovRegCoreSBIop);
334    exec_output += PredOpExecute.subst(vmovRegCoreSBIop);
335
336    vmovRegCoreSHCode = '''
337        Dest = sext<16>(bits(FpOp1.uw, imm * 16, imm * 16 + 15));
338    '''
339    vmovRegCoreSHIop = InstObjParams("vmov", "VmovRegCoreSH", "VfpRegRegImmOp",
340                                     { "code": vmovRegCoreSHCode,
341                                       "predicate_test": predicateTest }, [])
342    header_output  += VfpRegRegImmOpDeclare.subst(vmovRegCoreSHIop);
343    decoder_output  += VfpRegRegImmOpConstructor.subst(vmovRegCoreSHIop);
344    exec_output += PredOpExecute.subst(vmovRegCoreSHIop);
345
346    vmovRegCoreWCode = '''
347        Dest = FpOp1.uw;
348    '''
349    vmovRegCoreWIop = InstObjParams("vmov", "VmovRegCoreW", "VfpRegRegOp",
350                                     { "code": vmovRegCoreWCode,
351                                       "predicate_test": predicateTest }, [])
352    header_output  += VfpRegRegOpDeclare.subst(vmovRegCoreWIop);
353    decoder_output  += VfpRegRegOpConstructor.subst(vmovRegCoreWIop);
354    exec_output += PredOpExecute.subst(vmovRegCoreWIop);
355
356    vmov2Reg2CoreCode = '''
357        FpDestP0.uw = Op1.uw;
358        FpDestP1.uw = Op2.uw;
359    '''
360    vmov2Reg2CoreIop = InstObjParams("vmov", "Vmov2Reg2Core", "VfpRegRegRegOp",
361                                     { "code": vmov2Reg2CoreCode,
362                                       "predicate_test": predicateTest }, [])
363    header_output  += VfpRegRegRegOpDeclare.subst(vmov2Reg2CoreIop);
364    decoder_output  += VfpRegRegRegOpConstructor.subst(vmov2Reg2CoreIop);
365    exec_output += PredOpExecute.subst(vmov2Reg2CoreIop);
366
367    vmov2Core2RegCode = '''
368        Dest.uw = FpOp2P0.uw;
369        Op1.uw = FpOp2P1.uw;
370    '''
371    vmov2Core2RegIop = InstObjParams("vmov", "Vmov2Core2Reg", "VfpRegRegRegOp",
372                                     { "code": vmov2Core2RegCode,
373                                       "predicate_test": predicateTest }, [])
374    header_output  += VfpRegRegRegOpDeclare.subst(vmov2Core2RegIop);
375    decoder_output  += VfpRegRegRegOpConstructor.subst(vmov2Core2RegIop);
376    exec_output += PredOpExecute.subst(vmov2Core2RegIop);
377
378    vmulSCode = '''
379        VfpSavedState state = prepVfpFpscr(Fpscr);
380        FpDest = FpOp1 * FpOp2;
381        Fpscr = setVfpFpscr(Fpscr, state);
382        if ((isinf(FpOp1) && FpOp2 == 0) || (isinf(FpOp2) && FpOp1 == 0)) {
383            FpDest = NAN;
384        }
385    '''
386    vmulSIop = InstObjParams("vmuls", "VmulS", "VfpRegRegRegOp",
387                                     { "code": vmulSCode,
388                                       "predicate_test": predicateTest }, [])
389    header_output  += VfpRegRegRegOpDeclare.subst(vmulSIop);
390    decoder_output  += VfpRegRegRegOpConstructor.subst(vmulSIop);
391    exec_output += PredOpExecute.subst(vmulSIop);
392
393    vmulDCode = '''
394        IntDoubleUnion cOp1, cOp2, cDest;
395        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
396        cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32));
397        VfpSavedState state = prepVfpFpscr(Fpscr);
398        cDest.fp = cOp1.fp * cOp2.fp;
399        Fpscr = setVfpFpscr(Fpscr, state);
400        if ((isinf(cOp1.fp) && cOp2.fp == 0) ||
401                (isinf(cOp2.fp) && cOp1.fp == 0)) {
402            cDest.fp = NAN;
403        }
404        FpDestP0.uw = cDest.bits;
405        FpDestP1.uw = cDest.bits >> 32;
406    '''
407    vmulDIop = InstObjParams("vmuld", "VmulD", "VfpRegRegRegOp",
408                                     { "code": vmulDCode,
409                                       "predicate_test": predicateTest }, [])
410    header_output += VfpRegRegRegOpDeclare.subst(vmulDIop);
411    decoder_output += VfpRegRegRegOpConstructor.subst(vmulDIop);
412    exec_output += PredOpExecute.subst(vmulDIop);
413
414    vnegSCode = '''
415        FpDest = -FpOp1;
416    '''
417    vnegSIop = InstObjParams("vnegs", "VnegS", "VfpRegRegOp",
418                                     { "code": vnegSCode,
419                                       "predicate_test": predicateTest }, [])
420    header_output += VfpRegRegOpDeclare.subst(vnegSIop);
421    decoder_output += VfpRegRegOpConstructor.subst(vnegSIop);
422    exec_output += PredOpExecute.subst(vnegSIop);
423
424    vnegDCode = '''
425        IntDoubleUnion cOp1, cDest;
426        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
427        cDest.fp = -cOp1.fp;
428        FpDestP0.uw = cDest.bits;
429        FpDestP1.uw = cDest.bits >> 32;
430    '''
431    vnegDIop = InstObjParams("vnegd", "VnegD", "VfpRegRegOp",
432                                     { "code": vnegDCode,
433                                       "predicate_test": predicateTest }, [])
434    header_output += VfpRegRegOpDeclare.subst(vnegDIop);
435    decoder_output += VfpRegRegOpConstructor.subst(vnegDIop);
436    exec_output += PredOpExecute.subst(vnegDIop);
437
438    vabsSCode = '''
439        FpDest = fabsf(FpOp1);
440    '''
441    vabsSIop = InstObjParams("vabss", "VabsS", "VfpRegRegOp",
442                                     { "code": vabsSCode,
443                                       "predicate_test": predicateTest }, [])
444    header_output += VfpRegRegOpDeclare.subst(vabsSIop);
445    decoder_output += VfpRegRegOpConstructor.subst(vabsSIop);
446    exec_output += PredOpExecute.subst(vabsSIop);
447
448    vabsDCode = '''
449        IntDoubleUnion cOp1, cDest;
450        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
451        cDest.fp = fabs(cOp1.fp);
452        FpDestP0.uw = cDest.bits;
453        FpDestP1.uw = cDest.bits >> 32;
454    '''
455    vabsDIop = InstObjParams("vabsd", "VabsD", "VfpRegRegOp",
456                                     { "code": vabsDCode,
457                                       "predicate_test": predicateTest }, [])
458    header_output += VfpRegRegOpDeclare.subst(vabsDIop);
459    decoder_output += VfpRegRegOpConstructor.subst(vabsDIop);
460    exec_output += PredOpExecute.subst(vabsDIop);
461
462    vaddSCode = '''
463        VfpSavedState state = prepVfpFpscr(Fpscr);
464        FpDest = FpOp1 + FpOp2;
465        Fpscr = setVfpFpscr(Fpscr, state);
466    '''
467    vaddSIop = InstObjParams("vadds", "VaddS", "VfpRegRegRegOp",
468                                     { "code": vaddSCode,
469                                       "predicate_test": predicateTest }, [])
470    header_output += VfpRegRegRegOpDeclare.subst(vaddSIop);
471    decoder_output += VfpRegRegRegOpConstructor.subst(vaddSIop);
472    exec_output += PredOpExecute.subst(vaddSIop);
473
474    vaddDCode = '''
475        IntDoubleUnion cOp1, cOp2, cDest;
476        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
477        cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32));
478        VfpSavedState state = prepVfpFpscr(Fpscr);
479        cDest.fp = cOp1.fp + cOp2.fp;
480        Fpscr = setVfpFpscr(Fpscr, state);
481        FpDestP0.uw = cDest.bits;
482        FpDestP1.uw = cDest.bits >> 32;
483    '''
484    vaddDIop = InstObjParams("vaddd", "VaddD", "VfpRegRegRegOp",
485                                     { "code": vaddDCode,
486                                       "predicate_test": predicateTest }, [])
487    header_output += VfpRegRegRegOpDeclare.subst(vaddDIop);
488    decoder_output += VfpRegRegRegOpConstructor.subst(vaddDIop);
489    exec_output += PredOpExecute.subst(vaddDIop);
490
491    vsubSCode = '''
492        VfpSavedState state = prepVfpFpscr(Fpscr);
493        FpDest = FpOp1 - FpOp2;
494        Fpscr = setVfpFpscr(Fpscr, state)
495    '''
496    vsubSIop = InstObjParams("vsubs", "VsubS", "VfpRegRegRegOp",
497                                     { "code": vsubSCode,
498                                       "predicate_test": predicateTest }, [])
499    header_output += VfpRegRegRegOpDeclare.subst(vsubSIop);
500    decoder_output += VfpRegRegRegOpConstructor.subst(vsubSIop);
501    exec_output += PredOpExecute.subst(vsubSIop);
502
503    vsubDCode = '''
504        IntDoubleUnion cOp1, cOp2, cDest;
505        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
506        cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32));
507        VfpSavedState state = prepVfpFpscr(Fpscr);
508        cDest.fp = cOp1.fp - cOp2.fp;
509        Fpscr = setVfpFpscr(Fpscr, state);
510        FpDestP0.uw = cDest.bits;
511        FpDestP1.uw = cDest.bits >> 32;
512    '''
513    vsubDIop = InstObjParams("vsubd", "VsubD", "VfpRegRegRegOp",
514                                     { "code": vsubDCode,
515                                       "predicate_test": predicateTest }, [])
516    header_output += VfpRegRegRegOpDeclare.subst(vsubDIop);
517    decoder_output += VfpRegRegRegOpConstructor.subst(vsubDIop);
518    exec_output += PredOpExecute.subst(vsubDIop);
519
520    vdivSCode = '''
521        VfpSavedState state = prepVfpFpscr(Fpscr);
522        FpDest = FpOp1 / FpOp2;
523        Fpscr = setVfpFpscr(Fpscr, state);
524    '''
525    vdivSIop = InstObjParams("vdivs", "VdivS", "VfpRegRegRegOp",
526                                     { "code": vdivSCode,
527                                       "predicate_test": predicateTest }, [])
528    header_output += VfpRegRegRegOpDeclare.subst(vdivSIop);
529    decoder_output += VfpRegRegRegOpConstructor.subst(vdivSIop);
530    exec_output += PredOpExecute.subst(vdivSIop);
531
532    vdivDCode = '''
533        IntDoubleUnion cOp1, cOp2, cDest;
534        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
535        cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32));
536        VfpSavedState state = prepVfpFpscr(Fpscr);
537        cDest.fp = cOp1.fp / cOp2.fp;
538        Fpscr = setVfpFpscr(Fpscr, state);
539        FpDestP0.uw = cDest.bits;
540        FpDestP1.uw = cDest.bits >> 32;
541    '''
542    vdivDIop = InstObjParams("vdivd", "VdivD", "VfpRegRegRegOp",
543                                     { "code": vdivDCode,
544                                       "predicate_test": predicateTest }, [])
545    header_output += VfpRegRegRegOpDeclare.subst(vdivDIop);
546    decoder_output += VfpRegRegRegOpConstructor.subst(vdivDIop);
547    exec_output += PredOpExecute.subst(vdivDIop);
548
549    vsqrtSCode = '''
550        VfpSavedState state = prepVfpFpscr(Fpscr);
551        FpDest = sqrtf(FpOp1);
552        Fpscr = setVfpFpscr(Fpscr, state);
553        if (FpOp1 < 0) {
554            FpDest = NAN;
555        }
556    '''
557    vsqrtSIop = InstObjParams("vsqrts", "VsqrtS", "VfpRegRegOp",
558                                     { "code": vsqrtSCode,
559                                       "predicate_test": predicateTest }, [])
560    header_output += VfpRegRegOpDeclare.subst(vsqrtSIop);
561    decoder_output += VfpRegRegOpConstructor.subst(vsqrtSIop);
562    exec_output += PredOpExecute.subst(vsqrtSIop);
563
564    vsqrtDCode = '''
565        IntDoubleUnion cOp1, cDest;
566        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
567        VfpSavedState state = prepVfpFpscr(Fpscr);
568        cDest.fp = sqrt(cOp1.fp);
569        Fpscr = setVfpFpscr(Fpscr, state);
570        if (cOp1.fp < 0) {
571            cDest.fp = NAN;
572        }
573        FpDestP0.uw = cDest.bits;
574        FpDestP1.uw = cDest.bits >> 32;
575    '''
576    vsqrtDIop = InstObjParams("vsqrtd", "VsqrtD", "VfpRegRegOp",
577                                     { "code": vsqrtDCode,
578                                       "predicate_test": predicateTest }, [])
579    header_output  += VfpRegRegOpDeclare.subst(vsqrtDIop);
580    decoder_output  += VfpRegRegOpConstructor.subst(vsqrtDIop);
581    exec_output += PredOpExecute.subst(vsqrtDIop);
582
583    vmlaSCode = '''
584        VfpSavedState state = prepVfpFpscr(Fpscr);
585        float mid = FpOp1 * FpOp2;
586        if ((isinf(FpOp1) && FpOp2 == 0) || (isinf(FpOp2) && FpOp1 == 0)) {
587            mid = NAN;
588        }
589        FpDest = FpDest + mid;
590        Fpscr = setVfpFpscr(Fpscr, state);
591    '''
592    vmlaSIop = InstObjParams("vmlas", "VmlaS", "VfpRegRegRegOp",
593                                     { "code": vmlaSCode,
594                                       "predicate_test": predicateTest }, [])
595    header_output  += VfpRegRegRegOpDeclare.subst(vmlaSIop);
596    decoder_output  += VfpRegRegRegOpConstructor.subst(vmlaSIop);
597    exec_output += PredOpExecute.subst(vmlaSIop);
598
599    vmlaDCode = '''
600        IntDoubleUnion cOp1, cOp2, cDest;
601        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
602        cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32));
603        cDest.bits = ((uint64_t)FpDestP0.uw | ((uint64_t)FpDestP1.uw << 32));
604        VfpSavedState state = prepVfpFpscr(Fpscr);
605        double mid = cOp1.fp * cOp2.fp;
606        if ((isinf(cOp1.fp) && cOp2.fp == 0) ||
607                (isinf(cOp2.fp) && cOp1.fp == 0)) {
608            mid = NAN;
609        }
610        cDest.fp = cDest.fp + mid;
611        Fpscr = setVfpFpscr(Fpscr, state);
612        FpDestP0.uw = cDest.bits;
613        FpDestP1.uw = cDest.bits >> 32;
614    '''
615    vmlaDIop = InstObjParams("vmlad", "VmlaD", "VfpRegRegRegOp",
616                                     { "code": vmlaDCode,
617                                       "predicate_test": predicateTest }, [])
618    header_output  += VfpRegRegRegOpDeclare.subst(vmlaDIop);
619    decoder_output  += VfpRegRegRegOpConstructor.subst(vmlaDIop);
620    exec_output += PredOpExecute.subst(vmlaDIop);
621
622    vmlsSCode = '''
623        VfpSavedState state = prepVfpFpscr(Fpscr);
624        float mid = FpOp1 * FpOp2;
625        if ((isinf(FpOp1) && FpOp2 == 0) || (isinf(FpOp2) && FpOp1 == 0)) {
626            mid = NAN;
627        }
628        FpDest = FpDest - mid;
629        Fpscr = setVfpFpscr(Fpscr, state);
630    '''
631    vmlsSIop = InstObjParams("vmlss", "VmlsS", "VfpRegRegRegOp",
632                                     { "code": vmlsSCode,
633                                       "predicate_test": predicateTest }, [])
634    header_output  += VfpRegRegRegOpDeclare.subst(vmlsSIop);
635    decoder_output  += VfpRegRegRegOpConstructor.subst(vmlsSIop);
636    exec_output += PredOpExecute.subst(vmlsSIop);
637
638    vmlsDCode = '''
639        IntDoubleUnion cOp1, cOp2, cDest;
640        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
641        cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32));
642        cDest.bits = ((uint64_t)FpDestP0.uw | ((uint64_t)FpDestP1.uw << 32));
643        VfpSavedState state = prepVfpFpscr(Fpscr);
644        double mid = cOp1.fp * cOp2.fp;
645        if ((isinf(cOp1.fp) && cOp2.fp == 0) ||
646                (isinf(cOp2.fp) && cOp1.fp == 0)) {
647            mid = NAN;
648        }
649        cDest.fp = cDest.fp - mid;
650        Fpscr = setVfpFpscr(Fpscr, state);
651        FpDestP0.uw = cDest.bits;
652        FpDestP1.uw = cDest.bits >> 32;
653    '''
654    vmlsDIop = InstObjParams("vmlsd", "VmlsD", "VfpRegRegRegOp",
655                                     { "code": vmlsDCode,
656                                       "predicate_test": predicateTest }, [])
657    header_output  += VfpRegRegRegOpDeclare.subst(vmlsDIop);
658    decoder_output  += VfpRegRegRegOpConstructor.subst(vmlsDIop);
659    exec_output += PredOpExecute.subst(vmlsDIop);
660
661    vnmlaSCode = '''
662        VfpSavedState state = prepVfpFpscr(Fpscr);
663        float mid = FpOp1 * FpOp2;
664        if ((isinf(FpOp1) && FpOp2 == 0) || (isinf(FpOp2) && FpOp1 == 0)) {
665            mid = NAN;
666        }
667        FpDest = -FpDest - mid;
668        Fpscr = setVfpFpscr(Fpscr, state);
669    '''
670    vnmlaSIop = InstObjParams("vnmlas", "VnmlaS", "VfpRegRegRegOp",
671                                     { "code": vnmlaSCode,
672                                       "predicate_test": predicateTest }, [])
673    header_output  += VfpRegRegRegOpDeclare.subst(vnmlaSIop);
674    decoder_output  += VfpRegRegRegOpConstructor.subst(vnmlaSIop);
675    exec_output += PredOpExecute.subst(vnmlaSIop);
676
677    vnmlaDCode = '''
678        IntDoubleUnion cOp1, cOp2, cDest;
679        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
680        cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32));
681        cDest.bits = ((uint64_t)FpDestP0.uw | ((uint64_t)FpDestP1.uw << 32));
682        VfpSavedState state = prepVfpFpscr(Fpscr);
683        double mid = cOp1.fp * cOp2.fp;
684        if ((isinf(cOp1.fp) && cOp2.fp == 0) ||
685                (isinf(cOp2.fp) && cOp1.fp == 0)) {
686            mid = NAN;
687        }
688        cDest.fp = -cDest.fp - mid;
689        Fpscr = setVfpFpscr(Fpscr, state);
690        FpDestP0.uw = cDest.bits;
691        FpDestP1.uw = cDest.bits >> 32;
692    '''
693    vnmlaDIop = InstObjParams("vnmlad", "VnmlaD", "VfpRegRegRegOp",
694                                     { "code": vnmlaDCode,
695                                       "predicate_test": predicateTest }, [])
696    header_output  += VfpRegRegRegOpDeclare.subst(vnmlaDIop);
697    decoder_output  += VfpRegRegRegOpConstructor.subst(vnmlaDIop);
698    exec_output += PredOpExecute.subst(vnmlaDIop);
699
700    vnmlsSCode = '''
701        VfpSavedState state = prepVfpFpscr(Fpscr);
702        float mid = FpOp1 * FpOp2;
703        if ((isinf(FpOp1) && FpOp2 == 0) || (isinf(FpOp2) && FpOp1 == 0)) {
704            mid = NAN;
705        }
706        FpDest = -FpDest + mid;
707        Fpscr = setVfpFpscr(Fpscr, state);
708    '''
709    vnmlsSIop = InstObjParams("vnmlss", "VnmlsS", "VfpRegRegRegOp",
710                                     { "code": vnmlsSCode,
711                                       "predicate_test": predicateTest }, [])
712    header_output  += VfpRegRegRegOpDeclare.subst(vnmlsSIop);
713    decoder_output  += VfpRegRegRegOpConstructor.subst(vnmlsSIop);
714    exec_output += PredOpExecute.subst(vnmlsSIop);
715
716    vnmlsDCode = '''
717        IntDoubleUnion cOp1, cOp2, cDest;
718        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
719        cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32));
720        cDest.bits = ((uint64_t)FpDestP0.uw | ((uint64_t)FpDestP1.uw << 32));
721        VfpSavedState state = prepVfpFpscr(Fpscr);
722        double mid = cOp1.fp * cOp2.fp;
723        if ((isinf(cOp1.fp) && cOp2.fp == 0) ||
724                (isinf(cOp2.fp) && cOp1.fp == 0)) {
725            mid = NAN;
726        }
727        cDest.fp = -cDest.fp + mid;
728        Fpscr = setVfpFpscr(Fpscr, state);
729        FpDestP0.uw = cDest.bits;
730        FpDestP1.uw = cDest.bits >> 32;
731    '''
732    vnmlsDIop = InstObjParams("vnmlsd", "VnmlsD", "VfpRegRegRegOp",
733                                     { "code": vnmlsDCode,
734                                       "predicate_test": predicateTest }, [])
735    header_output  += VfpRegRegRegOpDeclare.subst(vnmlsDIop);
736    decoder_output  += VfpRegRegRegOpConstructor.subst(vnmlsDIop);
737    exec_output += PredOpExecute.subst(vnmlsDIop);
738
739    vnmulSCode = '''
740        VfpSavedState state = prepVfpFpscr(Fpscr);
741        float mid = FpOp1 * FpOp2;
742        if ((isinf(FpOp1) && FpOp2 == 0) || (isinf(FpOp2) && FpOp1 == 0)) {
743            mid = NAN;
744        }
745        FpDest = -mid;
746        Fpscr = setVfpFpscr(Fpscr, state);
747    '''
748    vnmulSIop = InstObjParams("vnmuls", "VnmulS", "VfpRegRegRegOp",
749                                     { "code": vnmulSCode,
750                                       "predicate_test": predicateTest }, [])
751    header_output  += VfpRegRegRegOpDeclare.subst(vnmulSIop);
752    decoder_output  += VfpRegRegRegOpConstructor.subst(vnmulSIop);
753    exec_output += PredOpExecute.subst(vnmulSIop);
754
755    vnmulDCode = '''
756        IntDoubleUnion cOp1, cOp2, cDest;
757        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
758        cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32));
759        cDest.bits = ((uint64_t)FpDestP0.uw | ((uint64_t)FpDestP1.uw << 32));
760        VfpSavedState state = prepVfpFpscr(Fpscr);
761        double mid = cOp1.fp * cOp2.fp;
762        if ((isinf(cOp1.fp) && cOp2.fp == 0) ||
763                (isinf(cOp2.fp) && cOp1.fp == 0)) {
764            mid = NAN;
765        }
766        cDest.fp = -mid;
767        Fpscr = setVfpFpscr(Fpscr, state);
768        FpDestP0.uw = cDest.bits;
769        FpDestP1.uw = cDest.bits >> 32;
770    '''
771    vnmulDIop = InstObjParams("vnmuld", "VnmulD", "VfpRegRegRegOp",
772                                     { "code": vnmulDCode,
773                                       "predicate_test": predicateTest }, [])
774    header_output += VfpRegRegRegOpDeclare.subst(vnmulDIop);
775    decoder_output += VfpRegRegRegOpConstructor.subst(vnmulDIop);
776    exec_output += PredOpExecute.subst(vnmulDIop);
777
778    vcvtUIntFpSCode = '''
779        VfpSavedState state = prepVfpFpscr(Fpscr);
780        FpDest = FpOp1.uw;
781        Fpscr = setVfpFpscr(Fpscr, state);
782    '''
783    vcvtUIntFpSIop = InstObjParams("vcvt", "VcvtUIntFpS", "VfpRegRegOp",
784                                     { "code": vcvtUIntFpSCode,
785                                       "predicate_test": predicateTest }, [])
786    header_output += VfpRegRegOpDeclare.subst(vcvtUIntFpSIop);
787    decoder_output += VfpRegRegOpConstructor.subst(vcvtUIntFpSIop);
788    exec_output += PredOpExecute.subst(vcvtUIntFpSIop);
789
790    vcvtUIntFpDCode = '''
791        IntDoubleUnion cDest;
792        VfpSavedState state = prepVfpFpscr(Fpscr);
793        cDest.fp = (uint64_t)FpOp1P0.uw;
794        Fpscr = setVfpFpscr(Fpscr, state);
795        FpDestP0.uw = cDest.bits;
796        FpDestP1.uw = cDest.bits >> 32;
797    '''
798    vcvtUIntFpDIop = InstObjParams("vcvt", "VcvtUIntFpD", "VfpRegRegOp",
799                                     { "code": vcvtUIntFpDCode,
800                                       "predicate_test": predicateTest }, [])
801    header_output += VfpRegRegOpDeclare.subst(vcvtUIntFpDIop);
802    decoder_output += VfpRegRegOpConstructor.subst(vcvtUIntFpDIop);
803    exec_output += PredOpExecute.subst(vcvtUIntFpDIop);
804
805    vcvtSIntFpSCode = '''
806        VfpSavedState state = prepVfpFpscr(Fpscr);
807        FpDest = FpOp1.sw;
808        Fpscr = setVfpFpscr(Fpscr, state);
809    '''
810    vcvtSIntFpSIop = InstObjParams("vcvt", "VcvtSIntFpS", "VfpRegRegOp",
811                                     { "code": vcvtSIntFpSCode,
812                                       "predicate_test": predicateTest }, [])
813    header_output += VfpRegRegOpDeclare.subst(vcvtSIntFpSIop);
814    decoder_output += VfpRegRegOpConstructor.subst(vcvtSIntFpSIop);
815    exec_output += PredOpExecute.subst(vcvtSIntFpSIop);
816
817    vcvtSIntFpDCode = '''
818        IntDoubleUnion cDest;
819        VfpSavedState state = prepVfpFpscr(Fpscr);
820        cDest.fp = FpOp1P0.sw;
821        Fpscr = setVfpFpscr(Fpscr, state);
822        FpDestP0.uw = cDest.bits;
823        FpDestP1.uw = cDest.bits >> 32;
824    '''
825    vcvtSIntFpDIop = InstObjParams("vcvt", "VcvtSIntFpD", "VfpRegRegOp",
826                                     { "code": vcvtSIntFpDCode,
827                                       "predicate_test": predicateTest }, [])
828    header_output += VfpRegRegOpDeclare.subst(vcvtSIntFpDIop);
829    decoder_output += VfpRegRegOpConstructor.subst(vcvtSIntFpDIop);
830    exec_output += PredOpExecute.subst(vcvtSIntFpDIop);
831
832    vcvtFpUIntSCode = '''
833        VfpSavedState state = prepVfpFpscr(Fpscr);
834        FpDest.uw = FpOp1;
835        Fpscr = setVfpFpscr(Fpscr, state);
836    '''
837    vcvtFpUIntSIop = InstObjParams("vcvt", "VcvtFpUIntS", "VfpRegRegOp",
838                                     { "code": vcvtFpUIntSCode,
839                                       "predicate_test": predicateTest }, [])
840    header_output += VfpRegRegOpDeclare.subst(vcvtFpUIntSIop);
841    decoder_output += VfpRegRegOpConstructor.subst(vcvtFpUIntSIop);
842    exec_output += PredOpExecute.subst(vcvtFpUIntSIop);
843
844    vcvtFpUIntDCode = '''
845        IntDoubleUnion cOp1;
846        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
847        VfpSavedState state = prepVfpFpscr(Fpscr);
848        uint64_t result = cOp1.fp;
849        Fpscr = setVfpFpscr(Fpscr, state);
850        FpDestP0.uw = result;
851    '''
852    vcvtFpUIntDIop = InstObjParams("vcvt", "VcvtFpUIntD", "VfpRegRegOp",
853                                     { "code": vcvtFpUIntDCode,
854                                       "predicate_test": predicateTest }, [])
855    header_output += VfpRegRegOpDeclare.subst(vcvtFpUIntDIop);
856    decoder_output += VfpRegRegOpConstructor.subst(vcvtFpUIntDIop);
857    exec_output += PredOpExecute.subst(vcvtFpUIntDIop);
858
859    vcvtFpSIntSCode = '''
860        VfpSavedState state = prepVfpFpscr(Fpscr);
861        FpDest.sw = FpOp1;
862        Fpscr = setVfpFpscr(Fpscr, state);
863    '''
864    vcvtFpSIntSIop = InstObjParams("vcvt", "VcvtFpSIntS", "VfpRegRegOp",
865                                     { "code": vcvtFpSIntSCode,
866                                       "predicate_test": predicateTest }, [])
867    header_output += VfpRegRegOpDeclare.subst(vcvtFpSIntSIop);
868    decoder_output += VfpRegRegOpConstructor.subst(vcvtFpSIntSIop);
869    exec_output += PredOpExecute.subst(vcvtFpSIntSIop);
870
871    vcvtFpSIntDCode = '''
872        IntDoubleUnion cOp1;
873        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
874        VfpSavedState state = prepVfpFpscr(Fpscr);
875        int64_t result = cOp1.fp;
876        Fpscr = setVfpFpscr(Fpscr, state);
877        FpDestP0.uw = result;
878    '''
879    vcvtFpSIntDIop = InstObjParams("vcvt", "VcvtFpSIntD", "VfpRegRegOp",
880                                     { "code": vcvtFpSIntDCode,
881                                       "predicate_test": predicateTest }, [])
882    header_output += VfpRegRegOpDeclare.subst(vcvtFpSIntDIop);
883    decoder_output += VfpRegRegOpConstructor.subst(vcvtFpSIntDIop);
884    exec_output += PredOpExecute.subst(vcvtFpSIntDIop);
885
886    vcvtFpSFpDCode = '''
887        IntDoubleUnion cDest;
888        VfpSavedState state = prepVfpFpscr(Fpscr);
889        cDest.fp = FpOp1;
890        Fpscr = setVfpFpscr(Fpscr, state);
891        FpDestP0.uw = cDest.bits;
892        FpDestP1.uw = cDest.bits >> 32;
893    '''
894    vcvtFpSFpDIop = InstObjParams("vcvt", "VcvtFpSFpD", "VfpRegRegOp",
895                                     { "code": vcvtFpSFpDCode,
896                                       "predicate_test": predicateTest }, [])
897    header_output += VfpRegRegOpDeclare.subst(vcvtFpSFpDIop);
898    decoder_output += VfpRegRegOpConstructor.subst(vcvtFpSFpDIop);
899    exec_output += PredOpExecute.subst(vcvtFpSFpDIop);
900
901    vcvtFpDFpSCode = '''
902        IntDoubleUnion cOp1;
903        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
904        VfpSavedState state = prepVfpFpscr(Fpscr);
905        FpDest = cOp1.fp;
906        Fpscr = setVfpFpscr(Fpscr, state);
907    '''
908    vcvtFpDFpSIop = InstObjParams("vcvt", "VcvtFpDFpS", "VfpRegRegOp",
909                                     { "code": vcvtFpDFpSCode,
910                                       "predicate_test": predicateTest }, [])
911    header_output += VfpRegRegOpDeclare.subst(vcvtFpDFpSIop);
912    decoder_output += VfpRegRegOpConstructor.subst(vcvtFpDFpSIop);
913    exec_output += PredOpExecute.subst(vcvtFpDFpSIop);
914
915    vcmpSCode = '''
916        FPSCR fpscr = Fpscr;
917        if (FpDest == FpOp1) {
918            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
919        } else if (FpDest < FpOp1) {
920            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
921        } else if (FpDest > FpOp1) {
922            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
923        } else {
924            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
925        }
926        Fpscr = fpscr;
927    '''
928    vcmpSIop = InstObjParams("vcmps", "VcmpS", "VfpRegRegOp",
929                                     { "code": vcmpSCode,
930                                       "predicate_test": predicateTest }, [])
931    header_output += VfpRegRegOpDeclare.subst(vcmpSIop);
932    decoder_output += VfpRegRegOpConstructor.subst(vcmpSIop);
933    exec_output += PredOpExecute.subst(vcmpSIop);
934
935    vcmpDCode = '''
936        IntDoubleUnion cOp1, cDest;
937        cDest.bits = ((uint64_t)FpDestP0.uw | ((uint64_t)FpDestP1.uw << 32));
938        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
939        FPSCR fpscr = Fpscr;
940        if (cDest.fp == cOp1.fp) {
941            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
942        } else if (cDest.fp < cOp1.fp) {
943            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
944        } else if (cDest.fp > cOp1.fp) {
945            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
946        } else {
947            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
948        }
949        Fpscr = fpscr;
950    '''
951    vcmpDIop = InstObjParams("vcmpd", "VcmpD", "VfpRegRegOp",
952                                     { "code": vcmpDCode,
953                                       "predicate_test": predicateTest }, [])
954    header_output += VfpRegRegOpDeclare.subst(vcmpDIop);
955    decoder_output += VfpRegRegOpConstructor.subst(vcmpDIop);
956    exec_output += PredOpExecute.subst(vcmpDIop);
957
958    vcmpZeroSCode = '''
959        FPSCR fpscr = Fpscr;
960        if (FpDest == imm) {
961            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
962        } else if (FpDest < imm) {
963            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
964        } else if (FpDest > imm) {
965            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
966        } else {
967            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
968        }
969        Fpscr = fpscr;
970    '''
971    vcmpZeroSIop = InstObjParams("vcmpZeros", "VcmpZeroS", "VfpRegImmOp",
972                                     { "code": vcmpZeroSCode,
973                                       "predicate_test": predicateTest }, [])
974    header_output += VfpRegImmOpDeclare.subst(vcmpZeroSIop);
975    decoder_output += VfpRegImmOpConstructor.subst(vcmpZeroSIop);
976    exec_output += PredOpExecute.subst(vcmpZeroSIop);
977
978    vcmpZeroDCode = '''
979        IntDoubleUnion cDest;
980        cDest.bits = ((uint64_t)FpDestP0.uw | ((uint64_t)FpDestP1.uw << 32));
981        FPSCR fpscr = Fpscr;
982        if (cDest.fp == imm) {
983            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
984        } else if (cDest.fp < imm) {
985            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
986        } else if (cDest.fp > imm) {
987            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
988        } else {
989            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
990        }
991        Fpscr = fpscr;
992    '''
993    vcmpZeroDIop = InstObjParams("vcmpZerod", "VcmpZeroD", "VfpRegImmOp",
994                                     { "code": vcmpZeroDCode,
995                                       "predicate_test": predicateTest }, [])
996    header_output += VfpRegImmOpDeclare.subst(vcmpZeroDIop);
997    decoder_output += VfpRegImmOpConstructor.subst(vcmpZeroDIop);
998    exec_output += PredOpExecute.subst(vcmpZeroDIop);
999}};
1000
1001let {{
1002
1003    header_output = ""
1004    decoder_output = ""
1005    exec_output = ""
1006
1007    vcvtFpSFixedSCode = '''
1008        VfpSavedState state = prepVfpFpscr(Fpscr);
1009        FpDest.sw = vfpFpSToFixed(FpOp1, true, false, imm);
1010        Fpscr = setVfpFpscr(Fpscr, state);
1011    '''
1012    vcvtFpSFixedSIop = InstObjParams("vcvt", "VcvtFpSFixedS", "VfpRegRegImmOp",
1013                                     { "code": vcvtFpSFixedSCode,
1014                                       "predicate_test": predicateTest }, [])
1015    header_output += VfpRegRegImmOpDeclare.subst(vcvtFpSFixedSIop);
1016    decoder_output += VfpRegRegImmOpConstructor.subst(vcvtFpSFixedSIop);
1017    exec_output += PredOpExecute.subst(vcvtFpSFixedSIop);
1018
1019    vcvtFpSFixedDCode = '''
1020        IntDoubleUnion cOp1;
1021        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
1022        VfpSavedState state = prepVfpFpscr(Fpscr);
1023        uint64_t mid = vfpFpDToFixed(cOp1.fp, true, false, imm);
1024        Fpscr = setVfpFpscr(Fpscr, state);
1025        FpDestP0.uw = mid;
1026        FpDestP1.uw = mid >> 32;
1027    '''
1028    vcvtFpSFixedDIop = InstObjParams("vcvt", "VcvtFpSFixedD", "VfpRegRegImmOp",
1029                                     { "code": vcvtFpSFixedDCode,
1030                                       "predicate_test": predicateTest }, [])
1031    header_output += VfpRegRegImmOpDeclare.subst(vcvtFpSFixedDIop);
1032    decoder_output += VfpRegRegImmOpConstructor.subst(vcvtFpSFixedDIop);
1033    exec_output += PredOpExecute.subst(vcvtFpSFixedDIop);
1034
1035    vcvtFpUFixedSCode = '''
1036        VfpSavedState state = prepVfpFpscr(Fpscr);
1037        FpDest.uw = vfpFpSToFixed(FpOp1, false, false, imm);
1038        Fpscr = setVfpFpscr(Fpscr, state);
1039    '''
1040    vcvtFpUFixedSIop = InstObjParams("vcvt", "VcvtFpUFixedS", "VfpRegRegImmOp",
1041                                     { "code": vcvtFpUFixedSCode,
1042                                       "predicate_test": predicateTest }, [])
1043    header_output += VfpRegRegImmOpDeclare.subst(vcvtFpUFixedSIop);
1044    decoder_output += VfpRegRegImmOpConstructor.subst(vcvtFpUFixedSIop);
1045    exec_output += PredOpExecute.subst(vcvtFpUFixedSIop);
1046
1047    vcvtFpUFixedDCode = '''
1048        IntDoubleUnion cOp1;
1049        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
1050        VfpSavedState state = prepVfpFpscr(Fpscr);
1051        uint64_t mid = vfpFpDToFixed(cOp1.fp, false, false, imm);
1052        Fpscr = setVfpFpscr(Fpscr, state);
1053        FpDestP0.uw = mid;
1054        FpDestP1.uw = mid >> 32;
1055    '''
1056    vcvtFpUFixedDIop = InstObjParams("vcvt", "VcvtFpUFixedD", "VfpRegRegImmOp",
1057                                     { "code": vcvtFpUFixedDCode,
1058                                       "predicate_test": predicateTest }, [])
1059    header_output += VfpRegRegImmOpDeclare.subst(vcvtFpUFixedDIop);
1060    decoder_output += VfpRegRegImmOpConstructor.subst(vcvtFpUFixedDIop);
1061    exec_output += PredOpExecute.subst(vcvtFpUFixedDIop);
1062
1063    vcvtSFixedFpSCode = '''
1064        VfpSavedState state = prepVfpFpscr(Fpscr);
1065        FpDest = vfpSFixedToFpS(FpOp1.sw, true, imm);
1066        Fpscr = setVfpFpscr(Fpscr, state);
1067    '''
1068    vcvtSFixedFpSIop = InstObjParams("vcvt", "VcvtSFixedFpS", "VfpRegRegImmOp",
1069                                     { "code": vcvtSFixedFpSCode,
1070                                       "predicate_test": predicateTest }, [])
1071    header_output += VfpRegRegImmOpDeclare.subst(vcvtSFixedFpSIop);
1072    decoder_output += VfpRegRegImmOpConstructor.subst(vcvtSFixedFpSIop);
1073    exec_output += PredOpExecute.subst(vcvtSFixedFpSIop);
1074
1075    vcvtSFixedFpDCode = '''
1076        IntDoubleUnion cDest;
1077        uint64_t mid = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
1078        VfpSavedState state = prepVfpFpscr(Fpscr);
1079        cDest.fp = vfpSFixedToFpD(mid, true, imm);
1080        Fpscr = setVfpFpscr(Fpscr, state);
1081        FpDestP0.uw = cDest.bits;
1082        FpDestP1.uw = cDest.bits >> 32;
1083    '''
1084    vcvtSFixedFpDIop = InstObjParams("vcvt", "VcvtSFixedFpD", "VfpRegRegImmOp",
1085                                     { "code": vcvtSFixedFpDCode,
1086                                       "predicate_test": predicateTest }, [])
1087    header_output += VfpRegRegImmOpDeclare.subst(vcvtSFixedFpDIop);
1088    decoder_output += VfpRegRegImmOpConstructor.subst(vcvtSFixedFpDIop);
1089    exec_output += PredOpExecute.subst(vcvtSFixedFpDIop);
1090
1091    vcvtUFixedFpSCode = '''
1092        VfpSavedState state = prepVfpFpscr(Fpscr);
1093        FpDest = vfpUFixedToFpS(FpOp1.uw, false, imm);
1094        Fpscr = setVfpFpscr(Fpscr, state);
1095    '''
1096    vcvtUFixedFpSIop = InstObjParams("vcvt", "VcvtUFixedFpS", "VfpRegRegImmOp",
1097                                     { "code": vcvtUFixedFpSCode,
1098                                       "predicate_test": predicateTest }, [])
1099    header_output += VfpRegRegImmOpDeclare.subst(vcvtUFixedFpSIop);
1100    decoder_output += VfpRegRegImmOpConstructor.subst(vcvtUFixedFpSIop);
1101    exec_output += PredOpExecute.subst(vcvtUFixedFpSIop);
1102
1103    vcvtUFixedFpDCode = '''
1104        IntDoubleUnion cDest;
1105        uint64_t mid = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
1106        VfpSavedState state = prepVfpFpscr(Fpscr);
1107        cDest.fp = vfpUFixedToFpD(mid, false, imm);
1108        Fpscr = setVfpFpscr(Fpscr, state);
1109        FpDestP0.uw = cDest.bits;
1110        FpDestP1.uw = cDest.bits >> 32;
1111    '''
1112    vcvtUFixedFpDIop = InstObjParams("vcvt", "VcvtUFixedFpD", "VfpRegRegImmOp",
1113                                     { "code": vcvtUFixedFpDCode,
1114                                       "predicate_test": predicateTest }, [])
1115    header_output += VfpRegRegImmOpDeclare.subst(vcvtUFixedFpDIop);
1116    decoder_output += VfpRegRegImmOpConstructor.subst(vcvtUFixedFpDIop);
1117    exec_output += PredOpExecute.subst(vcvtUFixedFpDIop);
1118
1119    vcvtFpSHFixedSCode = '''
1120        VfpSavedState state = prepVfpFpscr(Fpscr);
1121        FpDest.sh = vfpFpSToFixed(FpOp1, true, true, imm);
1122        Fpscr = setVfpFpscr(Fpscr, state);
1123    '''
1124    vcvtFpSHFixedSIop = InstObjParams("vcvt", "VcvtFpSHFixedS",
1125                                      "VfpRegRegImmOp",
1126                                     { "code": vcvtFpSHFixedSCode,
1127                                       "predicate_test": predicateTest }, [])
1128    header_output += VfpRegRegImmOpDeclare.subst(vcvtFpSHFixedSIop);
1129    decoder_output += VfpRegRegImmOpConstructor.subst(vcvtFpSHFixedSIop);
1130    exec_output += PredOpExecute.subst(vcvtFpSHFixedSIop);
1131
1132    vcvtFpSHFixedDCode = '''
1133        IntDoubleUnion cOp1;
1134        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
1135        VfpSavedState state = prepVfpFpscr(Fpscr);
1136        uint64_t result = vfpFpDToFixed(cOp1.fp, true, true, imm);
1137        Fpscr = setVfpFpscr(Fpscr, state);
1138        FpDestP0.uw = result;
1139        FpDestP1.uw = result >> 32;
1140    '''
1141    vcvtFpSHFixedDIop = InstObjParams("vcvt", "VcvtFpSHFixedD",
1142                                      "VfpRegRegImmOp",
1143                                     { "code": vcvtFpSHFixedDCode,
1144                                       "predicate_test": predicateTest }, [])
1145    header_output += VfpRegRegImmOpDeclare.subst(vcvtFpSHFixedDIop);
1146    decoder_output += VfpRegRegImmOpConstructor.subst(vcvtFpSHFixedDIop);
1147    exec_output += PredOpExecute.subst(vcvtFpSHFixedDIop);
1148
1149    vcvtFpUHFixedSCode = '''
1150        VfpSavedState state = prepVfpFpscr(Fpscr);
1151        FpDest.uh = vfpFpSToFixed(FpOp1, false, true, imm);
1152        Fpscr = setVfpFpscr(Fpscr, state);
1153    '''
1154    vcvtFpUHFixedSIop = InstObjParams("vcvt", "VcvtFpUHFixedS",
1155                                      "VfpRegRegImmOp",
1156                                     { "code": vcvtFpUHFixedSCode,
1157                                       "predicate_test": predicateTest }, [])
1158    header_output += VfpRegRegImmOpDeclare.subst(vcvtFpUHFixedSIop);
1159    decoder_output += VfpRegRegImmOpConstructor.subst(vcvtFpUHFixedSIop);
1160    exec_output += PredOpExecute.subst(vcvtFpUHFixedSIop);
1161
1162    vcvtFpUHFixedDCode = '''
1163        IntDoubleUnion cOp1;
1164        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
1165        VfpSavedState state = prepVfpFpscr(Fpscr);
1166        uint64_t mid = vfpFpDToFixed(cOp1.fp, false, true, imm);
1167        Fpscr = setVfpFpscr(Fpscr, state);
1168        FpDestP0.uw = mid;
1169        FpDestP1.uw = mid >> 32;
1170    '''
1171    vcvtFpUHFixedDIop = InstObjParams("vcvt", "VcvtFpUHFixedD",
1172                                      "VfpRegRegImmOp",
1173                                     { "code": vcvtFpUHFixedDCode,
1174                                       "predicate_test": predicateTest }, [])
1175    header_output += VfpRegRegImmOpDeclare.subst(vcvtFpUHFixedDIop);
1176    decoder_output += VfpRegRegImmOpConstructor.subst(vcvtFpUHFixedDIop);
1177    exec_output += PredOpExecute.subst(vcvtFpUHFixedDIop);
1178
1179    vcvtSHFixedFpSCode = '''
1180        VfpSavedState state = prepVfpFpscr(Fpscr);
1181        FpDest = vfpSFixedToFpS(FpOp1.sh, true, imm);
1182        Fpscr = setVfpFpscr(Fpscr, state);
1183    '''
1184    vcvtSHFixedFpSIop = InstObjParams("vcvt", "VcvtSHFixedFpS",
1185                                      "VfpRegRegImmOp",
1186                                     { "code": vcvtSHFixedFpSCode,
1187                                       "predicate_test": predicateTest }, [])
1188    header_output += VfpRegRegImmOpDeclare.subst(vcvtSHFixedFpSIop);
1189    decoder_output += VfpRegRegImmOpConstructor.subst(vcvtSHFixedFpSIop);
1190    exec_output += PredOpExecute.subst(vcvtSHFixedFpSIop);
1191
1192    vcvtSHFixedFpDCode = '''
1193        IntDoubleUnion cDest;
1194        uint64_t mid = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
1195        VfpSavedState state = prepVfpFpscr(Fpscr);
1196        cDest.fp = vfpSFixedToFpD(mid, true, imm);
1197        Fpscr = setVfpFpscr(Fpscr, state);
1198        FpDestP0.uw = cDest.bits;
1199        FpDestP1.uw = cDest.bits >> 32;
1200    '''
1201    vcvtSHFixedFpDIop = InstObjParams("vcvt", "VcvtSHFixedFpD",
1202                                      "VfpRegRegImmOp",
1203                                     { "code": vcvtSHFixedFpDCode,
1204                                       "predicate_test": predicateTest }, [])
1205    header_output += VfpRegRegImmOpDeclare.subst(vcvtSHFixedFpDIop);
1206    decoder_output += VfpRegRegImmOpConstructor.subst(vcvtSHFixedFpDIop);
1207    exec_output += PredOpExecute.subst(vcvtSHFixedFpDIop);
1208
1209    vcvtUHFixedFpSCode = '''
1210        VfpSavedState state = prepVfpFpscr(Fpscr);
1211        FpDest = vfpUFixedToFpS(FpOp1.uh, true, imm);
1212        Fpscr = setVfpFpscr(Fpscr, state);
1213    '''
1214    vcvtUHFixedFpSIop = InstObjParams("vcvt", "VcvtUHFixedFpS",
1215                                      "VfpRegRegImmOp",
1216                                     { "code": vcvtUHFixedFpSCode,
1217                                       "predicate_test": predicateTest }, [])
1218    header_output += VfpRegRegImmOpDeclare.subst(vcvtUHFixedFpSIop);
1219    decoder_output += VfpRegRegImmOpConstructor.subst(vcvtUHFixedFpSIop);
1220    exec_output += PredOpExecute.subst(vcvtUHFixedFpSIop);
1221
1222    vcvtUHFixedFpDCode = '''
1223        IntDoubleUnion cDest;
1224        uint64_t mid = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
1225        VfpSavedState state = prepVfpFpscr(Fpscr);
1226        cDest.fp = vfpUFixedToFpD(mid, true, imm);
1227        Fpscr = setVfpFpscr(Fpscr, state);
1228        FpDestP0.uw = cDest.bits;
1229        FpDestP1.uw = cDest.bits >> 32;
1230    '''
1231    vcvtUHFixedFpDIop = InstObjParams("vcvt", "VcvtUHFixedFpD",
1232                                      "VfpRegRegImmOp",
1233                                     { "code": vcvtUHFixedFpDCode,
1234                                       "predicate_test": predicateTest }, [])
1235    header_output += VfpRegRegImmOpDeclare.subst(vcvtUHFixedFpDIop);
1236    decoder_output += VfpRegRegImmOpConstructor.subst(vcvtUHFixedFpDIop);
1237    exec_output += PredOpExecute.subst(vcvtUHFixedFpDIop);
1238}};
1239