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 --- 31 unchanged lines hidden (view full) --- 40// 41// Authors: Stephen Hines 42 43//////////////////////////////////////////////////////////////////// 44// 45// Floating Point operate instructions 46// 47 |
48output header {{ 49 50 template<template <typename T> class Base> 51 StaticInstPtr 52 newNeonMemInst(const unsigned size, 53 const ExtMachInst &machInst, 54 const RegIndex dest, const RegIndex ra, 55 const uint32_t imm, const unsigned extraMemFlags) 56 { 57 switch (size) { 58 case 0: 59 return new Base<uint8_t>(machInst, dest, ra, imm, extraMemFlags); 60 case 1: 61 return new Base<uint16_t>(machInst, dest, ra, imm, extraMemFlags); 62 case 2: 63 return new Base<uint32_t>(machInst, dest, ra, imm, extraMemFlags); 64 case 3: 65 return new Base<uint64_t>(machInst, dest, ra, imm, extraMemFlags); 66 default: 67 panic("Unrecognized width %d for Neon mem inst.\n", (1 << size)); 68 } 69 } 70 71 template<template <typename T> class Base> 72 StaticInstPtr 73 newNeonMixInst(const unsigned size, 74 const ExtMachInst &machInst, 75 const RegIndex dest, const RegIndex op1, 76 const uint32_t step) 77 { 78 switch (size) { 79 case 0: 80 return new Base<uint8_t>(machInst, dest, op1, step); 81 case 1: 82 return new Base<uint16_t>(machInst, dest, op1, step); 83 case 2: 84 return new Base<uint32_t>(machInst, dest, op1, step); 85 case 3: 86 return new Base<uint64_t>(machInst, dest, op1, step); 87 default: 88 panic("Unrecognized width %d for Neon mem inst.\n", (1 << size)); 89 } 90 } 91 92}}; 93 |
94let {{ 95 header_output = ''' 96 StaticInstPtr 97 decodeNeonMem(ExtMachInst machInst); 98 99 StaticInstPtr 100 decodeNeonData(ExtMachInst machInst); 101 ''' 102 103 decoder_output = ''' 104 StaticInstPtr 105 decodeNeonMem(ExtMachInst machInst) 106 { 107 const uint32_t b = bits(machInst, 11, 8); |
108 const bool single = bits(machInst, 23); 109 const bool singleAll = single && (bits(b, 3, 2) == 3); 110 const bool load = bits(machInst, 21); |
111 |
112 unsigned width = 0; 113 114 if (single) { 115 width = bits(b, 1, 0) + 1; 116 } else { 117 switch (bits(b, 3, 1)) { 118 case 0x0: width = 4; 119 break; 120 case 0x1: width = (b & 0x1) ? 2 : 1; 121 break; 122 case 0x2: width = 3; 123 break; 124 case 0x3: width = 1; 125 break; 126 case 0x4: width = 2; 127 break; 128 case 0x5: 129 if ((b & 0x1) == 0) { 130 width = 1; 131 break; 132 } 133 // Fall through on purpose. 134 default: 135 return new Unknown(machInst); 136 } 137 } 138 assert(width > 0 && width <= 4); 139 140 const RegIndex rm = (RegIndex)(uint32_t)bits(machInst, 3, 0); 141 const RegIndex rn = (RegIndex)(uint32_t)bits(machInst, 19, 16); 142 const RegIndex vd = (RegIndex)(uint32_t)(bits(machInst, 15, 12) | 143 bits(machInst, 22) << 4); 144 const uint32_t type = bits(machInst, 11, 8); 145 uint32_t size = 0; 146 uint32_t align = 0; 147 unsigned inc = 1; 148 unsigned regs = 1; 149 unsigned lane = 0; 150 if (single) { 151 if (singleAll) { 152 size = bits(machInst, 7, 6); 153 bool t = bits(machInst, 5); 154 unsigned eBytes = (1 << size); 155 align = (eBytes - 1) | TLB::AllowUnaligned; 156 if (width == 1) { 157 regs = t ? 2 : 1; 158 inc = 1; |
159 } else { |
160 regs = width; 161 inc = t ? 2 : 1; 162 } 163 switch (width) { 164 case 1: 165 case 2: 166 if (bits(machInst, 4)) 167 align = width * eBytes - 1; 168 break; 169 case 3: 170 break; 171 case 4: 172 if (size == 3) { 173 if (bits(machInst, 4) == 0) 174 return new Unknown(machInst); 175 size = 2; 176 align = 0xf; 177 } else if (size == 2) { 178 if (bits(machInst, 4)) 179 align = 7; 180 } else { 181 if (bits(machInst, 4)) 182 align = 4 * eBytes - 1; |
183 } |
184 break; |
185 } 186 } else { |
187 size = bits(machInst, 11, 10); 188 unsigned eBytes = (1 << size); 189 align = (eBytes - 1) | TLB::AllowUnaligned; 190 regs = width; 191 unsigned indexAlign = bits(machInst, 7, 4); 192 // If width is 1, inc is always 1. That's overridden later. 193 switch (size) { 194 case 0: 195 inc = 1; 196 lane = bits(indexAlign, 3, 1); 197 break; 198 case 1: 199 inc = bits(indexAlign, 1) ? 2 : 1; 200 lane = bits(indexAlign, 3, 2); 201 break; 202 case 2: 203 inc = bits(indexAlign, 2) ? 2 : 1; 204 lane = bits(indexAlign, 3); 205 break; 206 } 207 // Override inc for width of 1. 208 if (width == 1) { 209 inc = 1; 210 } 211 switch (width) { 212 case 1: 213 switch (size) { 214 case 0: 215 break; 216 case 1: 217 if (bits(indexAlign, 0)) 218 align = 1; 219 break; 220 case 2: 221 if (bits(indexAlign, 1, 0)) 222 align = 3; 223 break; |
224 } |
225 break; 226 case 2: 227 if (bits(indexAlign, 0)) 228 align = (2 * eBytes) - 1; 229 break; 230 case 3: 231 break; 232 case 4: 233 switch (size) { 234 case 0: 235 case 1: 236 if (bits(indexAlign, 0)) 237 align = (4 * eBytes) - 1; |
238 break; |
239 case 2: 240 if (bits(indexAlign, 0)) 241 align = (4 << bits(indexAlign, 1, 0)) - 1; 242 break; |
243 } |
244 break; |
245 } 246 } |
247 if (size == 0x3) { 248 return new Unknown(machInst); 249 } |
250 } else { |
251 size = bits(machInst, 7, 6); 252 align = bits(machInst, 5, 4); 253 if (align == 0) { 254 // @align wasn't specified, so alignment can be turned off. 255 align = ((1 << size) - 1) | TLB::AllowUnaligned; 256 } else { 257 align = ((4 << align) - 1); 258 } 259 switch (width) { 260 case 1: 261 switch (type) { 262 case 0x7: regs = 1; 263 break; 264 case 0xa: regs = 2; 265 break; 266 case 0x6: regs = 3; 267 break; 268 case 0x2: regs = 4; 269 break; 270 default: 271 return new Unknown(machInst); 272 } 273 break; 274 case 2: 275 // Regs doesn't behave exactly as it does in the manual 276 // because they loop over regs registers twice and we break 277 // it down in the macroop. 278 switch (type) { 279 case 0x8: regs = 2; inc = 1; 280 break; 281 case 0x9: regs = 2; inc = 2; 282 break; 283 case 0x3: regs = 4; inc = 2; 284 break; 285 default: 286 return new Unknown(machInst); 287 } 288 break; 289 case 3: 290 regs = 3; 291 switch (type) { 292 case 0x4: inc = 1; 293 break; 294 case 0x5: inc = 2;; 295 break; 296 default: 297 return new Unknown(machInst); 298 } 299 break; 300 case 4: 301 regs = 4; 302 switch (type) { 303 case 0: inc = 1; 304 break; 305 case 1: inc = 2; 306 break; 307 default: 308 return new Unknown(machInst); 309 } 310 break; 311 } 312 } 313 314 if (load) { 315 // Load instructions. 316 if (single) { 317 return new VldSingle(machInst, singleAll, width, rn, vd, 318 regs, inc, size, align, rm, lane); 319 } else { 320 return new VldMult(machInst, width, rn, vd, 321 regs, inc, size, align, rm); 322 } 323 } else { |
324 // Store instructions. |
325 if (single) { 326 if (singleAll) { 327 return new Unknown(machInst); |
328 } else { |
329 return new VstSingle(machInst, false, width, rn, vd, 330 regs, inc, size, align, rm, lane); |
331 } 332 } else { |
333 return new VstMult(machInst, width, rn, vd, 334 regs, inc, size, align, rm); |
335 } 336 } 337 return new Unknown(machInst); 338 } 339 ''' 340 341 decoder_output += ''' 342 static StaticInstPtr 343 decodeNeonThreeRegistersSameLength(ExtMachInst machInst) 344 { 345 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 346 const uint32_t a = bits(machInst, 11, 8); 347 const bool b = bits(machInst, 4); 348 const uint32_t c = bits(machInst, 21, 20); |
349 const IntRegIndex vd = 350 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 351 (bits(machInst, 22) << 4))); 352 const IntRegIndex vn = 353 (IntRegIndex)(2 * (bits(machInst, 19, 16) | 354 (bits(machInst, 7) << 4))); 355 const IntRegIndex vm = 356 (IntRegIndex)(2 * (bits(machInst, 3, 0) | 357 (bits(machInst, 5) << 4))); 358 const unsigned size = bits(machInst, 21, 20); 359 const bool q = bits(machInst, 6); 360 if (q && ((vd & 0x1) || (vn & 0x1) || (vm & 0x1))) 361 return new Unknown(machInst); |
362 switch (a) { 363 case 0x0: 364 if (b) { |
365 if (u) { 366 return decodeNeonUThreeReg<VqaddUD, VqaddUQ>( 367 q, size, machInst, vd, vn, vm); |
368 } else { |
369 return decodeNeonSThreeReg<VqaddSD, VqaddSQ>( 370 q, size, machInst, vd, vn, vm); |
371 } 372 } else { |
373 if (size == 3) 374 return new Unknown(machInst); 375 return decodeNeonUSThreeReg<VhaddD, VhaddQ>( 376 q, u, size, machInst, vd, vn, vm); |
377 } 378 case 0x1: 379 if (!b) { |
380 return decodeNeonUSThreeReg<VrhaddD, VrhaddQ>( 381 q, u, size, machInst, vd, vn, vm); |
382 } else { 383 if (u) { 384 switch (c) { 385 case 0: |
386 if (q) { 387 return new VeorQ<uint64_t>(machInst, vd, vn, vm); 388 } else { 389 return new VeorD<uint64_t>(machInst, vd, vn, vm); 390 } |
391 case 1: |
392 if (q) { 393 return new VbslQ<uint64_t>(machInst, vd, vn, vm); 394 } else { 395 return new VbslD<uint64_t>(machInst, vd, vn, vm); 396 } |
397 case 2: |
398 if (q) { 399 return new VbitQ<uint64_t>(machInst, vd, vn, vm); 400 } else { 401 return new VbitD<uint64_t>(machInst, vd, vn, vm); 402 } |
403 case 3: |
404 if (q) { 405 return new VbifQ<uint64_t>(machInst, vd, vn, vm); 406 } else { 407 return new VbifD<uint64_t>(machInst, vd, vn, vm); 408 } |
409 } 410 } else { 411 switch (c) { 412 case 0: |
413 if (q) { 414 return new VandQ<uint64_t>(machInst, vd, vn, vm); 415 } else { 416 return new VandD<uint64_t>(machInst, vd, vn, vm); 417 } |
418 case 1: |
419 if (q) { 420 return new VbicQ<uint64_t>(machInst, vd, vn, vm); 421 } else { 422 return new VbicD<uint64_t>(machInst, vd, vn, vm); 423 } |
424 case 2: |
425 if (vn == vm) { 426 if (q) { 427 return new VmovQ<uint64_t>( 428 machInst, vd, vn, vm); |
429 } else { |
430 return new VmovD<uint64_t>( 431 machInst, vd, vn, vm); |
432 } |
433 } else { 434 if (q) { 435 return new VorrQ<uint64_t>( 436 machInst, vd, vn, vm); 437 } else { 438 return new VorrD<uint64_t>( 439 machInst, vd, vn, vm); 440 } |
441 } 442 case 3: |
443 if (q) { 444 return new VornQ<uint64_t>( 445 machInst, vd, vn, vm); 446 } else { 447 return new VornD<uint64_t>( 448 machInst, vd, vn, vm); 449 } |
450 } 451 } 452 } 453 case 0x2: 454 if (b) { |
455 if (u) { 456 return decodeNeonUThreeReg<VqsubUD, VqsubUQ>( 457 q, size, machInst, vd, vn, vm); |
458 } else { |
459 return decodeNeonSThreeReg<VqsubSD, VqsubSQ>( 460 q, size, machInst, vd, vn, vm); |
461 } |
462 } else { 463 if (size == 3) 464 return new Unknown(machInst); 465 return decodeNeonUSThreeReg<VhsubD, VhsubQ>( 466 q, u, size, machInst, vd, vn, vm); |
467 } 468 case 0x3: 469 if (b) { |
470 return decodeNeonUSThreeReg<VcgeD, VcgeQ>( 471 q, u, size, machInst, vd, vn, vm); |
472 } else { |
473 return decodeNeonUSThreeReg<VcgtD, VcgtQ>( 474 q, u, size, machInst, vd, vn, vm); |
475 } 476 case 0x4: 477 if (b) { |
478 if (u) { 479 return decodeNeonUThreeReg<VqshlUD, VqshlUQ>( 480 q, size, machInst, vd, vm, vn); 481 } else { 482 return decodeNeonSThreeReg<VqshlSD, VqshlSQ>( 483 q, size, machInst, vd, vm, vn); 484 } |
485 } else { |
486 return decodeNeonUSThreeReg<VshlD, VshlQ>( 487 q, u, size, machInst, vd, vm, vn); |
488 } 489 case 0x5: 490 if (b) { |
491 if (u) { 492 return decodeNeonUThreeReg<VqrshlUD, VqrshlUQ>( 493 q, size, machInst, vd, vm, vn); 494 } else { 495 return decodeNeonSThreeReg<VqrshlSD, VqrshlSQ>( 496 q, size, machInst, vd, vm, vn); 497 } |
498 } else { |
499 return decodeNeonUSThreeReg<VrshlD, VrshlQ>( 500 q, u, size, machInst, vd, vm, vn); |
501 } 502 case 0x6: 503 if (b) { |
504 return decodeNeonUSThreeReg<VminD, VminQ>( 505 q, u, size, machInst, vd, vn, vm); |
506 } else { |
507 return decodeNeonUSThreeReg<VmaxD, VmaxQ>( 508 q, u, size, machInst, vd, vn, vm); |
509 } 510 case 0x7: 511 if (b) { |
512 return decodeNeonUSThreeReg<VabaD, VabaQ>( 513 q, u, size, machInst, vd, vn, vm); |
514 } else { 515 if (bits(machInst, 23) == 1) { |
516 if (q) { |
517 return new Unknown(machInst); 518 } else { |
519 return decodeNeonUSThreeUSReg<Vabdl>( 520 u, size, machInst, vd, vn, vm); |
521 } 522 } else { |
523 return decodeNeonUSThreeReg<VabdD, VabdQ>( 524 q, u, size, machInst, vd, vn, vm); |
525 } 526 } 527 case 0x8: 528 if (b) { 529 if (u) { |
530 return decodeNeonUThreeReg<VceqD, VceqQ>( 531 q, size, machInst, vd, vn, vm); |
532 } else { |
533 return decodeNeonUThreeReg<VtstD, VtstQ>( 534 q, size, machInst, vd, vn, vm); |
535 } 536 } else { 537 if (u) { |
538 return decodeNeonUThreeReg<NVsubD, NVsubQ>( 539 q, size, machInst, vd, vn, vm); |
540 } else { |
541 return decodeNeonUThreeReg<NVaddD, NVaddQ>( 542 q, size, machInst, vd, vn, vm); |
543 } 544 } 545 case 0x9: 546 if (b) { 547 if (u) { |
548 return decodeNeonUThreeReg<NVmulpD, NVmulpQ>( 549 q, size, machInst, vd, vn, vm); |
550 } else { |
551 return decodeNeonSThreeReg<NVmulD, NVmulQ>( 552 q, size, machInst, vd, vn, vm); |
553 } 554 } else { 555 if (u) { |
556 return decodeNeonUSThreeReg<NVmlsD, NVmlsQ>( 557 q, u, size, machInst, vd, vn, vm); |
558 } else { |
559 return decodeNeonUSThreeReg<NVmlaD, NVmlaQ>( 560 q, u, size, machInst, vd, vn, vm); |
561 } 562 } 563 case 0xa: 564 if (b) { |
565 return decodeNeonUSThreeReg<VpminD, VpminQ>( 566 q, u, size, machInst, vd, vn, vm); |
567 } else { |
568 return decodeNeonUSThreeReg<VpmaxD, VpmaxQ>( 569 q, u, size, machInst, vd, vn, vm); |
570 } 571 case 0xb: 572 if (b) { 573 if (u) { 574 return new Unknown(machInst); 575 } else { |
576 return decodeNeonUThreeReg<NVpaddD, NVpaddQ>( 577 q, size, machInst, vd, vn, vm); |
578 } 579 } else { 580 if (u) { |
581 return decodeNeonSThreeSReg<VqrdmulhD, VqrdmulhQ>( 582 q, size, machInst, vd, vn, vm); |
583 } else { |
584 return decodeNeonSThreeSReg<VqdmulhD, VqdmulhQ>( 585 q, size, machInst, vd, vn, vm); |
586 } 587 } 588 case 0xc: 589 return new Unknown(machInst); 590 case 0xd: 591 if (b) { 592 if (u) { 593 if (bits(c, 1) == 0) { |
594 if (q) { 595 return new NVmulQFp<float>(machInst, vd, vn, vm); 596 } else { 597 return new NVmulDFp<float>(machInst, vd, vn, vm); 598 } |
599 } else { 600 return new Unknown(machInst); 601 } 602 } else { 603 if (bits(c, 1) == 0) { |
604 if (q) { 605 return new NVmlaQFp<float>(machInst, vd, vn, vm); 606 } else { 607 return new NVmlaDFp<float>(machInst, vd, vn, vm); 608 } |
609 } else { |
610 if (q) { 611 return new NVmlsQFp<float>(machInst, vd, vn, vm); 612 } else { 613 return new NVmlsDFp<float>(machInst, vd, vn, vm); 614 } |
615 } 616 } 617 } else { 618 if (u) { 619 if (bits(c, 1) == 0) { |
620 if (q) { 621 return new VpaddQFp<float>(machInst, vd, vn, vm); 622 } else { 623 return new VpaddDFp<float>(machInst, vd, vn, vm); 624 } |
625 } else { |
626 if (q) { 627 return new VabdQFp<float>(machInst, vd, vn, vm); 628 } else { 629 return new VabdDFp<float>(machInst, vd, vn, vm); 630 } |
631 } 632 } else { 633 if (bits(c, 1) == 0) { |
634 if (q) { 635 return new VaddQFp<float>(machInst, vd, vn, vm); 636 } else { 637 return new VaddDFp<float>(machInst, vd, vn, vm); 638 } |
639 } else { |
640 if (q) { 641 return new VsubQFp<float>(machInst, vd, vn, vm); 642 } else { 643 return new VsubDFp<float>(machInst, vd, vn, vm); 644 } |
645 } 646 } 647 } 648 case 0xe: 649 if (b) { 650 if (u) { 651 if (bits(c, 1) == 0) { |
652 if (q) { 653 return new VacgeQFp<float>(machInst, vd, vn, vm); 654 } else { 655 return new VacgeDFp<float>(machInst, vd, vn, vm); 656 } |
657 } else { |
658 if (q) { 659 return new VacgtQFp<float>(machInst, vd, vn, vm); 660 } else { 661 return new VacgtDFp<float>(machInst, vd, vn, vm); 662 } |
663 } 664 } else { 665 return new Unknown(machInst); 666 } 667 } else { 668 if (u) { 669 if (bits(c, 1) == 0) { |
670 if (q) { 671 return new VcgeQFp<float>(machInst, vd, vn, vm); 672 } else { 673 return new VcgeDFp<float>(machInst, vd, vn, vm); 674 } |
675 } else { |
676 if (q) { 677 return new VcgtQFp<float>(machInst, vd, vn, vm); 678 } else { 679 return new VcgtDFp<float>(machInst, vd, vn, vm); 680 } |
681 } 682 } else { 683 if (bits(c, 1) == 0) { |
684 if (q) { 685 return new VceqQFp<float>(machInst, vd, vn, vm); 686 } else { 687 return new VceqDFp<float>(machInst, vd, vn, vm); 688 } |
689 } else { 690 return new Unknown(machInst); 691 } 692 } 693 } 694 case 0xf: 695 if (b) { 696 if (u) { 697 return new Unknown(machInst); 698 } else { 699 if (bits(c, 1) == 0) { |
700 if (q) { 701 return new VrecpsQFp<float>(machInst, vd, vn, vm); 702 } else { 703 return new VrecpsDFp<float>(machInst, vd, vn, vm); 704 } |
705 } else { |
706 if (q) { 707 return new VrsqrtsQFp<float>(machInst, vd, vn, vm); 708 } else { 709 return new VrsqrtsDFp<float>(machInst, vd, vn, vm); 710 } |
711 } 712 } 713 } else { 714 if (u) { 715 if (bits(c, 1) == 0) { |
716 if (q) { 717 return new VpmaxQFp<float>(machInst, vd, vn, vm); 718 } else { 719 return new VpmaxDFp<float>(machInst, vd, vn, vm); 720 } |
721 } else { |
722 if (q) { 723 return new VpminQFp<float>(machInst, vd, vn, vm); 724 } else { 725 return new VpminDFp<float>(machInst, vd, vn, vm); 726 } |
727 } 728 } else { 729 if (bits(c, 1) == 0) { |
730 if (q) { 731 return new VmaxQFp<float>(machInst, vd, vn, vm); 732 } else { 733 return new VmaxDFp<float>(machInst, vd, vn, vm); 734 } |
735 } else { |
736 if (q) { 737 return new VminQFp<float>(machInst, vd, vn, vm); 738 } else { 739 return new VminDFp<float>(machInst, vd, vn, vm); 740 } |
741 } 742 } 743 } 744 } 745 return new Unknown(machInst); 746 } 747 748 static StaticInstPtr 749 decodeNeonOneRegModImm(ExtMachInst machInst) 750 { |
751 const IntRegIndex vd = 752 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 753 (bits(machInst, 22) << 4))); 754 const bool q = bits(machInst, 6); |
755 const bool op = bits(machInst, 5); |
756 const uint8_t cmode = bits(machInst, 11, 8); 757 const uint8_t imm = ((THUMB ? bits(machInst, 28) : 758 bits(machInst, 24)) << 7) | 759 (bits(machInst, 18, 16) << 4) | 760 (bits(machInst, 3, 0) << 0); 761 const uint64_t bigImm = simd_modified_imm(op, cmode, imm); |
762 if (op) { 763 if (bits(cmode, 3) == 0) { 764 if (bits(cmode, 0) == 0) { |
765 if (q) 766 return new NVmvniQ<uint64_t>(machInst, vd, bigImm); 767 else 768 return new NVmvniD<uint64_t>(machInst, vd, bigImm); |
769 } else { |
770 if (q) 771 return new NVbiciQ<uint64_t>(machInst, vd, bigImm); 772 else 773 return new NVbiciD<uint64_t>(machInst, vd, bigImm); |
774 } 775 } else { 776 if (bits(cmode, 2) == 1) { |
777 switch (bits(cmode, 1, 0)) { 778 case 0: 779 case 1: 780 if (q) 781 return new NVmvniQ<uint64_t>(machInst, vd, bigImm); 782 else 783 return new NVmvniD<uint64_t>(machInst, vd, bigImm); 784 case 2: 785 if (q) 786 return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 787 else 788 return new NVmoviD<uint64_t>(machInst, vd, bigImm); 789 case 3: 790 if (q) 791 return new Unknown(machInst); 792 else 793 return new Unknown(machInst); 794 } |
795 } else { 796 if (bits(cmode, 0) == 0) { |
797 if (q) 798 return new NVmvniQ<uint64_t>(machInst, vd, bigImm); 799 else 800 return new NVmvniD<uint64_t>(machInst, vd, bigImm); |
801 } else { |
802 if (q) 803 return new NVbiciQ<uint64_t>(machInst, vd, bigImm); 804 else 805 return new NVbiciD<uint64_t>(machInst, vd, bigImm); |
806 } 807 } 808 } 809 } else { 810 if (bits(cmode, 3) == 0) { 811 if (bits(cmode, 0) == 0) { |
812 if (q) 813 return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 814 else 815 return new NVmoviD<uint64_t>(machInst, vd, bigImm); |
816 } else { |
817 if (q) 818 return new NVorriQ<uint64_t>(machInst, vd, bigImm); 819 else 820 return new NVorriD<uint64_t>(machInst, vd, bigImm); |
821 } 822 } else { 823 if (bits(cmode, 2) == 1) { |
824 if (q) 825 return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 826 else 827 return new NVmoviD<uint64_t>(machInst, vd, bigImm); |
828 } else { 829 if (bits(cmode, 0) == 0) { |
830 if (q) 831 return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 832 else 833 return new NVmoviD<uint64_t>(machInst, vd, bigImm); |
834 } else { |
835 if (q) 836 return new NVorriQ<uint64_t>(machInst, vd, bigImm); 837 else 838 return new NVorriD<uint64_t>(machInst, vd, bigImm); |
839 } 840 } 841 } 842 } 843 return new Unknown(machInst); 844 } 845 846 static StaticInstPtr 847 decodeNeonTwoRegAndShift(ExtMachInst machInst) 848 { 849 const uint32_t a = bits(machInst, 11, 8); 850 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 851 const bool b = bits(machInst, 6); 852 const bool l = bits(machInst, 7); |
853 const IntRegIndex vd = 854 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 855 (bits(machInst, 22) << 4))); 856 const IntRegIndex vm = 857 (IntRegIndex)(2 * (bits(machInst, 3, 0) | 858 (bits(machInst, 5) << 4))); 859 unsigned imm6 = bits(machInst, 21, 16); 860 unsigned imm = ((l ? 1 : 0) << 6) | imm6; 861 unsigned size = 3; 862 unsigned lShiftAmt = 0; 863 unsigned bitSel; 864 for (bitSel = 1 << 6; true; bitSel >>= 1) { 865 if (bitSel & imm) 866 break; 867 else if (!size) 868 return new Unknown(machInst); 869 size--; 870 } 871 lShiftAmt = imm6 & ~bitSel; 872 unsigned rShiftAmt = 0; 873 if (a != 0xe && a != 0xf) { 874 if (size > 2) 875 rShiftAmt = 64 - imm6; 876 else 877 rShiftAmt = 2 * (8 << size) - imm6; 878 } |
879 880 switch (a) { 881 case 0x0: |
882 return decodeNeonUSTwoShiftReg<NVshrD, NVshrQ>( 883 b, u, size, machInst, vd, vm, rShiftAmt); |
884 case 0x1: |
885 return decodeNeonUSTwoShiftReg<NVsraD, NVsraQ>( 886 b, u, size, machInst, vd, vm, rShiftAmt); |
887 case 0x2: |
888 return decodeNeonUSTwoShiftReg<NVrshrD, NVrshrQ>( 889 b, u, size, machInst, vd, vm, rShiftAmt); |
890 case 0x3: |
891 return decodeNeonUSTwoShiftReg<NVrsraD, NVrsraQ>( 892 b, u, size, machInst, vd, vm, rShiftAmt); |
893 case 0x4: 894 if (u) { |
895 return decodeNeonUTwoShiftReg<NVsriD, NVsriQ>( 896 b, size, machInst, vd, vm, rShiftAmt); |
897 } else { 898 return new Unknown(machInst); 899 } 900 case 0x5: 901 if (u) { |
902 return decodeNeonUTwoShiftReg<NVsliD, NVsliQ>( 903 b, size, machInst, vd, vm, lShiftAmt); |
904 } else { |
905 return decodeNeonUTwoShiftReg<NVshlD, NVshlQ>( 906 b, size, machInst, vd, vm, lShiftAmt); |
907 } 908 case 0x6: 909 case 0x7: |
910 if (u) { 911 if (a == 0x6) { 912 return decodeNeonSTwoShiftReg<NVqshlusD, NVqshlusQ>( 913 b, size, machInst, vd, vm, lShiftAmt); 914 } else { 915 return decodeNeonUTwoShiftReg<NVqshluD, NVqshluQ>( 916 b, size, machInst, vd, vm, lShiftAmt); 917 } 918 } else { 919 return decodeNeonSTwoShiftReg<NVqshlD, NVqshlQ>( 920 b, size, machInst, vd, vm, lShiftAmt); 921 } |
922 case 0x8: 923 if (l) { 924 return new Unknown(machInst); 925 } else if (u) { |
926 return decodeNeonSTwoShiftSReg<NVqshruns, NVqrshruns>( 927 b, size, machInst, vd, vm, rShiftAmt); |
928 } else { |
929 return decodeNeonUTwoShiftSReg<NVshrn, NVrshrn>( 930 b, size, machInst, vd, vm, rShiftAmt); |
931 } 932 case 0x9: 933 if (l) { 934 return new Unknown(machInst); |
935 } else if (u) { 936 return decodeNeonUTwoShiftSReg<NVqshrun, NVqrshrun>( 937 b, size, machInst, vd, vm, rShiftAmt); |
938 } else { |
939 return decodeNeonSTwoShiftSReg<NVqshrn, NVqrshrn>( 940 b, size, machInst, vd, vm, rShiftAmt); |
941 } 942 case 0xa: 943 if (l || b) { 944 return new Unknown(machInst); 945 } else { |
946 return decodeNeonUSTwoShiftSReg<NVmovl, NVshll>( 947 lShiftAmt, u, size, machInst, vd, vm, lShiftAmt); |
948 } 949 case 0xe: |
950 if (l) { 951 return new Unknown(machInst); 952 } else { 953 if (bits(imm6, 5) == 0) 954 return new Unknown(machInst); 955 if (u) { 956 if (b) { 957 return new NVcvtu2fpQ<float>( 958 machInst, vd, vm, 64 - imm6); 959 } else { 960 return new NVcvtu2fpD<float>( 961 machInst, vd, vm, 64 - imm6); 962 } 963 } else { 964 if (b) { 965 return new NVcvts2fpQ<float>( 966 machInst, vd, vm, 64 - imm6); 967 } else { 968 return new NVcvts2fpD<float>( 969 machInst, vd, vm, 64 - imm6); 970 } 971 } 972 } |
973 case 0xf: 974 if (l) { 975 return new Unknown(machInst); |
976 } else { 977 if (bits(imm6, 5) == 0) 978 return new Unknown(machInst); 979 if (u) { 980 if (b) { 981 return new NVcvt2ufxQ<float>( 982 machInst, vd, vm, 64 - imm6); 983 } else { 984 return new NVcvt2ufxD<float>( 985 machInst, vd, vm, 64 - imm6); 986 } 987 } else { 988 if (b) { 989 return new NVcvt2sfxQ<float>( 990 machInst, vd, vm, 64 - imm6); 991 } else { 992 return new NVcvt2sfxD<float>( 993 machInst, vd, vm, 64 - imm6); 994 } 995 } |
996 } 997 } 998 return new Unknown(machInst); 999 } 1000 1001 static StaticInstPtr 1002 decodeNeonThreeRegDiffLengths(ExtMachInst machInst) 1003 { 1004 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 1005 const uint32_t a = bits(machInst, 11, 8); |
1006 const IntRegIndex vd = 1007 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 1008 (bits(machInst, 22) << 4))); 1009 const IntRegIndex vn = 1010 (IntRegIndex)(2 * (bits(machInst, 19, 16) | 1011 (bits(machInst, 7) << 4))); 1012 const IntRegIndex vm = 1013 (IntRegIndex)(2 * (bits(machInst, 3, 0) | 1014 (bits(machInst, 5) << 4))); 1015 const unsigned size = bits(machInst, 21, 20); |
1016 switch (a) { 1017 case 0x0: |
1018 return decodeNeonUSThreeUSReg<Vaddl>( 1019 u, size, machInst, vd, vn, vm); |
1020 case 0x1: |
1021 return decodeNeonUSThreeUSReg<Vaddw>( 1022 u, size, machInst, vd, vn, vm); |
1023 case 0x2: |
1024 return decodeNeonUSThreeUSReg<Vsubl>( 1025 u, size, machInst, vd, vn, vm); |
1026 case 0x3: |
1027 return decodeNeonUSThreeUSReg<Vsubw>( 1028 u, size, machInst, vd, vn, vm); |
1029 case 0x4: 1030 if (u) { |
1031 return decodeNeonUThreeUSReg<Vraddhn>( 1032 size, machInst, vd, vn, vm); |
1033 } else { |
1034 return decodeNeonUThreeUSReg<Vaddhn>( 1035 size, machInst, vd, vn, vm); |
1036 } 1037 case 0x5: |
1038 return decodeNeonUSThreeUSReg<Vabal>( 1039 u, size, machInst, vd, vn, vm); |
1040 case 0x6: 1041 if (u) { |
1042 return decodeNeonUThreeUSReg<Vrsubhn>( 1043 size, machInst, vd, vn, vm); |
1044 } else { |
1045 return decodeNeonUThreeUSReg<Vsubhn>( 1046 size, machInst, vd, vn, vm); |
1047 } 1048 case 0x7: 1049 if (bits(machInst, 23)) { |
1050 return decodeNeonUSThreeUSReg<Vabdl>( 1051 u, size, machInst, vd, vn, vm); |
1052 } else { |
1053 return decodeNeonUSThreeReg<VabdD, VabdQ>( 1054 bits(machInst, 6), u, size, machInst, vd, vn, vm); |
1055 } 1056 case 0x8: |
1057 return decodeNeonUSThreeUSReg<Vmlal>( 1058 u, size, machInst, vd, vn, vm); |
1059 case 0xa: |
1060 return decodeNeonUSThreeUSReg<Vmlsl>( 1061 u, size, machInst, vd, vn, vm); |
1062 case 0x9: |
1063 if (u) { 1064 return new Unknown(machInst); |
1065 } else { |
1066 return decodeNeonSThreeUSReg<Vqdmlal>( 1067 size, machInst, vd, vn, vm); |
1068 } 1069 case 0xb: |
1070 if (u) { |
1071 return new Unknown(machInst); 1072 } else { |
1073 return decodeNeonSThreeUSReg<Vqdmlsl>( 1074 size, machInst, vd, vn, vm); |
1075 } 1076 case 0xc: |
1077 return decodeNeonUSThreeUSReg<Vmull>( 1078 u, size, machInst, vd, vn, vm); |
1079 case 0xd: |
1080 if (u) { |
1081 return new Unknown(machInst); 1082 } else { |
1083 return decodeNeonSThreeUSReg<Vqdmull>( 1084 size, machInst, vd, vn, vm); |
1085 } 1086 case 0xe: |
1087 return decodeNeonUThreeUSReg<Vmullp>( 1088 size, machInst, vd, vn, vm); |
1089 } 1090 return new Unknown(machInst); 1091 } 1092 1093 static StaticInstPtr 1094 decodeNeonTwoRegScalar(ExtMachInst machInst) 1095 { 1096 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 1097 const uint32_t a = bits(machInst, 11, 8); |
1098 const unsigned size = bits(machInst, 21, 20); 1099 const IntRegIndex vd = 1100 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 1101 (bits(machInst, 22) << 4))); 1102 const IntRegIndex vn = 1103 (IntRegIndex)(2 * (bits(machInst, 19, 16) | 1104 (bits(machInst, 7) << 4))); 1105 const IntRegIndex vm = (size == 2) ? 1106 (IntRegIndex)(2 * bits(machInst, 3, 0)) : 1107 (IntRegIndex)(2 * bits(machInst, 2, 0)); 1108 const unsigned index = (size == 2) ? (unsigned)bits(machInst, 5) : 1109 (bits(machInst, 3) | (bits(machInst, 5) << 1)); |
1110 switch (a) { 1111 case 0x0: |
1112 if (u) { 1113 switch (size) { 1114 case 1: 1115 return new VmlasQ<uint16_t>(machInst, vd, vn, vm, index); 1116 case 2: 1117 return new VmlasQ<uint32_t>(machInst, vd, vn, vm, index); 1118 default: 1119 return new Unknown(machInst); 1120 } 1121 } else { 1122 switch (size) { 1123 case 1: 1124 return new VmlasD<uint16_t>(machInst, vd, vn, vm, index); 1125 case 2: 1126 return new VmlasD<uint32_t>(machInst, vd, vn, vm, index); 1127 default: 1128 return new Unknown(machInst); 1129 } 1130 } |
1131 case 0x1: |
1132 if (u) 1133 return new VmlasQFp<float>(machInst, vd, vn, vm, index); 1134 else 1135 return new VmlasDFp<float>(machInst, vd, vn, vm, index); |
1136 case 0x4: |
1137 if (u) { 1138 switch (size) { 1139 case 1: 1140 return new VmlssQ<uint16_t>(machInst, vd, vn, vm, index); 1141 case 2: 1142 return new VmlssQ<uint32_t>(machInst, vd, vn, vm, index); 1143 default: 1144 return new Unknown(machInst); 1145 } 1146 } else { 1147 switch (size) { 1148 case 1: 1149 return new VmlssD<uint16_t>(machInst, vd, vn, vm, index); 1150 case 2: 1151 return new VmlssD<uint32_t>(machInst, vd, vn, vm, index); 1152 default: 1153 return new Unknown(machInst); 1154 } 1155 } |
1156 case 0x5: |
1157 if (u) 1158 return new VmlssQFp<float>(machInst, vd, vn, vm, index); 1159 else 1160 return new VmlssDFp<float>(machInst, vd, vn, vm, index); |
1161 case 0x2: |
1162 if (u) { 1163 switch (size) { 1164 case 1: 1165 return new Vmlals<uint16_t>(machInst, vd, vn, vm, index); 1166 case 2: 1167 return new Vmlals<uint32_t>(machInst, vd, vn, vm, index); 1168 default: 1169 return new Unknown(machInst); 1170 } 1171 } else { 1172 switch (size) { 1173 case 1: 1174 return new Vmlals<int16_t>(machInst, vd, vn, vm, index); 1175 case 2: 1176 return new Vmlals<int32_t>(machInst, vd, vn, vm, index); 1177 default: 1178 return new Unknown(machInst); 1179 } 1180 } |
1181 case 0x6: |
1182 if (u) { 1183 switch (size) { 1184 case 1: 1185 return new Vmlsls<uint16_t>(machInst, vd, vn, vm, index); 1186 case 2: 1187 return new Vmlsls<uint32_t>(machInst, vd, vn, vm, index); 1188 default: 1189 return new Unknown(machInst); 1190 } 1191 } else { 1192 switch (size) { 1193 case 1: 1194 return new Vmlsls<int16_t>(machInst, vd, vn, vm, index); 1195 case 2: 1196 return new Vmlsls<int32_t>(machInst, vd, vn, vm, index); 1197 default: 1198 return new Unknown(machInst); 1199 } 1200 } |
1201 case 0x3: 1202 if (u) { 1203 return new Unknown(machInst); 1204 } else { |
1205 switch (size) { 1206 case 1: 1207 return new Vqdmlals<int16_t>(machInst, vd, vn, vm, index); 1208 case 2: 1209 return new Vqdmlals<int32_t>(machInst, vd, vn, vm, index); 1210 default: 1211 return new Unknown(machInst); 1212 } |
1213 } 1214 case 0x7: 1215 if (u) { 1216 return new Unknown(machInst); 1217 } else { |
1218 switch (size) { 1219 case 1: 1220 return new Vqdmlsls<int16_t>(machInst, vd, vn, vm, index); 1221 case 2: 1222 return new Vqdmlsls<int32_t>(machInst, vd, vn, vm, index); 1223 default: 1224 return new Unknown(machInst); 1225 } |
1226 } 1227 case 0x8: |
1228 if (u) { 1229 switch (size) { 1230 case 1: 1231 return new VmulsQ<uint16_t>(machInst, vd, vn, vm, index); 1232 case 2: 1233 return new VmulsQ<uint32_t>(machInst, vd, vn, vm, index); 1234 default: 1235 return new Unknown(machInst); 1236 } 1237 } else { 1238 switch (size) { 1239 case 1: 1240 return new VmulsD<uint16_t>(machInst, vd, vn, vm, index); 1241 case 2: 1242 return new VmulsD<uint32_t>(machInst, vd, vn, vm, index); 1243 default: 1244 return new Unknown(machInst); 1245 } 1246 } |
1247 case 0x9: |
1248 if (u) 1249 return new VmulsQFp<float>(machInst, vd, vn, vm, index); 1250 else 1251 return new VmulsDFp<float>(machInst, vd, vn, vm, index); |
1252 case 0xa: |
1253 if (u) { 1254 switch (size) { 1255 case 1: 1256 return new Vmulls<uint16_t>(machInst, vd, vn, vm, index); 1257 case 2: 1258 return new Vmulls<uint32_t>(machInst, vd, vn, vm, index); 1259 default: 1260 return new Unknown(machInst); 1261 } 1262 } else { 1263 switch (size) { 1264 case 1: 1265 return new Vmulls<int16_t>(machInst, vd, vn, vm, index); 1266 case 2: 1267 return new Vmulls<int32_t>(machInst, vd, vn, vm, index); 1268 default: 1269 return new Unknown(machInst); 1270 } 1271 } |
1272 case 0xb: 1273 if (u) { 1274 return new Unknown(machInst); 1275 } else { |
1276 if (u) { 1277 switch (size) { 1278 case 1: 1279 return new Vqdmulls<uint16_t>( 1280 machInst, vd, vn, vm, index); 1281 case 2: 1282 return new Vqdmulls<uint32_t>( 1283 machInst, vd, vn, vm, index); 1284 default: 1285 return new Unknown(machInst); 1286 } 1287 } else { 1288 switch (size) { 1289 case 1: 1290 return new Vqdmulls<int16_t>( 1291 machInst, vd, vn, vm, index); 1292 case 2: 1293 return new Vqdmulls<int32_t>( 1294 machInst, vd, vn, vm, index); 1295 default: 1296 return new Unknown(machInst); 1297 } 1298 } |
1299 } 1300 case 0xc: |
1301 if (u) { 1302 switch (size) { 1303 case 1: 1304 return new VqdmulhsQ<int16_t>( 1305 machInst, vd, vn, vm, index); 1306 case 2: 1307 return new VqdmulhsQ<int32_t>( 1308 machInst, vd, vn, vm, index); 1309 default: 1310 return new Unknown(machInst); 1311 } 1312 } else { 1313 switch (size) { 1314 case 1: 1315 return new VqdmulhsD<int16_t>( 1316 machInst, vd, vn, vm, index); 1317 case 2: 1318 return new VqdmulhsD<int32_t>( 1319 machInst, vd, vn, vm, index); 1320 default: 1321 return new Unknown(machInst); 1322 } 1323 } |
1324 case 0xd: |
1325 if (u) { 1326 switch (size) { 1327 case 1: 1328 return new VqrdmulhsQ<int16_t>( 1329 machInst, vd, vn, vm, index); 1330 case 2: 1331 return new VqrdmulhsQ<int32_t>( 1332 machInst, vd, vn, vm, index); 1333 default: 1334 return new Unknown(machInst); 1335 } 1336 } else { 1337 switch (size) { 1338 case 1: 1339 return new VqrdmulhsD<int16_t>( 1340 machInst, vd, vn, vm, index); 1341 case 2: 1342 return new VqrdmulhsD<int32_t>( 1343 machInst, vd, vn, vm, index); 1344 default: 1345 return new Unknown(machInst); 1346 } 1347 } |
1348 } 1349 return new Unknown(machInst); 1350 } 1351 1352 static StaticInstPtr 1353 decodeNeonTwoRegMisc(ExtMachInst machInst) 1354 { 1355 const uint32_t a = bits(machInst, 17, 16); 1356 const uint32_t b = bits(machInst, 10, 6); |
1357 const bool q = bits(machInst, 6); 1358 const IntRegIndex vd = 1359 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 1360 (bits(machInst, 22) << 4))); 1361 const IntRegIndex vm = 1362 (IntRegIndex)(2 * (bits(machInst, 3, 0) | 1363 (bits(machInst, 5) << 4))); 1364 const unsigned size = bits(machInst, 19, 18); |
1365 switch (a) { 1366 case 0x0: 1367 switch (bits(b, 4, 1)) { 1368 case 0x0: |
1369 switch (size) { 1370 case 0: 1371 if (q) { 1372 return new NVrev64Q<uint8_t>(machInst, vd, vm); 1373 } else { 1374 return new NVrev64D<uint8_t>(machInst, vd, vm); 1375 } 1376 case 1: 1377 if (q) { 1378 return new NVrev64Q<uint16_t>(machInst, vd, vm); 1379 } else { 1380 return new NVrev64D<uint16_t>(machInst, vd, vm); 1381 } 1382 case 2: 1383 if (q) { 1384 return new NVrev64Q<uint32_t>(machInst, vd, vm); 1385 } else { 1386 return new NVrev64D<uint32_t>(machInst, vd, vm); 1387 } 1388 default: 1389 return new Unknown(machInst); 1390 } |
1391 case 0x1: |
1392 switch (size) { 1393 case 0: 1394 if (q) { 1395 return new NVrev32Q<uint8_t>(machInst, vd, vm); 1396 } else { 1397 return new NVrev32D<uint8_t>(machInst, vd, vm); 1398 } 1399 case 1: 1400 if (q) { 1401 return new NVrev32Q<uint16_t>(machInst, vd, vm); 1402 } else { 1403 return new NVrev32D<uint16_t>(machInst, vd, vm); 1404 } 1405 default: 1406 return new Unknown(machInst); 1407 } |
1408 case 0x2: |
1409 if (size != 0) { 1410 return new Unknown(machInst); 1411 } else if (q) { 1412 return new NVrev16Q<uint8_t>(machInst, vd, vm); 1413 } else { 1414 return new NVrev16D<uint8_t>(machInst, vd, vm); 1415 } |
1416 case 0x4: |
1417 return decodeNeonSTwoMiscSReg<NVpaddlD, NVpaddlQ>( 1418 q, size, machInst, vd, vm); |
1419 case 0x5: |
1420 return decodeNeonUTwoMiscSReg<NVpaddlD, NVpaddlQ>( 1421 q, size, machInst, vd, vm); |
1422 case 0x8: |
1423 return decodeNeonSTwoMiscReg<NVclsD, NVclsQ>( 1424 q, size, machInst, vd, vm); |
1425 case 0x9: |
1426 return decodeNeonSTwoMiscReg<NVclzD, NVclzQ>( 1427 q, size, machInst, vd, vm); |
1428 case 0xa: |
1429 return decodeNeonUTwoMiscReg<NVcntD, NVcntQ>( 1430 q, size, machInst, vd, vm); |
1431 case 0xb: |
1432 if (q) 1433 return new NVmvnQ<uint64_t>(machInst, vd, vm); 1434 else 1435 return new NVmvnD<uint64_t>(machInst, vd, vm); |
1436 case 0xc: |
1437 return decodeNeonSTwoMiscSReg<NVpadalD, NVpadalQ>( 1438 q, size, machInst, vd, vm); |
1439 case 0xd: |
1440 return decodeNeonUTwoMiscSReg<NVpadalD, NVpadalQ>( 1441 q, size, machInst, vd, vm); |
1442 case 0xe: |
1443 return decodeNeonSTwoMiscReg<NVqabsD, NVqabsQ>( 1444 q, size, machInst, vd, vm); |
1445 case 0xf: |
1446 return decodeNeonSTwoMiscReg<NVqnegD, NVqnegQ>( 1447 q, size, machInst, vd, vm); |
1448 default: 1449 return new Unknown(machInst); 1450 } 1451 case 0x1: 1452 switch (bits(b, 3, 1)) { 1453 case 0x0: |
1454 if (bits(b, 4)) { 1455 if (q) { 1456 return new NVcgtQFp<float>(machInst, vd, vm); 1457 } else { 1458 return new NVcgtDFp<float>(machInst, vd, vm); 1459 } 1460 } else { 1461 return decodeNeonSTwoMiscReg<NVcgtD, NVcgtQ>( 1462 q, size, machInst, vd, vm); 1463 } |
1464 case 0x1: |
1465 if (bits(b, 4)) { 1466 if (q) { 1467 return new NVcgeQFp<float>(machInst, vd, vm); 1468 } else { 1469 return new NVcgeDFp<float>(machInst, vd, vm); 1470 } 1471 } else { 1472 return decodeNeonSTwoMiscReg<NVcgeD, NVcgeQ>( 1473 q, size, machInst, vd, vm); 1474 } |
1475 case 0x2: |
1476 if (bits(b, 4)) { 1477 if (q) { 1478 return new NVceqQFp<float>(machInst, vd, vm); 1479 } else { 1480 return new NVceqDFp<float>(machInst, vd, vm); 1481 } 1482 } else { 1483 return decodeNeonSTwoMiscReg<NVceqD, NVceqQ>( 1484 q, size, machInst, vd, vm); 1485 } |
1486 case 0x3: |
1487 if (bits(b, 4)) { 1488 if (q) { 1489 return new NVcleQFp<float>(machInst, vd, vm); 1490 } else { 1491 return new NVcleDFp<float>(machInst, vd, vm); 1492 } 1493 } else { 1494 return decodeNeonSTwoMiscReg<NVcleD, NVcleQ>( 1495 q, size, machInst, vd, vm); 1496 } |
1497 case 0x4: |
1498 if (bits(b, 4)) { 1499 if (q) { 1500 return new NVcltQFp<float>(machInst, vd, vm); 1501 } else { 1502 return new NVcltDFp<float>(machInst, vd, vm); 1503 } 1504 } else { 1505 return decodeNeonSTwoMiscReg<NVcltD, NVcltQ>( 1506 q, size, machInst, vd, vm); 1507 } |
1508 case 0x6: |
1509 if (bits(machInst, 10)) { 1510 if (q) 1511 return new NVabsQFp<float>(machInst, vd, vm); 1512 else 1513 return new NVabsDFp<float>(machInst, vd, vm); 1514 } else { 1515 return decodeNeonSTwoMiscReg<NVabsD, NVabsQ>( 1516 q, size, machInst, vd, vm); 1517 } |
1518 case 0x7: |
1519 if (bits(machInst, 10)) { 1520 if (q) 1521 return new NVnegQFp<float>(machInst, vd, vm); 1522 else 1523 return new NVnegDFp<float>(machInst, vd, vm); 1524 } else { 1525 return decodeNeonSTwoMiscReg<NVnegD, NVnegQ>( 1526 q, size, machInst, vd, vm); 1527 } |
1528 } 1529 case 0x2: 1530 switch (bits(b, 4, 1)) { 1531 case 0x0: |
1532 if (q) 1533 return new NVswpQ<uint64_t>(machInst, vd, vm); 1534 else 1535 return new NVswpD<uint64_t>(machInst, vd, vm); |
1536 case 0x1: |
1537 return decodeNeonUTwoMiscReg<NVtrnD, NVtrnQ>( 1538 q, size, machInst, vd, vm); |
1539 case 0x2: |
1540 return decodeNeonUTwoMiscReg<NVuzpD, NVuzpQ>( 1541 q, size, machInst, vd, vm); |
1542 case 0x3: |
1543 return decodeNeonUTwoMiscReg<NVzipD, NVzipQ>( 1544 q, size, machInst, vd, vm); |
1545 case 0x4: 1546 if (b == 0x8) { |
1547 return decodeNeonUTwoMiscUSReg<NVmovn>( 1548 size, machInst, vd, vm); |
1549 } else { |
1550 return decodeNeonSTwoMiscUSReg<NVqmovuns>( 1551 size, machInst, vd, vm); |
1552 } 1553 case 0x5: |
1554 if (q) { 1555 return decodeNeonUTwoMiscUSReg<NVqmovun>( 1556 size, machInst, vd, vm); 1557 } else { 1558 return decodeNeonSTwoMiscUSReg<NVqmovn>( 1559 size, machInst, vd, vm); 1560 } |
1561 case 0x6: 1562 if (b == 0xc) { |
1563 const IntRegIndex vd = 1564 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 1565 (bits(machInst, 22) << 4))); 1566 const IntRegIndex vm = 1567 (IntRegIndex)(2 * (bits(machInst, 3, 0) | 1568 (bits(machInst, 5) << 4))); 1569 unsigned size = bits(machInst, 19, 18); 1570 return decodeNeonSTwoShiftUSReg<NVshll>( 1571 size, machInst, vd, vm, 8 << size); |
1572 } else { 1573 return new Unknown(machInst); 1574 } 1575 case 0xc: 1576 case 0xe: 1577 if (b == 0x18) { |
1578 if (size != 1 || (vm % 2)) 1579 return new Unknown(machInst); 1580 return new NVcvts2h<uint16_t>(machInst, vd, vm); |
1581 } else if (b == 0x1c) { |
1582 if (size != 1 || (vd % 2)) 1583 return new Unknown(machInst); 1584 return new NVcvth2s<uint16_t>(machInst, vd, vm); |
1585 } else { 1586 return new Unknown(machInst); 1587 } 1588 default: 1589 return new Unknown(machInst); 1590 } 1591 case 0x3: 1592 if (bits(b, 4, 3) == 0x3) { |
1593 if ((q && (vd % 2 || vm % 2)) || size != 2) { 1594 return new Unknown(machInst); 1595 } else { 1596 if (bits(b, 2)) { 1597 if (bits(b, 1)) { 1598 if (q) { 1599 return new NVcvt2ufxQ<float>( 1600 machInst, vd, vm, 0); 1601 } else { 1602 return new NVcvt2ufxD<float>( 1603 machInst, vd, vm, 0); 1604 } 1605 } else { 1606 if (q) { 1607 return new NVcvt2sfxQ<float>( 1608 machInst, vd, vm, 0); 1609 } else { 1610 return new NVcvt2sfxD<float>( 1611 machInst, vd, vm, 0); 1612 } 1613 } 1614 } else { 1615 if (bits(b, 1)) { 1616 if (q) { 1617 return new NVcvtu2fpQ<float>( 1618 machInst, vd, vm, 0); 1619 } else { 1620 return new NVcvtu2fpD<float>( 1621 machInst, vd, vm, 0); 1622 } 1623 } else { 1624 if (q) { 1625 return new NVcvts2fpQ<float>( 1626 machInst, vd, vm, 0); 1627 } else { 1628 return new NVcvts2fpD<float>( 1629 machInst, vd, vm, 0); 1630 } 1631 } 1632 } 1633 } |
1634 } else if ((b & 0x1a) == 0x10) { |
1635 if (bits(b, 2)) { 1636 if (q) { 1637 return new NVrecpeQFp<float>(machInst, vd, vm); 1638 } else { 1639 return new NVrecpeDFp<float>(machInst, vd, vm); 1640 } 1641 } else { 1642 if (q) { 1643 return new NVrecpeQ<uint32_t>(machInst, vd, vm); 1644 } else { 1645 return new NVrecpeD<uint32_t>(machInst, vd, vm); 1646 } 1647 } |
1648 } else if ((b & 0x1a) == 0x12) { |
1649 if (bits(b, 2)) { 1650 if (q) { 1651 return new NVrsqrteQFp<float>(machInst, vd, vm); 1652 } else { 1653 return new NVrsqrteDFp<float>(machInst, vd, vm); 1654 } 1655 } else { 1656 if (q) { 1657 return new NVrsqrteQ<uint32_t>(machInst, vd, vm); 1658 } else { 1659 return new NVrsqrteD<uint32_t>(machInst, vd, vm); 1660 } 1661 } |
1662 } else { 1663 return new Unknown(machInst); 1664 } 1665 } 1666 return new Unknown(machInst); 1667 } 1668 1669 StaticInstPtr --- 8 unchanged lines hidden (view full) --- 1678 } else if ((c & 0x9) == 1) { 1679 if ((a & 0x7) == 0) { 1680 return decodeNeonOneRegModImm(machInst); 1681 } else { 1682 return decodeNeonTwoRegAndShift(machInst); 1683 } 1684 } else if ((c & 0x9) == 9) { 1685 return decodeNeonTwoRegAndShift(machInst); |
1686 } else if (bits(a, 2, 1) != 0x3) { 1687 if ((c & 0x5) == 0) { |
1688 return decodeNeonThreeRegDiffLengths(machInst); |
1689 } else if ((c & 0x5) == 4) { |
1690 return decodeNeonTwoRegScalar(machInst); 1691 } 1692 } else if ((a & 0x16) == 0x16) { |
1693 const IntRegIndex vd = 1694 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 1695 (bits(machInst, 22) << 4))); 1696 const IntRegIndex vn = 1697 (IntRegIndex)(2 * (bits(machInst, 19, 16) | 1698 (bits(machInst, 7) << 4))); 1699 const IntRegIndex vm = 1700 (IntRegIndex)(2 * (bits(machInst, 3, 0) | 1701 (bits(machInst, 5) << 4))); |
1702 if (!u) { 1703 if (bits(c, 0) == 0) { |
1704 unsigned imm4 = bits(machInst, 11, 8); 1705 bool q = bits(machInst, 6); 1706 if (imm4 >= 16 && !q) 1707 return new Unknown(machInst); 1708 if (q) { 1709 return new NVextQ<uint8_t>(machInst, vd, vn, vm, imm4); 1710 } else { 1711 return new NVextD<uint8_t>(machInst, vd, vn, vm, imm4); 1712 } |
1713 } 1714 } else if (bits(b, 3) == 0 && bits(c, 0) == 0) { 1715 return decodeNeonTwoRegMisc(machInst); 1716 } else if (bits(b, 3, 2) == 0x2 && bits(c, 0) == 0) { |
1717 unsigned length = bits(machInst, 9, 8) + 1; 1718 if ((uint32_t)vn / 2 + length > 32) 1719 return new Unknown(machInst); |
1720 if (bits(machInst, 6) == 0) { |
1721 switch (length) { 1722 case 1: 1723 return new NVtbl1(machInst, vd, vn, vm); 1724 case 2: 1725 return new NVtbl2(machInst, vd, vn, vm); 1726 case 3: 1727 return new NVtbl3(machInst, vd, vn, vm); 1728 case 4: 1729 return new NVtbl4(machInst, vd, vn, vm); 1730 } |
1731 } else { |
1732 switch (length) { 1733 case 1: 1734 return new NVtbx1(machInst, vd, vn, vm); 1735 case 2: 1736 return new NVtbx2(machInst, vd, vn, vm); 1737 case 3: 1738 return new NVtbx3(machInst, vd, vn, vm); 1739 case 4: 1740 return new NVtbx4(machInst, vd, vn, vm); 1741 } |
1742 } 1743 } else if (b == 0xc && (c & 0x9) == 0) { |
1744 unsigned imm4 = bits(machInst, 19, 16); 1745 if (bits(imm4, 2, 0) == 0) 1746 return new Unknown(machInst); 1747 unsigned size = 0; 1748 while ((imm4 & 0x1) == 0) { 1749 size++; 1750 imm4 >>= 1; 1751 } 1752 unsigned index = imm4 >> 1; 1753 const bool q = bits(machInst, 6); 1754 return decodeNeonUTwoShiftSReg<NVdupD, NVdupQ>( 1755 q, size, machInst, vd, vm, index); |
1756 } 1757 } 1758 return new Unknown(machInst); 1759 } 1760 ''' 1761}}; 1762 1763def format ThumbNeonMem() {{ 1764 decode_block = ''' 1765 return decodeNeonMem(machInst); 1766 ''' 1767}}; 1768 1769def format ThumbNeonData() {{ 1770 decode_block = ''' |
1771 return decodeNeonData(machInst); |
1772 ''' 1773}}; 1774 1775let {{ 1776 header_output = ''' 1777 StaticInstPtr 1778 decodeExtensionRegLoadStore(ExtMachInst machInst); 1779 ''' --- 39 unchanged lines hidden (view full) --- 1819 } else { 1820 return new Vmov2Reg2Core(machInst, (IntRegIndex)vm, 1821 rt, rt2); 1822 } 1823 } 1824 break; 1825 case 0x1: 1826 { |
1827 if (offset == 0 || vd + offset/2 > NumFloatArchRegs) { |
1828 break; 1829 } 1830 switch (bits(opcode, 1, 0)) { 1831 case 0x0: 1832 return new VLdmStm(machInst, rn, vd, single, 1833 true, false, false, offset); 1834 case 0x1: 1835 return new VLdmStm(machInst, rn, vd, single, --- 134 unchanged lines hidden (view full) --- 1970 return new Unknown(machInst); 1971 } 1972 return new Vmsr(machInst, (IntRegIndex)specReg, rt); 1973 } 1974 } else if (l == 0 && c == 1) { 1975 if (bits(a, 2) == 0) { 1976 uint32_t vd = (bits(machInst, 7) << 5) | 1977 (bits(machInst, 19, 16) << 1); |
1978 // Handle accessing each single precision half of the vector. 1979 vd += bits(machInst, 21); |
1980 const IntRegIndex rt = 1981 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 1982 if (bits(machInst, 22) == 1) { |
1983 return new VmovCoreRegB(machInst, (IntRegIndex)vd, 1984 rt, bits(machInst, 6, 5)); |
1985 } else if (bits(machInst, 5) == 1) { |
1986 return new VmovCoreRegH(machInst, (IntRegIndex)vd, 1987 rt, bits(machInst, 6)); |
1988 } else if (bits(machInst, 6) == 0) { |
1989 return new VmovCoreRegW(machInst, (IntRegIndex)vd, rt); |
1990 } else { 1991 return new Unknown(machInst); 1992 } |
1993 } else if (bits(b, 1) == 0) { |
1994 bool q = bits(machInst, 21); 1995 unsigned be = (bits(machInst, 22) << 1) | (bits(machInst, 5)); 1996 IntRegIndex vd = (IntRegIndex)(2 * (uint32_t) 1997 (bits(machInst, 19, 16) | (bits(machInst, 7) << 4))); 1998 IntRegIndex rt = (IntRegIndex)(uint32_t) 1999 bits(machInst, 15, 12); 2000 if (q) { 2001 switch (be) { 2002 case 0: 2003 return new NVdupQGpr<uint32_t>(machInst, vd, rt); 2004 case 1: 2005 return new NVdupQGpr<uint16_t>(machInst, vd, rt); 2006 case 2: 2007 return new NVdupQGpr<uint8_t>(machInst, vd, rt); 2008 case 3: 2009 return new Unknown(machInst); 2010 } 2011 } else { 2012 switch (be) { 2013 case 0: 2014 return new NVdupDGpr<uint32_t>(machInst, vd, rt); 2015 case 1: 2016 return new NVdupDGpr<uint16_t>(machInst, vd, rt); 2017 case 2: 2018 return new NVdupDGpr<uint8_t>(machInst, vd, rt); 2019 case 3: 2020 return new Unknown(machInst); 2021 } 2022 } |
2023 } 2024 } else if (l == 1 && c == 0) { 2025 if (a == 0) { 2026 const uint32_t vn = (bits(machInst, 19, 16) << 1) | 2027 bits(machInst, 7); 2028 const IntRegIndex rt = 2029 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2030 if (bits(machInst, 20) == 1) { --- 34 unchanged lines hidden (view full) --- 2065 (IntRegIndex)specReg, (uint32_t)cpsrMask); 2066 } else { 2067 return new Vmrs(machInst, rt, (IntRegIndex)specReg); 2068 } 2069 } 2070 } else { 2071 uint32_t vd = (bits(machInst, 7) << 5) | 2072 (bits(machInst, 19, 16) << 1); |
2073 // Handle indexing into each single precision half of the vector. 2074 vd += bits(machInst, 21); 2075 uint32_t index; |
2076 const IntRegIndex rt = 2077 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2078 const bool u = (bits(machInst, 23) == 1); 2079 if (bits(machInst, 22) == 1) { |
2080 index = bits(machInst, 6, 5); |
2081 if (u) { 2082 return new VmovRegCoreUB(machInst, rt, 2083 (IntRegIndex)vd, index); 2084 } else { 2085 return new VmovRegCoreSB(machInst, rt, 2086 (IntRegIndex)vd, index); 2087 } |
2088 } else if (bits(machInst, 5) == 1) { 2089 index = bits(machInst, 6); |
2090 if (u) { 2091 return new VmovRegCoreUH(machInst, rt, 2092 (IntRegIndex)vd, index); 2093 } else { 2094 return new VmovRegCoreSH(machInst, rt, 2095 (IntRegIndex)vd, index); 2096 } |
2097 } else if (bits(machInst, 6) == 0 && !u) { |
2098 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vd); |
2099 } else { 2100 return new Unknown(machInst); |
2101 } 2102 } 2103 return new Unknown(machInst); 2104 } 2105 ''' 2106}}; 2107 2108def format ShortFpTransfer() {{ --- 385 unchanged lines hidden --- |