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