fp.isa revision 7407:70f65d4c7fe3
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            switch (bits(opcode, 1, 0)) {
100              case 0x0:
101                return new VLdmStm(machInst, rn, vd, single,
102                                   true, false, false, offset);
103              case 0x1:
104                return new VLdmStm(machInst, rn, vd, single,
105                                   true, false, true, offset);
106              case 0x2:
107                return new VLdmStm(machInst, rn, vd, single,
108                                   true, true, false, offset);
109              case 0x3:
110                // If rn == sp, then this is called vpop.
111                return new VLdmStm(machInst, rn, vd, single,
112                                   true, true, true, offset);
113            }
114          case 0x2:
115            if (bits(opcode, 1, 0) == 0x2) {
116                // If rn == sp, then this is called vpush.
117                return new VLdmStm(machInst, rn, vd, single,
118                                   false, true, false, offset);
119            } else if (bits(opcode, 1, 0) == 0x3) {
120                return new VLdmStm(machInst, rn, vd, single,
121                                   false, true, true, offset);
122            }
123            // Fall through on purpose
124          case 0x3:
125            const bool up = (bits(machInst, 23) == 1);
126            const uint32_t imm = bits(machInst, 7, 0) << 2;
127            RegIndex vd;
128            if (single) {
129                vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
130                                          (bits(machInst, 22)));
131            } else {
132                vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
133                                          (bits(machInst, 22) << 5));
134            }
135            if (bits(opcode, 1, 0) == 0x0) {
136                if (single) {
137                    if (up) {
138                        return new %(vstr_us)s(machInst, vd, rn, up, imm);
139                    } else {
140                        return new %(vstr_s)s(machInst, vd, rn, up, imm);
141                    }
142                } else {
143                    if (up) {
144                        return new %(vstr_ud)s(machInst, vd, vd + 1,
145                                               rn, up, imm);
146                    } else {
147                        return new %(vstr_d)s(machInst, vd, vd + 1,
148                                              rn, up, imm);
149                    }
150                }
151            } else if (bits(opcode, 1, 0) == 0x1) {
152                if (single) {
153                    if (up) {
154                        return new %(vldr_us)s(machInst, vd, rn, up, imm);
155                    } else {
156                        return new %(vldr_s)s(machInst, vd, rn, up, imm);
157                    }
158                } else {
159                    if (up) {
160                        return new %(vldr_ud)s(machInst, vd, vd + 1,
161                                               rn, up, imm);
162                    } else {
163                        return new %(vldr_d)s(machInst, vd, vd + 1,
164                                              rn, up, imm);
165                    }
166                }
167            }
168        }
169        return new Unknown(machInst);
170    }
171    ''' % {
172        "vldr_us" : "VLDR_" + loadImmClassName(False, True, False),
173        "vldr_s" : "VLDR_" + loadImmClassName(False, False, False),
174        "vldr_ud" : "VLDR_" + loadDoubleImmClassName(False, True, False),
175        "vldr_d" : "VLDR_" + loadDoubleImmClassName(False, False, False),
176        "vstr_us" : "VSTR_" + storeImmClassName(False, True, False),
177        "vstr_s" : "VSTR_" + storeImmClassName(False, False, False),
178        "vstr_ud" : "VSTR_" + storeDoubleImmClassName(False, True, False),
179        "vstr_d" : "VSTR_" + storeDoubleImmClassName(False, False, False)
180    }
181}};
182
183def format ExtensionRegLoadStore() {{
184    decode_block = '''
185    return decodeExtensionRegLoadStore(machInst);
186    '''
187}};
188
189let {{
190    header_output = '''
191    StaticInstPtr
192    decodeShortFpTransfer(ExtMachInst machInst);
193    '''
194    decoder_output = '''
195    StaticInstPtr
196    decodeShortFpTransfer(ExtMachInst machInst)
197    {
198        const uint32_t l = bits(machInst, 20);
199        const uint32_t c = bits(machInst, 8);
200        const uint32_t a = bits(machInst, 23, 21);
201        const uint32_t b = bits(machInst, 6, 5);
202        if ((machInst.thumb == 1 && bits(machInst, 28) == 1) ||
203            (machInst.thumb == 0 && machInst.condCode == 0xf)) {
204            return new Unknown(machInst);
205        }
206        if (l == 0 && c == 0) {
207            if (a == 0) {
208                const uint32_t vn = (bits(machInst, 19, 16) << 1) |
209                                    bits(machInst, 7);
210                const IntRegIndex rt =
211                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
212                if (bits(machInst, 20) == 1) {
213                    return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
214                } else {
215                    return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
216                }
217            } else if (a == 0x7) {
218                const IntRegIndex rt =
219                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
220                uint32_t specReg = bits(machInst, 19, 16);
221                switch (specReg) {
222                  case 0:
223                    specReg = MISCREG_FPSID;
224                    break;
225                  case 1:
226                    specReg = MISCREG_FPSCR;
227                    break;
228                  case 6:
229                    specReg = MISCREG_MVFR1;
230                    break;
231                  case 7:
232                    specReg = MISCREG_MVFR0;
233                    break;
234                  case 8:
235                    specReg = MISCREG_FPEXC;
236                    break;
237                  default:
238                    return new Unknown(machInst);
239                }
240                return new Vmsr(machInst, (IntRegIndex)specReg, rt);
241            }
242        } else if (l == 0 && c == 1) {
243            if (bits(a, 2) == 0) {
244                uint32_t vd = (bits(machInst, 7) << 5) |
245                              (bits(machInst, 19, 16) << 1);
246                uint32_t index, size;
247                const IntRegIndex rt =
248                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
249                if (bits(machInst, 22) == 1) {
250                    size = 8;
251                    index = (bits(machInst, 21) << 2) |
252                            bits(machInst, 6, 5);
253                } else if (bits(machInst, 5) == 1) {
254                    size = 16;
255                    index = (bits(machInst, 21) << 1) |
256                            bits(machInst, 6);
257                } else if (bits(machInst, 6) == 0) {
258                    size = 32;
259                    index = bits(machInst, 21);
260                } else {
261                    return new Unknown(machInst);
262                }
263                if (index >= (32 / size)) {
264                    index -= (32 / size);
265                    vd++;
266                }
267                switch (size) {
268                  case 8:
269                    return new VmovCoreRegB(machInst, (IntRegIndex)vd,
270                                            rt, index);
271                  case 16:
272                    return new VmovCoreRegH(machInst, (IntRegIndex)vd,
273                                            rt, index);
274                  case 32:
275                    return new VmovCoreRegW(machInst, (IntRegIndex)vd, rt);
276                }
277            } else if (bits(b, 1) == 0) {
278                // A8-594
279                return new WarnUnimplemented("vdup", machInst);
280            }
281        } else if (l == 1 && c == 0) {
282            if (a == 0) {
283                const uint32_t vn = (bits(machInst, 19, 16) << 1) |
284                                    bits(machInst, 7);
285                const IntRegIndex rt =
286                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
287                if (bits(machInst, 20) == 1) {
288                    return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
289                } else {
290                    return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
291                }
292            } else if (a == 7) {
293                const IntRegIndex rt =
294                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
295                uint32_t specReg = bits(machInst, 19, 16);
296                switch (specReg) {
297                  case 0:
298                    specReg = MISCREG_FPSID;
299                    break;
300                  case 1:
301                    specReg = MISCREG_FPSCR;
302                    break;
303                  case 6:
304                    specReg = MISCREG_MVFR1;
305                    break;
306                  case 7:
307                    specReg = MISCREG_MVFR0;
308                    break;
309                  case 8:
310                    specReg = MISCREG_FPEXC;
311                    break;
312                  default:
313                    return new Unknown(machInst);
314                }
315                if (rt == 0xf) {
316                    CPSR cpsrMask = 0;
317                    cpsrMask.n = 1;
318                    cpsrMask.z = 1;
319                    cpsrMask.c = 1;
320                    cpsrMask.v = 1;
321                    return new VmrsApsr(machInst, INTREG_CONDCODES,
322                            (IntRegIndex)specReg, (uint32_t)cpsrMask);
323                } else {
324                    return new Vmrs(machInst, rt, (IntRegIndex)specReg);
325                }
326            }
327        } else {
328            uint32_t vd = (bits(machInst, 7) << 5) |
329                          (bits(machInst, 19, 16) << 1);
330            uint32_t index, size;
331            const IntRegIndex rt =
332                (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
333            const bool u = (bits(machInst, 23) == 1);
334            if (bits(machInst, 22) == 1) {
335                size = 8;
336                index = (bits(machInst, 21) << 2) |
337                        bits(machInst, 6, 5);
338            } else if (bits(machInst, 5) == 1) {
339                size = 16;
340                index = (bits(machInst, 21) << 1) |
341                        bits(machInst, 6);
342            } else if (bits(machInst, 6) == 0 && !u) {
343                size = 32;
344                index = bits(machInst, 21);
345            } else {
346                return new Unknown(machInst);
347            }
348            if (index >= (32 / size)) {
349                index -= (32 / size);
350                vd++;
351            }
352            switch (size) {
353              case 8:
354                if (u) {
355                    return new VmovRegCoreUB(machInst, rt,
356                                             (IntRegIndex)vd, index);
357                } else {
358                    return new VmovRegCoreSB(machInst, rt,
359                                             (IntRegIndex)vd, index);
360                }
361              case 16:
362                if (u) {
363                    return new VmovRegCoreUH(machInst, rt,
364                                             (IntRegIndex)vd, index);
365                } else {
366                    return new VmovRegCoreSH(machInst, rt,
367                                             (IntRegIndex)vd, index);
368                }
369              case 32:
370                return new VmovRegCoreW(machInst, rt, (IntRegIndex)vd);
371            }
372        }
373        return new Unknown(machInst);
374    }
375    '''
376}};
377
378def format ShortFpTransfer() {{
379    decode_block = '''
380    return decodeShortFpTransfer(machInst);
381    '''
382}};
383
384let {{
385    header_output = '''
386    StaticInstPtr
387    decodeVfpData(ExtMachInst machInst);
388    '''
389    decoder_output = '''
390    StaticInstPtr
391    decodeVfpData(ExtMachInst machInst)
392    {
393        const uint32_t opc1 = bits(machInst, 23, 20);
394        const uint32_t opc2 = bits(machInst, 19, 16);
395        const uint32_t opc3 = bits(machInst, 7, 6);
396        //const uint32_t opc4 = bits(machInst, 3, 0);
397        const bool single = (bits(machInst, 8) == 0);
398        // Used to select between vcmp and vcmpe.
399        const bool e = (bits(machInst, 7) == 1);
400        IntRegIndex vd;
401        IntRegIndex vm;
402        IntRegIndex vn;
403        if (single) {
404            vd = (IntRegIndex)(bits(machInst, 22) |
405                    (bits(machInst, 15, 12) << 1));
406            vm = (IntRegIndex)(bits(machInst, 5) |
407                    (bits(machInst, 3, 0) << 1));
408            vn = (IntRegIndex)(bits(machInst, 7) |
409                    (bits(machInst, 19, 16) << 1));
410        } else {
411            vd = (IntRegIndex)((bits(machInst, 22) << 5) |
412                    (bits(machInst, 15, 12) << 1));
413            vm = (IntRegIndex)((bits(machInst, 5) << 5) |
414                    (bits(machInst, 3, 0) << 1));
415            vn = (IntRegIndex)((bits(machInst, 7) << 5) |
416                    (bits(machInst, 19, 16) << 1));
417        }
418        switch (opc1 & 0xb /* 1011 */) {
419          case 0x0:
420            if (bits(machInst, 6) == 0) {
421                if (single) {
422                    return decodeVfpRegRegRegOp<VmlaS>(
423                            machInst, vd, vn, vm, false);
424                } else {
425                    return decodeVfpRegRegRegOp<VmlaD>(
426                            machInst, vd, vn, vm, true);
427                }
428            } else {
429                if (single) {
430                    return decodeVfpRegRegRegOp<VmlsS>(
431                            machInst, vd, vn, vm, false);
432                } else {
433                    return decodeVfpRegRegRegOp<VmlsD>(
434                            machInst, vd, vn, vm, true);
435                }
436            }
437          case 0x1:
438            if (bits(machInst, 6) == 1) {
439                if (single) {
440                    return decodeVfpRegRegRegOp<VnmlaS>(
441                            machInst, vd, vn, vm, false);
442                } else {
443                    return decodeVfpRegRegRegOp<VnmlaD>(
444                            machInst, vd, vn, vm, true);
445                }
446            } else {
447                if (single) {
448                    return decodeVfpRegRegRegOp<VnmlsS>(
449                            machInst, vd, vn, vm, false);
450                } else {
451                    return decodeVfpRegRegRegOp<VnmlsD>(
452                            machInst, vd, vn, vm, true);
453                }
454            }
455          case 0x2:
456            if ((opc3 & 0x1) == 0) {
457                if (single) {
458                    return decodeVfpRegRegRegOp<VmulS>(
459                            machInst, vd, vn, vm, false);
460                } else {
461                    return decodeVfpRegRegRegOp<VmulD>(
462                            machInst, vd, vn, vm, true);
463                }
464            } else {
465                if (single) {
466                    return decodeVfpRegRegRegOp<VnmulS>(
467                            machInst, vd, vn, vm, false);
468                } else {
469                    return decodeVfpRegRegRegOp<VnmulD>(
470                            machInst, vd, vn, vm, true);
471                }
472            }
473          case 0x3:
474            if ((opc3 & 0x1) == 0) {
475                if (single) {
476                    return decodeVfpRegRegRegOp<VaddS>(
477                            machInst, vd, vn, vm, false);
478                } else {
479                    return decodeVfpRegRegRegOp<VaddD>(
480                            machInst, vd, vn, vm, true);
481                }
482            } else {
483                if (single) {
484                    return decodeVfpRegRegRegOp<VsubS>(
485                            machInst, vd, vn, vm, false);
486                } else {
487                    return decodeVfpRegRegRegOp<VsubD>(
488                            machInst, vd, vn, vm, true);
489                }
490            }
491          case 0x8:
492            if ((opc3 & 0x1) == 0) {
493                if (single) {
494                    return decodeVfpRegRegRegOp<VdivS>(
495                            machInst, vd, vn, vm, false);
496                } else {
497                    return decodeVfpRegRegRegOp<VdivD>(
498                            machInst, vd, vn, vm, true);
499                }
500            }
501            break;
502          case 0xb:
503            if ((opc3 & 0x1) == 0) {
504                const uint32_t baseImm =
505                    bits(machInst, 3, 0) | (bits(machInst, 19, 16) << 4);
506                if (single) {
507                    uint32_t imm = vfp_modified_imm(baseImm, false);
508                    return decodeVfpRegImmOp<VmovImmS>(
509                            machInst, vd, imm, false);
510                } else {
511                    uint64_t imm = vfp_modified_imm(baseImm, true);
512                    return decodeVfpRegImmOp<VmovImmD>(
513                            machInst, vd, imm, true);
514                }
515            }
516            switch (opc2) {
517              case 0x0:
518                if (opc3 == 1) {
519                    if (single) {
520                        return decodeVfpRegRegOp<VmovRegS>(
521                                machInst, vd, vm, false);
522                    } else {
523                        return decodeVfpRegRegOp<VmovRegD>(
524                                machInst, vd, vm, true);
525                    }
526                } else {
527                    if (single) {
528                        return decodeVfpRegRegOp<VabsS>(
529                                machInst, vd, vm, false);
530                    } else {
531                        return decodeVfpRegRegOp<VabsD>(
532                                machInst, vd, vm, true);
533                    }
534                }
535              case 0x1:
536                if (opc3 == 1) {
537                    if (single) {
538                        return decodeVfpRegRegOp<VnegS>(
539                                machInst, vd, vm, false);
540                    } else {
541                        return decodeVfpRegRegOp<VnegD>(
542                                machInst, vd, vm, true);
543                    }
544                } else {
545                    if (single) {
546                        return decodeVfpRegRegOp<VsqrtS>(
547                                machInst, vd, vm, false);
548                    } else {
549                        return decodeVfpRegRegOp<VsqrtD>(
550                                machInst, vd, vm, true);
551                    }
552                }
553              case 0x2:
554              case 0x3:
555                {
556                    const bool toHalf = bits(machInst, 16);
557                    const bool top = bits(machInst, 7);
558                    if (top) {
559                        if (toHalf) {
560                            return new VcvtFpSFpHT(machInst, vd, vm);
561                        } else {
562                            return new VcvtFpHTFpS(machInst, vd, vm);
563                        }
564                    } else {
565                        if (toHalf) {
566                            return new VcvtFpSFpHB(machInst, vd, vm);
567                        } else {
568                            return new VcvtFpHBFpS(machInst, vd, vm);
569                        }
570                    }
571                }
572              case 0x4:
573                if (single) {
574                    if (e) {
575                        return new VcmpeS(machInst, vd, vm);
576                    } else {
577                        return new VcmpS(machInst, vd, vm);
578                    }
579                } else {
580                    if (e) {
581                        return new VcmpeD(machInst, vd, vm);
582                    } else {
583                        return new VcmpD(machInst, vd, vm);
584                    }
585                }
586              case 0x5:
587                if (single) {
588                    if (e) {
589                        return new VcmpeZeroS(machInst, vd, 0);
590                    } else {
591                        return new VcmpZeroS(machInst, vd, 0);
592                    }
593                } else {
594                    if (e) {
595                        return new VcmpeZeroD(machInst, vd, 0);
596                    } else {
597                        return new VcmpZeroD(machInst, vd, 0);
598                    }
599                }
600              case 0x7:
601                if (opc3 == 0x3) {
602                    if (single) {
603                        vm = (IntRegIndex)(bits(machInst, 5) |
604                                (bits(machInst, 3, 0) << 1));
605                        return new VcvtFpSFpD(machInst, vd, vm);
606                    } else {
607                        vd = (IntRegIndex)(bits(machInst, 22) |
608                                (bits(machInst, 15, 12) << 1));
609                        return new VcvtFpDFpS(machInst, vd, vm);
610                    }
611                }
612                break;
613              case 0x8:
614                if (bits(machInst, 7) == 0) {
615                    if (single) {
616                        return new VcvtUIntFpS(machInst, vd, vm);
617                    } else {
618                        vm = (IntRegIndex)(bits(machInst, 5) |
619                                (bits(machInst, 3, 0) << 1));
620                        return new VcvtUIntFpD(machInst, vd, vm);
621                    }
622                } else {
623                    if (single) {
624                        return new VcvtSIntFpS(machInst, vd, vm);
625                    } else {
626                        vm = (IntRegIndex)(bits(machInst, 5) |
627                                (bits(machInst, 3, 0) << 1));
628                        return new VcvtSIntFpD(machInst, vd, vm);
629                    }
630                }
631              case 0xa:
632                {
633                    const bool half = (bits(machInst, 7) == 0);
634                    const uint32_t imm = bits(machInst, 5) |
635                                         (bits(machInst, 3, 0) << 1);
636                    const uint32_t size =
637                        (bits(machInst, 7) == 0 ? 16 : 32) - imm;
638                    if (single) {
639                        if (half) {
640                            return new VcvtSHFixedFpS(machInst, vd, vd, size);
641                        } else {
642                            return new VcvtSFixedFpS(machInst, vd, vd, size);
643                        }
644                    } else {
645                        if (half) {
646                            return new VcvtSHFixedFpD(machInst, vd, vd, size);
647                        } else {
648                            return new VcvtSFixedFpD(machInst, vd, vd, size);
649                        }
650                    }
651                }
652              case 0xb:
653                {
654                    const bool half = (bits(machInst, 7) == 0);
655                    const uint32_t imm = bits(machInst, 5) |
656                                         (bits(machInst, 3, 0) << 1);
657                    const uint32_t size =
658                        (bits(machInst, 7) == 0 ? 16 : 32) - imm;
659                    if (single) {
660                        if (half) {
661                            return new VcvtUHFixedFpS(machInst, vd, vd, size);
662                        } else {
663                            return new VcvtUFixedFpS(machInst, vd, vd, size);
664                        }
665                    } else {
666                        if (half) {
667                            return new VcvtUHFixedFpD(machInst, vd, vd, size);
668                        } else {
669                            return new VcvtUFixedFpD(machInst, vd, vd, size);
670                        }
671                    }
672                }
673              case 0xc:
674                if (bits(machInst, 7) == 0) {
675                    if (single) {
676                        return new VcvtFpUIntSR(machInst, vd, vm);
677                    } else {
678                        vd = (IntRegIndex)(bits(machInst, 22) |
679                                (bits(machInst, 15, 12) << 1));
680                        return new VcvtFpUIntDR(machInst, vd, vm);
681                    }
682                } else {
683                    if (single) {
684                        return new VcvtFpUIntS(machInst, vd, vm);
685                    } else {
686                        vd = (IntRegIndex)(bits(machInst, 22) |
687                                (bits(machInst, 15, 12) << 1));
688                        return new VcvtFpUIntD(machInst, vd, vm);
689                    }
690                }
691              case 0xd:
692                if (bits(machInst, 7) == 0) {
693                    if (single) {
694                        return new VcvtFpSIntSR(machInst, vd, vm);
695                    } else {
696                        vd = (IntRegIndex)(bits(machInst, 22) |
697                                (bits(machInst, 15, 12) << 1));
698                        return new VcvtFpSIntDR(machInst, vd, vm);
699                    }
700                } else {
701                    if (single) {
702                        return new VcvtFpSIntS(machInst, vd, vm);
703                    } else {
704                        vd = (IntRegIndex)(bits(machInst, 22) |
705                                (bits(machInst, 15, 12) << 1));
706                        return new VcvtFpSIntD(machInst, vd, vm);
707                    }
708                }
709              case 0xe:
710                {
711                    const bool half = (bits(machInst, 7) == 0);
712                    const uint32_t imm = bits(machInst, 5) |
713                                         (bits(machInst, 3, 0) << 1);
714                    const uint32_t size =
715                        (bits(machInst, 7) == 0 ? 16 : 32) - imm;
716                    if (single) {
717                        if (half) {
718                            return new VcvtFpSHFixedS(machInst, vd, vd, size);
719                        } else {
720                            return new VcvtFpSFixedS(machInst, vd, vd, size);
721                        }
722                    } else {
723                        if (half) {
724                            return new VcvtFpSHFixedD(machInst, vd, vd, size);
725                        } else {
726                            return new VcvtFpSFixedD(machInst, vd, vd, size);
727                        }
728                    }
729                }
730              case 0xf:
731                {
732                    const bool half = (bits(machInst, 7) == 0);
733                    const uint32_t imm = bits(machInst, 5) |
734                                         (bits(machInst, 3, 0) << 1);
735                    const uint32_t size =
736                        (bits(machInst, 7) == 0 ? 16 : 32) - imm;
737                    if (single) {
738                        if (half) {
739                            return new VcvtFpUHFixedS(machInst, vd, vd, size);
740                        } else {
741                            return new VcvtFpUFixedS(machInst, vd, vd, size);
742                        }
743                    } else {
744                        if (half) {
745                            return new VcvtFpUHFixedD(machInst, vd, vd, size);
746                        } else {
747                            return new VcvtFpUFixedD(machInst, vd, vd, size);
748                        }
749                    }
750                }
751            }
752            break;
753        }
754        return new Unknown(machInst);
755    }
756    '''
757}};
758
759def format VfpData() {{
760    decode_block = '''
761    return decodeVfpData(machInst);
762    '''
763}};
764