fp.isa revision 7435
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    decodeNeonMem(ExtMachInst machInst);
52
53    StaticInstPtr
54    decodeNeonData(ExtMachInst machInst);
55    '''
56
57    decoder_output = '''
58    StaticInstPtr
59    decodeNeonMem(ExtMachInst machInst)
60    {
61        const uint32_t b = bits(machInst, 11, 8);
62        const bool a = bits(machInst, 23);
63        const bool l = bits(machInst, 21);
64
65        if (l) {
66            // Load instructions.
67            if (a) {
68                switch (b) {
69                }
70                // Single.
71            } else {
72                switch (b) {
73                }
74                // Multiple.
75            }
76        } else {
77            // Store instructions.
78            if (a) {
79                switch (b) {
80                }
81                // Single.
82            } else {
83                switch (b) {
84                }
85                // Multiple.
86            }
87        }
88        return new WarnUnimplemented("neon memory", machInst);
89    }
90    '''
91
92    decoder_output += '''
93    static StaticInstPtr
94    decodeNeonThreeRegistersSameLength(ExtMachInst machInst)
95    {
96        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
97        const uint32_t a = bits(machInst, 11, 8);
98        const bool b = bits(machInst, 4);
99        const uint32_t c = bits(machInst, 21, 20);
100        switch (a) {
101          case 0x0:
102            if (b) {
103                if (bits(machInst, 9) == 0) {
104                    return new WarnUnimplemented("vhadd", machInst);
105                } else {
106                    return new WarnUnimplemented("vhsub", machInst);
107                }
108            } else {
109                return new WarnUnimplemented("vqadd", machInst);
110            }
111          case 0x1:
112            if (!b) {
113                return new WarnUnimplemented("vrhadd", machInst);
114            } else {
115                if (u) {
116                    switch (c) {
117                      case 0:
118                        return new WarnUnimplemented("veor", machInst);
119                      case 1:
120                        return new WarnUnimplemented("vbsl", machInst);
121                      case 2:
122                        return new WarnUnimplemented("vbit", machInst);
123                      case 3:
124                        return new WarnUnimplemented("vbif", machInst);
125                    }
126                } else {
127                    switch (c) {
128                      case 0:
129                        return new WarnUnimplemented("vand (reg)", machInst);
130                      case 1:
131                        return new WarnUnimplemented("vbic (reg)", machInst);
132                      case 2:
133                        {
134                            const IntRegIndex n = (IntRegIndex)(
135                                    (uint32_t)bits(machInst, 19, 16) |
136                                    (uint32_t)(bits(machInst, 7) << 4));
137                            const IntRegIndex m = (IntRegIndex)(
138                                    (uint32_t)bits(machInst, 3, 0) |
139                                    (uint32_t)(bits(machInst, 5) << 4));
140                            if (n == m) {
141                                return new WarnUnimplemented("vmov (reg)",
142                                        machInst);
143                            } else {
144                                return new WarnUnimplemented("vorr (reg)",
145                                        machInst);
146                            }
147                        }
148                      case 3:
149                        return new WarnUnimplemented("vorn (reg)", machInst);
150                    }
151                }
152            }
153          case 0x2:
154            if (b) {
155                return new WarnUnimplemented("vqsub", machInst);
156            } else {
157                if (bits(machInst, 9) == 0) {
158                    return new WarnUnimplemented("vhadd", machInst);
159                } else {
160                    return new WarnUnimplemented("vhsub", machInst);
161                }
162            }
163          case 0x3:
164            if (b) {
165                return new WarnUnimplemented("vcge (reg)", machInst);
166            } else {
167                return new WarnUnimplemented("vcgt (reg)", machInst);
168            }
169          case 0x4:
170            if (b) {
171                return new WarnUnimplemented("vqshl (reg)", machInst);
172            } else {
173                return new WarnUnimplemented("vshl (reg)", machInst);
174            }
175          case 0x5:
176            if (b) {
177                return new WarnUnimplemented("vqrshl", machInst);
178            } else {
179                return new WarnUnimplemented("vrshl", machInst);
180            }
181          case 0x6:
182            if (b) {
183                return new WarnUnimplemented("vmin (int)", machInst);
184            } else {
185                return new WarnUnimplemented("vmax (int)", machInst);
186            }
187          case 0x7:
188            if (b) {
189                return new WarnUnimplemented("vaba", machInst);
190            } else {
191                if (bits(machInst, 23) == 1) {
192                    if (bits(machInst, 6) == 1) {
193                        return new Unknown(machInst);
194                    } else {
195                        return new WarnUnimplemented("vabdl (int)", machInst);
196                    }
197                } else {
198                    return new WarnUnimplemented("vabd (int)", machInst);
199                }
200            }
201          case 0x8:
202            if (b) {
203                if (u) {
204                    return new WarnUnimplemented("vceq (reg)", machInst);
205                } else {
206                    return new WarnUnimplemented("vtst", machInst);
207                }
208            } else {
209                if (u) {
210                    return new WarnUnimplemented("vsub (int)", machInst);
211                } else {
212                    return new WarnUnimplemented("vadd (int)", machInst);
213                }
214            }
215          case 0x9:
216            if (b) {
217                if (u) {
218                    return new WarnUnimplemented("vmul (poly)", machInst);
219                } else {
220                    return new WarnUnimplemented("vmul (int)", machInst);
221                }
222            } else {
223                if (u) {
224                    return new WarnUnimplemented("vmls (int)", machInst);
225                } else {
226                    return new WarnUnimplemented("vmla (int)", machInst);
227                }
228            }
229          case 0xa:
230            if (b) {
231                return new WarnUnimplemented("vpmin (int)", machInst);
232            } else {
233                return new WarnUnimplemented("vpmax (int)", machInst);
234            }
235          case 0xb:
236            if (b) {
237                if (u) {
238                    return new Unknown(machInst);
239                } else {
240                    return new WarnUnimplemented("vpadd (int)", machInst);
241                }
242            } else {
243                if (u) {
244                    return new WarnUnimplemented("vqrdmulh", machInst);
245                } else {
246                    return new WarnUnimplemented("vqdmulh", machInst);
247                }
248            }
249          case 0xc:
250            return new Unknown(machInst);
251          case 0xd:
252            if (b) {
253                if (u) {
254                    if (bits(c, 1) == 0) {
255                        return new WarnUnimplemented("vmul (fp)", machInst);
256                    } else {
257                        return new Unknown(machInst);
258                    }
259                } else {
260                    if (bits(c, 1) == 0) {
261                        return new WarnUnimplemented("vmla (fp)", machInst);
262                    } else {
263                        return new WarnUnimplemented("vmls (fp)", machInst);
264                    }
265                }
266            } else {
267                if (u) {
268                    if (bits(c, 1) == 0) {
269                        return new WarnUnimplemented("vpadd (fp)", machInst);
270                    } else {
271                        return new WarnUnimplemented("vabd (fp)", machInst);
272                    }
273                } else {
274                    if (bits(c, 1) == 0) {
275                        return new WarnUnimplemented("vadd (fp)", machInst);
276                    } else {
277                        return new WarnUnimplemented("vsub (fp)", machInst);
278                    }
279                }
280            }
281          case 0xe:
282            if (b) {
283                if (u) {
284                    if (bits(c, 1) == 0) {
285                        return new WarnUnimplemented("vacge", machInst);
286                    } else {
287                        return new WarnUnimplemented("vacgt", machInst);
288                    }
289                } else {
290                    return new Unknown(machInst);
291                }
292            } else {
293                if (u) {
294                    if (bits(c, 1) == 0) {
295                        return new WarnUnimplemented("vcge (reg)", machInst);
296                    } else {
297                        return new WarnUnimplemented("vcgt (reg)", machInst);
298                    }
299                } else {
300                    if (bits(c, 1) == 0) {
301                        return new WarnUnimplemented("vceq (reg)", machInst);
302                    } else {
303                        return new Unknown(machInst);
304                    }
305                }
306            }
307          case 0xf:
308            if (b) {
309                if (u) {
310                    return new Unknown(machInst);
311                } else {
312                    if (bits(c, 1) == 0) {
313                        return new WarnUnimplemented("vrecps", machInst);
314                    } else {
315                        return new WarnUnimplemented("vrsqrts", machInst);
316                    }
317                }
318            } else {
319                if (u) {
320                    if (bits(c, 1) == 0) {
321                        return new WarnUnimplemented("vpmax (fp)", machInst);
322                    } else {
323                        return new WarnUnimplemented("vpmin (fp)", machInst);
324                    }
325                } else {
326                    if (bits(c, 1) == 0) {
327                        return new WarnUnimplemented("vmax (fp)", machInst);
328                    } else {
329                        return new WarnUnimplemented("vmin (fp)", machInst);
330                    }
331                }
332            }
333        }
334        return new Unknown(machInst);
335    }
336
337    static StaticInstPtr
338    decodeNeonOneRegModImm(ExtMachInst machInst)
339    {
340        const bool op = bits(machInst, 5);
341        const uint32_t cmode = bits(machInst, 11, 8);
342        if (op) {
343            if (bits(cmode, 3) == 0) {
344                if (bits(cmode, 0) == 0) {
345                    return new WarnUnimplemented("vmov (imm)", machInst);
346                } else {
347                    return new WarnUnimplemented("vorr (imm)", machInst);
348                }
349            } else {
350                if (bits(cmode, 2) == 1) {
351                    return new WarnUnimplemented("vmov (imm)", machInst);
352                } else {
353                    if (bits(cmode, 0) == 0) {
354                        return new WarnUnimplemented("vmov (imm)", machInst);
355                    } else {
356                        return new WarnUnimplemented("vorr (imm)", machInst);
357                    }
358                }
359            }
360        } else {
361            if (bits(cmode, 3) == 0) {
362                if (bits(cmode, 0) == 0) {
363                    return new WarnUnimplemented("vmvn (imm)", machInst);
364                } else {
365                    return new WarnUnimplemented("vbic (imm)", machInst);
366                }
367            } else {
368                if (bits(cmode, 2) == 1) {
369                    switch (bits(cmode, 1, 0)) {
370                      case 0:
371                      case 1:
372                        return new WarnUnimplemented("vmvn (imm)", machInst);
373                      case 2:
374                        return new WarnUnimplemented("vmov (imm)", machInst);
375                      case 3:
376                        return new Unknown(machInst);
377                    }
378                    return new WarnUnimplemented("vmov (imm)", machInst);
379                } else {
380                    if (bits(cmode, 0) == 0) {
381                        return new WarnUnimplemented("vmvn (imm)", machInst);
382                    } else {
383                        return new WarnUnimplemented("vbic (imm)", machInst);
384                    }
385                }
386            }
387        }
388        return new Unknown(machInst);
389    }
390
391    static StaticInstPtr
392    decodeNeonTwoRegAndShift(ExtMachInst machInst)
393    {
394        const uint32_t a = bits(machInst, 11, 8);
395        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
396        const bool b = bits(machInst, 6);
397        const bool l = bits(machInst, 7);
398
399        switch (a) {
400          case 0x0:
401            return new WarnUnimplemented("vshr", machInst);
402          case 0x1:
403            return new WarnUnimplemented("vsra", machInst);
404          case 0x2:
405            return new WarnUnimplemented("vrshr", machInst);
406          case 0x3:
407            return new WarnUnimplemented("vrsra", machInst);
408          case 0x4:
409            if (u) {
410                return new WarnUnimplemented("vsri", machInst);
411            } else {
412                return new Unknown(machInst);
413            }
414          case 0x5:
415            if (u) {
416                return new WarnUnimplemented("vsli", machInst);
417            } else {
418                return new WarnUnimplemented("vshl (imm)", machInst);
419            }
420          case 0x6:
421          case 0x7:
422            return new WarnUnimplemented("vqshl, vqshlu (imm)", machInst);
423          case 0x8:
424            if (l) {
425                return new Unknown(machInst);
426            } else if (u) {
427                if (b) {
428                    return new WarnUnimplemented("vqrshrn, vqrshrun", machInst);
429                } else {
430                    return new WarnUnimplemented("vqshrn, vqshrun", machInst);
431                }
432            } else {
433                if (b) {
434                    return new WarnUnimplemented("vrshrn", machInst);
435                } else {
436                    return new WarnUnimplemented("vshrn", machInst);
437                }
438            }
439          case 0x9:
440            if (l) {
441                return new Unknown(machInst);
442            } else if (b) {
443                return new WarnUnimplemented("vqrshrn, vqrshrun", machInst);
444            } else {
445                return new WarnUnimplemented("vqshrn, vqshrun", machInst);
446            }
447          case 0xa:
448            if (l || b) {
449                return new Unknown(machInst);
450            } else {
451                // If the shift amount is zero, it's vmovl.
452                return new WarnUnimplemented("vshll, vmovl", machInst);
453            }
454          case 0xe:
455          case 0xf:
456            if (l) {
457                return new Unknown(machInst);
458            } else if (a == 0xe) {
459                return new WarnUnimplemented("vcvt (fixed to fp)", machInst);
460            } else if (a == 0xf) {
461                return new WarnUnimplemented("vcvt (fp to fixed)", machInst);
462            }
463        }
464        return new Unknown(machInst);
465    }
466
467    static StaticInstPtr
468    decodeNeonThreeRegDiffLengths(ExtMachInst machInst)
469    {
470        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
471        const uint32_t a = bits(machInst, 11, 8);
472
473        switch (a) {
474          case 0x0:
475            return new WarnUnimplemented("vaddl", machInst);
476          case 0x1:
477            return new WarnUnimplemented("vaddw", machInst);
478          case 0x2:
479            return new WarnUnimplemented("vsubl", machInst);
480          case 0x3:
481            return new WarnUnimplemented("vsubw", machInst);
482          case 0x4:
483            if (u) {
484                return new WarnUnimplemented("vraddhn", machInst);
485            } else {
486                return new WarnUnimplemented("vaddhn", machInst);
487            }
488          case 0x5:
489            return new WarnUnimplemented("vabal", machInst);
490          case 0x6:
491            if (u) {
492                return new WarnUnimplemented("vrsubhn", machInst);
493            } else {
494                return new WarnUnimplemented("vsubhn", machInst);
495            }
496          case 0x7:
497            if (bits(machInst, 23)) {
498                return new WarnUnimplemented("vabdl (int)", machInst);
499            } else {
500                return new WarnUnimplemented("vabd (int)", machInst);
501            }
502          case 0x8:
503            return new WarnUnimplemented("vmlal (int)", machInst);
504          case 0xa:
505            return new WarnUnimplemented("vmlsl (int)", machInst);
506          case 0x9:
507            if (bits(machInst, 23) == 0) {
508                if (bits(machInst, 4) == 0) {
509                    if (u) {
510                        return new WarnUnimplemented("vmls (int)", machInst);
511                    } else {
512                        return new WarnUnimplemented("vmla (int)", machInst);
513                    }
514                } else {
515                    if (u) {
516                        return new WarnUnimplemented("vmul (poly)", machInst);
517                    } else {
518                        return new WarnUnimplemented("vmul (int)", machInst);
519                    }
520                }
521            } else {
522                return new WarnUnimplemented("vqdmlal", machInst);
523            }
524          case 0xb:
525            if (!u) {
526                return new Unknown(machInst);
527            } else {
528                return new WarnUnimplemented("vqdmlsl", machInst);
529            }
530          case 0xc:
531            return new WarnUnimplemented("vmull (int)", machInst);
532          case 0xd:
533            if (!u) {
534                return new Unknown(machInst);
535            } else {
536                return new WarnUnimplemented("vqdmull", machInst);
537            }
538          case 0xe:
539            return new WarnUnimplemented("vmull (poly)", machInst);
540        }
541        return new Unknown(machInst);
542    }
543
544    static StaticInstPtr
545    decodeNeonTwoRegScalar(ExtMachInst machInst)
546    {
547        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
548        const uint32_t a = bits(machInst, 11, 8);
549
550        switch (a) {
551          case 0x0:
552            return new WarnUnimplemented("vmla (int scalar)", machInst);
553          case 0x1:
554            return new WarnUnimplemented("vmla (fp scalar)", machInst);
555          case 0x4:
556            return new WarnUnimplemented("vmls (int scalar)", machInst);
557          case 0x5:
558            return new WarnUnimplemented("vmls (fp scalar)", machInst);
559          case 0x2:
560            return new WarnUnimplemented("vmlal (scalar)", machInst);
561          case 0x6:
562            return new WarnUnimplemented("vmlsl (scalar)", machInst);
563          case 0x3:
564            if (u) {
565                return new Unknown(machInst);
566            } else {
567                return new WarnUnimplemented("vqdmlal", machInst);
568            }
569          case 0x7:
570            if (u) {
571                return new Unknown(machInst);
572            } else {
573                return new WarnUnimplemented("vqdmlsl", machInst);
574            }
575          case 0x8:
576            return new WarnUnimplemented("vmul (int scalar)", machInst);
577          case 0x9:
578            return new WarnUnimplemented("vmul (fp scalar)", machInst);
579          case 0xa:
580            return new WarnUnimplemented("vmull (scalar)", machInst);
581          case 0xb:
582            if (u) {
583                return new Unknown(machInst);
584            } else {
585                return new WarnUnimplemented("vqdmull", machInst);
586            }
587          case 0xc:
588            return new WarnUnimplemented("vqdmulh", machInst);
589          case 0xd:
590            return new WarnUnimplemented("vqrdmulh", machInst);
591        }
592        return new Unknown(machInst);
593    }
594
595    static StaticInstPtr
596    decodeNeonTwoRegMisc(ExtMachInst machInst)
597    {
598        const uint32_t a = bits(machInst, 17, 16);
599        const uint32_t b = bits(machInst, 10, 6);
600        switch (a) {
601          case 0x0:
602            switch (bits(b, 4, 1)) {
603              case 0x0:
604                return new WarnUnimplemented("vrev64", machInst);
605              case 0x1:
606                return new WarnUnimplemented("vrev32", machInst);
607              case 0x2:
608                return new WarnUnimplemented("vrev16", machInst);
609              case 0x4:
610              case 0x5:
611                return new WarnUnimplemented("vpaddl", machInst);
612              case 0x8:
613                return new WarnUnimplemented("vcls", machInst);
614              case 0x9:
615                return new WarnUnimplemented("vclz", machInst);
616              case 0xa:
617                return new WarnUnimplemented("vcnt", machInst);
618              case 0xb:
619                return new WarnUnimplemented("vmvn (reg)", machInst);
620              case 0xc:
621              case 0xd:
622                return new WarnUnimplemented("vpadal", machInst);
623              case 0xe:
624                return new WarnUnimplemented("vqabs", machInst);
625              case 0xf:
626                return new WarnUnimplemented("vqneg", machInst);
627              default:
628                return new Unknown(machInst);
629            }
630          case 0x1:
631            switch (bits(b, 3, 1)) {
632              case 0x0:
633                return new WarnUnimplemented("vcgt (imm #0)", machInst);
634              case 0x1:
635                return new WarnUnimplemented("vcge (imm #0)", machInst);
636              case 0x2:
637                return new WarnUnimplemented("vceq (imm #0)", machInst);
638              case 0x3:
639                return new WarnUnimplemented("vcle (imm #0)", machInst);
640              case 0x4:
641                return new WarnUnimplemented("vclt (imm #0)", machInst);
642              case 0x6:
643                return new WarnUnimplemented("vabs (imm #0)", machInst);
644              case 0x7:
645                return new WarnUnimplemented("vneg (imm #0)", machInst);
646            }
647          case 0x2:
648            switch (bits(b, 4, 1)) {
649              case 0x0:
650                return new WarnUnimplemented("vswp", machInst);
651              case 0x1:
652                return new WarnUnimplemented("vtrn", machInst);
653              case 0x2:
654                return new WarnUnimplemented("vuzp", machInst);
655              case 0x3:
656                return new WarnUnimplemented("vzip", machInst);
657              case 0x4:
658                if (b == 0x8) {
659                    return new WarnUnimplemented("vmovn", machInst);
660                } else {
661                    return new WarnUnimplemented("vqmovun", machInst);
662                }
663              case 0x5:
664                return new WarnUnimplemented("vqmovn", machInst);
665              case 0x6:
666                if (b == 0xc) {
667                    return new WarnUnimplemented("vshll", machInst);
668                } else {
669                    return new Unknown(machInst);
670                }
671              case 0xc:
672              case 0xe:
673                if (b == 0x18) {
674                    return new WarnUnimplemented("vcvt (single to half)",
675                            machInst);
676                } else if (b == 0x1c) {
677                    return new WarnUnimplemented("vcvt (half to single)",
678                            machInst);
679                } else {
680                    return new Unknown(machInst);
681                }
682              default:
683                return new Unknown(machInst);
684            }
685          case 0x3:
686            if (bits(b, 4, 3) == 0x3) {
687                return new WarnUnimplemented("vcvt (fp and int)", machInst);
688            } else if ((b & 0x1a) == 0x10) {
689                return new WarnUnimplemented("vrecpe", machInst);
690            } else if ((b & 0x1a) == 0x12) {
691                return new WarnUnimplemented("vrsqrte", machInst);
692            } else {
693                return new Unknown(machInst);
694            }
695        }
696        return new Unknown(machInst);
697    }
698
699    StaticInstPtr
700    decodeNeonData(ExtMachInst machInst)
701    {
702        const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
703        const uint32_t a = bits(machInst, 23, 19);
704        const uint32_t b = bits(machInst, 11, 8);
705        const uint32_t c = bits(machInst, 7, 4);
706        if (bits(a, 4) == 0) {
707            return decodeNeonThreeRegistersSameLength(machInst);
708        } else if ((c & 0x9) == 1) {
709            if ((a & 0x7) == 0) {
710                return decodeNeonOneRegModImm(machInst);
711            } else {
712                return decodeNeonTwoRegAndShift(machInst);
713            }
714        } else if ((c & 0x9) == 9) {
715            return decodeNeonTwoRegAndShift(machInst);
716        } else if ((c & 0x5) == 0) {
717            if (bits(a, 3, 2) != 0x3) {
718                return decodeNeonThreeRegDiffLengths(machInst);
719            }
720        } else if ((c & 0x5) == 4) {
721            if (bits(a, 3, 2) != 0x3) {
722                return decodeNeonTwoRegScalar(machInst);
723            }
724        } else if ((a & 0x16) == 0x16) {
725            if (!u) {
726                if (bits(c, 0) == 0) {
727                    return new WarnUnimplemented("vext", machInst);
728                }
729            } else if (bits(b, 3) == 0 && bits(c, 0) == 0) {
730                return decodeNeonTwoRegMisc(machInst);
731            } else if (bits(b, 3, 2) == 0x2 && bits(c, 0) == 0) {
732                if (bits(machInst, 6) == 0) {
733                    return new WarnUnimplemented("vtbl", machInst);
734                } else {
735                    return new WarnUnimplemented("vtbx", machInst);
736                }
737            } else if (b == 0xc && (c & 0x9) == 0) {
738                return new WarnUnimplemented("vdup (scalar)", machInst);
739            }
740        }
741        return new Unknown(machInst);
742    }
743    '''
744}};
745
746def format ThumbNeonMem() {{
747    decode_block = '''
748    return decodeNeonMem(machInst);
749    '''
750}};
751
752def format ThumbNeonData() {{
753    decode_block = '''
754    return decodeNeonMem(machInst);
755    '''
756}};
757
758let {{
759    header_output = '''
760    StaticInstPtr
761    decodeExtensionRegLoadStore(ExtMachInst machInst);
762    '''
763    decoder_output = '''
764    StaticInstPtr
765    decodeExtensionRegLoadStore(ExtMachInst machInst)
766    {
767        const uint32_t opcode = bits(machInst, 24, 20);
768        const uint32_t offset = bits(machInst, 7, 0);
769        const bool single = (bits(machInst, 8) == 0);
770        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
771        RegIndex vd;
772        if (single) {
773            vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
774                                      bits(machInst, 22));
775        } else {
776            vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
777                                      (bits(machInst, 22) << 5));
778        }
779        switch (bits(opcode, 4, 3)) {
780          case 0x0:
781            if (bits(opcode, 4, 1) == 0x2 &&
782                    !(machInst.thumb == 1 && bits(machInst, 28) == 1) &&
783                    !(machInst.thumb == 0 && machInst.condCode == 0xf)) {
784                if ((bits(machInst, 7, 4) & 0xd) != 1) {
785                    break;
786                }
787                const IntRegIndex rt =
788                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
789                const IntRegIndex rt2 =
790                    (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
791                const bool op = bits(machInst, 20);
792                uint32_t vm;
793                if (single) {
794                    vm = (bits(machInst, 3, 0) << 1) | bits(machInst, 5);
795                } else {
796                    vm = (bits(machInst, 3, 0) << 1) |
797                         (bits(machInst, 5) << 5);
798                }
799                if (op) {
800                    return new Vmov2Core2Reg(machInst, rt, rt2,
801                                             (IntRegIndex)vm);
802                } else {
803                    return new Vmov2Reg2Core(machInst, (IntRegIndex)vm,
804                                             rt, rt2);
805                }
806            }
807            break;
808          case 0x1:
809            {
810                if (offset == 0 || vd + offset > NumFloatArchRegs) {
811                    break;
812                }
813                switch (bits(opcode, 1, 0)) {
814                  case 0x0:
815                    return new VLdmStm(machInst, rn, vd, single,
816                                       true, false, false, offset);
817                  case 0x1:
818                    return new VLdmStm(machInst, rn, vd, single,
819                                       true, false, true, offset);
820                  case 0x2:
821                    return new VLdmStm(machInst, rn, vd, single,
822                                       true, true, false, offset);
823                  case 0x3:
824                    // If rn == sp, then this is called vpop.
825                    return new VLdmStm(machInst, rn, vd, single,
826                                       true, true, true, offset);
827                }
828            }
829          case 0x2:
830            if (bits(opcode, 1, 0) == 0x2) {
831                // If rn == sp, then this is called vpush.
832                return new VLdmStm(machInst, rn, vd, single,
833                                   false, true, false, offset);
834            } else if (bits(opcode, 1, 0) == 0x3) {
835                return new VLdmStm(machInst, rn, vd, single,
836                                   false, true, true, offset);
837            }
838            // Fall through on purpose
839          case 0x3:
840            const bool up = (bits(machInst, 23) == 1);
841            const uint32_t imm = bits(machInst, 7, 0) << 2;
842            RegIndex vd;
843            if (single) {
844                vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
845                                          (bits(machInst, 22)));
846            } else {
847                vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
848                                          (bits(machInst, 22) << 5));
849            }
850            if (bits(opcode, 1, 0) == 0x0) {
851                if (single) {
852                    if (up) {
853                        return new %(vstr_us)s(machInst, vd, rn, up, imm);
854                    } else {
855                        return new %(vstr_s)s(machInst, vd, rn, up, imm);
856                    }
857                } else {
858                    if (up) {
859                        return new %(vstr_ud)s(machInst, vd, vd + 1,
860                                               rn, up, imm);
861                    } else {
862                        return new %(vstr_d)s(machInst, vd, vd + 1,
863                                              rn, up, imm);
864                    }
865                }
866            } else if (bits(opcode, 1, 0) == 0x1) {
867                if (single) {
868                    if (up) {
869                        return new %(vldr_us)s(machInst, vd, rn, up, imm);
870                    } else {
871                        return new %(vldr_s)s(machInst, vd, rn, up, imm);
872                    }
873                } else {
874                    if (up) {
875                        return new %(vldr_ud)s(machInst, vd, vd + 1,
876                                               rn, up, imm);
877                    } else {
878                        return new %(vldr_d)s(machInst, vd, vd + 1,
879                                              rn, up, imm);
880                    }
881                }
882            }
883        }
884        return new Unknown(machInst);
885    }
886    ''' % {
887        "vldr_us" : "VLDR_" + loadImmClassName(False, True, False),
888        "vldr_s" : "VLDR_" + loadImmClassName(False, False, False),
889        "vldr_ud" : "VLDR_" + loadDoubleImmClassName(False, True, False),
890        "vldr_d" : "VLDR_" + loadDoubleImmClassName(False, False, False),
891        "vstr_us" : "VSTR_" + storeImmClassName(False, True, False),
892        "vstr_s" : "VSTR_" + storeImmClassName(False, False, False),
893        "vstr_ud" : "VSTR_" + storeDoubleImmClassName(False, True, False),
894        "vstr_d" : "VSTR_" + storeDoubleImmClassName(False, False, False)
895    }
896}};
897
898def format ExtensionRegLoadStore() {{
899    decode_block = '''
900    return decodeExtensionRegLoadStore(machInst);
901    '''
902}};
903
904let {{
905    header_output = '''
906    StaticInstPtr
907    decodeShortFpTransfer(ExtMachInst machInst);
908    '''
909    decoder_output = '''
910    StaticInstPtr
911    decodeShortFpTransfer(ExtMachInst machInst)
912    {
913        const uint32_t l = bits(machInst, 20);
914        const uint32_t c = bits(machInst, 8);
915        const uint32_t a = bits(machInst, 23, 21);
916        const uint32_t b = bits(machInst, 6, 5);
917        if ((machInst.thumb == 1 && bits(machInst, 28) == 1) ||
918            (machInst.thumb == 0 && machInst.condCode == 0xf)) {
919            return new Unknown(machInst);
920        }
921        if (l == 0 && c == 0) {
922            if (a == 0) {
923                const uint32_t vn = (bits(machInst, 19, 16) << 1) |
924                                    bits(machInst, 7);
925                const IntRegIndex rt =
926                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
927                if (bits(machInst, 20) == 1) {
928                    return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
929                } else {
930                    return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
931                }
932            } else if (a == 0x7) {
933                const IntRegIndex rt =
934                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
935                uint32_t specReg = bits(machInst, 19, 16);
936                switch (specReg) {
937                  case 0:
938                    specReg = MISCREG_FPSID;
939                    break;
940                  case 1:
941                    specReg = MISCREG_FPSCR;
942                    break;
943                  case 6:
944                    specReg = MISCREG_MVFR1;
945                    break;
946                  case 7:
947                    specReg = MISCREG_MVFR0;
948                    break;
949                  case 8:
950                    specReg = MISCREG_FPEXC;
951                    break;
952                  default:
953                    return new Unknown(machInst);
954                }
955                return new Vmsr(machInst, (IntRegIndex)specReg, rt);
956            }
957        } else if (l == 0 && c == 1) {
958            if (bits(a, 2) == 0) {
959                uint32_t vd = (bits(machInst, 7) << 5) |
960                              (bits(machInst, 19, 16) << 1);
961                uint32_t index, size;
962                const IntRegIndex rt =
963                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
964                if (bits(machInst, 22) == 1) {
965                    size = 8;
966                    index = (bits(machInst, 21) << 2) |
967                            bits(machInst, 6, 5);
968                } else if (bits(machInst, 5) == 1) {
969                    size = 16;
970                    index = (bits(machInst, 21) << 1) |
971                            bits(machInst, 6);
972                } else if (bits(machInst, 6) == 0) {
973                    size = 32;
974                    index = bits(machInst, 21);
975                } else {
976                    return new Unknown(machInst);
977                }
978                if (index >= (32 / size)) {
979                    index -= (32 / size);
980                    vd++;
981                }
982                switch (size) {
983                  case 8:
984                    return new VmovCoreRegB(machInst, (IntRegIndex)vd,
985                                            rt, index);
986                  case 16:
987                    return new VmovCoreRegH(machInst, (IntRegIndex)vd,
988                                            rt, index);
989                  case 32:
990                    return new VmovCoreRegW(machInst, (IntRegIndex)vd, rt);
991                }
992            } else if (bits(b, 1) == 0) {
993                // A8-594
994                return new WarnUnimplemented("vdup", machInst);
995            }
996        } else if (l == 1 && c == 0) {
997            if (a == 0) {
998                const uint32_t vn = (bits(machInst, 19, 16) << 1) |
999                                    bits(machInst, 7);
1000                const IntRegIndex rt =
1001                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1002                if (bits(machInst, 20) == 1) {
1003                    return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
1004                } else {
1005                    return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
1006                }
1007            } else if (a == 7) {
1008                const IntRegIndex rt =
1009                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1010                uint32_t specReg = bits(machInst, 19, 16);
1011                switch (specReg) {
1012                  case 0:
1013                    specReg = MISCREG_FPSID;
1014                    break;
1015                  case 1:
1016                    specReg = MISCREG_FPSCR;
1017                    break;
1018                  case 6:
1019                    specReg = MISCREG_MVFR1;
1020                    break;
1021                  case 7:
1022                    specReg = MISCREG_MVFR0;
1023                    break;
1024                  case 8:
1025                    specReg = MISCREG_FPEXC;
1026                    break;
1027                  default:
1028                    return new Unknown(machInst);
1029                }
1030                if (rt == 0xf) {
1031                    CPSR cpsrMask = 0;
1032                    cpsrMask.n = 1;
1033                    cpsrMask.z = 1;
1034                    cpsrMask.c = 1;
1035                    cpsrMask.v = 1;
1036                    return new VmrsApsr(machInst, INTREG_CONDCODES,
1037                            (IntRegIndex)specReg, (uint32_t)cpsrMask);
1038                } else {
1039                    return new Vmrs(machInst, rt, (IntRegIndex)specReg);
1040                }
1041            }
1042        } else {
1043            uint32_t vd = (bits(machInst, 7) << 5) |
1044                          (bits(machInst, 19, 16) << 1);
1045            uint32_t index, size;
1046            const IntRegIndex rt =
1047                (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1048            const bool u = (bits(machInst, 23) == 1);
1049            if (bits(machInst, 22) == 1) {
1050                size = 8;
1051                index = (bits(machInst, 21) << 2) |
1052                        bits(machInst, 6, 5);
1053            } else if (bits(machInst, 5) == 1) {
1054                size = 16;
1055                index = (bits(machInst, 21) << 1) |
1056                        bits(machInst, 6);
1057            } else if (bits(machInst, 6) == 0 && !u) {
1058                size = 32;
1059                index = bits(machInst, 21);
1060            } else {
1061                return new Unknown(machInst);
1062            }
1063            if (index >= (32 / size)) {
1064                index -= (32 / size);
1065                vd++;
1066            }
1067            switch (size) {
1068              case 8:
1069                if (u) {
1070                    return new VmovRegCoreUB(machInst, rt,
1071                                             (IntRegIndex)vd, index);
1072                } else {
1073                    return new VmovRegCoreSB(machInst, rt,
1074                                             (IntRegIndex)vd, index);
1075                }
1076              case 16:
1077                if (u) {
1078                    return new VmovRegCoreUH(machInst, rt,
1079                                             (IntRegIndex)vd, index);
1080                } else {
1081                    return new VmovRegCoreSH(machInst, rt,
1082                                             (IntRegIndex)vd, index);
1083                }
1084              case 32:
1085                return new VmovRegCoreW(machInst, rt, (IntRegIndex)vd);
1086            }
1087        }
1088        return new Unknown(machInst);
1089    }
1090    '''
1091}};
1092
1093def format ShortFpTransfer() {{
1094    decode_block = '''
1095    return decodeShortFpTransfer(machInst);
1096    '''
1097}};
1098
1099let {{
1100    header_output = '''
1101    StaticInstPtr
1102    decodeVfpData(ExtMachInst machInst);
1103    '''
1104    decoder_output = '''
1105    StaticInstPtr
1106    decodeVfpData(ExtMachInst machInst)
1107    {
1108        const uint32_t opc1 = bits(machInst, 23, 20);
1109        const uint32_t opc2 = bits(machInst, 19, 16);
1110        const uint32_t opc3 = bits(machInst, 7, 6);
1111        //const uint32_t opc4 = bits(machInst, 3, 0);
1112        const bool single = (bits(machInst, 8) == 0);
1113        // Used to select between vcmp and vcmpe.
1114        const bool e = (bits(machInst, 7) == 1);
1115        IntRegIndex vd;
1116        IntRegIndex vm;
1117        IntRegIndex vn;
1118        if (single) {
1119            vd = (IntRegIndex)(bits(machInst, 22) |
1120                    (bits(machInst, 15, 12) << 1));
1121            vm = (IntRegIndex)(bits(machInst, 5) |
1122                    (bits(machInst, 3, 0) << 1));
1123            vn = (IntRegIndex)(bits(machInst, 7) |
1124                    (bits(machInst, 19, 16) << 1));
1125        } else {
1126            vd = (IntRegIndex)((bits(machInst, 22) << 5) |
1127                    (bits(machInst, 15, 12) << 1));
1128            vm = (IntRegIndex)((bits(machInst, 5) << 5) |
1129                    (bits(machInst, 3, 0) << 1));
1130            vn = (IntRegIndex)((bits(machInst, 7) << 5) |
1131                    (bits(machInst, 19, 16) << 1));
1132        }
1133        switch (opc1 & 0xb /* 1011 */) {
1134          case 0x0:
1135            if (bits(machInst, 6) == 0) {
1136                if (single) {
1137                    return decodeVfpRegRegRegOp<VmlaS>(
1138                            machInst, vd, vn, vm, false);
1139                } else {
1140                    return decodeVfpRegRegRegOp<VmlaD>(
1141                            machInst, vd, vn, vm, true);
1142                }
1143            } else {
1144                if (single) {
1145                    return decodeVfpRegRegRegOp<VmlsS>(
1146                            machInst, vd, vn, vm, false);
1147                } else {
1148                    return decodeVfpRegRegRegOp<VmlsD>(
1149                            machInst, vd, vn, vm, true);
1150                }
1151            }
1152          case 0x1:
1153            if (bits(machInst, 6) == 1) {
1154                if (single) {
1155                    return decodeVfpRegRegRegOp<VnmlaS>(
1156                            machInst, vd, vn, vm, false);
1157                } else {
1158                    return decodeVfpRegRegRegOp<VnmlaD>(
1159                            machInst, vd, vn, vm, true);
1160                }
1161            } else {
1162                if (single) {
1163                    return decodeVfpRegRegRegOp<VnmlsS>(
1164                            machInst, vd, vn, vm, false);
1165                } else {
1166                    return decodeVfpRegRegRegOp<VnmlsD>(
1167                            machInst, vd, vn, vm, true);
1168                }
1169            }
1170          case 0x2:
1171            if ((opc3 & 0x1) == 0) {
1172                if (single) {
1173                    return decodeVfpRegRegRegOp<VmulS>(
1174                            machInst, vd, vn, vm, false);
1175                } else {
1176                    return decodeVfpRegRegRegOp<VmulD>(
1177                            machInst, vd, vn, vm, true);
1178                }
1179            } else {
1180                if (single) {
1181                    return decodeVfpRegRegRegOp<VnmulS>(
1182                            machInst, vd, vn, vm, false);
1183                } else {
1184                    return decodeVfpRegRegRegOp<VnmulD>(
1185                            machInst, vd, vn, vm, true);
1186                }
1187            }
1188          case 0x3:
1189            if ((opc3 & 0x1) == 0) {
1190                if (single) {
1191                    return decodeVfpRegRegRegOp<VaddS>(
1192                            machInst, vd, vn, vm, false);
1193                } else {
1194                    return decodeVfpRegRegRegOp<VaddD>(
1195                            machInst, vd, vn, vm, true);
1196                }
1197            } else {
1198                if (single) {
1199                    return decodeVfpRegRegRegOp<VsubS>(
1200                            machInst, vd, vn, vm, false);
1201                } else {
1202                    return decodeVfpRegRegRegOp<VsubD>(
1203                            machInst, vd, vn, vm, true);
1204                }
1205            }
1206          case 0x8:
1207            if ((opc3 & 0x1) == 0) {
1208                if (single) {
1209                    return decodeVfpRegRegRegOp<VdivS>(
1210                            machInst, vd, vn, vm, false);
1211                } else {
1212                    return decodeVfpRegRegRegOp<VdivD>(
1213                            machInst, vd, vn, vm, true);
1214                }
1215            }
1216            break;
1217          case 0xb:
1218            if ((opc3 & 0x1) == 0) {
1219                const uint32_t baseImm =
1220                    bits(machInst, 3, 0) | (bits(machInst, 19, 16) << 4);
1221                if (single) {
1222                    uint32_t imm = vfp_modified_imm(baseImm, false);
1223                    return decodeVfpRegImmOp<VmovImmS>(
1224                            machInst, vd, imm, false);
1225                } else {
1226                    uint64_t imm = vfp_modified_imm(baseImm, true);
1227                    return decodeVfpRegImmOp<VmovImmD>(
1228                            machInst, vd, imm, true);
1229                }
1230            }
1231            switch (opc2) {
1232              case 0x0:
1233                if (opc3 == 1) {
1234                    if (single) {
1235                        return decodeVfpRegRegOp<VmovRegS>(
1236                                machInst, vd, vm, false);
1237                    } else {
1238                        return decodeVfpRegRegOp<VmovRegD>(
1239                                machInst, vd, vm, true);
1240                    }
1241                } else {
1242                    if (single) {
1243                        return decodeVfpRegRegOp<VabsS>(
1244                                machInst, vd, vm, false);
1245                    } else {
1246                        return decodeVfpRegRegOp<VabsD>(
1247                                machInst, vd, vm, true);
1248                    }
1249                }
1250              case 0x1:
1251                if (opc3 == 1) {
1252                    if (single) {
1253                        return decodeVfpRegRegOp<VnegS>(
1254                                machInst, vd, vm, false);
1255                    } else {
1256                        return decodeVfpRegRegOp<VnegD>(
1257                                machInst, vd, vm, true);
1258                    }
1259                } else {
1260                    if (single) {
1261                        return decodeVfpRegRegOp<VsqrtS>(
1262                                machInst, vd, vm, false);
1263                    } else {
1264                        return decodeVfpRegRegOp<VsqrtD>(
1265                                machInst, vd, vm, true);
1266                    }
1267                }
1268              case 0x2:
1269              case 0x3:
1270                {
1271                    const bool toHalf = bits(machInst, 16);
1272                    const bool top = bits(machInst, 7);
1273                    if (top) {
1274                        if (toHalf) {
1275                            return new VcvtFpSFpHT(machInst, vd, vm);
1276                        } else {
1277                            return new VcvtFpHTFpS(machInst, vd, vm);
1278                        }
1279                    } else {
1280                        if (toHalf) {
1281                            return new VcvtFpSFpHB(machInst, vd, vm);
1282                        } else {
1283                            return new VcvtFpHBFpS(machInst, vd, vm);
1284                        }
1285                    }
1286                }
1287              case 0x4:
1288                if (single) {
1289                    if (e) {
1290                        return new VcmpeS(machInst, vd, vm);
1291                    } else {
1292                        return new VcmpS(machInst, vd, vm);
1293                    }
1294                } else {
1295                    if (e) {
1296                        return new VcmpeD(machInst, vd, vm);
1297                    } else {
1298                        return new VcmpD(machInst, vd, vm);
1299                    }
1300                }
1301              case 0x5:
1302                if (single) {
1303                    if (e) {
1304                        return new VcmpeZeroS(machInst, vd, 0);
1305                    } else {
1306                        return new VcmpZeroS(machInst, vd, 0);
1307                    }
1308                } else {
1309                    if (e) {
1310                        return new VcmpeZeroD(machInst, vd, 0);
1311                    } else {
1312                        return new VcmpZeroD(machInst, vd, 0);
1313                    }
1314                }
1315              case 0x7:
1316                if (opc3 == 0x3) {
1317                    if (single) {
1318                        vm = (IntRegIndex)(bits(machInst, 5) |
1319                                (bits(machInst, 3, 0) << 1));
1320                        return new VcvtFpSFpD(machInst, vd, vm);
1321                    } else {
1322                        vd = (IntRegIndex)(bits(machInst, 22) |
1323                                (bits(machInst, 15, 12) << 1));
1324                        return new VcvtFpDFpS(machInst, vd, vm);
1325                    }
1326                }
1327                break;
1328              case 0x8:
1329                if (bits(machInst, 7) == 0) {
1330                    if (single) {
1331                        return new VcvtUIntFpS(machInst, vd, vm);
1332                    } else {
1333                        vm = (IntRegIndex)(bits(machInst, 5) |
1334                                (bits(machInst, 3, 0) << 1));
1335                        return new VcvtUIntFpD(machInst, vd, vm);
1336                    }
1337                } else {
1338                    if (single) {
1339                        return new VcvtSIntFpS(machInst, vd, vm);
1340                    } else {
1341                        vm = (IntRegIndex)(bits(machInst, 5) |
1342                                (bits(machInst, 3, 0) << 1));
1343                        return new VcvtSIntFpD(machInst, vd, vm);
1344                    }
1345                }
1346              case 0xa:
1347                {
1348                    const bool half = (bits(machInst, 7) == 0);
1349                    const uint32_t imm = bits(machInst, 5) |
1350                                         (bits(machInst, 3, 0) << 1);
1351                    const uint32_t size =
1352                        (bits(machInst, 7) == 0 ? 16 : 32) - imm;
1353                    if (single) {
1354                        if (half) {
1355                            return new VcvtSHFixedFpS(machInst, vd, vd, size);
1356                        } else {
1357                            return new VcvtSFixedFpS(machInst, vd, vd, size);
1358                        }
1359                    } else {
1360                        if (half) {
1361                            return new VcvtSHFixedFpD(machInst, vd, vd, size);
1362                        } else {
1363                            return new VcvtSFixedFpD(machInst, vd, vd, size);
1364                        }
1365                    }
1366                }
1367              case 0xb:
1368                {
1369                    const bool half = (bits(machInst, 7) == 0);
1370                    const uint32_t imm = bits(machInst, 5) |
1371                                         (bits(machInst, 3, 0) << 1);
1372                    const uint32_t size =
1373                        (bits(machInst, 7) == 0 ? 16 : 32) - imm;
1374                    if (single) {
1375                        if (half) {
1376                            return new VcvtUHFixedFpS(machInst, vd, vd, size);
1377                        } else {
1378                            return new VcvtUFixedFpS(machInst, vd, vd, size);
1379                        }
1380                    } else {
1381                        if (half) {
1382                            return new VcvtUHFixedFpD(machInst, vd, vd, size);
1383                        } else {
1384                            return new VcvtUFixedFpD(machInst, vd, vd, size);
1385                        }
1386                    }
1387                }
1388              case 0xc:
1389                if (bits(machInst, 7) == 0) {
1390                    if (single) {
1391                        return new VcvtFpUIntSR(machInst, vd, vm);
1392                    } else {
1393                        vd = (IntRegIndex)(bits(machInst, 22) |
1394                                (bits(machInst, 15, 12) << 1));
1395                        return new VcvtFpUIntDR(machInst, vd, vm);
1396                    }
1397                } else {
1398                    if (single) {
1399                        return new VcvtFpUIntS(machInst, vd, vm);
1400                    } else {
1401                        vd = (IntRegIndex)(bits(machInst, 22) |
1402                                (bits(machInst, 15, 12) << 1));
1403                        return new VcvtFpUIntD(machInst, vd, vm);
1404                    }
1405                }
1406              case 0xd:
1407                if (bits(machInst, 7) == 0) {
1408                    if (single) {
1409                        return new VcvtFpSIntSR(machInst, vd, vm);
1410                    } else {
1411                        vd = (IntRegIndex)(bits(machInst, 22) |
1412                                (bits(machInst, 15, 12) << 1));
1413                        return new VcvtFpSIntDR(machInst, vd, vm);
1414                    }
1415                } else {
1416                    if (single) {
1417                        return new VcvtFpSIntS(machInst, vd, vm);
1418                    } else {
1419                        vd = (IntRegIndex)(bits(machInst, 22) |
1420                                (bits(machInst, 15, 12) << 1));
1421                        return new VcvtFpSIntD(machInst, vd, vm);
1422                    }
1423                }
1424              case 0xe:
1425                {
1426                    const bool half = (bits(machInst, 7) == 0);
1427                    const uint32_t imm = bits(machInst, 5) |
1428                                         (bits(machInst, 3, 0) << 1);
1429                    const uint32_t size =
1430                        (bits(machInst, 7) == 0 ? 16 : 32) - imm;
1431                    if (single) {
1432                        if (half) {
1433                            return new VcvtFpSHFixedS(machInst, vd, vd, size);
1434                        } else {
1435                            return new VcvtFpSFixedS(machInst, vd, vd, size);
1436                        }
1437                    } else {
1438                        if (half) {
1439                            return new VcvtFpSHFixedD(machInst, vd, vd, size);
1440                        } else {
1441                            return new VcvtFpSFixedD(machInst, vd, vd, size);
1442                        }
1443                    }
1444                }
1445              case 0xf:
1446                {
1447                    const bool half = (bits(machInst, 7) == 0);
1448                    const uint32_t imm = bits(machInst, 5) |
1449                                         (bits(machInst, 3, 0) << 1);
1450                    const uint32_t size =
1451                        (bits(machInst, 7) == 0 ? 16 : 32) - imm;
1452                    if (single) {
1453                        if (half) {
1454                            return new VcvtFpUHFixedS(machInst, vd, vd, size);
1455                        } else {
1456                            return new VcvtFpUFixedS(machInst, vd, vd, size);
1457                        }
1458                    } else {
1459                        if (half) {
1460                            return new VcvtFpUHFixedD(machInst, vd, vd, size);
1461                        } else {
1462                            return new VcvtFpUFixedD(machInst, vd, vd, size);
1463                        }
1464                    }
1465                }
1466            }
1467            break;
1468        }
1469        return new Unknown(machInst);
1470    }
1471    '''
1472}};
1473
1474def format VfpData() {{
1475    decode_block = '''
1476    return decodeVfpData(machInst);
1477    '''
1478}};
1479