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