fp.isa revision 7384:f12b4f28e5eb
16166Ssteve.reinhardt@amd.com// -*- mode:c++ -*-
26166Ssteve.reinhardt@amd.com
36166Ssteve.reinhardt@amd.com// Copyright (c) 2010 ARM Limited
46166Ssteve.reinhardt@amd.com// All rights reserved
56166Ssteve.reinhardt@amd.com//
66166Ssteve.reinhardt@amd.com// The license below extends only to copyright in the software and shall
76166Ssteve.reinhardt@amd.com// not be construed as granting a license to any other intellectual
86166Ssteve.reinhardt@amd.com// property including but not limited to intellectual property relating
96166Ssteve.reinhardt@amd.com// to a hardware implementation of the functionality of the software
106166Ssteve.reinhardt@amd.com// licensed hereunder.  You may use the software subject to the license
116166Ssteve.reinhardt@amd.com// terms below provided that you ensure that this notice is replicated
126166Ssteve.reinhardt@amd.com// unmodified and in its entirety in all distributions of the software,
136166Ssteve.reinhardt@amd.com// modified or unmodified, in source code or in binary form.
146166Ssteve.reinhardt@amd.com//
156166Ssteve.reinhardt@amd.com// Redistribution and use in source and binary forms, with or without
166166Ssteve.reinhardt@amd.com// modification, are permitted provided that the following conditions are
176166Ssteve.reinhardt@amd.com// met: redistributions of source code must retain the above copyright
186166Ssteve.reinhardt@amd.com// notice, this list of conditions and the following disclaimer;
196166Ssteve.reinhardt@amd.com// redistributions in binary form must reproduce the above copyright
206166Ssteve.reinhardt@amd.com// notice, this list of conditions and the following disclaimer in the
216166Ssteve.reinhardt@amd.com// documentation and/or other materials provided with the distribution;
226166Ssteve.reinhardt@amd.com// neither the name of the copyright holders nor the names of its
236166Ssteve.reinhardt@amd.com// contributors may be used to endorse or promote products derived from
246166Ssteve.reinhardt@amd.com// this software without specific prior written permission.
256166Ssteve.reinhardt@amd.com//
266166Ssteve.reinhardt@amd.com// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
276166Ssteve.reinhardt@amd.com// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
286166Ssteve.reinhardt@amd.com// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
296166Ssteve.reinhardt@amd.com// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
306166Ssteve.reinhardt@amd.com// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
316654Snate@binkert.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
326166Ssteve.reinhardt@amd.com// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
336166Ssteve.reinhardt@amd.com// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
346289Snate@binkert.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
356870Sdrh5@cs.wisc.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
366289Snate@binkert.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
376166Ssteve.reinhardt@amd.com//
386166Ssteve.reinhardt@amd.com// Authors: Gabe Black
396166Ssteve.reinhardt@amd.com
406166Ssteve.reinhardt@amd.comoutput header {{
416289Snate@binkert.org
426166Ssteve.reinhardt@amd.comtemplate <class Micro>
436166Ssteve.reinhardt@amd.comclass VfpMacroRegRegOp : public VfpMacroOp
447876Sgblack@eecs.umich.edu{
456166Ssteve.reinhardt@amd.com  public:
466166Ssteve.reinhardt@amd.com    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
379let {{
380
381    header_output = ""
382    decoder_output = ""
383    exec_output = ""
384
385    vmulSCode = '''
386        vfpFlushToZero(Fpscr, FpOp1, FpOp2);
387        VfpSavedState state = prepVfpFpscr(Fpscr);
388        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
389        FpDest = fixNan(Fpscr, FpOp1 * FpOp2, FpOp1, FpOp2);
390        __asm__ __volatile__("" :: "m" (FpDest));
391        Fpscr = setVfpFpscr(Fpscr, state);
392        if ((isinf(FpOp1) && FpOp2 == 0) || (isinf(FpOp2) && FpOp1 == 0)) {
393            FpDest = NAN;
394        }
395    '''
396    vmulSIop = InstObjParams("vmuls", "VmulS", "VfpRegRegRegOp",
397                                     { "code": vmulSCode,
398                                       "predicate_test": predicateTest }, [])
399    header_output  += VfpRegRegRegOpDeclare.subst(vmulSIop);
400    decoder_output  += VfpRegRegRegOpConstructor.subst(vmulSIop);
401    exec_output += PredOpExecute.subst(vmulSIop);
402
403    vmulDCode = '''
404        IntDoubleUnion cOp1, cOp2, cDest;
405        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
406        cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32));
407        vfpFlushToZero(Fpscr, cOp1.fp, cOp2.fp);
408        VfpSavedState state = prepVfpFpscr(Fpscr);
409        __asm__ __volatile__("" : "=m" (cOp1.fp) : "m" (cOp1.fp));
410        cDest.fp = fixNan(Fpscr, cOp1.fp * cOp2.fp, cOp1.fp, cOp2.fp);
411        __asm__ __volatile__("" :: "m" (cDest.fp));
412        Fpscr = setVfpFpscr(Fpscr, state);
413        if ((isinf(cOp1.fp) && cOp2.fp == 0) ||
414                (isinf(cOp2.fp) && cOp1.fp == 0)) {
415            cDest.fp = NAN;
416        }
417        FpDestP0.uw = cDest.bits;
418        FpDestP1.uw = cDest.bits >> 32;
419    '''
420    vmulDIop = InstObjParams("vmuld", "VmulD", "VfpRegRegRegOp",
421                                     { "code": vmulDCode,
422                                       "predicate_test": predicateTest }, [])
423    header_output += VfpRegRegRegOpDeclare.subst(vmulDIop);
424    decoder_output += VfpRegRegRegOpConstructor.subst(vmulDIop);
425    exec_output += PredOpExecute.subst(vmulDIop);
426
427    vnegSCode = '''
428        FpDest = -FpOp1;
429    '''
430    vnegSIop = InstObjParams("vnegs", "VnegS", "VfpRegRegOp",
431                                     { "code": vnegSCode,
432                                       "predicate_test": predicateTest }, [])
433    header_output += VfpRegRegOpDeclare.subst(vnegSIop);
434    decoder_output += VfpRegRegOpConstructor.subst(vnegSIop);
435    exec_output += PredOpExecute.subst(vnegSIop);
436
437    vnegDCode = '''
438        IntDoubleUnion cOp1, cDest;
439        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
440        cDest.fp = -cOp1.fp;
441        FpDestP0.uw = cDest.bits;
442        FpDestP1.uw = cDest.bits >> 32;
443    '''
444    vnegDIop = InstObjParams("vnegd", "VnegD", "VfpRegRegOp",
445                                     { "code": vnegDCode,
446                                       "predicate_test": predicateTest }, [])
447    header_output += VfpRegRegOpDeclare.subst(vnegDIop);
448    decoder_output += VfpRegRegOpConstructor.subst(vnegDIop);
449    exec_output += PredOpExecute.subst(vnegDIop);
450
451    vabsSCode = '''
452        FpDest = fabsf(FpOp1);
453    '''
454    vabsSIop = InstObjParams("vabss", "VabsS", "VfpRegRegOp",
455                                     { "code": vabsSCode,
456                                       "predicate_test": predicateTest }, [])
457    header_output += VfpRegRegOpDeclare.subst(vabsSIop);
458    decoder_output += VfpRegRegOpConstructor.subst(vabsSIop);
459    exec_output += PredOpExecute.subst(vabsSIop);
460
461    vabsDCode = '''
462        IntDoubleUnion cOp1, cDest;
463        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
464        cDest.fp = fabs(cOp1.fp);
465        FpDestP0.uw = cDest.bits;
466        FpDestP1.uw = cDest.bits >> 32;
467    '''
468    vabsDIop = InstObjParams("vabsd", "VabsD", "VfpRegRegOp",
469                                     { "code": vabsDCode,
470                                       "predicate_test": predicateTest }, [])
471    header_output += VfpRegRegOpDeclare.subst(vabsDIop);
472    decoder_output += VfpRegRegOpConstructor.subst(vabsDIop);
473    exec_output += PredOpExecute.subst(vabsDIop);
474
475    vaddSCode = '''
476        vfpFlushToZero(Fpscr, FpOp1, FpOp2);
477        VfpSavedState state = prepVfpFpscr(Fpscr);
478        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
479        FpDest = fixNan(Fpscr, FpOp1 + FpOp2, FpOp1, FpOp2);
480        __asm__ __volatile__("" :: "m" (FpDest));
481        Fpscr = setVfpFpscr(Fpscr, state);
482    '''
483    vaddSIop = InstObjParams("vadds", "VaddS", "VfpRegRegRegOp",
484                                     { "code": vaddSCode,
485                                       "predicate_test": predicateTest }, [])
486    header_output += VfpRegRegRegOpDeclare.subst(vaddSIop);
487    decoder_output += VfpRegRegRegOpConstructor.subst(vaddSIop);
488    exec_output += PredOpExecute.subst(vaddSIop);
489
490    vaddDCode = '''
491        IntDoubleUnion cOp1, cOp2, cDest;
492        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
493        cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32));
494        vfpFlushToZero(Fpscr, cOp1.fp, cOp2.fp);
495        VfpSavedState state = prepVfpFpscr(Fpscr);
496        __asm__ __volatile__("" : "=m" (cOp1.fp) : "m" (cOp1.fp));
497        cDest.fp = fixNan(Fpscr, cOp1.fp + cOp2.fp, cOp1.fp, cOp2.fp);
498        __asm__ __volatile__("" :: "m" (cDest.fp));
499        Fpscr = setVfpFpscr(Fpscr, state);
500        FpDestP0.uw = cDest.bits;
501        FpDestP1.uw = cDest.bits >> 32;
502    '''
503    vaddDIop = InstObjParams("vaddd", "VaddD", "VfpRegRegRegOp",
504                                     { "code": vaddDCode,
505                                       "predicate_test": predicateTest }, [])
506    header_output += VfpRegRegRegOpDeclare.subst(vaddDIop);
507    decoder_output += VfpRegRegRegOpConstructor.subst(vaddDIop);
508    exec_output += PredOpExecute.subst(vaddDIop);
509
510    vsubSCode = '''
511        vfpFlushToZero(Fpscr, FpOp1, FpOp2);
512        VfpSavedState state = prepVfpFpscr(Fpscr);
513        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
514        FpDest = fixNan(Fpscr, FpOp1 - FpOp2, FpOp1, FpOp2);
515        __asm__ __volatile__("" :: "m" (FpDest));
516        Fpscr = setVfpFpscr(Fpscr, state)
517    '''
518    vsubSIop = InstObjParams("vsubs", "VsubS", "VfpRegRegRegOp",
519                                     { "code": vsubSCode,
520                                       "predicate_test": predicateTest }, [])
521    header_output += VfpRegRegRegOpDeclare.subst(vsubSIop);
522    decoder_output += VfpRegRegRegOpConstructor.subst(vsubSIop);
523    exec_output += PredOpExecute.subst(vsubSIop);
524
525    vsubDCode = '''
526        IntDoubleUnion cOp1, cOp2, cDest;
527        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
528        cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32));
529        vfpFlushToZero(Fpscr, cOp1.fp, cOp2.fp);
530        VfpSavedState state = prepVfpFpscr(Fpscr);
531        __asm__ __volatile__("" : "=m" (cOp1.fp) : "m" (cOp1.fp));
532        cDest.fp = fixNan(Fpscr, cOp1.fp - cOp2.fp, cOp1.fp, cOp2.fp);
533        __asm__ __volatile__("" :: "m" (cDest.fp));
534        Fpscr = setVfpFpscr(Fpscr, state);
535        FpDestP0.uw = cDest.bits;
536        FpDestP1.uw = cDest.bits >> 32;
537    '''
538    vsubDIop = InstObjParams("vsubd", "VsubD", "VfpRegRegRegOp",
539                                     { "code": vsubDCode,
540                                       "predicate_test": predicateTest }, [])
541    header_output += VfpRegRegRegOpDeclare.subst(vsubDIop);
542    decoder_output += VfpRegRegRegOpConstructor.subst(vsubDIop);
543    exec_output += PredOpExecute.subst(vsubDIop);
544
545    vdivSCode = '''
546        vfpFlushToZero(Fpscr, FpOp1, FpOp2);
547        VfpSavedState state = prepVfpFpscr(Fpscr);
548        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
549        FpDest = fixNan(Fpscr, FpOp1 / FpOp2, FpOp1, FpOp2);
550        __asm__ __volatile__("" :: "m" (FpDest));
551        Fpscr = setVfpFpscr(Fpscr, state);
552    '''
553    vdivSIop = InstObjParams("vdivs", "VdivS", "VfpRegRegRegOp",
554                                     { "code": vdivSCode,
555                                       "predicate_test": predicateTest }, [])
556    header_output += VfpRegRegRegOpDeclare.subst(vdivSIop);
557    decoder_output += VfpRegRegRegOpConstructor.subst(vdivSIop);
558    exec_output += PredOpExecute.subst(vdivSIop);
559
560    vdivDCode = '''
561        IntDoubleUnion cOp1, cOp2, cDest;
562        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
563        cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32));
564        vfpFlushToZero(Fpscr, cOp1.fp, cOp2.fp);
565        VfpSavedState state = prepVfpFpscr(Fpscr);
566        __asm__ __volatile__("" : "=m" (cOp1.fp) : "m" (cDest.fp));
567        cDest.fp = fixNan(Fpscr, cOp1.fp / cOp2.fp, cOp1.fp, cOp2.fp);
568        __asm__ __volatile__("" :: "m" (cDest.fp));
569        Fpscr = setVfpFpscr(Fpscr, state);
570        FpDestP0.uw = cDest.bits;
571        FpDestP1.uw = cDest.bits >> 32;
572    '''
573    vdivDIop = InstObjParams("vdivd", "VdivD", "VfpRegRegRegOp",
574                                     { "code": vdivDCode,
575                                       "predicate_test": predicateTest }, [])
576    header_output += VfpRegRegRegOpDeclare.subst(vdivDIop);
577    decoder_output += VfpRegRegRegOpConstructor.subst(vdivDIop);
578    exec_output += PredOpExecute.subst(vdivDIop);
579
580    vsqrtSCode = '''
581        vfpFlushToZero(Fpscr, FpOp1);
582        VfpSavedState state = prepVfpFpscr(Fpscr);
583        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
584        FpDest = sqrtf(FpOp1);
585        __asm__ __volatile__("" :: "m" (FpDest));
586        Fpscr = setVfpFpscr(Fpscr, state);
587        if (FpOp1 < 0) {
588            FpDest = NAN;
589        }
590    '''
591    vsqrtSIop = InstObjParams("vsqrts", "VsqrtS", "VfpRegRegOp",
592                                     { "code": vsqrtSCode,
593                                       "predicate_test": predicateTest }, [])
594    header_output += VfpRegRegOpDeclare.subst(vsqrtSIop);
595    decoder_output += VfpRegRegOpConstructor.subst(vsqrtSIop);
596    exec_output += PredOpExecute.subst(vsqrtSIop);
597
598    vsqrtDCode = '''
599        IntDoubleUnion cOp1, cDest;
600        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
601        vfpFlushToZero(Fpscr, cOp1.fp);
602        VfpSavedState state = prepVfpFpscr(Fpscr);
603        __asm__ __volatile__("" : "=m" (cOp1.fp) : "m" (cDest.fp));
604        cDest.fp = sqrt(cOp1.fp);
605        __asm__ __volatile__("" :: "m" (cDest.fp));
606        Fpscr = setVfpFpscr(Fpscr, state);
607        if (cOp1.fp < 0) {
608            cDest.fp = NAN;
609        }
610        FpDestP0.uw = cDest.bits;
611        FpDestP1.uw = cDest.bits >> 32;
612    '''
613    vsqrtDIop = InstObjParams("vsqrtd", "VsqrtD", "VfpRegRegOp",
614                                     { "code": vsqrtDCode,
615                                       "predicate_test": predicateTest }, [])
616    header_output  += VfpRegRegOpDeclare.subst(vsqrtDIop);
617    decoder_output  += VfpRegRegOpConstructor.subst(vsqrtDIop);
618    exec_output += PredOpExecute.subst(vsqrtDIop);
619}};
620
621let {{
622
623    header_output = ""
624    decoder_output = ""
625    exec_output = ""
626
627    vmlaSCode = '''
628        vfpFlushToZero(Fpscr, FpOp1, FpOp2);
629        VfpSavedState state = prepVfpFpscr(Fpscr);
630        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
631        float mid = fixNan(Fpscr, FpOp1 * FpOp2, FpOp1, FpOp2);
632        if ((isinf(FpOp1) && FpOp2 == 0) || (isinf(FpOp2) && FpOp1 == 0)) {
633            mid = NAN;
634        }
635        vfpFlushToZero(Fpscr, FpDest, mid);
636        FpDest = fixNan(Fpscr, FpDest + mid, FpDest, mid);
637        __asm__ __volatile__("" :: "m" (FpDest));
638        Fpscr = setVfpFpscr(Fpscr, state);
639    '''
640    vmlaSIop = InstObjParams("vmlas", "VmlaS", "VfpRegRegRegOp",
641                                     { "code": vmlaSCode,
642                                       "predicate_test": predicateTest }, [])
643    header_output  += VfpRegRegRegOpDeclare.subst(vmlaSIop);
644    decoder_output  += VfpRegRegRegOpConstructor.subst(vmlaSIop);
645    exec_output += PredOpExecute.subst(vmlaSIop);
646
647    vmlaDCode = '''
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        vfpFlushToZero(Fpscr, cOp1.fp, cOp2.fp);
653        VfpSavedState state = prepVfpFpscr(Fpscr);
654        __asm__ __volatile__("" : "=m" (cOp1.fp) : "m" (cOp1.fp));
655        double mid = fixNan(Fpscr, cOp1.fp * cOp2.fp, cOp1.fp, cOp2.fp);
656        if ((isinf(cOp1.fp) && cOp2.fp == 0) ||
657                (isinf(cOp2.fp) && cOp1.fp == 0)) {
658            mid = NAN;
659        }
660        vfpFlushToZero(Fpscr, cDest.fp, mid);
661        cDest.fp = fixNan(Fpscr, cDest.fp + mid, cDest.fp, mid);
662        __asm__ __volatile__("" :: "m" (cDest.fp));
663        Fpscr = setVfpFpscr(Fpscr, state);
664        FpDestP0.uw = cDest.bits;
665        FpDestP1.uw = cDest.bits >> 32;
666    '''
667    vmlaDIop = InstObjParams("vmlad", "VmlaD", "VfpRegRegRegOp",
668                                     { "code": vmlaDCode,
669                                       "predicate_test": predicateTest }, [])
670    header_output  += VfpRegRegRegOpDeclare.subst(vmlaDIop);
671    decoder_output  += VfpRegRegRegOpConstructor.subst(vmlaDIop);
672    exec_output += PredOpExecute.subst(vmlaDIop);
673
674    vmlsSCode = '''
675        vfpFlushToZero(Fpscr, FpOp1, FpOp2);
676        VfpSavedState state = prepVfpFpscr(Fpscr);
677        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
678        float mid = fixNan(Fpscr, FpOp1 * FpOp2, FpOp1, FpOp2);
679        if ((isinf(FpOp1) && FpOp2 == 0) || (isinf(FpOp2) && FpOp1 == 0)) {
680            mid = NAN;
681        }
682        vfpFlushToZero(Fpscr, FpDest, mid);
683        FpDest = fixNan(Fpscr, FpDest - mid, FpDest, mid);
684        __asm__ __volatile__("" :: "m" (FpDest));
685        Fpscr = setVfpFpscr(Fpscr, state);
686    '''
687    vmlsSIop = InstObjParams("vmlss", "VmlsS", "VfpRegRegRegOp",
688                                     { "code": vmlsSCode,
689                                       "predicate_test": predicateTest }, [])
690    header_output  += VfpRegRegRegOpDeclare.subst(vmlsSIop);
691    decoder_output  += VfpRegRegRegOpConstructor.subst(vmlsSIop);
692    exec_output += PredOpExecute.subst(vmlsSIop);
693
694    vmlsDCode = '''
695        IntDoubleUnion cOp1, cOp2, cDest;
696        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
697        cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32));
698        cDest.bits = ((uint64_t)FpDestP0.uw | ((uint64_t)FpDestP1.uw << 32));
699        vfpFlushToZero(Fpscr, cOp1.fp, cOp2.fp);
700        VfpSavedState state = prepVfpFpscr(Fpscr);
701        __asm__ __volatile__("" : "=m" (cOp1.fp) : "m" (cOp1.fp));
702        double mid = fixNan(Fpscr, cOp1.fp * cOp2.fp, cOp1.fp, cOp2.fp);
703        if ((isinf(cOp1.fp) && cOp2.fp == 0) ||
704                (isinf(cOp2.fp) && cOp1.fp == 0)) {
705            mid = NAN;
706        }
707        cDest.fp = fixNan(Fpscr, cDest.fp - mid, cDest.fp, mid);
708        vfpFlushToZero(Fpscr, cDest.fp, mid);
709        __asm__ __volatile__("" :: "m" (cDest.fp));
710        Fpscr = setVfpFpscr(Fpscr, state);
711        FpDestP0.uw = cDest.bits;
712        FpDestP1.uw = cDest.bits >> 32;
713    '''
714    vmlsDIop = InstObjParams("vmlsd", "VmlsD", "VfpRegRegRegOp",
715                                     { "code": vmlsDCode,
716                                       "predicate_test": predicateTest }, [])
717    header_output  += VfpRegRegRegOpDeclare.subst(vmlsDIop);
718    decoder_output  += VfpRegRegRegOpConstructor.subst(vmlsDIop);
719    exec_output += PredOpExecute.subst(vmlsDIop);
720
721    vnmlaSCode = '''
722        vfpFlushToZero(Fpscr, FpOp1, FpOp2);
723        VfpSavedState state = prepVfpFpscr(Fpscr);
724        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
725        float mid = fixNan(Fpscr, FpOp1 * FpOp2, FpOp1, FpOp2);
726        if ((isinf(FpOp1) && FpOp2 == 0) || (isinf(FpOp2) && FpOp1 == 0)) {
727            mid = NAN;
728        }
729        vfpFlushToZero(Fpscr, FpDest, mid);
730        FpDest = fixNan(Fpscr, -FpDest - mid, FpDest, mid);
731        __asm__ __volatile__("" :: "m" (FpDest));
732        Fpscr = setVfpFpscr(Fpscr, state);
733    '''
734    vnmlaSIop = InstObjParams("vnmlas", "VnmlaS", "VfpRegRegRegOp",
735                                     { "code": vnmlaSCode,
736                                       "predicate_test": predicateTest }, [])
737    header_output  += VfpRegRegRegOpDeclare.subst(vnmlaSIop);
738    decoder_output  += VfpRegRegRegOpConstructor.subst(vnmlaSIop);
739    exec_output += PredOpExecute.subst(vnmlaSIop);
740
741    vnmlaDCode = '''
742        IntDoubleUnion cOp1, cOp2, cDest;
743        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
744        cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32));
745        cDest.bits = ((uint64_t)FpDestP0.uw | ((uint64_t)FpDestP1.uw << 32));
746        vfpFlushToZero(Fpscr, cOp1.fp, cOp2.fp);
747        VfpSavedState state = prepVfpFpscr(Fpscr);
748        __asm__ __volatile__("" : "=m" (cOp1.fp) : "m" (cOp1.fp));
749        double mid = fixNan(Fpscr, cOp1.fp * cOp2.fp, cOp1.fp, cOp2.fp);
750        if ((isinf(cOp1.fp) && cOp2.fp == 0) ||
751                (isinf(cOp2.fp) && cOp1.fp == 0)) {
752            mid = NAN;
753        }
754        vfpFlushToZero(Fpscr, cDest.fp, mid);
755        cDest.fp = fixNan(Fpscr, -cDest.fp - mid, cDest.fp, mid);
756        __asm__ __volatile__("" :: "m" (cDest.fp));
757        Fpscr = setVfpFpscr(Fpscr, state);
758        FpDestP0.uw = cDest.bits;
759        FpDestP1.uw = cDest.bits >> 32;
760    '''
761    vnmlaDIop = InstObjParams("vnmlad", "VnmlaD", "VfpRegRegRegOp",
762                                     { "code": vnmlaDCode,
763                                       "predicate_test": predicateTest }, [])
764    header_output  += VfpRegRegRegOpDeclare.subst(vnmlaDIop);
765    decoder_output  += VfpRegRegRegOpConstructor.subst(vnmlaDIop);
766    exec_output += PredOpExecute.subst(vnmlaDIop);
767
768    vnmlsSCode = '''
769        vfpFlushToZero(Fpscr, FpOp1, FpOp2);
770        VfpSavedState state = prepVfpFpscr(Fpscr);
771        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
772        float mid = fixNan(Fpscr, FpOp1 * FpOp2, FpOp1, FpOp2);
773        if ((isinf(FpOp1) && FpOp2 == 0) || (isinf(FpOp2) && FpOp1 == 0)) {
774            mid = NAN;
775        }
776        vfpFlushToZero(Fpscr, FpDest, mid);
777        FpDest = fixNan(Fpscr, -FpDest + mid, FpDest, mid);
778        __asm__ __volatile__("" :: "m" (FpDest));
779        Fpscr = setVfpFpscr(Fpscr, state);
780    '''
781    vnmlsSIop = InstObjParams("vnmlss", "VnmlsS", "VfpRegRegRegOp",
782                                     { "code": vnmlsSCode,
783                                       "predicate_test": predicateTest }, [])
784    header_output  += VfpRegRegRegOpDeclare.subst(vnmlsSIop);
785    decoder_output  += VfpRegRegRegOpConstructor.subst(vnmlsSIop);
786    exec_output += PredOpExecute.subst(vnmlsSIop);
787
788    vnmlsDCode = '''
789        IntDoubleUnion cOp1, cOp2, cDest;
790        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
791        cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32));
792        cDest.bits = ((uint64_t)FpDestP0.uw | ((uint64_t)FpDestP1.uw << 32));
793        vfpFlushToZero(Fpscr, cOp1.fp, cOp2.fp);
794        VfpSavedState state = prepVfpFpscr(Fpscr);
795        __asm__ __volatile__("" : "=m" (cOp1.fp) : "m" (cOp1.fp));
796        double mid = fixNan(Fpscr, cOp1.fp * cOp2.fp, cOp1.fp, cOp2.fp);
797        if ((isinf(cOp1.fp) && cOp2.fp == 0) ||
798                (isinf(cOp2.fp) && cOp1.fp == 0)) {
799            mid = NAN;
800        }
801        vfpFlushToZero(Fpscr, cDest.fp, mid);
802        cDest.fp = fixNan(Fpscr, -cDest.fp + mid, cDest.fp, mid);
803        __asm__ __volatile__("" :: "m" (cDest.fp));
804        Fpscr = setVfpFpscr(Fpscr, state);
805        FpDestP0.uw = cDest.bits;
806        FpDestP1.uw = cDest.bits >> 32;
807    '''
808    vnmlsDIop = InstObjParams("vnmlsd", "VnmlsD", "VfpRegRegRegOp",
809                                     { "code": vnmlsDCode,
810                                       "predicate_test": predicateTest }, [])
811    header_output  += VfpRegRegRegOpDeclare.subst(vnmlsDIop);
812    decoder_output  += VfpRegRegRegOpConstructor.subst(vnmlsDIop);
813    exec_output += PredOpExecute.subst(vnmlsDIop);
814
815    vnmulSCode = '''
816        vfpFlushToZero(Fpscr, FpOp1, FpOp2);
817        VfpSavedState state = prepVfpFpscr(Fpscr);
818        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
819        float mid = fixNan(Fpscr, FpOp1 * FpOp2, FpOp1, FpOp2);
820        if ((isinf(FpOp1) && FpOp2 == 0) || (isinf(FpOp2) && FpOp1 == 0)) {
821            mid = NAN;
822        }
823        FpDest = -mid;
824        __asm__ __volatile__("" :: "m" (FpDest));
825        Fpscr = setVfpFpscr(Fpscr, state);
826    '''
827    vnmulSIop = InstObjParams("vnmuls", "VnmulS", "VfpRegRegRegOp",
828                                     { "code": vnmulSCode,
829                                       "predicate_test": predicateTest }, [])
830    header_output  += VfpRegRegRegOpDeclare.subst(vnmulSIop);
831    decoder_output  += VfpRegRegRegOpConstructor.subst(vnmulSIop);
832    exec_output += PredOpExecute.subst(vnmulSIop);
833
834    vnmulDCode = '''
835        IntDoubleUnion cOp1, cOp2, cDest;
836        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
837        cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32));
838        cDest.bits = ((uint64_t)FpDestP0.uw | ((uint64_t)FpDestP1.uw << 32));
839        vfpFlushToZero(Fpscr, cOp1.fp, cOp2.fp);
840        VfpSavedState state = prepVfpFpscr(Fpscr);
841        __asm__ __volatile__("" : "=m" (cOp1.fp) : "m" (cOp1.fp));
842        double mid = fixNan(Fpscr, cOp1.fp * cOp2.fp, cOp1.fp, cOp2.fp);
843        if ((isinf(cOp1.fp) && cOp2.fp == 0) ||
844                (isinf(cOp2.fp) && cOp1.fp == 0)) {
845            mid = NAN;
846        }
847        cDest.fp = -mid;
848        __asm__ __volatile__("" :: "m" (cDest.fp));
849        Fpscr = setVfpFpscr(Fpscr, state);
850        FpDestP0.uw = cDest.bits;
851        FpDestP1.uw = cDest.bits >> 32;
852    '''
853    vnmulDIop = InstObjParams("vnmuld", "VnmulD", "VfpRegRegRegOp",
854                                     { "code": vnmulDCode,
855                                       "predicate_test": predicateTest }, [])
856    header_output += VfpRegRegRegOpDeclare.subst(vnmulDIop);
857    decoder_output += VfpRegRegRegOpConstructor.subst(vnmulDIop);
858    exec_output += PredOpExecute.subst(vnmulDIop);
859}};
860
861let {{
862
863    header_output = ""
864    decoder_output = ""
865    exec_output = ""
866
867    vcvtUIntFpSCode = '''
868        VfpSavedState state = prepVfpFpscr(Fpscr);
869        __asm__ __volatile__("" : "=m" (FpOp1.uw) : "m" (FpOp1.uw));
870        FpDest = FpOp1.uw;
871        __asm__ __volatile__("" :: "m" (FpDest));
872        Fpscr = setVfpFpscr(Fpscr, state);
873    '''
874    vcvtUIntFpSIop = InstObjParams("vcvt", "VcvtUIntFpS", "VfpRegRegOp",
875                                     { "code": vcvtUIntFpSCode,
876                                       "predicate_test": predicateTest }, [])
877    header_output += VfpRegRegOpDeclare.subst(vcvtUIntFpSIop);
878    decoder_output += VfpRegRegOpConstructor.subst(vcvtUIntFpSIop);
879    exec_output += PredOpExecute.subst(vcvtUIntFpSIop);
880
881    vcvtUIntFpDCode = '''
882        IntDoubleUnion cDest;
883        VfpSavedState state = prepVfpFpscr(Fpscr);
884        __asm__ __volatile__("" : "=m" (FpOp1P0.uw) : "m" (FpOp1P0.uw));
885        cDest.fp = (uint64_t)FpOp1P0.uw;
886        __asm__ __volatile__("" :: "m" (cDest.fp));
887        Fpscr = setVfpFpscr(Fpscr, state);
888        FpDestP0.uw = cDest.bits;
889        FpDestP1.uw = cDest.bits >> 32;
890    '''
891    vcvtUIntFpDIop = InstObjParams("vcvt", "VcvtUIntFpD", "VfpRegRegOp",
892                                     { "code": vcvtUIntFpDCode,
893                                       "predicate_test": predicateTest }, [])
894    header_output += VfpRegRegOpDeclare.subst(vcvtUIntFpDIop);
895    decoder_output += VfpRegRegOpConstructor.subst(vcvtUIntFpDIop);
896    exec_output += PredOpExecute.subst(vcvtUIntFpDIop);
897
898    vcvtSIntFpSCode = '''
899        VfpSavedState state = prepVfpFpscr(Fpscr);
900        __asm__ __volatile__("" : "=m" (FpOp1.sw) : "m" (FpOp1.sw));
901        FpDest = FpOp1.sw;
902        __asm__ __volatile__("" :: "m" (FpDest));
903        Fpscr = setVfpFpscr(Fpscr, state);
904    '''
905    vcvtSIntFpSIop = InstObjParams("vcvt", "VcvtSIntFpS", "VfpRegRegOp",
906                                     { "code": vcvtSIntFpSCode,
907                                       "predicate_test": predicateTest }, [])
908    header_output += VfpRegRegOpDeclare.subst(vcvtSIntFpSIop);
909    decoder_output += VfpRegRegOpConstructor.subst(vcvtSIntFpSIop);
910    exec_output += PredOpExecute.subst(vcvtSIntFpSIop);
911
912    vcvtSIntFpDCode = '''
913        IntDoubleUnion cDest;
914        VfpSavedState state = prepVfpFpscr(Fpscr);
915        __asm__ __volatile__("" : "=m" (FpOp1P0.sw) : "m" (FpOp1P0.sw));
916        cDest.fp = FpOp1P0.sw;
917        __asm__ __volatile__("" :: "m" (cDest.fp));
918        Fpscr = setVfpFpscr(Fpscr, state);
919        FpDestP0.uw = cDest.bits;
920        FpDestP1.uw = cDest.bits >> 32;
921    '''
922    vcvtSIntFpDIop = InstObjParams("vcvt", "VcvtSIntFpD", "VfpRegRegOp",
923                                     { "code": vcvtSIntFpDCode,
924                                       "predicate_test": predicateTest }, [])
925    header_output += VfpRegRegOpDeclare.subst(vcvtSIntFpDIop);
926    decoder_output += VfpRegRegOpConstructor.subst(vcvtSIntFpDIop);
927    exec_output += PredOpExecute.subst(vcvtSIntFpDIop);
928
929    vcvtFpUIntSRCode = '''
930        vfpFlushToZero(Fpscr, FpOp1);
931        VfpSavedState state = prepVfpFpscr(Fpscr);
932        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
933        FpDest.uw = FpOp1;
934        __asm__ __volatile__("" :: "m" (FpDest.uw));
935        Fpscr = setVfpFpscr(Fpscr, state);
936    '''
937    vcvtFpUIntSRIop = InstObjParams("vcvt", "VcvtFpUIntSR", "VfpRegRegOp",
938                                     { "code": vcvtFpUIntSRCode,
939                                       "predicate_test": predicateTest }, [])
940    header_output += VfpRegRegOpDeclare.subst(vcvtFpUIntSRIop);
941    decoder_output += VfpRegRegOpConstructor.subst(vcvtFpUIntSRIop);
942    exec_output += PredOpExecute.subst(vcvtFpUIntSRIop);
943
944    vcvtFpUIntDRCode = '''
945        IntDoubleUnion cOp1;
946        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
947        vfpFlushToZero(Fpscr, cOp1.fp);
948        VfpSavedState state = prepVfpFpscr(Fpscr);
949        __asm__ __volatile__("" : "=m" (cOp1.fp) : "m" (cOp1.fp));
950        uint64_t result = cOp1.fp;
951        __asm__ __volatile__("" :: "m" (result));
952        Fpscr = setVfpFpscr(Fpscr, state);
953        FpDestP0.uw = result;
954    '''
955    vcvtFpUIntDRIop = InstObjParams("vcvtr", "VcvtFpUIntDR", "VfpRegRegOp",
956                                     { "code": vcvtFpUIntDRCode,
957                                       "predicate_test": predicateTest }, [])
958    header_output += VfpRegRegOpDeclare.subst(vcvtFpUIntDRIop);
959    decoder_output += VfpRegRegOpConstructor.subst(vcvtFpUIntDRIop);
960    exec_output += PredOpExecute.subst(vcvtFpUIntDRIop);
961
962    vcvtFpSIntSRCode = '''
963        vfpFlushToZero(Fpscr, FpOp1);
964        VfpSavedState state = prepVfpFpscr(Fpscr);
965        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
966        FpDest.sw = FpOp1;
967        __asm__ __volatile__("" :: "m" (FpDest.sw));
968        Fpscr = setVfpFpscr(Fpscr, state);
969    '''
970    vcvtFpSIntSRIop = InstObjParams("vcvtr", "VcvtFpSIntSR", "VfpRegRegOp",
971                                     { "code": vcvtFpSIntSRCode,
972                                       "predicate_test": predicateTest }, [])
973    header_output += VfpRegRegOpDeclare.subst(vcvtFpSIntSRIop);
974    decoder_output += VfpRegRegOpConstructor.subst(vcvtFpSIntSRIop);
975    exec_output += PredOpExecute.subst(vcvtFpSIntSRIop);
976
977    vcvtFpSIntDRCode = '''
978        IntDoubleUnion cOp1;
979        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
980        vfpFlushToZero(Fpscr, cOp1.fp);
981        VfpSavedState state = prepVfpFpscr(Fpscr);
982        __asm__ __volatile__("" : "=m" (cOp1.fp) : "m" (cOp1.fp));
983        int64_t result = cOp1.fp;
984        __asm__ __volatile__("" :: "m" (result));
985        Fpscr = setVfpFpscr(Fpscr, state);
986        FpDestP0.uw = result;
987    '''
988    vcvtFpSIntDRIop = InstObjParams("vcvtr", "VcvtFpSIntDR", "VfpRegRegOp",
989                                     { "code": vcvtFpSIntDRCode,
990                                       "predicate_test": predicateTest }, [])
991    header_output += VfpRegRegOpDeclare.subst(vcvtFpSIntDRIop);
992    decoder_output += VfpRegRegOpConstructor.subst(vcvtFpSIntDRIop);
993    exec_output += PredOpExecute.subst(vcvtFpSIntDRIop);
994
995    vcvtFpUIntSCode = '''
996        vfpFlushToZero(Fpscr, FpOp1);
997        VfpSavedState state = prepVfpFpscr(Fpscr);
998        fesetround(FeRoundZero);
999        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1000        FpDest.uw = FpOp1;
1001        __asm__ __volatile__("" :: "m" (FpDest.uw));
1002        Fpscr = setVfpFpscr(Fpscr, state);
1003    '''
1004    vcvtFpUIntSIop = InstObjParams("vcvt", "VcvtFpUIntS", "VfpRegRegOp",
1005                                     { "code": vcvtFpUIntSCode,
1006                                       "predicate_test": predicateTest }, [])
1007    header_output += VfpRegRegOpDeclare.subst(vcvtFpUIntSIop);
1008    decoder_output += VfpRegRegOpConstructor.subst(vcvtFpUIntSIop);
1009    exec_output += PredOpExecute.subst(vcvtFpUIntSIop);
1010
1011    vcvtFpUIntDCode = '''
1012        IntDoubleUnion cOp1;
1013        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
1014        vfpFlushToZero(Fpscr, cOp1.fp);
1015        VfpSavedState state = prepVfpFpscr(Fpscr);
1016        fesetround(FeRoundZero);
1017        __asm__ __volatile__("" : "=m" (cOp1.fp) : "m" (cOp1.fp));
1018        uint64_t result = cOp1.fp;
1019        __asm__ __volatile__("" :: "m" (result));
1020        Fpscr = setVfpFpscr(Fpscr, state);
1021        FpDestP0.uw = result;
1022    '''
1023    vcvtFpUIntDIop = InstObjParams("vcvt", "VcvtFpUIntD", "VfpRegRegOp",
1024                                     { "code": vcvtFpUIntDCode,
1025                                       "predicate_test": predicateTest }, [])
1026    header_output += VfpRegRegOpDeclare.subst(vcvtFpUIntDIop);
1027    decoder_output += VfpRegRegOpConstructor.subst(vcvtFpUIntDIop);
1028    exec_output += PredOpExecute.subst(vcvtFpUIntDIop);
1029
1030    vcvtFpSIntSCode = '''
1031        vfpFlushToZero(Fpscr, FpOp1);
1032        VfpSavedState state = prepVfpFpscr(Fpscr);
1033        fesetround(FeRoundZero);
1034        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1035        FpDest.sw = FpOp1;
1036        __asm__ __volatile__("" :: "m" (FpDest.sw));
1037        Fpscr = setVfpFpscr(Fpscr, state);
1038    '''
1039    vcvtFpSIntSIop = InstObjParams("vcvt", "VcvtFpSIntS", "VfpRegRegOp",
1040                                     { "code": vcvtFpSIntSCode,
1041                                       "predicate_test": predicateTest }, [])
1042    header_output += VfpRegRegOpDeclare.subst(vcvtFpSIntSIop);
1043    decoder_output += VfpRegRegOpConstructor.subst(vcvtFpSIntSIop);
1044    exec_output += PredOpExecute.subst(vcvtFpSIntSIop);
1045
1046    vcvtFpSIntDCode = '''
1047        IntDoubleUnion cOp1;
1048        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
1049        vfpFlushToZero(Fpscr, cOp1.fp);
1050        VfpSavedState state = prepVfpFpscr(Fpscr);
1051        fesetround(FeRoundZero);
1052        __asm__ __volatile__("" : "=m" (cOp1.fp) : "m" (cOp1.fp));
1053        int64_t result = cOp1.fp;
1054        __asm__ __volatile__("" :: "m" (result));
1055        Fpscr = setVfpFpscr(Fpscr, state);
1056        FpDestP0.uw = result;
1057    '''
1058    vcvtFpSIntDIop = InstObjParams("vcvt", "VcvtFpSIntD", "VfpRegRegOp",
1059                                     { "code": vcvtFpSIntDCode,
1060                                       "predicate_test": predicateTest }, [])
1061    header_output += VfpRegRegOpDeclare.subst(vcvtFpSIntDIop);
1062    decoder_output += VfpRegRegOpConstructor.subst(vcvtFpSIntDIop);
1063    exec_output += PredOpExecute.subst(vcvtFpSIntDIop);
1064
1065    vcvtFpSFpDCode = '''
1066        IntDoubleUnion cDest;
1067        vfpFlushToZero(Fpscr, FpOp1);
1068        VfpSavedState state = prepVfpFpscr(Fpscr);
1069        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1070        cDest.fp = FpOp1;
1071        __asm__ __volatile__("" :: "m" (cDest.fp));
1072        Fpscr = setVfpFpscr(Fpscr, state);
1073        FpDestP0.uw = cDest.bits;
1074        FpDestP1.uw = cDest.bits >> 32;
1075    '''
1076    vcvtFpSFpDIop = InstObjParams("vcvt", "VcvtFpSFpD", "VfpRegRegOp",
1077                                     { "code": vcvtFpSFpDCode,
1078                                       "predicate_test": predicateTest }, [])
1079    header_output += VfpRegRegOpDeclare.subst(vcvtFpSFpDIop);
1080    decoder_output += VfpRegRegOpConstructor.subst(vcvtFpSFpDIop);
1081    exec_output += PredOpExecute.subst(vcvtFpSFpDIop);
1082
1083    vcvtFpDFpSCode = '''
1084        IntDoubleUnion cOp1;
1085        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
1086        vfpFlushToZero(Fpscr, cOp1.fp);
1087        VfpSavedState state = prepVfpFpscr(Fpscr);
1088        __asm__ __volatile__("" : "=m" (cOp1.fp) : "m" (cOp1.fp));
1089        FpDest = cOp1.fp;
1090        __asm__ __volatile__("" :: "m" (FpDest));
1091        Fpscr = setVfpFpscr(Fpscr, state);
1092    '''
1093    vcvtFpDFpSIop = InstObjParams("vcvt", "VcvtFpDFpS", "VfpRegRegOp",
1094                                     { "code": vcvtFpDFpSCode,
1095                                       "predicate_test": predicateTest }, [])
1096    header_output += VfpRegRegOpDeclare.subst(vcvtFpDFpSIop);
1097    decoder_output += VfpRegRegOpConstructor.subst(vcvtFpDFpSIop);
1098    exec_output += PredOpExecute.subst(vcvtFpDFpSIop);
1099
1100    vcmpSCode = '''
1101        FPSCR fpscr = Fpscr;
1102        vfpFlushToZero(Fpscr, FpDest, FpOp1);
1103        if (FpDest == FpOp1) {
1104            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1105        } else if (FpDest < FpOp1) {
1106            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1107        } else if (FpDest > FpOp1) {
1108            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1109        } else {
1110            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1111        }
1112        Fpscr = fpscr;
1113    '''
1114    vcmpSIop = InstObjParams("vcmps", "VcmpS", "VfpRegRegOp",
1115                                     { "code": vcmpSCode,
1116                                       "predicate_test": predicateTest }, [])
1117    header_output += VfpRegRegOpDeclare.subst(vcmpSIop);
1118    decoder_output += VfpRegRegOpConstructor.subst(vcmpSIop);
1119    exec_output += PredOpExecute.subst(vcmpSIop);
1120
1121    vcmpDCode = '''
1122        IntDoubleUnion cOp1, cDest;
1123        cDest.bits = ((uint64_t)FpDestP0.uw | ((uint64_t)FpDestP1.uw << 32));
1124        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
1125        vfpFlushToZero(Fpscr, cDest.fp, cOp1.fp);
1126        FPSCR fpscr = Fpscr;
1127        if (cDest.fp == cOp1.fp) {
1128            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1129        } else if (cDest.fp < cOp1.fp) {
1130            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1131        } else if (cDest.fp > cOp1.fp) {
1132            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1133        } else {
1134            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1135        }
1136        Fpscr = fpscr;
1137    '''
1138    vcmpDIop = InstObjParams("vcmpd", "VcmpD", "VfpRegRegOp",
1139                                     { "code": vcmpDCode,
1140                                       "predicate_test": predicateTest }, [])
1141    header_output += VfpRegRegOpDeclare.subst(vcmpDIop);
1142    decoder_output += VfpRegRegOpConstructor.subst(vcmpDIop);
1143    exec_output += PredOpExecute.subst(vcmpDIop);
1144
1145    vcmpZeroSCode = '''
1146        FPSCR fpscr = Fpscr;
1147        vfpFlushToZero(Fpscr, FpDest);
1148        if (FpDest == imm) {
1149            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1150        } else if (FpDest < imm) {
1151            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1152        } else if (FpDest > imm) {
1153            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1154        } else {
1155            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1156        }
1157        Fpscr = fpscr;
1158    '''
1159    vcmpZeroSIop = InstObjParams("vcmpZeros", "VcmpZeroS", "VfpRegImmOp",
1160                                     { "code": vcmpZeroSCode,
1161                                       "predicate_test": predicateTest }, [])
1162    header_output += VfpRegImmOpDeclare.subst(vcmpZeroSIop);
1163    decoder_output += VfpRegImmOpConstructor.subst(vcmpZeroSIop);
1164    exec_output += PredOpExecute.subst(vcmpZeroSIop);
1165
1166    vcmpZeroDCode = '''
1167        IntDoubleUnion cDest;
1168        cDest.bits = ((uint64_t)FpDestP0.uw | ((uint64_t)FpDestP1.uw << 32));
1169        vfpFlushToZero(Fpscr, cDest.fp);
1170        FPSCR fpscr = Fpscr;
1171        if (cDest.fp == imm) {
1172            fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0;
1173        } else if (cDest.fp < imm) {
1174            fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0;
1175        } else if (cDest.fp > imm) {
1176            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0;
1177        } else {
1178            fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1;
1179        }
1180        Fpscr = fpscr;
1181    '''
1182    vcmpZeroDIop = InstObjParams("vcmpZerod", "VcmpZeroD", "VfpRegImmOp",
1183                                     { "code": vcmpZeroDCode,
1184                                       "predicate_test": predicateTest }, [])
1185    header_output += VfpRegImmOpDeclare.subst(vcmpZeroDIop);
1186    decoder_output += VfpRegImmOpConstructor.subst(vcmpZeroDIop);
1187    exec_output += PredOpExecute.subst(vcmpZeroDIop);
1188}};
1189
1190let {{
1191
1192    header_output = ""
1193    decoder_output = ""
1194    exec_output = ""
1195
1196    vcvtFpSFixedSCode = '''
1197        vfpFlushToZero(Fpscr, FpOp1);
1198        VfpSavedState state = prepVfpFpscr(Fpscr);
1199        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1200        FpDest.sw = vfpFpSToFixed(FpOp1, true, false, imm);
1201        __asm__ __volatile__("" :: "m" (FpDest.sw));
1202        Fpscr = setVfpFpscr(Fpscr, state);
1203    '''
1204    vcvtFpSFixedSIop = InstObjParams("vcvt", "VcvtFpSFixedS", "VfpRegRegImmOp",
1205                                     { "code": vcvtFpSFixedSCode,
1206                                       "predicate_test": predicateTest }, [])
1207    header_output += VfpRegRegImmOpDeclare.subst(vcvtFpSFixedSIop);
1208    decoder_output += VfpRegRegImmOpConstructor.subst(vcvtFpSFixedSIop);
1209    exec_output += PredOpExecute.subst(vcvtFpSFixedSIop);
1210
1211    vcvtFpSFixedDCode = '''
1212        IntDoubleUnion cOp1;
1213        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
1214        vfpFlushToZero(Fpscr, cOp1.fp);
1215        VfpSavedState state = prepVfpFpscr(Fpscr);
1216        __asm__ __volatile__("" : "=m" (cOp1.fp) : "m" (cOp1.fp));
1217        uint64_t mid = vfpFpDToFixed(cOp1.fp, true, false, imm);
1218        __asm__ __volatile__("" :: "m" (mid));
1219        Fpscr = setVfpFpscr(Fpscr, state);
1220        FpDestP0.uw = mid;
1221        FpDestP1.uw = mid >> 32;
1222    '''
1223    vcvtFpSFixedDIop = InstObjParams("vcvt", "VcvtFpSFixedD", "VfpRegRegImmOp",
1224                                     { "code": vcvtFpSFixedDCode,
1225                                       "predicate_test": predicateTest }, [])
1226    header_output += VfpRegRegImmOpDeclare.subst(vcvtFpSFixedDIop);
1227    decoder_output += VfpRegRegImmOpConstructor.subst(vcvtFpSFixedDIop);
1228    exec_output += PredOpExecute.subst(vcvtFpSFixedDIop);
1229
1230    vcvtFpUFixedSCode = '''
1231        vfpFlushToZero(Fpscr, FpOp1);
1232        VfpSavedState state = prepVfpFpscr(Fpscr);
1233        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1234        FpDest.uw = vfpFpSToFixed(FpOp1, false, false, imm);
1235        __asm__ __volatile__("" :: "m" (FpDest.uw));
1236        Fpscr = setVfpFpscr(Fpscr, state);
1237    '''
1238    vcvtFpUFixedSIop = InstObjParams("vcvt", "VcvtFpUFixedS", "VfpRegRegImmOp",
1239                                     { "code": vcvtFpUFixedSCode,
1240                                       "predicate_test": predicateTest }, [])
1241    header_output += VfpRegRegImmOpDeclare.subst(vcvtFpUFixedSIop);
1242    decoder_output += VfpRegRegImmOpConstructor.subst(vcvtFpUFixedSIop);
1243    exec_output += PredOpExecute.subst(vcvtFpUFixedSIop);
1244
1245    vcvtFpUFixedDCode = '''
1246        IntDoubleUnion cOp1;
1247        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
1248        vfpFlushToZero(Fpscr, cOp1.fp);
1249        VfpSavedState state = prepVfpFpscr(Fpscr);
1250        __asm__ __volatile__("" : "=m" (cOp1.fp) : "m" (cOp1.fp));
1251        uint64_t mid = vfpFpDToFixed(cOp1.fp, false, false, imm);
1252        __asm__ __volatile__("" :: "m" (mid));
1253        Fpscr = setVfpFpscr(Fpscr, state);
1254        FpDestP0.uw = mid;
1255        FpDestP1.uw = mid >> 32;
1256    '''
1257    vcvtFpUFixedDIop = InstObjParams("vcvt", "VcvtFpUFixedD", "VfpRegRegImmOp",
1258                                     { "code": vcvtFpUFixedDCode,
1259                                       "predicate_test": predicateTest }, [])
1260    header_output += VfpRegRegImmOpDeclare.subst(vcvtFpUFixedDIop);
1261    decoder_output += VfpRegRegImmOpConstructor.subst(vcvtFpUFixedDIop);
1262    exec_output += PredOpExecute.subst(vcvtFpUFixedDIop);
1263
1264    vcvtSFixedFpSCode = '''
1265        VfpSavedState state = prepVfpFpscr(Fpscr);
1266        __asm__ __volatile__("" : "=m" (FpOp1.sw) : "m" (FpOp1.sw));
1267        FpDest = vfpSFixedToFpS(FpOp1.sw, false, imm);
1268        __asm__ __volatile__("" :: "m" (FpDest));
1269        Fpscr = setVfpFpscr(Fpscr, state);
1270    '''
1271    vcvtSFixedFpSIop = InstObjParams("vcvt", "VcvtSFixedFpS", "VfpRegRegImmOp",
1272                                     { "code": vcvtSFixedFpSCode,
1273                                       "predicate_test": predicateTest }, [])
1274    header_output += VfpRegRegImmOpDeclare.subst(vcvtSFixedFpSIop);
1275    decoder_output += VfpRegRegImmOpConstructor.subst(vcvtSFixedFpSIop);
1276    exec_output += PredOpExecute.subst(vcvtSFixedFpSIop);
1277
1278    vcvtSFixedFpDCode = '''
1279        IntDoubleUnion cDest;
1280        uint64_t mid = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
1281        VfpSavedState state = prepVfpFpscr(Fpscr);
1282        __asm__ __volatile__("" : "=m" (mid) : "m" (mid));
1283        cDest.fp = vfpSFixedToFpD(mid, false, imm);
1284        __asm__ __volatile__("" :: "m" (cDest.fp));
1285        Fpscr = setVfpFpscr(Fpscr, state);
1286        FpDestP0.uw = cDest.bits;
1287        FpDestP1.uw = cDest.bits >> 32;
1288    '''
1289    vcvtSFixedFpDIop = InstObjParams("vcvt", "VcvtSFixedFpD", "VfpRegRegImmOp",
1290                                     { "code": vcvtSFixedFpDCode,
1291                                       "predicate_test": predicateTest }, [])
1292    header_output += VfpRegRegImmOpDeclare.subst(vcvtSFixedFpDIop);
1293    decoder_output += VfpRegRegImmOpConstructor.subst(vcvtSFixedFpDIop);
1294    exec_output += PredOpExecute.subst(vcvtSFixedFpDIop);
1295
1296    vcvtUFixedFpSCode = '''
1297        VfpSavedState state = prepVfpFpscr(Fpscr);
1298        __asm__ __volatile__("" : "=m" (FpOp1.uw) : "m" (FpOp1.uw));
1299        FpDest = vfpUFixedToFpS(FpOp1.uw, false, imm);
1300        __asm__ __volatile__("" :: "m" (FpDest));
1301        Fpscr = setVfpFpscr(Fpscr, state);
1302    '''
1303    vcvtUFixedFpSIop = InstObjParams("vcvt", "VcvtUFixedFpS", "VfpRegRegImmOp",
1304                                     { "code": vcvtUFixedFpSCode,
1305                                       "predicate_test": predicateTest }, [])
1306    header_output += VfpRegRegImmOpDeclare.subst(vcvtUFixedFpSIop);
1307    decoder_output += VfpRegRegImmOpConstructor.subst(vcvtUFixedFpSIop);
1308    exec_output += PredOpExecute.subst(vcvtUFixedFpSIop);
1309
1310    vcvtUFixedFpDCode = '''
1311        IntDoubleUnion cDest;
1312        uint64_t mid = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
1313        VfpSavedState state = prepVfpFpscr(Fpscr);
1314        __asm__ __volatile__("" : "=m" (mid) : "m" (mid));
1315        cDest.fp = vfpUFixedToFpD(mid, false, imm);
1316        __asm__ __volatile__("" :: "m" (cDest.fp));
1317        Fpscr = setVfpFpscr(Fpscr, state);
1318        FpDestP0.uw = cDest.bits;
1319        FpDestP1.uw = cDest.bits >> 32;
1320    '''
1321    vcvtUFixedFpDIop = InstObjParams("vcvt", "VcvtUFixedFpD", "VfpRegRegImmOp",
1322                                     { "code": vcvtUFixedFpDCode,
1323                                       "predicate_test": predicateTest }, [])
1324    header_output += VfpRegRegImmOpDeclare.subst(vcvtUFixedFpDIop);
1325    decoder_output += VfpRegRegImmOpConstructor.subst(vcvtUFixedFpDIop);
1326    exec_output += PredOpExecute.subst(vcvtUFixedFpDIop);
1327
1328    vcvtFpSHFixedSCode = '''
1329        vfpFlushToZero(Fpscr, FpOp1);
1330        VfpSavedState state = prepVfpFpscr(Fpscr);
1331        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1332        FpDest.sh = vfpFpSToFixed(FpOp1, true, true, imm);
1333        __asm__ __volatile__("" :: "m" (FpDest.sh));
1334        Fpscr = setVfpFpscr(Fpscr, state);
1335    '''
1336    vcvtFpSHFixedSIop = InstObjParams("vcvt", "VcvtFpSHFixedS",
1337                                      "VfpRegRegImmOp",
1338                                     { "code": vcvtFpSHFixedSCode,
1339                                       "predicate_test": predicateTest }, [])
1340    header_output += VfpRegRegImmOpDeclare.subst(vcvtFpSHFixedSIop);
1341    decoder_output += VfpRegRegImmOpConstructor.subst(vcvtFpSHFixedSIop);
1342    exec_output += PredOpExecute.subst(vcvtFpSHFixedSIop);
1343
1344    vcvtFpSHFixedDCode = '''
1345        IntDoubleUnion cOp1;
1346        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
1347        vfpFlushToZero(Fpscr, cOp1.fp);
1348        VfpSavedState state = prepVfpFpscr(Fpscr);
1349        __asm__ __volatile__("" : "=m" (cOp1.fp) : "m" (cOp1.fp));
1350        uint64_t result = vfpFpDToFixed(cOp1.fp, true, true, imm);
1351        __asm__ __volatile__("" :: "m" (result));
1352        Fpscr = setVfpFpscr(Fpscr, state);
1353        FpDestP0.uw = result;
1354        FpDestP1.uw = result >> 32;
1355    '''
1356    vcvtFpSHFixedDIop = InstObjParams("vcvt", "VcvtFpSHFixedD",
1357                                      "VfpRegRegImmOp",
1358                                     { "code": vcvtFpSHFixedDCode,
1359                                       "predicate_test": predicateTest }, [])
1360    header_output += VfpRegRegImmOpDeclare.subst(vcvtFpSHFixedDIop);
1361    decoder_output += VfpRegRegImmOpConstructor.subst(vcvtFpSHFixedDIop);
1362    exec_output += PredOpExecute.subst(vcvtFpSHFixedDIop);
1363
1364    vcvtFpUHFixedSCode = '''
1365        vfpFlushToZero(Fpscr, FpOp1);
1366        VfpSavedState state = prepVfpFpscr(Fpscr);
1367        __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1));
1368        FpDest.uh = vfpFpSToFixed(FpOp1, false, true, imm);
1369        __asm__ __volatile__("" :: "m" (FpDest.uh));
1370        Fpscr = setVfpFpscr(Fpscr, state);
1371    '''
1372    vcvtFpUHFixedSIop = InstObjParams("vcvt", "VcvtFpUHFixedS",
1373                                      "VfpRegRegImmOp",
1374                                     { "code": vcvtFpUHFixedSCode,
1375                                       "predicate_test": predicateTest }, [])
1376    header_output += VfpRegRegImmOpDeclare.subst(vcvtFpUHFixedSIop);
1377    decoder_output += VfpRegRegImmOpConstructor.subst(vcvtFpUHFixedSIop);
1378    exec_output += PredOpExecute.subst(vcvtFpUHFixedSIop);
1379
1380    vcvtFpUHFixedDCode = '''
1381        IntDoubleUnion cOp1;
1382        cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
1383        vfpFlushToZero(Fpscr, cOp1.fp);
1384        VfpSavedState state = prepVfpFpscr(Fpscr);
1385        __asm__ __volatile__("" : "=m" (cOp1.fp) : "m" (cOp1.fp));
1386        uint64_t mid = vfpFpDToFixed(cOp1.fp, false, true, imm);
1387        __asm__ __volatile__("" :: "m" (mid));
1388        Fpscr = setVfpFpscr(Fpscr, state);
1389        FpDestP0.uw = mid;
1390        FpDestP1.uw = mid >> 32;
1391    '''
1392    vcvtFpUHFixedDIop = InstObjParams("vcvt", "VcvtFpUHFixedD",
1393                                      "VfpRegRegImmOp",
1394                                     { "code": vcvtFpUHFixedDCode,
1395                                       "predicate_test": predicateTest }, [])
1396    header_output += VfpRegRegImmOpDeclare.subst(vcvtFpUHFixedDIop);
1397    decoder_output += VfpRegRegImmOpConstructor.subst(vcvtFpUHFixedDIop);
1398    exec_output += PredOpExecute.subst(vcvtFpUHFixedDIop);
1399
1400    vcvtSHFixedFpSCode = '''
1401        VfpSavedState state = prepVfpFpscr(Fpscr);
1402        __asm__ __volatile__("" : "=m" (FpOp1.sh) : "m" (FpOp1.sh));
1403        FpDest = vfpSFixedToFpS(FpOp1.sh, true, imm);
1404        __asm__ __volatile__("" :: "m" (FpDest));
1405        Fpscr = setVfpFpscr(Fpscr, state);
1406    '''
1407    vcvtSHFixedFpSIop = InstObjParams("vcvt", "VcvtSHFixedFpS",
1408                                      "VfpRegRegImmOp",
1409                                     { "code": vcvtSHFixedFpSCode,
1410                                       "predicate_test": predicateTest }, [])
1411    header_output += VfpRegRegImmOpDeclare.subst(vcvtSHFixedFpSIop);
1412    decoder_output += VfpRegRegImmOpConstructor.subst(vcvtSHFixedFpSIop);
1413    exec_output += PredOpExecute.subst(vcvtSHFixedFpSIop);
1414
1415    vcvtSHFixedFpDCode = '''
1416        IntDoubleUnion cDest;
1417        uint64_t mid = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
1418        VfpSavedState state = prepVfpFpscr(Fpscr);
1419        __asm__ __volatile__("" : "=m" (mid) : "m" (mid));
1420        cDest.fp = vfpSFixedToFpD(mid, true, imm);
1421        __asm__ __volatile__("" :: "m" (cDest.fp));
1422        Fpscr = setVfpFpscr(Fpscr, state);
1423        FpDestP0.uw = cDest.bits;
1424        FpDestP1.uw = cDest.bits >> 32;
1425    '''
1426    vcvtSHFixedFpDIop = InstObjParams("vcvt", "VcvtSHFixedFpD",
1427                                      "VfpRegRegImmOp",
1428                                     { "code": vcvtSHFixedFpDCode,
1429                                       "predicate_test": predicateTest }, [])
1430    header_output += VfpRegRegImmOpDeclare.subst(vcvtSHFixedFpDIop);
1431    decoder_output += VfpRegRegImmOpConstructor.subst(vcvtSHFixedFpDIop);
1432    exec_output += PredOpExecute.subst(vcvtSHFixedFpDIop);
1433
1434    vcvtUHFixedFpSCode = '''
1435        VfpSavedState state = prepVfpFpscr(Fpscr);
1436        __asm__ __volatile__("" : "=m" (FpOp1.uh) : "m" (FpOp1.uh));
1437        FpDest = vfpUFixedToFpS(FpOp1.uh, true, imm);
1438        __asm__ __volatile__("" :: "m" (FpDest));
1439        Fpscr = setVfpFpscr(Fpscr, state);
1440    '''
1441    vcvtUHFixedFpSIop = InstObjParams("vcvt", "VcvtUHFixedFpS",
1442                                      "VfpRegRegImmOp",
1443                                     { "code": vcvtUHFixedFpSCode,
1444                                       "predicate_test": predicateTest }, [])
1445    header_output += VfpRegRegImmOpDeclare.subst(vcvtUHFixedFpSIop);
1446    decoder_output += VfpRegRegImmOpConstructor.subst(vcvtUHFixedFpSIop);
1447    exec_output += PredOpExecute.subst(vcvtUHFixedFpSIop);
1448
1449    vcvtUHFixedFpDCode = '''
1450        IntDoubleUnion cDest;
1451        uint64_t mid = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32));
1452        VfpSavedState state = prepVfpFpscr(Fpscr);
1453        __asm__ __volatile__("" : "=m" (mid) : "m" (mid));
1454        cDest.fp = vfpUFixedToFpD(mid, true, imm);
1455        __asm__ __volatile__("" :: "m" (cDest.fp));
1456        Fpscr = setVfpFpscr(Fpscr, state);
1457        FpDestP0.uw = cDest.bits;
1458        FpDestP1.uw = cDest.bits >> 32;
1459    '''
1460    vcvtUHFixedFpDIop = InstObjParams("vcvt", "VcvtUHFixedFpD",
1461                                      "VfpRegRegImmOp",
1462                                     { "code": vcvtUHFixedFpDCode,
1463                                       "predicate_test": predicateTest }, [])
1464    header_output += VfpRegRegImmOpDeclare.subst(vcvtUHFixedFpDIop);
1465    decoder_output += VfpRegRegImmOpConstructor.subst(vcvtUHFixedFpDIop);
1466    exec_output += PredOpExecute.subst(vcvtUHFixedFpDIop);
1467}};
1468