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