fp.isa revision 7413:18e0f95d1f32
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// Copyright (c) 2007-2008 The Florida State University
16// All rights reserved.
17//
18// Redistribution and use in source and binary forms, with or without
19// modification, are permitted provided that the following conditions are
20// met: redistributions of source code must retain the above copyright
21// notice, this list of conditions and the following disclaimer;
22// redistributions in binary form must reproduce the above copyright
23// notice, this list of conditions and the following disclaimer in the
24// documentation and/or other materials provided with the distribution;
25// neither the name of the copyright holders nor the names of its
26// contributors may be used to endorse or promote products derived from
27// this software without specific prior written permission.
28//
29// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40//
41// Authors: Stephen Hines
42
43////////////////////////////////////////////////////////////////////
44//
45// Floating Point operate instructions
46//
47
48let {{
49    header_output = '''
50    StaticInstPtr
51    decodeExtensionRegLoadStore(ExtMachInst machInst);
52    '''
53    decoder_output = '''
54    StaticInstPtr
55    decodeExtensionRegLoadStore(ExtMachInst machInst)
56    {
57        const uint32_t opcode = bits(machInst, 24, 20);
58        const uint32_t offset = bits(machInst, 7, 0);
59        const bool single = (bits(machInst, 8) == 0);
60        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
61        RegIndex vd;
62        if (single) {
63            vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
64                                      bits(machInst, 22));
65        } else {
66            vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
67                                      (bits(machInst, 22) << 5));
68        }
69        switch (bits(opcode, 4, 3)) {
70          case 0x0:
71            if (bits(opcode, 4, 1) == 0x2 &&
72                    !(machInst.thumb == 1 && bits(machInst, 28) == 1) &&
73                    !(machInst.thumb == 0 && machInst.condCode == 0xf)) {
74                if ((bits(machInst, 7, 4) & 0xd) != 1) {
75                    break;
76                }
77                const IntRegIndex rt =
78                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
79                const IntRegIndex rt2 =
80                    (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
81                const bool op = bits(machInst, 20);
82                uint32_t vm;
83                if (single) {
84                    vm = (bits(machInst, 3, 0) << 1) | bits(machInst, 5);
85                } else {
86                    vm = (bits(machInst, 3, 0) << 1) |
87                         (bits(machInst, 5) << 5);
88                }
89                if (op) {
90                    return new Vmov2Core2Reg(machInst, rt, rt2,
91                                             (IntRegIndex)vm);
92                } else {
93                    return new Vmov2Reg2Core(machInst, (IntRegIndex)vm,
94                                             rt, rt2);
95                }
96            }
97            break;
98          case 0x1:
99            {
100                if (offset == 0 || vd + offset > NumFloatArchRegs) {
101                    break;
102                }
103                switch (bits(opcode, 1, 0)) {
104                  case 0x0:
105                    return new VLdmStm(machInst, rn, vd, single,
106                                       true, false, false, offset);
107                  case 0x1:
108                    return new VLdmStm(machInst, rn, vd, single,
109                                       true, false, true, offset);
110                  case 0x2:
111                    return new VLdmStm(machInst, rn, vd, single,
112                                       true, true, false, offset);
113                  case 0x3:
114                    // If rn == sp, then this is called vpop.
115                    return new VLdmStm(machInst, rn, vd, single,
116                                       true, true, true, offset);
117                }
118            }
119          case 0x2:
120            if (bits(opcode, 1, 0) == 0x2) {
121                // If rn == sp, then this is called vpush.
122                return new VLdmStm(machInst, rn, vd, single,
123                                   false, true, false, offset);
124            } else if (bits(opcode, 1, 0) == 0x3) {
125                return new VLdmStm(machInst, rn, vd, single,
126                                   false, true, true, offset);
127            }
128            // Fall through on purpose
129          case 0x3:
130            const bool up = (bits(machInst, 23) == 1);
131            const uint32_t imm = bits(machInst, 7, 0) << 2;
132            RegIndex vd;
133            if (single) {
134                vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
135                                          (bits(machInst, 22)));
136            } else {
137                vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
138                                          (bits(machInst, 22) << 5));
139            }
140            if (bits(opcode, 1, 0) == 0x0) {
141                if (single) {
142                    if (up) {
143                        return new %(vstr_us)s(machInst, vd, rn, up, imm);
144                    } else {
145                        return new %(vstr_s)s(machInst, vd, rn, up, imm);
146                    }
147                } else {
148                    if (up) {
149                        return new %(vstr_ud)s(machInst, vd, vd + 1,
150                                               rn, up, imm);
151                    } else {
152                        return new %(vstr_d)s(machInst, vd, vd + 1,
153                                              rn, up, imm);
154                    }
155                }
156            } else if (bits(opcode, 1, 0) == 0x1) {
157                if (single) {
158                    if (up) {
159                        return new %(vldr_us)s(machInst, vd, rn, up, imm);
160                    } else {
161                        return new %(vldr_s)s(machInst, vd, rn, up, imm);
162                    }
163                } else {
164                    if (up) {
165                        return new %(vldr_ud)s(machInst, vd, vd + 1,
166                                               rn, up, imm);
167                    } else {
168                        return new %(vldr_d)s(machInst, vd, vd + 1,
169                                              rn, up, imm);
170                    }
171                }
172            }
173        }
174        return new Unknown(machInst);
175    }
176    ''' % {
177        "vldr_us" : "VLDR_" + loadImmClassName(False, True, False),
178        "vldr_s" : "VLDR_" + loadImmClassName(False, False, False),
179        "vldr_ud" : "VLDR_" + loadDoubleImmClassName(False, True, False),
180        "vldr_d" : "VLDR_" + loadDoubleImmClassName(False, False, False),
181        "vstr_us" : "VSTR_" + storeImmClassName(False, True, False),
182        "vstr_s" : "VSTR_" + storeImmClassName(False, False, False),
183        "vstr_ud" : "VSTR_" + storeDoubleImmClassName(False, True, False),
184        "vstr_d" : "VSTR_" + storeDoubleImmClassName(False, False, False)
185    }
186}};
187
188def format ExtensionRegLoadStore() {{
189    decode_block = '''
190    return decodeExtensionRegLoadStore(machInst);
191    '''
192}};
193
194let {{
195    header_output = '''
196    StaticInstPtr
197    decodeShortFpTransfer(ExtMachInst machInst);
198    '''
199    decoder_output = '''
200    StaticInstPtr
201    decodeShortFpTransfer(ExtMachInst machInst)
202    {
203        const uint32_t l = bits(machInst, 20);
204        const uint32_t c = bits(machInst, 8);
205        const uint32_t a = bits(machInst, 23, 21);
206        const uint32_t b = bits(machInst, 6, 5);
207        if ((machInst.thumb == 1 && bits(machInst, 28) == 1) ||
208            (machInst.thumb == 0 && machInst.condCode == 0xf)) {
209            return new Unknown(machInst);
210        }
211        if (l == 0 && c == 0) {
212            if (a == 0) {
213                const uint32_t vn = (bits(machInst, 19, 16) << 1) |
214                                    bits(machInst, 7);
215                const IntRegIndex rt =
216                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
217                if (bits(machInst, 20) == 1) {
218                    return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
219                } else {
220                    return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
221                }
222            } else if (a == 0x7) {
223                const IntRegIndex rt =
224                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
225                uint32_t specReg = bits(machInst, 19, 16);
226                switch (specReg) {
227                  case 0:
228                    specReg = MISCREG_FPSID;
229                    break;
230                  case 1:
231                    specReg = MISCREG_FPSCR;
232                    break;
233                  case 6:
234                    specReg = MISCREG_MVFR1;
235                    break;
236                  case 7:
237                    specReg = MISCREG_MVFR0;
238                    break;
239                  case 8:
240                    specReg = MISCREG_FPEXC;
241                    break;
242                  default:
243                    return new Unknown(machInst);
244                }
245                return new Vmsr(machInst, (IntRegIndex)specReg, rt);
246            }
247        } else if (l == 0 && c == 1) {
248            if (bits(a, 2) == 0) {
249                uint32_t vd = (bits(machInst, 7) << 5) |
250                              (bits(machInst, 19, 16) << 1);
251                uint32_t index, size;
252                const IntRegIndex rt =
253                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
254                if (bits(machInst, 22) == 1) {
255                    size = 8;
256                    index = (bits(machInst, 21) << 2) |
257                            bits(machInst, 6, 5);
258                } else if (bits(machInst, 5) == 1) {
259                    size = 16;
260                    index = (bits(machInst, 21) << 1) |
261                            bits(machInst, 6);
262                } else if (bits(machInst, 6) == 0) {
263                    size = 32;
264                    index = bits(machInst, 21);
265                } else {
266                    return new Unknown(machInst);
267                }
268                if (index >= (32 / size)) {
269                    index -= (32 / size);
270                    vd++;
271                }
272                switch (size) {
273                  case 8:
274                    return new VmovCoreRegB(machInst, (IntRegIndex)vd,
275                                            rt, index);
276                  case 16:
277                    return new VmovCoreRegH(machInst, (IntRegIndex)vd,
278                                            rt, index);
279                  case 32:
280                    return new VmovCoreRegW(machInst, (IntRegIndex)vd, rt);
281                }
282            } else if (bits(b, 1) == 0) {
283                // A8-594
284                return new WarnUnimplemented("vdup", machInst);
285            }
286        } else if (l == 1 && c == 0) {
287            if (a == 0) {
288                const uint32_t vn = (bits(machInst, 19, 16) << 1) |
289                                    bits(machInst, 7);
290                const IntRegIndex rt =
291                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
292                if (bits(machInst, 20) == 1) {
293                    return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
294                } else {
295                    return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
296                }
297            } else if (a == 7) {
298                const IntRegIndex rt =
299                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
300                uint32_t specReg = bits(machInst, 19, 16);
301                switch (specReg) {
302                  case 0:
303                    specReg = MISCREG_FPSID;
304                    break;
305                  case 1:
306                    specReg = MISCREG_FPSCR;
307                    break;
308                  case 6:
309                    specReg = MISCREG_MVFR1;
310                    break;
311                  case 7:
312                    specReg = MISCREG_MVFR0;
313                    break;
314                  case 8:
315                    specReg = MISCREG_FPEXC;
316                    break;
317                  default:
318                    return new Unknown(machInst);
319                }
320                if (rt == 0xf) {
321                    CPSR cpsrMask = 0;
322                    cpsrMask.n = 1;
323                    cpsrMask.z = 1;
324                    cpsrMask.c = 1;
325                    cpsrMask.v = 1;
326                    return new VmrsApsr(machInst, INTREG_CONDCODES,
327                            (IntRegIndex)specReg, (uint32_t)cpsrMask);
328                } else {
329                    return new Vmrs(machInst, rt, (IntRegIndex)specReg);
330                }
331            }
332        } else {
333            uint32_t vd = (bits(machInst, 7) << 5) |
334                          (bits(machInst, 19, 16) << 1);
335            uint32_t index, size;
336            const IntRegIndex rt =
337                (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
338            const bool u = (bits(machInst, 23) == 1);
339            if (bits(machInst, 22) == 1) {
340                size = 8;
341                index = (bits(machInst, 21) << 2) |
342                        bits(machInst, 6, 5);
343            } else if (bits(machInst, 5) == 1) {
344                size = 16;
345                index = (bits(machInst, 21) << 1) |
346                        bits(machInst, 6);
347            } else if (bits(machInst, 6) == 0 && !u) {
348                size = 32;
349                index = bits(machInst, 21);
350            } else {
351                return new Unknown(machInst);
352            }
353            if (index >= (32 / size)) {
354                index -= (32 / size);
355                vd++;
356            }
357            switch (size) {
358              case 8:
359                if (u) {
360                    return new VmovRegCoreUB(machInst, rt,
361                                             (IntRegIndex)vd, index);
362                } else {
363                    return new VmovRegCoreSB(machInst, rt,
364                                             (IntRegIndex)vd, index);
365                }
366              case 16:
367                if (u) {
368                    return new VmovRegCoreUH(machInst, rt,
369                                             (IntRegIndex)vd, index);
370                } else {
371                    return new VmovRegCoreSH(machInst, rt,
372                                             (IntRegIndex)vd, index);
373                }
374              case 32:
375                return new VmovRegCoreW(machInst, rt, (IntRegIndex)vd);
376            }
377        }
378        return new Unknown(machInst);
379    }
380    '''
381}};
382
383def format ShortFpTransfer() {{
384    decode_block = '''
385    return decodeShortFpTransfer(machInst);
386    '''
387}};
388
389let {{
390    header_output = '''
391    StaticInstPtr
392    decodeVfpData(ExtMachInst machInst);
393    '''
394    decoder_output = '''
395    StaticInstPtr
396    decodeVfpData(ExtMachInst machInst)
397    {
398        const uint32_t opc1 = bits(machInst, 23, 20);
399        const uint32_t opc2 = bits(machInst, 19, 16);
400        const uint32_t opc3 = bits(machInst, 7, 6);
401        //const uint32_t opc4 = bits(machInst, 3, 0);
402        const bool single = (bits(machInst, 8) == 0);
403        // Used to select between vcmp and vcmpe.
404        const bool e = (bits(machInst, 7) == 1);
405        IntRegIndex vd;
406        IntRegIndex vm;
407        IntRegIndex vn;
408        if (single) {
409            vd = (IntRegIndex)(bits(machInst, 22) |
410                    (bits(machInst, 15, 12) << 1));
411            vm = (IntRegIndex)(bits(machInst, 5) |
412                    (bits(machInst, 3, 0) << 1));
413            vn = (IntRegIndex)(bits(machInst, 7) |
414                    (bits(machInst, 19, 16) << 1));
415        } else {
416            vd = (IntRegIndex)((bits(machInst, 22) << 5) |
417                    (bits(machInst, 15, 12) << 1));
418            vm = (IntRegIndex)((bits(machInst, 5) << 5) |
419                    (bits(machInst, 3, 0) << 1));
420            vn = (IntRegIndex)((bits(machInst, 7) << 5) |
421                    (bits(machInst, 19, 16) << 1));
422        }
423        switch (opc1 & 0xb /* 1011 */) {
424          case 0x0:
425            if (bits(machInst, 6) == 0) {
426                if (single) {
427                    return decodeVfpRegRegRegOp<VmlaS>(
428                            machInst, vd, vn, vm, false);
429                } else {
430                    return decodeVfpRegRegRegOp<VmlaD>(
431                            machInst, vd, vn, vm, true);
432                }
433            } else {
434                if (single) {
435                    return decodeVfpRegRegRegOp<VmlsS>(
436                            machInst, vd, vn, vm, false);
437                } else {
438                    return decodeVfpRegRegRegOp<VmlsD>(
439                            machInst, vd, vn, vm, true);
440                }
441            }
442          case 0x1:
443            if (bits(machInst, 6) == 1) {
444                if (single) {
445                    return decodeVfpRegRegRegOp<VnmlaS>(
446                            machInst, vd, vn, vm, false);
447                } else {
448                    return decodeVfpRegRegRegOp<VnmlaD>(
449                            machInst, vd, vn, vm, true);
450                }
451            } else {
452                if (single) {
453                    return decodeVfpRegRegRegOp<VnmlsS>(
454                            machInst, vd, vn, vm, false);
455                } else {
456                    return decodeVfpRegRegRegOp<VnmlsD>(
457                            machInst, vd, vn, vm, true);
458                }
459            }
460          case 0x2:
461            if ((opc3 & 0x1) == 0) {
462                if (single) {
463                    return decodeVfpRegRegRegOp<VmulS>(
464                            machInst, vd, vn, vm, false);
465                } else {
466                    return decodeVfpRegRegRegOp<VmulD>(
467                            machInst, vd, vn, vm, true);
468                }
469            } else {
470                if (single) {
471                    return decodeVfpRegRegRegOp<VnmulS>(
472                            machInst, vd, vn, vm, false);
473                } else {
474                    return decodeVfpRegRegRegOp<VnmulD>(
475                            machInst, vd, vn, vm, true);
476                }
477            }
478          case 0x3:
479            if ((opc3 & 0x1) == 0) {
480                if (single) {
481                    return decodeVfpRegRegRegOp<VaddS>(
482                            machInst, vd, vn, vm, false);
483                } else {
484                    return decodeVfpRegRegRegOp<VaddD>(
485                            machInst, vd, vn, vm, true);
486                }
487            } else {
488                if (single) {
489                    return decodeVfpRegRegRegOp<VsubS>(
490                            machInst, vd, vn, vm, false);
491                } else {
492                    return decodeVfpRegRegRegOp<VsubD>(
493                            machInst, vd, vn, vm, true);
494                }
495            }
496          case 0x8:
497            if ((opc3 & 0x1) == 0) {
498                if (single) {
499                    return decodeVfpRegRegRegOp<VdivS>(
500                            machInst, vd, vn, vm, false);
501                } else {
502                    return decodeVfpRegRegRegOp<VdivD>(
503                            machInst, vd, vn, vm, true);
504                }
505            }
506            break;
507          case 0xb:
508            if ((opc3 & 0x1) == 0) {
509                const uint32_t baseImm =
510                    bits(machInst, 3, 0) | (bits(machInst, 19, 16) << 4);
511                if (single) {
512                    uint32_t imm = vfp_modified_imm(baseImm, false);
513                    return decodeVfpRegImmOp<VmovImmS>(
514                            machInst, vd, imm, false);
515                } else {
516                    uint64_t imm = vfp_modified_imm(baseImm, true);
517                    return decodeVfpRegImmOp<VmovImmD>(
518                            machInst, vd, imm, true);
519                }
520            }
521            switch (opc2) {
522              case 0x0:
523                if (opc3 == 1) {
524                    if (single) {
525                        return decodeVfpRegRegOp<VmovRegS>(
526                                machInst, vd, vm, false);
527                    } else {
528                        return decodeVfpRegRegOp<VmovRegD>(
529                                machInst, vd, vm, true);
530                    }
531                } else {
532                    if (single) {
533                        return decodeVfpRegRegOp<VabsS>(
534                                machInst, vd, vm, false);
535                    } else {
536                        return decodeVfpRegRegOp<VabsD>(
537                                machInst, vd, vm, true);
538                    }
539                }
540              case 0x1:
541                if (opc3 == 1) {
542                    if (single) {
543                        return decodeVfpRegRegOp<VnegS>(
544                                machInst, vd, vm, false);
545                    } else {
546                        return decodeVfpRegRegOp<VnegD>(
547                                machInst, vd, vm, true);
548                    }
549                } else {
550                    if (single) {
551                        return decodeVfpRegRegOp<VsqrtS>(
552                                machInst, vd, vm, false);
553                    } else {
554                        return decodeVfpRegRegOp<VsqrtD>(
555                                machInst, vd, vm, true);
556                    }
557                }
558              case 0x2:
559              case 0x3:
560                {
561                    const bool toHalf = bits(machInst, 16);
562                    const bool top = bits(machInst, 7);
563                    if (top) {
564                        if (toHalf) {
565                            return new VcvtFpSFpHT(machInst, vd, vm);
566                        } else {
567                            return new VcvtFpHTFpS(machInst, vd, vm);
568                        }
569                    } else {
570                        if (toHalf) {
571                            return new VcvtFpSFpHB(machInst, vd, vm);
572                        } else {
573                            return new VcvtFpHBFpS(machInst, vd, vm);
574                        }
575                    }
576                }
577              case 0x4:
578                if (single) {
579                    if (e) {
580                        return new VcmpeS(machInst, vd, vm);
581                    } else {
582                        return new VcmpS(machInst, vd, vm);
583                    }
584                } else {
585                    if (e) {
586                        return new VcmpeD(machInst, vd, vm);
587                    } else {
588                        return new VcmpD(machInst, vd, vm);
589                    }
590                }
591              case 0x5:
592                if (single) {
593                    if (e) {
594                        return new VcmpeZeroS(machInst, vd, 0);
595                    } else {
596                        return new VcmpZeroS(machInst, vd, 0);
597                    }
598                } else {
599                    if (e) {
600                        return new VcmpeZeroD(machInst, vd, 0);
601                    } else {
602                        return new VcmpZeroD(machInst, vd, 0);
603                    }
604                }
605              case 0x7:
606                if (opc3 == 0x3) {
607                    if (single) {
608                        vm = (IntRegIndex)(bits(machInst, 5) |
609                                (bits(machInst, 3, 0) << 1));
610                        return new VcvtFpSFpD(machInst, vd, vm);
611                    } else {
612                        vd = (IntRegIndex)(bits(machInst, 22) |
613                                (bits(machInst, 15, 12) << 1));
614                        return new VcvtFpDFpS(machInst, vd, vm);
615                    }
616                }
617                break;
618              case 0x8:
619                if (bits(machInst, 7) == 0) {
620                    if (single) {
621                        return new VcvtUIntFpS(machInst, vd, vm);
622                    } else {
623                        vm = (IntRegIndex)(bits(machInst, 5) |
624                                (bits(machInst, 3, 0) << 1));
625                        return new VcvtUIntFpD(machInst, vd, vm);
626                    }
627                } else {
628                    if (single) {
629                        return new VcvtSIntFpS(machInst, vd, vm);
630                    } else {
631                        vm = (IntRegIndex)(bits(machInst, 5) |
632                                (bits(machInst, 3, 0) << 1));
633                        return new VcvtSIntFpD(machInst, vd, vm);
634                    }
635                }
636              case 0xa:
637                {
638                    const bool half = (bits(machInst, 7) == 0);
639                    const uint32_t imm = bits(machInst, 5) |
640                                         (bits(machInst, 3, 0) << 1);
641                    const uint32_t size =
642                        (bits(machInst, 7) == 0 ? 16 : 32) - imm;
643                    if (single) {
644                        if (half) {
645                            return new VcvtSHFixedFpS(machInst, vd, vd, size);
646                        } else {
647                            return new VcvtSFixedFpS(machInst, vd, vd, size);
648                        }
649                    } else {
650                        if (half) {
651                            return new VcvtSHFixedFpD(machInst, vd, vd, size);
652                        } else {
653                            return new VcvtSFixedFpD(machInst, vd, vd, size);
654                        }
655                    }
656                }
657              case 0xb:
658                {
659                    const bool half = (bits(machInst, 7) == 0);
660                    const uint32_t imm = bits(machInst, 5) |
661                                         (bits(machInst, 3, 0) << 1);
662                    const uint32_t size =
663                        (bits(machInst, 7) == 0 ? 16 : 32) - imm;
664                    if (single) {
665                        if (half) {
666                            return new VcvtUHFixedFpS(machInst, vd, vd, size);
667                        } else {
668                            return new VcvtUFixedFpS(machInst, vd, vd, size);
669                        }
670                    } else {
671                        if (half) {
672                            return new VcvtUHFixedFpD(machInst, vd, vd, size);
673                        } else {
674                            return new VcvtUFixedFpD(machInst, vd, vd, size);
675                        }
676                    }
677                }
678              case 0xc:
679                if (bits(machInst, 7) == 0) {
680                    if (single) {
681                        return new VcvtFpUIntSR(machInst, vd, vm);
682                    } else {
683                        vd = (IntRegIndex)(bits(machInst, 22) |
684                                (bits(machInst, 15, 12) << 1));
685                        return new VcvtFpUIntDR(machInst, vd, vm);
686                    }
687                } else {
688                    if (single) {
689                        return new VcvtFpUIntS(machInst, vd, vm);
690                    } else {
691                        vd = (IntRegIndex)(bits(machInst, 22) |
692                                (bits(machInst, 15, 12) << 1));
693                        return new VcvtFpUIntD(machInst, vd, vm);
694                    }
695                }
696              case 0xd:
697                if (bits(machInst, 7) == 0) {
698                    if (single) {
699                        return new VcvtFpSIntSR(machInst, vd, vm);
700                    } else {
701                        vd = (IntRegIndex)(bits(machInst, 22) |
702                                (bits(machInst, 15, 12) << 1));
703                        return new VcvtFpSIntDR(machInst, vd, vm);
704                    }
705                } else {
706                    if (single) {
707                        return new VcvtFpSIntS(machInst, vd, vm);
708                    } else {
709                        vd = (IntRegIndex)(bits(machInst, 22) |
710                                (bits(machInst, 15, 12) << 1));
711                        return new VcvtFpSIntD(machInst, vd, vm);
712                    }
713                }
714              case 0xe:
715                {
716                    const bool half = (bits(machInst, 7) == 0);
717                    const uint32_t imm = bits(machInst, 5) |
718                                         (bits(machInst, 3, 0) << 1);
719                    const uint32_t size =
720                        (bits(machInst, 7) == 0 ? 16 : 32) - imm;
721                    if (single) {
722                        if (half) {
723                            return new VcvtFpSHFixedS(machInst, vd, vd, size);
724                        } else {
725                            return new VcvtFpSFixedS(machInst, vd, vd, size);
726                        }
727                    } else {
728                        if (half) {
729                            return new VcvtFpSHFixedD(machInst, vd, vd, size);
730                        } else {
731                            return new VcvtFpSFixedD(machInst, vd, vd, size);
732                        }
733                    }
734                }
735              case 0xf:
736                {
737                    const bool half = (bits(machInst, 7) == 0);
738                    const uint32_t imm = bits(machInst, 5) |
739                                         (bits(machInst, 3, 0) << 1);
740                    const uint32_t size =
741                        (bits(machInst, 7) == 0 ? 16 : 32) - imm;
742                    if (single) {
743                        if (half) {
744                            return new VcvtFpUHFixedS(machInst, vd, vd, size);
745                        } else {
746                            return new VcvtFpUFixedS(machInst, vd, vd, size);
747                        }
748                    } else {
749                        if (half) {
750                            return new VcvtFpUHFixedD(machInst, vd, vd, size);
751                        } else {
752                            return new VcvtFpUFixedD(machInst, vd, vd, size);
753                        }
754                    }
755                }
756            }
757            break;
758        }
759        return new Unknown(machInst);
760    }
761    '''
762}};
763
764def format VfpData() {{
765    decode_block = '''
766    return decodeVfpData(machInst);
767    '''
768}};
769