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