fp.isa revision 7377:ce388054b481
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        FpDest = FpOp1 * FpOp2;
380        if ((isinf(FpOp1) && FpOp2 == 0) || (isinf(FpOp2) && FpOp1 == 0)) {
381            FpDest = NAN;
382        }
383    '''
384    vmulSIop = InstObjParams("vmuls", "VmulS", "VfpRegRegRegOp",
385                                     { "code": vmulSCode,
386                                       "predicate_test": predicateTest }, [])
387    header_output  += VfpRegRegRegOpDeclare.subst(vmulSIop);
388    decoder_output  += VfpRegRegRegOpConstructor.subst(vmulSIop);
389    exec_output += PredOpExecute.subst(vmulSIop);
390
391    vmulDCode = '''
392        IntDoubleUnion cOp1, cOp2, cDest;
393        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
394        cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32));
395        cDest.fp = cOp1.fp * cOp2.fp;
396        if ((isinf(cOp1.fp) && cOp2.fp == 0) ||
397                (isinf(cOp2.fp) && cOp1.fp == 0)) {
398            cDest.fp = NAN;
399        }
400        FpDestP0.uw = cDest.bits;
401        FpDestP1.uw = cDest.bits >> 32;
402    '''
403    vmulDIop = InstObjParams("vmuld", "VmulD", "VfpRegRegRegOp",
404                                     { "code": vmulDCode,
405                                       "predicate_test": predicateTest }, [])
406    header_output += VfpRegRegRegOpDeclare.subst(vmulDIop);
407    decoder_output += VfpRegRegRegOpConstructor.subst(vmulDIop);
408    exec_output += PredOpExecute.subst(vmulDIop);
409
410    vnegSCode = '''
411        FpDest = -FpOp1;
412    '''
413    vnegSIop = InstObjParams("vnegs", "VnegS", "VfpRegRegOp",
414                                     { "code": vnegSCode,
415                                       "predicate_test": predicateTest }, [])
416    header_output += VfpRegRegOpDeclare.subst(vnegSIop);
417    decoder_output += VfpRegRegOpConstructor.subst(vnegSIop);
418    exec_output += PredOpExecute.subst(vnegSIop);
419
420    vnegDCode = '''
421        IntDoubleUnion cOp1, cDest;
422        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
423        cDest.fp = -cOp1.fp;
424        FpDestP0.uw = cDest.bits;
425        FpDestP1.uw = cDest.bits >> 32;
426    '''
427    vnegDIop = InstObjParams("vnegd", "VnegD", "VfpRegRegOp",
428                                     { "code": vnegDCode,
429                                       "predicate_test": predicateTest }, [])
430    header_output += VfpRegRegOpDeclare.subst(vnegDIop);
431    decoder_output += VfpRegRegOpConstructor.subst(vnegDIop);
432    exec_output += PredOpExecute.subst(vnegDIop);
433
434    vabsSCode = '''
435        FpDest = fabsf(FpOp1);
436    '''
437    vabsSIop = InstObjParams("vabss", "VabsS", "VfpRegRegOp",
438                                     { "code": vabsSCode,
439                                       "predicate_test": predicateTest }, [])
440    header_output += VfpRegRegOpDeclare.subst(vabsSIop);
441    decoder_output += VfpRegRegOpConstructor.subst(vabsSIop);
442    exec_output += PredOpExecute.subst(vabsSIop);
443
444    vabsDCode = '''
445        IntDoubleUnion cOp1, cDest;
446        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
447        cDest.fp = fabs(cOp1.fp);
448        FpDestP0.uw = cDest.bits;
449        FpDestP1.uw = cDest.bits >> 32;
450    '''
451    vabsDIop = InstObjParams("vabsd", "VabsD", "VfpRegRegOp",
452                                     { "code": vabsDCode,
453                                       "predicate_test": predicateTest }, [])
454    header_output += VfpRegRegOpDeclare.subst(vabsDIop);
455    decoder_output += VfpRegRegOpConstructor.subst(vabsDIop);
456    exec_output += PredOpExecute.subst(vabsDIop);
457
458    vaddSCode = '''
459        FpDest = FpOp1 + FpOp2;
460    '''
461    vaddSIop = InstObjParams("vadds", "VaddS", "VfpRegRegRegOp",
462                                     { "code": vaddSCode,
463                                       "predicate_test": predicateTest }, [])
464    header_output += VfpRegRegRegOpDeclare.subst(vaddSIop);
465    decoder_output += VfpRegRegRegOpConstructor.subst(vaddSIop);
466    exec_output += PredOpExecute.subst(vaddSIop);
467
468    vaddDCode = '''
469        IntDoubleUnion cOp1, cOp2, cDest;
470        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
471        cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32));
472        cDest.fp = cOp1.fp + cOp2.fp;
473        FpDestP0.uw = cDest.bits;
474        FpDestP1.uw = cDest.bits >> 32;
475    '''
476    vaddDIop = InstObjParams("vaddd", "VaddD", "VfpRegRegRegOp",
477                                     { "code": vaddDCode,
478                                       "predicate_test": predicateTest }, [])
479    header_output += VfpRegRegRegOpDeclare.subst(vaddDIop);
480    decoder_output += VfpRegRegRegOpConstructor.subst(vaddDIop);
481    exec_output += PredOpExecute.subst(vaddDIop);
482
483    vsubSCode = '''
484        FpDest = FpOp1 - FpOp2;
485    '''
486    vsubSIop = InstObjParams("vsubs", "VsubS", "VfpRegRegRegOp",
487                                     { "code": vsubSCode,
488                                       "predicate_test": predicateTest }, [])
489    header_output += VfpRegRegRegOpDeclare.subst(vsubSIop);
490    decoder_output += VfpRegRegRegOpConstructor.subst(vsubSIop);
491    exec_output += PredOpExecute.subst(vsubSIop);
492
493    vsubDCode = '''
494        IntDoubleUnion cOp1, cOp2, cDest;
495        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
496        cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32));
497        cDest.fp = cOp1.fp - cOp2.fp;
498        FpDestP0.uw = cDest.bits;
499        FpDestP1.uw = cDest.bits >> 32;
500    '''
501    vsubDIop = InstObjParams("vsubd", "VsubD", "VfpRegRegRegOp",
502                                     { "code": vsubDCode,
503                                       "predicate_test": predicateTest }, [])
504    header_output += VfpRegRegRegOpDeclare.subst(vsubDIop);
505    decoder_output += VfpRegRegRegOpConstructor.subst(vsubDIop);
506    exec_output += PredOpExecute.subst(vsubDIop);
507
508    vdivSCode = '''
509        FpDest = FpOp1 / FpOp2;
510    '''
511    vdivSIop = InstObjParams("vdivs", "VdivS", "VfpRegRegRegOp",
512                                     { "code": vdivSCode,
513                                       "predicate_test": predicateTest }, [])
514    header_output += VfpRegRegRegOpDeclare.subst(vdivSIop);
515    decoder_output += VfpRegRegRegOpConstructor.subst(vdivSIop);
516    exec_output += PredOpExecute.subst(vdivSIop);
517
518    vdivDCode = '''
519        IntDoubleUnion cOp1, cOp2, cDest;
520        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
521        cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32));
522        cDest.fp = cOp1.fp / cOp2.fp;
523        FpDestP0.uw = cDest.bits;
524        FpDestP1.uw = cDest.bits >> 32;
525    '''
526    vdivDIop = InstObjParams("vdivd", "VdivD", "VfpRegRegRegOp",
527                                     { "code": vdivDCode,
528                                       "predicate_test": predicateTest }, [])
529    header_output += VfpRegRegRegOpDeclare.subst(vdivDIop);
530    decoder_output += VfpRegRegRegOpConstructor.subst(vdivDIop);
531    exec_output += PredOpExecute.subst(vdivDIop);
532
533    vsqrtSCode = '''
534        FpDest = sqrtf(FpOp1);
535        if (FpOp1 < 0) {
536            FpDest = NAN;
537        }
538    '''
539    vsqrtSIop = InstObjParams("vsqrts", "VsqrtS", "VfpRegRegOp",
540                                     { "code": vsqrtSCode,
541                                       "predicate_test": predicateTest }, [])
542    header_output += VfpRegRegOpDeclare.subst(vsqrtSIop);
543    decoder_output += VfpRegRegOpConstructor.subst(vsqrtSIop);
544    exec_output += PredOpExecute.subst(vsqrtSIop);
545
546    vsqrtDCode = '''
547        IntDoubleUnion cOp1, cDest;
548        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
549        cDest.fp = sqrt(cOp1.fp);
550        if (cOp1.fp < 0) {
551            cDest.fp = NAN;
552        }
553        FpDestP0.uw = cDest.bits;
554        FpDestP1.uw = cDest.bits >> 32;
555    '''
556    vsqrtDIop = InstObjParams("vsqrtd", "VsqrtD", "VfpRegRegOp",
557                                     { "code": vsqrtDCode,
558                                       "predicate_test": predicateTest }, [])
559    header_output  += VfpRegRegOpDeclare.subst(vsqrtDIop);
560    decoder_output  += VfpRegRegOpConstructor.subst(vsqrtDIop);
561    exec_output += PredOpExecute.subst(vsqrtDIop);
562
563    vmlaSCode = '''
564        float mid = FpOp1 * FpOp2;
565        if ((isinf(FpOp1) && FpOp2 == 0) || (isinf(FpOp2) && FpOp1 == 0)) {
566            mid = NAN;
567        }
568        FpDest = FpDest + mid;
569    '''
570    vmlaSIop = InstObjParams("vmlas", "VmlaS", "VfpRegRegRegOp",
571                                     { "code": vmlaSCode,
572                                       "predicate_test": predicateTest }, [])
573    header_output  += VfpRegRegRegOpDeclare.subst(vmlaSIop);
574    decoder_output  += VfpRegRegRegOpConstructor.subst(vmlaSIop);
575    exec_output += PredOpExecute.subst(vmlaSIop);
576
577    vmlaDCode = '''
578        IntDoubleUnion cOp1, cOp2, cDest;
579        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
580        cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32));
581        cDest.bits = ((uint64_t)FpDestP0.uw | ((uint64_t)FpDestP1.uw << 32));
582        double mid = cOp1.fp * cOp2.fp;
583        if ((isinf(cOp1.fp) && cOp2.fp == 0) ||
584                (isinf(cOp2.fp) && cOp1.fp == 0)) {
585            mid = NAN;
586        }
587        cDest.fp = cDest.fp + mid;
588        FpDestP0.uw = cDest.bits;
589        FpDestP1.uw = cDest.bits >> 32;
590    '''
591    vmlaDIop = InstObjParams("vmlad", "VmlaD", "VfpRegRegRegOp",
592                                     { "code": vmlaDCode,
593                                       "predicate_test": predicateTest }, [])
594    header_output  += VfpRegRegRegOpDeclare.subst(vmlaDIop);
595    decoder_output  += VfpRegRegRegOpConstructor.subst(vmlaDIop);
596    exec_output += PredOpExecute.subst(vmlaDIop);
597
598    vmlsSCode = '''
599        float mid = FpOp1 * FpOp2;
600        if ((isinf(FpOp1) && FpOp2 == 0) || (isinf(FpOp2) && FpOp1 == 0)) {
601            mid = NAN;
602        }
603        FpDest = FpDest - mid;
604    '''
605    vmlsSIop = InstObjParams("vmlss", "VmlsS", "VfpRegRegRegOp",
606                                     { "code": vmlsSCode,
607                                       "predicate_test": predicateTest }, [])
608    header_output  += VfpRegRegRegOpDeclare.subst(vmlsSIop);
609    decoder_output  += VfpRegRegRegOpConstructor.subst(vmlsSIop);
610    exec_output += PredOpExecute.subst(vmlsSIop);
611
612    vmlsDCode = '''
613        IntDoubleUnion cOp1, cOp2, cDest;
614        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
615        cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32));
616        cDest.bits = ((uint64_t)FpDestP0.uw | ((uint64_t)FpDestP1.uw << 32));
617        double mid = cOp1.fp * cOp2.fp;
618        if ((isinf(cOp1.fp) && cOp2.fp == 0) ||
619                (isinf(cOp2.fp) && cOp1.fp == 0)) {
620            mid = NAN;
621        }
622        cDest.fp = cDest.fp - mid;
623        FpDestP0.uw = cDest.bits;
624        FpDestP1.uw = cDest.bits >> 32;
625    '''
626    vmlsDIop = InstObjParams("vmlsd", "VmlsD", "VfpRegRegRegOp",
627                                     { "code": vmlsDCode,
628                                       "predicate_test": predicateTest }, [])
629    header_output  += VfpRegRegRegOpDeclare.subst(vmlsDIop);
630    decoder_output  += VfpRegRegRegOpConstructor.subst(vmlsDIop);
631    exec_output += PredOpExecute.subst(vmlsDIop);
632
633    vnmlaSCode = '''
634        float mid = FpOp1 * FpOp2;
635        if ((isinf(FpOp1) && FpOp2 == 0) || (isinf(FpOp2) && FpOp1 == 0)) {
636            mid = NAN;
637        }
638        FpDest = -FpDest - mid;
639    '''
640    vnmlaSIop = InstObjParams("vnmlas", "VnmlaS", "VfpRegRegRegOp",
641                                     { "code": vnmlaSCode,
642                                       "predicate_test": predicateTest }, [])
643    header_output  += VfpRegRegRegOpDeclare.subst(vnmlaSIop);
644    decoder_output  += VfpRegRegRegOpConstructor.subst(vnmlaSIop);
645    exec_output += PredOpExecute.subst(vnmlaSIop);
646
647    vnmlaDCode = '''
648        IntDoubleUnion cOp1, cOp2, cDest;
649        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
650        cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32));
651        cDest.bits = ((uint64_t)FpDestP0.uw | ((uint64_t)FpDestP1.uw << 32));
652        double mid = cOp1.fp * cOp2.fp;
653        if ((isinf(cOp1.fp) && cOp2.fp == 0) ||
654                (isinf(cOp2.fp) && cOp1.fp == 0)) {
655            mid = NAN;
656        }
657        cDest.fp = -cDest.fp - mid;
658        FpDestP0.uw = cDest.bits;
659        FpDestP1.uw = cDest.bits >> 32;
660    '''
661    vnmlaDIop = InstObjParams("vnmlad", "VnmlaD", "VfpRegRegRegOp",
662                                     { "code": vnmlaDCode,
663                                       "predicate_test": predicateTest }, [])
664    header_output  += VfpRegRegRegOpDeclare.subst(vnmlaDIop);
665    decoder_output  += VfpRegRegRegOpConstructor.subst(vnmlaDIop);
666    exec_output += PredOpExecute.subst(vnmlaDIop);
667
668    vnmlsSCode = '''
669        float mid = FpOp1 * FpOp2;
670        if ((isinf(FpOp1) && FpOp2 == 0) || (isinf(FpOp2) && FpOp1 == 0)) {
671            mid = NAN;
672        }
673        FpDest = -FpDest + mid;
674    '''
675    vnmlsSIop = InstObjParams("vnmlss", "VnmlsS", "VfpRegRegRegOp",
676                                     { "code": vnmlsSCode,
677                                       "predicate_test": predicateTest }, [])
678    header_output  += VfpRegRegRegOpDeclare.subst(vnmlsSIop);
679    decoder_output  += VfpRegRegRegOpConstructor.subst(vnmlsSIop);
680    exec_output += PredOpExecute.subst(vnmlsSIop);
681
682    vnmlsDCode = '''
683        IntDoubleUnion cOp1, cOp2, cDest;
684        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
685        cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32));
686        cDest.bits = ((uint64_t)FpDestP0.uw | ((uint64_t)FpDestP1.uw << 32));
687        double mid = cOp1.fp * cOp2.fp;
688        if ((isinf(cOp1.fp) && cOp2.fp == 0) ||
689                (isinf(cOp2.fp) && cOp1.fp == 0)) {
690            mid = NAN;
691        }
692        cDest.fp = -cDest.fp + mid;
693        FpDestP0.uw = cDest.bits;
694        FpDestP1.uw = cDest.bits >> 32;
695    '''
696    vnmlsDIop = InstObjParams("vnmlsd", "VnmlsD", "VfpRegRegRegOp",
697                                     { "code": vnmlsDCode,
698                                       "predicate_test": predicateTest }, [])
699    header_output  += VfpRegRegRegOpDeclare.subst(vnmlsDIop);
700    decoder_output  += VfpRegRegRegOpConstructor.subst(vnmlsDIop);
701    exec_output += PredOpExecute.subst(vnmlsDIop);
702
703    vnmulSCode = '''
704        float mid = FpOp1 * FpOp2;
705        if ((isinf(FpOp1) && FpOp2 == 0) || (isinf(FpOp2) && FpOp1 == 0)) {
706            mid = NAN;
707        }
708        FpDest = -mid;
709    '''
710    vnmulSIop = InstObjParams("vnmuls", "VnmulS", "VfpRegRegRegOp",
711                                     { "code": vnmulSCode,
712                                       "predicate_test": predicateTest }, [])
713    header_output  += VfpRegRegRegOpDeclare.subst(vnmulSIop);
714    decoder_output  += VfpRegRegRegOpConstructor.subst(vnmulSIop);
715    exec_output += PredOpExecute.subst(vnmulSIop);
716
717    vnmulDCode = '''
718        IntDoubleUnion cOp1, cOp2, cDest;
719        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
720        cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32));
721        cDest.bits = ((uint64_t)FpDestP0.uw | ((uint64_t)FpDestP1.uw << 32));
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 = -mid;
728        FpDestP0.uw = cDest.bits;
729        FpDestP1.uw = cDest.bits >> 32;
730    '''
731    vnmulDIop = InstObjParams("vnmuld", "VnmulD", "VfpRegRegRegOp",
732                                     { "code": vnmulDCode,
733                                       "predicate_test": predicateTest }, [])
734    header_output += VfpRegRegRegOpDeclare.subst(vnmulDIop);
735    decoder_output += VfpRegRegRegOpConstructor.subst(vnmulDIop);
736    exec_output += PredOpExecute.subst(vnmulDIop);
737
738    vcvtUIntFpSCode = '''
739        FpDest = FpOp1.uw;
740    '''
741    vcvtUIntFpSIop = InstObjParams("vcvt", "VcvtUIntFpS", "VfpRegRegOp",
742                                     { "code": vcvtUIntFpSCode,
743                                       "predicate_test": predicateTest }, [])
744    header_output += VfpRegRegOpDeclare.subst(vcvtUIntFpSIop);
745    decoder_output += VfpRegRegOpConstructor.subst(vcvtUIntFpSIop);
746    exec_output += PredOpExecute.subst(vcvtUIntFpSIop);
747
748    vcvtUIntFpDCode = '''
749        IntDoubleUnion cDest;
750        cDest.fp = (uint64_t)FpOp1P0.uw;
751        FpDestP0.uw = cDest.bits;
752        FpDestP1.uw = cDest.bits >> 32;
753    '''
754    vcvtUIntFpDIop = InstObjParams("vcvt", "VcvtUIntFpD", "VfpRegRegOp",
755                                     { "code": vcvtUIntFpDCode,
756                                       "predicate_test": predicateTest }, [])
757    header_output += VfpRegRegOpDeclare.subst(vcvtUIntFpDIop);
758    decoder_output += VfpRegRegOpConstructor.subst(vcvtUIntFpDIop);
759    exec_output += PredOpExecute.subst(vcvtUIntFpDIop);
760
761    vcvtSIntFpSCode = '''
762        FpDest = FpOp1.sw;
763    '''
764    vcvtSIntFpSIop = InstObjParams("vcvt", "VcvtSIntFpS", "VfpRegRegOp",
765                                     { "code": vcvtSIntFpSCode,
766                                       "predicate_test": predicateTest }, [])
767    header_output += VfpRegRegOpDeclare.subst(vcvtSIntFpSIop);
768    decoder_output += VfpRegRegOpConstructor.subst(vcvtSIntFpSIop);
769    exec_output += PredOpExecute.subst(vcvtSIntFpSIop);
770
771    vcvtSIntFpDCode = '''
772        IntDoubleUnion cDest;
773        cDest.fp = FpOp1P0.sw;
774        FpDestP0.uw = cDest.bits;
775        FpDestP1.uw = cDest.bits >> 32;
776    '''
777    vcvtSIntFpDIop = InstObjParams("vcvt", "VcvtSIntFpD", "VfpRegRegOp",
778                                     { "code": vcvtSIntFpDCode,
779                                       "predicate_test": predicateTest }, [])
780    header_output += VfpRegRegOpDeclare.subst(vcvtSIntFpDIop);
781    decoder_output += VfpRegRegOpConstructor.subst(vcvtSIntFpDIop);
782    exec_output += PredOpExecute.subst(vcvtSIntFpDIop);
783
784    vcvtFpUIntSCode = '''
785        FpDest.uw = FpOp1;
786    '''
787    vcvtFpUIntSIop = InstObjParams("vcvt", "VcvtFpUIntS", "VfpRegRegOp",
788                                     { "code": vcvtFpUIntSCode,
789                                       "predicate_test": predicateTest }, [])
790    header_output += VfpRegRegOpDeclare.subst(vcvtFpUIntSIop);
791    decoder_output += VfpRegRegOpConstructor.subst(vcvtFpUIntSIop);
792    exec_output += PredOpExecute.subst(vcvtFpUIntSIop);
793
794    vcvtFpUIntDCode = '''
795        IntDoubleUnion cOp1;
796        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
797        uint64_t result = cOp1.fp;
798        FpDestP0.uw = result;
799    '''
800    vcvtFpUIntDIop = InstObjParams("vcvt", "VcvtFpUIntD", "VfpRegRegOp",
801                                     { "code": vcvtFpUIntDCode,
802                                       "predicate_test": predicateTest }, [])
803    header_output += VfpRegRegOpDeclare.subst(vcvtFpUIntDIop);
804    decoder_output += VfpRegRegOpConstructor.subst(vcvtFpUIntDIop);
805    exec_output += PredOpExecute.subst(vcvtFpUIntDIop);
806
807    vcvtFpSIntSCode = '''
808        FpDest.sw = FpOp1;
809    '''
810    vcvtFpSIntSIop = InstObjParams("vcvt", "VcvtFpSIntS", "VfpRegRegOp",
811                                     { "code": vcvtFpSIntSCode,
812                                       "predicate_test": predicateTest }, [])
813    header_output += VfpRegRegOpDeclare.subst(vcvtFpSIntSIop);
814    decoder_output += VfpRegRegOpConstructor.subst(vcvtFpSIntSIop);
815    exec_output += PredOpExecute.subst(vcvtFpSIntSIop);
816
817    vcvtFpSIntDCode = '''
818        IntDoubleUnion cOp1;
819        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
820        int64_t result = cOp1.fp;
821        FpDestP0.uw = result;
822    '''
823    vcvtFpSIntDIop = InstObjParams("vcvt", "VcvtFpSIntD", "VfpRegRegOp",
824                                     { "code": vcvtFpSIntDCode,
825                                       "predicate_test": predicateTest }, [])
826    header_output += VfpRegRegOpDeclare.subst(vcvtFpSIntDIop);
827    decoder_output += VfpRegRegOpConstructor.subst(vcvtFpSIntDIop);
828    exec_output += PredOpExecute.subst(vcvtFpSIntDIop);
829
830    vcvtFpSFpDCode = '''
831        IntDoubleUnion cDest;
832        cDest.fp = FpOp1;
833        FpDestP0.uw = cDest.bits;
834        FpDestP1.uw = cDest.bits >> 32;
835    '''
836    vcvtFpSFpDIop = InstObjParams("vcvt", "VcvtFpSFpD", "VfpRegRegOp",
837                                     { "code": vcvtFpSFpDCode,
838                                       "predicate_test": predicateTest }, [])
839    header_output += VfpRegRegOpDeclare.subst(vcvtFpSFpDIop);
840    decoder_output += VfpRegRegOpConstructor.subst(vcvtFpSFpDIop);
841    exec_output += PredOpExecute.subst(vcvtFpSFpDIop);
842
843    vcvtFpDFpSCode = '''
844        IntDoubleUnion cOp1;
845        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
846        FpDest = cOp1.fp;
847    '''
848    vcvtFpDFpSIop = InstObjParams("vcvt", "VcvtFpDFpS", "VfpRegRegOp",
849                                     { "code": vcvtFpDFpSCode,
850                                       "predicate_test": predicateTest }, [])
851    header_output += VfpRegRegOpDeclare.subst(vcvtFpDFpSIop);
852    decoder_output += VfpRegRegOpConstructor.subst(vcvtFpDFpSIop);
853    exec_output += PredOpExecute.subst(vcvtFpDFpSIop);
854
855    vcmpSCode = '''
856        FPSCR fpscr = Fpscr;
857        if (FpDest == FpOp1) {
858            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
859        } else if (FpDest < FpOp1) {
860            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
861        } else if (FpDest > FpOp1) {
862            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
863        } else {
864            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
865        }
866        Fpscr = fpscr;
867    '''
868    vcmpSIop = InstObjParams("vcmps", "VcmpS", "VfpRegRegOp",
869                                     { "code": vcmpSCode,
870                                       "predicate_test": predicateTest }, [])
871    header_output += VfpRegRegOpDeclare.subst(vcmpSIop);
872    decoder_output += VfpRegRegOpConstructor.subst(vcmpSIop);
873    exec_output += PredOpExecute.subst(vcmpSIop);
874
875    vcmpDCode = '''
876        IntDoubleUnion cOp1, cDest;
877        cDest.bits = ((uint64_t)FpDestP0.uw | ((uint64_t)FpDestP1.uw << 32));
878        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
879        FPSCR fpscr = Fpscr;
880        if (cDest.fp == cOp1.fp) {
881            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
882        } else if (cDest.fp < cOp1.fp) {
883            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
884        } else if (cDest.fp > cOp1.fp) {
885            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
886        } else {
887            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
888        }
889        Fpscr = fpscr;
890    '''
891    vcmpDIop = InstObjParams("vcmpd", "VcmpD", "VfpRegRegOp",
892                                     { "code": vcmpDCode,
893                                       "predicate_test": predicateTest }, [])
894    header_output += VfpRegRegOpDeclare.subst(vcmpDIop);
895    decoder_output += VfpRegRegOpConstructor.subst(vcmpDIop);
896    exec_output += PredOpExecute.subst(vcmpDIop);
897
898    vcmpZeroSCode = '''
899        FPSCR fpscr = Fpscr;
900        if (FpDest == imm) {
901            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
902        } else if (FpDest < imm) {
903            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
904        } else if (FpDest > imm) {
905            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
906        } else {
907            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
908        }
909        Fpscr = fpscr;
910    '''
911    vcmpZeroSIop = InstObjParams("vcmpZeros", "VcmpZeroS", "VfpRegImmOp",
912                                     { "code": vcmpZeroSCode,
913                                       "predicate_test": predicateTest }, [])
914    header_output += VfpRegImmOpDeclare.subst(vcmpZeroSIop);
915    decoder_output += VfpRegImmOpConstructor.subst(vcmpZeroSIop);
916    exec_output += PredOpExecute.subst(vcmpZeroSIop);
917
918    vcmpZeroDCode = '''
919        IntDoubleUnion cDest;
920        cDest.bits = ((uint64_t)FpDestP0.uw | ((uint64_t)FpDestP1.uw << 32));
921        FPSCR fpscr = Fpscr;
922        if (cDest.fp == imm) {
923            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
924        } else if (cDest.fp < imm) {
925            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
926        } else if (cDest.fp > imm) {
927            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
928        } else {
929            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
930        }
931        Fpscr = fpscr;
932    '''
933    vcmpZeroDIop = InstObjParams("vcmpZerod", "VcmpZeroD", "VfpRegImmOp",
934                                     { "code": vcmpZeroDCode,
935                                       "predicate_test": predicateTest }, [])
936    header_output += VfpRegImmOpDeclare.subst(vcmpZeroDIop);
937    decoder_output += VfpRegImmOpConstructor.subst(vcmpZeroDIop);
938    exec_output += PredOpExecute.subst(vcmpZeroDIop);
939}};
940