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