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 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 = TLB::MustBeOne; 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 align = size | TLB::AllowUnaligned; 155 if (width == 1) { 156 regs = t ? 2 : 1; 157 inc = 1; 158 } else { 159 regs = width; 160 inc = t ? 2 : 1; 161 } 162 switch (width) { 163 case 1: 164 case 2: 165 if (bits(machInst, 4)) 166 align = size + width - 1; 167 break; 168 case 3: 169 break; 170 case 4: 171 if (size == 3) { 172 if (bits(machInst, 4) == 0) 173 return new Unknown(machInst); 174 size = 2; 175 align = 0x4; 176 } else if (size == 2) { 177 if (bits(machInst, 4)) 178 align = 0x3; 179 } else { 180 if (bits(machInst, 4)) 181 align = size + 2; 182 } 183 break; 184 } 185 } else { 186 size = bits(machInst, 11, 10); 187 align = size | TLB::AllowUnaligned; 188 regs = width; 189 unsigned indexAlign = bits(machInst, 7, 4); 190 // If width is 1, inc is always 1. That's overridden later. 191 switch (size) { 192 case 0: 193 inc = 1; 194 lane = bits(indexAlign, 3, 1); 195 break; 196 case 1: 197 inc = bits(indexAlign, 1) ? 2 : 1; 198 lane = bits(indexAlign, 3, 2); 199 break; 200 case 2: 201 inc = bits(indexAlign, 2) ? 2 : 1; 202 lane = bits(indexAlign, 3); 203 break; 204 } 205 // Override inc for width of 1. 206 if (width == 1) { 207 inc = 1; 208 } 209 switch (width) { 210 case 1: 211 switch (size) { 212 case 0: 213 break; 214 case 1: 215 if (bits(indexAlign, 0)) 216 align = 1; 217 break; 218 case 2: 219 if (bits(indexAlign, 1, 0)) 220 align = 2; 221 break; 222 } 223 break; 224 case 2: 225 if (bits(indexAlign, 0)) 226 align = size + 1; 227 break; 228 case 3: 229 break; 230 case 4: 231 switch (size) { 232 case 0: 233 case 1: 234 if (bits(indexAlign, 0)) 235 align = size + 2; 236 break; 237 case 2: 238 if (bits(indexAlign, 0)) 239 align = bits(indexAlign, 1, 0) + 2; 240 break; 241 } 242 break; 243 } 244 } 245 if (size == 0x3) { 246 return new Unknown(machInst); 247 } 248 } else { 249 size = bits(machInst, 7, 6); 250 align = bits(machInst, 5, 4); 251 if (align == 0) { 252 // @align wasn't specified, so alignment can be turned off. 253 align = size | TLB::AllowUnaligned; 254 } else { 255 align = align + 2; 256 } 257 switch (width) { 258 case 1: 259 switch (type) { 260 case 0x7: regs = 1; 261 break; 262 case 0xa: regs = 2; 263 break; 264 case 0x6: regs = 3; 265 break; 266 case 0x2: regs = 4; 267 break; 268 default: 269 return new Unknown(machInst); 270 } 271 break; 272 case 2: 273 // Regs doesn't behave exactly as it does in the manual 274 // because they loop over regs registers twice and we break 275 // it down in the macroop. 276 switch (type) { 277 case 0x8: regs = 2; inc = 1; 278 break; 279 case 0x9: regs = 2; inc = 2; 280 break; 281 case 0x3: regs = 4; inc = 2; 282 break; 283 default: 284 return new Unknown(machInst); 285 } 286 break; 287 case 3: 288 regs = 3; 289 switch (type) { 290 case 0x4: inc = 1; 291 break; 292 case 0x5: inc = 2;; 293 break; 294 default: 295 return new Unknown(machInst); 296 } 297 break; 298 case 4: 299 regs = 4; 300 switch (type) { 301 case 0: inc = 1; 302 break; 303 case 1: inc = 2; 304 break; 305 default: 306 return new Unknown(machInst); 307 } 308 break; 309 } 310 } 311 312 if (load) { 313 // Load instructions. 314 if (single) { 315 return new VldSingle(machInst, singleAll, width, rn, vd, 316 regs, inc, size, align, rm, lane); 317 } else { 318 return new VldMult(machInst, width, rn, vd, 319 regs, inc, size, align, rm); 320 } 321 } else { 322 // Store instructions. 323 if (single) { 324 if (singleAll) { 325 return new Unknown(machInst); 326 } else { 327 return new VstSingle(machInst, false, width, rn, vd, 328 regs, inc, size, align, rm, lane); 329 } 330 } else { 331 return new VstMult(machInst, width, rn, vd, 332 regs, inc, size, align, rm); 333 } 334 } 335 return new Unknown(machInst); 336 } 337 ''' 338 339 decoder_output += ''' 340 static StaticInstPtr 341 decodeNeonThreeRegistersSameLength(ExtMachInst machInst) 342 { 343 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 344 const uint32_t a = bits(machInst, 11, 8); 345 const bool b = bits(machInst, 4); 346 const uint32_t c = bits(machInst, 21, 20); 347 const IntRegIndex vd = 348 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 349 (bits(machInst, 22) << 4))); 350 const IntRegIndex vn = 351 (IntRegIndex)(2 * (bits(machInst, 19, 16) | 352 (bits(machInst, 7) << 4))); 353 const IntRegIndex vm = 354 (IntRegIndex)(2 * (bits(machInst, 3, 0) | 355 (bits(machInst, 5) << 4))); 356 const unsigned size = bits(machInst, 21, 20); 357 const bool q = bits(machInst, 6); 358 if (q && ((vd & 0x1) || (vn & 0x1) || (vm & 0x1))) 359 return new Unknown(machInst); 360 switch (a) { 361 case 0x0: 362 if (b) { 363 if (u) { 364 return decodeNeonUThreeReg<VqaddUD, VqaddUQ>( 365 q, size, machInst, vd, vn, vm); 366 } else { 367 return decodeNeonSThreeReg<VqaddSD, VqaddSQ>( 368 q, size, machInst, vd, vn, vm); 369 } 370 } else { 371 if (size == 3) 372 return new Unknown(machInst); 373 return decodeNeonUSThreeReg<VhaddD, VhaddQ>( 374 q, u, size, machInst, vd, vn, vm); 375 } 376 case 0x1: 377 if (!b) { 378 return decodeNeonUSThreeReg<VrhaddD, VrhaddQ>( 379 q, u, size, machInst, vd, vn, vm); 380 } else { 381 if (u) { 382 switch (c) { 383 case 0: 384 if (q) { 385 return new VeorQ<uint64_t>(machInst, vd, vn, vm); 386 } else { 387 return new VeorD<uint64_t>(machInst, vd, vn, vm); 388 } 389 case 1: 390 if (q) { 391 return new VbslQ<uint64_t>(machInst, vd, vn, vm); 392 } else { 393 return new VbslD<uint64_t>(machInst, vd, vn, vm); 394 } 395 case 2: 396 if (q) { 397 return new VbitQ<uint64_t>(machInst, vd, vn, vm); 398 } else { 399 return new VbitD<uint64_t>(machInst, vd, vn, vm); 400 } 401 case 3: 402 if (q) { 403 return new VbifQ<uint64_t>(machInst, vd, vn, vm); 404 } else { 405 return new VbifD<uint64_t>(machInst, vd, vn, vm); 406 } 407 } 408 } else { 409 switch (c) { 410 case 0: 411 if (q) { 412 return new VandQ<uint64_t>(machInst, vd, vn, vm); 413 } else { 414 return new VandD<uint64_t>(machInst, vd, vn, vm); 415 } 416 case 1: 417 if (q) { 418 return new VbicQ<uint64_t>(machInst, vd, vn, vm); 419 } else { 420 return new VbicD<uint64_t>(machInst, vd, vn, vm); 421 } 422 case 2: 423 if (vn == vm) { 424 if (q) { 425 return new VmovQ<uint64_t>( 426 machInst, vd, vn, vm); 427 } else { 428 return new VmovD<uint64_t>( 429 machInst, vd, vn, vm); 430 } 431 } else { 432 if (q) { 433 return new VorrQ<uint64_t>( 434 machInst, vd, vn, vm); 435 } else { 436 return new VorrD<uint64_t>( 437 machInst, vd, vn, vm); 438 } 439 } 440 case 3: 441 if (q) { 442 return new VornQ<uint64_t>( 443 machInst, vd, vn, vm); 444 } else { 445 return new VornD<uint64_t>( 446 machInst, vd, vn, vm); 447 } 448 } 449 } 450 } 451 case 0x2: 452 if (b) { 453 if (u) { 454 return decodeNeonUThreeReg<VqsubUD, VqsubUQ>( 455 q, size, machInst, vd, vn, vm); 456 } else { 457 return decodeNeonSThreeReg<VqsubSD, VqsubSQ>( 458 q, size, machInst, vd, vn, vm); 459 } 460 } else { 461 if (size == 3) 462 return new Unknown(machInst); 463 return decodeNeonUSThreeReg<VhsubD, VhsubQ>( 464 q, u, size, machInst, vd, vn, vm); 465 } 466 case 0x3: 467 if (b) { 468 return decodeNeonUSThreeReg<VcgeD, VcgeQ>( 469 q, u, size, machInst, vd, vn, vm); 470 } else { 471 return decodeNeonUSThreeReg<VcgtD, VcgtQ>( 472 q, u, size, machInst, vd, vn, vm); 473 } 474 case 0x4: 475 if (b) { 476 if (u) { 477 return decodeNeonUThreeReg<VqshlUD, VqshlUQ>( 478 q, size, machInst, vd, vm, vn); 479 } else { 480 return decodeNeonSThreeReg<VqshlSD, VqshlSQ>( 481 q, size, machInst, vd, vm, vn); 482 } 483 } else { 484 return decodeNeonUSThreeReg<VshlD, VshlQ>( 485 q, u, size, machInst, vd, vm, vn); 486 } 487 case 0x5: 488 if (b) { 489 if (u) { 490 return decodeNeonUThreeReg<VqrshlUD, VqrshlUQ>( 491 q, size, machInst, vd, vm, vn); 492 } else { 493 return decodeNeonSThreeReg<VqrshlSD, VqrshlSQ>( 494 q, size, machInst, vd, vm, vn); 495 } 496 } else { 497 return decodeNeonUSThreeReg<VrshlD, VrshlQ>( 498 q, u, size, machInst, vd, vm, vn); 499 } 500 case 0x6: 501 if (b) { 502 return decodeNeonUSThreeReg<VminD, VminQ>( 503 q, u, size, machInst, vd, vn, vm); 504 } else { 505 return decodeNeonUSThreeReg<VmaxD, VmaxQ>( 506 q, u, size, machInst, vd, vn, vm); 507 } 508 case 0x7: 509 if (b) { 510 return decodeNeonUSThreeReg<VabaD, VabaQ>( 511 q, u, size, machInst, vd, vn, vm); 512 } else { 513 if (bits(machInst, 23) == 1) { 514 if (q) { 515 return new Unknown(machInst); 516 } else { 517 return decodeNeonUSThreeUSReg<Vabdl>( 518 u, size, machInst, vd, vn, vm); 519 } 520 } else { 521 return decodeNeonUSThreeReg<VabdD, VabdQ>( 522 q, u, size, machInst, vd, vn, vm); 523 } 524 } 525 case 0x8: 526 if (b) { 527 if (u) { 528 return decodeNeonUThreeReg<VceqD, VceqQ>( 529 q, size, machInst, vd, vn, vm); 530 } else { 531 return decodeNeonUThreeReg<VtstD, VtstQ>( 532 q, size, machInst, vd, vn, vm); 533 } 534 } else { 535 if (u) { 536 return decodeNeonUThreeReg<NVsubD, NVsubQ>( 537 q, size, machInst, vd, vn, vm); 538 } else { 539 return decodeNeonUThreeReg<NVaddD, NVaddQ>( 540 q, size, machInst, vd, vn, vm); 541 } 542 } 543 case 0x9: 544 if (b) { 545 if (u) { 546 return decodeNeonUThreeReg<NVmulpD, NVmulpQ>( 547 q, size, machInst, vd, vn, vm); 548 } else { 549 return decodeNeonSThreeReg<NVmulD, NVmulQ>( 550 q, size, machInst, vd, vn, vm); 551 } 552 } else { 553 if (u) { 554 return decodeNeonUSThreeReg<NVmlsD, NVmlsQ>( 555 q, u, size, machInst, vd, vn, vm); 556 } else { 557 return decodeNeonUSThreeReg<NVmlaD, NVmlaQ>( 558 q, u, size, machInst, vd, vn, vm); 559 } 560 } 561 case 0xa: 562 if (q) 563 return new Unknown(machInst); 564 if (b) { 565 return decodeNeonUSThreeUSReg<VpminD>( 566 u, size, machInst, vd, vn, vm); 567 } else { 568 return decodeNeonUSThreeUSReg<VpmaxD>( 569 u, size, machInst, vd, vn, vm); 570 } 571 case 0xb: 572 if (b) { 573 if (u || q) { 574 return new Unknown(machInst); 575 } else { 576 return decodeNeonUThreeUSReg<NVpaddD>( 577 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 if (b) { 590 if (!u) { 591 if (bits(c, 1) == 0) { 592 if (q) { 593 return new NVfmaQFp<float>(machInst, vd, vn, vm); 594 } else { 595 return new NVfmaDFp<float>(machInst, vd, vn, vm); 596 } 597 } else { 598 if (q) { 599 return new NVfmsQFp<float>(machInst, vd, vn, vm); 600 } else { 601 return new NVfmsDFp<float>(machInst, vd, vn, vm); 602 } 603 } 604 } 605 } 606 return new Unknown(machInst); 607 case 0xd: 608 if (b) { 609 if (u) { 610 if (bits(c, 1) == 0) { 611 if (q) { 612 return new NVmulQFp<float>(machInst, vd, vn, vm); 613 } else { 614 return new NVmulDFp<float>(machInst, vd, vn, vm); 615 } 616 } else { 617 return new Unknown(machInst); 618 } 619 } else { 620 if (bits(c, 1) == 0) { 621 if (q) { 622 return new NVmlaQFp<float>(machInst, vd, vn, vm); 623 } else { 624 return new NVmlaDFp<float>(machInst, vd, vn, vm); 625 } 626 } else { 627 if (q) { 628 return new NVmlsQFp<float>(machInst, vd, vn, vm); 629 } else { 630 return new NVmlsDFp<float>(machInst, vd, vn, vm); 631 } 632 } 633 } 634 } else { 635 if (u) { 636 if (bits(c, 1) == 0) { 637 if (q) { 638 return new VpaddQFp<float>(machInst, vd, vn, vm); 639 } else { 640 return new VpaddDFp<float>(machInst, vd, vn, vm); 641 } 642 } else { 643 if (q) { 644 return new VabdQFp<float>(machInst, vd, vn, vm); 645 } else { 646 return new VabdDFp<float>(machInst, vd, vn, vm); 647 } 648 } 649 } else { 650 if (bits(c, 1) == 0) { 651 if (q) { 652 return new VaddQFp<float>(machInst, vd, vn, vm); 653 } else { 654 return new VaddDFp<float>(machInst, vd, vn, vm); 655 } 656 } else { 657 if (q) { 658 return new VsubQFp<float>(machInst, vd, vn, vm); 659 } else { 660 return new VsubDFp<float>(machInst, vd, vn, vm); 661 } 662 } 663 } 664 } 665 case 0xe: 666 if (b) { 667 if (u) { 668 if (bits(c, 1) == 0) { 669 if (q) { 670 return new VacgeQFp<float>(machInst, vd, vn, vm); 671 } else { 672 return new VacgeDFp<float>(machInst, vd, vn, vm); 673 } 674 } else { 675 if (q) { 676 return new VacgtQFp<float>(machInst, vd, vn, vm); 677 } else { 678 return new VacgtDFp<float>(machInst, vd, vn, vm); 679 } 680 } 681 } else { 682 return new Unknown(machInst); 683 } 684 } else { 685 if (u) { 686 if (bits(c, 1) == 0) { 687 if (q) { 688 return new VcgeQFp<float>(machInst, vd, vn, vm); 689 } else { 690 return new VcgeDFp<float>(machInst, vd, vn, vm); 691 } 692 } else { 693 if (q) { 694 return new VcgtQFp<float>(machInst, vd, vn, vm); 695 } else { 696 return new VcgtDFp<float>(machInst, vd, vn, vm); 697 } 698 } 699 } else { 700 if (bits(c, 1) == 0) { 701 if (q) { 702 return new VceqQFp<float>(machInst, vd, vn, vm); 703 } else { 704 return new VceqDFp<float>(machInst, vd, vn, vm); 705 } 706 } else { 707 return new Unknown(machInst); 708 } 709 } 710 } 711 case 0xf: 712 if (b) { 713 if (u) { 714 return new Unknown(machInst); 715 } else { 716 if (bits(c, 1) == 0) { 717 if (q) { 718 return new VrecpsQFp<float>(machInst, vd, vn, vm); 719 } else { 720 return new VrecpsDFp<float>(machInst, vd, vn, vm); 721 } 722 } else { 723 if (q) { 724 return new VrsqrtsQFp<float>(machInst, vd, vn, vm); 725 } else { 726 return new VrsqrtsDFp<float>(machInst, vd, vn, vm); 727 } 728 } 729 } 730 } else { 731 if (u) { 732 if (bits(c, 1) == 0) { 733 if (q) { 734 return new VpmaxQFp<float>(machInst, vd, vn, vm); 735 } else { 736 return new VpmaxDFp<float>(machInst, vd, vn, vm); 737 } 738 } else { 739 if (q) { 740 return new VpminQFp<float>(machInst, vd, vn, vm); 741 } else { 742 return new VpminDFp<float>(machInst, vd, vn, vm); 743 } 744 } 745 } else { 746 if (bits(c, 1) == 0) { 747 if (q) { 748 return new VmaxQFp<float>(machInst, vd, vn, vm); 749 } else { 750 return new VmaxDFp<float>(machInst, vd, vn, vm); 751 } 752 } else { 753 if (q) { 754 return new VminQFp<float>(machInst, vd, vn, vm); 755 } else { 756 return new VminDFp<float>(machInst, vd, vn, vm); 757 } 758 } 759 } 760 } 761 } 762 return new Unknown(machInst); 763 } 764 765 static StaticInstPtr 766 decodeNeonOneRegModImm(ExtMachInst machInst) 767 { 768 const IntRegIndex vd = 769 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 770 (bits(machInst, 22) << 4))); 771 const bool q = bits(machInst, 6); 772 const bool op = bits(machInst, 5); 773 const uint8_t cmode = bits(machInst, 11, 8); 774 const uint8_t imm = ((THUMB ? bits(machInst, 28) : 775 bits(machInst, 24)) << 7) | 776 (bits(machInst, 18, 16) << 4) | 777 (bits(machInst, 3, 0) << 0); 778 779 // Check for invalid immediate encodings and return an unknown op 780 // if it happens 781 bool immValid = true; 782 const uint64_t bigImm = simd_modified_imm(op, cmode, imm, immValid); 783 if (!immValid) { 784 return new Unknown(machInst); 785 } 786 787 if (op) { 788 if (bits(cmode, 3) == 0) { 789 if (bits(cmode, 0) == 0) { 790 if (q) 791 return new NVmvniQ<uint64_t>(machInst, vd, bigImm); 792 else 793 return new NVmvniD<uint64_t>(machInst, vd, bigImm); 794 } else { 795 if (q) 796 return new NVbiciQ<uint64_t>(machInst, vd, bigImm); 797 else 798 return new NVbiciD<uint64_t>(machInst, vd, bigImm); 799 } 800 } else { 801 if (bits(cmode, 2) == 1) { 802 switch (bits(cmode, 1, 0)) { 803 case 0: 804 case 1: 805 if (q) 806 return new NVmvniQ<uint64_t>(machInst, vd, bigImm); 807 else 808 return new NVmvniD<uint64_t>(machInst, vd, bigImm); 809 case 2: 810 if (q) 811 return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 812 else 813 return new NVmoviD<uint64_t>(machInst, vd, bigImm); 814 case 3: 815 if (q) 816 return new Unknown(machInst); 817 else 818 return new Unknown(machInst); 819 } 820 } else { 821 if (bits(cmode, 0) == 0) { 822 if (q) 823 return new NVmvniQ<uint64_t>(machInst, vd, bigImm); 824 else 825 return new NVmvniD<uint64_t>(machInst, vd, bigImm); 826 } else { 827 if (q) 828 return new NVbiciQ<uint64_t>(machInst, vd, bigImm); 829 else 830 return new NVbiciD<uint64_t>(machInst, vd, bigImm); 831 } 832 } 833 } 834 } else { 835 if (bits(cmode, 3) == 0) { 836 if (bits(cmode, 0) == 0) { 837 if (q) 838 return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 839 else 840 return new NVmoviD<uint64_t>(machInst, vd, bigImm); 841 } else { 842 if (q) 843 return new NVorriQ<uint64_t>(machInst, vd, bigImm); 844 else 845 return new NVorriD<uint64_t>(machInst, vd, bigImm); 846 } 847 } else { 848 if (bits(cmode, 2) == 1) { 849 if (q) 850 return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 851 else 852 return new NVmoviD<uint64_t>(machInst, vd, bigImm); 853 } else { 854 if (bits(cmode, 0) == 0) { 855 if (q) 856 return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 857 else 858 return new NVmoviD<uint64_t>(machInst, vd, bigImm); 859 } else { 860 if (q) 861 return new NVorriQ<uint64_t>(machInst, vd, bigImm); 862 else 863 return new NVorriD<uint64_t>(machInst, vd, bigImm); 864 } 865 } 866 } 867 } 868 return new Unknown(machInst); 869 } 870 871 static StaticInstPtr 872 decodeNeonTwoRegAndShift(ExtMachInst machInst) 873 { 874 const uint32_t a = bits(machInst, 11, 8); 875 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 876 const bool b = bits(machInst, 6); 877 const bool l = bits(machInst, 7); 878 const IntRegIndex vd = 879 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 880 (bits(machInst, 22) << 4))); 881 const IntRegIndex vm = 882 (IntRegIndex)(2 * (bits(machInst, 3, 0) | 883 (bits(machInst, 5) << 4))); 884 unsigned imm6 = bits(machInst, 21, 16); 885 unsigned imm = ((l ? 1 : 0) << 6) | imm6; 886 unsigned size = 3; 887 unsigned lShiftAmt = 0; 888 unsigned bitSel; 889 for (bitSel = 1 << 6; true; bitSel >>= 1) { 890 if (bitSel & imm) 891 break; 892 else if (!size) 893 return new Unknown(machInst); 894 size--; 895 } 896 lShiftAmt = imm6 & ~bitSel; 897 unsigned rShiftAmt = 0; 898 if (a != 0xe && a != 0xf) { 899 if (size > 2) 900 rShiftAmt = 64 - imm6; 901 else 902 rShiftAmt = 2 * (8 << size) - imm6; 903 } 904 905 switch (a) { 906 case 0x0: 907 return decodeNeonUSTwoShiftReg<NVshrD, NVshrQ>( 908 b, u, size, machInst, vd, vm, rShiftAmt); 909 case 0x1: 910 return decodeNeonUSTwoShiftReg<NVsraD, NVsraQ>( 911 b, u, size, machInst, vd, vm, rShiftAmt); 912 case 0x2: 913 return decodeNeonUSTwoShiftReg<NVrshrD, NVrshrQ>( 914 b, u, size, machInst, vd, vm, rShiftAmt); 915 case 0x3: 916 return decodeNeonUSTwoShiftReg<NVrsraD, NVrsraQ>( 917 b, u, size, machInst, vd, vm, rShiftAmt); 918 case 0x4: 919 if (u) { 920 return decodeNeonUTwoShiftReg<NVsriD, NVsriQ>( 921 b, size, machInst, vd, vm, rShiftAmt); 922 } else { 923 return new Unknown(machInst); 924 } 925 case 0x5: 926 if (u) { 927 return decodeNeonUTwoShiftReg<NVsliD, NVsliQ>( 928 b, size, machInst, vd, vm, lShiftAmt); 929 } else { 930 return decodeNeonUTwoShiftReg<NVshlD, NVshlQ>( 931 b, size, machInst, vd, vm, lShiftAmt); 932 } 933 case 0x6: 934 case 0x7: 935 if (u) { 936 if (a == 0x6) { 937 return decodeNeonSTwoShiftReg<NVqshlusD, NVqshlusQ>( 938 b, size, machInst, vd, vm, lShiftAmt); 939 } else { 940 return decodeNeonUTwoShiftReg<NVqshluD, NVqshluQ>( 941 b, size, machInst, vd, vm, lShiftAmt); 942 } 943 } else { 944 return decodeNeonSTwoShiftReg<NVqshlD, NVqshlQ>( 945 b, size, machInst, vd, vm, lShiftAmt); 946 } 947 case 0x8: 948 if (l) { 949 return new Unknown(machInst); 950 } else if (u) { 951 return decodeNeonSTwoShiftSReg<NVqshruns, NVqrshruns>( 952 b, size, machInst, vd, vm, rShiftAmt); 953 } else { 954 return decodeNeonUTwoShiftSReg<NVshrn, NVrshrn>( 955 b, size, machInst, vd, vm, rShiftAmt); 956 } 957 case 0x9: 958 if (l) { 959 return new Unknown(machInst); 960 } else if (u) { 961 return decodeNeonUTwoShiftSReg<NVqshrun, NVqrshrun>( 962 b, size, machInst, vd, vm, rShiftAmt); 963 } else { 964 return decodeNeonSTwoShiftSReg<NVqshrn, NVqrshrn>( 965 b, size, machInst, vd, vm, rShiftAmt); 966 } 967 case 0xa: 968 if (l || b) { 969 return new Unknown(machInst); 970 } else { 971 return decodeNeonUSTwoShiftSReg<NVmovl, NVshll>( 972 lShiftAmt, u, size, machInst, vd, vm, lShiftAmt); 973 } 974 case 0xe: 975 if (l) { 976 return new Unknown(machInst); 977 } else { 978 if (bits(imm6, 5) == 0) 979 return new Unknown(machInst); 980 if (u) { 981 if (b) { 982 return new NVcvtu2fpQ<float>( 983 machInst, vd, vm, 64 - imm6); 984 } else { 985 return new NVcvtu2fpD<float>( 986 machInst, vd, vm, 64 - imm6); 987 } 988 } else { 989 if (b) { 990 return new NVcvts2fpQ<float>( 991 machInst, vd, vm, 64 - imm6); 992 } else { 993 return new NVcvts2fpD<float>( 994 machInst, vd, vm, 64 - imm6); 995 } 996 } 997 } 998 case 0xf: 999 if (l) { 1000 return new Unknown(machInst); 1001 } else { 1002 if (bits(imm6, 5) == 0) 1003 return new Unknown(machInst); 1004 if (u) { 1005 if (b) { 1006 return new NVcvt2ufxQ<float>( 1007 machInst, vd, vm, 64 - imm6); 1008 } else { 1009 return new NVcvt2ufxD<float>( 1010 machInst, vd, vm, 64 - imm6); 1011 } 1012 } else { 1013 if (b) { 1014 return new NVcvt2sfxQ<float>( 1015 machInst, vd, vm, 64 - imm6); 1016 } else { 1017 return new NVcvt2sfxD<float>( 1018 machInst, vd, vm, 64 - imm6); 1019 } 1020 } 1021 } 1022 } 1023 return new Unknown(machInst); 1024 } 1025 1026 static StaticInstPtr 1027 decodeNeonThreeRegDiffLengths(ExtMachInst machInst) 1028 { 1029 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 1030 const uint32_t a = bits(machInst, 11, 8); 1031 const IntRegIndex vd = 1032 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 1033 (bits(machInst, 22) << 4))); 1034 const IntRegIndex vn = 1035 (IntRegIndex)(2 * (bits(machInst, 19, 16) | 1036 (bits(machInst, 7) << 4))); 1037 const IntRegIndex vm = 1038 (IntRegIndex)(2 * (bits(machInst, 3, 0) | 1039 (bits(machInst, 5) << 4))); 1040 const unsigned size = bits(machInst, 21, 20); 1041 switch (a) { 1042 case 0x0: 1043 return decodeNeonUSThreeUSReg<Vaddl>( 1044 u, size, machInst, vd, vn, vm); 1045 case 0x1: 1046 return decodeNeonUSThreeUSReg<Vaddw>( 1047 u, size, machInst, vd, vn, vm); 1048 case 0x2: 1049 return decodeNeonUSThreeUSReg<Vsubl>( 1050 u, size, machInst, vd, vn, vm); 1051 case 0x3: 1052 return decodeNeonUSThreeUSReg<Vsubw>( 1053 u, size, machInst, vd, vn, vm); 1054 case 0x4: 1055 if (u) { 1056 return decodeNeonUThreeUSReg<Vraddhn>( 1057 size, machInst, vd, vn, vm); 1058 } else { 1059 return decodeNeonUThreeUSReg<Vaddhn>( 1060 size, machInst, vd, vn, vm); 1061 } 1062 case 0x5: 1063 return decodeNeonUSThreeUSReg<Vabal>( 1064 u, size, machInst, vd, vn, vm); 1065 case 0x6: 1066 if (u) { 1067 return decodeNeonUThreeUSReg<Vrsubhn>( 1068 size, machInst, vd, vn, vm); 1069 } else { 1070 return decodeNeonUThreeUSReg<Vsubhn>( 1071 size, machInst, vd, vn, vm); 1072 } 1073 case 0x7: 1074 if (bits(machInst, 23)) { 1075 return decodeNeonUSThreeUSReg<Vabdl>( 1076 u, size, machInst, vd, vn, vm); 1077 } else { 1078 return decodeNeonUSThreeReg<VabdD, VabdQ>( 1079 bits(machInst, 6), u, size, machInst, vd, vn, vm); 1080 } 1081 case 0x8: 1082 return decodeNeonUSThreeUSReg<Vmlal>( 1083 u, size, machInst, vd, vn, vm); 1084 case 0xa: 1085 return decodeNeonUSThreeUSReg<Vmlsl>( 1086 u, size, machInst, vd, vn, vm); 1087 case 0x9: 1088 if (u) { 1089 return new Unknown(machInst); 1090 } else { 1091 return decodeNeonSThreeUSReg<Vqdmlal>( 1092 size, machInst, vd, vn, vm); 1093 } 1094 case 0xb: 1095 if (u) { 1096 return new Unknown(machInst); 1097 } else { 1098 return decodeNeonSThreeUSReg<Vqdmlsl>( 1099 size, machInst, vd, vn, vm); 1100 } 1101 case 0xc: 1102 return decodeNeonUSThreeUSReg<Vmull>( 1103 u, size, machInst, vd, vn, vm); 1104 case 0xd: 1105 if (u) { 1106 return new Unknown(machInst); 1107 } else { 1108 return decodeNeonSThreeUSReg<Vqdmull>( 1109 size, machInst, vd, vn, vm); 1110 } 1111 case 0xe: 1112 return decodeNeonUThreeUSReg<Vmullp>( 1113 size, machInst, vd, vn, vm); 1114 } 1115 return new Unknown(machInst); 1116 } 1117 1118 static StaticInstPtr 1119 decodeNeonTwoRegScalar(ExtMachInst machInst) 1120 { 1121 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 1122 const uint32_t a = bits(machInst, 11, 8); 1123 const unsigned size = bits(machInst, 21, 20); 1124 const IntRegIndex vd = 1125 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 1126 (bits(machInst, 22) << 4))); 1127 const IntRegIndex vn = 1128 (IntRegIndex)(2 * (bits(machInst, 19, 16) | 1129 (bits(machInst, 7) << 4))); 1130 const IntRegIndex vm = (size == 2) ? 1131 (IntRegIndex)(2 * bits(machInst, 3, 0)) : 1132 (IntRegIndex)(2 * bits(machInst, 2, 0)); 1133 const unsigned index = (size == 2) ? (unsigned)bits(machInst, 5) : 1134 (bits(machInst, 3) | (bits(machInst, 5) << 1)); 1135 switch (a) { 1136 case 0x0: 1137 if (u) { 1138 switch (size) { 1139 case 1: 1140 return new VmlasQ<uint16_t>(machInst, vd, vn, vm, index); 1141 case 2: 1142 return new VmlasQ<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 VmlasD<uint16_t>(machInst, vd, vn, vm, index); 1150 case 2: 1151 return new VmlasD<uint32_t>(machInst, vd, vn, vm, index); 1152 default: 1153 return new Unknown(machInst); 1154 } 1155 } 1156 case 0x1: 1157 if (u) 1158 return new VmlasQFp<float>(machInst, vd, vn, vm, index); 1159 else 1160 return new VmlasDFp<float>(machInst, vd, vn, vm, index); 1161 case 0x4: 1162 if (u) { 1163 switch (size) { 1164 case 1: 1165 return new VmlssQ<uint16_t>(machInst, vd, vn, vm, index); 1166 case 2: 1167 return new VmlssQ<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 VmlssD<uint16_t>(machInst, vd, vn, vm, index); 1175 case 2: 1176 return new VmlssD<uint32_t>(machInst, vd, vn, vm, index); 1177 default: 1178 return new Unknown(machInst); 1179 } 1180 } 1181 case 0x5: 1182 if (u) 1183 return new VmlssQFp<float>(machInst, vd, vn, vm, index); 1184 else 1185 return new VmlssDFp<float>(machInst, vd, vn, vm, index); 1186 case 0x2: 1187 if (u) { 1188 switch (size) { 1189 case 1: 1190 return new Vmlals<uint16_t>(machInst, vd, vn, vm, index); 1191 case 2: 1192 return new Vmlals<uint32_t>(machInst, vd, vn, vm, index); 1193 default: 1194 return new Unknown(machInst); 1195 } 1196 } else { 1197 switch (size) { 1198 case 1: 1199 return new Vmlals<int16_t>(machInst, vd, vn, vm, index); 1200 case 2: 1201 return new Vmlals<int32_t>(machInst, vd, vn, vm, index); 1202 default: 1203 return new Unknown(machInst); 1204 } 1205 } 1206 case 0x6: 1207 if (u) { 1208 switch (size) { 1209 case 1: 1210 return new Vmlsls<uint16_t>(machInst, vd, vn, vm, index); 1211 case 2: 1212 return new Vmlsls<uint32_t>(machInst, vd, vn, vm, index); 1213 default: 1214 return new Unknown(machInst); 1215 } 1216 } else { 1217 switch (size) { 1218 case 1: 1219 return new Vmlsls<int16_t>(machInst, vd, vn, vm, index); 1220 case 2: 1221 return new Vmlsls<int32_t>(machInst, vd, vn, vm, index); 1222 default: 1223 return new Unknown(machInst); 1224 } 1225 } 1226 case 0x3: 1227 if (u) { 1228 return new Unknown(machInst); 1229 } else { 1230 switch (size) { 1231 case 1: 1232 return new Vqdmlals<int16_t>(machInst, vd, vn, vm, index); 1233 case 2: 1234 return new Vqdmlals<int32_t>(machInst, vd, vn, vm, index); 1235 default: 1236 return new Unknown(machInst); 1237 } 1238 } 1239 case 0x7: 1240 if (u) { 1241 return new Unknown(machInst); 1242 } else { 1243 switch (size) { 1244 case 1: 1245 return new Vqdmlsls<int16_t>(machInst, vd, vn, vm, index); 1246 case 2: 1247 return new Vqdmlsls<int32_t>(machInst, vd, vn, vm, index); 1248 default: 1249 return new Unknown(machInst); 1250 } 1251 } 1252 case 0x8: 1253 if (u) { 1254 switch (size) { 1255 case 1: 1256 return new VmulsQ<uint16_t>(machInst, vd, vn, vm, index); 1257 case 2: 1258 return new VmulsQ<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 VmulsD<uint16_t>(machInst, vd, vn, vm, index); 1266 case 2: 1267 return new VmulsD<uint32_t>(machInst, vd, vn, vm, index); 1268 default: 1269 return new Unknown(machInst); 1270 } 1271 } 1272 case 0x9: 1273 if (u) 1274 return new VmulsQFp<float>(machInst, vd, vn, vm, index); 1275 else 1276 return new VmulsDFp<float>(machInst, vd, vn, vm, index); 1277 case 0xa: 1278 if (u) { 1279 switch (size) { 1280 case 1: 1281 return new Vmulls<uint16_t>(machInst, vd, vn, vm, index); 1282 case 2: 1283 return new Vmulls<uint32_t>(machInst, vd, vn, vm, index); 1284 default: 1285 return new Unknown(machInst); 1286 } 1287 } else { 1288 switch (size) { 1289 case 1: 1290 return new Vmulls<int16_t>(machInst, vd, vn, vm, index); 1291 case 2: 1292 return new Vmulls<int32_t>(machInst, vd, vn, vm, index); 1293 default: 1294 return new Unknown(machInst); 1295 } 1296 } 1297 case 0xb: 1298 if (u) { 1299 return new Unknown(machInst); 1300 } else { 1301 if (u) { 1302 switch (size) { 1303 case 1: 1304 return new Vqdmulls<uint16_t>( 1305 machInst, vd, vn, vm, index); 1306 case 2: 1307 return new Vqdmulls<uint32_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 Vqdmulls<int16_t>( 1316 machInst, vd, vn, vm, index); 1317 case 2: 1318 return new Vqdmulls<int32_t>( 1319 machInst, vd, vn, vm, index); 1320 default: 1321 return new Unknown(machInst); 1322 } 1323 } 1324 } 1325 case 0xc: 1326 if (u) { 1327 switch (size) { 1328 case 1: 1329 return new VqdmulhsQ<int16_t>( 1330 machInst, vd, vn, vm, index); 1331 case 2: 1332 return new VqdmulhsQ<int32_t>( 1333 machInst, vd, vn, vm, index); 1334 default: 1335 return new Unknown(machInst); 1336 } 1337 } else { 1338 switch (size) { 1339 case 1: 1340 return new VqdmulhsD<int16_t>( 1341 machInst, vd, vn, vm, index); 1342 case 2: 1343 return new VqdmulhsD<int32_t>( 1344 machInst, vd, vn, vm, index); 1345 default: 1346 return new Unknown(machInst); 1347 } 1348 } 1349 case 0xd: 1350 if (u) { 1351 switch (size) { 1352 case 1: 1353 return new VqrdmulhsQ<int16_t>( 1354 machInst, vd, vn, vm, index); 1355 case 2: 1356 return new VqrdmulhsQ<int32_t>( 1357 machInst, vd, vn, vm, index); 1358 default: 1359 return new Unknown(machInst); 1360 } 1361 } else { 1362 switch (size) { 1363 case 1: 1364 return new VqrdmulhsD<int16_t>( 1365 machInst, vd, vn, vm, index); 1366 case 2: 1367 return new VqrdmulhsD<int32_t>( 1368 machInst, vd, vn, vm, index); 1369 default: 1370 return new Unknown(machInst); 1371 } 1372 } 1373 } 1374 return new Unknown(machInst); 1375 } 1376 1377 static StaticInstPtr 1378 decodeNeonTwoRegMisc(ExtMachInst machInst) 1379 { 1380 const uint32_t a = bits(machInst, 17, 16); 1381 const uint32_t b = bits(machInst, 10, 6); 1382 const bool q = bits(machInst, 6); 1383 const IntRegIndex vd = 1384 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 1385 (bits(machInst, 22) << 4))); 1386 const IntRegIndex vm = 1387 (IntRegIndex)(2 * (bits(machInst, 3, 0) | 1388 (bits(machInst, 5) << 4))); 1389 const unsigned size = bits(machInst, 19, 18); 1390 switch (a) { 1391 case 0x0: 1392 switch (bits(b, 4, 1)) { 1393 case 0x0: 1394 switch (size) { 1395 case 0: 1396 if (q) { 1397 return new NVrev64Q<uint8_t>(machInst, vd, vm); 1398 } else { 1399 return new NVrev64D<uint8_t>(machInst, vd, vm); 1400 } 1401 case 1: 1402 if (q) { 1403 return new NVrev64Q<uint16_t>(machInst, vd, vm); 1404 } else { 1405 return new NVrev64D<uint16_t>(machInst, vd, vm); 1406 } 1407 case 2: 1408 if (q) { 1409 return new NVrev64Q<uint32_t>(machInst, vd, vm); 1410 } else { 1411 return new NVrev64D<uint32_t>(machInst, vd, vm); 1412 } 1413 default: 1414 return new Unknown(machInst); 1415 } 1416 case 0x1: 1417 switch (size) { 1418 case 0: 1419 if (q) { 1420 return new NVrev32Q<uint8_t>(machInst, vd, vm); 1421 } else { 1422 return new NVrev32D<uint8_t>(machInst, vd, vm); 1423 } 1424 case 1: 1425 if (q) { 1426 return new NVrev32Q<uint16_t>(machInst, vd, vm); 1427 } else { 1428 return new NVrev32D<uint16_t>(machInst, vd, vm); 1429 } 1430 default: 1431 return new Unknown(machInst); 1432 } 1433 case 0x2: 1434 if (size != 0) { 1435 return new Unknown(machInst); 1436 } else if (q) { 1437 return new NVrev16Q<uint8_t>(machInst, vd, vm); 1438 } else { 1439 return new NVrev16D<uint8_t>(machInst, vd, vm); 1440 } 1441 case 0x4: 1442 return decodeNeonSTwoMiscSReg<NVpaddlD, NVpaddlQ>( 1443 q, size, machInst, vd, vm); 1444 case 0x5: 1445 return decodeNeonUTwoMiscSReg<NVpaddlD, NVpaddlQ>( 1446 q, size, machInst, vd, vm); 1447 case 0x8: 1448 return decodeNeonSTwoMiscReg<NVclsD, NVclsQ>( 1449 q, size, machInst, vd, vm); 1450 case 0x9: 1451 return decodeNeonSTwoMiscReg<NVclzD, NVclzQ>( 1452 q, size, machInst, vd, vm); 1453 case 0xa: 1454 return decodeNeonUTwoMiscReg<NVcntD, NVcntQ>( 1455 q, size, machInst, vd, vm); 1456 case 0xb: 1457 if (q) 1458 return new NVmvnQ<uint64_t>(machInst, vd, vm); 1459 else 1460 return new NVmvnD<uint64_t>(machInst, vd, vm); 1461 case 0xc: 1462 return decodeNeonSTwoMiscSReg<NVpadalD, NVpadalQ>( 1463 q, size, machInst, vd, vm); 1464 case 0xd: 1465 return decodeNeonUTwoMiscSReg<NVpadalD, NVpadalQ>( 1466 q, size, machInst, vd, vm); 1467 case 0xe: 1468 return decodeNeonSTwoMiscReg<NVqabsD, NVqabsQ>( 1469 q, size, machInst, vd, vm); 1470 case 0xf: 1471 return decodeNeonSTwoMiscReg<NVqnegD, NVqnegQ>( 1472 q, size, machInst, vd, vm); 1473 default: 1474 return new Unknown(machInst); 1475 } 1476 case 0x1: 1477 switch (bits(b, 3, 1)) { 1478 case 0x0: 1479 if (bits(b, 4)) { 1480 if (q) { 1481 return new NVcgtQFp<float>(machInst, vd, vm); 1482 } else { 1483 return new NVcgtDFp<float>(machInst, vd, vm); 1484 } 1485 } else { 1486 return decodeNeonSTwoMiscReg<NVcgtD, NVcgtQ>( 1487 q, size, machInst, vd, vm); 1488 } 1489 case 0x1: 1490 if (bits(b, 4)) { 1491 if (q) { 1492 return new NVcgeQFp<float>(machInst, vd, vm); 1493 } else { 1494 return new NVcgeDFp<float>(machInst, vd, vm); 1495 } 1496 } else { 1497 return decodeNeonSTwoMiscReg<NVcgeD, NVcgeQ>( 1498 q, size, machInst, vd, vm); 1499 } 1500 case 0x2: 1501 if (bits(b, 4)) { 1502 if (q) { 1503 return new NVceqQFp<float>(machInst, vd, vm); 1504 } else { 1505 return new NVceqDFp<float>(machInst, vd, vm); 1506 } 1507 } else { 1508 return decodeNeonSTwoMiscReg<NVceqD, NVceqQ>( 1509 q, size, machInst, vd, vm); 1510 } 1511 case 0x3: 1512 if (bits(b, 4)) { 1513 if (q) { 1514 return new NVcleQFp<float>(machInst, vd, vm); 1515 } else { 1516 return new NVcleDFp<float>(machInst, vd, vm); 1517 } 1518 } else { 1519 return decodeNeonSTwoMiscReg<NVcleD, NVcleQ>( 1520 q, size, machInst, vd, vm); 1521 } 1522 case 0x4: 1523 if (bits(b, 4)) { 1524 if (q) { 1525 return new NVcltQFp<float>(machInst, vd, vm); 1526 } else { 1527 return new NVcltDFp<float>(machInst, vd, vm); 1528 } 1529 } else { 1530 return decodeNeonSTwoMiscReg<NVcltD, NVcltQ>( 1531 q, size, machInst, vd, vm); 1532 } 1533 case 0x6: 1534 if (bits(machInst, 10)) { 1535 if (q) 1536 return new NVabsQFp<float>(machInst, vd, vm); 1537 else 1538 return new NVabsDFp<float>(machInst, vd, vm); 1539 } else { 1540 return decodeNeonSTwoMiscReg<NVabsD, NVabsQ>( 1541 q, size, machInst, vd, vm); 1542 } 1543 case 0x7: 1544 if (bits(machInst, 10)) { 1545 if (q) 1546 return new NVnegQFp<float>(machInst, vd, vm); 1547 else 1548 return new NVnegDFp<float>(machInst, vd, vm); 1549 } else { 1550 return decodeNeonSTwoMiscReg<NVnegD, NVnegQ>( 1551 q, size, machInst, vd, vm); 1552 } 1553 } 1554 case 0x2: 1555 switch (bits(b, 4, 1)) { 1556 case 0x0: 1557 if (q) 1558 return new NVswpQ<uint64_t>(machInst, vd, vm); 1559 else 1560 return new NVswpD<uint64_t>(machInst, vd, vm); 1561 case 0x1: 1562 return decodeNeonUTwoMiscSReg<NVtrnD, NVtrnQ>( 1563 q, size, machInst, vd, vm); 1564 case 0x2: 1565 return decodeNeonUTwoMiscReg<NVuzpD, NVuzpQ>( 1566 q, size, machInst, vd, vm); 1567 case 0x3: 1568 return decodeNeonUTwoMiscReg<NVzipD, NVzipQ>( 1569 q, size, machInst, vd, vm); 1570 case 0x4: 1571 if (b == 0x8) { 1572 return decodeNeonUTwoMiscUSReg<NVmovn>( 1573 size, machInst, vd, vm); 1574 } else { 1575 return decodeNeonSTwoMiscUSReg<NVqmovuns>( 1576 size, machInst, vd, vm); 1577 } 1578 case 0x5: 1579 if (q) { 1580 return decodeNeonUTwoMiscUSReg<NVqmovun>( 1581 size, machInst, vd, vm); 1582 } else { 1583 return decodeNeonSTwoMiscUSReg<NVqmovn>( 1584 size, machInst, vd, vm); 1585 } 1586 case 0x6: 1587 if (b == 0xc) { 1588 return decodeNeonSTwoShiftUSReg<NVshll>( 1589 size, machInst, vd, vm, 8 << size); 1590 } else { 1591 return new Unknown(machInst); 1592 } 1593 case 0xc: 1594 case 0xe: 1595 if (b == 0x18) { 1596 if (size != 1 || (vm % 2)) 1597 return new Unknown(machInst); 1598 return new NVcvts2h<uint16_t>(machInst, vd, vm); 1599 } else if (b == 0x1c) { 1600 if (size != 1 || (vd % 2)) 1601 return new Unknown(machInst); 1602 return new NVcvth2s<uint16_t>(machInst, vd, vm); 1603 } else { 1604 return new Unknown(machInst); 1605 } 1606 default: 1607 return new Unknown(machInst); 1608 } 1609 case 0x3: 1610 if (bits(b, 4, 3) == 0x3) { 1611 if ((q && (vd % 2 || vm % 2)) || size != 2) { 1612 return new Unknown(machInst); 1613 } else { 1614 if (bits(b, 2)) { 1615 if (bits(b, 1)) { 1616 if (q) { 1617 return new NVcvt2ufxQ<float>( 1618 machInst, vd, vm, 0); 1619 } else { 1620 return new NVcvt2ufxD<float>( 1621 machInst, vd, vm, 0); 1622 } 1623 } else { 1624 if (q) { 1625 return new NVcvt2sfxQ<float>( 1626 machInst, vd, vm, 0); 1627 } else { 1628 return new NVcvt2sfxD<float>( 1629 machInst, vd, vm, 0); 1630 } 1631 } 1632 } else { 1633 if (bits(b, 1)) { 1634 if (q) { 1635 return new NVcvtu2fpQ<float>( 1636 machInst, vd, vm, 0); 1637 } else { 1638 return new NVcvtu2fpD<float>( 1639 machInst, vd, vm, 0); 1640 } 1641 } else { 1642 if (q) { 1643 return new NVcvts2fpQ<float>( 1644 machInst, vd, vm, 0); 1645 } else { 1646 return new NVcvts2fpD<float>( 1647 machInst, vd, vm, 0); 1648 } 1649 } 1650 } 1651 } 1652 } else if ((b & 0x1a) == 0x10) { 1653 if (bits(b, 2)) { 1654 if (q) { 1655 return new NVrecpeQFp<float>(machInst, vd, vm); 1656 } else { 1657 return new NVrecpeDFp<float>(machInst, vd, vm); 1658 } 1659 } else { 1660 if (q) { 1661 return new NVrecpeQ<uint32_t>(machInst, vd, vm); 1662 } else { 1663 return new NVrecpeD<uint32_t>(machInst, vd, vm); 1664 } 1665 } 1666 } else if ((b & 0x1a) == 0x12) { 1667 if (bits(b, 2)) { 1668 if (q) { 1669 return new NVrsqrteQFp<float>(machInst, vd, vm); 1670 } else { 1671 return new NVrsqrteDFp<float>(machInst, vd, vm); 1672 } 1673 } else { 1674 if (q) { 1675 return new NVrsqrteQ<uint32_t>(machInst, vd, vm); 1676 } else { 1677 return new NVrsqrteD<uint32_t>(machInst, vd, vm); 1678 } 1679 } 1680 } else { 1681 return new Unknown(machInst); 1682 } 1683 } 1684 return new Unknown(machInst); 1685 } 1686 1687 StaticInstPtr 1688 decodeNeonData(ExtMachInst machInst) 1689 { 1690 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 1691 const uint32_t a = bits(machInst, 23, 19); 1692 const uint32_t b = bits(machInst, 11, 8); 1693 const uint32_t c = bits(machInst, 7, 4); 1694 if (bits(a, 4) == 0) { 1695 return decodeNeonThreeRegistersSameLength(machInst); 1696 } else if ((c & 0x9) == 1) { 1697 if ((a & 0x7) == 0) { 1698 return decodeNeonOneRegModImm(machInst); 1699 } else { 1700 return decodeNeonTwoRegAndShift(machInst); 1701 } 1702 } else if ((c & 0x9) == 9) { 1703 return decodeNeonTwoRegAndShift(machInst); 1704 } else if (bits(a, 2, 1) != 0x3) { 1705 if ((c & 0x5) == 0) { 1706 return decodeNeonThreeRegDiffLengths(machInst); 1707 } else if ((c & 0x5) == 4) { 1708 return decodeNeonTwoRegScalar(machInst); 1709 } 1710 } else if ((a & 0x16) == 0x16) { 1711 const IntRegIndex vd = 1712 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 1713 (bits(machInst, 22) << 4))); 1714 const IntRegIndex vn = 1715 (IntRegIndex)(2 * (bits(machInst, 19, 16) | 1716 (bits(machInst, 7) << 4))); 1717 const IntRegIndex vm = 1718 (IntRegIndex)(2 * (bits(machInst, 3, 0) | 1719 (bits(machInst, 5) << 4))); 1720 if (!u) { 1721 if (bits(c, 0) == 0) { 1722 unsigned imm4 = bits(machInst, 11, 8); 1723 bool q = bits(machInst, 6); 1724 if (imm4 >= 16 && !q) 1725 return new Unknown(machInst); 1726 if (q) { 1727 return new NVextQ<uint8_t>(machInst, vd, vn, vm, imm4); 1728 } else { 1729 return new NVextD<uint8_t>(machInst, vd, vn, vm, imm4); 1730 } 1731 } 1732 } else if (bits(b, 3) == 0 && bits(c, 0) == 0) { 1733 return decodeNeonTwoRegMisc(machInst); 1734 } else if (bits(b, 3, 2) == 0x2 && bits(c, 0) == 0) { 1735 unsigned length = bits(machInst, 9, 8) + 1; 1736 if ((uint32_t)vn / 2 + length > 32) 1737 return new Unknown(machInst); 1738 if (bits(machInst, 6) == 0) { 1739 switch (length) { 1740 case 1: 1741 return new NVtbl1(machInst, vd, vn, vm); 1742 case 2: 1743 return new NVtbl2(machInst, vd, vn, vm); 1744 case 3: 1745 return new NVtbl3(machInst, vd, vn, vm); 1746 case 4: 1747 return new NVtbl4(machInst, vd, vn, vm); 1748 } 1749 } else { 1750 switch (length) { 1751 case 1: 1752 return new NVtbx1(machInst, vd, vn, vm); 1753 case 2: 1754 return new NVtbx2(machInst, vd, vn, vm); 1755 case 3: 1756 return new NVtbx3(machInst, vd, vn, vm); 1757 case 4: 1758 return new NVtbx4(machInst, vd, vn, vm); 1759 } 1760 } 1761 } else if (b == 0xc && (c & 0x9) == 0) { 1762 unsigned imm4 = bits(machInst, 19, 16); 1763 if (bits(imm4, 2, 0) == 0) 1764 return new Unknown(machInst); 1765 unsigned size = 0; 1766 while ((imm4 & 0x1) == 0) { 1767 size++; 1768 imm4 >>= 1; 1769 } 1770 unsigned index = imm4 >> 1; 1771 const bool q = bits(machInst, 6); 1772 return decodeNeonUTwoShiftSReg<NVdupD, NVdupQ>( 1773 q, size, machInst, vd, vm, index); 1774 } 1775 } 1776 return new Unknown(machInst); 1777 } 1778 ''' 1779}}; 1780 1781def format ThumbNeonMem() {{ 1782 decode_block = ''' 1783 return decodeNeonMem(machInst); 1784 ''' 1785}}; 1786 1787def format ThumbNeonData() {{ 1788 decode_block = ''' 1789 return decodeNeonData(machInst); 1790 ''' 1791}}; 1792 1793let {{ 1794 header_output = ''' 1795 StaticInstPtr 1796 decodeExtensionRegLoadStore(ExtMachInst machInst); 1797 ''' 1798 decoder_output = ''' 1799 StaticInstPtr 1800 decodeExtensionRegLoadStore(ExtMachInst machInst) 1801 { 1802 const uint32_t opcode = bits(machInst, 24, 20); 1803 const uint32_t offset = bits(machInst, 7, 0); 1804 const bool single = (bits(machInst, 8) == 0); 1805 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 1806 RegIndex vd; 1807 if (single) { 1808 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 1809 bits(machInst, 22)); 1810 } else { 1811 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 1812 (bits(machInst, 22) << 5)); 1813 } 1814 switch (bits(opcode, 4, 3)) { 1815 case 0x0: 1816 if (bits(opcode, 4, 1) == 0x2 && 1817 !(machInst.thumb == 1 && bits(machInst, 28) == 1) && 1818 !(machInst.thumb == 0 && machInst.condCode == 0xf)) { 1819 if ((bits(machInst, 7, 4) & 0xd) != 1) { 1820 break; 1821 } 1822 const IntRegIndex rt = 1823 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 1824 const IntRegIndex rt2 = 1825 (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 1826 const bool op = bits(machInst, 20); 1827 uint32_t vm; 1828 if (single) { 1829 vm = (bits(machInst, 3, 0) << 1) | bits(machInst, 5); 1830 } else { 1831 vm = (bits(machInst, 3, 0) << 1) | 1832 (bits(machInst, 5) << 5); 1833 } 1834 if (op) { 1835 return new Vmov2Core2Reg(machInst, rt, rt2, 1836 (IntRegIndex)vm); 1837 } else { 1838 return new Vmov2Reg2Core(machInst, (IntRegIndex)vm, 1839 rt, rt2); 1840 } 1841 } 1842 break; 1843 case 0x1: 1844 { 1845 if (offset == 0 || vd + offset/2 > NumFloatV7ArchRegs) { 1846 break; 1847 } 1848 switch (bits(opcode, 1, 0)) { 1849 case 0x0: 1850 return new VLdmStm(machInst, rn, vd, single, 1851 true, false, false, offset); 1852 case 0x1: 1853 return new VLdmStm(machInst, rn, vd, single, 1854 true, false, true, offset); 1855 case 0x2: 1856 return new VLdmStm(machInst, rn, vd, single, 1857 true, true, false, offset); 1858 case 0x3: 1859 // If rn == sp, then this is called vpop. 1860 return new VLdmStm(machInst, rn, vd, single, 1861 true, true, true, offset); 1862 } 1863 } 1864 case 0x2: 1865 if (bits(opcode, 1, 0) == 0x2) { 1866 // If rn == sp, then this is called vpush. 1867 return new VLdmStm(machInst, rn, vd, single, 1868 false, true, false, offset); 1869 } else if (bits(opcode, 1, 0) == 0x3) { 1870 return new VLdmStm(machInst, rn, vd, single, 1871 false, true, true, offset); 1872 } 1873 // Fall through on purpose 1874 case 0x3: 1875 const bool up = (bits(machInst, 23) == 1); 1876 const uint32_t imm = bits(machInst, 7, 0) << 2; 1877 if (single) { 1878 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 1879 (bits(machInst, 22))); 1880 } else { 1881 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 1882 (bits(machInst, 22) << 5)); 1883 } 1884 if (bits(opcode, 1, 0) == 0x0) { 1885 if (single) { 1886 if (up) { 1887 return new %(vstr_us)s(machInst, vd, rn, up, imm); 1888 } else { 1889 return new %(vstr_s)s(machInst, vd, rn, up, imm); 1890 } 1891 } else { 1892 if (up) { 1893 return new %(vstr_ud)s(machInst, vd, vd + 1, 1894 rn, up, imm); 1895 } else { 1896 return new %(vstr_d)s(machInst, vd, vd + 1, 1897 rn, up, imm); 1898 } 1899 } 1900 } else if (bits(opcode, 1, 0) == 0x1) { 1901 if (single) { 1902 if (up) { 1903 return new %(vldr_us)s(machInst, vd, rn, up, imm); 1904 } else { 1905 return new %(vldr_s)s(machInst, vd, rn, up, imm); 1906 } 1907 } else { 1908 if (up) { 1909 return new %(vldr_ud)s(machInst, vd, vd + 1, 1910 rn, up, imm); 1911 } else { 1912 return new %(vldr_d)s(machInst, vd, vd + 1, 1913 rn, up, imm); 1914 } 1915 } 1916 } 1917 } 1918 return new Unknown(machInst); 1919 } 1920 ''' % { 1921 "vldr_us" : "VLDR_" + loadImmClassName(False, True, False), 1922 "vldr_s" : "VLDR_" + loadImmClassName(False, False, False), 1923 "vldr_ud" : "VLDR_" + loadDoubleImmClassName(False, True, False), 1924 "vldr_d" : "VLDR_" + loadDoubleImmClassName(False, False, False), 1925 "vstr_us" : "VSTR_" + storeImmClassName(False, True, False), 1926 "vstr_s" : "VSTR_" + storeImmClassName(False, False, False), 1927 "vstr_ud" : "VSTR_" + storeDoubleImmClassName(False, True, False), 1928 "vstr_d" : "VSTR_" + storeDoubleImmClassName(False, False, False) 1929 } 1930}}; 1931 1932def format ExtensionRegLoadStore() {{ 1933 decode_block = ''' 1934 return decodeExtensionRegLoadStore(machInst); 1935 ''' 1936}}; 1937 1938let {{ 1939 header_output = ''' 1940 StaticInstPtr 1941 decodeShortFpTransfer(ExtMachInst machInst); 1942 ''' 1943 decoder_output = ''' 1944 StaticInstPtr 1945 decodeShortFpTransfer(ExtMachInst machInst) 1946 { 1947 const uint32_t l = bits(machInst, 20); 1948 const uint32_t c = bits(machInst, 8); 1949 const uint32_t a = bits(machInst, 23, 21); 1950 const uint32_t b = bits(machInst, 6, 5); 1951 if ((machInst.thumb == 1 && bits(machInst, 28) == 1) || 1952 (machInst.thumb == 0 && machInst.condCode == 0xf)) {
| 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 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 = TLB::MustBeOne; 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 align = size | TLB::AllowUnaligned; 155 if (width == 1) { 156 regs = t ? 2 : 1; 157 inc = 1; 158 } else { 159 regs = width; 160 inc = t ? 2 : 1; 161 } 162 switch (width) { 163 case 1: 164 case 2: 165 if (bits(machInst, 4)) 166 align = size + width - 1; 167 break; 168 case 3: 169 break; 170 case 4: 171 if (size == 3) { 172 if (bits(machInst, 4) == 0) 173 return new Unknown(machInst); 174 size = 2; 175 align = 0x4; 176 } else if (size == 2) { 177 if (bits(machInst, 4)) 178 align = 0x3; 179 } else { 180 if (bits(machInst, 4)) 181 align = size + 2; 182 } 183 break; 184 } 185 } else { 186 size = bits(machInst, 11, 10); 187 align = size | TLB::AllowUnaligned; 188 regs = width; 189 unsigned indexAlign = bits(machInst, 7, 4); 190 // If width is 1, inc is always 1. That's overridden later. 191 switch (size) { 192 case 0: 193 inc = 1; 194 lane = bits(indexAlign, 3, 1); 195 break; 196 case 1: 197 inc = bits(indexAlign, 1) ? 2 : 1; 198 lane = bits(indexAlign, 3, 2); 199 break; 200 case 2: 201 inc = bits(indexAlign, 2) ? 2 : 1; 202 lane = bits(indexAlign, 3); 203 break; 204 } 205 // Override inc for width of 1. 206 if (width == 1) { 207 inc = 1; 208 } 209 switch (width) { 210 case 1: 211 switch (size) { 212 case 0: 213 break; 214 case 1: 215 if (bits(indexAlign, 0)) 216 align = 1; 217 break; 218 case 2: 219 if (bits(indexAlign, 1, 0)) 220 align = 2; 221 break; 222 } 223 break; 224 case 2: 225 if (bits(indexAlign, 0)) 226 align = size + 1; 227 break; 228 case 3: 229 break; 230 case 4: 231 switch (size) { 232 case 0: 233 case 1: 234 if (bits(indexAlign, 0)) 235 align = size + 2; 236 break; 237 case 2: 238 if (bits(indexAlign, 0)) 239 align = bits(indexAlign, 1, 0) + 2; 240 break; 241 } 242 break; 243 } 244 } 245 if (size == 0x3) { 246 return new Unknown(machInst); 247 } 248 } else { 249 size = bits(machInst, 7, 6); 250 align = bits(machInst, 5, 4); 251 if (align == 0) { 252 // @align wasn't specified, so alignment can be turned off. 253 align = size | TLB::AllowUnaligned; 254 } else { 255 align = align + 2; 256 } 257 switch (width) { 258 case 1: 259 switch (type) { 260 case 0x7: regs = 1; 261 break; 262 case 0xa: regs = 2; 263 break; 264 case 0x6: regs = 3; 265 break; 266 case 0x2: regs = 4; 267 break; 268 default: 269 return new Unknown(machInst); 270 } 271 break; 272 case 2: 273 // Regs doesn't behave exactly as it does in the manual 274 // because they loop over regs registers twice and we break 275 // it down in the macroop. 276 switch (type) { 277 case 0x8: regs = 2; inc = 1; 278 break; 279 case 0x9: regs = 2; inc = 2; 280 break; 281 case 0x3: regs = 4; inc = 2; 282 break; 283 default: 284 return new Unknown(machInst); 285 } 286 break; 287 case 3: 288 regs = 3; 289 switch (type) { 290 case 0x4: inc = 1; 291 break; 292 case 0x5: inc = 2;; 293 break; 294 default: 295 return new Unknown(machInst); 296 } 297 break; 298 case 4: 299 regs = 4; 300 switch (type) { 301 case 0: inc = 1; 302 break; 303 case 1: inc = 2; 304 break; 305 default: 306 return new Unknown(machInst); 307 } 308 break; 309 } 310 } 311 312 if (load) { 313 // Load instructions. 314 if (single) { 315 return new VldSingle(machInst, singleAll, width, rn, vd, 316 regs, inc, size, align, rm, lane); 317 } else { 318 return new VldMult(machInst, width, rn, vd, 319 regs, inc, size, align, rm); 320 } 321 } else { 322 // Store instructions. 323 if (single) { 324 if (singleAll) { 325 return new Unknown(machInst); 326 } else { 327 return new VstSingle(machInst, false, width, rn, vd, 328 regs, inc, size, align, rm, lane); 329 } 330 } else { 331 return new VstMult(machInst, width, rn, vd, 332 regs, inc, size, align, rm); 333 } 334 } 335 return new Unknown(machInst); 336 } 337 ''' 338 339 decoder_output += ''' 340 static StaticInstPtr 341 decodeNeonThreeRegistersSameLength(ExtMachInst machInst) 342 { 343 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 344 const uint32_t a = bits(machInst, 11, 8); 345 const bool b = bits(machInst, 4); 346 const uint32_t c = bits(machInst, 21, 20); 347 const IntRegIndex vd = 348 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 349 (bits(machInst, 22) << 4))); 350 const IntRegIndex vn = 351 (IntRegIndex)(2 * (bits(machInst, 19, 16) | 352 (bits(machInst, 7) << 4))); 353 const IntRegIndex vm = 354 (IntRegIndex)(2 * (bits(machInst, 3, 0) | 355 (bits(machInst, 5) << 4))); 356 const unsigned size = bits(machInst, 21, 20); 357 const bool q = bits(machInst, 6); 358 if (q && ((vd & 0x1) || (vn & 0x1) || (vm & 0x1))) 359 return new Unknown(machInst); 360 switch (a) { 361 case 0x0: 362 if (b) { 363 if (u) { 364 return decodeNeonUThreeReg<VqaddUD, VqaddUQ>( 365 q, size, machInst, vd, vn, vm); 366 } else { 367 return decodeNeonSThreeReg<VqaddSD, VqaddSQ>( 368 q, size, machInst, vd, vn, vm); 369 } 370 } else { 371 if (size == 3) 372 return new Unknown(machInst); 373 return decodeNeonUSThreeReg<VhaddD, VhaddQ>( 374 q, u, size, machInst, vd, vn, vm); 375 } 376 case 0x1: 377 if (!b) { 378 return decodeNeonUSThreeReg<VrhaddD, VrhaddQ>( 379 q, u, size, machInst, vd, vn, vm); 380 } else { 381 if (u) { 382 switch (c) { 383 case 0: 384 if (q) { 385 return new VeorQ<uint64_t>(machInst, vd, vn, vm); 386 } else { 387 return new VeorD<uint64_t>(machInst, vd, vn, vm); 388 } 389 case 1: 390 if (q) { 391 return new VbslQ<uint64_t>(machInst, vd, vn, vm); 392 } else { 393 return new VbslD<uint64_t>(machInst, vd, vn, vm); 394 } 395 case 2: 396 if (q) { 397 return new VbitQ<uint64_t>(machInst, vd, vn, vm); 398 } else { 399 return new VbitD<uint64_t>(machInst, vd, vn, vm); 400 } 401 case 3: 402 if (q) { 403 return new VbifQ<uint64_t>(machInst, vd, vn, vm); 404 } else { 405 return new VbifD<uint64_t>(machInst, vd, vn, vm); 406 } 407 } 408 } else { 409 switch (c) { 410 case 0: 411 if (q) { 412 return new VandQ<uint64_t>(machInst, vd, vn, vm); 413 } else { 414 return new VandD<uint64_t>(machInst, vd, vn, vm); 415 } 416 case 1: 417 if (q) { 418 return new VbicQ<uint64_t>(machInst, vd, vn, vm); 419 } else { 420 return new VbicD<uint64_t>(machInst, vd, vn, vm); 421 } 422 case 2: 423 if (vn == vm) { 424 if (q) { 425 return new VmovQ<uint64_t>( 426 machInst, vd, vn, vm); 427 } else { 428 return new VmovD<uint64_t>( 429 machInst, vd, vn, vm); 430 } 431 } else { 432 if (q) { 433 return new VorrQ<uint64_t>( 434 machInst, vd, vn, vm); 435 } else { 436 return new VorrD<uint64_t>( 437 machInst, vd, vn, vm); 438 } 439 } 440 case 3: 441 if (q) { 442 return new VornQ<uint64_t>( 443 machInst, vd, vn, vm); 444 } else { 445 return new VornD<uint64_t>( 446 machInst, vd, vn, vm); 447 } 448 } 449 } 450 } 451 case 0x2: 452 if (b) { 453 if (u) { 454 return decodeNeonUThreeReg<VqsubUD, VqsubUQ>( 455 q, size, machInst, vd, vn, vm); 456 } else { 457 return decodeNeonSThreeReg<VqsubSD, VqsubSQ>( 458 q, size, machInst, vd, vn, vm); 459 } 460 } else { 461 if (size == 3) 462 return new Unknown(machInst); 463 return decodeNeonUSThreeReg<VhsubD, VhsubQ>( 464 q, u, size, machInst, vd, vn, vm); 465 } 466 case 0x3: 467 if (b) { 468 return decodeNeonUSThreeReg<VcgeD, VcgeQ>( 469 q, u, size, machInst, vd, vn, vm); 470 } else { 471 return decodeNeonUSThreeReg<VcgtD, VcgtQ>( 472 q, u, size, machInst, vd, vn, vm); 473 } 474 case 0x4: 475 if (b) { 476 if (u) { 477 return decodeNeonUThreeReg<VqshlUD, VqshlUQ>( 478 q, size, machInst, vd, vm, vn); 479 } else { 480 return decodeNeonSThreeReg<VqshlSD, VqshlSQ>( 481 q, size, machInst, vd, vm, vn); 482 } 483 } else { 484 return decodeNeonUSThreeReg<VshlD, VshlQ>( 485 q, u, size, machInst, vd, vm, vn); 486 } 487 case 0x5: 488 if (b) { 489 if (u) { 490 return decodeNeonUThreeReg<VqrshlUD, VqrshlUQ>( 491 q, size, machInst, vd, vm, vn); 492 } else { 493 return decodeNeonSThreeReg<VqrshlSD, VqrshlSQ>( 494 q, size, machInst, vd, vm, vn); 495 } 496 } else { 497 return decodeNeonUSThreeReg<VrshlD, VrshlQ>( 498 q, u, size, machInst, vd, vm, vn); 499 } 500 case 0x6: 501 if (b) { 502 return decodeNeonUSThreeReg<VminD, VminQ>( 503 q, u, size, machInst, vd, vn, vm); 504 } else { 505 return decodeNeonUSThreeReg<VmaxD, VmaxQ>( 506 q, u, size, machInst, vd, vn, vm); 507 } 508 case 0x7: 509 if (b) { 510 return decodeNeonUSThreeReg<VabaD, VabaQ>( 511 q, u, size, machInst, vd, vn, vm); 512 } else { 513 if (bits(machInst, 23) == 1) { 514 if (q) { 515 return new Unknown(machInst); 516 } else { 517 return decodeNeonUSThreeUSReg<Vabdl>( 518 u, size, machInst, vd, vn, vm); 519 } 520 } else { 521 return decodeNeonUSThreeReg<VabdD, VabdQ>( 522 q, u, size, machInst, vd, vn, vm); 523 } 524 } 525 case 0x8: 526 if (b) { 527 if (u) { 528 return decodeNeonUThreeReg<VceqD, VceqQ>( 529 q, size, machInst, vd, vn, vm); 530 } else { 531 return decodeNeonUThreeReg<VtstD, VtstQ>( 532 q, size, machInst, vd, vn, vm); 533 } 534 } else { 535 if (u) { 536 return decodeNeonUThreeReg<NVsubD, NVsubQ>( 537 q, size, machInst, vd, vn, vm); 538 } else { 539 return decodeNeonUThreeReg<NVaddD, NVaddQ>( 540 q, size, machInst, vd, vn, vm); 541 } 542 } 543 case 0x9: 544 if (b) { 545 if (u) { 546 return decodeNeonUThreeReg<NVmulpD, NVmulpQ>( 547 q, size, machInst, vd, vn, vm); 548 } else { 549 return decodeNeonSThreeReg<NVmulD, NVmulQ>( 550 q, size, machInst, vd, vn, vm); 551 } 552 } else { 553 if (u) { 554 return decodeNeonUSThreeReg<NVmlsD, NVmlsQ>( 555 q, u, size, machInst, vd, vn, vm); 556 } else { 557 return decodeNeonUSThreeReg<NVmlaD, NVmlaQ>( 558 q, u, size, machInst, vd, vn, vm); 559 } 560 } 561 case 0xa: 562 if (q) 563 return new Unknown(machInst); 564 if (b) { 565 return decodeNeonUSThreeUSReg<VpminD>( 566 u, size, machInst, vd, vn, vm); 567 } else { 568 return decodeNeonUSThreeUSReg<VpmaxD>( 569 u, size, machInst, vd, vn, vm); 570 } 571 case 0xb: 572 if (b) { 573 if (u || q) { 574 return new Unknown(machInst); 575 } else { 576 return decodeNeonUThreeUSReg<NVpaddD>( 577 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 if (b) { 590 if (!u) { 591 if (bits(c, 1) == 0) { 592 if (q) { 593 return new NVfmaQFp<float>(machInst, vd, vn, vm); 594 } else { 595 return new NVfmaDFp<float>(machInst, vd, vn, vm); 596 } 597 } else { 598 if (q) { 599 return new NVfmsQFp<float>(machInst, vd, vn, vm); 600 } else { 601 return new NVfmsDFp<float>(machInst, vd, vn, vm); 602 } 603 } 604 } 605 } 606 return new Unknown(machInst); 607 case 0xd: 608 if (b) { 609 if (u) { 610 if (bits(c, 1) == 0) { 611 if (q) { 612 return new NVmulQFp<float>(machInst, vd, vn, vm); 613 } else { 614 return new NVmulDFp<float>(machInst, vd, vn, vm); 615 } 616 } else { 617 return new Unknown(machInst); 618 } 619 } else { 620 if (bits(c, 1) == 0) { 621 if (q) { 622 return new NVmlaQFp<float>(machInst, vd, vn, vm); 623 } else { 624 return new NVmlaDFp<float>(machInst, vd, vn, vm); 625 } 626 } else { 627 if (q) { 628 return new NVmlsQFp<float>(machInst, vd, vn, vm); 629 } else { 630 return new NVmlsDFp<float>(machInst, vd, vn, vm); 631 } 632 } 633 } 634 } else { 635 if (u) { 636 if (bits(c, 1) == 0) { 637 if (q) { 638 return new VpaddQFp<float>(machInst, vd, vn, vm); 639 } else { 640 return new VpaddDFp<float>(machInst, vd, vn, vm); 641 } 642 } else { 643 if (q) { 644 return new VabdQFp<float>(machInst, vd, vn, vm); 645 } else { 646 return new VabdDFp<float>(machInst, vd, vn, vm); 647 } 648 } 649 } else { 650 if (bits(c, 1) == 0) { 651 if (q) { 652 return new VaddQFp<float>(machInst, vd, vn, vm); 653 } else { 654 return new VaddDFp<float>(machInst, vd, vn, vm); 655 } 656 } else { 657 if (q) { 658 return new VsubQFp<float>(machInst, vd, vn, vm); 659 } else { 660 return new VsubDFp<float>(machInst, vd, vn, vm); 661 } 662 } 663 } 664 } 665 case 0xe: 666 if (b) { 667 if (u) { 668 if (bits(c, 1) == 0) { 669 if (q) { 670 return new VacgeQFp<float>(machInst, vd, vn, vm); 671 } else { 672 return new VacgeDFp<float>(machInst, vd, vn, vm); 673 } 674 } else { 675 if (q) { 676 return new VacgtQFp<float>(machInst, vd, vn, vm); 677 } else { 678 return new VacgtDFp<float>(machInst, vd, vn, vm); 679 } 680 } 681 } else { 682 return new Unknown(machInst); 683 } 684 } else { 685 if (u) { 686 if (bits(c, 1) == 0) { 687 if (q) { 688 return new VcgeQFp<float>(machInst, vd, vn, vm); 689 } else { 690 return new VcgeDFp<float>(machInst, vd, vn, vm); 691 } 692 } else { 693 if (q) { 694 return new VcgtQFp<float>(machInst, vd, vn, vm); 695 } else { 696 return new VcgtDFp<float>(machInst, vd, vn, vm); 697 } 698 } 699 } else { 700 if (bits(c, 1) == 0) { 701 if (q) { 702 return new VceqQFp<float>(machInst, vd, vn, vm); 703 } else { 704 return new VceqDFp<float>(machInst, vd, vn, vm); 705 } 706 } else { 707 return new Unknown(machInst); 708 } 709 } 710 } 711 case 0xf: 712 if (b) { 713 if (u) { 714 return new Unknown(machInst); 715 } else { 716 if (bits(c, 1) == 0) { 717 if (q) { 718 return new VrecpsQFp<float>(machInst, vd, vn, vm); 719 } else { 720 return new VrecpsDFp<float>(machInst, vd, vn, vm); 721 } 722 } else { 723 if (q) { 724 return new VrsqrtsQFp<float>(machInst, vd, vn, vm); 725 } else { 726 return new VrsqrtsDFp<float>(machInst, vd, vn, vm); 727 } 728 } 729 } 730 } else { 731 if (u) { 732 if (bits(c, 1) == 0) { 733 if (q) { 734 return new VpmaxQFp<float>(machInst, vd, vn, vm); 735 } else { 736 return new VpmaxDFp<float>(machInst, vd, vn, vm); 737 } 738 } else { 739 if (q) { 740 return new VpminQFp<float>(machInst, vd, vn, vm); 741 } else { 742 return new VpminDFp<float>(machInst, vd, vn, vm); 743 } 744 } 745 } else { 746 if (bits(c, 1) == 0) { 747 if (q) { 748 return new VmaxQFp<float>(machInst, vd, vn, vm); 749 } else { 750 return new VmaxDFp<float>(machInst, vd, vn, vm); 751 } 752 } else { 753 if (q) { 754 return new VminQFp<float>(machInst, vd, vn, vm); 755 } else { 756 return new VminDFp<float>(machInst, vd, vn, vm); 757 } 758 } 759 } 760 } 761 } 762 return new Unknown(machInst); 763 } 764 765 static StaticInstPtr 766 decodeNeonOneRegModImm(ExtMachInst machInst) 767 { 768 const IntRegIndex vd = 769 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 770 (bits(machInst, 22) << 4))); 771 const bool q = bits(machInst, 6); 772 const bool op = bits(machInst, 5); 773 const uint8_t cmode = bits(machInst, 11, 8); 774 const uint8_t imm = ((THUMB ? bits(machInst, 28) : 775 bits(machInst, 24)) << 7) | 776 (bits(machInst, 18, 16) << 4) | 777 (bits(machInst, 3, 0) << 0); 778 779 // Check for invalid immediate encodings and return an unknown op 780 // if it happens 781 bool immValid = true; 782 const uint64_t bigImm = simd_modified_imm(op, cmode, imm, immValid); 783 if (!immValid) { 784 return new Unknown(machInst); 785 } 786 787 if (op) { 788 if (bits(cmode, 3) == 0) { 789 if (bits(cmode, 0) == 0) { 790 if (q) 791 return new NVmvniQ<uint64_t>(machInst, vd, bigImm); 792 else 793 return new NVmvniD<uint64_t>(machInst, vd, bigImm); 794 } else { 795 if (q) 796 return new NVbiciQ<uint64_t>(machInst, vd, bigImm); 797 else 798 return new NVbiciD<uint64_t>(machInst, vd, bigImm); 799 } 800 } else { 801 if (bits(cmode, 2) == 1) { 802 switch (bits(cmode, 1, 0)) { 803 case 0: 804 case 1: 805 if (q) 806 return new NVmvniQ<uint64_t>(machInst, vd, bigImm); 807 else 808 return new NVmvniD<uint64_t>(machInst, vd, bigImm); 809 case 2: 810 if (q) 811 return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 812 else 813 return new NVmoviD<uint64_t>(machInst, vd, bigImm); 814 case 3: 815 if (q) 816 return new Unknown(machInst); 817 else 818 return new Unknown(machInst); 819 } 820 } else { 821 if (bits(cmode, 0) == 0) { 822 if (q) 823 return new NVmvniQ<uint64_t>(machInst, vd, bigImm); 824 else 825 return new NVmvniD<uint64_t>(machInst, vd, bigImm); 826 } else { 827 if (q) 828 return new NVbiciQ<uint64_t>(machInst, vd, bigImm); 829 else 830 return new NVbiciD<uint64_t>(machInst, vd, bigImm); 831 } 832 } 833 } 834 } else { 835 if (bits(cmode, 3) == 0) { 836 if (bits(cmode, 0) == 0) { 837 if (q) 838 return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 839 else 840 return new NVmoviD<uint64_t>(machInst, vd, bigImm); 841 } else { 842 if (q) 843 return new NVorriQ<uint64_t>(machInst, vd, bigImm); 844 else 845 return new NVorriD<uint64_t>(machInst, vd, bigImm); 846 } 847 } else { 848 if (bits(cmode, 2) == 1) { 849 if (q) 850 return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 851 else 852 return new NVmoviD<uint64_t>(machInst, vd, bigImm); 853 } else { 854 if (bits(cmode, 0) == 0) { 855 if (q) 856 return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 857 else 858 return new NVmoviD<uint64_t>(machInst, vd, bigImm); 859 } else { 860 if (q) 861 return new NVorriQ<uint64_t>(machInst, vd, bigImm); 862 else 863 return new NVorriD<uint64_t>(machInst, vd, bigImm); 864 } 865 } 866 } 867 } 868 return new Unknown(machInst); 869 } 870 871 static StaticInstPtr 872 decodeNeonTwoRegAndShift(ExtMachInst machInst) 873 { 874 const uint32_t a = bits(machInst, 11, 8); 875 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 876 const bool b = bits(machInst, 6); 877 const bool l = bits(machInst, 7); 878 const IntRegIndex vd = 879 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 880 (bits(machInst, 22) << 4))); 881 const IntRegIndex vm = 882 (IntRegIndex)(2 * (bits(machInst, 3, 0) | 883 (bits(machInst, 5) << 4))); 884 unsigned imm6 = bits(machInst, 21, 16); 885 unsigned imm = ((l ? 1 : 0) << 6) | imm6; 886 unsigned size = 3; 887 unsigned lShiftAmt = 0; 888 unsigned bitSel; 889 for (bitSel = 1 << 6; true; bitSel >>= 1) { 890 if (bitSel & imm) 891 break; 892 else if (!size) 893 return new Unknown(machInst); 894 size--; 895 } 896 lShiftAmt = imm6 & ~bitSel; 897 unsigned rShiftAmt = 0; 898 if (a != 0xe && a != 0xf) { 899 if (size > 2) 900 rShiftAmt = 64 - imm6; 901 else 902 rShiftAmt = 2 * (8 << size) - imm6; 903 } 904 905 switch (a) { 906 case 0x0: 907 return decodeNeonUSTwoShiftReg<NVshrD, NVshrQ>( 908 b, u, size, machInst, vd, vm, rShiftAmt); 909 case 0x1: 910 return decodeNeonUSTwoShiftReg<NVsraD, NVsraQ>( 911 b, u, size, machInst, vd, vm, rShiftAmt); 912 case 0x2: 913 return decodeNeonUSTwoShiftReg<NVrshrD, NVrshrQ>( 914 b, u, size, machInst, vd, vm, rShiftAmt); 915 case 0x3: 916 return decodeNeonUSTwoShiftReg<NVrsraD, NVrsraQ>( 917 b, u, size, machInst, vd, vm, rShiftAmt); 918 case 0x4: 919 if (u) { 920 return decodeNeonUTwoShiftReg<NVsriD, NVsriQ>( 921 b, size, machInst, vd, vm, rShiftAmt); 922 } else { 923 return new Unknown(machInst); 924 } 925 case 0x5: 926 if (u) { 927 return decodeNeonUTwoShiftReg<NVsliD, NVsliQ>( 928 b, size, machInst, vd, vm, lShiftAmt); 929 } else { 930 return decodeNeonUTwoShiftReg<NVshlD, NVshlQ>( 931 b, size, machInst, vd, vm, lShiftAmt); 932 } 933 case 0x6: 934 case 0x7: 935 if (u) { 936 if (a == 0x6) { 937 return decodeNeonSTwoShiftReg<NVqshlusD, NVqshlusQ>( 938 b, size, machInst, vd, vm, lShiftAmt); 939 } else { 940 return decodeNeonUTwoShiftReg<NVqshluD, NVqshluQ>( 941 b, size, machInst, vd, vm, lShiftAmt); 942 } 943 } else { 944 return decodeNeonSTwoShiftReg<NVqshlD, NVqshlQ>( 945 b, size, machInst, vd, vm, lShiftAmt); 946 } 947 case 0x8: 948 if (l) { 949 return new Unknown(machInst); 950 } else if (u) { 951 return decodeNeonSTwoShiftSReg<NVqshruns, NVqrshruns>( 952 b, size, machInst, vd, vm, rShiftAmt); 953 } else { 954 return decodeNeonUTwoShiftSReg<NVshrn, NVrshrn>( 955 b, size, machInst, vd, vm, rShiftAmt); 956 } 957 case 0x9: 958 if (l) { 959 return new Unknown(machInst); 960 } else if (u) { 961 return decodeNeonUTwoShiftSReg<NVqshrun, NVqrshrun>( 962 b, size, machInst, vd, vm, rShiftAmt); 963 } else { 964 return decodeNeonSTwoShiftSReg<NVqshrn, NVqrshrn>( 965 b, size, machInst, vd, vm, rShiftAmt); 966 } 967 case 0xa: 968 if (l || b) { 969 return new Unknown(machInst); 970 } else { 971 return decodeNeonUSTwoShiftSReg<NVmovl, NVshll>( 972 lShiftAmt, u, size, machInst, vd, vm, lShiftAmt); 973 } 974 case 0xe: 975 if (l) { 976 return new Unknown(machInst); 977 } else { 978 if (bits(imm6, 5) == 0) 979 return new Unknown(machInst); 980 if (u) { 981 if (b) { 982 return new NVcvtu2fpQ<float>( 983 machInst, vd, vm, 64 - imm6); 984 } else { 985 return new NVcvtu2fpD<float>( 986 machInst, vd, vm, 64 - imm6); 987 } 988 } else { 989 if (b) { 990 return new NVcvts2fpQ<float>( 991 machInst, vd, vm, 64 - imm6); 992 } else { 993 return new NVcvts2fpD<float>( 994 machInst, vd, vm, 64 - imm6); 995 } 996 } 997 } 998 case 0xf: 999 if (l) { 1000 return new Unknown(machInst); 1001 } else { 1002 if (bits(imm6, 5) == 0) 1003 return new Unknown(machInst); 1004 if (u) { 1005 if (b) { 1006 return new NVcvt2ufxQ<float>( 1007 machInst, vd, vm, 64 - imm6); 1008 } else { 1009 return new NVcvt2ufxD<float>( 1010 machInst, vd, vm, 64 - imm6); 1011 } 1012 } else { 1013 if (b) { 1014 return new NVcvt2sfxQ<float>( 1015 machInst, vd, vm, 64 - imm6); 1016 } else { 1017 return new NVcvt2sfxD<float>( 1018 machInst, vd, vm, 64 - imm6); 1019 } 1020 } 1021 } 1022 } 1023 return new Unknown(machInst); 1024 } 1025 1026 static StaticInstPtr 1027 decodeNeonThreeRegDiffLengths(ExtMachInst machInst) 1028 { 1029 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 1030 const uint32_t a = bits(machInst, 11, 8); 1031 const IntRegIndex vd = 1032 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 1033 (bits(machInst, 22) << 4))); 1034 const IntRegIndex vn = 1035 (IntRegIndex)(2 * (bits(machInst, 19, 16) | 1036 (bits(machInst, 7) << 4))); 1037 const IntRegIndex vm = 1038 (IntRegIndex)(2 * (bits(machInst, 3, 0) | 1039 (bits(machInst, 5) << 4))); 1040 const unsigned size = bits(machInst, 21, 20); 1041 switch (a) { 1042 case 0x0: 1043 return decodeNeonUSThreeUSReg<Vaddl>( 1044 u, size, machInst, vd, vn, vm); 1045 case 0x1: 1046 return decodeNeonUSThreeUSReg<Vaddw>( 1047 u, size, machInst, vd, vn, vm); 1048 case 0x2: 1049 return decodeNeonUSThreeUSReg<Vsubl>( 1050 u, size, machInst, vd, vn, vm); 1051 case 0x3: 1052 return decodeNeonUSThreeUSReg<Vsubw>( 1053 u, size, machInst, vd, vn, vm); 1054 case 0x4: 1055 if (u) { 1056 return decodeNeonUThreeUSReg<Vraddhn>( 1057 size, machInst, vd, vn, vm); 1058 } else { 1059 return decodeNeonUThreeUSReg<Vaddhn>( 1060 size, machInst, vd, vn, vm); 1061 } 1062 case 0x5: 1063 return decodeNeonUSThreeUSReg<Vabal>( 1064 u, size, machInst, vd, vn, vm); 1065 case 0x6: 1066 if (u) { 1067 return decodeNeonUThreeUSReg<Vrsubhn>( 1068 size, machInst, vd, vn, vm); 1069 } else { 1070 return decodeNeonUThreeUSReg<Vsubhn>( 1071 size, machInst, vd, vn, vm); 1072 } 1073 case 0x7: 1074 if (bits(machInst, 23)) { 1075 return decodeNeonUSThreeUSReg<Vabdl>( 1076 u, size, machInst, vd, vn, vm); 1077 } else { 1078 return decodeNeonUSThreeReg<VabdD, VabdQ>( 1079 bits(machInst, 6), u, size, machInst, vd, vn, vm); 1080 } 1081 case 0x8: 1082 return decodeNeonUSThreeUSReg<Vmlal>( 1083 u, size, machInst, vd, vn, vm); 1084 case 0xa: 1085 return decodeNeonUSThreeUSReg<Vmlsl>( 1086 u, size, machInst, vd, vn, vm); 1087 case 0x9: 1088 if (u) { 1089 return new Unknown(machInst); 1090 } else { 1091 return decodeNeonSThreeUSReg<Vqdmlal>( 1092 size, machInst, vd, vn, vm); 1093 } 1094 case 0xb: 1095 if (u) { 1096 return new Unknown(machInst); 1097 } else { 1098 return decodeNeonSThreeUSReg<Vqdmlsl>( 1099 size, machInst, vd, vn, vm); 1100 } 1101 case 0xc: 1102 return decodeNeonUSThreeUSReg<Vmull>( 1103 u, size, machInst, vd, vn, vm); 1104 case 0xd: 1105 if (u) { 1106 return new Unknown(machInst); 1107 } else { 1108 return decodeNeonSThreeUSReg<Vqdmull>( 1109 size, machInst, vd, vn, vm); 1110 } 1111 case 0xe: 1112 return decodeNeonUThreeUSReg<Vmullp>( 1113 size, machInst, vd, vn, vm); 1114 } 1115 return new Unknown(machInst); 1116 } 1117 1118 static StaticInstPtr 1119 decodeNeonTwoRegScalar(ExtMachInst machInst) 1120 { 1121 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 1122 const uint32_t a = bits(machInst, 11, 8); 1123 const unsigned size = bits(machInst, 21, 20); 1124 const IntRegIndex vd = 1125 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 1126 (bits(machInst, 22) << 4))); 1127 const IntRegIndex vn = 1128 (IntRegIndex)(2 * (bits(machInst, 19, 16) | 1129 (bits(machInst, 7) << 4))); 1130 const IntRegIndex vm = (size == 2) ? 1131 (IntRegIndex)(2 * bits(machInst, 3, 0)) : 1132 (IntRegIndex)(2 * bits(machInst, 2, 0)); 1133 const unsigned index = (size == 2) ? (unsigned)bits(machInst, 5) : 1134 (bits(machInst, 3) | (bits(machInst, 5) << 1)); 1135 switch (a) { 1136 case 0x0: 1137 if (u) { 1138 switch (size) { 1139 case 1: 1140 return new VmlasQ<uint16_t>(machInst, vd, vn, vm, index); 1141 case 2: 1142 return new VmlasQ<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 VmlasD<uint16_t>(machInst, vd, vn, vm, index); 1150 case 2: 1151 return new VmlasD<uint32_t>(machInst, vd, vn, vm, index); 1152 default: 1153 return new Unknown(machInst); 1154 } 1155 } 1156 case 0x1: 1157 if (u) 1158 return new VmlasQFp<float>(machInst, vd, vn, vm, index); 1159 else 1160 return new VmlasDFp<float>(machInst, vd, vn, vm, index); 1161 case 0x4: 1162 if (u) { 1163 switch (size) { 1164 case 1: 1165 return new VmlssQ<uint16_t>(machInst, vd, vn, vm, index); 1166 case 2: 1167 return new VmlssQ<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 VmlssD<uint16_t>(machInst, vd, vn, vm, index); 1175 case 2: 1176 return new VmlssD<uint32_t>(machInst, vd, vn, vm, index); 1177 default: 1178 return new Unknown(machInst); 1179 } 1180 } 1181 case 0x5: 1182 if (u) 1183 return new VmlssQFp<float>(machInst, vd, vn, vm, index); 1184 else 1185 return new VmlssDFp<float>(machInst, vd, vn, vm, index); 1186 case 0x2: 1187 if (u) { 1188 switch (size) { 1189 case 1: 1190 return new Vmlals<uint16_t>(machInst, vd, vn, vm, index); 1191 case 2: 1192 return new Vmlals<uint32_t>(machInst, vd, vn, vm, index); 1193 default: 1194 return new Unknown(machInst); 1195 } 1196 } else { 1197 switch (size) { 1198 case 1: 1199 return new Vmlals<int16_t>(machInst, vd, vn, vm, index); 1200 case 2: 1201 return new Vmlals<int32_t>(machInst, vd, vn, vm, index); 1202 default: 1203 return new Unknown(machInst); 1204 } 1205 } 1206 case 0x6: 1207 if (u) { 1208 switch (size) { 1209 case 1: 1210 return new Vmlsls<uint16_t>(machInst, vd, vn, vm, index); 1211 case 2: 1212 return new Vmlsls<uint32_t>(machInst, vd, vn, vm, index); 1213 default: 1214 return new Unknown(machInst); 1215 } 1216 } else { 1217 switch (size) { 1218 case 1: 1219 return new Vmlsls<int16_t>(machInst, vd, vn, vm, index); 1220 case 2: 1221 return new Vmlsls<int32_t>(machInst, vd, vn, vm, index); 1222 default: 1223 return new Unknown(machInst); 1224 } 1225 } 1226 case 0x3: 1227 if (u) { 1228 return new Unknown(machInst); 1229 } else { 1230 switch (size) { 1231 case 1: 1232 return new Vqdmlals<int16_t>(machInst, vd, vn, vm, index); 1233 case 2: 1234 return new Vqdmlals<int32_t>(machInst, vd, vn, vm, index); 1235 default: 1236 return new Unknown(machInst); 1237 } 1238 } 1239 case 0x7: 1240 if (u) { 1241 return new Unknown(machInst); 1242 } else { 1243 switch (size) { 1244 case 1: 1245 return new Vqdmlsls<int16_t>(machInst, vd, vn, vm, index); 1246 case 2: 1247 return new Vqdmlsls<int32_t>(machInst, vd, vn, vm, index); 1248 default: 1249 return new Unknown(machInst); 1250 } 1251 } 1252 case 0x8: 1253 if (u) { 1254 switch (size) { 1255 case 1: 1256 return new VmulsQ<uint16_t>(machInst, vd, vn, vm, index); 1257 case 2: 1258 return new VmulsQ<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 VmulsD<uint16_t>(machInst, vd, vn, vm, index); 1266 case 2: 1267 return new VmulsD<uint32_t>(machInst, vd, vn, vm, index); 1268 default: 1269 return new Unknown(machInst); 1270 } 1271 } 1272 case 0x9: 1273 if (u) 1274 return new VmulsQFp<float>(machInst, vd, vn, vm, index); 1275 else 1276 return new VmulsDFp<float>(machInst, vd, vn, vm, index); 1277 case 0xa: 1278 if (u) { 1279 switch (size) { 1280 case 1: 1281 return new Vmulls<uint16_t>(machInst, vd, vn, vm, index); 1282 case 2: 1283 return new Vmulls<uint32_t>(machInst, vd, vn, vm, index); 1284 default: 1285 return new Unknown(machInst); 1286 } 1287 } else { 1288 switch (size) { 1289 case 1: 1290 return new Vmulls<int16_t>(machInst, vd, vn, vm, index); 1291 case 2: 1292 return new Vmulls<int32_t>(machInst, vd, vn, vm, index); 1293 default: 1294 return new Unknown(machInst); 1295 } 1296 } 1297 case 0xb: 1298 if (u) { 1299 return new Unknown(machInst); 1300 } else { 1301 if (u) { 1302 switch (size) { 1303 case 1: 1304 return new Vqdmulls<uint16_t>( 1305 machInst, vd, vn, vm, index); 1306 case 2: 1307 return new Vqdmulls<uint32_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 Vqdmulls<int16_t>( 1316 machInst, vd, vn, vm, index); 1317 case 2: 1318 return new Vqdmulls<int32_t>( 1319 machInst, vd, vn, vm, index); 1320 default: 1321 return new Unknown(machInst); 1322 } 1323 } 1324 } 1325 case 0xc: 1326 if (u) { 1327 switch (size) { 1328 case 1: 1329 return new VqdmulhsQ<int16_t>( 1330 machInst, vd, vn, vm, index); 1331 case 2: 1332 return new VqdmulhsQ<int32_t>( 1333 machInst, vd, vn, vm, index); 1334 default: 1335 return new Unknown(machInst); 1336 } 1337 } else { 1338 switch (size) { 1339 case 1: 1340 return new VqdmulhsD<int16_t>( 1341 machInst, vd, vn, vm, index); 1342 case 2: 1343 return new VqdmulhsD<int32_t>( 1344 machInst, vd, vn, vm, index); 1345 default: 1346 return new Unknown(machInst); 1347 } 1348 } 1349 case 0xd: 1350 if (u) { 1351 switch (size) { 1352 case 1: 1353 return new VqrdmulhsQ<int16_t>( 1354 machInst, vd, vn, vm, index); 1355 case 2: 1356 return new VqrdmulhsQ<int32_t>( 1357 machInst, vd, vn, vm, index); 1358 default: 1359 return new Unknown(machInst); 1360 } 1361 } else { 1362 switch (size) { 1363 case 1: 1364 return new VqrdmulhsD<int16_t>( 1365 machInst, vd, vn, vm, index); 1366 case 2: 1367 return new VqrdmulhsD<int32_t>( 1368 machInst, vd, vn, vm, index); 1369 default: 1370 return new Unknown(machInst); 1371 } 1372 } 1373 } 1374 return new Unknown(machInst); 1375 } 1376 1377 static StaticInstPtr 1378 decodeNeonTwoRegMisc(ExtMachInst machInst) 1379 { 1380 const uint32_t a = bits(machInst, 17, 16); 1381 const uint32_t b = bits(machInst, 10, 6); 1382 const bool q = bits(machInst, 6); 1383 const IntRegIndex vd = 1384 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 1385 (bits(machInst, 22) << 4))); 1386 const IntRegIndex vm = 1387 (IntRegIndex)(2 * (bits(machInst, 3, 0) | 1388 (bits(machInst, 5) << 4))); 1389 const unsigned size = bits(machInst, 19, 18); 1390 switch (a) { 1391 case 0x0: 1392 switch (bits(b, 4, 1)) { 1393 case 0x0: 1394 switch (size) { 1395 case 0: 1396 if (q) { 1397 return new NVrev64Q<uint8_t>(machInst, vd, vm); 1398 } else { 1399 return new NVrev64D<uint8_t>(machInst, vd, vm); 1400 } 1401 case 1: 1402 if (q) { 1403 return new NVrev64Q<uint16_t>(machInst, vd, vm); 1404 } else { 1405 return new NVrev64D<uint16_t>(machInst, vd, vm); 1406 } 1407 case 2: 1408 if (q) { 1409 return new NVrev64Q<uint32_t>(machInst, vd, vm); 1410 } else { 1411 return new NVrev64D<uint32_t>(machInst, vd, vm); 1412 } 1413 default: 1414 return new Unknown(machInst); 1415 } 1416 case 0x1: 1417 switch (size) { 1418 case 0: 1419 if (q) { 1420 return new NVrev32Q<uint8_t>(machInst, vd, vm); 1421 } else { 1422 return new NVrev32D<uint8_t>(machInst, vd, vm); 1423 } 1424 case 1: 1425 if (q) { 1426 return new NVrev32Q<uint16_t>(machInst, vd, vm); 1427 } else { 1428 return new NVrev32D<uint16_t>(machInst, vd, vm); 1429 } 1430 default: 1431 return new Unknown(machInst); 1432 } 1433 case 0x2: 1434 if (size != 0) { 1435 return new Unknown(machInst); 1436 } else if (q) { 1437 return new NVrev16Q<uint8_t>(machInst, vd, vm); 1438 } else { 1439 return new NVrev16D<uint8_t>(machInst, vd, vm); 1440 } 1441 case 0x4: 1442 return decodeNeonSTwoMiscSReg<NVpaddlD, NVpaddlQ>( 1443 q, size, machInst, vd, vm); 1444 case 0x5: 1445 return decodeNeonUTwoMiscSReg<NVpaddlD, NVpaddlQ>( 1446 q, size, machInst, vd, vm); 1447 case 0x8: 1448 return decodeNeonSTwoMiscReg<NVclsD, NVclsQ>( 1449 q, size, machInst, vd, vm); 1450 case 0x9: 1451 return decodeNeonSTwoMiscReg<NVclzD, NVclzQ>( 1452 q, size, machInst, vd, vm); 1453 case 0xa: 1454 return decodeNeonUTwoMiscReg<NVcntD, NVcntQ>( 1455 q, size, machInst, vd, vm); 1456 case 0xb: 1457 if (q) 1458 return new NVmvnQ<uint64_t>(machInst, vd, vm); 1459 else 1460 return new NVmvnD<uint64_t>(machInst, vd, vm); 1461 case 0xc: 1462 return decodeNeonSTwoMiscSReg<NVpadalD, NVpadalQ>( 1463 q, size, machInst, vd, vm); 1464 case 0xd: 1465 return decodeNeonUTwoMiscSReg<NVpadalD, NVpadalQ>( 1466 q, size, machInst, vd, vm); 1467 case 0xe: 1468 return decodeNeonSTwoMiscReg<NVqabsD, NVqabsQ>( 1469 q, size, machInst, vd, vm); 1470 case 0xf: 1471 return decodeNeonSTwoMiscReg<NVqnegD, NVqnegQ>( 1472 q, size, machInst, vd, vm); 1473 default: 1474 return new Unknown(machInst); 1475 } 1476 case 0x1: 1477 switch (bits(b, 3, 1)) { 1478 case 0x0: 1479 if (bits(b, 4)) { 1480 if (q) { 1481 return new NVcgtQFp<float>(machInst, vd, vm); 1482 } else { 1483 return new NVcgtDFp<float>(machInst, vd, vm); 1484 } 1485 } else { 1486 return decodeNeonSTwoMiscReg<NVcgtD, NVcgtQ>( 1487 q, size, machInst, vd, vm); 1488 } 1489 case 0x1: 1490 if (bits(b, 4)) { 1491 if (q) { 1492 return new NVcgeQFp<float>(machInst, vd, vm); 1493 } else { 1494 return new NVcgeDFp<float>(machInst, vd, vm); 1495 } 1496 } else { 1497 return decodeNeonSTwoMiscReg<NVcgeD, NVcgeQ>( 1498 q, size, machInst, vd, vm); 1499 } 1500 case 0x2: 1501 if (bits(b, 4)) { 1502 if (q) { 1503 return new NVceqQFp<float>(machInst, vd, vm); 1504 } else { 1505 return new NVceqDFp<float>(machInst, vd, vm); 1506 } 1507 } else { 1508 return decodeNeonSTwoMiscReg<NVceqD, NVceqQ>( 1509 q, size, machInst, vd, vm); 1510 } 1511 case 0x3: 1512 if (bits(b, 4)) { 1513 if (q) { 1514 return new NVcleQFp<float>(machInst, vd, vm); 1515 } else { 1516 return new NVcleDFp<float>(machInst, vd, vm); 1517 } 1518 } else { 1519 return decodeNeonSTwoMiscReg<NVcleD, NVcleQ>( 1520 q, size, machInst, vd, vm); 1521 } 1522 case 0x4: 1523 if (bits(b, 4)) { 1524 if (q) { 1525 return new NVcltQFp<float>(machInst, vd, vm); 1526 } else { 1527 return new NVcltDFp<float>(machInst, vd, vm); 1528 } 1529 } else { 1530 return decodeNeonSTwoMiscReg<NVcltD, NVcltQ>( 1531 q, size, machInst, vd, vm); 1532 } 1533 case 0x6: 1534 if (bits(machInst, 10)) { 1535 if (q) 1536 return new NVabsQFp<float>(machInst, vd, vm); 1537 else 1538 return new NVabsDFp<float>(machInst, vd, vm); 1539 } else { 1540 return decodeNeonSTwoMiscReg<NVabsD, NVabsQ>( 1541 q, size, machInst, vd, vm); 1542 } 1543 case 0x7: 1544 if (bits(machInst, 10)) { 1545 if (q) 1546 return new NVnegQFp<float>(machInst, vd, vm); 1547 else 1548 return new NVnegDFp<float>(machInst, vd, vm); 1549 } else { 1550 return decodeNeonSTwoMiscReg<NVnegD, NVnegQ>( 1551 q, size, machInst, vd, vm); 1552 } 1553 } 1554 case 0x2: 1555 switch (bits(b, 4, 1)) { 1556 case 0x0: 1557 if (q) 1558 return new NVswpQ<uint64_t>(machInst, vd, vm); 1559 else 1560 return new NVswpD<uint64_t>(machInst, vd, vm); 1561 case 0x1: 1562 return decodeNeonUTwoMiscSReg<NVtrnD, NVtrnQ>( 1563 q, size, machInst, vd, vm); 1564 case 0x2: 1565 return decodeNeonUTwoMiscReg<NVuzpD, NVuzpQ>( 1566 q, size, machInst, vd, vm); 1567 case 0x3: 1568 return decodeNeonUTwoMiscReg<NVzipD, NVzipQ>( 1569 q, size, machInst, vd, vm); 1570 case 0x4: 1571 if (b == 0x8) { 1572 return decodeNeonUTwoMiscUSReg<NVmovn>( 1573 size, machInst, vd, vm); 1574 } else { 1575 return decodeNeonSTwoMiscUSReg<NVqmovuns>( 1576 size, machInst, vd, vm); 1577 } 1578 case 0x5: 1579 if (q) { 1580 return decodeNeonUTwoMiscUSReg<NVqmovun>( 1581 size, machInst, vd, vm); 1582 } else { 1583 return decodeNeonSTwoMiscUSReg<NVqmovn>( 1584 size, machInst, vd, vm); 1585 } 1586 case 0x6: 1587 if (b == 0xc) { 1588 return decodeNeonSTwoShiftUSReg<NVshll>( 1589 size, machInst, vd, vm, 8 << size); 1590 } else { 1591 return new Unknown(machInst); 1592 } 1593 case 0xc: 1594 case 0xe: 1595 if (b == 0x18) { 1596 if (size != 1 || (vm % 2)) 1597 return new Unknown(machInst); 1598 return new NVcvts2h<uint16_t>(machInst, vd, vm); 1599 } else if (b == 0x1c) { 1600 if (size != 1 || (vd % 2)) 1601 return new Unknown(machInst); 1602 return new NVcvth2s<uint16_t>(machInst, vd, vm); 1603 } else { 1604 return new Unknown(machInst); 1605 } 1606 default: 1607 return new Unknown(machInst); 1608 } 1609 case 0x3: 1610 if (bits(b, 4, 3) == 0x3) { 1611 if ((q && (vd % 2 || vm % 2)) || size != 2) { 1612 return new Unknown(machInst); 1613 } else { 1614 if (bits(b, 2)) { 1615 if (bits(b, 1)) { 1616 if (q) { 1617 return new NVcvt2ufxQ<float>( 1618 machInst, vd, vm, 0); 1619 } else { 1620 return new NVcvt2ufxD<float>( 1621 machInst, vd, vm, 0); 1622 } 1623 } else { 1624 if (q) { 1625 return new NVcvt2sfxQ<float>( 1626 machInst, vd, vm, 0); 1627 } else { 1628 return new NVcvt2sfxD<float>( 1629 machInst, vd, vm, 0); 1630 } 1631 } 1632 } else { 1633 if (bits(b, 1)) { 1634 if (q) { 1635 return new NVcvtu2fpQ<float>( 1636 machInst, vd, vm, 0); 1637 } else { 1638 return new NVcvtu2fpD<float>( 1639 machInst, vd, vm, 0); 1640 } 1641 } else { 1642 if (q) { 1643 return new NVcvts2fpQ<float>( 1644 machInst, vd, vm, 0); 1645 } else { 1646 return new NVcvts2fpD<float>( 1647 machInst, vd, vm, 0); 1648 } 1649 } 1650 } 1651 } 1652 } else if ((b & 0x1a) == 0x10) { 1653 if (bits(b, 2)) { 1654 if (q) { 1655 return new NVrecpeQFp<float>(machInst, vd, vm); 1656 } else { 1657 return new NVrecpeDFp<float>(machInst, vd, vm); 1658 } 1659 } else { 1660 if (q) { 1661 return new NVrecpeQ<uint32_t>(machInst, vd, vm); 1662 } else { 1663 return new NVrecpeD<uint32_t>(machInst, vd, vm); 1664 } 1665 } 1666 } else if ((b & 0x1a) == 0x12) { 1667 if (bits(b, 2)) { 1668 if (q) { 1669 return new NVrsqrteQFp<float>(machInst, vd, vm); 1670 } else { 1671 return new NVrsqrteDFp<float>(machInst, vd, vm); 1672 } 1673 } else { 1674 if (q) { 1675 return new NVrsqrteQ<uint32_t>(machInst, vd, vm); 1676 } else { 1677 return new NVrsqrteD<uint32_t>(machInst, vd, vm); 1678 } 1679 } 1680 } else { 1681 return new Unknown(machInst); 1682 } 1683 } 1684 return new Unknown(machInst); 1685 } 1686 1687 StaticInstPtr 1688 decodeNeonData(ExtMachInst machInst) 1689 { 1690 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 1691 const uint32_t a = bits(machInst, 23, 19); 1692 const uint32_t b = bits(machInst, 11, 8); 1693 const uint32_t c = bits(machInst, 7, 4); 1694 if (bits(a, 4) == 0) { 1695 return decodeNeonThreeRegistersSameLength(machInst); 1696 } else if ((c & 0x9) == 1) { 1697 if ((a & 0x7) == 0) { 1698 return decodeNeonOneRegModImm(machInst); 1699 } else { 1700 return decodeNeonTwoRegAndShift(machInst); 1701 } 1702 } else if ((c & 0x9) == 9) { 1703 return decodeNeonTwoRegAndShift(machInst); 1704 } else if (bits(a, 2, 1) != 0x3) { 1705 if ((c & 0x5) == 0) { 1706 return decodeNeonThreeRegDiffLengths(machInst); 1707 } else if ((c & 0x5) == 4) { 1708 return decodeNeonTwoRegScalar(machInst); 1709 } 1710 } else if ((a & 0x16) == 0x16) { 1711 const IntRegIndex vd = 1712 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 1713 (bits(machInst, 22) << 4))); 1714 const IntRegIndex vn = 1715 (IntRegIndex)(2 * (bits(machInst, 19, 16) | 1716 (bits(machInst, 7) << 4))); 1717 const IntRegIndex vm = 1718 (IntRegIndex)(2 * (bits(machInst, 3, 0) | 1719 (bits(machInst, 5) << 4))); 1720 if (!u) { 1721 if (bits(c, 0) == 0) { 1722 unsigned imm4 = bits(machInst, 11, 8); 1723 bool q = bits(machInst, 6); 1724 if (imm4 >= 16 && !q) 1725 return new Unknown(machInst); 1726 if (q) { 1727 return new NVextQ<uint8_t>(machInst, vd, vn, vm, imm4); 1728 } else { 1729 return new NVextD<uint8_t>(machInst, vd, vn, vm, imm4); 1730 } 1731 } 1732 } else if (bits(b, 3) == 0 && bits(c, 0) == 0) { 1733 return decodeNeonTwoRegMisc(machInst); 1734 } else if (bits(b, 3, 2) == 0x2 && bits(c, 0) == 0) { 1735 unsigned length = bits(machInst, 9, 8) + 1; 1736 if ((uint32_t)vn / 2 + length > 32) 1737 return new Unknown(machInst); 1738 if (bits(machInst, 6) == 0) { 1739 switch (length) { 1740 case 1: 1741 return new NVtbl1(machInst, vd, vn, vm); 1742 case 2: 1743 return new NVtbl2(machInst, vd, vn, vm); 1744 case 3: 1745 return new NVtbl3(machInst, vd, vn, vm); 1746 case 4: 1747 return new NVtbl4(machInst, vd, vn, vm); 1748 } 1749 } else { 1750 switch (length) { 1751 case 1: 1752 return new NVtbx1(machInst, vd, vn, vm); 1753 case 2: 1754 return new NVtbx2(machInst, vd, vn, vm); 1755 case 3: 1756 return new NVtbx3(machInst, vd, vn, vm); 1757 case 4: 1758 return new NVtbx4(machInst, vd, vn, vm); 1759 } 1760 } 1761 } else if (b == 0xc && (c & 0x9) == 0) { 1762 unsigned imm4 = bits(machInst, 19, 16); 1763 if (bits(imm4, 2, 0) == 0) 1764 return new Unknown(machInst); 1765 unsigned size = 0; 1766 while ((imm4 & 0x1) == 0) { 1767 size++; 1768 imm4 >>= 1; 1769 } 1770 unsigned index = imm4 >> 1; 1771 const bool q = bits(machInst, 6); 1772 return decodeNeonUTwoShiftSReg<NVdupD, NVdupQ>( 1773 q, size, machInst, vd, vm, index); 1774 } 1775 } 1776 return new Unknown(machInst); 1777 } 1778 ''' 1779}}; 1780 1781def format ThumbNeonMem() {{ 1782 decode_block = ''' 1783 return decodeNeonMem(machInst); 1784 ''' 1785}}; 1786 1787def format ThumbNeonData() {{ 1788 decode_block = ''' 1789 return decodeNeonData(machInst); 1790 ''' 1791}}; 1792 1793let {{ 1794 header_output = ''' 1795 StaticInstPtr 1796 decodeExtensionRegLoadStore(ExtMachInst machInst); 1797 ''' 1798 decoder_output = ''' 1799 StaticInstPtr 1800 decodeExtensionRegLoadStore(ExtMachInst machInst) 1801 { 1802 const uint32_t opcode = bits(machInst, 24, 20); 1803 const uint32_t offset = bits(machInst, 7, 0); 1804 const bool single = (bits(machInst, 8) == 0); 1805 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 1806 RegIndex vd; 1807 if (single) { 1808 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 1809 bits(machInst, 22)); 1810 } else { 1811 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 1812 (bits(machInst, 22) << 5)); 1813 } 1814 switch (bits(opcode, 4, 3)) { 1815 case 0x0: 1816 if (bits(opcode, 4, 1) == 0x2 && 1817 !(machInst.thumb == 1 && bits(machInst, 28) == 1) && 1818 !(machInst.thumb == 0 && machInst.condCode == 0xf)) { 1819 if ((bits(machInst, 7, 4) & 0xd) != 1) { 1820 break; 1821 } 1822 const IntRegIndex rt = 1823 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 1824 const IntRegIndex rt2 = 1825 (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 1826 const bool op = bits(machInst, 20); 1827 uint32_t vm; 1828 if (single) { 1829 vm = (bits(machInst, 3, 0) << 1) | bits(machInst, 5); 1830 } else { 1831 vm = (bits(machInst, 3, 0) << 1) | 1832 (bits(machInst, 5) << 5); 1833 } 1834 if (op) { 1835 return new Vmov2Core2Reg(machInst, rt, rt2, 1836 (IntRegIndex)vm); 1837 } else { 1838 return new Vmov2Reg2Core(machInst, (IntRegIndex)vm, 1839 rt, rt2); 1840 } 1841 } 1842 break; 1843 case 0x1: 1844 { 1845 if (offset == 0 || vd + offset/2 > NumFloatV7ArchRegs) { 1846 break; 1847 } 1848 switch (bits(opcode, 1, 0)) { 1849 case 0x0: 1850 return new VLdmStm(machInst, rn, vd, single, 1851 true, false, false, offset); 1852 case 0x1: 1853 return new VLdmStm(machInst, rn, vd, single, 1854 true, false, true, offset); 1855 case 0x2: 1856 return new VLdmStm(machInst, rn, vd, single, 1857 true, true, false, offset); 1858 case 0x3: 1859 // If rn == sp, then this is called vpop. 1860 return new VLdmStm(machInst, rn, vd, single, 1861 true, true, true, offset); 1862 } 1863 } 1864 case 0x2: 1865 if (bits(opcode, 1, 0) == 0x2) { 1866 // If rn == sp, then this is called vpush. 1867 return new VLdmStm(machInst, rn, vd, single, 1868 false, true, false, offset); 1869 } else if (bits(opcode, 1, 0) == 0x3) { 1870 return new VLdmStm(machInst, rn, vd, single, 1871 false, true, true, offset); 1872 } 1873 // Fall through on purpose 1874 case 0x3: 1875 const bool up = (bits(machInst, 23) == 1); 1876 const uint32_t imm = bits(machInst, 7, 0) << 2; 1877 if (single) { 1878 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 1879 (bits(machInst, 22))); 1880 } else { 1881 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 1882 (bits(machInst, 22) << 5)); 1883 } 1884 if (bits(opcode, 1, 0) == 0x0) { 1885 if (single) { 1886 if (up) { 1887 return new %(vstr_us)s(machInst, vd, rn, up, imm); 1888 } else { 1889 return new %(vstr_s)s(machInst, vd, rn, up, imm); 1890 } 1891 } else { 1892 if (up) { 1893 return new %(vstr_ud)s(machInst, vd, vd + 1, 1894 rn, up, imm); 1895 } else { 1896 return new %(vstr_d)s(machInst, vd, vd + 1, 1897 rn, up, imm); 1898 } 1899 } 1900 } else if (bits(opcode, 1, 0) == 0x1) { 1901 if (single) { 1902 if (up) { 1903 return new %(vldr_us)s(machInst, vd, rn, up, imm); 1904 } else { 1905 return new %(vldr_s)s(machInst, vd, rn, up, imm); 1906 } 1907 } else { 1908 if (up) { 1909 return new %(vldr_ud)s(machInst, vd, vd + 1, 1910 rn, up, imm); 1911 } else { 1912 return new %(vldr_d)s(machInst, vd, vd + 1, 1913 rn, up, imm); 1914 } 1915 } 1916 } 1917 } 1918 return new Unknown(machInst); 1919 } 1920 ''' % { 1921 "vldr_us" : "VLDR_" + loadImmClassName(False, True, False), 1922 "vldr_s" : "VLDR_" + loadImmClassName(False, False, False), 1923 "vldr_ud" : "VLDR_" + loadDoubleImmClassName(False, True, False), 1924 "vldr_d" : "VLDR_" + loadDoubleImmClassName(False, False, False), 1925 "vstr_us" : "VSTR_" + storeImmClassName(False, True, False), 1926 "vstr_s" : "VSTR_" + storeImmClassName(False, False, False), 1927 "vstr_ud" : "VSTR_" + storeDoubleImmClassName(False, True, False), 1928 "vstr_d" : "VSTR_" + storeDoubleImmClassName(False, False, False) 1929 } 1930}}; 1931 1932def format ExtensionRegLoadStore() {{ 1933 decode_block = ''' 1934 return decodeExtensionRegLoadStore(machInst); 1935 ''' 1936}}; 1937 1938let {{ 1939 header_output = ''' 1940 StaticInstPtr 1941 decodeShortFpTransfer(ExtMachInst machInst); 1942 ''' 1943 decoder_output = ''' 1944 StaticInstPtr 1945 decodeShortFpTransfer(ExtMachInst machInst) 1946 { 1947 const uint32_t l = bits(machInst, 20); 1948 const uint32_t c = bits(machInst, 8); 1949 const uint32_t a = bits(machInst, 23, 21); 1950 const uint32_t b = bits(machInst, 6, 5); 1951 if ((machInst.thumb == 1 && bits(machInst, 28) == 1) || 1952 (machInst.thumb == 0 && machInst.condCode == 0xf)) {
|
1954 } 1955 if (l == 0 && c == 0) { 1956 if (a == 0) { 1957 const uint32_t vn = (bits(machInst, 19, 16) << 1) | 1958 bits(machInst, 7); 1959 const IntRegIndex rt = 1960 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 1961 if (bits(machInst, 20) == 1) { 1962 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn); 1963 } else { 1964 return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt); 1965 } 1966 } else if (a == 0x7) { 1967 const IntRegIndex rt = 1968 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 1969 uint32_t reg = bits(machInst, 19, 16); 1970 uint32_t specReg; 1971 switch (reg) { 1972 case 0: 1973 specReg = MISCREG_FPSID; 1974 break; 1975 case 1: 1976 specReg = MISCREG_FPSCR; 1977 break; 1978 case 6: 1979 specReg = MISCREG_MVFR1; 1980 break; 1981 case 7: 1982 specReg = MISCREG_MVFR0; 1983 break; 1984 case 8: 1985 specReg = MISCREG_FPEXC; 1986 break; 1987 default: 1988 return new Unknown(machInst); 1989 } 1990 if (specReg == MISCREG_FPSCR) { 1991 return new VmsrFpscr(machInst, (IntRegIndex)specReg, rt); 1992 } else { 1993 uint32_t iss = mcrMrcIssBuild(0, bits(machInst, 3, 0), rt, 1994 reg, a, bits(machInst, 7, 5)); 1995 return new Vmsr(machInst, (IntRegIndex)specReg, rt, iss); 1996 } 1997 } 1998 } else if (l == 0 && c == 1) { 1999 if (bits(a, 2) == 0) { 2000 uint32_t vd = (bits(machInst, 7) << 5) | 2001 (bits(machInst, 19, 16) << 1); 2002 // Handle accessing each single precision half of the vector. 2003 vd += bits(machInst, 21); 2004 const IntRegIndex rt = 2005 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2006 if (bits(machInst, 22) == 1) { 2007 return new VmovCoreRegB(machInst, (IntRegIndex)vd, 2008 rt, bits(machInst, 6, 5)); 2009 } else if (bits(machInst, 5) == 1) { 2010 return new VmovCoreRegH(machInst, (IntRegIndex)vd, 2011 rt, bits(machInst, 6)); 2012 } else if (bits(machInst, 6) == 0) { 2013 return new VmovCoreRegW(machInst, (IntRegIndex)vd, rt); 2014 } else { 2015 return new Unknown(machInst); 2016 } 2017 } else if (bits(b, 1) == 0) { 2018 bool q = bits(machInst, 21); 2019 unsigned be = (bits(machInst, 22) << 1) | (bits(machInst, 5)); 2020 IntRegIndex vd = (IntRegIndex)(2 * (uint32_t) 2021 (bits(machInst, 19, 16) | (bits(machInst, 7) << 4))); 2022 IntRegIndex rt = (IntRegIndex)(uint32_t) 2023 bits(machInst, 15, 12); 2024 if (q) { 2025 switch (be) { 2026 case 0: 2027 return new NVdupQGpr<uint32_t>(machInst, vd, rt); 2028 case 1: 2029 return new NVdupQGpr<uint16_t>(machInst, vd, rt); 2030 case 2: 2031 return new NVdupQGpr<uint8_t>(machInst, vd, rt); 2032 case 3: 2033 return new Unknown(machInst); 2034 } 2035 } else { 2036 switch (be) { 2037 case 0: 2038 return new NVdupDGpr<uint32_t>(machInst, vd, rt); 2039 case 1: 2040 return new NVdupDGpr<uint16_t>(machInst, vd, rt); 2041 case 2: 2042 return new NVdupDGpr<uint8_t>(machInst, vd, rt); 2043 case 3: 2044 return new Unknown(machInst); 2045 } 2046 } 2047 } 2048 } else if (l == 1 && c == 0) { 2049 if (a == 0) { 2050 const uint32_t vn = (bits(machInst, 19, 16) << 1) | 2051 bits(machInst, 7); 2052 const IntRegIndex rt = 2053 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2054 if (bits(machInst, 20) == 1) { 2055 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn); 2056 } else { 2057 return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt); 2058 } 2059 } else if (a == 7) { 2060 const IntRegIndex rt = 2061 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2062 uint32_t reg = bits(machInst, 19, 16); 2063 uint32_t specReg; 2064 switch (reg) { 2065 case 0: 2066 specReg = MISCREG_FPSID; 2067 break; 2068 case 1: 2069 specReg = MISCREG_FPSCR; 2070 break; 2071 case 6: 2072 specReg = MISCREG_MVFR1; 2073 break; 2074 case 7: 2075 specReg = MISCREG_MVFR0; 2076 break; 2077 case 8: 2078 specReg = MISCREG_FPEXC; 2079 break; 2080 default: 2081 return new Unknown(machInst); 2082 } 2083 if (rt == 0xf) { 2084 if (specReg == MISCREG_FPSCR) { 2085 return new VmrsApsrFpscr(machInst); 2086 } else { 2087 return new Unknown(machInst); 2088 } 2089 } else if (specReg == MISCREG_FPSCR) { 2090 return new VmrsFpscr(machInst, rt, (IntRegIndex)specReg); 2091 } else { 2092 uint32_t iss = mcrMrcIssBuild(l, bits(machInst, 3, 0), rt, 2093 reg, a, bits(machInst, 7, 5)); 2094 return new Vmrs(machInst, rt, (IntRegIndex)specReg, iss); 2095 } 2096 } 2097 } else { 2098 uint32_t vd = (bits(machInst, 7) << 5) | 2099 (bits(machInst, 19, 16) << 1); 2100 // Handle indexing into each single precision half of the vector. 2101 vd += bits(machInst, 21); 2102 uint32_t index; 2103 const IntRegIndex rt = 2104 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2105 const bool u = (bits(machInst, 23) == 1); 2106 if (bits(machInst, 22) == 1) { 2107 index = bits(machInst, 6, 5); 2108 if (u) { 2109 return new VmovRegCoreUB(machInst, rt, 2110 (IntRegIndex)vd, index); 2111 } else { 2112 return new VmovRegCoreSB(machInst, rt, 2113 (IntRegIndex)vd, index); 2114 } 2115 } else if (bits(machInst, 5) == 1) { 2116 index = bits(machInst, 6); 2117 if (u) { 2118 return new VmovRegCoreUH(machInst, rt, 2119 (IntRegIndex)vd, index); 2120 } else { 2121 return new VmovRegCoreSH(machInst, rt, 2122 (IntRegIndex)vd, index); 2123 } 2124 } else if (bits(machInst, 6) == 0 && !u) { 2125 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vd); 2126 } else { 2127 return new Unknown(machInst); 2128 } 2129 } 2130 return new Unknown(machInst); 2131 } 2132 ''' 2133}}; 2134 2135def format ShortFpTransfer() {{ 2136 decode_block = ''' 2137 return decodeShortFpTransfer(machInst); 2138 ''' 2139}}; 2140 2141let {{ 2142 header_output = ''' 2143 StaticInstPtr 2144 decodeVfpData(ExtMachInst machInst); 2145 ''' 2146 decoder_output = ''' 2147 StaticInstPtr 2148 decodeVfpData(ExtMachInst machInst) 2149 { 2150 const uint32_t opc1 = bits(machInst, 23, 20); 2151 const uint32_t opc2 = bits(machInst, 19, 16); 2152 const uint32_t opc3 = bits(machInst, 7, 6); 2153 //const uint32_t opc4 = bits(machInst, 3, 0); 2154 const bool single = (bits(machInst, 8) == 0); 2155 // Used to select between vcmp and vcmpe. 2156 const bool e = (bits(machInst, 7) == 1); 2157 IntRegIndex vd; 2158 IntRegIndex vm; 2159 IntRegIndex vn; 2160 if (single) { 2161 vd = (IntRegIndex)(bits(machInst, 22) | 2162 (bits(machInst, 15, 12) << 1)); 2163 vm = (IntRegIndex)(bits(machInst, 5) | 2164 (bits(machInst, 3, 0) << 1)); 2165 vn = (IntRegIndex)(bits(machInst, 7) | 2166 (bits(machInst, 19, 16) << 1)); 2167 } else { 2168 vd = (IntRegIndex)((bits(machInst, 22) << 5) | 2169 (bits(machInst, 15, 12) << 1)); 2170 vm = (IntRegIndex)((bits(machInst, 5) << 5) | 2171 (bits(machInst, 3, 0) << 1)); 2172 vn = (IntRegIndex)((bits(machInst, 7) << 5) | 2173 (bits(machInst, 19, 16) << 1)); 2174 } 2175 switch (opc1 & 0xb /* 1011 */) { 2176 case 0x0: 2177 if (bits(machInst, 6) == 0) { 2178 if (single) { 2179 return decodeVfpRegRegRegOp<VmlaS>( 2180 machInst, vd, vn, vm, false); 2181 } else { 2182 return decodeVfpRegRegRegOp<VmlaD>( 2183 machInst, vd, vn, vm, true); 2184 } 2185 } else { 2186 if (single) { 2187 return decodeVfpRegRegRegOp<VmlsS>( 2188 machInst, vd, vn, vm, false); 2189 } else { 2190 return decodeVfpRegRegRegOp<VmlsD>( 2191 machInst, vd, vn, vm, true); 2192 } 2193 } 2194 case 0x1: 2195 if (bits(machInst, 6) == 1) { 2196 if (single) { 2197 return decodeVfpRegRegRegOp<VnmlaS>( 2198 machInst, vd, vn, vm, false); 2199 } else { 2200 return decodeVfpRegRegRegOp<VnmlaD>( 2201 machInst, vd, vn, vm, true); 2202 } 2203 } else { 2204 if (single) { 2205 return decodeVfpRegRegRegOp<VnmlsS>( 2206 machInst, vd, vn, vm, false); 2207 } else { 2208 return decodeVfpRegRegRegOp<VnmlsD>( 2209 machInst, vd, vn, vm, true); 2210 } 2211 } 2212 case 0x2: 2213 if ((opc3 & 0x1) == 0) { 2214 if (single) { 2215 return decodeVfpRegRegRegOp<VmulS>( 2216 machInst, vd, vn, vm, false); 2217 } else { 2218 return decodeVfpRegRegRegOp<VmulD>( 2219 machInst, vd, vn, vm, true); 2220 } 2221 } else { 2222 if (single) { 2223 return decodeVfpRegRegRegOp<VnmulS>( 2224 machInst, vd, vn, vm, false); 2225 } else { 2226 return decodeVfpRegRegRegOp<VnmulD>( 2227 machInst, vd, vn, vm, true); 2228 } 2229 } 2230 case 0x3: 2231 if ((opc3 & 0x1) == 0) { 2232 if (single) { 2233 return decodeVfpRegRegRegOp<VaddS>( 2234 machInst, vd, vn, vm, false); 2235 } else { 2236 return decodeVfpRegRegRegOp<VaddD>( 2237 machInst, vd, vn, vm, true); 2238 } 2239 } else { 2240 if (single) { 2241 return decodeVfpRegRegRegOp<VsubS>( 2242 machInst, vd, vn, vm, false); 2243 } else { 2244 return decodeVfpRegRegRegOp<VsubD>( 2245 machInst, vd, vn, vm, true); 2246 } 2247 } 2248 case 0x8: 2249 if ((opc3 & 0x1) == 0) { 2250 if (single) { 2251 return decodeVfpRegRegRegOp<VdivS>( 2252 machInst, vd, vn, vm, false); 2253 } else { 2254 return decodeVfpRegRegRegOp<VdivD>( 2255 machInst, vd, vn, vm, true); 2256 } 2257 } 2258 break; 2259 case 0x9: 2260 if ((opc3 & 0x1) == 0) { 2261 if (single) { 2262 return decodeVfpRegRegRegOp<VfnmaS>( 2263 machInst, vd, vn, vm, false); 2264 } else { 2265 return decodeVfpRegRegRegOp<VfnmaD>( 2266 machInst, vd, vn, vm, true); 2267 } 2268 } else { 2269 if (single) { 2270 return decodeVfpRegRegRegOp<VfnmsS>( 2271 machInst, vd, vn, vm, false); 2272 } else { 2273 return decodeVfpRegRegRegOp<VfnmsD>( 2274 machInst, vd, vn, vm, true); 2275 } 2276 } 2277 break; 2278 case 0xa: 2279 if ((opc3 & 0x1) == 0) { 2280 if (single) { 2281 return decodeVfpRegRegRegOp<VfmaS>( 2282 machInst, vd, vn, vm, false); 2283 } else { 2284 return decodeVfpRegRegRegOp<VfmaD>( 2285 machInst, vd, vn, vm, true); 2286 } 2287 } else { 2288 if (single) { 2289 return decodeVfpRegRegRegOp<VfmsS>( 2290 machInst, vd, vn, vm, false); 2291 } else { 2292 return decodeVfpRegRegRegOp<VfmsD>( 2293 machInst, vd, vn, vm, true); 2294 } 2295 } 2296 break; 2297 case 0xb: 2298 if ((opc3 & 0x1) == 0) { 2299 const uint32_t baseImm = 2300 bits(machInst, 3, 0) | (bits(machInst, 19, 16) << 4); 2301 if (single) { 2302 uint32_t imm = vfp_modified_imm(baseImm, false); 2303 return decodeVfpRegImmOp<VmovImmS>( 2304 machInst, vd, imm, false); 2305 } else { 2306 uint64_t imm = vfp_modified_imm(baseImm, true); 2307 return decodeVfpRegImmOp<VmovImmD>( 2308 machInst, vd, imm, true); 2309 } 2310 } 2311 switch (opc2) { 2312 case 0x0: 2313 if (opc3 == 1) { 2314 if (single) { 2315 return decodeVfpRegRegOp<VmovRegS>( 2316 machInst, vd, vm, false); 2317 } else { 2318 return decodeVfpRegRegOp<VmovRegD>( 2319 machInst, vd, vm, true); 2320 } 2321 } else { 2322 if (single) { 2323 return decodeVfpRegRegOp<VabsS>( 2324 machInst, vd, vm, false); 2325 } else { 2326 return decodeVfpRegRegOp<VabsD>( 2327 machInst, vd, vm, true); 2328 } 2329 } 2330 case 0x1: 2331 if (opc3 == 1) { 2332 if (single) { 2333 return decodeVfpRegRegOp<VnegS>( 2334 machInst, vd, vm, false); 2335 } else { 2336 return decodeVfpRegRegOp<VnegD>( 2337 machInst, vd, vm, true); 2338 } 2339 } else { 2340 if (single) { 2341 return decodeVfpRegRegOp<VsqrtS>( 2342 machInst, vd, vm, false); 2343 } else { 2344 return decodeVfpRegRegOp<VsqrtD>( 2345 machInst, vd, vm, true); 2346 } 2347 } 2348 case 0x2: 2349 case 0x3: 2350 { 2351 const bool toHalf = bits(machInst, 16); 2352 const bool top = bits(machInst, 7); 2353 if (top) { 2354 if (toHalf) { 2355 return new VcvtFpSFpHT(machInst, vd, vm); 2356 } else { 2357 return new VcvtFpHTFpS(machInst, vd, vm); 2358 } 2359 } else { 2360 if (toHalf) { 2361 return new VcvtFpSFpHB(machInst, vd, vm); 2362 } else { 2363 return new VcvtFpHBFpS(machInst, vd, vm); 2364 } 2365 } 2366 } 2367 case 0x4: 2368 if (single) { 2369 if (e) { 2370 return new VcmpeS(machInst, vd, vm); 2371 } else { 2372 return new VcmpS(machInst, vd, vm); 2373 } 2374 } else { 2375 if (e) { 2376 return new VcmpeD(machInst, vd, vm); 2377 } else { 2378 return new VcmpD(machInst, vd, vm); 2379 } 2380 } 2381 case 0x5: 2382 if (single) { 2383 if (e) { 2384 return new VcmpeZeroS(machInst, vd, 0); 2385 } else { 2386 return new VcmpZeroS(machInst, vd, 0); 2387 } 2388 } else { 2389 if (e) { 2390 return new VcmpeZeroD(machInst, vd, 0); 2391 } else { 2392 return new VcmpZeroD(machInst, vd, 0); 2393 } 2394 } 2395 case 0x7: 2396 if (opc3 == 0x3) { 2397 if (single) { 2398 vd = (IntRegIndex)((bits(machInst, 22) << 5) | 2399 (bits(machInst, 15, 12) << 1)); 2400 return new VcvtFpSFpD(machInst, vd, vm); 2401 } else { 2402 vd = (IntRegIndex)(bits(machInst, 22) | 2403 (bits(machInst, 15, 12) << 1)); 2404 return new VcvtFpDFpS(machInst, vd, vm); 2405 } 2406 } 2407 break; 2408 case 0x8: 2409 if (bits(machInst, 7) == 0) { 2410 if (single) { 2411 return new VcvtUIntFpS(machInst, vd, vm); 2412 } else { 2413 vm = (IntRegIndex)(bits(machInst, 5) | 2414 (bits(machInst, 3, 0) << 1)); 2415 return new VcvtUIntFpD(machInst, vd, vm); 2416 } 2417 } else { 2418 if (single) { 2419 return new VcvtSIntFpS(machInst, vd, vm); 2420 } else { 2421 vm = (IntRegIndex)(bits(machInst, 5) | 2422 (bits(machInst, 3, 0) << 1)); 2423 return new VcvtSIntFpD(machInst, vd, vm); 2424 } 2425 } 2426 case 0xa: 2427 { 2428 const bool half = (bits(machInst, 7) == 0); 2429 const uint32_t imm = bits(machInst, 5) | 2430 (bits(machInst, 3, 0) << 1); 2431 const uint32_t size = 2432 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2433 if (single) { 2434 if (half) { 2435 return new VcvtSHFixedFpS(machInst, vd, vd, size); 2436 } else { 2437 return new VcvtSFixedFpS(machInst, vd, vd, size); 2438 } 2439 } else { 2440 if (half) { 2441 return new VcvtSHFixedFpD(machInst, vd, vd, size); 2442 } else { 2443 return new VcvtSFixedFpD(machInst, vd, vd, size); 2444 } 2445 } 2446 } 2447 case 0xb: 2448 { 2449 const bool half = (bits(machInst, 7) == 0); 2450 const uint32_t imm = bits(machInst, 5) | 2451 (bits(machInst, 3, 0) << 1); 2452 const uint32_t size = 2453 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2454 if (single) { 2455 if (half) { 2456 return new VcvtUHFixedFpS(machInst, vd, vd, size); 2457 } else { 2458 return new VcvtUFixedFpS(machInst, vd, vd, size); 2459 } 2460 } else { 2461 if (half) { 2462 return new VcvtUHFixedFpD(machInst, vd, vd, size); 2463 } else { 2464 return new VcvtUFixedFpD(machInst, vd, vd, size); 2465 } 2466 } 2467 } 2468 case 0xc: 2469 if (bits(machInst, 7) == 0) { 2470 if (single) { 2471 return new VcvtFpUIntSR(machInst, vd, vm); 2472 } else { 2473 vd = (IntRegIndex)(bits(machInst, 22) | 2474 (bits(machInst, 15, 12) << 1)); 2475 return new VcvtFpUIntDR(machInst, vd, vm); 2476 } 2477 } else { 2478 if (single) { 2479 return new VcvtFpUIntS(machInst, vd, vm); 2480 } else { 2481 vd = (IntRegIndex)(bits(machInst, 22) | 2482 (bits(machInst, 15, 12) << 1)); 2483 return new VcvtFpUIntD(machInst, vd, vm); 2484 } 2485 } 2486 case 0xd: 2487 if (bits(machInst, 7) == 0) { 2488 if (single) { 2489 return new VcvtFpSIntSR(machInst, vd, vm); 2490 } else { 2491 vd = (IntRegIndex)(bits(machInst, 22) | 2492 (bits(machInst, 15, 12) << 1)); 2493 return new VcvtFpSIntDR(machInst, vd, vm); 2494 } 2495 } else { 2496 if (single) { 2497 return new VcvtFpSIntS(machInst, vd, vm); 2498 } else { 2499 vd = (IntRegIndex)(bits(machInst, 22) | 2500 (bits(machInst, 15, 12) << 1)); 2501 return new VcvtFpSIntD(machInst, vd, vm); 2502 } 2503 } 2504 case 0xe: 2505 { 2506 const bool half = (bits(machInst, 7) == 0); 2507 const uint32_t imm = bits(machInst, 5) | 2508 (bits(machInst, 3, 0) << 1); 2509 const uint32_t size = 2510 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2511 if (single) { 2512 if (half) { 2513 return new VcvtFpSHFixedS(machInst, vd, vd, size); 2514 } else { 2515 return new VcvtFpSFixedS(machInst, vd, vd, size); 2516 } 2517 } else { 2518 if (half) { 2519 return new VcvtFpSHFixedD(machInst, vd, vd, size); 2520 } else { 2521 return new VcvtFpSFixedD(machInst, vd, vd, size); 2522 } 2523 } 2524 } 2525 case 0xf: 2526 { 2527 const bool half = (bits(machInst, 7) == 0); 2528 const uint32_t imm = bits(machInst, 5) | 2529 (bits(machInst, 3, 0) << 1); 2530 const uint32_t size = 2531 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2532 if (single) { 2533 if (half) { 2534 return new VcvtFpUHFixedS(machInst, vd, vd, size); 2535 } else { 2536 return new VcvtFpUFixedS(machInst, vd, vd, size); 2537 } 2538 } else { 2539 if (half) { 2540 return new VcvtFpUHFixedD(machInst, vd, vd, size); 2541 } else { 2542 return new VcvtFpUFixedD(machInst, vd, vd, size); 2543 } 2544 } 2545 } 2546 } 2547 break; 2548 } 2549 return new Unknown(machInst); 2550 } 2551 ''' 2552}}; 2553 2554def format VfpData() {{ 2555 decode_block = ''' 2556 return decodeVfpData(machInst); 2557 ''' 2558}};
| 2048 } 2049 if (l == 0 && c == 0) { 2050 if (a == 0) { 2051 const uint32_t vn = (bits(machInst, 19, 16) << 1) | 2052 bits(machInst, 7); 2053 const IntRegIndex rt = 2054 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2055 if (bits(machInst, 20) == 1) { 2056 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn); 2057 } else { 2058 return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt); 2059 } 2060 } else if (a == 0x7) { 2061 const IntRegIndex rt = 2062 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2063 uint32_t reg = bits(machInst, 19, 16); 2064 uint32_t specReg; 2065 switch (reg) { 2066 case 0: 2067 specReg = MISCREG_FPSID; 2068 break; 2069 case 1: 2070 specReg = MISCREG_FPSCR; 2071 break; 2072 case 6: 2073 specReg = MISCREG_MVFR1; 2074 break; 2075 case 7: 2076 specReg = MISCREG_MVFR0; 2077 break; 2078 case 8: 2079 specReg = MISCREG_FPEXC; 2080 break; 2081 default: 2082 return new Unknown(machInst); 2083 } 2084 if (specReg == MISCREG_FPSCR) { 2085 return new VmsrFpscr(machInst, (IntRegIndex)specReg, rt); 2086 } else { 2087 uint32_t iss = mcrMrcIssBuild(0, bits(machInst, 3, 0), rt, 2088 reg, a, bits(machInst, 7, 5)); 2089 return new Vmsr(machInst, (IntRegIndex)specReg, rt, iss); 2090 } 2091 } 2092 } else if (l == 0 && c == 1) { 2093 if (bits(a, 2) == 0) { 2094 uint32_t vd = (bits(machInst, 7) << 5) | 2095 (bits(machInst, 19, 16) << 1); 2096 // Handle accessing each single precision half of the vector. 2097 vd += bits(machInst, 21); 2098 const IntRegIndex rt = 2099 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2100 if (bits(machInst, 22) == 1) { 2101 return new VmovCoreRegB(machInst, (IntRegIndex)vd, 2102 rt, bits(machInst, 6, 5)); 2103 } else if (bits(machInst, 5) == 1) { 2104 return new VmovCoreRegH(machInst, (IntRegIndex)vd, 2105 rt, bits(machInst, 6)); 2106 } else if (bits(machInst, 6) == 0) { 2107 return new VmovCoreRegW(machInst, (IntRegIndex)vd, rt); 2108 } else { 2109 return new Unknown(machInst); 2110 } 2111 } else if (bits(b, 1) == 0) { 2112 bool q = bits(machInst, 21); 2113 unsigned be = (bits(machInst, 22) << 1) | (bits(machInst, 5)); 2114 IntRegIndex vd = (IntRegIndex)(2 * (uint32_t) 2115 (bits(machInst, 19, 16) | (bits(machInst, 7) << 4))); 2116 IntRegIndex rt = (IntRegIndex)(uint32_t) 2117 bits(machInst, 15, 12); 2118 if (q) { 2119 switch (be) { 2120 case 0: 2121 return new NVdupQGpr<uint32_t>(machInst, vd, rt); 2122 case 1: 2123 return new NVdupQGpr<uint16_t>(machInst, vd, rt); 2124 case 2: 2125 return new NVdupQGpr<uint8_t>(machInst, vd, rt); 2126 case 3: 2127 return new Unknown(machInst); 2128 } 2129 } else { 2130 switch (be) { 2131 case 0: 2132 return new NVdupDGpr<uint32_t>(machInst, vd, rt); 2133 case 1: 2134 return new NVdupDGpr<uint16_t>(machInst, vd, rt); 2135 case 2: 2136 return new NVdupDGpr<uint8_t>(machInst, vd, rt); 2137 case 3: 2138 return new Unknown(machInst); 2139 } 2140 } 2141 } 2142 } else if (l == 1 && c == 0) { 2143 if (a == 0) { 2144 const uint32_t vn = (bits(machInst, 19, 16) << 1) | 2145 bits(machInst, 7); 2146 const IntRegIndex rt = 2147 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2148 if (bits(machInst, 20) == 1) { 2149 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn); 2150 } else { 2151 return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt); 2152 } 2153 } else if (a == 7) { 2154 const IntRegIndex rt = 2155 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2156 uint32_t reg = bits(machInst, 19, 16); 2157 uint32_t specReg; 2158 switch (reg) { 2159 case 0: 2160 specReg = MISCREG_FPSID; 2161 break; 2162 case 1: 2163 specReg = MISCREG_FPSCR; 2164 break; 2165 case 6: 2166 specReg = MISCREG_MVFR1; 2167 break; 2168 case 7: 2169 specReg = MISCREG_MVFR0; 2170 break; 2171 case 8: 2172 specReg = MISCREG_FPEXC; 2173 break; 2174 default: 2175 return new Unknown(machInst); 2176 } 2177 if (rt == 0xf) { 2178 if (specReg == MISCREG_FPSCR) { 2179 return new VmrsApsrFpscr(machInst); 2180 } else { 2181 return new Unknown(machInst); 2182 } 2183 } else if (specReg == MISCREG_FPSCR) { 2184 return new VmrsFpscr(machInst, rt, (IntRegIndex)specReg); 2185 } else { 2186 uint32_t iss = mcrMrcIssBuild(l, bits(machInst, 3, 0), rt, 2187 reg, a, bits(machInst, 7, 5)); 2188 return new Vmrs(machInst, rt, (IntRegIndex)specReg, iss); 2189 } 2190 } 2191 } else { 2192 uint32_t vd = (bits(machInst, 7) << 5) | 2193 (bits(machInst, 19, 16) << 1); 2194 // Handle indexing into each single precision half of the vector. 2195 vd += bits(machInst, 21); 2196 uint32_t index; 2197 const IntRegIndex rt = 2198 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2199 const bool u = (bits(machInst, 23) == 1); 2200 if (bits(machInst, 22) == 1) { 2201 index = bits(machInst, 6, 5); 2202 if (u) { 2203 return new VmovRegCoreUB(machInst, rt, 2204 (IntRegIndex)vd, index); 2205 } else { 2206 return new VmovRegCoreSB(machInst, rt, 2207 (IntRegIndex)vd, index); 2208 } 2209 } else if (bits(machInst, 5) == 1) { 2210 index = bits(machInst, 6); 2211 if (u) { 2212 return new VmovRegCoreUH(machInst, rt, 2213 (IntRegIndex)vd, index); 2214 } else { 2215 return new VmovRegCoreSH(machInst, rt, 2216 (IntRegIndex)vd, index); 2217 } 2218 } else if (bits(machInst, 6) == 0 && !u) { 2219 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vd); 2220 } else { 2221 return new Unknown(machInst); 2222 } 2223 } 2224 return new Unknown(machInst); 2225 } 2226 ''' 2227}}; 2228 2229def format ShortFpTransfer() {{ 2230 decode_block = ''' 2231 return decodeShortFpTransfer(machInst); 2232 ''' 2233}}; 2234 2235let {{ 2236 header_output = ''' 2237 StaticInstPtr 2238 decodeVfpData(ExtMachInst machInst); 2239 ''' 2240 decoder_output = ''' 2241 StaticInstPtr 2242 decodeVfpData(ExtMachInst machInst) 2243 { 2244 const uint32_t opc1 = bits(machInst, 23, 20); 2245 const uint32_t opc2 = bits(machInst, 19, 16); 2246 const uint32_t opc3 = bits(machInst, 7, 6); 2247 //const uint32_t opc4 = bits(machInst, 3, 0); 2248 const bool single = (bits(machInst, 8) == 0); 2249 // Used to select between vcmp and vcmpe. 2250 const bool e = (bits(machInst, 7) == 1); 2251 IntRegIndex vd; 2252 IntRegIndex vm; 2253 IntRegIndex vn; 2254 if (single) { 2255 vd = (IntRegIndex)(bits(machInst, 22) | 2256 (bits(machInst, 15, 12) << 1)); 2257 vm = (IntRegIndex)(bits(machInst, 5) | 2258 (bits(machInst, 3, 0) << 1)); 2259 vn = (IntRegIndex)(bits(machInst, 7) | 2260 (bits(machInst, 19, 16) << 1)); 2261 } else { 2262 vd = (IntRegIndex)((bits(machInst, 22) << 5) | 2263 (bits(machInst, 15, 12) << 1)); 2264 vm = (IntRegIndex)((bits(machInst, 5) << 5) | 2265 (bits(machInst, 3, 0) << 1)); 2266 vn = (IntRegIndex)((bits(machInst, 7) << 5) | 2267 (bits(machInst, 19, 16) << 1)); 2268 } 2269 switch (opc1 & 0xb /* 1011 */) { 2270 case 0x0: 2271 if (bits(machInst, 6) == 0) { 2272 if (single) { 2273 return decodeVfpRegRegRegOp<VmlaS>( 2274 machInst, vd, vn, vm, false); 2275 } else { 2276 return decodeVfpRegRegRegOp<VmlaD>( 2277 machInst, vd, vn, vm, true); 2278 } 2279 } else { 2280 if (single) { 2281 return decodeVfpRegRegRegOp<VmlsS>( 2282 machInst, vd, vn, vm, false); 2283 } else { 2284 return decodeVfpRegRegRegOp<VmlsD>( 2285 machInst, vd, vn, vm, true); 2286 } 2287 } 2288 case 0x1: 2289 if (bits(machInst, 6) == 1) { 2290 if (single) { 2291 return decodeVfpRegRegRegOp<VnmlaS>( 2292 machInst, vd, vn, vm, false); 2293 } else { 2294 return decodeVfpRegRegRegOp<VnmlaD>( 2295 machInst, vd, vn, vm, true); 2296 } 2297 } else { 2298 if (single) { 2299 return decodeVfpRegRegRegOp<VnmlsS>( 2300 machInst, vd, vn, vm, false); 2301 } else { 2302 return decodeVfpRegRegRegOp<VnmlsD>( 2303 machInst, vd, vn, vm, true); 2304 } 2305 } 2306 case 0x2: 2307 if ((opc3 & 0x1) == 0) { 2308 if (single) { 2309 return decodeVfpRegRegRegOp<VmulS>( 2310 machInst, vd, vn, vm, false); 2311 } else { 2312 return decodeVfpRegRegRegOp<VmulD>( 2313 machInst, vd, vn, vm, true); 2314 } 2315 } else { 2316 if (single) { 2317 return decodeVfpRegRegRegOp<VnmulS>( 2318 machInst, vd, vn, vm, false); 2319 } else { 2320 return decodeVfpRegRegRegOp<VnmulD>( 2321 machInst, vd, vn, vm, true); 2322 } 2323 } 2324 case 0x3: 2325 if ((opc3 & 0x1) == 0) { 2326 if (single) { 2327 return decodeVfpRegRegRegOp<VaddS>( 2328 machInst, vd, vn, vm, false); 2329 } else { 2330 return decodeVfpRegRegRegOp<VaddD>( 2331 machInst, vd, vn, vm, true); 2332 } 2333 } else { 2334 if (single) { 2335 return decodeVfpRegRegRegOp<VsubS>( 2336 machInst, vd, vn, vm, false); 2337 } else { 2338 return decodeVfpRegRegRegOp<VsubD>( 2339 machInst, vd, vn, vm, true); 2340 } 2341 } 2342 case 0x8: 2343 if ((opc3 & 0x1) == 0) { 2344 if (single) { 2345 return decodeVfpRegRegRegOp<VdivS>( 2346 machInst, vd, vn, vm, false); 2347 } else { 2348 return decodeVfpRegRegRegOp<VdivD>( 2349 machInst, vd, vn, vm, true); 2350 } 2351 } 2352 break; 2353 case 0x9: 2354 if ((opc3 & 0x1) == 0) { 2355 if (single) { 2356 return decodeVfpRegRegRegOp<VfnmaS>( 2357 machInst, vd, vn, vm, false); 2358 } else { 2359 return decodeVfpRegRegRegOp<VfnmaD>( 2360 machInst, vd, vn, vm, true); 2361 } 2362 } else { 2363 if (single) { 2364 return decodeVfpRegRegRegOp<VfnmsS>( 2365 machInst, vd, vn, vm, false); 2366 } else { 2367 return decodeVfpRegRegRegOp<VfnmsD>( 2368 machInst, vd, vn, vm, true); 2369 } 2370 } 2371 break; 2372 case 0xa: 2373 if ((opc3 & 0x1) == 0) { 2374 if (single) { 2375 return decodeVfpRegRegRegOp<VfmaS>( 2376 machInst, vd, vn, vm, false); 2377 } else { 2378 return decodeVfpRegRegRegOp<VfmaD>( 2379 machInst, vd, vn, vm, true); 2380 } 2381 } else { 2382 if (single) { 2383 return decodeVfpRegRegRegOp<VfmsS>( 2384 machInst, vd, vn, vm, false); 2385 } else { 2386 return decodeVfpRegRegRegOp<VfmsD>( 2387 machInst, vd, vn, vm, true); 2388 } 2389 } 2390 break; 2391 case 0xb: 2392 if ((opc3 & 0x1) == 0) { 2393 const uint32_t baseImm = 2394 bits(machInst, 3, 0) | (bits(machInst, 19, 16) << 4); 2395 if (single) { 2396 uint32_t imm = vfp_modified_imm(baseImm, false); 2397 return decodeVfpRegImmOp<VmovImmS>( 2398 machInst, vd, imm, false); 2399 } else { 2400 uint64_t imm = vfp_modified_imm(baseImm, true); 2401 return decodeVfpRegImmOp<VmovImmD>( 2402 machInst, vd, imm, true); 2403 } 2404 } 2405 switch (opc2) { 2406 case 0x0: 2407 if (opc3 == 1) { 2408 if (single) { 2409 return decodeVfpRegRegOp<VmovRegS>( 2410 machInst, vd, vm, false); 2411 } else { 2412 return decodeVfpRegRegOp<VmovRegD>( 2413 machInst, vd, vm, true); 2414 } 2415 } else { 2416 if (single) { 2417 return decodeVfpRegRegOp<VabsS>( 2418 machInst, vd, vm, false); 2419 } else { 2420 return decodeVfpRegRegOp<VabsD>( 2421 machInst, vd, vm, true); 2422 } 2423 } 2424 case 0x1: 2425 if (opc3 == 1) { 2426 if (single) { 2427 return decodeVfpRegRegOp<VnegS>( 2428 machInst, vd, vm, false); 2429 } else { 2430 return decodeVfpRegRegOp<VnegD>( 2431 machInst, vd, vm, true); 2432 } 2433 } else { 2434 if (single) { 2435 return decodeVfpRegRegOp<VsqrtS>( 2436 machInst, vd, vm, false); 2437 } else { 2438 return decodeVfpRegRegOp<VsqrtD>( 2439 machInst, vd, vm, true); 2440 } 2441 } 2442 case 0x2: 2443 case 0x3: 2444 { 2445 const bool toHalf = bits(machInst, 16); 2446 const bool top = bits(machInst, 7); 2447 if (top) { 2448 if (toHalf) { 2449 return new VcvtFpSFpHT(machInst, vd, vm); 2450 } else { 2451 return new VcvtFpHTFpS(machInst, vd, vm); 2452 } 2453 } else { 2454 if (toHalf) { 2455 return new VcvtFpSFpHB(machInst, vd, vm); 2456 } else { 2457 return new VcvtFpHBFpS(machInst, vd, vm); 2458 } 2459 } 2460 } 2461 case 0x4: 2462 if (single) { 2463 if (e) { 2464 return new VcmpeS(machInst, vd, vm); 2465 } else { 2466 return new VcmpS(machInst, vd, vm); 2467 } 2468 } else { 2469 if (e) { 2470 return new VcmpeD(machInst, vd, vm); 2471 } else { 2472 return new VcmpD(machInst, vd, vm); 2473 } 2474 } 2475 case 0x5: 2476 if (single) { 2477 if (e) { 2478 return new VcmpeZeroS(machInst, vd, 0); 2479 } else { 2480 return new VcmpZeroS(machInst, vd, 0); 2481 } 2482 } else { 2483 if (e) { 2484 return new VcmpeZeroD(machInst, vd, 0); 2485 } else { 2486 return new VcmpZeroD(machInst, vd, 0); 2487 } 2488 } 2489 case 0x7: 2490 if (opc3 == 0x3) { 2491 if (single) { 2492 vd = (IntRegIndex)((bits(machInst, 22) << 5) | 2493 (bits(machInst, 15, 12) << 1)); 2494 return new VcvtFpSFpD(machInst, vd, vm); 2495 } else { 2496 vd = (IntRegIndex)(bits(machInst, 22) | 2497 (bits(machInst, 15, 12) << 1)); 2498 return new VcvtFpDFpS(machInst, vd, vm); 2499 } 2500 } 2501 break; 2502 case 0x8: 2503 if (bits(machInst, 7) == 0) { 2504 if (single) { 2505 return new VcvtUIntFpS(machInst, vd, vm); 2506 } else { 2507 vm = (IntRegIndex)(bits(machInst, 5) | 2508 (bits(machInst, 3, 0) << 1)); 2509 return new VcvtUIntFpD(machInst, vd, vm); 2510 } 2511 } else { 2512 if (single) { 2513 return new VcvtSIntFpS(machInst, vd, vm); 2514 } else { 2515 vm = (IntRegIndex)(bits(machInst, 5) | 2516 (bits(machInst, 3, 0) << 1)); 2517 return new VcvtSIntFpD(machInst, vd, vm); 2518 } 2519 } 2520 case 0xa: 2521 { 2522 const bool half = (bits(machInst, 7) == 0); 2523 const uint32_t imm = bits(machInst, 5) | 2524 (bits(machInst, 3, 0) << 1); 2525 const uint32_t size = 2526 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2527 if (single) { 2528 if (half) { 2529 return new VcvtSHFixedFpS(machInst, vd, vd, size); 2530 } else { 2531 return new VcvtSFixedFpS(machInst, vd, vd, size); 2532 } 2533 } else { 2534 if (half) { 2535 return new VcvtSHFixedFpD(machInst, vd, vd, size); 2536 } else { 2537 return new VcvtSFixedFpD(machInst, vd, vd, size); 2538 } 2539 } 2540 } 2541 case 0xb: 2542 { 2543 const bool half = (bits(machInst, 7) == 0); 2544 const uint32_t imm = bits(machInst, 5) | 2545 (bits(machInst, 3, 0) << 1); 2546 const uint32_t size = 2547 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2548 if (single) { 2549 if (half) { 2550 return new VcvtUHFixedFpS(machInst, vd, vd, size); 2551 } else { 2552 return new VcvtUFixedFpS(machInst, vd, vd, size); 2553 } 2554 } else { 2555 if (half) { 2556 return new VcvtUHFixedFpD(machInst, vd, vd, size); 2557 } else { 2558 return new VcvtUFixedFpD(machInst, vd, vd, size); 2559 } 2560 } 2561 } 2562 case 0xc: 2563 if (bits(machInst, 7) == 0) { 2564 if (single) { 2565 return new VcvtFpUIntSR(machInst, vd, vm); 2566 } else { 2567 vd = (IntRegIndex)(bits(machInst, 22) | 2568 (bits(machInst, 15, 12) << 1)); 2569 return new VcvtFpUIntDR(machInst, vd, vm); 2570 } 2571 } else { 2572 if (single) { 2573 return new VcvtFpUIntS(machInst, vd, vm); 2574 } else { 2575 vd = (IntRegIndex)(bits(machInst, 22) | 2576 (bits(machInst, 15, 12) << 1)); 2577 return new VcvtFpUIntD(machInst, vd, vm); 2578 } 2579 } 2580 case 0xd: 2581 if (bits(machInst, 7) == 0) { 2582 if (single) { 2583 return new VcvtFpSIntSR(machInst, vd, vm); 2584 } else { 2585 vd = (IntRegIndex)(bits(machInst, 22) | 2586 (bits(machInst, 15, 12) << 1)); 2587 return new VcvtFpSIntDR(machInst, vd, vm); 2588 } 2589 } else { 2590 if (single) { 2591 return new VcvtFpSIntS(machInst, vd, vm); 2592 } else { 2593 vd = (IntRegIndex)(bits(machInst, 22) | 2594 (bits(machInst, 15, 12) << 1)); 2595 return new VcvtFpSIntD(machInst, vd, vm); 2596 } 2597 } 2598 case 0xe: 2599 { 2600 const bool half = (bits(machInst, 7) == 0); 2601 const uint32_t imm = bits(machInst, 5) | 2602 (bits(machInst, 3, 0) << 1); 2603 const uint32_t size = 2604 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2605 if (single) { 2606 if (half) { 2607 return new VcvtFpSHFixedS(machInst, vd, vd, size); 2608 } else { 2609 return new VcvtFpSFixedS(machInst, vd, vd, size); 2610 } 2611 } else { 2612 if (half) { 2613 return new VcvtFpSHFixedD(machInst, vd, vd, size); 2614 } else { 2615 return new VcvtFpSFixedD(machInst, vd, vd, size); 2616 } 2617 } 2618 } 2619 case 0xf: 2620 { 2621 const bool half = (bits(machInst, 7) == 0); 2622 const uint32_t imm = bits(machInst, 5) | 2623 (bits(machInst, 3, 0) << 1); 2624 const uint32_t size = 2625 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2626 if (single) { 2627 if (half) { 2628 return new VcvtFpUHFixedS(machInst, vd, vd, size); 2629 } else { 2630 return new VcvtFpUFixedS(machInst, vd, vd, size); 2631 } 2632 } else { 2633 if (half) { 2634 return new VcvtFpUHFixedD(machInst, vd, vd, size); 2635 } else { 2636 return new VcvtFpUFixedD(machInst, vd, vd, size); 2637 } 2638 } 2639 } 2640 } 2641 break; 2642 } 2643 return new Unknown(machInst); 2644 } 2645 ''' 2646}}; 2647 2648def format VfpData() {{ 2649 decode_block = ''' 2650 return decodeVfpData(machInst); 2651 ''' 2652}};
|