aarch64.isa revision 12673:b862f22eeed9
1// Copyright (c) 2011-2018 ARM Limited 2// All rights reserved 3// 4// The license below extends only to copyright in the software and shall 5// not be construed as granting a license to any other intellectual 6// property including but not limited to intellectual property relating 7// to a hardware implementation of the functionality of the software 8// licensed hereunder. You may use the software subject to the license 9// terms below provided that you ensure that this notice is replicated 10// unmodified and in its entirety in all distributions of the software, 11// modified or unmodified, in source code or in binary form. 12// 13// Redistribution and use in source and binary forms, with or without 14// modification, are permitted provided that the following conditions are 15// met: redistributions of source code must retain the above copyright 16// notice, this list of conditions and the following disclaimer; 17// redistributions in binary form must reproduce the above copyright 18// notice, this list of conditions and the following disclaimer in the 19// documentation and/or other materials provided with the distribution; 20// neither the name of the copyright holders nor the names of its 21// contributors may be used to endorse or promote products derived from 22// this software without specific prior written permission. 23// 24// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 27// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 28// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 29// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 30// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 31// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 32// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 34// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35// 36// Authors: Gabe Black 37// Thomas Grocutt 38// Mbou Eyole 39// Giacomo Gabrielli 40 41output header {{ 42namespace Aarch64 43{ 44 StaticInstPtr decodeDataProcImm(ExtMachInst machInst); 45 StaticInstPtr decodeBranchExcSys(ExtMachInst machInst); 46 StaticInstPtr decodeLoadsStores(ExtMachInst machInst); 47 StaticInstPtr decodeDataProcReg(ExtMachInst machInst); 48 49 template <typename DecoderFeatures> 50 StaticInstPtr decodeFpAdvSIMD(ExtMachInst machInst); 51 StaticInstPtr decodeFp(ExtMachInst machInst); 52 template <typename DecoderFeatures> 53 StaticInstPtr decodeAdvSIMD(ExtMachInst machInst); 54 StaticInstPtr decodeAdvSIMDScalar(ExtMachInst machInst); 55 56 StaticInstPtr decodeGem5Ops(ExtMachInst machInst); 57} 58}}; 59 60output decoder {{ 61namespace Aarch64 62{ 63 StaticInstPtr 64 decodeDataProcImm(ExtMachInst machInst) 65 { 66 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 67 IntRegIndex rdsp = makeSP(rd); 68 IntRegIndex rdzr = makeZero(rd); 69 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 70 IntRegIndex rnsp = makeSP(rn); 71 72 uint8_t opc = bits(machInst, 30, 29); 73 bool sf = bits(machInst, 31); 74 bool n = bits(machInst, 22); 75 uint8_t immr = bits(machInst, 21, 16); 76 uint8_t imms = bits(machInst, 15, 10); 77 switch (bits(machInst, 25, 23)) { 78 case 0x0: 79 case 0x1: 80 { 81 uint64_t immlo = bits(machInst, 30, 29); 82 uint64_t immhi = bits(machInst, 23, 5); 83 uint64_t imm = (immlo << 0) | (immhi << 2); 84 if (bits(machInst, 31) == 0) 85 return new AdrXImm(machInst, rdzr, INTREG_ZERO, sext<21>(imm)); 86 else 87 return new AdrpXImm(machInst, rdzr, INTREG_ZERO, 88 sext<33>(imm << 12)); 89 } 90 case 0x2: 91 case 0x3: 92 { 93 uint32_t imm12 = bits(machInst, 21, 10); 94 uint8_t shift = bits(machInst, 23, 22); 95 uint32_t imm; 96 if (shift == 0x0) 97 imm = imm12 << 0; 98 else if (shift == 0x1) 99 imm = imm12 << 12; 100 else 101 return new Unknown64(machInst); 102 switch (opc) { 103 case 0x0: 104 return new AddXImm(machInst, rdsp, rnsp, imm); 105 case 0x1: 106 return new AddXImmCc(machInst, rdzr, rnsp, imm); 107 case 0x2: 108 return new SubXImm(machInst, rdsp, rnsp, imm); 109 case 0x3: 110 return new SubXImmCc(machInst, rdzr, rnsp, imm); 111 default: 112 M5_UNREACHABLE; 113 } 114 } 115 case 0x4: 116 { 117 if (!sf && n) 118 return new Unknown64(machInst); 119 // len = MSB(n:NOT(imms)), len < 1 is undefined. 120 uint8_t len = 0; 121 if (n) { 122 len = 6; 123 } else if (imms == 0x3f || imms == 0x3e) { 124 return new Unknown64(machInst); 125 } else { 126 len = findMsbSet(imms ^ 0x3f); 127 } 128 // Generate r, s, and size. 129 uint64_t r = bits(immr, len - 1, 0); 130 uint64_t s = bits(imms, len - 1, 0); 131 uint8_t size = 1 << len; 132 if (s == size - 1) 133 return new Unknown64(machInst); 134 // Generate the pattern with s 1s, rotated by r, with size bits. 135 uint64_t pattern = mask(s + 1); 136 if (r) { 137 pattern = (pattern >> r) | (pattern << (size - r)); 138 pattern &= mask(size); 139 } 140 uint8_t width = sf ? 64 : 32; 141 // Replicate that to fill up the immediate. 142 for (unsigned i = 1; i < (width / size); i *= 2) 143 pattern |= (pattern << (i * size)); 144 uint64_t imm = pattern; 145 146 switch (opc) { 147 case 0x0: 148 return new AndXImm(machInst, rdsp, rn, imm); 149 case 0x1: 150 return new OrrXImm(machInst, rdsp, rn, imm); 151 case 0x2: 152 return new EorXImm(machInst, rdsp, rn, imm); 153 case 0x3: 154 return new AndXImmCc(machInst, rdzr, rn, imm); 155 default: 156 M5_UNREACHABLE; 157 } 158 } 159 case 0x5: 160 { 161 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 162 IntRegIndex rdzr = makeZero(rd); 163 uint32_t imm16 = bits(machInst, 20, 5); 164 uint32_t hw = bits(machInst, 22, 21); 165 switch (opc) { 166 case 0x0: 167 return new Movn(machInst, rdzr, imm16, hw * 16); 168 case 0x1: 169 return new Unknown64(machInst); 170 case 0x2: 171 return new Movz(machInst, rdzr, imm16, hw * 16); 172 case 0x3: 173 return new Movk(machInst, rdzr, imm16, hw * 16); 174 default: 175 M5_UNREACHABLE; 176 } 177 } 178 case 0x6: 179 if ((sf != n) || (!sf && (bits(immr, 5) || bits(imms, 5)))) 180 return new Unknown64(machInst); 181 switch (opc) { 182 case 0x0: 183 return new Sbfm64(machInst, rdzr, rn, immr, imms); 184 case 0x1: 185 return new Bfm64(machInst, rdzr, rn, immr, imms); 186 case 0x2: 187 return new Ubfm64(machInst, rdzr, rn, immr, imms); 188 case 0x3: 189 return new Unknown64(machInst); 190 default: 191 M5_UNREACHABLE; 192 } 193 case 0x7: 194 { 195 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 196 if (opc || bits(machInst, 21)) 197 return new Unknown64(machInst); 198 else 199 return new Extr64(machInst, rdzr, rn, rm, imms); 200 } 201 } 202 return new FailUnimplemented("Unhandled Case8", machInst); 203 } 204} 205}}; 206 207output decoder {{ 208namespace Aarch64 209{ 210 StaticInstPtr 211 decodeBranchExcSys(ExtMachInst machInst) 212 { 213 switch (bits(machInst, 30, 29)) { 214 case 0x0: 215 { 216 int64_t imm = sext<26>(bits(machInst, 25, 0)) << 2; 217 if (bits(machInst, 31) == 0) 218 return new B64(machInst, imm); 219 else 220 return new Bl64(machInst, imm); 221 } 222 case 0x1: 223 { 224 IntRegIndex rt = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 225 if (bits(machInst, 25) == 0) { 226 int64_t imm = sext<19>(bits(machInst, 23, 5)) << 2; 227 if (bits(machInst, 24) == 0) 228 return new Cbz64(machInst, imm, rt); 229 else 230 return new Cbnz64(machInst, imm, rt); 231 } else { 232 uint64_t bitmask = 0x1; 233 bitmask <<= bits(machInst, 23, 19); 234 int64_t imm = sext<14>(bits(machInst, 18, 5)) << 2; 235 if (bits(machInst, 31)) 236 bitmask <<= 32; 237 if (bits(machInst, 24) == 0) 238 return new Tbz64(machInst, bitmask, imm, rt); 239 else 240 return new Tbnz64(machInst, bitmask, imm, rt); 241 } 242 } 243 case 0x2: 244 // bit 30:26=10101 245 if (bits(machInst, 31) == 0) { 246 if (bits(machInst, 25, 24) || bits(machInst, 4)) 247 return new Unknown64(machInst); 248 int64_t imm = sext<19>(bits(machInst, 23, 5)) << 2; 249 ConditionCode condCode = 250 (ConditionCode)(uint8_t)(bits(machInst, 3, 0)); 251 return new BCond64(machInst, imm, condCode); 252 } else if (bits(machInst, 25, 24) == 0x0) { 253 254 if (bits(machInst, 4, 2)) 255 return new Unknown64(machInst); 256 257 auto imm16 = bits(machInst, 20, 5); 258 uint8_t decVal = (bits(machInst, 1, 0) << 0) | 259 (bits(machInst, 23, 21) << 2); 260 261 switch (decVal) { 262 case 0x01: 263 return new Svc64(machInst, imm16); 264 case 0x02: 265 return new Hvc64(machInst, imm16); 266 case 0x03: 267 return new Smc64(machInst, imm16); 268 case 0x04: 269 return new Brk64(machInst, imm16); 270 case 0x08: 271 return new Hlt64(machInst, imm16); 272 case 0x15: 273 return new FailUnimplemented("dcps1", machInst); 274 case 0x16: 275 return new FailUnimplemented("dcps2", machInst); 276 case 0x17: 277 return new FailUnimplemented("dcps3", machInst); 278 default: 279 return new Unknown64(machInst); 280 } 281 } else if (bits(machInst, 25, 22) == 0x4) { 282 // bit 31:22=1101010100 283 bool l = bits(machInst, 21); 284 uint8_t op0 = bits(machInst, 20, 19); 285 uint8_t op1 = bits(machInst, 18, 16); 286 uint8_t crn = bits(machInst, 15, 12); 287 uint8_t crm = bits(machInst, 11, 8); 288 uint8_t op2 = bits(machInst, 7, 5); 289 IntRegIndex rt = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 290 switch (op0) { 291 case 0x0: 292 if (rt != 0x1f || l) 293 return new Unknown64(machInst); 294 if (crn == 0x2 && op1 == 0x3) { 295 switch (op2) { 296 case 0x0: 297 return new NopInst(machInst); 298 case 0x1: 299 return new YieldInst(machInst); 300 case 0x2: 301 return new WfeInst(machInst); 302 case 0x3: 303 return new WfiInst(machInst); 304 case 0x4: 305 return new SevInst(machInst); 306 case 0x5: 307 return new SevlInst(machInst); 308 default: 309 return new Unknown64(machInst); 310 } 311 } else if (crn == 0x3 && op1 == 0x3) { 312 switch (op2) { 313 case 0x2: 314 return new Clrex64(machInst); 315 case 0x4: 316 return new Dsb64(machInst); 317 case 0x5: 318 return new Dmb64(machInst); 319 case 0x6: 320 return new Isb64(machInst); 321 default: 322 return new Unknown64(machInst); 323 } 324 } else if (crn == 0x4) { 325 // MSR immediate 326 switch (op1 << 3 | op2) { 327 case 0x5: 328 // SP 329 return new MsrSP64(machInst, 330 (IntRegIndex) MISCREG_SPSEL, 331 INTREG_ZERO, 332 crm & 0x1); 333 case 0x1e: 334 // DAIFSet 335 return new MsrDAIFSet64( 336 machInst, 337 (IntRegIndex) MISCREG_DAIF, 338 INTREG_ZERO, 339 crm); 340 case 0x1f: 341 // DAIFClr 342 return new MsrDAIFClr64( 343 machInst, 344 (IntRegIndex) MISCREG_DAIF, 345 INTREG_ZERO, 346 crm); 347 default: 348 return new Unknown64(machInst); 349 } 350 } else { 351 return new Unknown64(machInst); 352 } 353 break; 354 case 0x1: 355 case 0x2: 356 case 0x3: 357 { 358 // bit 31:22=1101010100, 20:19=11 359 bool read = l; 360 MiscRegIndex miscReg = 361 decodeAArch64SysReg(op0, op1, crn, crm, op2); 362 if (read) { 363 if ((miscReg == MISCREG_DC_CIVAC_Xt) || 364 (miscReg == MISCREG_DC_CVAC_Xt) || 365 (miscReg == MISCREG_DC_IVAC_Xt) || 366 (miscReg == MISCREG_DC_ZVA_Xt)) { 367 return new Unknown64(machInst); 368 } 369 } 370 // Check for invalid registers 371 if (miscReg == MISCREG_UNKNOWN) { 372 auto full_mnemonic = 373 csprintf("%s op0:%d op1:%d crn:%d crm:%d op2:%d", 374 read ? "mrs" : "msr", 375 op0, op1, crn, crm, op2); 376 377 return new FailUnimplemented(read ? "mrs" : "msr", 378 machInst, full_mnemonic); 379 380 } else if (miscRegInfo[miscReg][MISCREG_IMPLEMENTED]) { 381 if (miscReg == MISCREG_NZCV) { 382 if (read) 383 return new MrsNZCV64(machInst, rt, (IntRegIndex) miscReg); 384 else 385 return new MsrNZCV64(machInst, (IntRegIndex) miscReg, rt); 386 } 387 uint32_t iss = msrMrs64IssBuild(read, op0, op1, crn, crm, op2, rt); 388 if (read) { 389 StaticInstPtr si = new Mrs64(machInst, rt, miscReg, iss); 390 if (miscRegInfo[miscReg][MISCREG_UNVERIFIABLE]) 391 si->setFlag(StaticInst::IsUnverifiable); 392 return si; 393 } else { 394 switch (miscReg) { 395 case MISCREG_DC_ZVA_Xt: 396 return new Dczva(machInst, rt, miscReg, iss); 397 case MISCREG_DC_CVAU_Xt: 398 return new Dccvau(machInst, rt, miscReg, iss); 399 case MISCREG_DC_CVAC_Xt: 400 return new Dccvac(machInst, rt, miscReg, iss); 401 case MISCREG_DC_CIVAC_Xt: 402 return new Dccivac(machInst, rt, miscReg, iss); 403 case MISCREG_DC_IVAC_Xt: 404 return new Dcivac(machInst, rt, miscReg, iss); 405 default: 406 return new Msr64(machInst, miscReg, rt, iss); 407 } 408 } 409 } else if (miscRegInfo[miscReg][MISCREG_WARN_NOT_FAIL]) { 410 std::string full_mnem = csprintf("%s %s", 411 read ? "mrs" : "msr", miscRegName[miscReg]); 412 return new WarnUnimplemented(read ? "mrs" : "msr", 413 machInst, full_mnem); 414 } else { 415 return new FailUnimplemented(read ? "mrs" : "msr", 416 machInst, 417 csprintf("%s %s", 418 read ? "mrs" : "msr", 419 miscRegName[miscReg])); 420 } 421 } 422 break; 423 default: 424 M5_UNREACHABLE; 425 } 426 } else if (bits(machInst, 25) == 0x1) { 427 uint8_t opc = bits(machInst, 24, 21); 428 uint8_t op2 = bits(machInst, 20, 16); 429 uint8_t op3 = bits(machInst, 15, 10); 430 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 431 uint8_t op4 = bits(machInst, 4, 0); 432 if (op2 != 0x1f || op3 != 0x0 || op4 != 0x0) 433 return new Unknown64(machInst); 434 switch (opc) { 435 case 0x0: 436 return new Br64(machInst, rn); 437 case 0x1: 438 return new Blr64(machInst, rn); 439 case 0x2: 440 return new Ret64(machInst, rn); 441 case 0x4: 442 if (rn != 0x1f) 443 return new Unknown64(machInst); 444 return new Eret64(machInst); 445 case 0x5: 446 if (rn != 0x1f) 447 return new Unknown64(machInst); 448 return new FailUnimplemented("dret", machInst); 449 default: 450 return new Unknown64(machInst); 451 } 452 } 453 M5_FALLTHROUGH; 454 default: 455 return new Unknown64(machInst); 456 } 457 return new FailUnimplemented("Unhandled Case7", machInst); 458 } 459} 460}}; 461 462output decoder {{ 463namespace Aarch64 464{ 465 StaticInstPtr 466 decodeLoadsStores(ExtMachInst machInst) 467 { 468 // bit 27,25=10 469 switch (bits(machInst, 29, 28)) { 470 case 0x0: 471 if (bits(machInst, 26) == 0) { 472 if (bits(machInst, 24) != 0) 473 return new Unknown64(machInst); 474 IntRegIndex rt = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 475 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 476 IntRegIndex rnsp = makeSP(rn); 477 IntRegIndex rt2 = (IntRegIndex)(uint8_t)bits(machInst, 14, 10); 478 IntRegIndex rs = (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 479 uint8_t opc = (bits(machInst, 15) << 0) | 480 (bits(machInst, 23, 21) << 1); 481 uint8_t size = bits(machInst, 31, 30); 482 switch (opc) { 483 case 0x0: 484 switch (size) { 485 case 0x0: 486 return new STXRB64(machInst, rt, rnsp, rs); 487 case 0x1: 488 return new STXRH64(machInst, rt, rnsp, rs); 489 case 0x2: 490 return new STXRW64(machInst, rt, rnsp, rs); 491 case 0x3: 492 return new STXRX64(machInst, rt, rnsp, rs); 493 default: 494 M5_UNREACHABLE; 495 } 496 case 0x1: 497 switch (size) { 498 case 0x0: 499 return new STLXRB64(machInst, rt, rnsp, rs); 500 case 0x1: 501 return new STLXRH64(machInst, rt, rnsp, rs); 502 case 0x2: 503 return new STLXRW64(machInst, rt, rnsp, rs); 504 case 0x3: 505 return new STLXRX64(machInst, rt, rnsp, rs); 506 default: 507 M5_UNREACHABLE; 508 } 509 case 0x2: 510 switch (size) { 511 case 0x0: 512 case 0x1: 513 return new Unknown64(machInst); 514 case 0x2: 515 return new STXPW64(machInst, rs, rt, rt2, rnsp); 516 case 0x3: 517 return new STXPX64(machInst, rs, rt, rt2, rnsp); 518 default: 519 M5_UNREACHABLE; 520 } 521 522 case 0x3: 523 switch (size) { 524 case 0x0: 525 case 0x1: 526 return new Unknown64(machInst); 527 case 0x2: 528 return new STLXPW64(machInst, rs, rt, rt2, rnsp); 529 case 0x3: 530 return new STLXPX64(machInst, rs, rt, rt2, rnsp); 531 default: 532 M5_UNREACHABLE; 533 } 534 535 case 0x4: 536 switch (size) { 537 case 0x0: 538 return new LDXRB64(machInst, rt, rnsp, rs); 539 case 0x1: 540 return new LDXRH64(machInst, rt, rnsp, rs); 541 case 0x2: 542 return new LDXRW64(machInst, rt, rnsp, rs); 543 case 0x3: 544 return new LDXRX64(machInst, rt, rnsp, rs); 545 default: 546 M5_UNREACHABLE; 547 } 548 case 0x5: 549 switch (size) { 550 case 0x0: 551 return new LDAXRB64(machInst, rt, rnsp, rs); 552 case 0x1: 553 return new LDAXRH64(machInst, rt, rnsp, rs); 554 case 0x2: 555 return new LDAXRW64(machInst, rt, rnsp, rs); 556 case 0x3: 557 return new LDAXRX64(machInst, rt, rnsp, rs); 558 default: 559 M5_UNREACHABLE; 560 } 561 case 0x6: 562 switch (size) { 563 case 0x0: 564 case 0x1: 565 return new Unknown64(machInst); 566 case 0x2: 567 return new LDXPW64(machInst, rt, rt2, rnsp); 568 case 0x3: 569 return new LDXPX64(machInst, rt, rt2, rnsp); 570 default: 571 M5_UNREACHABLE; 572 } 573 574 case 0x7: 575 switch (size) { 576 case 0x0: 577 case 0x1: 578 return new Unknown64(machInst); 579 case 0x2: 580 return new LDAXPW64(machInst, rt, rt2, rnsp); 581 case 0x3: 582 return new LDAXPX64(machInst, rt, rt2, rnsp); 583 default: 584 M5_UNREACHABLE; 585 } 586 587 case 0x9: 588 switch (size) { 589 case 0x0: 590 return new STLRB64(machInst, rt, rnsp); 591 case 0x1: 592 return new STLRH64(machInst, rt, rnsp); 593 case 0x2: 594 return new STLRW64(machInst, rt, rnsp); 595 case 0x3: 596 return new STLRX64(machInst, rt, rnsp); 597 default: 598 M5_UNREACHABLE; 599 } 600 case 0xd: 601 switch (size) { 602 case 0x0: 603 return new LDARB64(machInst, rt, rnsp); 604 case 0x1: 605 return new LDARH64(machInst, rt, rnsp); 606 case 0x2: 607 return new LDARW64(machInst, rt, rnsp); 608 case 0x3: 609 return new LDARX64(machInst, rt, rnsp); 610 default: 611 M5_UNREACHABLE; 612 } 613 default: 614 return new Unknown64(machInst); 615 } 616 } else if (bits(machInst, 31)) { 617 return new Unknown64(machInst); 618 } else { 619 return decodeNeonMem(machInst); 620 } 621 case 0x1: 622 { 623 if (bits(machInst, 24) != 0) 624 return new Unknown64(machInst); 625 uint8_t switchVal = (bits(machInst, 26) << 0) | 626 (bits(machInst, 31, 30) << 1); 627 int64_t imm = sext<19>(bits(machInst, 23, 5)) << 2; 628 IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 629 switch (switchVal) { 630 case 0x0: 631 return new LDRWL64_LIT(machInst, rt, imm); 632 case 0x1: 633 return new LDRSFP64_LIT(machInst, rt, imm); 634 case 0x2: 635 return new LDRXL64_LIT(machInst, rt, imm); 636 case 0x3: 637 return new LDRDFP64_LIT(machInst, rt, imm); 638 case 0x4: 639 return new LDRSWL64_LIT(machInst, rt, imm); 640 case 0x5: 641 return new BigFpMemLit("ldr", machInst, rt, imm); 642 case 0x6: 643 return new PRFM64_LIT(machInst, rt, imm); 644 default: 645 return new Unknown64(machInst); 646 } 647 } 648 case 0x2: 649 { 650 uint8_t opc = bits(machInst, 31, 30); 651 if (opc >= 3) 652 return new Unknown64(machInst); 653 uint32_t size = 0; 654 bool fp = bits(machInst, 26); 655 bool load = bits(machInst, 22); 656 if (fp) { 657 size = 4 << opc; 658 } else { 659 if ((opc == 1) && !load) 660 return new Unknown64(machInst); 661 size = (opc == 0 || opc == 1) ? 4 : 8; 662 } 663 uint8_t type = bits(machInst, 24, 23); 664 int64_t imm = sext<7>(bits(machInst, 21, 15)) * size; 665 666 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 667 IntRegIndex rt = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 668 IntRegIndex rt2 = (IntRegIndex)(uint8_t)bits(machInst, 14, 10); 669 670 bool noAlloc = (type == 0); 671 bool signExt = !noAlloc && !fp && opc == 1; 672 PairMemOp::AddrMode mode; 673 const char *mnemonic = NULL; 674 switch (type) { 675 case 0x0: 676 case 0x2: 677 mode = PairMemOp::AddrMd_Offset; 678 break; 679 case 0x1: 680 mode = PairMemOp::AddrMd_PostIndex; 681 break; 682 case 0x3: 683 mode = PairMemOp::AddrMd_PreIndex; 684 break; 685 default: 686 return new Unknown64(machInst); 687 } 688 if (load) { 689 if (noAlloc) 690 mnemonic = "ldnp"; 691 else if (signExt) 692 mnemonic = "ldpsw"; 693 else 694 mnemonic = "ldp"; 695 } else { 696 if (noAlloc) 697 mnemonic = "stnp"; 698 else 699 mnemonic = "stp"; 700 } 701 702 return new LdpStp(mnemonic, machInst, size, fp, load, noAlloc, 703 signExt, false, false, imm, mode, rn, rt, rt2); 704 } 705 // bit 29:27=111, 25=0 706 case 0x3: 707 { 708 uint8_t switchVal = (bits(machInst, 23, 22) << 0) | 709 (bits(machInst, 26) << 2) | 710 (bits(machInst, 31, 30) << 3); 711 if (bits(machInst, 24) == 1) { 712 uint64_t imm12 = bits(machInst, 21, 10); 713 IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 714 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 715 IntRegIndex rnsp = makeSP(rn); 716 switch (switchVal) { 717 case 0x00: 718 return new STRB64_IMM(machInst, rt, rnsp, imm12); 719 case 0x01: 720 return new LDRB64_IMM(machInst, rt, rnsp, imm12); 721 case 0x02: 722 return new LDRSBX64_IMM(machInst, rt, rnsp, imm12); 723 case 0x03: 724 return new LDRSBW64_IMM(machInst, rt, rnsp, imm12); 725 case 0x04: 726 return new STRBFP64_IMM(machInst, rt, rnsp, imm12); 727 case 0x05: 728 return new LDRBFP64_IMM(machInst, rt, rnsp, imm12); 729 case 0x06: 730 return new BigFpMemImm("str", machInst, false, 731 rt, rnsp, imm12 << 4); 732 case 0x07: 733 return new BigFpMemImm("ldr", machInst, true, 734 rt, rnsp, imm12 << 4); 735 case 0x08: 736 return new STRH64_IMM(machInst, rt, rnsp, imm12 << 1); 737 case 0x09: 738 return new LDRH64_IMM(machInst, rt, rnsp, imm12 << 1); 739 case 0x0a: 740 return new LDRSHX64_IMM(machInst, rt, rnsp, imm12 << 1); 741 case 0x0b: 742 return new LDRSHW64_IMM(machInst, rt, rnsp, imm12 << 1); 743 case 0x0c: 744 return new STRHFP64_IMM(machInst, rt, rnsp, imm12 << 1); 745 case 0x0d: 746 return new LDRHFP64_IMM(machInst, rt, rnsp, imm12 << 1); 747 case 0x10: 748 return new STRW64_IMM(machInst, rt, rnsp, imm12 << 2); 749 case 0x11: 750 return new LDRW64_IMM(machInst, rt, rnsp, imm12 << 2); 751 case 0x12: 752 return new LDRSW64_IMM(machInst, rt, rnsp, imm12 << 2); 753 case 0x14: 754 return new STRSFP64_IMM(machInst, rt, rnsp, imm12 << 2); 755 case 0x15: 756 return new LDRSFP64_IMM(machInst, rt, rnsp, imm12 << 2); 757 case 0x18: 758 return new STRX64_IMM(machInst, rt, rnsp, imm12 << 3); 759 case 0x19: 760 return new LDRX64_IMM(machInst, rt, rnsp, imm12 << 3); 761 case 0x1a: 762 return new PRFM64_IMM(machInst, rt, rnsp, imm12 << 3); 763 case 0x1c: 764 return new STRDFP64_IMM(machInst, rt, rnsp, imm12 << 3); 765 case 0x1d: 766 return new LDRDFP64_IMM(machInst, rt, rnsp, imm12 << 3); 767 default: 768 return new Unknown64(machInst); 769 } 770 } else if (bits(machInst, 21) == 1) { 771 if (bits(machInst, 11, 10) != 0x2) 772 return new Unknown64(machInst); 773 if (!bits(machInst, 14)) 774 return new Unknown64(machInst); 775 IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 776 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 777 IntRegIndex rnsp = makeSP(rn); 778 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 20, 16); 779 ArmExtendType type = 780 (ArmExtendType)(uint32_t)bits(machInst, 15, 13); 781 uint8_t s = bits(machInst, 12); 782 switch (switchVal) { 783 case 0x00: 784 return new STRB64_REG(machInst, rt, rnsp, rm, type, 0); 785 case 0x01: 786 return new LDRB64_REG(machInst, rt, rnsp, rm, type, 0); 787 case 0x02: 788 return new LDRSBX64_REG(machInst, rt, rnsp, rm, type, 0); 789 case 0x03: 790 return new LDRSBW64_REG(machInst, rt, rnsp, rm, type, 0); 791 case 0x04: 792 return new STRBFP64_REG(machInst, rt, rnsp, rm, type, 0); 793 case 0x05: 794 return new LDRBFP64_REG(machInst, rt, rnsp, rm, type, 0); 795 case 0x6: 796 return new BigFpMemReg("str", machInst, false, 797 rt, rnsp, rm, type, s * 4); 798 case 0x7: 799 return new BigFpMemReg("ldr", machInst, true, 800 rt, rnsp, rm, type, s * 4); 801 case 0x08: 802 return new STRH64_REG(machInst, rt, rnsp, rm, type, s); 803 case 0x09: 804 return new LDRH64_REG(machInst, rt, rnsp, rm, type, s); 805 case 0x0a: 806 return new LDRSHX64_REG(machInst, rt, rnsp, rm, type, s); 807 case 0x0b: 808 return new LDRSHW64_REG(machInst, rt, rnsp, rm, type, s); 809 case 0x0c: 810 return new STRHFP64_REG(machInst, rt, rnsp, rm, type, s); 811 case 0x0d: 812 return new LDRHFP64_REG(machInst, rt, rnsp, rm, type, s); 813 case 0x10: 814 return new STRW64_REG(machInst, rt, rnsp, rm, type, s * 2); 815 case 0x11: 816 return new LDRW64_REG(machInst, rt, rnsp, rm, type, s * 2); 817 case 0x12: 818 return new LDRSW64_REG(machInst, rt, rnsp, rm, type, s * 2); 819 case 0x14: 820 return new STRSFP64_REG(machInst, rt, rnsp, rm, type, s * 2); 821 case 0x15: 822 return new LDRSFP64_REG(machInst, rt, rnsp, rm, type, s * 2); 823 case 0x18: 824 return new STRX64_REG(machInst, rt, rnsp, rm, type, s * 3); 825 case 0x19: 826 return new LDRX64_REG(machInst, rt, rnsp, rm, type, s * 3); 827 case 0x1a: 828 return new PRFM64_REG(machInst, rt, rnsp, rm, type, s * 3); 829 case 0x1c: 830 return new STRDFP64_REG(machInst, rt, rnsp, rm, type, s * 3); 831 case 0x1d: 832 return new LDRDFP64_REG(machInst, rt, rnsp, rm, type, s * 3); 833 default: 834 return new Unknown64(machInst); 835 } 836 } else { 837 // bit 29:27=111, 25:24=00, 21=0 838 switch (bits(machInst, 11, 10)) { 839 case 0x0: 840 { 841 IntRegIndex rt = 842 (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 843 IntRegIndex rn = 844 (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 845 IntRegIndex rnsp = makeSP(rn); 846 uint64_t imm = sext<9>(bits(machInst, 20, 12)); 847 switch (switchVal) { 848 case 0x00: 849 return new STURB64_IMM(machInst, rt, rnsp, imm); 850 case 0x01: 851 return new LDURB64_IMM(machInst, rt, rnsp, imm); 852 case 0x02: 853 return new LDURSBX64_IMM(machInst, rt, rnsp, imm); 854 case 0x03: 855 return new LDURSBW64_IMM(machInst, rt, rnsp, imm); 856 case 0x04: 857 return new STURBFP64_IMM(machInst, rt, rnsp, imm); 858 case 0x05: 859 return new LDURBFP64_IMM(machInst, rt, rnsp, imm); 860 case 0x06: 861 return new BigFpMemImm("stur", machInst, false, 862 rt, rnsp, imm); 863 case 0x07: 864 return new BigFpMemImm("ldur", machInst, true, 865 rt, rnsp, imm); 866 case 0x08: 867 return new STURH64_IMM(machInst, rt, rnsp, imm); 868 case 0x09: 869 return new LDURH64_IMM(machInst, rt, rnsp, imm); 870 case 0x0a: 871 return new LDURSHX64_IMM(machInst, rt, rnsp, imm); 872 case 0x0b: 873 return new LDURSHW64_IMM(machInst, rt, rnsp, imm); 874 case 0x0c: 875 return new STURHFP64_IMM(machInst, rt, rnsp, imm); 876 case 0x0d: 877 return new LDURHFP64_IMM(machInst, rt, rnsp, imm); 878 case 0x10: 879 return new STURW64_IMM(machInst, rt, rnsp, imm); 880 case 0x11: 881 return new LDURW64_IMM(machInst, rt, rnsp, imm); 882 case 0x12: 883 return new LDURSW64_IMM(machInst, rt, rnsp, imm); 884 case 0x14: 885 return new STURSFP64_IMM(machInst, rt, rnsp, imm); 886 case 0x15: 887 return new LDURSFP64_IMM(machInst, rt, rnsp, imm); 888 case 0x18: 889 return new STURX64_IMM(machInst, rt, rnsp, imm); 890 case 0x19: 891 return new LDURX64_IMM(machInst, rt, rnsp, imm); 892 case 0x1a: 893 return new PRFUM64_IMM(machInst, rt, rnsp, imm); 894 case 0x1c: 895 return new STURDFP64_IMM(machInst, rt, rnsp, imm); 896 case 0x1d: 897 return new LDURDFP64_IMM(machInst, rt, rnsp, imm); 898 default: 899 return new Unknown64(machInst); 900 } 901 } 902 // bit 29:27=111, 25:24=00, 21=0, 11:10=01 903 case 0x1: 904 { 905 IntRegIndex rt = 906 (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 907 IntRegIndex rn = 908 (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 909 IntRegIndex rnsp = makeSP(rn); 910 uint64_t imm = sext<9>(bits(machInst, 20, 12)); 911 switch (switchVal) { 912 case 0x00: 913 return new STRB64_POST(machInst, rt, rnsp, imm); 914 case 0x01: 915 return new LDRB64_POST(machInst, rt, rnsp, imm); 916 case 0x02: 917 return new LDRSBX64_POST(machInst, rt, rnsp, imm); 918 case 0x03: 919 return new LDRSBW64_POST(machInst, rt, rnsp, imm); 920 case 0x04: 921 return new STRBFP64_POST(machInst, rt, rnsp, imm); 922 case 0x05: 923 return new LDRBFP64_POST(machInst, rt, rnsp, imm); 924 case 0x06: 925 return new BigFpMemPost("str", machInst, false, 926 rt, rnsp, imm); 927 case 0x07: 928 return new BigFpMemPost("ldr", machInst, true, 929 rt, rnsp, imm); 930 case 0x08: 931 return new STRH64_POST(machInst, rt, rnsp, imm); 932 case 0x09: 933 return new LDRH64_POST(machInst, rt, rnsp, imm); 934 case 0x0a: 935 return new LDRSHX64_POST(machInst, rt, rnsp, imm); 936 case 0x0b: 937 return new LDRSHW64_POST(machInst, rt, rnsp, imm); 938 case 0x0c: 939 return new STRHFP64_POST(machInst, rt, rnsp, imm); 940 case 0x0d: 941 return new LDRHFP64_POST(machInst, rt, rnsp, imm); 942 case 0x10: 943 return new STRW64_POST(machInst, rt, rnsp, imm); 944 case 0x11: 945 return new LDRW64_POST(machInst, rt, rnsp, imm); 946 case 0x12: 947 return new LDRSW64_POST(machInst, rt, rnsp, imm); 948 case 0x14: 949 return new STRSFP64_POST(machInst, rt, rnsp, imm); 950 case 0x15: 951 return new LDRSFP64_POST(machInst, rt, rnsp, imm); 952 case 0x18: 953 return new STRX64_POST(machInst, rt, rnsp, imm); 954 case 0x19: 955 return new LDRX64_POST(machInst, rt, rnsp, imm); 956 case 0x1c: 957 return new STRDFP64_POST(machInst, rt, rnsp, imm); 958 case 0x1d: 959 return new LDRDFP64_POST(machInst, rt, rnsp, imm); 960 default: 961 return new Unknown64(machInst); 962 } 963 } 964 case 0x2: 965 { 966 IntRegIndex rt = 967 (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 968 IntRegIndex rn = 969 (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 970 IntRegIndex rnsp = makeSP(rn); 971 uint64_t imm = sext<9>(bits(machInst, 20, 12)); 972 switch (switchVal) { 973 case 0x00: 974 return new STTRB64_IMM(machInst, rt, rnsp, imm); 975 case 0x01: 976 return new LDTRB64_IMM(machInst, rt, rnsp, imm); 977 case 0x02: 978 return new LDTRSBX64_IMM(machInst, rt, rnsp, imm); 979 case 0x03: 980 return new LDTRSBW64_IMM(machInst, rt, rnsp, imm); 981 case 0x08: 982 return new STTRH64_IMM(machInst, rt, rnsp, imm); 983 case 0x09: 984 return new LDTRH64_IMM(machInst, rt, rnsp, imm); 985 case 0x0a: 986 return new LDTRSHX64_IMM(machInst, rt, rnsp, imm); 987 case 0x0b: 988 return new LDTRSHW64_IMM(machInst, rt, rnsp, imm); 989 case 0x10: 990 return new STTRW64_IMM(machInst, rt, rnsp, imm); 991 case 0x11: 992 return new LDTRW64_IMM(machInst, rt, rnsp, imm); 993 case 0x12: 994 return new LDTRSW64_IMM(machInst, rt, rnsp, imm); 995 case 0x18: 996 return new STTRX64_IMM(machInst, rt, rnsp, imm); 997 case 0x19: 998 return new LDTRX64_IMM(machInst, rt, rnsp, imm); 999 default: 1000 return new Unknown64(machInst); 1001 } 1002 } 1003 case 0x3: 1004 { 1005 IntRegIndex rt = 1006 (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 1007 IntRegIndex rn = 1008 (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 1009 IntRegIndex rnsp = makeSP(rn); 1010 uint64_t imm = sext<9>(bits(machInst, 20, 12)); 1011 switch (switchVal) { 1012 case 0x00: 1013 return new STRB64_PRE(machInst, rt, rnsp, imm); 1014 case 0x01: 1015 return new LDRB64_PRE(machInst, rt, rnsp, imm); 1016 case 0x02: 1017 return new LDRSBX64_PRE(machInst, rt, rnsp, imm); 1018 case 0x03: 1019 return new LDRSBW64_PRE(machInst, rt, rnsp, imm); 1020 case 0x04: 1021 return new STRBFP64_PRE(machInst, rt, rnsp, imm); 1022 case 0x05: 1023 return new LDRBFP64_PRE(machInst, rt, rnsp, imm); 1024 case 0x06: 1025 return new BigFpMemPre("str", machInst, false, 1026 rt, rnsp, imm); 1027 case 0x07: 1028 return new BigFpMemPre("ldr", machInst, true, 1029 rt, rnsp, imm); 1030 case 0x08: 1031 return new STRH64_PRE(machInst, rt, rnsp, imm); 1032 case 0x09: 1033 return new LDRH64_PRE(machInst, rt, rnsp, imm); 1034 case 0x0a: 1035 return new LDRSHX64_PRE(machInst, rt, rnsp, imm); 1036 case 0x0b: 1037 return new LDRSHW64_PRE(machInst, rt, rnsp, imm); 1038 case 0x0c: 1039 return new STRHFP64_PRE(machInst, rt, rnsp, imm); 1040 case 0x0d: 1041 return new LDRHFP64_PRE(machInst, rt, rnsp, imm); 1042 case 0x10: 1043 return new STRW64_PRE(machInst, rt, rnsp, imm); 1044 case 0x11: 1045 return new LDRW64_PRE(machInst, rt, rnsp, imm); 1046 case 0x12: 1047 return new LDRSW64_PRE(machInst, rt, rnsp, imm); 1048 case 0x14: 1049 return new STRSFP64_PRE(machInst, rt, rnsp, imm); 1050 case 0x15: 1051 return new LDRSFP64_PRE(machInst, rt, rnsp, imm); 1052 case 0x18: 1053 return new STRX64_PRE(machInst, rt, rnsp, imm); 1054 case 0x19: 1055 return new LDRX64_PRE(machInst, rt, rnsp, imm); 1056 case 0x1c: 1057 return new STRDFP64_PRE(machInst, rt, rnsp, imm); 1058 case 0x1d: 1059 return new LDRDFP64_PRE(machInst, rt, rnsp, imm); 1060 default: 1061 return new Unknown64(machInst); 1062 } 1063 } 1064 default: 1065 M5_UNREACHABLE; 1066 } 1067 } 1068 } 1069 default: 1070 M5_UNREACHABLE; 1071 } 1072 return new FailUnimplemented("Unhandled Case1", machInst); 1073 } 1074} 1075}}; 1076 1077output decoder {{ 1078namespace Aarch64 1079{ 1080 StaticInstPtr 1081 decodeDataProcReg(ExtMachInst machInst) 1082 { 1083 uint8_t switchVal = (bits(machInst, 28) << 1) | 1084 (bits(machInst, 24) << 0); 1085 switch (switchVal) { 1086 case 0x0: 1087 { 1088 uint8_t switchVal = (bits(machInst, 21) << 0) | 1089 (bits(machInst, 30, 29) << 1); 1090 ArmShiftType type = (ArmShiftType)(uint8_t)bits(machInst, 23, 22); 1091 uint8_t imm6 = bits(machInst, 15, 10); 1092 bool sf = bits(machInst, 31); 1093 if (!sf && (imm6 & 0x20)) 1094 return new Unknown64(machInst); 1095 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 1096 IntRegIndex rdzr = makeZero(rd); 1097 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 1098 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 1099 1100 switch (switchVal) { 1101 case 0x0: 1102 return new AndXSReg(machInst, rdzr, rn, rm, imm6, type); 1103 case 0x1: 1104 return new BicXSReg(machInst, rdzr, rn, rm, imm6, type); 1105 case 0x2: 1106 return new OrrXSReg(machInst, rdzr, rn, rm, imm6, type); 1107 case 0x3: 1108 return new OrnXSReg(machInst, rdzr, rn, rm, imm6, type); 1109 case 0x4: 1110 return new EorXSReg(machInst, rdzr, rn, rm, imm6, type); 1111 case 0x5: 1112 return new EonXSReg(machInst, rdzr, rn, rm, imm6, type); 1113 case 0x6: 1114 return new AndXSRegCc(machInst, rdzr, rn, rm, imm6, type); 1115 case 0x7: 1116 return new BicXSRegCc(machInst, rdzr, rn, rm, imm6, type); 1117 default: 1118 M5_UNREACHABLE; 1119 } 1120 } 1121 case 0x1: 1122 { 1123 uint8_t switchVal = bits(machInst, 30, 29); 1124 if (bits(machInst, 21) == 0) { 1125 ArmShiftType type = 1126 (ArmShiftType)(uint8_t)bits(machInst, 23, 22); 1127 if (type == ROR) 1128 return new Unknown64(machInst); 1129 uint8_t imm6 = bits(machInst, 15, 10); 1130 if (!bits(machInst, 31) && bits(imm6, 5)) 1131 return new Unknown64(machInst); 1132 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 1133 IntRegIndex rdzr = makeZero(rd); 1134 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 1135 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 1136 switch (switchVal) { 1137 case 0x0: 1138 return new AddXSReg(machInst, rdzr, rn, rm, imm6, type); 1139 case 0x1: 1140 return new AddXSRegCc(machInst, rdzr, rn, rm, imm6, type); 1141 case 0x2: 1142 return new SubXSReg(machInst, rdzr, rn, rm, imm6, type); 1143 case 0x3: 1144 return new SubXSRegCc(machInst, rdzr, rn, rm, imm6, type); 1145 default: 1146 M5_UNREACHABLE; 1147 } 1148 } else { 1149 if (bits(machInst, 23, 22) != 0 || bits(machInst, 12, 10) > 0x4) 1150 return new Unknown64(machInst); 1151 ArmExtendType type = 1152 (ArmExtendType)(uint8_t)bits(machInst, 15, 13); 1153 uint8_t imm3 = bits(machInst, 12, 10); 1154 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 1155 IntRegIndex rdsp = makeSP(rd); 1156 IntRegIndex rdzr = makeZero(rd); 1157 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 1158 IntRegIndex rnsp = makeSP(rn); 1159 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 1160 1161 switch (switchVal) { 1162 case 0x0: 1163 return new AddXEReg(machInst, rdsp, rnsp, rm, type, imm3); 1164 case 0x1: 1165 return new AddXERegCc(machInst, rdzr, rnsp, rm, type, imm3); 1166 case 0x2: 1167 return new SubXEReg(machInst, rdsp, rnsp, rm, type, imm3); 1168 case 0x3: 1169 return new SubXERegCc(machInst, rdzr, rnsp, rm, type, imm3); 1170 default: 1171 M5_UNREACHABLE; 1172 } 1173 } 1174 } 1175 case 0x2: 1176 { 1177 if (bits(machInst, 21) == 1) 1178 return new Unknown64(machInst); 1179 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 1180 IntRegIndex rdzr = makeZero(rd); 1181 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 1182 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 1183 switch (bits(machInst, 23, 22)) { 1184 case 0x0: 1185 { 1186 if (bits(machInst, 15, 10)) 1187 return new Unknown64(machInst); 1188 uint8_t switchVal = bits(machInst, 30, 29); 1189 switch (switchVal) { 1190 case 0x0: 1191 return new AdcXSReg(machInst, rdzr, rn, rm, 0, LSL); 1192 case 0x1: 1193 return new AdcXSRegCc(machInst, rdzr, rn, rm, 0, LSL); 1194 case 0x2: 1195 return new SbcXSReg(machInst, rdzr, rn, rm, 0, LSL); 1196 case 0x3: 1197 return new SbcXSRegCc(machInst, rdzr, rn, rm, 0, LSL); 1198 default: 1199 M5_UNREACHABLE; 1200 } 1201 } 1202 case 0x1: 1203 { 1204 if ((bits(machInst, 4) == 1) || 1205 (bits(machInst, 10) == 1) || 1206 (bits(machInst, 29) == 0)) { 1207 return new Unknown64(machInst); 1208 } 1209 ConditionCode cond = 1210 (ConditionCode)(uint8_t)bits(machInst, 15, 12); 1211 uint8_t flags = bits(machInst, 3, 0); 1212 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 1213 if (bits(machInst, 11) == 0) { 1214 IntRegIndex rm = 1215 (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 1216 if (bits(machInst, 30) == 0) { 1217 return new CcmnReg64(machInst, rn, rm, cond, flags); 1218 } else { 1219 return new CcmpReg64(machInst, rn, rm, cond, flags); 1220 } 1221 } else { 1222 uint8_t imm5 = bits(machInst, 20, 16); 1223 if (bits(machInst, 30) == 0) { 1224 return new CcmnImm64(machInst, rn, imm5, cond, flags); 1225 } else { 1226 return new CcmpImm64(machInst, rn, imm5, cond, flags); 1227 } 1228 } 1229 } 1230 case 0x2: 1231 { 1232 if (bits(machInst, 29) == 1 || 1233 bits(machInst, 11) == 1) { 1234 return new Unknown64(machInst); 1235 } 1236 uint8_t switchVal = (bits(machInst, 10) << 0) | 1237 (bits(machInst, 30) << 1); 1238 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 1239 IntRegIndex rdzr = makeZero(rd); 1240 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 1241 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 1242 ConditionCode cond = 1243 (ConditionCode)(uint8_t)bits(machInst, 15, 12); 1244 switch (switchVal) { 1245 case 0x0: 1246 return new Csel64(machInst, rdzr, rn, rm, cond); 1247 case 0x1: 1248 return new Csinc64(machInst, rdzr, rn, rm, cond); 1249 case 0x2: 1250 return new Csinv64(machInst, rdzr, rn, rm, cond); 1251 case 0x3: 1252 return new Csneg64(machInst, rdzr, rn, rm, cond); 1253 default: 1254 M5_UNREACHABLE; 1255 } 1256 } 1257 case 0x3: 1258 if (bits(machInst, 30) == 0) { 1259 if (bits(machInst, 29) != 0) 1260 return new Unknown64(machInst); 1261 uint8_t switchVal = bits(machInst, 15, 10); 1262 switch (switchVal) { 1263 case 0x2: 1264 return new Udiv64(machInst, rdzr, rn, rm); 1265 case 0x3: 1266 return new Sdiv64(machInst, rdzr, rn, rm); 1267 case 0x8: 1268 return new Lslv64(machInst, rdzr, rn, rm); 1269 case 0x9: 1270 return new Lsrv64(machInst, rdzr, rn, rm); 1271 case 0xa: 1272 return new Asrv64(machInst, rdzr, rn, rm); 1273 case 0xb: 1274 return new Rorv64(machInst, rdzr, rn, rm); 1275 case 0x10: 1276 return new Crc32b64(machInst, rdzr, rn, rm); 1277 case 0x11: 1278 return new Crc32h64(machInst, rdzr, rn, rm); 1279 case 0x12: 1280 return new Crc32w64(machInst, rdzr, rn, rm); 1281 case 0x13: 1282 return new Crc32x64(machInst, rdzr, rn, rm); 1283 case 0x14: 1284 return new Crc32cb64(machInst, rdzr, rn, rm); 1285 case 0x15: 1286 return new Crc32ch64(machInst, rdzr, rn, rm); 1287 case 0x16: 1288 return new Crc32cw64(machInst, rdzr, rn, rm); 1289 case 0x17: 1290 return new Crc32cx64(machInst, rdzr, rn, rm); 1291 default: 1292 return new Unknown64(machInst); 1293 } 1294 } else { 1295 if (bits(machInst, 20, 16) != 0 || 1296 bits(machInst, 29) != 0) { 1297 return new Unknown64(machInst); 1298 } 1299 uint8_t switchVal = bits(machInst, 15, 10); 1300 switch (switchVal) { 1301 case 0x0: 1302 return new Rbit64(machInst, rdzr, rn); 1303 case 0x1: 1304 return new Rev1664(machInst, rdzr, rn); 1305 case 0x2: 1306 if (bits(machInst, 31) == 0) 1307 return new Rev64(machInst, rdzr, rn); 1308 else 1309 return new Rev3264(machInst, rdzr, rn); 1310 case 0x3: 1311 if (bits(machInst, 31) != 1) 1312 return new Unknown64(machInst); 1313 return new Rev64(machInst, rdzr, rn); 1314 case 0x4: 1315 return new Clz64(machInst, rdzr, rn); 1316 case 0x5: 1317 return new Cls64(machInst, rdzr, rn); 1318 default: 1319 return new Unknown64(machInst); 1320 } 1321 } 1322 default: 1323 M5_UNREACHABLE; 1324 } 1325 } 1326 case 0x3: 1327 { 1328 if (bits(machInst, 30, 29) != 0x0 || 1329 (bits(machInst, 23, 21) != 0 && bits(machInst, 31) == 0)) 1330 return new Unknown64(machInst); 1331 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 1332 IntRegIndex rdzr = makeZero(rd); 1333 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 1334 IntRegIndex ra = (IntRegIndex)(uint8_t)bits(machInst, 14, 10); 1335 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 1336 switch (bits(machInst, 23, 21)) { 1337 case 0x0: 1338 if (bits(machInst, 15) == 0) 1339 return new Madd64(machInst, rdzr, ra, rn, rm); 1340 else 1341 return new Msub64(machInst, rdzr, ra, rn, rm); 1342 case 0x1: 1343 if (bits(machInst, 15) == 0) 1344 return new Smaddl64(machInst, rdzr, ra, rn, rm); 1345 else 1346 return new Smsubl64(machInst, rdzr, ra, rn, rm); 1347 case 0x2: 1348 if (bits(machInst, 15) != 0) 1349 return new Unknown64(machInst); 1350 return new Smulh64(machInst, rdzr, rn, rm); 1351 case 0x5: 1352 if (bits(machInst, 15) == 0) 1353 return new Umaddl64(machInst, rdzr, ra, rn, rm); 1354 else 1355 return new Umsubl64(machInst, rdzr, ra, rn, rm); 1356 case 0x6: 1357 if (bits(machInst, 15) != 0) 1358 return new Unknown64(machInst); 1359 return new Umulh64(machInst, rdzr, rn, rm); 1360 default: 1361 return new Unknown64(machInst); 1362 } 1363 } 1364 default: 1365 M5_UNREACHABLE; 1366 } 1367 return new FailUnimplemented("Unhandled Case2", machInst); 1368 } 1369} 1370}}; 1371 1372output decoder {{ 1373namespace Aarch64 1374{ 1375 template <typename DecoderFeatures> 1376 StaticInstPtr 1377 decodeAdvSIMD(ExtMachInst machInst) 1378 { 1379 if (bits(machInst, 24) == 1) { 1380 if (bits(machInst, 10) == 0) { 1381 return decodeNeonIndexedElem<DecoderFeatures>(machInst); 1382 } else if (bits(machInst, 23) == 1) { 1383 return new Unknown64(machInst); 1384 } else { 1385 if (bits(machInst, 22, 19)) { 1386 return decodeNeonShiftByImm(machInst); 1387 } else { 1388 return decodeNeonModImm(machInst); 1389 } 1390 } 1391 } else if (bits(machInst, 21) == 1) { 1392 if (bits(machInst, 10) == 1) { 1393 return decodeNeon3Same<DecoderFeatures>(machInst); 1394 } else if (bits(machInst, 11) == 0) { 1395 return decodeNeon3Diff(machInst); 1396 } else if (bits(machInst, 20, 17) == 0x0) { 1397 return decodeNeon2RegMisc(machInst); 1398 } else if (bits(machInst, 20, 17) == 0x8) { 1399 return decodeNeonAcrossLanes(machInst); 1400 } else { 1401 return new Unknown64(machInst); 1402 } 1403 } else if (bits(machInst, 24) || 1404 bits(machInst, 21) || 1405 bits(machInst, 15)) { 1406 return new Unknown64(machInst); 1407 } else if (bits(machInst, 10) == 1) { 1408 if (bits(machInst, 23, 22)) 1409 return new Unknown64(machInst); 1410 return decodeNeonCopy(machInst); 1411 } else if (bits(machInst, 29) == 1) { 1412 return decodeNeonExt(machInst); 1413 } else if (bits(machInst, 11) == 1) { 1414 return decodeNeonZipUzpTrn(machInst); 1415 } else if (bits(machInst, 23, 22) == 0x0) { 1416 return decodeNeonTblTbx(machInst); 1417 } else { 1418 return new Unknown64(machInst); 1419 } 1420 return new FailUnimplemented("Unhandled Case3", machInst); 1421 } 1422} 1423}}; 1424 1425 1426output decoder {{ 1427namespace Aarch64 1428{ 1429 StaticInstPtr 1430 // bit 30=0, 28:25=1111 1431 decodeFp(ExtMachInst machInst) 1432 { 1433 if (bits(machInst, 24) == 1) { 1434 if (bits(machInst, 31) || bits(machInst, 29)) 1435 return new Unknown64(machInst); 1436 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 1437 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 1438 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 20, 16); 1439 IntRegIndex ra = (IntRegIndex)(uint32_t)bits(machInst, 14, 10); 1440 uint8_t switchVal = (bits(machInst, 23, 21) << 1) | 1441 (bits(machInst, 15) << 0); 1442 switch (switchVal) { 1443 case 0x0: // FMADD Sd = Sa + Sn*Sm 1444 return new FMAddS(machInst, rd, rn, rm, ra); 1445 case 0x1: // FMSUB Sd = Sa + (-Sn)*Sm 1446 return new FMSubS(machInst, rd, rn, rm, ra); 1447 case 0x2: // FNMADD Sd = (-Sa) + (-Sn)*Sm 1448 return new FNMAddS(machInst, rd, rn, rm, ra); 1449 case 0x3: // FNMSUB Sd = (-Sa) + Sn*Sm 1450 return new FNMSubS(machInst, rd, rn, rm, ra); 1451 case 0x4: // FMADD Dd = Da + Dn*Dm 1452 return new FMAddD(machInst, rd, rn, rm, ra); 1453 case 0x5: // FMSUB Dd = Da + (-Dn)*Dm 1454 return new FMSubD(machInst, rd, rn, rm, ra); 1455 case 0x6: // FNMADD Dd = (-Da) + (-Dn)*Dm 1456 return new FNMAddD(machInst, rd, rn, rm, ra); 1457 case 0x7: // FNMSUB Dd = (-Da) + Dn*Dm 1458 return new FNMSubD(machInst, rd, rn, rm, ra); 1459 default: 1460 return new Unknown64(machInst); 1461 } 1462 } else if (bits(machInst, 21) == 0) { 1463 bool s = bits(machInst, 29); 1464 if (s) 1465 return new Unknown64(machInst); 1466 uint8_t switchVal = bits(machInst, 20, 16); 1467 uint8_t type = bits(machInst, 23, 22); 1468 uint8_t scale = bits(machInst, 15, 10); 1469 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 1470 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 1471 if (bits(machInst, 18, 17) == 3 && scale != 0) 1472 return new Unknown64(machInst); 1473 // 30:24=0011110, 21=0 1474 switch (switchVal) { 1475 case 0x00: 1476 return new FailUnimplemented("fcvtns", machInst); 1477 case 0x01: 1478 return new FailUnimplemented("fcvtnu", machInst); 1479 case 0x02: 1480 switch ( (bits(machInst, 31) << 2) | type ) { 1481 case 0: // SCVTF Sd = convertFromInt(Wn/(2^fbits)) 1482 return new FcvtSFixedFpSW(machInst, rd, rn, scale); 1483 case 1: // SCVTF Dd = convertFromInt(Wn/(2^fbits)) 1484 return new FcvtSFixedFpDW(machInst, rd, rn, scale); 1485 case 4: // SCVTF Sd = convertFromInt(Xn/(2^fbits)) 1486 return new FcvtSFixedFpSX(machInst, rd, rn, scale); 1487 case 5: // SCVTF Dd = convertFromInt(Xn/(2^fbits)) 1488 return new FcvtSFixedFpDX(machInst, rd, rn, scale); 1489 default: 1490 return new Unknown64(machInst); 1491 } 1492 case 0x03: 1493 switch ( (bits(machInst, 31) << 2) | type ) { 1494 case 0: // UCVTF Sd = convertFromInt(Wn/(2^fbits)) 1495 return new FcvtUFixedFpSW(machInst, rd, rn, scale); 1496 case 1: // UCVTF Dd = convertFromInt(Wn/(2^fbits)) 1497 return new FcvtUFixedFpDW(machInst, rd, rn, scale); 1498 case 4: // UCVTF Sd = convertFromInt(Xn/(2^fbits)) 1499 return new FcvtUFixedFpSX(machInst, rd, rn, scale); 1500 case 5: // UCVTF Dd = convertFromInt(Xn/(2^fbits)) 1501 return new FcvtUFixedFpDX(machInst, rd, rn, scale); 1502 default: 1503 return new Unknown64(machInst); 1504 } 1505 case 0x04: 1506 return new FailUnimplemented("fcvtas", machInst); 1507 case 0x05: 1508 return new FailUnimplemented("fcvtau", machInst); 1509 case 0x08: 1510 return new FailUnimplemented("fcvtps", machInst); 1511 case 0x09: 1512 return new FailUnimplemented("fcvtpu", machInst); 1513 case 0x0e: 1514 return new FailUnimplemented("fmov elem. to 64", machInst); 1515 case 0x0f: 1516 return new FailUnimplemented("fmov 64 bit", machInst); 1517 case 0x10: 1518 return new FailUnimplemented("fcvtms", machInst); 1519 case 0x11: 1520 return new FailUnimplemented("fcvtmu", machInst); 1521 case 0x18: 1522 switch ( (bits(machInst, 31) << 2) | type ) { 1523 case 0: // FCVTZS Wd = convertToIntExactTowardZero(Sn*(2^fbits)) 1524 return new FcvtFpSFixedSW(machInst, rd, rn, scale); 1525 case 1: // FCVTZS Wd = convertToIntExactTowardZero(Dn*(2^fbits)) 1526 return new FcvtFpSFixedDW(machInst, rd, rn, scale); 1527 case 4: // FCVTZS Xd = convertToIntExactTowardZero(Sn*(2^fbits)) 1528 return new FcvtFpSFixedSX(machInst, rd, rn, scale); 1529 case 5: // FCVTZS Xd = convertToIntExactTowardZero(Dn*(2^fbits)) 1530 return new FcvtFpSFixedDX(machInst, rd, rn, scale); 1531 default: 1532 return new Unknown64(machInst); 1533 } 1534 case 0x19: 1535 switch ( (bits(machInst, 31) << 2) | type ) { 1536 case 0: // FCVTZU Wd = convertToIntExactTowardZero(Sn*(2^fbits)) 1537 return new FcvtFpUFixedSW(machInst, rd, rn, scale); 1538 case 1: // FCVTZU Wd = convertToIntExactTowardZero(Dn*(2^fbits)) 1539 return new FcvtFpUFixedDW(machInst, rd, rn, scale); 1540 case 4: // FCVTZU Xd = convertToIntExactTowardZero(Sn*(2^fbits)) 1541 return new FcvtFpUFixedSX(machInst, rd, rn, scale); 1542 case 5: // FCVTZU Xd = convertToIntExactTowardZero(Dn*(2^fbits)) 1543 return new FcvtFpUFixedDX(machInst, rd, rn, scale); 1544 default: 1545 return new Unknown64(machInst); 1546 } 1547 default: 1548 return new Unknown64(machInst); 1549 } 1550 } else { 1551 // 30=0, 28:24=11110, 21=1 1552 uint8_t type = bits(machInst, 23, 22); 1553 uint8_t imm8 = bits(machInst, 20, 13); 1554 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 1555 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 1556 switch (bits(machInst, 11, 10)) { 1557 case 0x0: 1558 if (bits(machInst, 12) == 1) { 1559 if (bits(machInst, 31) || 1560 bits(machInst, 29) || 1561 bits(machInst, 9, 5)) { 1562 return new Unknown64(machInst); 1563 } 1564 // 31:29=000, 28:24=11110, 21=1, 12:10=100 1565 if (type == 0) { 1566 // FMOV S[d] = imm8<7>:NOT(imm8<6>):Replicate(imm8<6>,5) 1567 // :imm8<5:0>:Zeros(19) 1568 uint32_t imm = vfp_modified_imm(imm8, false); 1569 return new FmovImmS(machInst, rd, imm); 1570 } else if (type == 1) { 1571 // FMOV D[d] = imm8<7>:NOT(imm8<6>):Replicate(imm8<6>,8) 1572 // :imm8<5:0>:Zeros(48) 1573 uint64_t imm = vfp_modified_imm(imm8, true); 1574 return new FmovImmD(machInst, rd, imm); 1575 } else { 1576 return new Unknown64(machInst); 1577 } 1578 } else if (bits(machInst, 13) == 1) { 1579 if (bits(machInst, 31) || 1580 bits(machInst, 29) || 1581 bits(machInst, 15, 14) || 1582 bits(machInst, 23) || 1583 bits(machInst, 2, 0)) { 1584 return new Unknown64(machInst); 1585 } 1586 uint8_t switchVal = (bits(machInst, 4, 3) << 0) | 1587 (bits(machInst, 22) << 2); 1588 IntRegIndex rm = (IntRegIndex)(uint32_t) 1589 bits(machInst, 20, 16); 1590 // 28:23=000111100, 21=1, 15:10=001000, 2:0=000 1591 switch (switchVal) { 1592 case 0x0: 1593 // FCMP flags = compareQuiet(Sn,Sm) 1594 return new FCmpRegS(machInst, rn, rm); 1595 case 0x1: 1596 // FCMP flags = compareQuiet(Sn,0.0) 1597 return new FCmpImmS(machInst, rn, 0); 1598 case 0x2: 1599 // FCMPE flags = compareSignaling(Sn,Sm) 1600 return new FCmpERegS(machInst, rn, rm); 1601 case 0x3: 1602 // FCMPE flags = compareSignaling(Sn,0.0) 1603 return new FCmpEImmS(machInst, rn, 0); 1604 case 0x4: 1605 // FCMP flags = compareQuiet(Dn,Dm) 1606 return new FCmpRegD(machInst, rn, rm); 1607 case 0x5: 1608 // FCMP flags = compareQuiet(Dn,0.0) 1609 return new FCmpImmD(machInst, rn, 0); 1610 case 0x6: 1611 // FCMPE flags = compareSignaling(Dn,Dm) 1612 return new FCmpERegD(machInst, rn, rm); 1613 case 0x7: 1614 // FCMPE flags = compareSignaling(Dn,0.0) 1615 return new FCmpEImmD(machInst, rn, 0); 1616 default: 1617 return new Unknown64(machInst); 1618 } 1619 } else if (bits(machInst, 14) == 1) { 1620 if (bits(machInst, 31) || bits(machInst, 29)) 1621 return new Unknown64(machInst); 1622 uint8_t opcode = bits(machInst, 20, 15); 1623 // Bits 31:24=00011110, 21=1, 14:10=10000 1624 switch (opcode) { 1625 case 0x0: 1626 if (type == 0) 1627 // FMOV Sd = Sn 1628 return new FmovRegS(machInst, rd, rn); 1629 else if (type == 1) 1630 // FMOV Dd = Dn 1631 return new FmovRegD(machInst, rd, rn); 1632 break; 1633 case 0x1: 1634 if (type == 0) 1635 // FABS Sd = abs(Sn) 1636 return new FAbsS(machInst, rd, rn); 1637 else if (type == 1) 1638 // FABS Dd = abs(Dn) 1639 return new FAbsD(machInst, rd, rn); 1640 break; 1641 case 0x2: 1642 if (type == 0) 1643 // FNEG Sd = -Sn 1644 return new FNegS(machInst, rd, rn); 1645 else if (type == 1) 1646 // FNEG Dd = -Dn 1647 return new FNegD(machInst, rd, rn); 1648 break; 1649 case 0x3: 1650 if (type == 0) 1651 // FSQRT Sd = sqrt(Sn) 1652 return new FSqrtS(machInst, rd, rn); 1653 else if (type == 1) 1654 // FSQRT Dd = sqrt(Dn) 1655 return new FSqrtD(machInst, rd, rn); 1656 break; 1657 case 0x4: 1658 if (type == 1) 1659 // FCVT Sd = convertFormat(Dn) 1660 return new FcvtFpDFpS(machInst, rd, rn); 1661 else if (type == 3) 1662 // FCVT Sd = convertFormat(Hn) 1663 return new FcvtFpHFpS(machInst, rd, rn); 1664 break; 1665 case 0x5: 1666 if (type == 0) 1667 // FCVT Dd = convertFormat(Sn) 1668 return new FCvtFpSFpD(machInst, rd, rn); 1669 else if (type == 3) 1670 // FCVT Dd = convertFormat(Hn) 1671 return new FcvtFpHFpD(machInst, rd, rn); 1672 break; 1673 case 0x7: 1674 if (type == 0) 1675 // FCVT Hd = convertFormat(Sn) 1676 return new FcvtFpSFpH(machInst, rd, rn); 1677 else if (type == 1) 1678 // FCVT Hd = convertFormat(Dn) 1679 return new FcvtFpDFpH(machInst, rd, rn); 1680 break; 1681 case 0x8: 1682 if (type == 0) // FRINTN Sd = roundToIntegralTiesToEven(Sn) 1683 return new FRIntNS(machInst, rd, rn); 1684 else if (type == 1) // FRINTN Dd = roundToIntegralTiesToEven(Dn) 1685 return new FRIntND(machInst, rd, rn); 1686 break; 1687 case 0x9: 1688 if (type == 0) // FRINTP Sd = roundToIntegralTowardPlusInf(Sn) 1689 return new FRIntPS(machInst, rd, rn); 1690 else if (type == 1) // FRINTP Dd = roundToIntegralTowardPlusInf(Dn) 1691 return new FRIntPD(machInst, rd, rn); 1692 break; 1693 case 0xa: 1694 if (type == 0) // FRINTM Sd = roundToIntegralTowardMinusInf(Sn) 1695 return new FRIntMS(machInst, rd, rn); 1696 else if (type == 1) // FRINTM Dd = roundToIntegralTowardMinusInf(Dn) 1697 return new FRIntMD(machInst, rd, rn); 1698 break; 1699 case 0xb: 1700 if (type == 0) // FRINTZ Sd = roundToIntegralTowardZero(Sn) 1701 return new FRIntZS(machInst, rd, rn); 1702 else if (type == 1) // FRINTZ Dd = roundToIntegralTowardZero(Dn) 1703 return new FRIntZD(machInst, rd, rn); 1704 break; 1705 case 0xc: 1706 if (type == 0) // FRINTA Sd = roundToIntegralTiesToAway(Sn) 1707 return new FRIntAS(machInst, rd, rn); 1708 else if (type == 1) // FRINTA Dd = roundToIntegralTiesToAway(Dn) 1709 return new FRIntAD(machInst, rd, rn); 1710 break; 1711 case 0xe: 1712 if (type == 0) // FRINTX Sd = roundToIntegralExact(Sn) 1713 return new FRIntXS(machInst, rd, rn); 1714 else if (type == 1) // FRINTX Dd = roundToIntegralExact(Dn) 1715 return new FRIntXD(machInst, rd, rn); 1716 break; 1717 case 0xf: 1718 if (type == 0) // FRINTI Sd = roundToIntegral(Sn) 1719 return new FRIntIS(machInst, rd, rn); 1720 else if (type == 1) // FRINTI Dd = roundToIntegral(Dn) 1721 return new FRIntID(machInst, rd, rn); 1722 break; 1723 default: 1724 return new Unknown64(machInst); 1725 } 1726 return new Unknown64(machInst); 1727 } else if (bits(machInst, 15) == 1) { 1728 return new Unknown64(machInst); 1729 } else { 1730 if (bits(machInst, 29)) 1731 return new Unknown64(machInst); 1732 uint8_t rmode = bits(machInst, 20, 19); 1733 uint8_t switchVal1 = bits(machInst, 18, 16); 1734 uint8_t switchVal2 = (type << 1) | bits(machInst, 31); 1735 // 30:24=0011110, 21=1, 15:10=000000 1736 switch (switchVal1) { 1737 case 0x0: 1738 switch ((switchVal2 << 2) | rmode) { 1739 case 0x0: //FCVTNS Wd = convertToIntExactTiesToEven(Sn) 1740 return new FcvtFpSIntWSN(machInst, rd, rn); 1741 case 0x1: //FCVTPS Wd = convertToIntExactTowardPlusInf(Sn) 1742 return new FcvtFpSIntWSP(machInst, rd, rn); 1743 case 0x2: //FCVTMS Wd = convertToIntExactTowardMinusInf(Sn) 1744 return new FcvtFpSIntWSM(machInst, rd, rn); 1745 case 0x3: //FCVTZS Wd = convertToIntExactTowardZero(Sn) 1746 return new FcvtFpSIntWSZ(machInst, rd, rn); 1747 case 0x4: //FCVTNS Xd = convertToIntExactTiesToEven(Sn) 1748 return new FcvtFpSIntXSN(machInst, rd, rn); 1749 case 0x5: //FCVTPS Xd = convertToIntExactTowardPlusInf(Sn) 1750 return new FcvtFpSIntXSP(machInst, rd, rn); 1751 case 0x6: //FCVTMS Xd = convertToIntExactTowardMinusInf(Sn) 1752 return new FcvtFpSIntXSM(machInst, rd, rn); 1753 case 0x7: //FCVTZS Xd = convertToIntExactTowardZero(Sn) 1754 return new FcvtFpSIntXSZ(machInst, rd, rn); 1755 case 0x8: //FCVTNS Wd = convertToIntExactTiesToEven(Dn) 1756 return new FcvtFpSIntWDN(machInst, rd, rn); 1757 case 0x9: //FCVTPS Wd = convertToIntExactTowardPlusInf(Dn) 1758 return new FcvtFpSIntWDP(machInst, rd, rn); 1759 case 0xA: //FCVTMS Wd = convertToIntExactTowardMinusInf(Dn) 1760 return new FcvtFpSIntWDM(machInst, rd, rn); 1761 case 0xB: //FCVTZS Wd = convertToIntExactTowardZero(Dn) 1762 return new FcvtFpSIntWDZ(machInst, rd, rn); 1763 case 0xC: //FCVTNS Xd = convertToIntExactTiesToEven(Dn) 1764 return new FcvtFpSIntXDN(machInst, rd, rn); 1765 case 0xD: //FCVTPS Xd = convertToIntExactTowardPlusInf(Dn) 1766 return new FcvtFpSIntXDP(machInst, rd, rn); 1767 case 0xE: //FCVTMS Xd = convertToIntExactTowardMinusInf(Dn) 1768 return new FcvtFpSIntXDM(machInst, rd, rn); 1769 case 0xF: //FCVTZS Xd = convertToIntExactTowardZero(Dn) 1770 return new FcvtFpSIntXDZ(machInst, rd, rn); 1771 default: 1772 return new Unknown64(machInst); 1773 } 1774 case 0x1: 1775 switch ((switchVal2 << 2) | rmode) { 1776 case 0x0: //FCVTNU Wd = convertToIntExactTiesToEven(Sn) 1777 return new FcvtFpUIntWSN(machInst, rd, rn); 1778 case 0x1: //FCVTPU Wd = convertToIntExactTowardPlusInf(Sn) 1779 return new FcvtFpUIntWSP(machInst, rd, rn); 1780 case 0x2: //FCVTMU Wd = convertToIntExactTowardMinusInf(Sn) 1781 return new FcvtFpUIntWSM(machInst, rd, rn); 1782 case 0x3: //FCVTZU Wd = convertToIntExactTowardZero(Sn) 1783 return new FcvtFpUIntWSZ(machInst, rd, rn); 1784 case 0x4: //FCVTNU Xd = convertToIntExactTiesToEven(Sn) 1785 return new FcvtFpUIntXSN(machInst, rd, rn); 1786 case 0x5: //FCVTPU Xd = convertToIntExactTowardPlusInf(Sn) 1787 return new FcvtFpUIntXSP(machInst, rd, rn); 1788 case 0x6: //FCVTMU Xd = convertToIntExactTowardMinusInf(Sn) 1789 return new FcvtFpUIntXSM(machInst, rd, rn); 1790 case 0x7: //FCVTZU Xd = convertToIntExactTowardZero(Sn) 1791 return new FcvtFpUIntXSZ(machInst, rd, rn); 1792 case 0x8: //FCVTNU Wd = convertToIntExactTiesToEven(Dn) 1793 return new FcvtFpUIntWDN(machInst, rd, rn); 1794 case 0x9: //FCVTPU Wd = convertToIntExactTowardPlusInf(Dn) 1795 return new FcvtFpUIntWDP(machInst, rd, rn); 1796 case 0xA: //FCVTMU Wd = convertToIntExactTowardMinusInf(Dn) 1797 return new FcvtFpUIntWDM(machInst, rd, rn); 1798 case 0xB: //FCVTZU Wd = convertToIntExactTowardZero(Dn) 1799 return new FcvtFpUIntWDZ(machInst, rd, rn); 1800 case 0xC: //FCVTNU Xd = convertToIntExactTiesToEven(Dn) 1801 return new FcvtFpUIntXDN(machInst, rd, rn); 1802 case 0xD: //FCVTPU Xd = convertToIntExactTowardPlusInf(Dn) 1803 return new FcvtFpUIntXDP(machInst, rd, rn); 1804 case 0xE: //FCVTMU Xd = convertToIntExactTowardMinusInf(Dn) 1805 return new FcvtFpUIntXDM(machInst, rd, rn); 1806 case 0xF: //FCVTZU Xd = convertToIntExactTowardZero(Dn) 1807 return new FcvtFpUIntXDZ(machInst, rd, rn); 1808 default: 1809 return new Unknown64(machInst); 1810 } 1811 case 0x2: 1812 if (rmode != 0) 1813 return new Unknown64(machInst); 1814 switch (switchVal2) { 1815 case 0: // SCVTF Sd = convertFromInt(Wn) 1816 return new FcvtWSIntFpS(machInst, rd, rn); 1817 case 1: // SCVTF Sd = convertFromInt(Xn) 1818 return new FcvtXSIntFpS(machInst, rd, rn); 1819 case 2: // SCVTF Dd = convertFromInt(Wn) 1820 return new FcvtWSIntFpD(machInst, rd, rn); 1821 case 3: // SCVTF Dd = convertFromInt(Xn) 1822 return new FcvtXSIntFpD(machInst, rd, rn); 1823 default: 1824 return new Unknown64(machInst); 1825 } 1826 case 0x3: 1827 switch (switchVal2) { 1828 case 0: // UCVTF Sd = convertFromInt(Wn) 1829 return new FcvtWUIntFpS(machInst, rd, rn); 1830 case 1: // UCVTF Sd = convertFromInt(Xn) 1831 return new FcvtXUIntFpS(machInst, rd, rn); 1832 case 2: // UCVTF Dd = convertFromInt(Wn) 1833 return new FcvtWUIntFpD(machInst, rd, rn); 1834 case 3: // UCVTF Dd = convertFromInt(Xn) 1835 return new FcvtXUIntFpD(machInst, rd, rn); 1836 default: 1837 return new Unknown64(machInst); 1838 } 1839 case 0x4: 1840 if (rmode != 0) 1841 return new Unknown64(machInst); 1842 switch (switchVal2) { 1843 case 0: // FCVTAS Wd = convertToIntExactTiesToAway(Sn) 1844 return new FcvtFpSIntWSA(machInst, rd, rn); 1845 case 1: // FCVTAS Xd = convertToIntExactTiesToAway(Sn) 1846 return new FcvtFpSIntXSA(machInst, rd, rn); 1847 case 2: // FCVTAS Wd = convertToIntExactTiesToAway(Dn) 1848 return new FcvtFpSIntWDA(machInst, rd, rn); 1849 case 3: // FCVTAS Wd = convertToIntExactTiesToAway(Dn) 1850 return new FcvtFpSIntXDA(machInst, rd, rn); 1851 default: 1852 return new Unknown64(machInst); 1853 } 1854 case 0x5: 1855 switch (switchVal2) { 1856 case 0: // FCVTAU Wd = convertToIntExactTiesToAway(Sn) 1857 return new FcvtFpUIntWSA(machInst, rd, rn); 1858 case 1: // FCVTAU Xd = convertToIntExactTiesToAway(Sn) 1859 return new FcvtFpUIntXSA(machInst, rd, rn); 1860 case 2: // FCVTAU Wd = convertToIntExactTiesToAway(Dn) 1861 return new FcvtFpUIntWDA(machInst, rd, rn); 1862 case 3: // FCVTAU Xd = convertToIntExactTiesToAway(Dn) 1863 return new FcvtFpUIntXDA(machInst, rd, rn); 1864 default: 1865 return new Unknown64(machInst); 1866 } 1867 case 0x06: 1868 switch (switchVal2) { 1869 case 0: // FMOV Wd = Sn 1870 if (rmode != 0) 1871 return new Unknown64(machInst); 1872 return new FmovRegCoreW(machInst, rd, rn); 1873 case 3: // FMOV Xd = Dn 1874 if (rmode != 0) 1875 return new Unknown64(machInst); 1876 return new FmovRegCoreX(machInst, rd, rn); 1877 case 5: // FMOV Xd = Vn<127:64> 1878 if (rmode != 1) 1879 return new Unknown64(machInst); 1880 return new FmovURegCoreX(machInst, rd, rn); 1881 default: 1882 return new Unknown64(machInst); 1883 } 1884 break; 1885 case 0x07: 1886 switch (switchVal2) { 1887 case 0: // FMOV Sd = Wn 1888 if (rmode != 0) 1889 return new Unknown64(machInst); 1890 return new FmovCoreRegW(machInst, rd, rn); 1891 case 3: // FMOV Xd = Dn 1892 if (rmode != 0) 1893 return new Unknown64(machInst); 1894 return new FmovCoreRegX(machInst, rd, rn); 1895 case 5: // FMOV Xd = Vn<127:64> 1896 if (rmode != 1) 1897 return new Unknown64(machInst); 1898 return new FmovUCoreRegX(machInst, rd, rn); 1899 default: 1900 return new Unknown64(machInst); 1901 } 1902 break; 1903 default: // Warning! missing cases in switch statement above, that still need to be added 1904 return new Unknown64(machInst); 1905 } 1906 } 1907 M5_UNREACHABLE; 1908 case 0x1: 1909 { 1910 if (bits(machInst, 31) || 1911 bits(machInst, 29) || 1912 bits(machInst, 23)) { 1913 return new Unknown64(machInst); 1914 } 1915 IntRegIndex rm = (IntRegIndex)(uint32_t) bits(machInst, 20, 16); 1916 IntRegIndex rn = (IntRegIndex)(uint32_t) bits(machInst, 9, 5); 1917 uint8_t imm = (IntRegIndex)(uint32_t) bits(machInst, 3, 0); 1918 ConditionCode cond = 1919 (ConditionCode)(uint8_t)(bits(machInst, 15, 12)); 1920 uint8_t switchVal = (bits(machInst, 4) << 0) | 1921 (bits(machInst, 22) << 1); 1922 // 31:23=000111100, 21=1, 11:10=01 1923 switch (switchVal) { 1924 case 0x0: 1925 // FCCMP flags = if cond the compareQuiet(Sn,Sm) else #nzcv 1926 return new FCCmpRegS(machInst, rn, rm, cond, imm); 1927 case 0x1: 1928 // FCCMP flags = if cond then compareSignaling(Sn,Sm) 1929 // else #nzcv 1930 return new FCCmpERegS(machInst, rn, rm, cond, imm); 1931 case 0x2: 1932 // FCCMP flags = if cond then compareQuiet(Dn,Dm) else #nzcv 1933 return new FCCmpRegD(machInst, rn, rm, cond, imm); 1934 case 0x3: 1935 // FCCMP flags = if cond then compareSignaling(Dn,Dm) 1936 // else #nzcv 1937 return new FCCmpERegD(machInst, rn, rm, cond, imm); 1938 default: 1939 return new Unknown64(machInst); 1940 } 1941 } 1942 case 0x2: 1943 { 1944 if (bits(machInst, 31) || 1945 bits(machInst, 29) || 1946 bits(machInst, 23)) { 1947 return new Unknown64(machInst); 1948 } 1949 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 1950 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 1951 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 20, 16); 1952 uint8_t switchVal = (bits(machInst, 15, 12) << 0) | 1953 (bits(machInst, 22) << 4); 1954 switch (switchVal) { 1955 case 0x00: // FMUL Sd = Sn * Sm 1956 return new FMulS(machInst, rd, rn, rm); 1957 case 0x10: // FMUL Dd = Dn * Dm 1958 return new FMulD(machInst, rd, rn, rm); 1959 case 0x01: // FDIV Sd = Sn / Sm 1960 return new FDivS(machInst, rd, rn, rm); 1961 case 0x11: // FDIV Dd = Dn / Dm 1962 return new FDivD(machInst, rd, rn, rm); 1963 case 0x02: // FADD Sd = Sn + Sm 1964 return new FAddS(machInst, rd, rn, rm); 1965 case 0x12: // FADD Dd = Dn + Dm 1966 return new FAddD(machInst, rd, rn, rm); 1967 case 0x03: // FSUB Sd = Sn - Sm 1968 return new FSubS(machInst, rd, rn, rm); 1969 case 0x13: // FSUB Dd = Dn - Dm 1970 return new FSubD(machInst, rd, rn, rm); 1971 case 0x04: // FMAX Sd = max(Sn, Sm) 1972 return new FMaxS(machInst, rd, rn, rm); 1973 case 0x14: // FMAX Dd = max(Dn, Dm) 1974 return new FMaxD(machInst, rd, rn, rm); 1975 case 0x05: // FMIN Sd = min(Sn, Sm) 1976 return new FMinS(machInst, rd, rn, rm); 1977 case 0x15: // FMIN Dd = min(Dn, Dm) 1978 return new FMinD(machInst, rd, rn, rm); 1979 case 0x06: // FMAXNM Sd = maxNum(Sn, Sm) 1980 return new FMaxNMS(machInst, rd, rn, rm); 1981 case 0x16: // FMAXNM Dd = maxNum(Dn, Dm) 1982 return new FMaxNMD(machInst, rd, rn, rm); 1983 case 0x07: // FMINNM Sd = minNum(Sn, Sm) 1984 return new FMinNMS(machInst, rd, rn, rm); 1985 case 0x17: // FMINNM Dd = minNum(Dn, Dm) 1986 return new FMinNMD(machInst, rd, rn, rm); 1987 case 0x08: // FNMUL Sd = -(Sn * Sm) 1988 return new FNMulS(machInst, rd, rn, rm); 1989 case 0x18: // FNMUL Dd = -(Dn * Dm) 1990 return new FNMulD(machInst, rd, rn, rm); 1991 default: 1992 return new Unknown64(machInst); 1993 } 1994 } 1995 case 0x3: 1996 { 1997 if (bits(machInst, 31) || bits(machInst, 29)) 1998 return new Unknown64(machInst); 1999 uint8_t type = bits(machInst, 23, 22); 2000 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 2001 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 2002 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 20, 16); 2003 ConditionCode cond = 2004 (ConditionCode)(uint8_t)(bits(machInst, 15, 12)); 2005 if (type == 0) // FCSEL Sd = if cond then Sn else Sm 2006 return new FCSelS(machInst, rd, rn, rm, cond); 2007 else if (type == 1) // FCSEL Dd = if cond then Dn else Dm 2008 return new FCSelD(machInst, rd, rn, rm, cond); 2009 else 2010 return new Unknown64(machInst); 2011 } 2012 default: 2013 M5_UNREACHABLE; 2014 } 2015 } 2016 M5_UNREACHABLE; 2017 } 2018} 2019}}; 2020 2021output decoder {{ 2022namespace Aarch64 2023{ 2024 StaticInstPtr 2025 decodeAdvSIMDScalar(ExtMachInst machInst) 2026 { 2027 if (bits(machInst, 24) == 1) { 2028 if (bits(machInst, 10) == 0) { 2029 return decodeNeonScIndexedElem(machInst); 2030 } else if (bits(machInst, 23) == 0) { 2031 return decodeNeonScShiftByImm(machInst); 2032 } 2033 } else if (bits(machInst, 21) == 1) { 2034 if (bits(machInst, 10) == 1) { 2035 return decodeNeonSc3Same(machInst); 2036 } else if (bits(machInst, 11) == 0) { 2037 return decodeNeonSc3Diff(machInst); 2038 } else if (bits(machInst, 20, 17) == 0x0) { 2039 return decodeNeonSc2RegMisc(machInst); 2040 } else if (bits(machInst, 20, 17) == 0x8) { 2041 return decodeNeonScPwise(machInst); 2042 } else { 2043 return new Unknown64(machInst); 2044 } 2045 } else if (bits(machInst, 23, 22) == 0 && 2046 bits(machInst, 15) == 0 && 2047 bits(machInst, 10) == 1) { 2048 return decodeNeonScCopy(machInst); 2049 } else { 2050 return new Unknown64(machInst); 2051 } 2052 return new FailUnimplemented("Unhandled Case6", machInst); 2053 } 2054} 2055}}; 2056 2057output decoder {{ 2058namespace Aarch64 2059{ 2060 template <typename DecoderFeatures> 2061 StaticInstPtr 2062 decodeFpAdvSIMD(ExtMachInst machInst) 2063 { 2064 2065 if (bits(machInst, 28) == 0) { 2066 if (bits(machInst, 31) == 0) { 2067 return decodeAdvSIMD<DecoderFeatures>(machInst); 2068 } else { 2069 return new Unknown64(machInst); 2070 } 2071 } else if (bits(machInst, 30) == 0) { 2072 return decodeFp(machInst); 2073 } else if (bits(machInst, 31) == 0) { 2074 return decodeAdvSIMDScalar(machInst); 2075 } else { 2076 return new Unknown64(machInst); 2077 } 2078 } 2079} 2080}}; 2081 2082let {{ 2083 decoder_output =''' 2084namespace Aarch64 2085{''' 2086 for decoderFlavour, type_dict in decoders.iteritems(): 2087 decoder_output +=''' 2088template StaticInstPtr decodeFpAdvSIMD<%(df)sDecoder>(ExtMachInst machInst); 2089''' % { "df" : decoderFlavour } 2090 decoder_output +=''' 2091}''' 2092}}; 2093 2094output decoder {{ 2095namespace Aarch64 2096{ 2097 StaticInstPtr 2098 decodeGem5Ops(ExtMachInst machInst) 2099 { 2100 const uint32_t m5func = bits(machInst, 23, 16); 2101 switch (m5func) { 2102 case M5OP_ARM: return new Arm(machInst); 2103 case M5OP_QUIESCE: return new Quiesce(machInst); 2104 case M5OP_QUIESCE_NS: return new QuiesceNs64(machInst); 2105 case M5OP_QUIESCE_CYCLE: return new QuiesceCycles64(machInst); 2106 case M5OP_QUIESCE_TIME: return new QuiesceTime64(machInst); 2107 case M5OP_RPNS: return new Rpns64(machInst); 2108 case M5OP_WAKE_CPU: return new WakeCPU64(machInst); 2109 case M5OP_DEPRECATED1: return new Deprecated_ivlb(machInst); 2110 case M5OP_DEPRECATED2: return new Deprecated_ivle(machInst); 2111 case M5OP_DEPRECATED3: return new Deprecated_exit (machInst); 2112 case M5OP_EXIT: return new M5exit64(machInst); 2113 case M5OP_FAIL: return new M5fail64(machInst); 2114 case M5OP_LOAD_SYMBOL: return new Loadsymbol(machInst); 2115 case M5OP_INIT_PARAM: return new Initparam64(machInst); 2116 case M5OP_RESET_STATS: return new Resetstats64(machInst); 2117 case M5OP_DUMP_STATS: return new Dumpstats64(machInst); 2118 case M5OP_DUMP_RESET_STATS: return new Dumpresetstats64(machInst); 2119 case M5OP_CHECKPOINT: return new M5checkpoint64(machInst); 2120 case M5OP_WRITE_FILE: return new M5writefile64(machInst); 2121 case M5OP_READ_FILE: return new M5readfile64(machInst); 2122 case M5OP_DEBUG_BREAK: return new M5break(machInst); 2123 case M5OP_SWITCH_CPU: return new M5switchcpu(machInst); 2124 case M5OP_ADD_SYMBOL: return new M5addsymbol64(machInst); 2125 case M5OP_PANIC: return new M5panic(machInst); 2126 case M5OP_WORK_BEGIN: return new M5workbegin64(machInst); 2127 case M5OP_WORK_END: return new M5workend64(machInst); 2128 default: return new Unknown64(machInst); 2129 } 2130 } 2131} 2132}}; 2133 2134def format Aarch64() {{ 2135 decode_block = ''' 2136 { 2137 using namespace Aarch64; 2138 if (bits(machInst, 27) == 0x0) { 2139 if (bits(machInst, 28) == 0x0) 2140 return new Unknown64(machInst); 2141 else if (bits(machInst, 26) == 0) 2142 // bit 28:26=100 2143 return decodeDataProcImm(machInst); 2144 else 2145 // bit 28:26=101 2146 return decodeBranchExcSys(machInst); 2147 } else if (bits(machInst, 25) == 0) { 2148 // bit 27=1, 25=0 2149 return decodeLoadsStores(machInst); 2150 } else if (bits(machInst, 26) == 0) { 2151 // bit 27:25=101 2152 return decodeDataProcReg(machInst); 2153 } else if (bits(machInst, 24) == 1 && 2154 bits(machInst, 31, 28) == 0xF) { 2155 return decodeGem5Ops(machInst); 2156 } else { 2157 // bit 27:25=111 2158 switch(decoderFlavour){ 2159 default: 2160 return decodeFpAdvSIMD<GenericDecoder>(machInst); 2161 } 2162 } 2163 } 2164 ''' 2165}}; 2166