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