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