fp.isa revision 8301
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 (b) { 565 return decodeNeonUSThreeReg<VpminD, VpminQ>( 566 q, u, size, machInst, vd, vn, vm); 567 } else { 568 return decodeNeonUSThreeReg<VpmaxD, VpmaxQ>( 569 q, u, size, machInst, vd, vn, vm); 570 } 571 case 0xb: 572 if (b) { 573 if (u) { 574 return new Unknown(machInst); 575 } else { 576 return decodeNeonUThreeReg<NVpaddD, NVpaddQ>( 577 q, size, machInst, vd, vn, vm); 578 } 579 } else { 580 if (u) { 581 return decodeNeonSThreeSReg<VqrdmulhD, VqrdmulhQ>( 582 q, size, machInst, vd, vn, vm); 583 } else { 584 return decodeNeonSThreeSReg<VqdmulhD, VqdmulhQ>( 585 q, size, machInst, vd, vn, vm); 586 } 587 } 588 case 0xc: 589 return new Unknown(machInst); 590 case 0xd: 591 if (b) { 592 if (u) { 593 if (bits(c, 1) == 0) { 594 if (q) { 595 return new NVmulQFp<float>(machInst, vd, vn, vm); 596 } else { 597 return new NVmulDFp<float>(machInst, vd, vn, vm); 598 } 599 } else { 600 return new Unknown(machInst); 601 } 602 } else { 603 if (bits(c, 1) == 0) { 604 if (q) { 605 return new NVmlaQFp<float>(machInst, vd, vn, vm); 606 } else { 607 return new NVmlaDFp<float>(machInst, vd, vn, vm); 608 } 609 } else { 610 if (q) { 611 return new NVmlsQFp<float>(machInst, vd, vn, vm); 612 } else { 613 return new NVmlsDFp<float>(machInst, vd, vn, vm); 614 } 615 } 616 } 617 } else { 618 if (u) { 619 if (bits(c, 1) == 0) { 620 if (q) { 621 return new VpaddQFp<float>(machInst, vd, vn, vm); 622 } else { 623 return new VpaddDFp<float>(machInst, vd, vn, vm); 624 } 625 } else { 626 if (q) { 627 return new VabdQFp<float>(machInst, vd, vn, vm); 628 } else { 629 return new VabdDFp<float>(machInst, vd, vn, vm); 630 } 631 } 632 } else { 633 if (bits(c, 1) == 0) { 634 if (q) { 635 return new VaddQFp<float>(machInst, vd, vn, vm); 636 } else { 637 return new VaddDFp<float>(machInst, vd, vn, vm); 638 } 639 } else { 640 if (q) { 641 return new VsubQFp<float>(machInst, vd, vn, vm); 642 } else { 643 return new VsubDFp<float>(machInst, vd, vn, vm); 644 } 645 } 646 } 647 } 648 case 0xe: 649 if (b) { 650 if (u) { 651 if (bits(c, 1) == 0) { 652 if (q) { 653 return new VacgeQFp<float>(machInst, vd, vn, vm); 654 } else { 655 return new VacgeDFp<float>(machInst, vd, vn, vm); 656 } 657 } else { 658 if (q) { 659 return new VacgtQFp<float>(machInst, vd, vn, vm); 660 } else { 661 return new VacgtDFp<float>(machInst, vd, vn, vm); 662 } 663 } 664 } else { 665 return new Unknown(machInst); 666 } 667 } else { 668 if (u) { 669 if (bits(c, 1) == 0) { 670 if (q) { 671 return new VcgeQFp<float>(machInst, vd, vn, vm); 672 } else { 673 return new VcgeDFp<float>(machInst, vd, vn, vm); 674 } 675 } else { 676 if (q) { 677 return new VcgtQFp<float>(machInst, vd, vn, vm); 678 } else { 679 return new VcgtDFp<float>(machInst, vd, vn, vm); 680 } 681 } 682 } else { 683 if (bits(c, 1) == 0) { 684 if (q) { 685 return new VceqQFp<float>(machInst, vd, vn, vm); 686 } else { 687 return new VceqDFp<float>(machInst, vd, vn, vm); 688 } 689 } else { 690 return new Unknown(machInst); 691 } 692 } 693 } 694 case 0xf: 695 if (b) { 696 if (u) { 697 return new Unknown(machInst); 698 } else { 699 if (bits(c, 1) == 0) { 700 if (q) { 701 return new VrecpsQFp<float>(machInst, vd, vn, vm); 702 } else { 703 return new VrecpsDFp<float>(machInst, vd, vn, vm); 704 } 705 } else { 706 if (q) { 707 return new VrsqrtsQFp<float>(machInst, vd, vn, vm); 708 } else { 709 return new VrsqrtsDFp<float>(machInst, vd, vn, vm); 710 } 711 } 712 } 713 } else { 714 if (u) { 715 if (bits(c, 1) == 0) { 716 if (q) { 717 return new VpmaxQFp<float>(machInst, vd, vn, vm); 718 } else { 719 return new VpmaxDFp<float>(machInst, vd, vn, vm); 720 } 721 } else { 722 if (q) { 723 return new VpminQFp<float>(machInst, vd, vn, vm); 724 } else { 725 return new VpminDFp<float>(machInst, vd, vn, vm); 726 } 727 } 728 } else { 729 if (bits(c, 1) == 0) { 730 if (q) { 731 return new VmaxQFp<float>(machInst, vd, vn, vm); 732 } else { 733 return new VmaxDFp<float>(machInst, vd, vn, vm); 734 } 735 } else { 736 if (q) { 737 return new VminQFp<float>(machInst, vd, vn, vm); 738 } else { 739 return new VminDFp<float>(machInst, vd, vn, vm); 740 } 741 } 742 } 743 } 744 } 745 return new Unknown(machInst); 746 } 747 748 static StaticInstPtr 749 decodeNeonOneRegModImm(ExtMachInst machInst) 750 { 751 const IntRegIndex vd = 752 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 753 (bits(machInst, 22) << 4))); 754 const bool q = bits(machInst, 6); 755 const bool op = bits(machInst, 5); 756 const uint8_t cmode = bits(machInst, 11, 8); 757 const uint8_t imm = ((THUMB ? bits(machInst, 28) : 758 bits(machInst, 24)) << 7) | 759 (bits(machInst, 18, 16) << 4) | 760 (bits(machInst, 3, 0) << 0); 761 762 // Check for invalid immediate encodings and return an unknown op 763 // if it happens 764 bool immValid = true; 765 const uint64_t bigImm = simd_modified_imm(op, cmode, imm, immValid); 766 if (!immValid) { 767 return new Unknown(machInst); 768 } 769 770 if (op) { 771 if (bits(cmode, 3) == 0) { 772 if (bits(cmode, 0) == 0) { 773 if (q) 774 return new NVmvniQ<uint64_t>(machInst, vd, bigImm); 775 else 776 return new NVmvniD<uint64_t>(machInst, vd, bigImm); 777 } else { 778 if (q) 779 return new NVbiciQ<uint64_t>(machInst, vd, bigImm); 780 else 781 return new NVbiciD<uint64_t>(machInst, vd, bigImm); 782 } 783 } else { 784 if (bits(cmode, 2) == 1) { 785 switch (bits(cmode, 1, 0)) { 786 case 0: 787 case 1: 788 if (q) 789 return new NVmvniQ<uint64_t>(machInst, vd, bigImm); 790 else 791 return new NVmvniD<uint64_t>(machInst, vd, bigImm); 792 case 2: 793 if (q) 794 return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 795 else 796 return new NVmoviD<uint64_t>(machInst, vd, bigImm); 797 case 3: 798 if (q) 799 return new Unknown(machInst); 800 else 801 return new Unknown(machInst); 802 } 803 } else { 804 if (bits(cmode, 0) == 0) { 805 if (q) 806 return new NVmvniQ<uint64_t>(machInst, vd, bigImm); 807 else 808 return new NVmvniD<uint64_t>(machInst, vd, bigImm); 809 } else { 810 if (q) 811 return new NVbiciQ<uint64_t>(machInst, vd, bigImm); 812 else 813 return new NVbiciD<uint64_t>(machInst, vd, bigImm); 814 } 815 } 816 } 817 } else { 818 if (bits(cmode, 3) == 0) { 819 if (bits(cmode, 0) == 0) { 820 if (q) 821 return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 822 else 823 return new NVmoviD<uint64_t>(machInst, vd, bigImm); 824 } else { 825 if (q) 826 return new NVorriQ<uint64_t>(machInst, vd, bigImm); 827 else 828 return new NVorriD<uint64_t>(machInst, vd, bigImm); 829 } 830 } else { 831 if (bits(cmode, 2) == 1) { 832 if (q) 833 return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 834 else 835 return new NVmoviD<uint64_t>(machInst, vd, bigImm); 836 } else { 837 if (bits(cmode, 0) == 0) { 838 if (q) 839 return new NVmoviQ<uint64_t>(machInst, vd, bigImm); 840 else 841 return new NVmoviD<uint64_t>(machInst, vd, bigImm); 842 } else { 843 if (q) 844 return new NVorriQ<uint64_t>(machInst, vd, bigImm); 845 else 846 return new NVorriD<uint64_t>(machInst, vd, bigImm); 847 } 848 } 849 } 850 } 851 return new Unknown(machInst); 852 } 853 854 static StaticInstPtr 855 decodeNeonTwoRegAndShift(ExtMachInst machInst) 856 { 857 const uint32_t a = bits(machInst, 11, 8); 858 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 859 const bool b = bits(machInst, 6); 860 const bool l = bits(machInst, 7); 861 const IntRegIndex vd = 862 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 863 (bits(machInst, 22) << 4))); 864 const IntRegIndex vm = 865 (IntRegIndex)(2 * (bits(machInst, 3, 0) | 866 (bits(machInst, 5) << 4))); 867 unsigned imm6 = bits(machInst, 21, 16); 868 unsigned imm = ((l ? 1 : 0) << 6) | imm6; 869 unsigned size = 3; 870 unsigned lShiftAmt = 0; 871 unsigned bitSel; 872 for (bitSel = 1 << 6; true; bitSel >>= 1) { 873 if (bitSel & imm) 874 break; 875 else if (!size) 876 return new Unknown(machInst); 877 size--; 878 } 879 lShiftAmt = imm6 & ~bitSel; 880 unsigned rShiftAmt = 0; 881 if (a != 0xe && a != 0xf) { 882 if (size > 2) 883 rShiftAmt = 64 - imm6; 884 else 885 rShiftAmt = 2 * (8 << size) - imm6; 886 } 887 888 switch (a) { 889 case 0x0: 890 return decodeNeonUSTwoShiftReg<NVshrD, NVshrQ>( 891 b, u, size, machInst, vd, vm, rShiftAmt); 892 case 0x1: 893 return decodeNeonUSTwoShiftReg<NVsraD, NVsraQ>( 894 b, u, size, machInst, vd, vm, rShiftAmt); 895 case 0x2: 896 return decodeNeonUSTwoShiftReg<NVrshrD, NVrshrQ>( 897 b, u, size, machInst, vd, vm, rShiftAmt); 898 case 0x3: 899 return decodeNeonUSTwoShiftReg<NVrsraD, NVrsraQ>( 900 b, u, size, machInst, vd, vm, rShiftAmt); 901 case 0x4: 902 if (u) { 903 return decodeNeonUTwoShiftReg<NVsriD, NVsriQ>( 904 b, size, machInst, vd, vm, rShiftAmt); 905 } else { 906 return new Unknown(machInst); 907 } 908 case 0x5: 909 if (u) { 910 return decodeNeonUTwoShiftReg<NVsliD, NVsliQ>( 911 b, size, machInst, vd, vm, lShiftAmt); 912 } else { 913 return decodeNeonUTwoShiftReg<NVshlD, NVshlQ>( 914 b, size, machInst, vd, vm, lShiftAmt); 915 } 916 case 0x6: 917 case 0x7: 918 if (u) { 919 if (a == 0x6) { 920 return decodeNeonSTwoShiftReg<NVqshlusD, NVqshlusQ>( 921 b, size, machInst, vd, vm, lShiftAmt); 922 } else { 923 return decodeNeonUTwoShiftReg<NVqshluD, NVqshluQ>( 924 b, size, machInst, vd, vm, lShiftAmt); 925 } 926 } else { 927 return decodeNeonSTwoShiftReg<NVqshlD, NVqshlQ>( 928 b, size, machInst, vd, vm, lShiftAmt); 929 } 930 case 0x8: 931 if (l) { 932 return new Unknown(machInst); 933 } else if (u) { 934 return decodeNeonSTwoShiftSReg<NVqshruns, NVqrshruns>( 935 b, size, machInst, vd, vm, rShiftAmt); 936 } else { 937 return decodeNeonUTwoShiftSReg<NVshrn, NVrshrn>( 938 b, size, machInst, vd, vm, rShiftAmt); 939 } 940 case 0x9: 941 if (l) { 942 return new Unknown(machInst); 943 } else if (u) { 944 return decodeNeonUTwoShiftSReg<NVqshrun, NVqrshrun>( 945 b, size, machInst, vd, vm, rShiftAmt); 946 } else { 947 return decodeNeonSTwoShiftSReg<NVqshrn, NVqrshrn>( 948 b, size, machInst, vd, vm, rShiftAmt); 949 } 950 case 0xa: 951 if (l || b) { 952 return new Unknown(machInst); 953 } else { 954 return decodeNeonUSTwoShiftSReg<NVmovl, NVshll>( 955 lShiftAmt, u, size, machInst, vd, vm, lShiftAmt); 956 } 957 case 0xe: 958 if (l) { 959 return new Unknown(machInst); 960 } else { 961 if (bits(imm6, 5) == 0) 962 return new Unknown(machInst); 963 if (u) { 964 if (b) { 965 return new NVcvtu2fpQ<float>( 966 machInst, vd, vm, 64 - imm6); 967 } else { 968 return new NVcvtu2fpD<float>( 969 machInst, vd, vm, 64 - imm6); 970 } 971 } else { 972 if (b) { 973 return new NVcvts2fpQ<float>( 974 machInst, vd, vm, 64 - imm6); 975 } else { 976 return new NVcvts2fpD<float>( 977 machInst, vd, vm, 64 - imm6); 978 } 979 } 980 } 981 case 0xf: 982 if (l) { 983 return new Unknown(machInst); 984 } else { 985 if (bits(imm6, 5) == 0) 986 return new Unknown(machInst); 987 if (u) { 988 if (b) { 989 return new NVcvt2ufxQ<float>( 990 machInst, vd, vm, 64 - imm6); 991 } else { 992 return new NVcvt2ufxD<float>( 993 machInst, vd, vm, 64 - imm6); 994 } 995 } else { 996 if (b) { 997 return new NVcvt2sfxQ<float>( 998 machInst, vd, vm, 64 - imm6); 999 } else { 1000 return new NVcvt2sfxD<float>( 1001 machInst, vd, vm, 64 - imm6); 1002 } 1003 } 1004 } 1005 } 1006 return new Unknown(machInst); 1007 } 1008 1009 static StaticInstPtr 1010 decodeNeonThreeRegDiffLengths(ExtMachInst machInst) 1011 { 1012 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 1013 const uint32_t a = bits(machInst, 11, 8); 1014 const IntRegIndex vd = 1015 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 1016 (bits(machInst, 22) << 4))); 1017 const IntRegIndex vn = 1018 (IntRegIndex)(2 * (bits(machInst, 19, 16) | 1019 (bits(machInst, 7) << 4))); 1020 const IntRegIndex vm = 1021 (IntRegIndex)(2 * (bits(machInst, 3, 0) | 1022 (bits(machInst, 5) << 4))); 1023 const unsigned size = bits(machInst, 21, 20); 1024 switch (a) { 1025 case 0x0: 1026 return decodeNeonUSThreeUSReg<Vaddl>( 1027 u, size, machInst, vd, vn, vm); 1028 case 0x1: 1029 return decodeNeonUSThreeUSReg<Vaddw>( 1030 u, size, machInst, vd, vn, vm); 1031 case 0x2: 1032 return decodeNeonUSThreeUSReg<Vsubl>( 1033 u, size, machInst, vd, vn, vm); 1034 case 0x3: 1035 return decodeNeonUSThreeUSReg<Vsubw>( 1036 u, size, machInst, vd, vn, vm); 1037 case 0x4: 1038 if (u) { 1039 return decodeNeonUThreeUSReg<Vraddhn>( 1040 size, machInst, vd, vn, vm); 1041 } else { 1042 return decodeNeonUThreeUSReg<Vaddhn>( 1043 size, machInst, vd, vn, vm); 1044 } 1045 case 0x5: 1046 return decodeNeonUSThreeUSReg<Vabal>( 1047 u, size, machInst, vd, vn, vm); 1048 case 0x6: 1049 if (u) { 1050 return decodeNeonUThreeUSReg<Vrsubhn>( 1051 size, machInst, vd, vn, vm); 1052 } else { 1053 return decodeNeonUThreeUSReg<Vsubhn>( 1054 size, machInst, vd, vn, vm); 1055 } 1056 case 0x7: 1057 if (bits(machInst, 23)) { 1058 return decodeNeonUSThreeUSReg<Vabdl>( 1059 u, size, machInst, vd, vn, vm); 1060 } else { 1061 return decodeNeonUSThreeReg<VabdD, VabdQ>( 1062 bits(machInst, 6), u, size, machInst, vd, vn, vm); 1063 } 1064 case 0x8: 1065 return decodeNeonUSThreeUSReg<Vmlal>( 1066 u, size, machInst, vd, vn, vm); 1067 case 0xa: 1068 return decodeNeonUSThreeUSReg<Vmlsl>( 1069 u, size, machInst, vd, vn, vm); 1070 case 0x9: 1071 if (u) { 1072 return new Unknown(machInst); 1073 } else { 1074 return decodeNeonSThreeUSReg<Vqdmlal>( 1075 size, machInst, vd, vn, vm); 1076 } 1077 case 0xb: 1078 if (u) { 1079 return new Unknown(machInst); 1080 } else { 1081 return decodeNeonSThreeUSReg<Vqdmlsl>( 1082 size, machInst, vd, vn, vm); 1083 } 1084 case 0xc: 1085 return decodeNeonUSThreeUSReg<Vmull>( 1086 u, size, machInst, vd, vn, vm); 1087 case 0xd: 1088 if (u) { 1089 return new Unknown(machInst); 1090 } else { 1091 return decodeNeonSThreeUSReg<Vqdmull>( 1092 size, machInst, vd, vn, vm); 1093 } 1094 case 0xe: 1095 return decodeNeonUThreeUSReg<Vmullp>( 1096 size, machInst, vd, vn, vm); 1097 } 1098 return new Unknown(machInst); 1099 } 1100 1101 static StaticInstPtr 1102 decodeNeonTwoRegScalar(ExtMachInst machInst) 1103 { 1104 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 1105 const uint32_t a = bits(machInst, 11, 8); 1106 const unsigned size = bits(machInst, 21, 20); 1107 const IntRegIndex vd = 1108 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 1109 (bits(machInst, 22) << 4))); 1110 const IntRegIndex vn = 1111 (IntRegIndex)(2 * (bits(machInst, 19, 16) | 1112 (bits(machInst, 7) << 4))); 1113 const IntRegIndex vm = (size == 2) ? 1114 (IntRegIndex)(2 * bits(machInst, 3, 0)) : 1115 (IntRegIndex)(2 * bits(machInst, 2, 0)); 1116 const unsigned index = (size == 2) ? (unsigned)bits(machInst, 5) : 1117 (bits(machInst, 3) | (bits(machInst, 5) << 1)); 1118 switch (a) { 1119 case 0x0: 1120 if (u) { 1121 switch (size) { 1122 case 1: 1123 return new VmlasQ<uint16_t>(machInst, vd, vn, vm, index); 1124 case 2: 1125 return new VmlasQ<uint32_t>(machInst, vd, vn, vm, index); 1126 default: 1127 return new Unknown(machInst); 1128 } 1129 } else { 1130 switch (size) { 1131 case 1: 1132 return new VmlasD<uint16_t>(machInst, vd, vn, vm, index); 1133 case 2: 1134 return new VmlasD<uint32_t>(machInst, vd, vn, vm, index); 1135 default: 1136 return new Unknown(machInst); 1137 } 1138 } 1139 case 0x1: 1140 if (u) 1141 return new VmlasQFp<float>(machInst, vd, vn, vm, index); 1142 else 1143 return new VmlasDFp<float>(machInst, vd, vn, vm, index); 1144 case 0x4: 1145 if (u) { 1146 switch (size) { 1147 case 1: 1148 return new VmlssQ<uint16_t>(machInst, vd, vn, vm, index); 1149 case 2: 1150 return new VmlssQ<uint32_t>(machInst, vd, vn, vm, index); 1151 default: 1152 return new Unknown(machInst); 1153 } 1154 } else { 1155 switch (size) { 1156 case 1: 1157 return new VmlssD<uint16_t>(machInst, vd, vn, vm, index); 1158 case 2: 1159 return new VmlssD<uint32_t>(machInst, vd, vn, vm, index); 1160 default: 1161 return new Unknown(machInst); 1162 } 1163 } 1164 case 0x5: 1165 if (u) 1166 return new VmlssQFp<float>(machInst, vd, vn, vm, index); 1167 else 1168 return new VmlssDFp<float>(machInst, vd, vn, vm, index); 1169 case 0x2: 1170 if (u) { 1171 switch (size) { 1172 case 1: 1173 return new Vmlals<uint16_t>(machInst, vd, vn, vm, index); 1174 case 2: 1175 return new Vmlals<uint32_t>(machInst, vd, vn, vm, index); 1176 default: 1177 return new Unknown(machInst); 1178 } 1179 } else { 1180 switch (size) { 1181 case 1: 1182 return new Vmlals<int16_t>(machInst, vd, vn, vm, index); 1183 case 2: 1184 return new Vmlals<int32_t>(machInst, vd, vn, vm, index); 1185 default: 1186 return new Unknown(machInst); 1187 } 1188 } 1189 case 0x6: 1190 if (u) { 1191 switch (size) { 1192 case 1: 1193 return new Vmlsls<uint16_t>(machInst, vd, vn, vm, index); 1194 case 2: 1195 return new Vmlsls<uint32_t>(machInst, vd, vn, vm, index); 1196 default: 1197 return new Unknown(machInst); 1198 } 1199 } else { 1200 switch (size) { 1201 case 1: 1202 return new Vmlsls<int16_t>(machInst, vd, vn, vm, index); 1203 case 2: 1204 return new Vmlsls<int32_t>(machInst, vd, vn, vm, index); 1205 default: 1206 return new Unknown(machInst); 1207 } 1208 } 1209 case 0x3: 1210 if (u) { 1211 return new Unknown(machInst); 1212 } else { 1213 switch (size) { 1214 case 1: 1215 return new Vqdmlals<int16_t>(machInst, vd, vn, vm, index); 1216 case 2: 1217 return new Vqdmlals<int32_t>(machInst, vd, vn, vm, index); 1218 default: 1219 return new Unknown(machInst); 1220 } 1221 } 1222 case 0x7: 1223 if (u) { 1224 return new Unknown(machInst); 1225 } else { 1226 switch (size) { 1227 case 1: 1228 return new Vqdmlsls<int16_t>(machInst, vd, vn, vm, index); 1229 case 2: 1230 return new Vqdmlsls<int32_t>(machInst, vd, vn, vm, index); 1231 default: 1232 return new Unknown(machInst); 1233 } 1234 } 1235 case 0x8: 1236 if (u) { 1237 switch (size) { 1238 case 1: 1239 return new VmulsQ<uint16_t>(machInst, vd, vn, vm, index); 1240 case 2: 1241 return new VmulsQ<uint32_t>(machInst, vd, vn, vm, index); 1242 default: 1243 return new Unknown(machInst); 1244 } 1245 } else { 1246 switch (size) { 1247 case 1: 1248 return new VmulsD<uint16_t>(machInst, vd, vn, vm, index); 1249 case 2: 1250 return new VmulsD<uint32_t>(machInst, vd, vn, vm, index); 1251 default: 1252 return new Unknown(machInst); 1253 } 1254 } 1255 case 0x9: 1256 if (u) 1257 return new VmulsQFp<float>(machInst, vd, vn, vm, index); 1258 else 1259 return new VmulsDFp<float>(machInst, vd, vn, vm, index); 1260 case 0xa: 1261 if (u) { 1262 switch (size) { 1263 case 1: 1264 return new Vmulls<uint16_t>(machInst, vd, vn, vm, index); 1265 case 2: 1266 return new Vmulls<uint32_t>(machInst, vd, vn, vm, index); 1267 default: 1268 return new Unknown(machInst); 1269 } 1270 } else { 1271 switch (size) { 1272 case 1: 1273 return new Vmulls<int16_t>(machInst, vd, vn, vm, index); 1274 case 2: 1275 return new Vmulls<int32_t>(machInst, vd, vn, vm, index); 1276 default: 1277 return new Unknown(machInst); 1278 } 1279 } 1280 case 0xb: 1281 if (u) { 1282 return new Unknown(machInst); 1283 } else { 1284 if (u) { 1285 switch (size) { 1286 case 1: 1287 return new Vqdmulls<uint16_t>( 1288 machInst, vd, vn, vm, index); 1289 case 2: 1290 return new Vqdmulls<uint32_t>( 1291 machInst, vd, vn, vm, index); 1292 default: 1293 return new Unknown(machInst); 1294 } 1295 } else { 1296 switch (size) { 1297 case 1: 1298 return new Vqdmulls<int16_t>( 1299 machInst, vd, vn, vm, index); 1300 case 2: 1301 return new Vqdmulls<int32_t>( 1302 machInst, vd, vn, vm, index); 1303 default: 1304 return new Unknown(machInst); 1305 } 1306 } 1307 } 1308 case 0xc: 1309 if (u) { 1310 switch (size) { 1311 case 1: 1312 return new VqdmulhsQ<int16_t>( 1313 machInst, vd, vn, vm, index); 1314 case 2: 1315 return new VqdmulhsQ<int32_t>( 1316 machInst, vd, vn, vm, index); 1317 default: 1318 return new Unknown(machInst); 1319 } 1320 } else { 1321 switch (size) { 1322 case 1: 1323 return new VqdmulhsD<int16_t>( 1324 machInst, vd, vn, vm, index); 1325 case 2: 1326 return new VqdmulhsD<int32_t>( 1327 machInst, vd, vn, vm, index); 1328 default: 1329 return new Unknown(machInst); 1330 } 1331 } 1332 case 0xd: 1333 if (u) { 1334 switch (size) { 1335 case 1: 1336 return new VqrdmulhsQ<int16_t>( 1337 machInst, vd, vn, vm, index); 1338 case 2: 1339 return new VqrdmulhsQ<int32_t>( 1340 machInst, vd, vn, vm, index); 1341 default: 1342 return new Unknown(machInst); 1343 } 1344 } else { 1345 switch (size) { 1346 case 1: 1347 return new VqrdmulhsD<int16_t>( 1348 machInst, vd, vn, vm, index); 1349 case 2: 1350 return new VqrdmulhsD<int32_t>( 1351 machInst, vd, vn, vm, index); 1352 default: 1353 return new Unknown(machInst); 1354 } 1355 } 1356 } 1357 return new Unknown(machInst); 1358 } 1359 1360 static StaticInstPtr 1361 decodeNeonTwoRegMisc(ExtMachInst machInst) 1362 { 1363 const uint32_t a = bits(machInst, 17, 16); 1364 const uint32_t b = bits(machInst, 10, 6); 1365 const bool q = bits(machInst, 6); 1366 const IntRegIndex vd = 1367 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 1368 (bits(machInst, 22) << 4))); 1369 const IntRegIndex vm = 1370 (IntRegIndex)(2 * (bits(machInst, 3, 0) | 1371 (bits(machInst, 5) << 4))); 1372 const unsigned size = bits(machInst, 19, 18); 1373 switch (a) { 1374 case 0x0: 1375 switch (bits(b, 4, 1)) { 1376 case 0x0: 1377 switch (size) { 1378 case 0: 1379 if (q) { 1380 return new NVrev64Q<uint8_t>(machInst, vd, vm); 1381 } else { 1382 return new NVrev64D<uint8_t>(machInst, vd, vm); 1383 } 1384 case 1: 1385 if (q) { 1386 return new NVrev64Q<uint16_t>(machInst, vd, vm); 1387 } else { 1388 return new NVrev64D<uint16_t>(machInst, vd, vm); 1389 } 1390 case 2: 1391 if (q) { 1392 return new NVrev64Q<uint32_t>(machInst, vd, vm); 1393 } else { 1394 return new NVrev64D<uint32_t>(machInst, vd, vm); 1395 } 1396 default: 1397 return new Unknown(machInst); 1398 } 1399 case 0x1: 1400 switch (size) { 1401 case 0: 1402 if (q) { 1403 return new NVrev32Q<uint8_t>(machInst, vd, vm); 1404 } else { 1405 return new NVrev32D<uint8_t>(machInst, vd, vm); 1406 } 1407 case 1: 1408 if (q) { 1409 return new NVrev32Q<uint16_t>(machInst, vd, vm); 1410 } else { 1411 return new NVrev32D<uint16_t>(machInst, vd, vm); 1412 } 1413 default: 1414 return new Unknown(machInst); 1415 } 1416 case 0x2: 1417 if (size != 0) { 1418 return new Unknown(machInst); 1419 } else if (q) { 1420 return new NVrev16Q<uint8_t>(machInst, vd, vm); 1421 } else { 1422 return new NVrev16D<uint8_t>(machInst, vd, vm); 1423 } 1424 case 0x4: 1425 return decodeNeonSTwoMiscSReg<NVpaddlD, NVpaddlQ>( 1426 q, size, machInst, vd, vm); 1427 case 0x5: 1428 return decodeNeonUTwoMiscSReg<NVpaddlD, NVpaddlQ>( 1429 q, size, machInst, vd, vm); 1430 case 0x8: 1431 return decodeNeonSTwoMiscReg<NVclsD, NVclsQ>( 1432 q, size, machInst, vd, vm); 1433 case 0x9: 1434 return decodeNeonSTwoMiscReg<NVclzD, NVclzQ>( 1435 q, size, machInst, vd, vm); 1436 case 0xa: 1437 return decodeNeonUTwoMiscReg<NVcntD, NVcntQ>( 1438 q, size, machInst, vd, vm); 1439 case 0xb: 1440 if (q) 1441 return new NVmvnQ<uint64_t>(machInst, vd, vm); 1442 else 1443 return new NVmvnD<uint64_t>(machInst, vd, vm); 1444 case 0xc: 1445 return decodeNeonSTwoMiscSReg<NVpadalD, NVpadalQ>( 1446 q, size, machInst, vd, vm); 1447 case 0xd: 1448 return decodeNeonUTwoMiscSReg<NVpadalD, NVpadalQ>( 1449 q, size, machInst, vd, vm); 1450 case 0xe: 1451 return decodeNeonSTwoMiscReg<NVqabsD, NVqabsQ>( 1452 q, size, machInst, vd, vm); 1453 case 0xf: 1454 return decodeNeonSTwoMiscReg<NVqnegD, NVqnegQ>( 1455 q, size, machInst, vd, vm); 1456 default: 1457 return new Unknown(machInst); 1458 } 1459 case 0x1: 1460 switch (bits(b, 3, 1)) { 1461 case 0x0: 1462 if (bits(b, 4)) { 1463 if (q) { 1464 return new NVcgtQFp<float>(machInst, vd, vm); 1465 } else { 1466 return new NVcgtDFp<float>(machInst, vd, vm); 1467 } 1468 } else { 1469 return decodeNeonSTwoMiscReg<NVcgtD, NVcgtQ>( 1470 q, size, machInst, vd, vm); 1471 } 1472 case 0x1: 1473 if (bits(b, 4)) { 1474 if (q) { 1475 return new NVcgeQFp<float>(machInst, vd, vm); 1476 } else { 1477 return new NVcgeDFp<float>(machInst, vd, vm); 1478 } 1479 } else { 1480 return decodeNeonSTwoMiscReg<NVcgeD, NVcgeQ>( 1481 q, size, machInst, vd, vm); 1482 } 1483 case 0x2: 1484 if (bits(b, 4)) { 1485 if (q) { 1486 return new NVceqQFp<float>(machInst, vd, vm); 1487 } else { 1488 return new NVceqDFp<float>(machInst, vd, vm); 1489 } 1490 } else { 1491 return decodeNeonSTwoMiscReg<NVceqD, NVceqQ>( 1492 q, size, machInst, vd, vm); 1493 } 1494 case 0x3: 1495 if (bits(b, 4)) { 1496 if (q) { 1497 return new NVcleQFp<float>(machInst, vd, vm); 1498 } else { 1499 return new NVcleDFp<float>(machInst, vd, vm); 1500 } 1501 } else { 1502 return decodeNeonSTwoMiscReg<NVcleD, NVcleQ>( 1503 q, size, machInst, vd, vm); 1504 } 1505 case 0x4: 1506 if (bits(b, 4)) { 1507 if (q) { 1508 return new NVcltQFp<float>(machInst, vd, vm); 1509 } else { 1510 return new NVcltDFp<float>(machInst, vd, vm); 1511 } 1512 } else { 1513 return decodeNeonSTwoMiscReg<NVcltD, NVcltQ>( 1514 q, size, machInst, vd, vm); 1515 } 1516 case 0x6: 1517 if (bits(machInst, 10)) { 1518 if (q) 1519 return new NVabsQFp<float>(machInst, vd, vm); 1520 else 1521 return new NVabsDFp<float>(machInst, vd, vm); 1522 } else { 1523 return decodeNeonSTwoMiscReg<NVabsD, NVabsQ>( 1524 q, size, machInst, vd, vm); 1525 } 1526 case 0x7: 1527 if (bits(machInst, 10)) { 1528 if (q) 1529 return new NVnegQFp<float>(machInst, vd, vm); 1530 else 1531 return new NVnegDFp<float>(machInst, vd, vm); 1532 } else { 1533 return decodeNeonSTwoMiscReg<NVnegD, NVnegQ>( 1534 q, size, machInst, vd, vm); 1535 } 1536 } 1537 case 0x2: 1538 switch (bits(b, 4, 1)) { 1539 case 0x0: 1540 if (q) 1541 return new NVswpQ<uint64_t>(machInst, vd, vm); 1542 else 1543 return new NVswpD<uint64_t>(machInst, vd, vm); 1544 case 0x1: 1545 return decodeNeonUTwoMiscReg<NVtrnD, NVtrnQ>( 1546 q, size, machInst, vd, vm); 1547 case 0x2: 1548 return decodeNeonUTwoMiscReg<NVuzpD, NVuzpQ>( 1549 q, size, machInst, vd, vm); 1550 case 0x3: 1551 return decodeNeonUTwoMiscReg<NVzipD, NVzipQ>( 1552 q, size, machInst, vd, vm); 1553 case 0x4: 1554 if (b == 0x8) { 1555 return decodeNeonUTwoMiscUSReg<NVmovn>( 1556 size, machInst, vd, vm); 1557 } else { 1558 return decodeNeonSTwoMiscUSReg<NVqmovuns>( 1559 size, machInst, vd, vm); 1560 } 1561 case 0x5: 1562 if (q) { 1563 return decodeNeonUTwoMiscUSReg<NVqmovun>( 1564 size, machInst, vd, vm); 1565 } else { 1566 return decodeNeonSTwoMiscUSReg<NVqmovn>( 1567 size, machInst, vd, vm); 1568 } 1569 case 0x6: 1570 if (b == 0xc) { 1571 const IntRegIndex vd = 1572 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 1573 (bits(machInst, 22) << 4))); 1574 const IntRegIndex vm = 1575 (IntRegIndex)(2 * (bits(machInst, 3, 0) | 1576 (bits(machInst, 5) << 4))); 1577 unsigned size = bits(machInst, 19, 18); 1578 return decodeNeonSTwoShiftUSReg<NVshll>( 1579 size, machInst, vd, vm, 8 << size); 1580 } else { 1581 return new Unknown(machInst); 1582 } 1583 case 0xc: 1584 case 0xe: 1585 if (b == 0x18) { 1586 if (size != 1 || (vm % 2)) 1587 return new Unknown(machInst); 1588 return new NVcvts2h<uint16_t>(machInst, vd, vm); 1589 } else if (b == 0x1c) { 1590 if (size != 1 || (vd % 2)) 1591 return new Unknown(machInst); 1592 return new NVcvth2s<uint16_t>(machInst, vd, vm); 1593 } else { 1594 return new Unknown(machInst); 1595 } 1596 default: 1597 return new Unknown(machInst); 1598 } 1599 case 0x3: 1600 if (bits(b, 4, 3) == 0x3) { 1601 if ((q && (vd % 2 || vm % 2)) || size != 2) { 1602 return new Unknown(machInst); 1603 } else { 1604 if (bits(b, 2)) { 1605 if (bits(b, 1)) { 1606 if (q) { 1607 return new NVcvt2ufxQ<float>( 1608 machInst, vd, vm, 0); 1609 } else { 1610 return new NVcvt2ufxD<float>( 1611 machInst, vd, vm, 0); 1612 } 1613 } else { 1614 if (q) { 1615 return new NVcvt2sfxQ<float>( 1616 machInst, vd, vm, 0); 1617 } else { 1618 return new NVcvt2sfxD<float>( 1619 machInst, vd, vm, 0); 1620 } 1621 } 1622 } else { 1623 if (bits(b, 1)) { 1624 if (q) { 1625 return new NVcvtu2fpQ<float>( 1626 machInst, vd, vm, 0); 1627 } else { 1628 return new NVcvtu2fpD<float>( 1629 machInst, vd, vm, 0); 1630 } 1631 } else { 1632 if (q) { 1633 return new NVcvts2fpQ<float>( 1634 machInst, vd, vm, 0); 1635 } else { 1636 return new NVcvts2fpD<float>( 1637 machInst, vd, vm, 0); 1638 } 1639 } 1640 } 1641 } 1642 } else if ((b & 0x1a) == 0x10) { 1643 if (bits(b, 2)) { 1644 if (q) { 1645 return new NVrecpeQFp<float>(machInst, vd, vm); 1646 } else { 1647 return new NVrecpeDFp<float>(machInst, vd, vm); 1648 } 1649 } else { 1650 if (q) { 1651 return new NVrecpeQ<uint32_t>(machInst, vd, vm); 1652 } else { 1653 return new NVrecpeD<uint32_t>(machInst, vd, vm); 1654 } 1655 } 1656 } else if ((b & 0x1a) == 0x12) { 1657 if (bits(b, 2)) { 1658 if (q) { 1659 return new NVrsqrteQFp<float>(machInst, vd, vm); 1660 } else { 1661 return new NVrsqrteDFp<float>(machInst, vd, vm); 1662 } 1663 } else { 1664 if (q) { 1665 return new NVrsqrteQ<uint32_t>(machInst, vd, vm); 1666 } else { 1667 return new NVrsqrteD<uint32_t>(machInst, vd, vm); 1668 } 1669 } 1670 } else { 1671 return new Unknown(machInst); 1672 } 1673 } 1674 return new Unknown(machInst); 1675 } 1676 1677 StaticInstPtr 1678 decodeNeonData(ExtMachInst machInst) 1679 { 1680 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 1681 const uint32_t a = bits(machInst, 23, 19); 1682 const uint32_t b = bits(machInst, 11, 8); 1683 const uint32_t c = bits(machInst, 7, 4); 1684 if (bits(a, 4) == 0) { 1685 return decodeNeonThreeRegistersSameLength(machInst); 1686 } else if ((c & 0x9) == 1) { 1687 if ((a & 0x7) == 0) { 1688 return decodeNeonOneRegModImm(machInst); 1689 } else { 1690 return decodeNeonTwoRegAndShift(machInst); 1691 } 1692 } else if ((c & 0x9) == 9) { 1693 return decodeNeonTwoRegAndShift(machInst); 1694 } else if (bits(a, 2, 1) != 0x3) { 1695 if ((c & 0x5) == 0) { 1696 return decodeNeonThreeRegDiffLengths(machInst); 1697 } else if ((c & 0x5) == 4) { 1698 return decodeNeonTwoRegScalar(machInst); 1699 } 1700 } else if ((a & 0x16) == 0x16) { 1701 const IntRegIndex vd = 1702 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 1703 (bits(machInst, 22) << 4))); 1704 const IntRegIndex vn = 1705 (IntRegIndex)(2 * (bits(machInst, 19, 16) | 1706 (bits(machInst, 7) << 4))); 1707 const IntRegIndex vm = 1708 (IntRegIndex)(2 * (bits(machInst, 3, 0) | 1709 (bits(machInst, 5) << 4))); 1710 if (!u) { 1711 if (bits(c, 0) == 0) { 1712 unsigned imm4 = bits(machInst, 11, 8); 1713 bool q = bits(machInst, 6); 1714 if (imm4 >= 16 && !q) 1715 return new Unknown(machInst); 1716 if (q) { 1717 return new NVextQ<uint8_t>(machInst, vd, vn, vm, imm4); 1718 } else { 1719 return new NVextD<uint8_t>(machInst, vd, vn, vm, imm4); 1720 } 1721 } 1722 } else if (bits(b, 3) == 0 && bits(c, 0) == 0) { 1723 return decodeNeonTwoRegMisc(machInst); 1724 } else if (bits(b, 3, 2) == 0x2 && bits(c, 0) == 0) { 1725 unsigned length = bits(machInst, 9, 8) + 1; 1726 if ((uint32_t)vn / 2 + length > 32) 1727 return new Unknown(machInst); 1728 if (bits(machInst, 6) == 0) { 1729 switch (length) { 1730 case 1: 1731 return new NVtbl1(machInst, vd, vn, vm); 1732 case 2: 1733 return new NVtbl2(machInst, vd, vn, vm); 1734 case 3: 1735 return new NVtbl3(machInst, vd, vn, vm); 1736 case 4: 1737 return new NVtbl4(machInst, vd, vn, vm); 1738 } 1739 } else { 1740 switch (length) { 1741 case 1: 1742 return new NVtbx1(machInst, vd, vn, vm); 1743 case 2: 1744 return new NVtbx2(machInst, vd, vn, vm); 1745 case 3: 1746 return new NVtbx3(machInst, vd, vn, vm); 1747 case 4: 1748 return new NVtbx4(machInst, vd, vn, vm); 1749 } 1750 } 1751 } else if (b == 0xc && (c & 0x9) == 0) { 1752 unsigned imm4 = bits(machInst, 19, 16); 1753 if (bits(imm4, 2, 0) == 0) 1754 return new Unknown(machInst); 1755 unsigned size = 0; 1756 while ((imm4 & 0x1) == 0) { 1757 size++; 1758 imm4 >>= 1; 1759 } 1760 unsigned index = imm4 >> 1; 1761 const bool q = bits(machInst, 6); 1762 return decodeNeonUTwoShiftSReg<NVdupD, NVdupQ>( 1763 q, size, machInst, vd, vm, index); 1764 } 1765 } 1766 return new Unknown(machInst); 1767 } 1768 ''' 1769}}; 1770 1771def format ThumbNeonMem() {{ 1772 decode_block = ''' 1773 return decodeNeonMem(machInst); 1774 ''' 1775}}; 1776 1777def format ThumbNeonData() {{ 1778 decode_block = ''' 1779 return decodeNeonData(machInst); 1780 ''' 1781}}; 1782 1783let {{ 1784 header_output = ''' 1785 StaticInstPtr 1786 decodeExtensionRegLoadStore(ExtMachInst machInst); 1787 ''' 1788 decoder_output = ''' 1789 StaticInstPtr 1790 decodeExtensionRegLoadStore(ExtMachInst machInst) 1791 { 1792 const uint32_t opcode = bits(machInst, 24, 20); 1793 const uint32_t offset = bits(machInst, 7, 0); 1794 const bool single = (bits(machInst, 8) == 0); 1795 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 1796 RegIndex vd; 1797 if (single) { 1798 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 1799 bits(machInst, 22)); 1800 } else { 1801 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 1802 (bits(machInst, 22) << 5)); 1803 } 1804 switch (bits(opcode, 4, 3)) { 1805 case 0x0: 1806 if (bits(opcode, 4, 1) == 0x2 && 1807 !(machInst.thumb == 1 && bits(machInst, 28) == 1) && 1808 !(machInst.thumb == 0 && machInst.condCode == 0xf)) { 1809 if ((bits(machInst, 7, 4) & 0xd) != 1) { 1810 break; 1811 } 1812 const IntRegIndex rt = 1813 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 1814 const IntRegIndex rt2 = 1815 (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 1816 const bool op = bits(machInst, 20); 1817 uint32_t vm; 1818 if (single) { 1819 vm = (bits(machInst, 3, 0) << 1) | bits(machInst, 5); 1820 } else { 1821 vm = (bits(machInst, 3, 0) << 1) | 1822 (bits(machInst, 5) << 5); 1823 } 1824 if (op) { 1825 return new Vmov2Core2Reg(machInst, rt, rt2, 1826 (IntRegIndex)vm); 1827 } else { 1828 return new Vmov2Reg2Core(machInst, (IntRegIndex)vm, 1829 rt, rt2); 1830 } 1831 } 1832 break; 1833 case 0x1: 1834 { 1835 if (offset == 0 || vd + offset/2 > NumFloatArchRegs) { 1836 break; 1837 } 1838 switch (bits(opcode, 1, 0)) { 1839 case 0x0: 1840 return new VLdmStm(machInst, rn, vd, single, 1841 true, false, false, offset); 1842 case 0x1: 1843 return new VLdmStm(machInst, rn, vd, single, 1844 true, false, true, offset); 1845 case 0x2: 1846 return new VLdmStm(machInst, rn, vd, single, 1847 true, true, false, offset); 1848 case 0x3: 1849 // If rn == sp, then this is called vpop. 1850 return new VLdmStm(machInst, rn, vd, single, 1851 true, true, true, offset); 1852 } 1853 } 1854 case 0x2: 1855 if (bits(opcode, 1, 0) == 0x2) { 1856 // If rn == sp, then this is called vpush. 1857 return new VLdmStm(machInst, rn, vd, single, 1858 false, true, false, offset); 1859 } else if (bits(opcode, 1, 0) == 0x3) { 1860 return new VLdmStm(machInst, rn, vd, single, 1861 false, true, true, offset); 1862 } 1863 // Fall through on purpose 1864 case 0x3: 1865 const bool up = (bits(machInst, 23) == 1); 1866 const uint32_t imm = bits(machInst, 7, 0) << 2; 1867 RegIndex vd; 1868 if (single) { 1869 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 1870 (bits(machInst, 22))); 1871 } else { 1872 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 1873 (bits(machInst, 22) << 5)); 1874 } 1875 if (bits(opcode, 1, 0) == 0x0) { 1876 if (single) { 1877 if (up) { 1878 return new %(vstr_us)s(machInst, vd, rn, up, imm); 1879 } else { 1880 return new %(vstr_s)s(machInst, vd, rn, up, imm); 1881 } 1882 } else { 1883 if (up) { 1884 return new %(vstr_ud)s(machInst, vd, vd + 1, 1885 rn, up, imm); 1886 } else { 1887 return new %(vstr_d)s(machInst, vd, vd + 1, 1888 rn, up, imm); 1889 } 1890 } 1891 } else if (bits(opcode, 1, 0) == 0x1) { 1892 if (single) { 1893 if (up) { 1894 return new %(vldr_us)s(machInst, vd, rn, up, imm); 1895 } else { 1896 return new %(vldr_s)s(machInst, vd, rn, up, imm); 1897 } 1898 } else { 1899 if (up) { 1900 return new %(vldr_ud)s(machInst, vd, vd + 1, 1901 rn, up, imm); 1902 } else { 1903 return new %(vldr_d)s(machInst, vd, vd + 1, 1904 rn, up, imm); 1905 } 1906 } 1907 } 1908 } 1909 return new Unknown(machInst); 1910 } 1911 ''' % { 1912 "vldr_us" : "VLDR_" + loadImmClassName(False, True, False), 1913 "vldr_s" : "VLDR_" + loadImmClassName(False, False, False), 1914 "vldr_ud" : "VLDR_" + loadDoubleImmClassName(False, True, False), 1915 "vldr_d" : "VLDR_" + loadDoubleImmClassName(False, False, False), 1916 "vstr_us" : "VSTR_" + storeImmClassName(False, True, False), 1917 "vstr_s" : "VSTR_" + storeImmClassName(False, False, False), 1918 "vstr_ud" : "VSTR_" + storeDoubleImmClassName(False, True, False), 1919 "vstr_d" : "VSTR_" + storeDoubleImmClassName(False, False, False) 1920 } 1921}}; 1922 1923def format ExtensionRegLoadStore() {{ 1924 decode_block = ''' 1925 return decodeExtensionRegLoadStore(machInst); 1926 ''' 1927}}; 1928 1929let {{ 1930 header_output = ''' 1931 StaticInstPtr 1932 decodeShortFpTransfer(ExtMachInst machInst); 1933 ''' 1934 decoder_output = ''' 1935 StaticInstPtr 1936 decodeShortFpTransfer(ExtMachInst machInst) 1937 { 1938 const uint32_t l = bits(machInst, 20); 1939 const uint32_t c = bits(machInst, 8); 1940 const uint32_t a = bits(machInst, 23, 21); 1941 const uint32_t b = bits(machInst, 6, 5); 1942 if ((machInst.thumb == 1 && bits(machInst, 28) == 1) || 1943 (machInst.thumb == 0 && machInst.condCode == 0xf)) { 1944 return new Unknown(machInst); 1945 } 1946 if (l == 0 && c == 0) { 1947 if (a == 0) { 1948 const uint32_t vn = (bits(machInst, 19, 16) << 1) | 1949 bits(machInst, 7); 1950 const IntRegIndex rt = 1951 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 1952 if (bits(machInst, 20) == 1) { 1953 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn); 1954 } else { 1955 return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt); 1956 } 1957 } else if (a == 0x7) { 1958 const IntRegIndex rt = 1959 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 1960 uint32_t specReg = bits(machInst, 19, 16); 1961 switch (specReg) { 1962 case 0: 1963 specReg = MISCREG_FPSID; 1964 break; 1965 case 1: 1966 specReg = MISCREG_FPSCR; 1967 break; 1968 case 6: 1969 specReg = MISCREG_MVFR1; 1970 break; 1971 case 7: 1972 specReg = MISCREG_MVFR0; 1973 break; 1974 case 8: 1975 specReg = MISCREG_FPEXC; 1976 break; 1977 default: 1978 return new Unknown(machInst); 1979 } 1980 if (specReg == MISCREG_FPSCR) { 1981 return new VmsrFpscr(machInst, (IntRegIndex)specReg, rt); 1982 } else { 1983 return new Vmsr(machInst, (IntRegIndex)specReg, rt); 1984 } 1985 } 1986 } else if (l == 0 && c == 1) { 1987 if (bits(a, 2) == 0) { 1988 uint32_t vd = (bits(machInst, 7) << 5) | 1989 (bits(machInst, 19, 16) << 1); 1990 // Handle accessing each single precision half of the vector. 1991 vd += bits(machInst, 21); 1992 const IntRegIndex rt = 1993 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 1994 if (bits(machInst, 22) == 1) { 1995 return new VmovCoreRegB(machInst, (IntRegIndex)vd, 1996 rt, bits(machInst, 6, 5)); 1997 } else if (bits(machInst, 5) == 1) { 1998 return new VmovCoreRegH(machInst, (IntRegIndex)vd, 1999 rt, bits(machInst, 6)); 2000 } else if (bits(machInst, 6) == 0) { 2001 return new VmovCoreRegW(machInst, (IntRegIndex)vd, rt); 2002 } else { 2003 return new Unknown(machInst); 2004 } 2005 } else if (bits(b, 1) == 0) { 2006 bool q = bits(machInst, 21); 2007 unsigned be = (bits(machInst, 22) << 1) | (bits(machInst, 5)); 2008 IntRegIndex vd = (IntRegIndex)(2 * (uint32_t) 2009 (bits(machInst, 19, 16) | (bits(machInst, 7) << 4))); 2010 IntRegIndex rt = (IntRegIndex)(uint32_t) 2011 bits(machInst, 15, 12); 2012 if (q) { 2013 switch (be) { 2014 case 0: 2015 return new NVdupQGpr<uint32_t>(machInst, vd, rt); 2016 case 1: 2017 return new NVdupQGpr<uint16_t>(machInst, vd, rt); 2018 case 2: 2019 return new NVdupQGpr<uint8_t>(machInst, vd, rt); 2020 case 3: 2021 return new Unknown(machInst); 2022 } 2023 } else { 2024 switch (be) { 2025 case 0: 2026 return new NVdupDGpr<uint32_t>(machInst, vd, rt); 2027 case 1: 2028 return new NVdupDGpr<uint16_t>(machInst, vd, rt); 2029 case 2: 2030 return new NVdupDGpr<uint8_t>(machInst, vd, rt); 2031 case 3: 2032 return new Unknown(machInst); 2033 } 2034 } 2035 } 2036 } else if (l == 1 && c == 0) { 2037 if (a == 0) { 2038 const uint32_t vn = (bits(machInst, 19, 16) << 1) | 2039 bits(machInst, 7); 2040 const IntRegIndex rt = 2041 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2042 if (bits(machInst, 20) == 1) { 2043 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn); 2044 } else { 2045 return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt); 2046 } 2047 } else if (a == 7) { 2048 const IntRegIndex rt = 2049 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2050 uint32_t specReg = bits(machInst, 19, 16); 2051 switch (specReg) { 2052 case 0: 2053 specReg = MISCREG_FPSID; 2054 break; 2055 case 1: 2056 specReg = MISCREG_FPSCR; 2057 break; 2058 case 6: 2059 specReg = MISCREG_MVFR1; 2060 break; 2061 case 7: 2062 specReg = MISCREG_MVFR0; 2063 break; 2064 case 8: 2065 specReg = MISCREG_FPEXC; 2066 break; 2067 default: 2068 return new Unknown(machInst); 2069 } 2070 if (rt == 0xf) { 2071 CPSR cpsrMask = 0; 2072 cpsrMask.n = 1; 2073 cpsrMask.z = 1; 2074 cpsrMask.c = 1; 2075 cpsrMask.v = 1; 2076 if (specReg == MISCREG_FPSCR) { 2077 return new VmrsApsrFpscr(machInst, INTREG_CONDCODES_F, 2078 (IntRegIndex)specReg, (uint32_t)cpsrMask); 2079 } else { 2080 return new Unknown(machInst); 2081 } 2082 } else if (specReg == MISCREG_FPSCR) { 2083 return new VmrsFpscr(machInst, rt, (IntRegIndex)specReg); 2084 } else { 2085 return new Vmrs(machInst, rt, (IntRegIndex)specReg); 2086 } 2087 } 2088 } else { 2089 uint32_t vd = (bits(machInst, 7) << 5) | 2090 (bits(machInst, 19, 16) << 1); 2091 // Handle indexing into each single precision half of the vector. 2092 vd += bits(machInst, 21); 2093 uint32_t index; 2094 const IntRegIndex rt = 2095 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2096 const bool u = (bits(machInst, 23) == 1); 2097 if (bits(machInst, 22) == 1) { 2098 index = bits(machInst, 6, 5); 2099 if (u) { 2100 return new VmovRegCoreUB(machInst, rt, 2101 (IntRegIndex)vd, index); 2102 } else { 2103 return new VmovRegCoreSB(machInst, rt, 2104 (IntRegIndex)vd, index); 2105 } 2106 } else if (bits(machInst, 5) == 1) { 2107 index = bits(machInst, 6); 2108 if (u) { 2109 return new VmovRegCoreUH(machInst, rt, 2110 (IntRegIndex)vd, index); 2111 } else { 2112 return new VmovRegCoreSH(machInst, rt, 2113 (IntRegIndex)vd, index); 2114 } 2115 } else if (bits(machInst, 6) == 0 && !u) { 2116 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vd); 2117 } else { 2118 return new Unknown(machInst); 2119 } 2120 } 2121 return new Unknown(machInst); 2122 } 2123 ''' 2124}}; 2125 2126def format ShortFpTransfer() {{ 2127 decode_block = ''' 2128 return decodeShortFpTransfer(machInst); 2129 ''' 2130}}; 2131 2132let {{ 2133 header_output = ''' 2134 StaticInstPtr 2135 decodeVfpData(ExtMachInst machInst); 2136 ''' 2137 decoder_output = ''' 2138 StaticInstPtr 2139 decodeVfpData(ExtMachInst machInst) 2140 { 2141 const uint32_t opc1 = bits(machInst, 23, 20); 2142 const uint32_t opc2 = bits(machInst, 19, 16); 2143 const uint32_t opc3 = bits(machInst, 7, 6); 2144 //const uint32_t opc4 = bits(machInst, 3, 0); 2145 const bool single = (bits(machInst, 8) == 0); 2146 // Used to select between vcmp and vcmpe. 2147 const bool e = (bits(machInst, 7) == 1); 2148 IntRegIndex vd; 2149 IntRegIndex vm; 2150 IntRegIndex vn; 2151 if (single) { 2152 vd = (IntRegIndex)(bits(machInst, 22) | 2153 (bits(machInst, 15, 12) << 1)); 2154 vm = (IntRegIndex)(bits(machInst, 5) | 2155 (bits(machInst, 3, 0) << 1)); 2156 vn = (IntRegIndex)(bits(machInst, 7) | 2157 (bits(machInst, 19, 16) << 1)); 2158 } else { 2159 vd = (IntRegIndex)((bits(machInst, 22) << 5) | 2160 (bits(machInst, 15, 12) << 1)); 2161 vm = (IntRegIndex)((bits(machInst, 5) << 5) | 2162 (bits(machInst, 3, 0) << 1)); 2163 vn = (IntRegIndex)((bits(machInst, 7) << 5) | 2164 (bits(machInst, 19, 16) << 1)); 2165 } 2166 switch (opc1 & 0xb /* 1011 */) { 2167 case 0x0: 2168 if (bits(machInst, 6) == 0) { 2169 if (single) { 2170 return decodeVfpRegRegRegOp<VmlaS>( 2171 machInst, vd, vn, vm, false); 2172 } else { 2173 return decodeVfpRegRegRegOp<VmlaD>( 2174 machInst, vd, vn, vm, true); 2175 } 2176 } else { 2177 if (single) { 2178 return decodeVfpRegRegRegOp<VmlsS>( 2179 machInst, vd, vn, vm, false); 2180 } else { 2181 return decodeVfpRegRegRegOp<VmlsD>( 2182 machInst, vd, vn, vm, true); 2183 } 2184 } 2185 case 0x1: 2186 if (bits(machInst, 6) == 1) { 2187 if (single) { 2188 return decodeVfpRegRegRegOp<VnmlaS>( 2189 machInst, vd, vn, vm, false); 2190 } else { 2191 return decodeVfpRegRegRegOp<VnmlaD>( 2192 machInst, vd, vn, vm, true); 2193 } 2194 } else { 2195 if (single) { 2196 return decodeVfpRegRegRegOp<VnmlsS>( 2197 machInst, vd, vn, vm, false); 2198 } else { 2199 return decodeVfpRegRegRegOp<VnmlsD>( 2200 machInst, vd, vn, vm, true); 2201 } 2202 } 2203 case 0x2: 2204 if ((opc3 & 0x1) == 0) { 2205 if (single) { 2206 return decodeVfpRegRegRegOp<VmulS>( 2207 machInst, vd, vn, vm, false); 2208 } else { 2209 return decodeVfpRegRegRegOp<VmulD>( 2210 machInst, vd, vn, vm, true); 2211 } 2212 } else { 2213 if (single) { 2214 return decodeVfpRegRegRegOp<VnmulS>( 2215 machInst, vd, vn, vm, false); 2216 } else { 2217 return decodeVfpRegRegRegOp<VnmulD>( 2218 machInst, vd, vn, vm, true); 2219 } 2220 } 2221 case 0x3: 2222 if ((opc3 & 0x1) == 0) { 2223 if (single) { 2224 return decodeVfpRegRegRegOp<VaddS>( 2225 machInst, vd, vn, vm, false); 2226 } else { 2227 return decodeVfpRegRegRegOp<VaddD>( 2228 machInst, vd, vn, vm, true); 2229 } 2230 } else { 2231 if (single) { 2232 return decodeVfpRegRegRegOp<VsubS>( 2233 machInst, vd, vn, vm, false); 2234 } else { 2235 return decodeVfpRegRegRegOp<VsubD>( 2236 machInst, vd, vn, vm, true); 2237 } 2238 } 2239 case 0x8: 2240 if ((opc3 & 0x1) == 0) { 2241 if (single) { 2242 return decodeVfpRegRegRegOp<VdivS>( 2243 machInst, vd, vn, vm, false); 2244 } else { 2245 return decodeVfpRegRegRegOp<VdivD>( 2246 machInst, vd, vn, vm, true); 2247 } 2248 } 2249 break; 2250 case 0xb: 2251 if ((opc3 & 0x1) == 0) { 2252 const uint32_t baseImm = 2253 bits(machInst, 3, 0) | (bits(machInst, 19, 16) << 4); 2254 if (single) { 2255 uint32_t imm = vfp_modified_imm(baseImm, false); 2256 return decodeVfpRegImmOp<VmovImmS>( 2257 machInst, vd, imm, false); 2258 } else { 2259 uint64_t imm = vfp_modified_imm(baseImm, true); 2260 return decodeVfpRegImmOp<VmovImmD>( 2261 machInst, vd, imm, true); 2262 } 2263 } 2264 switch (opc2) { 2265 case 0x0: 2266 if (opc3 == 1) { 2267 if (single) { 2268 return decodeVfpRegRegOp<VmovRegS>( 2269 machInst, vd, vm, false); 2270 } else { 2271 return decodeVfpRegRegOp<VmovRegD>( 2272 machInst, vd, vm, true); 2273 } 2274 } else { 2275 if (single) { 2276 return decodeVfpRegRegOp<VabsS>( 2277 machInst, vd, vm, false); 2278 } else { 2279 return decodeVfpRegRegOp<VabsD>( 2280 machInst, vd, vm, true); 2281 } 2282 } 2283 case 0x1: 2284 if (opc3 == 1) { 2285 if (single) { 2286 return decodeVfpRegRegOp<VnegS>( 2287 machInst, vd, vm, false); 2288 } else { 2289 return decodeVfpRegRegOp<VnegD>( 2290 machInst, vd, vm, true); 2291 } 2292 } else { 2293 if (single) { 2294 return decodeVfpRegRegOp<VsqrtS>( 2295 machInst, vd, vm, false); 2296 } else { 2297 return decodeVfpRegRegOp<VsqrtD>( 2298 machInst, vd, vm, true); 2299 } 2300 } 2301 case 0x2: 2302 case 0x3: 2303 { 2304 const bool toHalf = bits(machInst, 16); 2305 const bool top = bits(machInst, 7); 2306 if (top) { 2307 if (toHalf) { 2308 return new VcvtFpSFpHT(machInst, vd, vm); 2309 } else { 2310 return new VcvtFpHTFpS(machInst, vd, vm); 2311 } 2312 } else { 2313 if (toHalf) { 2314 return new VcvtFpSFpHB(machInst, vd, vm); 2315 } else { 2316 return new VcvtFpHBFpS(machInst, vd, vm); 2317 } 2318 } 2319 } 2320 case 0x4: 2321 if (single) { 2322 if (e) { 2323 return new VcmpeS(machInst, vd, vm); 2324 } else { 2325 return new VcmpS(machInst, vd, vm); 2326 } 2327 } else { 2328 if (e) { 2329 return new VcmpeD(machInst, vd, vm); 2330 } else { 2331 return new VcmpD(machInst, vd, vm); 2332 } 2333 } 2334 case 0x5: 2335 if (single) { 2336 if (e) { 2337 return new VcmpeZeroS(machInst, vd, 0); 2338 } else { 2339 return new VcmpZeroS(machInst, vd, 0); 2340 } 2341 } else { 2342 if (e) { 2343 return new VcmpeZeroD(machInst, vd, 0); 2344 } else { 2345 return new VcmpZeroD(machInst, vd, 0); 2346 } 2347 } 2348 case 0x7: 2349 if (opc3 == 0x3) { 2350 if (single) { 2351 vd = (IntRegIndex)((bits(machInst, 22) << 5) | 2352 (bits(machInst, 15, 12) << 1)); 2353 return new VcvtFpSFpD(machInst, vd, vm); 2354 } else { 2355 vd = (IntRegIndex)(bits(machInst, 22) | 2356 (bits(machInst, 15, 12) << 1)); 2357 return new VcvtFpDFpS(machInst, vd, vm); 2358 } 2359 } 2360 break; 2361 case 0x8: 2362 if (bits(machInst, 7) == 0) { 2363 if (single) { 2364 return new VcvtUIntFpS(machInst, vd, vm); 2365 } else { 2366 vm = (IntRegIndex)(bits(machInst, 5) | 2367 (bits(machInst, 3, 0) << 1)); 2368 return new VcvtUIntFpD(machInst, vd, vm); 2369 } 2370 } else { 2371 if (single) { 2372 return new VcvtSIntFpS(machInst, vd, vm); 2373 } else { 2374 vm = (IntRegIndex)(bits(machInst, 5) | 2375 (bits(machInst, 3, 0) << 1)); 2376 return new VcvtSIntFpD(machInst, vd, vm); 2377 } 2378 } 2379 case 0xa: 2380 { 2381 const bool half = (bits(machInst, 7) == 0); 2382 const uint32_t imm = bits(machInst, 5) | 2383 (bits(machInst, 3, 0) << 1); 2384 const uint32_t size = 2385 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2386 if (single) { 2387 if (half) { 2388 return new VcvtSHFixedFpS(machInst, vd, vd, size); 2389 } else { 2390 return new VcvtSFixedFpS(machInst, vd, vd, size); 2391 } 2392 } else { 2393 if (half) { 2394 return new VcvtSHFixedFpD(machInst, vd, vd, size); 2395 } else { 2396 return new VcvtSFixedFpD(machInst, vd, vd, size); 2397 } 2398 } 2399 } 2400 case 0xb: 2401 { 2402 const bool half = (bits(machInst, 7) == 0); 2403 const uint32_t imm = bits(machInst, 5) | 2404 (bits(machInst, 3, 0) << 1); 2405 const uint32_t size = 2406 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2407 if (single) { 2408 if (half) { 2409 return new VcvtUHFixedFpS(machInst, vd, vd, size); 2410 } else { 2411 return new VcvtUFixedFpS(machInst, vd, vd, size); 2412 } 2413 } else { 2414 if (half) { 2415 return new VcvtUHFixedFpD(machInst, vd, vd, size); 2416 } else { 2417 return new VcvtUFixedFpD(machInst, vd, vd, size); 2418 } 2419 } 2420 } 2421 case 0xc: 2422 if (bits(machInst, 7) == 0) { 2423 if (single) { 2424 return new VcvtFpUIntSR(machInst, vd, vm); 2425 } else { 2426 vd = (IntRegIndex)(bits(machInst, 22) | 2427 (bits(machInst, 15, 12) << 1)); 2428 return new VcvtFpUIntDR(machInst, vd, vm); 2429 } 2430 } else { 2431 if (single) { 2432 return new VcvtFpUIntS(machInst, vd, vm); 2433 } else { 2434 vd = (IntRegIndex)(bits(machInst, 22) | 2435 (bits(machInst, 15, 12) << 1)); 2436 return new VcvtFpUIntD(machInst, vd, vm); 2437 } 2438 } 2439 case 0xd: 2440 if (bits(machInst, 7) == 0) { 2441 if (single) { 2442 return new VcvtFpSIntSR(machInst, vd, vm); 2443 } else { 2444 vd = (IntRegIndex)(bits(machInst, 22) | 2445 (bits(machInst, 15, 12) << 1)); 2446 return new VcvtFpSIntDR(machInst, vd, vm); 2447 } 2448 } else { 2449 if (single) { 2450 return new VcvtFpSIntS(machInst, vd, vm); 2451 } else { 2452 vd = (IntRegIndex)(bits(machInst, 22) | 2453 (bits(machInst, 15, 12) << 1)); 2454 return new VcvtFpSIntD(machInst, vd, vm); 2455 } 2456 } 2457 case 0xe: 2458 { 2459 const bool half = (bits(machInst, 7) == 0); 2460 const uint32_t imm = bits(machInst, 5) | 2461 (bits(machInst, 3, 0) << 1); 2462 const uint32_t size = 2463 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2464 if (single) { 2465 if (half) { 2466 return new VcvtFpSHFixedS(machInst, vd, vd, size); 2467 } else { 2468 return new VcvtFpSFixedS(machInst, vd, vd, size); 2469 } 2470 } else { 2471 if (half) { 2472 return new VcvtFpSHFixedD(machInst, vd, vd, size); 2473 } else { 2474 return new VcvtFpSFixedD(machInst, vd, vd, size); 2475 } 2476 } 2477 } 2478 case 0xf: 2479 { 2480 const bool half = (bits(machInst, 7) == 0); 2481 const uint32_t imm = bits(machInst, 5) | 2482 (bits(machInst, 3, 0) << 1); 2483 const uint32_t size = 2484 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2485 if (single) { 2486 if (half) { 2487 return new VcvtFpUHFixedS(machInst, vd, vd, size); 2488 } else { 2489 return new VcvtFpUFixedS(machInst, vd, vd, size); 2490 } 2491 } else { 2492 if (half) { 2493 return new VcvtFpUHFixedD(machInst, vd, vd, size); 2494 } else { 2495 return new VcvtFpUFixedD(machInst, vd, vd, size); 2496 } 2497 } 2498 } 2499 } 2500 break; 2501 } 2502 return new Unknown(machInst); 2503 } 2504 ''' 2505}}; 2506 2507def format VfpData() {{ 2508 decode_block = ''' 2509 return decodeVfpData(machInst); 2510 ''' 2511}}; 2512