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