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