Deleted Added
sdiff udiff text old ( 7591:aabe621e58df ) new ( 7639:8c09b7ff5b57 )
full compact
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}};