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 return decodeNeonSTwoShiftUSReg<NVshll>( 1574 size, machInst, vd, vm, 8 << size); 1575 } else { 1576 return new Unknown(machInst); 1577 } 1578 case 0xc: 1579 case 0xe: 1580 if (b == 0x18) { 1581 if (size != 1 || (vm % 2)) 1582 return new Unknown(machInst); 1583 return new NVcvts2h<uint16_t>(machInst, vd, vm); 1584 } else if (b == 0x1c) { 1585 if (size != 1 || (vd % 2)) 1586 return new Unknown(machInst); 1587 return new NVcvth2s<uint16_t>(machInst, vd, vm); 1588 } else { 1589 return new Unknown(machInst); 1590 } 1591 default: 1592 return new Unknown(machInst); 1593 } 1594 case 0x3: 1595 if (bits(b, 4, 3) == 0x3) { 1596 if ((q && (vd % 2 || vm % 2)) || size != 2) { 1597 return new Unknown(machInst); 1598 } else { 1599 if (bits(b, 2)) { 1600 if (bits(b, 1)) { 1601 if (q) { 1602 return new NVcvt2ufxQ<float>( 1603 machInst, vd, vm, 0); 1604 } else { 1605 return new NVcvt2ufxD<float>( 1606 machInst, vd, vm, 0); 1607 } 1608 } else { 1609 if (q) { 1610 return new NVcvt2sfxQ<float>( 1611 machInst, vd, vm, 0); 1612 } else { 1613 return new NVcvt2sfxD<float>( 1614 machInst, vd, vm, 0); 1615 } 1616 } 1617 } else { 1618 if (bits(b, 1)) { 1619 if (q) { 1620 return new NVcvtu2fpQ<float>( 1621 machInst, vd, vm, 0); 1622 } else { 1623 return new NVcvtu2fpD<float>( 1624 machInst, vd, vm, 0); 1625 } 1626 } else { 1627 if (q) { 1628 return new NVcvts2fpQ<float>( 1629 machInst, vd, vm, 0); 1630 } else { 1631 return new NVcvts2fpD<float>( 1632 machInst, vd, vm, 0); 1633 } 1634 } 1635 } 1636 } 1637 } else if ((b & 0x1a) == 0x10) { 1638 if (bits(b, 2)) { 1639 if (q) { 1640 return new NVrecpeQFp<float>(machInst, vd, vm); 1641 } else { 1642 return new NVrecpeDFp<float>(machInst, vd, vm); 1643 } 1644 } else { 1645 if (q) { 1646 return new NVrecpeQ<uint32_t>(machInst, vd, vm); 1647 } else { 1648 return new NVrecpeD<uint32_t>(machInst, vd, vm); 1649 } 1650 } 1651 } else if ((b & 0x1a) == 0x12) { 1652 if (bits(b, 2)) { 1653 if (q) { 1654 return new NVrsqrteQFp<float>(machInst, vd, vm); 1655 } else { 1656 return new NVrsqrteDFp<float>(machInst, vd, vm); 1657 } 1658 } else { 1659 if (q) { 1660 return new NVrsqrteQ<uint32_t>(machInst, vd, vm); 1661 } else { 1662 return new NVrsqrteD<uint32_t>(machInst, vd, vm); 1663 } 1664 } 1665 } else { 1666 return new Unknown(machInst); 1667 } 1668 } 1669 return new Unknown(machInst); 1670 } 1671 1672 StaticInstPtr 1673 decodeNeonData(ExtMachInst machInst) 1674 { 1675 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24); 1676 const uint32_t a = bits(machInst, 23, 19); 1677 const uint32_t b = bits(machInst, 11, 8); 1678 const uint32_t c = bits(machInst, 7, 4); 1679 if (bits(a, 4) == 0) { 1680 return decodeNeonThreeRegistersSameLength(machInst); 1681 } else if ((c & 0x9) == 1) { 1682 if ((a & 0x7) == 0) { 1683 return decodeNeonOneRegModImm(machInst); 1684 } else { 1685 return decodeNeonTwoRegAndShift(machInst); 1686 } 1687 } else if ((c & 0x9) == 9) { 1688 return decodeNeonTwoRegAndShift(machInst); 1689 } else if (bits(a, 2, 1) != 0x3) { 1690 if ((c & 0x5) == 0) { 1691 return decodeNeonThreeRegDiffLengths(machInst); 1692 } else if ((c & 0x5) == 4) { 1693 return decodeNeonTwoRegScalar(machInst); 1694 } 1695 } else if ((a & 0x16) == 0x16) { 1696 const IntRegIndex vd = 1697 (IntRegIndex)(2 * (bits(machInst, 15, 12) | 1698 (bits(machInst, 22) << 4))); 1699 const IntRegIndex vn = 1700 (IntRegIndex)(2 * (bits(machInst, 19, 16) | 1701 (bits(machInst, 7) << 4))); 1702 const IntRegIndex vm = 1703 (IntRegIndex)(2 * (bits(machInst, 3, 0) | 1704 (bits(machInst, 5) << 4))); 1705 if (!u) { 1706 if (bits(c, 0) == 0) { 1707 unsigned imm4 = bits(machInst, 11, 8); 1708 bool q = bits(machInst, 6); 1709 if (imm4 >= 16 && !q) 1710 return new Unknown(machInst); 1711 if (q) { 1712 return new NVextQ<uint8_t>(machInst, vd, vn, vm, imm4); 1713 } else { 1714 return new NVextD<uint8_t>(machInst, vd, vn, vm, imm4); 1715 } 1716 } 1717 } else if (bits(b, 3) == 0 && bits(c, 0) == 0) { 1718 return decodeNeonTwoRegMisc(machInst); 1719 } else if (bits(b, 3, 2) == 0x2 && bits(c, 0) == 0) { 1720 unsigned length = bits(machInst, 9, 8) + 1; 1721 if ((uint32_t)vn / 2 + length > 32) 1722 return new Unknown(machInst); 1723 if (bits(machInst, 6) == 0) { 1724 switch (length) { 1725 case 1: 1726 return new NVtbl1(machInst, vd, vn, vm); 1727 case 2: 1728 return new NVtbl2(machInst, vd, vn, vm); 1729 case 3: 1730 return new NVtbl3(machInst, vd, vn, vm); 1731 case 4: 1732 return new NVtbl4(machInst, vd, vn, vm); 1733 } 1734 } else { 1735 switch (length) { 1736 case 1: 1737 return new NVtbx1(machInst, vd, vn, vm); 1738 case 2: 1739 return new NVtbx2(machInst, vd, vn, vm); 1740 case 3: 1741 return new NVtbx3(machInst, vd, vn, vm); 1742 case 4: 1743 return new NVtbx4(machInst, vd, vn, vm); 1744 } 1745 } 1746 } else if (b == 0xc && (c & 0x9) == 0) { 1747 unsigned imm4 = bits(machInst, 19, 16); 1748 if (bits(imm4, 2, 0) == 0) 1749 return new Unknown(machInst); 1750 unsigned size = 0; 1751 while ((imm4 & 0x1) == 0) { 1752 size++; 1753 imm4 >>= 1; 1754 } 1755 unsigned index = imm4 >> 1; 1756 const bool q = bits(machInst, 6); 1757 return decodeNeonUTwoShiftSReg<NVdupD, NVdupQ>( 1758 q, size, machInst, vd, vm, index); 1759 } 1760 } 1761 return new Unknown(machInst); 1762 } 1763 ''' 1764}}; 1765 1766def format ThumbNeonMem() {{ 1767 decode_block = ''' 1768 return decodeNeonMem(machInst); 1769 ''' 1770}}; 1771 1772def format ThumbNeonData() {{ 1773 decode_block = ''' 1774 return decodeNeonData(machInst); 1775 ''' 1776}}; 1777 1778let {{ 1779 header_output = ''' 1780 StaticInstPtr 1781 decodeExtensionRegLoadStore(ExtMachInst machInst); 1782 ''' 1783 decoder_output = ''' 1784 StaticInstPtr 1785 decodeExtensionRegLoadStore(ExtMachInst machInst) 1786 { 1787 const uint32_t opcode = bits(machInst, 24, 20); 1788 const uint32_t offset = bits(machInst, 7, 0); 1789 const bool single = (bits(machInst, 8) == 0); 1790 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 1791 RegIndex vd; 1792 if (single) { 1793 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 1794 bits(machInst, 22)); 1795 } else { 1796 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 1797 (bits(machInst, 22) << 5)); 1798 } 1799 switch (bits(opcode, 4, 3)) { 1800 case 0x0: 1801 if (bits(opcode, 4, 1) == 0x2 && 1802 !(machInst.thumb == 1 && bits(machInst, 28) == 1) && 1803 !(machInst.thumb == 0 && machInst.condCode == 0xf)) { 1804 if ((bits(machInst, 7, 4) & 0xd) != 1) { 1805 break; 1806 } 1807 const IntRegIndex rt = 1808 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 1809 const IntRegIndex rt2 = 1810 (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 1811 const bool op = bits(machInst, 20); 1812 uint32_t vm; 1813 if (single) { 1814 vm = (bits(machInst, 3, 0) << 1) | bits(machInst, 5); 1815 } else { 1816 vm = (bits(machInst, 3, 0) << 1) | 1817 (bits(machInst, 5) << 5); 1818 } 1819 if (op) { 1820 return new Vmov2Core2Reg(machInst, rt, rt2, 1821 (IntRegIndex)vm); 1822 } else { 1823 return new Vmov2Reg2Core(machInst, (IntRegIndex)vm, 1824 rt, rt2); 1825 } 1826 } 1827 break; 1828 case 0x1: 1829 { 1830 if (offset == 0 || vd + offset/2 > NumFloatArchRegs) { 1831 break; 1832 } 1833 switch (bits(opcode, 1, 0)) { 1834 case 0x0: 1835 return new VLdmStm(machInst, rn, vd, single, 1836 true, false, false, offset); 1837 case 0x1: 1838 return new VLdmStm(machInst, rn, vd, single, 1839 true, false, true, offset); 1840 case 0x2: 1841 return new VLdmStm(machInst, rn, vd, single, 1842 true, true, false, offset); 1843 case 0x3: 1844 // If rn == sp, then this is called vpop. 1845 return new VLdmStm(machInst, rn, vd, single, 1846 true, true, true, offset); 1847 } 1848 } 1849 case 0x2: 1850 if (bits(opcode, 1, 0) == 0x2) { 1851 // If rn == sp, then this is called vpush. 1852 return new VLdmStm(machInst, rn, vd, single, 1853 false, true, false, offset); 1854 } else if (bits(opcode, 1, 0) == 0x3) { 1855 return new VLdmStm(machInst, rn, vd, single, 1856 false, true, true, offset); 1857 } 1858 // Fall through on purpose 1859 case 0x3: 1860 const bool up = (bits(machInst, 23) == 1); 1861 const uint32_t imm = bits(machInst, 7, 0) << 2; |
1862 if (single) { 1863 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 1864 (bits(machInst, 22))); 1865 } else { 1866 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) | 1867 (bits(machInst, 22) << 5)); 1868 } 1869 if (bits(opcode, 1, 0) == 0x0) { 1870 if (single) { 1871 if (up) { 1872 return new %(vstr_us)s(machInst, vd, rn, up, imm); 1873 } else { 1874 return new %(vstr_s)s(machInst, vd, rn, up, imm); 1875 } 1876 } else { 1877 if (up) { 1878 return new %(vstr_ud)s(machInst, vd, vd + 1, 1879 rn, up, imm); 1880 } else { 1881 return new %(vstr_d)s(machInst, vd, vd + 1, 1882 rn, up, imm); 1883 } 1884 } 1885 } else if (bits(opcode, 1, 0) == 0x1) { 1886 if (single) { 1887 if (up) { 1888 return new %(vldr_us)s(machInst, vd, rn, up, imm); 1889 } else { 1890 return new %(vldr_s)s(machInst, vd, rn, up, imm); 1891 } 1892 } else { 1893 if (up) { 1894 return new %(vldr_ud)s(machInst, vd, vd + 1, 1895 rn, up, imm); 1896 } else { 1897 return new %(vldr_d)s(machInst, vd, vd + 1, 1898 rn, up, imm); 1899 } 1900 } 1901 } 1902 } 1903 return new Unknown(machInst); 1904 } 1905 ''' % { 1906 "vldr_us" : "VLDR_" + loadImmClassName(False, True, False), 1907 "vldr_s" : "VLDR_" + loadImmClassName(False, False, False), 1908 "vldr_ud" : "VLDR_" + loadDoubleImmClassName(False, True, False), 1909 "vldr_d" : "VLDR_" + loadDoubleImmClassName(False, False, False), 1910 "vstr_us" : "VSTR_" + storeImmClassName(False, True, False), 1911 "vstr_s" : "VSTR_" + storeImmClassName(False, False, False), 1912 "vstr_ud" : "VSTR_" + storeDoubleImmClassName(False, True, False), 1913 "vstr_d" : "VSTR_" + storeDoubleImmClassName(False, False, False) 1914 } 1915}}; 1916 1917def format ExtensionRegLoadStore() {{ 1918 decode_block = ''' 1919 return decodeExtensionRegLoadStore(machInst); 1920 ''' 1921}}; 1922 1923let {{ 1924 header_output = ''' 1925 StaticInstPtr 1926 decodeShortFpTransfer(ExtMachInst machInst); 1927 ''' 1928 decoder_output = ''' 1929 StaticInstPtr 1930 decodeShortFpTransfer(ExtMachInst machInst) 1931 { 1932 const uint32_t l = bits(machInst, 20); 1933 const uint32_t c = bits(machInst, 8); 1934 const uint32_t a = bits(machInst, 23, 21); 1935 const uint32_t b = bits(machInst, 6, 5); 1936 if ((machInst.thumb == 1 && bits(machInst, 28) == 1) || 1937 (machInst.thumb == 0 && machInst.condCode == 0xf)) { 1938 return new Unknown(machInst); 1939 } 1940 if (l == 0 && c == 0) { 1941 if (a == 0) { 1942 const uint32_t vn = (bits(machInst, 19, 16) << 1) | 1943 bits(machInst, 7); 1944 const IntRegIndex rt = 1945 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 1946 if (bits(machInst, 20) == 1) { 1947 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn); 1948 } else { 1949 return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt); 1950 } 1951 } else if (a == 0x7) { 1952 const IntRegIndex rt = 1953 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 1954 uint32_t specReg = bits(machInst, 19, 16); 1955 switch (specReg) { 1956 case 0: 1957 specReg = MISCREG_FPSID; 1958 break; 1959 case 1: 1960 specReg = MISCREG_FPSCR; 1961 break; 1962 case 6: 1963 specReg = MISCREG_MVFR1; 1964 break; 1965 case 7: 1966 specReg = MISCREG_MVFR0; 1967 break; 1968 case 8: 1969 specReg = MISCREG_FPEXC; 1970 break; 1971 default: 1972 return new Unknown(machInst); 1973 } 1974 if (specReg == MISCREG_FPSCR) { 1975 return new VmsrFpscr(machInst, (IntRegIndex)specReg, rt); 1976 } else { 1977 return new Vmsr(machInst, (IntRegIndex)specReg, rt); 1978 } 1979 } 1980 } else if (l == 0 && c == 1) { 1981 if (bits(a, 2) == 0) { 1982 uint32_t vd = (bits(machInst, 7) << 5) | 1983 (bits(machInst, 19, 16) << 1); 1984 // Handle accessing each single precision half of the vector. 1985 vd += bits(machInst, 21); 1986 const IntRegIndex rt = 1987 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 1988 if (bits(machInst, 22) == 1) { 1989 return new VmovCoreRegB(machInst, (IntRegIndex)vd, 1990 rt, bits(machInst, 6, 5)); 1991 } else if (bits(machInst, 5) == 1) { 1992 return new VmovCoreRegH(machInst, (IntRegIndex)vd, 1993 rt, bits(machInst, 6)); 1994 } else if (bits(machInst, 6) == 0) { 1995 return new VmovCoreRegW(machInst, (IntRegIndex)vd, rt); 1996 } else { 1997 return new Unknown(machInst); 1998 } 1999 } else if (bits(b, 1) == 0) { 2000 bool q = bits(machInst, 21); 2001 unsigned be = (bits(machInst, 22) << 1) | (bits(machInst, 5)); 2002 IntRegIndex vd = (IntRegIndex)(2 * (uint32_t) 2003 (bits(machInst, 19, 16) | (bits(machInst, 7) << 4))); 2004 IntRegIndex rt = (IntRegIndex)(uint32_t) 2005 bits(machInst, 15, 12); 2006 if (q) { 2007 switch (be) { 2008 case 0: 2009 return new NVdupQGpr<uint32_t>(machInst, vd, rt); 2010 case 1: 2011 return new NVdupQGpr<uint16_t>(machInst, vd, rt); 2012 case 2: 2013 return new NVdupQGpr<uint8_t>(machInst, vd, rt); 2014 case 3: 2015 return new Unknown(machInst); 2016 } 2017 } else { 2018 switch (be) { 2019 case 0: 2020 return new NVdupDGpr<uint32_t>(machInst, vd, rt); 2021 case 1: 2022 return new NVdupDGpr<uint16_t>(machInst, vd, rt); 2023 case 2: 2024 return new NVdupDGpr<uint8_t>(machInst, vd, rt); 2025 case 3: 2026 return new Unknown(machInst); 2027 } 2028 } 2029 } 2030 } else if (l == 1 && c == 0) { 2031 if (a == 0) { 2032 const uint32_t vn = (bits(machInst, 19, 16) << 1) | 2033 bits(machInst, 7); 2034 const IntRegIndex rt = 2035 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2036 if (bits(machInst, 20) == 1) { 2037 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn); 2038 } else { 2039 return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt); 2040 } 2041 } else if (a == 7) { 2042 const IntRegIndex rt = 2043 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2044 uint32_t specReg = bits(machInst, 19, 16); 2045 switch (specReg) { 2046 case 0: 2047 specReg = MISCREG_FPSID; 2048 break; 2049 case 1: 2050 specReg = MISCREG_FPSCR; 2051 break; 2052 case 6: 2053 specReg = MISCREG_MVFR1; 2054 break; 2055 case 7: 2056 specReg = MISCREG_MVFR0; 2057 break; 2058 case 8: 2059 specReg = MISCREG_FPEXC; 2060 break; 2061 default: 2062 return new Unknown(machInst); 2063 } 2064 if (rt == 0xf) { 2065 if (specReg == MISCREG_FPSCR) { 2066 return new VmrsApsrFpscr(machInst); 2067 } else { 2068 return new Unknown(machInst); 2069 } 2070 } else if (specReg == MISCREG_FPSCR) { 2071 return new VmrsFpscr(machInst, rt, (IntRegIndex)specReg); 2072 } else { 2073 return new Vmrs(machInst, rt, (IntRegIndex)specReg); 2074 } 2075 } 2076 } else { 2077 uint32_t vd = (bits(machInst, 7) << 5) | 2078 (bits(machInst, 19, 16) << 1); 2079 // Handle indexing into each single precision half of the vector. 2080 vd += bits(machInst, 21); 2081 uint32_t index; 2082 const IntRegIndex rt = 2083 (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2084 const bool u = (bits(machInst, 23) == 1); 2085 if (bits(machInst, 22) == 1) { 2086 index = bits(machInst, 6, 5); 2087 if (u) { 2088 return new VmovRegCoreUB(machInst, rt, 2089 (IntRegIndex)vd, index); 2090 } else { 2091 return new VmovRegCoreSB(machInst, rt, 2092 (IntRegIndex)vd, index); 2093 } 2094 } else if (bits(machInst, 5) == 1) { 2095 index = bits(machInst, 6); 2096 if (u) { 2097 return new VmovRegCoreUH(machInst, rt, 2098 (IntRegIndex)vd, index); 2099 } else { 2100 return new VmovRegCoreSH(machInst, rt, 2101 (IntRegIndex)vd, index); 2102 } 2103 } else if (bits(machInst, 6) == 0 && !u) { 2104 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vd); 2105 } else { 2106 return new Unknown(machInst); 2107 } 2108 } 2109 return new Unknown(machInst); 2110 } 2111 ''' 2112}}; 2113 2114def format ShortFpTransfer() {{ 2115 decode_block = ''' 2116 return decodeShortFpTransfer(machInst); 2117 ''' 2118}}; 2119 2120let {{ 2121 header_output = ''' 2122 StaticInstPtr 2123 decodeVfpData(ExtMachInst machInst); 2124 ''' 2125 decoder_output = ''' 2126 StaticInstPtr 2127 decodeVfpData(ExtMachInst machInst) 2128 { 2129 const uint32_t opc1 = bits(machInst, 23, 20); 2130 const uint32_t opc2 = bits(machInst, 19, 16); 2131 const uint32_t opc3 = bits(machInst, 7, 6); 2132 //const uint32_t opc4 = bits(machInst, 3, 0); 2133 const bool single = (bits(machInst, 8) == 0); 2134 // Used to select between vcmp and vcmpe. 2135 const bool e = (bits(machInst, 7) == 1); 2136 IntRegIndex vd; 2137 IntRegIndex vm; 2138 IntRegIndex vn; 2139 if (single) { 2140 vd = (IntRegIndex)(bits(machInst, 22) | 2141 (bits(machInst, 15, 12) << 1)); 2142 vm = (IntRegIndex)(bits(machInst, 5) | 2143 (bits(machInst, 3, 0) << 1)); 2144 vn = (IntRegIndex)(bits(machInst, 7) | 2145 (bits(machInst, 19, 16) << 1)); 2146 } else { 2147 vd = (IntRegIndex)((bits(machInst, 22) << 5) | 2148 (bits(machInst, 15, 12) << 1)); 2149 vm = (IntRegIndex)((bits(machInst, 5) << 5) | 2150 (bits(machInst, 3, 0) << 1)); 2151 vn = (IntRegIndex)((bits(machInst, 7) << 5) | 2152 (bits(machInst, 19, 16) << 1)); 2153 } 2154 switch (opc1 & 0xb /* 1011 */) { 2155 case 0x0: 2156 if (bits(machInst, 6) == 0) { 2157 if (single) { 2158 return decodeVfpRegRegRegOp<VmlaS>( 2159 machInst, vd, vn, vm, false); 2160 } else { 2161 return decodeVfpRegRegRegOp<VmlaD>( 2162 machInst, vd, vn, vm, true); 2163 } 2164 } else { 2165 if (single) { 2166 return decodeVfpRegRegRegOp<VmlsS>( 2167 machInst, vd, vn, vm, false); 2168 } else { 2169 return decodeVfpRegRegRegOp<VmlsD>( 2170 machInst, vd, vn, vm, true); 2171 } 2172 } 2173 case 0x1: 2174 if (bits(machInst, 6) == 1) { 2175 if (single) { 2176 return decodeVfpRegRegRegOp<VnmlaS>( 2177 machInst, vd, vn, vm, false); 2178 } else { 2179 return decodeVfpRegRegRegOp<VnmlaD>( 2180 machInst, vd, vn, vm, true); 2181 } 2182 } else { 2183 if (single) { 2184 return decodeVfpRegRegRegOp<VnmlsS>( 2185 machInst, vd, vn, vm, false); 2186 } else { 2187 return decodeVfpRegRegRegOp<VnmlsD>( 2188 machInst, vd, vn, vm, true); 2189 } 2190 } 2191 case 0x2: 2192 if ((opc3 & 0x1) == 0) { 2193 if (single) { 2194 return decodeVfpRegRegRegOp<VmulS>( 2195 machInst, vd, vn, vm, false); 2196 } else { 2197 return decodeVfpRegRegRegOp<VmulD>( 2198 machInst, vd, vn, vm, true); 2199 } 2200 } else { 2201 if (single) { 2202 return decodeVfpRegRegRegOp<VnmulS>( 2203 machInst, vd, vn, vm, false); 2204 } else { 2205 return decodeVfpRegRegRegOp<VnmulD>( 2206 machInst, vd, vn, vm, true); 2207 } 2208 } 2209 case 0x3: 2210 if ((opc3 & 0x1) == 0) { 2211 if (single) { 2212 return decodeVfpRegRegRegOp<VaddS>( 2213 machInst, vd, vn, vm, false); 2214 } else { 2215 return decodeVfpRegRegRegOp<VaddD>( 2216 machInst, vd, vn, vm, true); 2217 } 2218 } else { 2219 if (single) { 2220 return decodeVfpRegRegRegOp<VsubS>( 2221 machInst, vd, vn, vm, false); 2222 } else { 2223 return decodeVfpRegRegRegOp<VsubD>( 2224 machInst, vd, vn, vm, true); 2225 } 2226 } 2227 case 0x8: 2228 if ((opc3 & 0x1) == 0) { 2229 if (single) { 2230 return decodeVfpRegRegRegOp<VdivS>( 2231 machInst, vd, vn, vm, false); 2232 } else { 2233 return decodeVfpRegRegRegOp<VdivD>( 2234 machInst, vd, vn, vm, true); 2235 } 2236 } 2237 break; 2238 case 0xb: 2239 if ((opc3 & 0x1) == 0) { 2240 const uint32_t baseImm = 2241 bits(machInst, 3, 0) | (bits(machInst, 19, 16) << 4); 2242 if (single) { 2243 uint32_t imm = vfp_modified_imm(baseImm, false); 2244 return decodeVfpRegImmOp<VmovImmS>( 2245 machInst, vd, imm, false); 2246 } else { 2247 uint64_t imm = vfp_modified_imm(baseImm, true); 2248 return decodeVfpRegImmOp<VmovImmD>( 2249 machInst, vd, imm, true); 2250 } 2251 } 2252 switch (opc2) { 2253 case 0x0: 2254 if (opc3 == 1) { 2255 if (single) { 2256 return decodeVfpRegRegOp<VmovRegS>( 2257 machInst, vd, vm, false); 2258 } else { 2259 return decodeVfpRegRegOp<VmovRegD>( 2260 machInst, vd, vm, true); 2261 } 2262 } else { 2263 if (single) { 2264 return decodeVfpRegRegOp<VabsS>( 2265 machInst, vd, vm, false); 2266 } else { 2267 return decodeVfpRegRegOp<VabsD>( 2268 machInst, vd, vm, true); 2269 } 2270 } 2271 case 0x1: 2272 if (opc3 == 1) { 2273 if (single) { 2274 return decodeVfpRegRegOp<VnegS>( 2275 machInst, vd, vm, false); 2276 } else { 2277 return decodeVfpRegRegOp<VnegD>( 2278 machInst, vd, vm, true); 2279 } 2280 } else { 2281 if (single) { 2282 return decodeVfpRegRegOp<VsqrtS>( 2283 machInst, vd, vm, false); 2284 } else { 2285 return decodeVfpRegRegOp<VsqrtD>( 2286 machInst, vd, vm, true); 2287 } 2288 } 2289 case 0x2: 2290 case 0x3: 2291 { 2292 const bool toHalf = bits(machInst, 16); 2293 const bool top = bits(machInst, 7); 2294 if (top) { 2295 if (toHalf) { 2296 return new VcvtFpSFpHT(machInst, vd, vm); 2297 } else { 2298 return new VcvtFpHTFpS(machInst, vd, vm); 2299 } 2300 } else { 2301 if (toHalf) { 2302 return new VcvtFpSFpHB(machInst, vd, vm); 2303 } else { 2304 return new VcvtFpHBFpS(machInst, vd, vm); 2305 } 2306 } 2307 } 2308 case 0x4: 2309 if (single) { 2310 if (e) { 2311 return new VcmpeS(machInst, vd, vm); 2312 } else { 2313 return new VcmpS(machInst, vd, vm); 2314 } 2315 } else { 2316 if (e) { 2317 return new VcmpeD(machInst, vd, vm); 2318 } else { 2319 return new VcmpD(machInst, vd, vm); 2320 } 2321 } 2322 case 0x5: 2323 if (single) { 2324 if (e) { 2325 return new VcmpeZeroS(machInst, vd, 0); 2326 } else { 2327 return new VcmpZeroS(machInst, vd, 0); 2328 } 2329 } else { 2330 if (e) { 2331 return new VcmpeZeroD(machInst, vd, 0); 2332 } else { 2333 return new VcmpZeroD(machInst, vd, 0); 2334 } 2335 } 2336 case 0x7: 2337 if (opc3 == 0x3) { 2338 if (single) { 2339 vd = (IntRegIndex)((bits(machInst, 22) << 5) | 2340 (bits(machInst, 15, 12) << 1)); 2341 return new VcvtFpSFpD(machInst, vd, vm); 2342 } else { 2343 vd = (IntRegIndex)(bits(machInst, 22) | 2344 (bits(machInst, 15, 12) << 1)); 2345 return new VcvtFpDFpS(machInst, vd, vm); 2346 } 2347 } 2348 break; 2349 case 0x8: 2350 if (bits(machInst, 7) == 0) { 2351 if (single) { 2352 return new VcvtUIntFpS(machInst, vd, vm); 2353 } else { 2354 vm = (IntRegIndex)(bits(machInst, 5) | 2355 (bits(machInst, 3, 0) << 1)); 2356 return new VcvtUIntFpD(machInst, vd, vm); 2357 } 2358 } else { 2359 if (single) { 2360 return new VcvtSIntFpS(machInst, vd, vm); 2361 } else { 2362 vm = (IntRegIndex)(bits(machInst, 5) | 2363 (bits(machInst, 3, 0) << 1)); 2364 return new VcvtSIntFpD(machInst, vd, vm); 2365 } 2366 } 2367 case 0xa: 2368 { 2369 const bool half = (bits(machInst, 7) == 0); 2370 const uint32_t imm = bits(machInst, 5) | 2371 (bits(machInst, 3, 0) << 1); 2372 const uint32_t size = 2373 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2374 if (single) { 2375 if (half) { 2376 return new VcvtSHFixedFpS(machInst, vd, vd, size); 2377 } else { 2378 return new VcvtSFixedFpS(machInst, vd, vd, size); 2379 } 2380 } else { 2381 if (half) { 2382 return new VcvtSHFixedFpD(machInst, vd, vd, size); 2383 } else { 2384 return new VcvtSFixedFpD(machInst, vd, vd, size); 2385 } 2386 } 2387 } 2388 case 0xb: 2389 { 2390 const bool half = (bits(machInst, 7) == 0); 2391 const uint32_t imm = bits(machInst, 5) | 2392 (bits(machInst, 3, 0) << 1); 2393 const uint32_t size = 2394 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2395 if (single) { 2396 if (half) { 2397 return new VcvtUHFixedFpS(machInst, vd, vd, size); 2398 } else { 2399 return new VcvtUFixedFpS(machInst, vd, vd, size); 2400 } 2401 } else { 2402 if (half) { 2403 return new VcvtUHFixedFpD(machInst, vd, vd, size); 2404 } else { 2405 return new VcvtUFixedFpD(machInst, vd, vd, size); 2406 } 2407 } 2408 } 2409 case 0xc: 2410 if (bits(machInst, 7) == 0) { 2411 if (single) { 2412 return new VcvtFpUIntSR(machInst, vd, vm); 2413 } else { 2414 vd = (IntRegIndex)(bits(machInst, 22) | 2415 (bits(machInst, 15, 12) << 1)); 2416 return new VcvtFpUIntDR(machInst, vd, vm); 2417 } 2418 } else { 2419 if (single) { 2420 return new VcvtFpUIntS(machInst, vd, vm); 2421 } else { 2422 vd = (IntRegIndex)(bits(machInst, 22) | 2423 (bits(machInst, 15, 12) << 1)); 2424 return new VcvtFpUIntD(machInst, vd, vm); 2425 } 2426 } 2427 case 0xd: 2428 if (bits(machInst, 7) == 0) { 2429 if (single) { 2430 return new VcvtFpSIntSR(machInst, vd, vm); 2431 } else { 2432 vd = (IntRegIndex)(bits(machInst, 22) | 2433 (bits(machInst, 15, 12) << 1)); 2434 return new VcvtFpSIntDR(machInst, vd, vm); 2435 } 2436 } else { 2437 if (single) { 2438 return new VcvtFpSIntS(machInst, vd, vm); 2439 } else { 2440 vd = (IntRegIndex)(bits(machInst, 22) | 2441 (bits(machInst, 15, 12) << 1)); 2442 return new VcvtFpSIntD(machInst, vd, vm); 2443 } 2444 } 2445 case 0xe: 2446 { 2447 const bool half = (bits(machInst, 7) == 0); 2448 const uint32_t imm = bits(machInst, 5) | 2449 (bits(machInst, 3, 0) << 1); 2450 const uint32_t size = 2451 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2452 if (single) { 2453 if (half) { 2454 return new VcvtFpSHFixedS(machInst, vd, vd, size); 2455 } else { 2456 return new VcvtFpSFixedS(machInst, vd, vd, size); 2457 } 2458 } else { 2459 if (half) { 2460 return new VcvtFpSHFixedD(machInst, vd, vd, size); 2461 } else { 2462 return new VcvtFpSFixedD(machInst, vd, vd, size); 2463 } 2464 } 2465 } 2466 case 0xf: 2467 { 2468 const bool half = (bits(machInst, 7) == 0); 2469 const uint32_t imm = bits(machInst, 5) | 2470 (bits(machInst, 3, 0) << 1); 2471 const uint32_t size = 2472 (bits(machInst, 7) == 0 ? 16 : 32) - imm; 2473 if (single) { 2474 if (half) { 2475 return new VcvtFpUHFixedS(machInst, vd, vd, size); 2476 } else { 2477 return new VcvtFpUFixedS(machInst, vd, vd, size); 2478 } 2479 } else { 2480 if (half) { 2481 return new VcvtFpUHFixedD(machInst, vd, vd, size); 2482 } else { 2483 return new VcvtFpUFixedD(machInst, vd, vd, size); 2484 } 2485 } 2486 } 2487 } 2488 break; 2489 } 2490 return new Unknown(machInst); 2491 } 2492 ''' 2493}}; 2494 2495def format VfpData() {{ 2496 decode_block = ''' 2497 return decodeVfpData(machInst); 2498 ''' 2499}}; |