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