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 decodeAtomicArithOp(ExtMachInst machInst) 545 { 546 uint8_t opc = bits(machInst, 14, 12); 547 uint8_t o3 = bits(machInst, 15); 548 uint8_t size_ar = bits(machInst, 23, 22)<<0 | bits(machInst, 31, 30)<<2; 549 IntRegIndex rt = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 550 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 551 IntRegIndex rnsp = makeSP(rn); 552 IntRegIndex rs = (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 553 uint8_t A_rt = bits(machInst, 4, 0)<<0 | bits(machInst, 23)<<5; 554 555 switch(opc) { 556 case 0x0: 557 switch(size_ar){ 558 case 0x0: 559 if (o3 == 1) 560 return new SWPB(machInst, rt, rnsp, rs); 561 else if (A_rt == 0x1f) 562 return new STADDB(machInst, rt, rnsp, rs); 563 else 564 return new LDADDB(machInst, rt, rnsp, rs); 565 case 0x1 : 566 if (o3 == 1) 567 return new SWPLB(machInst, rt, rnsp, rs); 568 else if (A_rt == 0x1f) 569 return new STADDLB(machInst, rt, rnsp, rs); 570 else 571 return new LDADDLB(machInst, rt, rnsp, rs); 572 case 0x2: 573 if (o3 == 1) 574 return new SWPAB(machInst, rt, rnsp, rs); 575 else 576 return new LDADDAB(machInst, rt, rnsp, rs); 577 case 0x3: 578 if (o3 == 1) 579 return new SWPLAB(machInst, rt, rnsp, rs); 580 else 581 return new LDADDLAB(machInst, rt, rnsp, rs); 582 case 0x4: 583 if (o3 == 1) 584 return new SWPH(machInst, rt, rnsp, rs); 585 else if (A_rt == 0x1f) 586 return new STADDH(machInst, rt, rnsp, rs); 587 else 588 return new LDADDH(machInst, rt, rnsp, rs); 589 case 0x5 : 590 if (o3 == 1) 591 return new SWPLH(machInst, rt, rnsp, rs); 592 else if (A_rt == 0x1f) 593 return new STADDLH(machInst, rt, rnsp, rs); 594 else 595 return new LDADDLH(machInst, rt, rnsp, rs); 596 case 0x6: 597 if (o3 == 1) 598 return new SWPAH(machInst, rt, rnsp, rs); 599 else 600 return new LDADDAH(machInst, rt, rnsp, rs); 601 case 0x7: 602 if (o3 == 1) 603 return new SWPLAH(machInst, rt, rnsp, rs); 604 else 605 return new LDADDLAH(machInst, rt, rnsp, rs); 606 case 0x8: 607 if (o3 == 1) 608 return new SWP(machInst, rt, rnsp, rs); 609 else if (A_rt == 0x1f) 610 return new STADD(machInst, rt, rnsp, rs); 611 else 612 return new LDADD(machInst, rt, rnsp, rs); 613 case 0x9 : 614 if (o3 == 1) 615 return new SWPL(machInst, rt, rnsp, rs); 616 else if (A_rt == 0x1f) 617 return new STADDL(machInst, rt, rnsp, rs); 618 else 619 return new LDADDL(machInst, rt, rnsp, rs); 620 case 0xa: 621 if (o3 == 1) 622 return new SWPA(machInst, rt, rnsp, rs); 623 else 624 return new LDADDA(machInst, rt, rnsp, rs); 625 case 0xb: 626 if (o3 == 1) 627 return new SWPLA(machInst, rt, rnsp, rs); 628 else 629 return new LDADDLA(machInst, rt, rnsp, rs); 630 case 0xc: 631 if (o3 == 1) 632 return new SWP64(machInst, rt, rnsp, rs); 633 634 else if (A_rt == 0x1f) 635 return new STADD64(machInst, rt, rnsp, rs); 636 else 637 return new LDADD64(machInst, rt, rnsp, rs); 638 case 0xd : 639 if (o3 == 1) 640 return new SWPL64(machInst, rt, rnsp, rs); 641 else if (A_rt == 0x1f) 642 return new STADDL64(machInst, rt, rnsp, rs); 643 else 644 return new LDADDL64(machInst, rt, rnsp, rs); 645 case 0xe: 646 if (o3 == 1) 647 return new SWPA64(machInst, rt, rnsp, rs); 648 else 649 return new LDADDA64(machInst, rt, rnsp, rs); 650 case 0xf: 651 if (o3 == 1) 652 return new SWPLA64(machInst, rt, rnsp, rs); 653 else 654 return new LDADDLA64(machInst, rt, rnsp, rs);
| 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 decodeAtomicArithOp(ExtMachInst machInst) 545 { 546 uint8_t opc = bits(machInst, 14, 12); 547 uint8_t o3 = bits(machInst, 15); 548 uint8_t size_ar = bits(machInst, 23, 22)<<0 | bits(machInst, 31, 30)<<2; 549 IntRegIndex rt = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 550 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 551 IntRegIndex rnsp = makeSP(rn); 552 IntRegIndex rs = (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 553 uint8_t A_rt = bits(machInst, 4, 0)<<0 | bits(machInst, 23)<<5; 554 555 switch(opc) { 556 case 0x0: 557 switch(size_ar){ 558 case 0x0: 559 if (o3 == 1) 560 return new SWPB(machInst, rt, rnsp, rs); 561 else if (A_rt == 0x1f) 562 return new STADDB(machInst, rt, rnsp, rs); 563 else 564 return new LDADDB(machInst, rt, rnsp, rs); 565 case 0x1 : 566 if (o3 == 1) 567 return new SWPLB(machInst, rt, rnsp, rs); 568 else if (A_rt == 0x1f) 569 return new STADDLB(machInst, rt, rnsp, rs); 570 else 571 return new LDADDLB(machInst, rt, rnsp, rs); 572 case 0x2: 573 if (o3 == 1) 574 return new SWPAB(machInst, rt, rnsp, rs); 575 else 576 return new LDADDAB(machInst, rt, rnsp, rs); 577 case 0x3: 578 if (o3 == 1) 579 return new SWPLAB(machInst, rt, rnsp, rs); 580 else 581 return new LDADDLAB(machInst, rt, rnsp, rs); 582 case 0x4: 583 if (o3 == 1) 584 return new SWPH(machInst, rt, rnsp, rs); 585 else if (A_rt == 0x1f) 586 return new STADDH(machInst, rt, rnsp, rs); 587 else 588 return new LDADDH(machInst, rt, rnsp, rs); 589 case 0x5 : 590 if (o3 == 1) 591 return new SWPLH(machInst, rt, rnsp, rs); 592 else if (A_rt == 0x1f) 593 return new STADDLH(machInst, rt, rnsp, rs); 594 else 595 return new LDADDLH(machInst, rt, rnsp, rs); 596 case 0x6: 597 if (o3 == 1) 598 return new SWPAH(machInst, rt, rnsp, rs); 599 else 600 return new LDADDAH(machInst, rt, rnsp, rs); 601 case 0x7: 602 if (o3 == 1) 603 return new SWPLAH(machInst, rt, rnsp, rs); 604 else 605 return new LDADDLAH(machInst, rt, rnsp, rs); 606 case 0x8: 607 if (o3 == 1) 608 return new SWP(machInst, rt, rnsp, rs); 609 else if (A_rt == 0x1f) 610 return new STADD(machInst, rt, rnsp, rs); 611 else 612 return new LDADD(machInst, rt, rnsp, rs); 613 case 0x9 : 614 if (o3 == 1) 615 return new SWPL(machInst, rt, rnsp, rs); 616 else if (A_rt == 0x1f) 617 return new STADDL(machInst, rt, rnsp, rs); 618 else 619 return new LDADDL(machInst, rt, rnsp, rs); 620 case 0xa: 621 if (o3 == 1) 622 return new SWPA(machInst, rt, rnsp, rs); 623 else 624 return new LDADDA(machInst, rt, rnsp, rs); 625 case 0xb: 626 if (o3 == 1) 627 return new SWPLA(machInst, rt, rnsp, rs); 628 else 629 return new LDADDLA(machInst, rt, rnsp, rs); 630 case 0xc: 631 if (o3 == 1) 632 return new SWP64(machInst, rt, rnsp, rs); 633 634 else if (A_rt == 0x1f) 635 return new STADD64(machInst, rt, rnsp, rs); 636 else 637 return new LDADD64(machInst, rt, rnsp, rs); 638 case 0xd : 639 if (o3 == 1) 640 return new SWPL64(machInst, rt, rnsp, rs); 641 else if (A_rt == 0x1f) 642 return new STADDL64(machInst, rt, rnsp, rs); 643 else 644 return new LDADDL64(machInst, rt, rnsp, rs); 645 case 0xe: 646 if (o3 == 1) 647 return new SWPA64(machInst, rt, rnsp, rs); 648 else 649 return new LDADDA64(machInst, rt, rnsp, rs); 650 case 0xf: 651 if (o3 == 1) 652 return new SWPLA64(machInst, rt, rnsp, rs); 653 else 654 return new LDADDLA64(machInst, rt, rnsp, rs);
|
1068 } 1069 default: 1070 return new Unknown64(machInst); 1071 } 1072 } 1073} 1074}}; 1075 1076 1077output decoder {{ 1078namespace Aarch64 1079{ 1080 1081 StaticInstPtr 1082 decodeLoadsStores(ExtMachInst machInst) 1083 { 1084 // bit 27,25=10 1085 switch (bits(machInst, 29, 28)) { 1086 case 0x0: 1087 if (bits(machInst, 26) == 0) { 1088 if (bits(machInst, 24) != 0) 1089 return new Unknown64(machInst); 1090 IntRegIndex rt = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 1091 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 1092 IntRegIndex rnsp = makeSP(rn); 1093 IntRegIndex rt2 = (IntRegIndex)(uint8_t)bits(machInst, 14, 10); 1094 IntRegIndex rs = (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 1095 uint8_t opc = (bits(machInst, 15) << 0) | 1096 (bits(machInst, 23, 21) << 1); 1097 uint8_t size = bits(machInst, 31, 30); 1098 switch (opc) { 1099 case 0x0: 1100 switch (size) { 1101 case 0x0: 1102 return new STXRB64(machInst, rt, rnsp, rs); 1103 case 0x1: 1104 return new STXRH64(machInst, rt, rnsp, rs); 1105 case 0x2: 1106 return new STXRW64(machInst, rt, rnsp, rs); 1107 case 0x3: 1108 return new STXRX64(machInst, rt, rnsp, rs); 1109 default: 1110 M5_UNREACHABLE; 1111 } 1112 case 0x1: 1113 switch (size) { 1114 case 0x0: 1115 return new STLXRB64(machInst, rt, rnsp, rs); 1116 case 0x1: 1117 return new STLXRH64(machInst, rt, rnsp, rs); 1118 case 0x2: 1119 return new STLXRW64(machInst, rt, rnsp, rs); 1120 case 0x3: 1121 return new STLXRX64(machInst, rt, rnsp, rs); 1122 default: 1123 M5_UNREACHABLE; 1124 } 1125 case 0x2: 1126 switch (size) { 1127 case 0x0: 1128 return new CASP32(machInst, rt, rnsp, rs); 1129 case 0x1: 1130 return new CASP64(machInst, rt, rnsp, rs); 1131 case 0x2: 1132 return new STXPW64(machInst, rs, rt, rt2, rnsp); 1133 case 0x3: 1134 return new STXPX64(machInst, rs, rt, rt2, rnsp); 1135 default: 1136 M5_UNREACHABLE; 1137 } 1138 1139 case 0x3: 1140 switch (size) { 1141 case 0x0: 1142 return new CASPL32(machInst, rt, rnsp, rs); 1143 case 0x1: 1144 return new CASPL64(machInst, rt, rnsp, rs); 1145 case 0x2: 1146 return new STLXPW64(machInst, rs, rt, rt2, rnsp); 1147 case 0x3: 1148 return new STLXPX64(machInst, rs, rt, rt2, rnsp); 1149 default: 1150 M5_UNREACHABLE; 1151 } 1152 1153 case 0x4: 1154 switch (size) { 1155 case 0x0: 1156 return new LDXRB64(machInst, rt, rnsp, rs); 1157 case 0x1: 1158 return new LDXRH64(machInst, rt, rnsp, rs); 1159 case 0x2: 1160 return new LDXRW64(machInst, rt, rnsp, rs); 1161 case 0x3: 1162 return new LDXRX64(machInst, rt, rnsp, rs); 1163 default: 1164 M5_UNREACHABLE; 1165 } 1166 case 0x5: 1167 switch (size) { 1168 case 0x0: 1169 return new LDAXRB64(machInst, rt, rnsp, rs); 1170 case 0x1: 1171 return new LDAXRH64(machInst, rt, rnsp, rs); 1172 case 0x2: 1173 return new LDAXRW64(machInst, rt, rnsp, rs); 1174 case 0x3: 1175 return new LDAXRX64(machInst, rt, rnsp, rs); 1176 default: 1177 M5_UNREACHABLE; 1178 } 1179 case 0x6: 1180 switch (size) { 1181 case 0x0: 1182 return new CASPA32(machInst, rt, rnsp, rs); 1183 case 0x1: 1184 return new CASPA64(machInst, rt, rnsp, rs); 1185 case 0x2: 1186 return new LDXPW64(machInst, rt, rt2, rnsp); 1187 case 0x3: 1188 return new LDXPX64(machInst, rt, rt2, rnsp); 1189 default: 1190 M5_UNREACHABLE; 1191 } 1192 case 0x7: 1193 switch (size) { 1194 case 0x0: 1195 return new CASPAL32(machInst, rt, rnsp, rs); 1196 case 0x1: 1197 return new CASPAL64(machInst, rt, rnsp, rs); 1198 case 0x2: 1199 return new LDAXPW64(machInst, rt, rt2, rnsp); 1200 case 0x3: 1201 return new LDAXPX64(machInst, rt, rt2, rnsp); 1202 default: 1203 M5_UNREACHABLE; 1204 } 1205 case 0x9: 1206 switch (size) { 1207 case 0x0: 1208 return new STLRB64(machInst, rt, rnsp); 1209 case 0x1: 1210 return new STLRH64(machInst, rt, rnsp); 1211 case 0x2: 1212 return new STLRW64(machInst, rt, rnsp); 1213 case 0x3: 1214 return new STLRX64(machInst, rt, rnsp); 1215 default: 1216 M5_UNREACHABLE; 1217 } 1218 case 0xa: 1219 switch (size) { 1220 case 0x0: 1221 return new CASB(machInst, rt, rnsp, rs); 1222 case 0x1: 1223 return new CASH(machInst, rt, rnsp, rs); 1224 case 0x2: 1225 return new CAS32(machInst, rt, rnsp, rs); 1226 case 0x3: 1227 return new CAS64(machInst, rt, rnsp, rs); 1228 default: 1229 M5_UNREACHABLE; 1230 } 1231 case 0xb: 1232 switch (size) { 1233 case 0x0: 1234 return new CASLB(machInst, rt, rnsp, rs); 1235 case 0x1: 1236 return new CASLH(machInst, rt, rnsp, rs); 1237 case 0x2: 1238 return new CASL32(machInst, rt, rnsp, rs); 1239 case 0x3: 1240 return new CASL64(machInst, rt, rnsp, rs); 1241 default: 1242 M5_UNREACHABLE; 1243 } 1244 case 0xd: 1245 switch (size) { 1246 case 0x0: 1247 return new LDARB64(machInst, rt, rnsp); 1248 case 0x1: 1249 return new LDARH64(machInst, rt, rnsp); 1250 case 0x2: 1251 return new LDARW64(machInst, rt, rnsp); 1252 case 0x3: 1253 return new LDARX64(machInst, rt, rnsp); 1254 default: 1255 M5_UNREACHABLE; 1256 } 1257 case 0xe: 1258 switch (size) { 1259 case 0x0: 1260 return new CASAB(machInst, rt, rnsp, rs); 1261 case 0x1: 1262 return new CASAH(machInst, rt, rnsp, rs); 1263 case 0x2: 1264 return new CASA32(machInst, rt, rnsp, rs); 1265 case 0x3: 1266 return new CASA64(machInst, rt, rnsp, rs); 1267 default: 1268 M5_UNREACHABLE; 1269 } 1270 case 0xf: 1271 switch (size) { 1272 case 0x0: 1273 return new CASALB(machInst, rt, rnsp, rs); 1274 case 0x1: 1275 return new CASALH(machInst, rt, rnsp, rs); 1276 case 0x2: 1277 return new CASAL32(machInst, rt, rnsp, rs); 1278 case 0x3: 1279 return new CASAL64(machInst, rt, rnsp, rs); 1280 default: 1281 M5_UNREACHABLE; 1282 } 1283 default: 1284 return new Unknown64(machInst); 1285 } 1286 } else if (bits(machInst, 31)) { 1287 return new Unknown64(machInst); 1288 } else { 1289 return decodeNeonMem(machInst); 1290 } 1291 case 0x1: 1292 { 1293 if (bits(machInst, 24) != 0) 1294 return new Unknown64(machInst); 1295 uint8_t switchVal = (bits(machInst, 26) << 0) | 1296 (bits(machInst, 31, 30) << 1); 1297 int64_t imm = sext<19>(bits(machInst, 23, 5)) << 2; 1298 IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 1299 switch (switchVal) { 1300 case 0x0: 1301 return new LDRWL64_LIT(machInst, rt, imm); 1302 case 0x1: 1303 return new LDRSFP64_LIT(machInst, rt, imm); 1304 case 0x2: 1305 return new LDRXL64_LIT(machInst, rt, imm); 1306 case 0x3: 1307 return new LDRDFP64_LIT(machInst, rt, imm); 1308 case 0x4: 1309 return new LDRSWL64_LIT(machInst, rt, imm); 1310 case 0x5: 1311 return new BigFpMemLit("ldr", machInst, rt, imm); 1312 case 0x6: 1313 return new PRFM64_LIT(machInst, rt, imm); 1314 default: 1315 return new Unknown64(machInst); 1316 } 1317 } 1318 case 0x2: 1319 { 1320 uint8_t opc = bits(machInst, 31, 30); 1321 if (opc >= 3) 1322 return new Unknown64(machInst); 1323 uint32_t size = 0; 1324 bool fp = bits(machInst, 26); 1325 bool load = bits(machInst, 22); 1326 if (fp) { 1327 size = 4 << opc; 1328 } else { 1329 if ((opc == 1) && !load) 1330 return new Unknown64(machInst); 1331 size = (opc == 0 || opc == 1) ? 4 : 8; 1332 } 1333 uint8_t type = bits(machInst, 24, 23); 1334 int64_t imm = sext<7>(bits(machInst, 21, 15)) * size; 1335 1336 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 1337 IntRegIndex rt = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 1338 IntRegIndex rt2 = (IntRegIndex)(uint8_t)bits(machInst, 14, 10); 1339 1340 bool noAlloc = (type == 0); 1341 bool signExt = !noAlloc && !fp && opc == 1; 1342 PairMemOp::AddrMode mode; 1343 const char *mnemonic = NULL; 1344 switch (type) { 1345 case 0x0: 1346 case 0x2: 1347 mode = PairMemOp::AddrMd_Offset; 1348 break; 1349 case 0x1: 1350 mode = PairMemOp::AddrMd_PostIndex; 1351 break; 1352 case 0x3: 1353 mode = PairMemOp::AddrMd_PreIndex; 1354 break; 1355 default: 1356 return new Unknown64(machInst); 1357 } 1358 if (load) { 1359 if (noAlloc) 1360 mnemonic = "ldnp"; 1361 else if (signExt) 1362 mnemonic = "ldpsw"; 1363 else 1364 mnemonic = "ldp"; 1365 } else { 1366 if (noAlloc) 1367 mnemonic = "stnp"; 1368 else 1369 mnemonic = "stp"; 1370 } 1371 1372 return new LdpStp(mnemonic, machInst, size, fp, load, noAlloc, 1373 signExt, false, false, imm, mode, rn, rt, rt2); 1374 } 1375 // bit 29:27=111, 25=0 1376 case 0x3: 1377 { 1378 uint8_t switchVal = (bits(machInst, 23, 22) << 0) | 1379 (bits(machInst, 26) << 2) | 1380 (bits(machInst, 31, 30) << 3); 1381 if (bits(machInst, 24) == 1) { 1382 uint64_t imm12 = bits(machInst, 21, 10); 1383 IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 1384 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 1385 IntRegIndex rnsp = makeSP(rn); 1386 switch (switchVal) { 1387 case 0x00: 1388 return new STRB64_IMM(machInst, rt, rnsp, imm12); 1389 case 0x01: 1390 return new LDRB64_IMM(machInst, rt, rnsp, imm12); 1391 case 0x02: 1392 return new LDRSBX64_IMM(machInst, rt, rnsp, imm12); 1393 case 0x03: 1394 return new LDRSBW64_IMM(machInst, rt, rnsp, imm12); 1395 case 0x04: 1396 return new STRBFP64_IMM(machInst, rt, rnsp, imm12); 1397 case 0x05: 1398 return new LDRBFP64_IMM(machInst, rt, rnsp, imm12); 1399 case 0x06: 1400 return new BigFpMemImm("str", machInst, false, 1401 rt, rnsp, imm12 << 4); 1402 case 0x07: 1403 return new BigFpMemImm("ldr", machInst, true, 1404 rt, rnsp, imm12 << 4); 1405 case 0x08: 1406 return new STRH64_IMM(machInst, rt, rnsp, imm12 << 1); 1407 case 0x09: 1408 return new LDRH64_IMM(machInst, rt, rnsp, imm12 << 1); 1409 case 0x0a: 1410 return new LDRSHX64_IMM(machInst, rt, rnsp, imm12 << 1); 1411 case 0x0b: 1412 return new LDRSHW64_IMM(machInst, rt, rnsp, imm12 << 1); 1413 case 0x0c: 1414 return new STRHFP64_IMM(machInst, rt, rnsp, imm12 << 1); 1415 case 0x0d: 1416 return new LDRHFP64_IMM(machInst, rt, rnsp, imm12 << 1); 1417 case 0x10: 1418 return new STRW64_IMM(machInst, rt, rnsp, imm12 << 2); 1419 case 0x11: 1420 return new LDRW64_IMM(machInst, rt, rnsp, imm12 << 2); 1421 case 0x12: 1422 return new LDRSW64_IMM(machInst, rt, rnsp, imm12 << 2); 1423 case 0x14: 1424 return new STRSFP64_IMM(machInst, rt, rnsp, imm12 << 2); 1425 case 0x15: 1426 return new LDRSFP64_IMM(machInst, rt, rnsp, imm12 << 2); 1427 case 0x18: 1428 return new STRX64_IMM(machInst, rt, rnsp, imm12 << 3); 1429 case 0x19: 1430 return new LDRX64_IMM(machInst, rt, rnsp, imm12 << 3); 1431 case 0x1a: 1432 return new PRFM64_IMM(machInst, rt, rnsp, imm12 << 3); 1433 case 0x1c: 1434 return new STRDFP64_IMM(machInst, rt, rnsp, imm12 << 3); 1435 case 0x1d: 1436 return new LDRDFP64_IMM(machInst, rt, rnsp, imm12 << 3); 1437 default: 1438 return new Unknown64(machInst); 1439 } 1440 } else if (bits(machInst, 21) == 1) { 1441 uint8_t group = bits(machInst, 11, 10); 1442 switch (group) { 1443 case 0x0: 1444 { 1445 if ((switchVal & 0x7) == 0x2 && 1446 bits(machInst, 20, 12) == 0x1fc) { 1447 IntRegIndex rt = (IntRegIndex)(uint32_t) 1448 bits(machInst, 4, 0); 1449 IntRegIndex rn = (IntRegIndex)(uint32_t) 1450 bits(machInst, 9, 5); 1451 IntRegIndex rnsp = makeSP(rn); 1452 uint8_t size = bits(machInst, 31, 30); 1453 switch (size) { 1454 case 0x0: 1455 return new LDAPRB64(machInst, rt, rnsp); 1456 case 0x1: 1457 return new LDAPRH64(machInst, rt, rnsp); 1458 case 0x2: 1459 return new LDAPRW64(machInst, rt, rnsp); 1460 case 0x3: 1461 return new LDAPRX64(machInst, rt, rnsp); 1462 default: 1463 M5_UNREACHABLE; 1464 } 1465 } else { 1466 return decodeAtomicArithOp(machInst); 1467 } 1468 } 1469 case 0x2: 1470 { 1471 if (!bits(machInst, 14)) 1472 return new Unknown64(machInst); 1473 IntRegIndex rt = (IntRegIndex)(uint32_t) 1474 bits(machInst, 4, 0); 1475 IntRegIndex rn = (IntRegIndex)(uint32_t) 1476 bits(machInst, 9, 5); 1477 IntRegIndex rnsp = makeSP(rn); 1478 IntRegIndex rm = (IntRegIndex)(uint32_t) 1479 bits(machInst, 20, 16); 1480 ArmExtendType type = 1481 (ArmExtendType)(uint32_t)bits(machInst, 15, 13); 1482 uint8_t s = bits(machInst, 12); 1483 switch (switchVal) { 1484 case 0x00: 1485 return new STRB64_REG(machInst, rt, rnsp, rm, 1486 type, 0); 1487 case 0x01: 1488 return new LDRB64_REG(machInst, rt, rnsp, rm, 1489 type, 0); 1490 case 0x02: 1491 return new LDRSBX64_REG(machInst, rt, rnsp, rm, 1492 type, 0); 1493 case 0x03: 1494 return new LDRSBW64_REG(machInst, rt, rnsp, rm, 1495 type, 0); 1496 case 0x04: 1497 return new STRBFP64_REG(machInst, rt, rnsp, rm, 1498 type, 0); 1499 case 0x05: 1500 return new LDRBFP64_REG(machInst, rt, rnsp, rm, 1501 type, 0); 1502 case 0x6: 1503 return new BigFpMemReg("str", machInst, false, 1504 rt, rnsp, rm, type, s * 4); 1505 case 0x7: 1506 return new BigFpMemReg("ldr", machInst, true, 1507 rt, rnsp, rm, type, s * 4); 1508 case 0x08: 1509 return new STRH64_REG(machInst, rt, rnsp, rm, 1510 type, s); 1511 case 0x09: 1512 return new LDRH64_REG(machInst, rt, rnsp, rm, 1513 type, s); 1514 case 0x0a: 1515 return new LDRSHX64_REG(machInst, rt, rnsp, rm, 1516 type, s); 1517 case 0x0b: 1518 return new LDRSHW64_REG(machInst, rt, rnsp, rm, 1519 type, s); 1520 case 0x0c: 1521 return new STRHFP64_REG(machInst, rt, rnsp, rm, 1522 type, s); 1523 case 0x0d: 1524 return new LDRHFP64_REG(machInst, rt, rnsp, rm, 1525 type, s); 1526 case 0x10: 1527 return new STRW64_REG(machInst, rt, rnsp, rm, 1528 type, s * 2); 1529 case 0x11: 1530 return new LDRW64_REG(machInst, rt, rnsp, rm, 1531 type, s * 2); 1532 case 0x12: 1533 return new LDRSW64_REG(machInst, rt, rnsp, rm, 1534 type, s * 2); 1535 case 0x14: 1536 return new STRSFP64_REG(machInst, rt, rnsp, rm, 1537 type, s * 2); 1538 case 0x15: 1539 return new LDRSFP64_REG(machInst, rt, rnsp, rm, 1540 type, s * 2); 1541 case 0x18: 1542 return new STRX64_REG(machInst, rt, rnsp, rm, 1543 type, s * 3); 1544 case 0x19: 1545 return new LDRX64_REG(machInst, rt, rnsp, rm, 1546 type, s * 3); 1547 case 0x1a: 1548 return new PRFM64_REG(machInst, rt, rnsp, rm, 1549 type, s * 3); 1550 case 0x1c: 1551 return new STRDFP64_REG(machInst, rt, rnsp, rm, 1552 type, s * 3); 1553 case 0x1d: 1554 return new LDRDFP64_REG(machInst, rt, rnsp, rm, 1555 type, s * 3); 1556 default: 1557 return new Unknown64(machInst); 1558 1559 } 1560 } 1561 default: 1562 return new Unknown64(machInst); 1563 } 1564 } else { 1565 // bit 29:27=111, 25:24=00, 21=0 1566 switch (bits(machInst, 11, 10)) { 1567 case 0x0: 1568 { 1569 IntRegIndex rt = 1570 (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 1571 IntRegIndex rn = 1572 (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 1573 IntRegIndex rnsp = makeSP(rn); 1574 uint64_t imm = sext<9>(bits(machInst, 20, 12)); 1575 switch (switchVal) { 1576 case 0x00: 1577 return new STURB64_IMM(machInst, rt, rnsp, imm); 1578 case 0x01: 1579 return new LDURB64_IMM(machInst, rt, rnsp, imm); 1580 case 0x02: 1581 return new LDURSBX64_IMM(machInst, rt, rnsp, imm); 1582 case 0x03: 1583 return new LDURSBW64_IMM(machInst, rt, rnsp, imm); 1584 case 0x04: 1585 return new STURBFP64_IMM(machInst, rt, rnsp, imm); 1586 case 0x05: 1587 return new LDURBFP64_IMM(machInst, rt, rnsp, imm); 1588 case 0x06: 1589 return new BigFpMemImm("stur", machInst, false, 1590 rt, rnsp, imm); 1591 case 0x07: 1592 return new BigFpMemImm("ldur", machInst, true, 1593 rt, rnsp, imm); 1594 case 0x08: 1595 return new STURH64_IMM(machInst, rt, rnsp, imm); 1596 case 0x09: 1597 return new LDURH64_IMM(machInst, rt, rnsp, imm); 1598 case 0x0a: 1599 return new LDURSHX64_IMM(machInst, rt, rnsp, imm); 1600 case 0x0b: 1601 return new LDURSHW64_IMM(machInst, rt, rnsp, imm); 1602 case 0x0c: 1603 return new STURHFP64_IMM(machInst, rt, rnsp, imm); 1604 case 0x0d: 1605 return new LDURHFP64_IMM(machInst, rt, rnsp, imm); 1606 case 0x10: 1607 return new STURW64_IMM(machInst, rt, rnsp, imm); 1608 case 0x11: 1609 return new LDURW64_IMM(machInst, rt, rnsp, imm); 1610 case 0x12: 1611 return new LDURSW64_IMM(machInst, rt, rnsp, imm); 1612 case 0x14: 1613 return new STURSFP64_IMM(machInst, rt, rnsp, imm); 1614 case 0x15: 1615 return new LDURSFP64_IMM(machInst, rt, rnsp, imm); 1616 case 0x18: 1617 return new STURX64_IMM(machInst, rt, rnsp, imm); 1618 case 0x19: 1619 return new LDURX64_IMM(machInst, rt, rnsp, imm); 1620 case 0x1a: 1621 return new PRFUM64_IMM(machInst, rt, rnsp, imm); 1622 case 0x1c: 1623 return new STURDFP64_IMM(machInst, rt, rnsp, imm); 1624 case 0x1d: 1625 return new LDURDFP64_IMM(machInst, rt, rnsp, imm); 1626 default: 1627 return new Unknown64(machInst); 1628 } 1629 } 1630 // bit 29:27=111, 25:24=00, 21=0, 11:10=01 1631 case 0x1: 1632 { 1633 IntRegIndex rt = 1634 (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 1635 IntRegIndex rn = 1636 (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 1637 IntRegIndex rnsp = makeSP(rn); 1638 uint64_t imm = sext<9>(bits(machInst, 20, 12)); 1639 switch (switchVal) { 1640 case 0x00: 1641 return new STRB64_POST(machInst, rt, rnsp, imm); 1642 case 0x01: 1643 return new LDRB64_POST(machInst, rt, rnsp, imm); 1644 case 0x02: 1645 return new LDRSBX64_POST(machInst, rt, rnsp, imm); 1646 case 0x03: 1647 return new LDRSBW64_POST(machInst, rt, rnsp, imm); 1648 case 0x04: 1649 return new STRBFP64_POST(machInst, rt, rnsp, imm); 1650 case 0x05: 1651 return new LDRBFP64_POST(machInst, rt, rnsp, imm); 1652 case 0x06: 1653 return new BigFpMemPost("str", machInst, false, 1654 rt, rnsp, imm); 1655 case 0x07: 1656 return new BigFpMemPost("ldr", machInst, true, 1657 rt, rnsp, imm); 1658 case 0x08: 1659 return new STRH64_POST(machInst, rt, rnsp, imm); 1660 case 0x09: 1661 return new LDRH64_POST(machInst, rt, rnsp, imm); 1662 case 0x0a: 1663 return new LDRSHX64_POST(machInst, rt, rnsp, imm); 1664 case 0x0b: 1665 return new LDRSHW64_POST(machInst, rt, rnsp, imm); 1666 case 0x0c: 1667 return new STRHFP64_POST(machInst, rt, rnsp, imm); 1668 case 0x0d: 1669 return new LDRHFP64_POST(machInst, rt, rnsp, imm); 1670 case 0x10: 1671 return new STRW64_POST(machInst, rt, rnsp, imm); 1672 case 0x11: 1673 return new LDRW64_POST(machInst, rt, rnsp, imm); 1674 case 0x12: 1675 return new LDRSW64_POST(machInst, rt, rnsp, imm); 1676 case 0x14: 1677 return new STRSFP64_POST(machInst, rt, rnsp, imm); 1678 case 0x15: 1679 return new LDRSFP64_POST(machInst, rt, rnsp, imm); 1680 case 0x18: 1681 return new STRX64_POST(machInst, rt, rnsp, imm); 1682 case 0x19: 1683 return new LDRX64_POST(machInst, rt, rnsp, imm); 1684 case 0x1c: 1685 return new STRDFP64_POST(machInst, rt, rnsp, imm); 1686 case 0x1d: 1687 return new LDRDFP64_POST(machInst, rt, rnsp, imm); 1688 default: 1689 return new Unknown64(machInst); 1690 } 1691 } 1692 case 0x2: 1693 { 1694 IntRegIndex rt = 1695 (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 1696 IntRegIndex rn = 1697 (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 1698 IntRegIndex rnsp = makeSP(rn); 1699 uint64_t imm = sext<9>(bits(machInst, 20, 12)); 1700 switch (switchVal) { 1701 case 0x00: 1702 return new STTRB64_IMM(machInst, rt, rnsp, imm); 1703 case 0x01: 1704 return new LDTRB64_IMM(machInst, rt, rnsp, imm); 1705 case 0x02: 1706 return new LDTRSBX64_IMM(machInst, rt, rnsp, imm); 1707 case 0x03: 1708 return new LDTRSBW64_IMM(machInst, rt, rnsp, imm); 1709 case 0x08: 1710 return new STTRH64_IMM(machInst, rt, rnsp, imm); 1711 case 0x09: 1712 return new LDTRH64_IMM(machInst, rt, rnsp, imm); 1713 case 0x0a: 1714 return new LDTRSHX64_IMM(machInst, rt, rnsp, imm); 1715 case 0x0b: 1716 return new LDTRSHW64_IMM(machInst, rt, rnsp, imm); 1717 case 0x10: 1718 return new STTRW64_IMM(machInst, rt, rnsp, imm); 1719 case 0x11: 1720 return new LDTRW64_IMM(machInst, rt, rnsp, imm); 1721 case 0x12: 1722 return new LDTRSW64_IMM(machInst, rt, rnsp, imm); 1723 case 0x18: 1724 return new STTRX64_IMM(machInst, rt, rnsp, imm); 1725 case 0x19: 1726 return new LDTRX64_IMM(machInst, rt, rnsp, imm); 1727 default: 1728 return new Unknown64(machInst); 1729 } 1730 } 1731 case 0x3: 1732 { 1733 IntRegIndex rt = 1734 (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 1735 IntRegIndex rn = 1736 (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 1737 IntRegIndex rnsp = makeSP(rn); 1738 uint64_t imm = sext<9>(bits(machInst, 20, 12)); 1739 switch (switchVal) { 1740 case 0x00: 1741 return new STRB64_PRE(machInst, rt, rnsp, imm); 1742 case 0x01: 1743 return new LDRB64_PRE(machInst, rt, rnsp, imm); 1744 case 0x02: 1745 return new LDRSBX64_PRE(machInst, rt, rnsp, imm); 1746 case 0x03: 1747 return new LDRSBW64_PRE(machInst, rt, rnsp, imm); 1748 case 0x04: 1749 return new STRBFP64_PRE(machInst, rt, rnsp, imm); 1750 case 0x05: 1751 return new LDRBFP64_PRE(machInst, rt, rnsp, imm); 1752 case 0x06: 1753 return new BigFpMemPre("str", machInst, false, 1754 rt, rnsp, imm); 1755 case 0x07: 1756 return new BigFpMemPre("ldr", machInst, true, 1757 rt, rnsp, imm); 1758 case 0x08: 1759 return new STRH64_PRE(machInst, rt, rnsp, imm); 1760 case 0x09: 1761 return new LDRH64_PRE(machInst, rt, rnsp, imm); 1762 case 0x0a: 1763 return new LDRSHX64_PRE(machInst, rt, rnsp, imm); 1764 case 0x0b: 1765 return new LDRSHW64_PRE(machInst, rt, rnsp, imm); 1766 case 0x0c: 1767 return new STRHFP64_PRE(machInst, rt, rnsp, imm); 1768 case 0x0d: 1769 return new LDRHFP64_PRE(machInst, rt, rnsp, imm); 1770 case 0x10: 1771 return new STRW64_PRE(machInst, rt, rnsp, imm); 1772 case 0x11: 1773 return new LDRW64_PRE(machInst, rt, rnsp, imm); 1774 case 0x12: 1775 return new LDRSW64_PRE(machInst, rt, rnsp, imm); 1776 case 0x14: 1777 return new STRSFP64_PRE(machInst, rt, rnsp, imm); 1778 case 0x15: 1779 return new LDRSFP64_PRE(machInst, rt, rnsp, imm); 1780 case 0x18: 1781 return new STRX64_PRE(machInst, rt, rnsp, imm); 1782 case 0x19: 1783 return new LDRX64_PRE(machInst, rt, rnsp, imm); 1784 case 0x1c: 1785 return new STRDFP64_PRE(machInst, rt, rnsp, imm); 1786 case 0x1d: 1787 return new LDRDFP64_PRE(machInst, rt, rnsp, imm); 1788 default: 1789 return new Unknown64(machInst); 1790 } 1791 } 1792 default: 1793 M5_UNREACHABLE; 1794 } 1795 } 1796 } 1797 default: 1798 M5_UNREACHABLE; 1799 } 1800 return new FailUnimplemented("Unhandled Case1", machInst); 1801 } 1802} 1803}}; 1804 1805output decoder {{ 1806namespace Aarch64 1807{ 1808 StaticInstPtr 1809 decodeDataProcReg(ExtMachInst machInst) 1810 { 1811 uint8_t switchVal = (bits(machInst, 28) << 1) | 1812 (bits(machInst, 24) << 0); 1813 switch (switchVal) { 1814 case 0x0: 1815 { 1816 uint8_t switchVal = (bits(machInst, 21) << 0) | 1817 (bits(machInst, 30, 29) << 1); 1818 ArmShiftType type = (ArmShiftType)(uint8_t)bits(machInst, 23, 22); 1819 uint8_t imm6 = bits(machInst, 15, 10); 1820 bool sf = bits(machInst, 31); 1821 if (!sf && (imm6 & 0x20)) 1822 return new Unknown64(machInst); 1823 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 1824 IntRegIndex rdzr = makeZero(rd); 1825 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 1826 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 1827 1828 switch (switchVal) { 1829 case 0x0: 1830 return new AndXSReg(machInst, rdzr, rn, rm, imm6, type); 1831 case 0x1: 1832 return new BicXSReg(machInst, rdzr, rn, rm, imm6, type); 1833 case 0x2: 1834 return new OrrXSReg(machInst, rdzr, rn, rm, imm6, type); 1835 case 0x3: 1836 return new OrnXSReg(machInst, rdzr, rn, rm, imm6, type); 1837 case 0x4: 1838 return new EorXSReg(machInst, rdzr, rn, rm, imm6, type); 1839 case 0x5: 1840 return new EonXSReg(machInst, rdzr, rn, rm, imm6, type); 1841 case 0x6: 1842 return new AndXSRegCc(machInst, rdzr, rn, rm, imm6, type); 1843 case 0x7: 1844 return new BicXSRegCc(machInst, rdzr, rn, rm, imm6, type); 1845 default: 1846 M5_UNREACHABLE; 1847 } 1848 } 1849 case 0x1: 1850 { 1851 uint8_t switchVal = bits(machInst, 30, 29); 1852 if (bits(machInst, 21) == 0) { 1853 ArmShiftType type = 1854 (ArmShiftType)(uint8_t)bits(machInst, 23, 22); 1855 if (type == ROR) 1856 return new Unknown64(machInst); 1857 uint8_t imm6 = bits(machInst, 15, 10); 1858 if (!bits(machInst, 31) && bits(imm6, 5)) 1859 return new Unknown64(machInst); 1860 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 1861 IntRegIndex rdzr = makeZero(rd); 1862 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 1863 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 1864 switch (switchVal) { 1865 case 0x0: 1866 return new AddXSReg(machInst, rdzr, rn, rm, imm6, type); 1867 case 0x1: 1868 return new AddXSRegCc(machInst, rdzr, rn, rm, imm6, type); 1869 case 0x2: 1870 return new SubXSReg(machInst, rdzr, rn, rm, imm6, type); 1871 case 0x3: 1872 return new SubXSRegCc(machInst, rdzr, rn, rm, imm6, type); 1873 default: 1874 M5_UNREACHABLE; 1875 } 1876 } else { 1877 if (bits(machInst, 23, 22) != 0 || bits(machInst, 12, 10) > 0x4) 1878 return new Unknown64(machInst); 1879 ArmExtendType type = 1880 (ArmExtendType)(uint8_t)bits(machInst, 15, 13); 1881 uint8_t imm3 = bits(machInst, 12, 10); 1882 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 1883 IntRegIndex rdsp = makeSP(rd); 1884 IntRegIndex rdzr = makeZero(rd); 1885 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 1886 IntRegIndex rnsp = makeSP(rn); 1887 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 1888 1889 switch (switchVal) { 1890 case 0x0: 1891 return new AddXEReg(machInst, rdsp, rnsp, rm, type, imm3); 1892 case 0x1: 1893 return new AddXERegCc(machInst, rdzr, rnsp, rm, type, imm3); 1894 case 0x2: 1895 return new SubXEReg(machInst, rdsp, rnsp, rm, type, imm3); 1896 case 0x3: 1897 return new SubXERegCc(machInst, rdzr, rnsp, rm, type, imm3); 1898 default: 1899 M5_UNREACHABLE; 1900 } 1901 } 1902 } 1903 case 0x2: 1904 { 1905 if (bits(machInst, 21) == 1) 1906 return new Unknown64(machInst); 1907 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 1908 IntRegIndex rdzr = makeZero(rd); 1909 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 1910 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 1911 switch (bits(machInst, 23, 22)) { 1912 case 0x0: 1913 { 1914 if (bits(machInst, 15, 10)) 1915 return new Unknown64(machInst); 1916 uint8_t switchVal = bits(machInst, 30, 29); 1917 switch (switchVal) { 1918 case 0x0: 1919 return new AdcXSReg(machInst, rdzr, rn, rm, 0, LSL); 1920 case 0x1: 1921 return new AdcXSRegCc(machInst, rdzr, rn, rm, 0, LSL); 1922 case 0x2: 1923 return new SbcXSReg(machInst, rdzr, rn, rm, 0, LSL); 1924 case 0x3: 1925 return new SbcXSRegCc(machInst, rdzr, rn, rm, 0, LSL); 1926 default: 1927 M5_UNREACHABLE; 1928 } 1929 } 1930 case 0x1: 1931 { 1932 if ((bits(machInst, 4) == 1) || 1933 (bits(machInst, 10) == 1) || 1934 (bits(machInst, 29) == 0)) { 1935 return new Unknown64(machInst); 1936 } 1937 ConditionCode cond = 1938 (ConditionCode)(uint8_t)bits(machInst, 15, 12); 1939 uint8_t flags = bits(machInst, 3, 0); 1940 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 1941 if (bits(machInst, 11) == 0) { 1942 IntRegIndex rm = 1943 (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 1944 if (bits(machInst, 30) == 0) { 1945 return new CcmnReg64(machInst, rn, rm, cond, flags); 1946 } else { 1947 return new CcmpReg64(machInst, rn, rm, cond, flags); 1948 } 1949 } else { 1950 uint8_t imm5 = bits(machInst, 20, 16); 1951 if (bits(machInst, 30) == 0) { 1952 return new CcmnImm64(machInst, rn, imm5, cond, flags); 1953 } else { 1954 return new CcmpImm64(machInst, rn, imm5, cond, flags); 1955 } 1956 } 1957 } 1958 case 0x2: 1959 { 1960 if (bits(machInst, 29) == 1 || 1961 bits(machInst, 11) == 1) { 1962 return new Unknown64(machInst); 1963 } 1964 uint8_t switchVal = (bits(machInst, 10) << 0) | 1965 (bits(machInst, 30) << 1); 1966 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 1967 IntRegIndex rdzr = makeZero(rd); 1968 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 1969 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 1970 ConditionCode cond = 1971 (ConditionCode)(uint8_t)bits(machInst, 15, 12); 1972 switch (switchVal) { 1973 case 0x0: 1974 return new Csel64(machInst, rdzr, rn, rm, cond); 1975 case 0x1: 1976 return new Csinc64(machInst, rdzr, rn, rm, cond); 1977 case 0x2: 1978 return new Csinv64(machInst, rdzr, rn, rm, cond); 1979 case 0x3: 1980 return new Csneg64(machInst, rdzr, rn, rm, cond); 1981 default: 1982 M5_UNREACHABLE; 1983 } 1984 } 1985 case 0x3: 1986 if (bits(machInst, 30) == 0) { 1987 if (bits(machInst, 29) != 0) 1988 return new Unknown64(machInst); 1989 uint8_t switchVal = bits(machInst, 15, 10); 1990 switch (switchVal) { 1991 case 0x2: 1992 return new Udiv64(machInst, rdzr, rn, rm); 1993 case 0x3: 1994 return new Sdiv64(machInst, rdzr, rn, rm); 1995 case 0x8: 1996 return new Lslv64(machInst, rdzr, rn, rm); 1997 case 0x9: 1998 return new Lsrv64(machInst, rdzr, rn, rm); 1999 case 0xa: 2000 return new Asrv64(machInst, rdzr, rn, rm); 2001 case 0xb: 2002 return new Rorv64(machInst, rdzr, rn, rm); 2003 case 0x10: 2004 return new Crc32b64(machInst, rdzr, rn, rm); 2005 case 0x11: 2006 return new Crc32h64(machInst, rdzr, rn, rm); 2007 case 0x12: 2008 return new Crc32w64(machInst, rdzr, rn, rm); 2009 case 0x13: 2010 return new Crc32x64(machInst, rdzr, rn, rm); 2011 case 0x14: 2012 return new Crc32cb64(machInst, rdzr, rn, rm); 2013 case 0x15: 2014 return new Crc32ch64(machInst, rdzr, rn, rm); 2015 case 0x16: 2016 return new Crc32cw64(machInst, rdzr, rn, rm); 2017 case 0x17: 2018 return new Crc32cx64(machInst, rdzr, rn, rm); 2019 default: 2020 return new Unknown64(machInst); 2021 } 2022 } else { 2023 if (bits(machInst, 20, 16) != 0 || 2024 bits(machInst, 29) != 0) { 2025 return new Unknown64(machInst); 2026 } 2027 uint8_t switchVal = bits(machInst, 15, 10); 2028 switch (switchVal) { 2029 case 0x0: 2030 return new Rbit64(machInst, rdzr, rn); 2031 case 0x1: 2032 return new Rev1664(machInst, rdzr, rn); 2033 case 0x2: 2034 if (bits(machInst, 31) == 0) 2035 return new Rev64(machInst, rdzr, rn); 2036 else 2037 return new Rev3264(machInst, rdzr, rn); 2038 case 0x3: 2039 if (bits(machInst, 31) != 1) 2040 return new Unknown64(machInst); 2041 return new Rev64(machInst, rdzr, rn); 2042 case 0x4: 2043 return new Clz64(machInst, rdzr, rn); 2044 case 0x5: 2045 return new Cls64(machInst, rdzr, rn); 2046 default: 2047 return new Unknown64(machInst); 2048 } 2049 } 2050 default: 2051 M5_UNREACHABLE; 2052 } 2053 } 2054 case 0x3: 2055 { 2056 if (bits(machInst, 30, 29) != 0x0 || 2057 (bits(machInst, 23, 21) != 0 && bits(machInst, 31) == 0)) 2058 return new Unknown64(machInst); 2059 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 2060 IntRegIndex rdzr = makeZero(rd); 2061 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 2062 IntRegIndex ra = (IntRegIndex)(uint8_t)bits(machInst, 14, 10); 2063 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 2064 switch (bits(machInst, 23, 21)) { 2065 case 0x0: 2066 if (bits(machInst, 15) == 0) 2067 return new Madd64(machInst, rdzr, ra, rn, rm); 2068 else 2069 return new Msub64(machInst, rdzr, ra, rn, rm); 2070 case 0x1: 2071 if (bits(machInst, 15) == 0) 2072 return new Smaddl64(machInst, rdzr, ra, rn, rm); 2073 else 2074 return new Smsubl64(machInst, rdzr, ra, rn, rm); 2075 case 0x2: 2076 if (bits(machInst, 15) != 0) 2077 return new Unknown64(machInst); 2078 return new Smulh64(machInst, rdzr, rn, rm); 2079 case 0x5: 2080 if (bits(machInst, 15) == 0) 2081 return new Umaddl64(machInst, rdzr, ra, rn, rm); 2082 else 2083 return new Umsubl64(machInst, rdzr, ra, rn, rm); 2084 case 0x6: 2085 if (bits(machInst, 15) != 0) 2086 return new Unknown64(machInst); 2087 return new Umulh64(machInst, rdzr, rn, rm); 2088 default: 2089 return new Unknown64(machInst); 2090 } 2091 } 2092 default: 2093 M5_UNREACHABLE; 2094 } 2095 return new FailUnimplemented("Unhandled Case2", machInst); 2096 } 2097} 2098}}; 2099 2100output decoder {{ 2101namespace Aarch64 2102{ 2103 template <typename DecoderFeatures> 2104 StaticInstPtr 2105 decodeAdvSIMD(ExtMachInst machInst) 2106 { 2107 if (bits(machInst, 24) == 1) { 2108 if (bits(machInst, 10) == 0) { 2109 return decodeNeonIndexedElem<DecoderFeatures>(machInst); 2110 } else if (bits(machInst, 23) == 1) { 2111 return new Unknown64(machInst); 2112 } else { 2113 if (bits(machInst, 22, 19)) { 2114 return decodeNeonShiftByImm(machInst); 2115 } else { 2116 return decodeNeonModImm(machInst); 2117 } 2118 } 2119 } else if (bits(machInst, 21) == 1) { 2120 if (bits(machInst, 10) == 1) { 2121 return decodeNeon3Same<DecoderFeatures>(machInst); 2122 } else if (bits(machInst, 11) == 0) { 2123 return decodeNeon3Diff(machInst); 2124 } else if (bits(machInst, 20, 17) == 0x0) { 2125 return decodeNeon2RegMisc(machInst); 2126 } else if (bits(machInst, 20, 17) == 0x4) { 2127 return decodeCryptoAES(machInst); 2128 } else if (bits(machInst, 20, 17) == 0x8) { 2129 return decodeNeonAcrossLanes(machInst); 2130 } else { 2131 return new Unknown64(machInst); 2132 } 2133 } else if (bits(machInst, 24) || 2134 bits(machInst, 21) || 2135 bits(machInst, 15)) { 2136 return new Unknown64(machInst); 2137 } else if (bits(machInst, 10) == 1) { 2138 if (bits(machInst, 23, 22)) 2139 return new Unknown64(machInst); 2140 return decodeNeonCopy(machInst); 2141 } else if (bits(machInst, 29) == 1) { 2142 return decodeNeonExt(machInst); 2143 } else if (bits(machInst, 11) == 1) { 2144 return decodeNeonZipUzpTrn(machInst); 2145 } else if (bits(machInst, 23, 22) == 0x0) { 2146 return decodeNeonTblTbx(machInst); 2147 } else { 2148 return new Unknown64(machInst); 2149 } 2150 return new FailUnimplemented("Unhandled Case3", machInst); 2151 } 2152} 2153}}; 2154 2155 2156output decoder {{ 2157namespace Aarch64 2158{ 2159 StaticInstPtr 2160 // bit 30=0, 28:25=1111 2161 decodeFp(ExtMachInst machInst) 2162 { 2163 if (bits(machInst, 24) == 1) { 2164 if (bits(machInst, 31) || bits(machInst, 29)) 2165 return new Unknown64(machInst); 2166 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 2167 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 2168 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 20, 16); 2169 IntRegIndex ra = (IntRegIndex)(uint32_t)bits(machInst, 14, 10); 2170 uint8_t switchVal = (bits(machInst, 23, 21) << 1) | 2171 (bits(machInst, 15) << 0); 2172 switch (switchVal) { 2173 case 0x0: // FMADD Sd = Sa + Sn*Sm 2174 return new FMAddS(machInst, rd, rn, rm, ra); 2175 case 0x1: // FMSUB Sd = Sa + (-Sn)*Sm 2176 return new FMSubS(machInst, rd, rn, rm, ra); 2177 case 0x2: // FNMADD Sd = (-Sa) + (-Sn)*Sm 2178 return new FNMAddS(machInst, rd, rn, rm, ra); 2179 case 0x3: // FNMSUB Sd = (-Sa) + Sn*Sm 2180 return new FNMSubS(machInst, rd, rn, rm, ra); 2181 case 0x4: // FMADD Dd = Da + Dn*Dm 2182 return new FMAddD(machInst, rd, rn, rm, ra); 2183 case 0x5: // FMSUB Dd = Da + (-Dn)*Dm 2184 return new FMSubD(machInst, rd, rn, rm, ra); 2185 case 0x6: // FNMADD Dd = (-Da) + (-Dn)*Dm 2186 return new FNMAddD(machInst, rd, rn, rm, ra); 2187 case 0x7: // FNMSUB Dd = (-Da) + Dn*Dm 2188 return new FNMSubD(machInst, rd, rn, rm, ra); 2189 default: 2190 return new Unknown64(machInst); 2191 } 2192 } else if (bits(machInst, 21) == 0) { 2193 bool s = bits(machInst, 29); 2194 if (s) 2195 return new Unknown64(machInst); 2196 uint8_t switchVal = bits(machInst, 20, 16); 2197 uint8_t type = bits(machInst, 23, 22); 2198 uint8_t scale = bits(machInst, 15, 10); 2199 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 2200 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 2201 if (bits(machInst, 18, 17) == 3 && scale != 0) 2202 return new Unknown64(machInst); 2203 // 30:24=0011110, 21=0 2204 switch (switchVal) { 2205 case 0x00: 2206 return new FailUnimplemented("fcvtns", machInst); 2207 case 0x01: 2208 return new FailUnimplemented("fcvtnu", machInst); 2209 case 0x02: 2210 switch ( (bits(machInst, 31) << 2) | type ) { 2211 case 0: // SCVTF Sd = convertFromInt(Wn/(2^fbits)) 2212 return new FcvtSFixedFpSW(machInst, rd, rn, scale); 2213 case 1: // SCVTF Dd = convertFromInt(Wn/(2^fbits)) 2214 return new FcvtSFixedFpDW(machInst, rd, rn, scale); 2215 case 4: // SCVTF Sd = convertFromInt(Xn/(2^fbits)) 2216 return new FcvtSFixedFpSX(machInst, rd, rn, scale); 2217 case 5: // SCVTF Dd = convertFromInt(Xn/(2^fbits)) 2218 return new FcvtSFixedFpDX(machInst, rd, rn, scale); 2219 default: 2220 return new Unknown64(machInst); 2221 } 2222 case 0x03: 2223 switch ( (bits(machInst, 31) << 2) | type ) { 2224 case 0: // UCVTF Sd = convertFromInt(Wn/(2^fbits)) 2225 return new FcvtUFixedFpSW(machInst, rd, rn, scale); 2226 case 1: // UCVTF Dd = convertFromInt(Wn/(2^fbits)) 2227 return new FcvtUFixedFpDW(machInst, rd, rn, scale); 2228 case 4: // UCVTF Sd = convertFromInt(Xn/(2^fbits)) 2229 return new FcvtUFixedFpSX(machInst, rd, rn, scale); 2230 case 5: // UCVTF Dd = convertFromInt(Xn/(2^fbits)) 2231 return new FcvtUFixedFpDX(machInst, rd, rn, scale); 2232 default: 2233 return new Unknown64(machInst); 2234 } 2235 case 0x04: 2236 return new FailUnimplemented("fcvtas", machInst); 2237 case 0x05: 2238 return new FailUnimplemented("fcvtau", machInst); 2239 case 0x08: 2240 return new FailUnimplemented("fcvtps", machInst); 2241 case 0x09: 2242 return new FailUnimplemented("fcvtpu", machInst); 2243 case 0x0e: 2244 return new FailUnimplemented("fmov elem. to 64", machInst); 2245 case 0x0f: 2246 return new FailUnimplemented("fmov 64 bit", machInst); 2247 case 0x10: 2248 return new FailUnimplemented("fcvtms", machInst); 2249 case 0x11: 2250 return new FailUnimplemented("fcvtmu", machInst); 2251 case 0x18: 2252 switch ( (bits(machInst, 31) << 2) | type ) { 2253 case 0: // FCVTZS Wd = convertToIntExactTowardZero(Sn*(2^fbits)) 2254 return new FcvtFpSFixedSW(machInst, rd, rn, scale); 2255 case 1: // FCVTZS Wd = convertToIntExactTowardZero(Dn*(2^fbits)) 2256 return new FcvtFpSFixedDW(machInst, rd, rn, scale); 2257 case 4: // FCVTZS Xd = convertToIntExactTowardZero(Sn*(2^fbits)) 2258 return new FcvtFpSFixedSX(machInst, rd, rn, scale); 2259 case 5: // FCVTZS Xd = convertToIntExactTowardZero(Dn*(2^fbits)) 2260 return new FcvtFpSFixedDX(machInst, rd, rn, scale); 2261 default: 2262 return new Unknown64(machInst); 2263 } 2264 case 0x19: 2265 switch ( (bits(machInst, 31) << 2) | type ) { 2266 case 0: // FCVTZU Wd = convertToIntExactTowardZero(Sn*(2^fbits)) 2267 return new FcvtFpUFixedSW(machInst, rd, rn, scale); 2268 case 1: // FCVTZU Wd = convertToIntExactTowardZero(Dn*(2^fbits)) 2269 return new FcvtFpUFixedDW(machInst, rd, rn, scale); 2270 case 4: // FCVTZU Xd = convertToIntExactTowardZero(Sn*(2^fbits)) 2271 return new FcvtFpUFixedSX(machInst, rd, rn, scale); 2272 case 5: // FCVTZU Xd = convertToIntExactTowardZero(Dn*(2^fbits)) 2273 return new FcvtFpUFixedDX(machInst, rd, rn, scale); 2274 default: 2275 return new Unknown64(machInst); 2276 } 2277 default: 2278 return new Unknown64(machInst); 2279 } 2280 } else { 2281 // 30=0, 28:24=11110, 21=1 2282 uint8_t type = bits(machInst, 23, 22); 2283 uint8_t imm8 = bits(machInst, 20, 13); 2284 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 2285 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 2286 switch (bits(machInst, 11, 10)) { 2287 case 0x0: 2288 if (bits(machInst, 12) == 1) { 2289 if (bits(machInst, 31) || 2290 bits(machInst, 29) || 2291 bits(machInst, 9, 5)) { 2292 return new Unknown64(machInst); 2293 } 2294 // 31:29=000, 28:24=11110, 21=1, 12:10=100 2295 if (type == 0) { 2296 // FMOV S[d] = imm8<7>:NOT(imm8<6>):Replicate(imm8<6>,5) 2297 // :imm8<5:0>:Zeros(19) 2298 uint32_t imm = vfp_modified_imm(imm8, 2299 FpDataType::Fp32); 2300 return new FmovImmS(machInst, rd, imm); 2301 } else if (type == 1) { 2302 // FMOV D[d] = imm8<7>:NOT(imm8<6>):Replicate(imm8<6>,8) 2303 // :imm8<5:0>:Zeros(48) 2304 uint64_t imm = vfp_modified_imm(imm8, 2305 FpDataType::Fp64); 2306 return new FmovImmD(machInst, rd, imm); 2307 } else { 2308 return new Unknown64(machInst); 2309 } 2310 } else if (bits(machInst, 13) == 1) { 2311 if (bits(machInst, 31) || 2312 bits(machInst, 29) || 2313 bits(machInst, 15, 14) || 2314 bits(machInst, 23) || 2315 bits(machInst, 2, 0)) { 2316 return new Unknown64(machInst); 2317 } 2318 uint8_t switchVal = (bits(machInst, 4, 3) << 0) | 2319 (bits(machInst, 22) << 2); 2320 IntRegIndex rm = (IntRegIndex)(uint32_t) 2321 bits(machInst, 20, 16); 2322 // 28:23=000111100, 21=1, 15:10=001000, 2:0=000 2323 switch (switchVal) { 2324 case 0x0: 2325 // FCMP flags = compareQuiet(Sn,Sm) 2326 return new FCmpRegS(machInst, rn, rm); 2327 case 0x1: 2328 // FCMP flags = compareQuiet(Sn,0.0) 2329 return new FCmpImmS(machInst, rn, 0); 2330 case 0x2: 2331 // FCMPE flags = compareSignaling(Sn,Sm) 2332 return new FCmpERegS(machInst, rn, rm); 2333 case 0x3: 2334 // FCMPE flags = compareSignaling(Sn,0.0) 2335 return new FCmpEImmS(machInst, rn, 0); 2336 case 0x4: 2337 // FCMP flags = compareQuiet(Dn,Dm) 2338 return new FCmpRegD(machInst, rn, rm); 2339 case 0x5: 2340 // FCMP flags = compareQuiet(Dn,0.0) 2341 return new FCmpImmD(machInst, rn, 0); 2342 case 0x6: 2343 // FCMPE flags = compareSignaling(Dn,Dm) 2344 return new FCmpERegD(machInst, rn, rm); 2345 case 0x7: 2346 // FCMPE flags = compareSignaling(Dn,0.0) 2347 return new FCmpEImmD(machInst, rn, 0); 2348 default: 2349 return new Unknown64(machInst); 2350 } 2351 } else if (bits(machInst, 14) == 1) { 2352 if (bits(machInst, 31) || bits(machInst, 29)) 2353 return new Unknown64(machInst); 2354 uint8_t opcode = bits(machInst, 20, 15); 2355 // Bits 31:24=00011110, 21=1, 14:10=10000 2356 switch (opcode) { 2357 case 0x0: 2358 if (type == 0) 2359 // FMOV Sd = Sn 2360 return new FmovRegS(machInst, rd, rn); 2361 else if (type == 1) 2362 // FMOV Dd = Dn 2363 return new FmovRegD(machInst, rd, rn); 2364 break; 2365 case 0x1: 2366 if (type == 0) 2367 // FABS Sd = abs(Sn) 2368 return new FAbsS(machInst, rd, rn); 2369 else if (type == 1) 2370 // FABS Dd = abs(Dn) 2371 return new FAbsD(machInst, rd, rn); 2372 break; 2373 case 0x2: 2374 if (type == 0) 2375 // FNEG Sd = -Sn 2376 return new FNegS(machInst, rd, rn); 2377 else if (type == 1) 2378 // FNEG Dd = -Dn 2379 return new FNegD(machInst, rd, rn); 2380 break; 2381 case 0x3: 2382 if (type == 0) 2383 // FSQRT Sd = sqrt(Sn) 2384 return new FSqrtS(machInst, rd, rn); 2385 else if (type == 1) 2386 // FSQRT Dd = sqrt(Dn) 2387 return new FSqrtD(machInst, rd, rn); 2388 break; 2389 case 0x4: 2390 if (type == 1) 2391 // FCVT Sd = convertFormat(Dn) 2392 return new FcvtFpDFpS(machInst, rd, rn); 2393 else if (type == 3) 2394 // FCVT Sd = convertFormat(Hn) 2395 return new FcvtFpHFpS(machInst, rd, rn); 2396 break; 2397 case 0x5: 2398 if (type == 0) 2399 // FCVT Dd = convertFormat(Sn) 2400 return new FCvtFpSFpD(machInst, rd, rn); 2401 else if (type == 3) 2402 // FCVT Dd = convertFormat(Hn) 2403 return new FcvtFpHFpD(machInst, rd, rn); 2404 break; 2405 case 0x7: 2406 if (type == 0) 2407 // FCVT Hd = convertFormat(Sn) 2408 return new FcvtFpSFpH(machInst, rd, rn); 2409 else if (type == 1) 2410 // FCVT Hd = convertFormat(Dn) 2411 return new FcvtFpDFpH(machInst, rd, rn); 2412 break; 2413 case 0x8: 2414 if (type == 0) // FRINTN Sd = roundToIntegralTiesToEven(Sn) 2415 return new FRIntNS(machInst, rd, rn); 2416 else if (type == 1) // FRINTN Dd = roundToIntegralTiesToEven(Dn) 2417 return new FRIntND(machInst, rd, rn); 2418 break; 2419 case 0x9: 2420 if (type == 0) // FRINTP Sd = roundToIntegralTowardPlusInf(Sn) 2421 return new FRIntPS(machInst, rd, rn); 2422 else if (type == 1) // FRINTP Dd = roundToIntegralTowardPlusInf(Dn) 2423 return new FRIntPD(machInst, rd, rn); 2424 break; 2425 case 0xa: 2426 if (type == 0) // FRINTM Sd = roundToIntegralTowardMinusInf(Sn) 2427 return new FRIntMS(machInst, rd, rn); 2428 else if (type == 1) // FRINTM Dd = roundToIntegralTowardMinusInf(Dn) 2429 return new FRIntMD(machInst, rd, rn); 2430 break; 2431 case 0xb: 2432 if (type == 0) // FRINTZ Sd = roundToIntegralTowardZero(Sn) 2433 return new FRIntZS(machInst, rd, rn); 2434 else if (type == 1) // FRINTZ Dd = roundToIntegralTowardZero(Dn) 2435 return new FRIntZD(machInst, rd, rn); 2436 break; 2437 case 0xc: 2438 if (type == 0) // FRINTA Sd = roundToIntegralTiesToAway(Sn) 2439 return new FRIntAS(machInst, rd, rn); 2440 else if (type == 1) // FRINTA Dd = roundToIntegralTiesToAway(Dn) 2441 return new FRIntAD(machInst, rd, rn); 2442 break; 2443 case 0xe: 2444 if (type == 0) // FRINTX Sd = roundToIntegralExact(Sn) 2445 return new FRIntXS(machInst, rd, rn); 2446 else if (type == 1) // FRINTX Dd = roundToIntegralExact(Dn) 2447 return new FRIntXD(machInst, rd, rn); 2448 break; 2449 case 0xf: 2450 if (type == 0) // FRINTI Sd = roundToIntegral(Sn) 2451 return new FRIntIS(machInst, rd, rn); 2452 else if (type == 1) // FRINTI Dd = roundToIntegral(Dn) 2453 return new FRIntID(machInst, rd, rn); 2454 break; 2455 default: 2456 return new Unknown64(machInst); 2457 } 2458 return new Unknown64(machInst); 2459 } else if (bits(machInst, 15) == 1) { 2460 return new Unknown64(machInst); 2461 } else { 2462 if (bits(machInst, 29)) 2463 return new Unknown64(machInst); 2464 uint8_t rmode = bits(machInst, 20, 19); 2465 uint8_t switchVal1 = bits(machInst, 18, 16); 2466 uint8_t switchVal2 = (type << 1) | bits(machInst, 31); 2467 // 30:24=0011110, 21=1, 15:10=000000 2468 switch (switchVal1) { 2469 case 0x0: 2470 switch ((switchVal2 << 2) | rmode) { 2471 case 0x0: //FCVTNS Wd = convertToIntExactTiesToEven(Sn) 2472 return new FcvtFpSIntWSN(machInst, rd, rn); 2473 case 0x1: //FCVTPS Wd = convertToIntExactTowardPlusInf(Sn) 2474 return new FcvtFpSIntWSP(machInst, rd, rn); 2475 case 0x2: //FCVTMS Wd = convertToIntExactTowardMinusInf(Sn) 2476 return new FcvtFpSIntWSM(machInst, rd, rn); 2477 case 0x3: //FCVTZS Wd = convertToIntExactTowardZero(Sn) 2478 return new FcvtFpSIntWSZ(machInst, rd, rn); 2479 case 0x4: //FCVTNS Xd = convertToIntExactTiesToEven(Sn) 2480 return new FcvtFpSIntXSN(machInst, rd, rn); 2481 case 0x5: //FCVTPS Xd = convertToIntExactTowardPlusInf(Sn) 2482 return new FcvtFpSIntXSP(machInst, rd, rn); 2483 case 0x6: //FCVTMS Xd = convertToIntExactTowardMinusInf(Sn) 2484 return new FcvtFpSIntXSM(machInst, rd, rn); 2485 case 0x7: //FCVTZS Xd = convertToIntExactTowardZero(Sn) 2486 return new FcvtFpSIntXSZ(machInst, rd, rn); 2487 case 0x8: //FCVTNS Wd = convertToIntExactTiesToEven(Dn) 2488 return new FcvtFpSIntWDN(machInst, rd, rn); 2489 case 0x9: //FCVTPS Wd = convertToIntExactTowardPlusInf(Dn) 2490 return new FcvtFpSIntWDP(machInst, rd, rn); 2491 case 0xA: //FCVTMS Wd = convertToIntExactTowardMinusInf(Dn) 2492 return new FcvtFpSIntWDM(machInst, rd, rn); 2493 case 0xB: //FCVTZS Wd = convertToIntExactTowardZero(Dn) 2494 return new FcvtFpSIntWDZ(machInst, rd, rn); 2495 case 0xC: //FCVTNS Xd = convertToIntExactTiesToEven(Dn) 2496 return new FcvtFpSIntXDN(machInst, rd, rn); 2497 case 0xD: //FCVTPS Xd = convertToIntExactTowardPlusInf(Dn) 2498 return new FcvtFpSIntXDP(machInst, rd, rn); 2499 case 0xE: //FCVTMS Xd = convertToIntExactTowardMinusInf(Dn) 2500 return new FcvtFpSIntXDM(machInst, rd, rn); 2501 case 0xF: //FCVTZS Xd = convertToIntExactTowardZero(Dn) 2502 return new FcvtFpSIntXDZ(machInst, rd, rn); 2503 default: 2504 return new Unknown64(machInst); 2505 } 2506 case 0x1: 2507 switch ((switchVal2 << 2) | rmode) { 2508 case 0x0: //FCVTNU Wd = convertToIntExactTiesToEven(Sn) 2509 return new FcvtFpUIntWSN(machInst, rd, rn); 2510 case 0x1: //FCVTPU Wd = convertToIntExactTowardPlusInf(Sn) 2511 return new FcvtFpUIntWSP(machInst, rd, rn); 2512 case 0x2: //FCVTMU Wd = convertToIntExactTowardMinusInf(Sn) 2513 return new FcvtFpUIntWSM(machInst, rd, rn); 2514 case 0x3: //FCVTZU Wd = convertToIntExactTowardZero(Sn) 2515 return new FcvtFpUIntWSZ(machInst, rd, rn); 2516 case 0x4: //FCVTNU Xd = convertToIntExactTiesToEven(Sn) 2517 return new FcvtFpUIntXSN(machInst, rd, rn); 2518 case 0x5: //FCVTPU Xd = convertToIntExactTowardPlusInf(Sn) 2519 return new FcvtFpUIntXSP(machInst, rd, rn); 2520 case 0x6: //FCVTMU Xd = convertToIntExactTowardMinusInf(Sn) 2521 return new FcvtFpUIntXSM(machInst, rd, rn); 2522 case 0x7: //FCVTZU Xd = convertToIntExactTowardZero(Sn) 2523 return new FcvtFpUIntXSZ(machInst, rd, rn); 2524 case 0x8: //FCVTNU Wd = convertToIntExactTiesToEven(Dn) 2525 return new FcvtFpUIntWDN(machInst, rd, rn); 2526 case 0x9: //FCVTPU Wd = convertToIntExactTowardPlusInf(Dn) 2527 return new FcvtFpUIntWDP(machInst, rd, rn); 2528 case 0xA: //FCVTMU Wd = convertToIntExactTowardMinusInf(Dn) 2529 return new FcvtFpUIntWDM(machInst, rd, rn); 2530 case 0xB: //FCVTZU Wd = convertToIntExactTowardZero(Dn) 2531 return new FcvtFpUIntWDZ(machInst, rd, rn); 2532 case 0xC: //FCVTNU Xd = convertToIntExactTiesToEven(Dn) 2533 return new FcvtFpUIntXDN(machInst, rd, rn); 2534 case 0xD: //FCVTPU Xd = convertToIntExactTowardPlusInf(Dn) 2535 return new FcvtFpUIntXDP(machInst, rd, rn); 2536 case 0xE: //FCVTMU Xd = convertToIntExactTowardMinusInf(Dn) 2537 return new FcvtFpUIntXDM(machInst, rd, rn); 2538 case 0xF: //FCVTZU Xd = convertToIntExactTowardZero(Dn) 2539 return new FcvtFpUIntXDZ(machInst, rd, rn); 2540 default: 2541 return new Unknown64(machInst); 2542 } 2543 case 0x2: 2544 if (rmode != 0) 2545 return new Unknown64(machInst); 2546 switch (switchVal2) { 2547 case 0: // SCVTF Sd = convertFromInt(Wn) 2548 return new FcvtWSIntFpS(machInst, rd, rn); 2549 case 1: // SCVTF Sd = convertFromInt(Xn) 2550 return new FcvtXSIntFpS(machInst, rd, rn); 2551 case 2: // SCVTF Dd = convertFromInt(Wn) 2552 return new FcvtWSIntFpD(machInst, rd, rn); 2553 case 3: // SCVTF Dd = convertFromInt(Xn) 2554 return new FcvtXSIntFpD(machInst, rd, rn); 2555 default: 2556 return new Unknown64(machInst); 2557 } 2558 case 0x3: 2559 switch (switchVal2) { 2560 case 0: // UCVTF Sd = convertFromInt(Wn) 2561 return new FcvtWUIntFpS(machInst, rd, rn); 2562 case 1: // UCVTF Sd = convertFromInt(Xn) 2563 return new FcvtXUIntFpS(machInst, rd, rn); 2564 case 2: // UCVTF Dd = convertFromInt(Wn) 2565 return new FcvtWUIntFpD(machInst, rd, rn); 2566 case 3: // UCVTF Dd = convertFromInt(Xn) 2567 return new FcvtXUIntFpD(machInst, rd, rn); 2568 default: 2569 return new Unknown64(machInst); 2570 } 2571 case 0x4: 2572 if (rmode != 0) 2573 return new Unknown64(machInst); 2574 switch (switchVal2) { 2575 case 0: // FCVTAS Wd = convertToIntExactTiesToAway(Sn) 2576 return new FcvtFpSIntWSA(machInst, rd, rn); 2577 case 1: // FCVTAS Xd = convertToIntExactTiesToAway(Sn) 2578 return new FcvtFpSIntXSA(machInst, rd, rn); 2579 case 2: // FCVTAS Wd = convertToIntExactTiesToAway(Dn) 2580 return new FcvtFpSIntWDA(machInst, rd, rn); 2581 case 3: // FCVTAS Wd = convertToIntExactTiesToAway(Dn) 2582 return new FcvtFpSIntXDA(machInst, rd, rn); 2583 default: 2584 return new Unknown64(machInst); 2585 } 2586 case 0x5: 2587 switch (switchVal2) { 2588 case 0: // FCVTAU Wd = convertToIntExactTiesToAway(Sn) 2589 return new FcvtFpUIntWSA(machInst, rd, rn); 2590 case 1: // FCVTAU Xd = convertToIntExactTiesToAway(Sn) 2591 return new FcvtFpUIntXSA(machInst, rd, rn); 2592 case 2: // FCVTAU Wd = convertToIntExactTiesToAway(Dn) 2593 return new FcvtFpUIntWDA(machInst, rd, rn); 2594 case 3: // FCVTAU Xd = convertToIntExactTiesToAway(Dn) 2595 return new FcvtFpUIntXDA(machInst, rd, rn); 2596 default: 2597 return new Unknown64(machInst); 2598 } 2599 case 0x06: 2600 switch (switchVal2) { 2601 case 0: // FMOV Wd = Sn 2602 if (rmode != 0) 2603 return new Unknown64(machInst); 2604 return new FmovRegCoreW(machInst, rd, rn); 2605 case 3: // FMOV Xd = Dn 2606 if (rmode != 0) 2607 return new Unknown64(machInst); 2608 return new FmovRegCoreX(machInst, rd, rn); 2609 case 5: // FMOV Xd = Vn<127:64> 2610 if (rmode != 1) 2611 return new Unknown64(machInst); 2612 return new FmovURegCoreX(machInst, rd, rn); 2613 default: 2614 return new Unknown64(machInst); 2615 } 2616 break; 2617 case 0x07: 2618 switch (switchVal2) { 2619 case 0: // FMOV Sd = Wn 2620 if (rmode != 0) 2621 return new Unknown64(machInst); 2622 return new FmovCoreRegW(machInst, rd, rn); 2623 case 3: // FMOV Xd = Dn 2624 if (rmode != 0) 2625 return new Unknown64(machInst); 2626 return new FmovCoreRegX(machInst, rd, rn); 2627 case 5: // FMOV Xd = Vn<127:64> 2628 if (rmode != 1) 2629 return new Unknown64(machInst); 2630 return new FmovUCoreRegX(machInst, rd, rn); 2631 default: 2632 return new Unknown64(machInst); 2633 } 2634 break; 2635 default: // Warning! missing cases in switch statement above, that still need to be added 2636 return new Unknown64(machInst); 2637 } 2638 } 2639 M5_UNREACHABLE; 2640 case 0x1: 2641 { 2642 if (bits(machInst, 31) || 2643 bits(machInst, 29) || 2644 bits(machInst, 23)) { 2645 return new Unknown64(machInst); 2646 } 2647 IntRegIndex rm = (IntRegIndex)(uint32_t) bits(machInst, 20, 16); 2648 IntRegIndex rn = (IntRegIndex)(uint32_t) bits(machInst, 9, 5); 2649 uint8_t imm = (IntRegIndex)(uint32_t) bits(machInst, 3, 0); 2650 ConditionCode cond = 2651 (ConditionCode)(uint8_t)(bits(machInst, 15, 12)); 2652 uint8_t switchVal = (bits(machInst, 4) << 0) | 2653 (bits(machInst, 22) << 1); 2654 // 31:23=000111100, 21=1, 11:10=01 2655 switch (switchVal) { 2656 case 0x0: 2657 // FCCMP flags = if cond the compareQuiet(Sn,Sm) else #nzcv 2658 return new FCCmpRegS(machInst, rn, rm, cond, imm); 2659 case 0x1: 2660 // FCCMP flags = if cond then compareSignaling(Sn,Sm) 2661 // else #nzcv 2662 return new FCCmpERegS(machInst, rn, rm, cond, imm); 2663 case 0x2: 2664 // FCCMP flags = if cond then compareQuiet(Dn,Dm) else #nzcv 2665 return new FCCmpRegD(machInst, rn, rm, cond, imm); 2666 case 0x3: 2667 // FCCMP flags = if cond then compareSignaling(Dn,Dm) 2668 // else #nzcv 2669 return new FCCmpERegD(machInst, rn, rm, cond, imm); 2670 default: 2671 return new Unknown64(machInst); 2672 } 2673 } 2674 case 0x2: 2675 { 2676 if (bits(machInst, 31) || 2677 bits(machInst, 29) || 2678 bits(machInst, 23)) { 2679 return new Unknown64(machInst); 2680 } 2681 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 2682 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 2683 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 20, 16); 2684 uint8_t switchVal = (bits(machInst, 15, 12) << 0) | 2685 (bits(machInst, 22) << 4); 2686 switch (switchVal) { 2687 case 0x00: // FMUL Sd = Sn * Sm 2688 return new FMulS(machInst, rd, rn, rm); 2689 case 0x10: // FMUL Dd = Dn * Dm 2690 return new FMulD(machInst, rd, rn, rm); 2691 case 0x01: // FDIV Sd = Sn / Sm 2692 return new FDivS(machInst, rd, rn, rm); 2693 case 0x11: // FDIV Dd = Dn / Dm 2694 return new FDivD(machInst, rd, rn, rm); 2695 case 0x02: // FADD Sd = Sn + Sm 2696 return new FAddS(machInst, rd, rn, rm); 2697 case 0x12: // FADD Dd = Dn + Dm 2698 return new FAddD(machInst, rd, rn, rm); 2699 case 0x03: // FSUB Sd = Sn - Sm 2700 return new FSubS(machInst, rd, rn, rm); 2701 case 0x13: // FSUB Dd = Dn - Dm 2702 return new FSubD(machInst, rd, rn, rm); 2703 case 0x04: // FMAX Sd = max(Sn, Sm) 2704 return new FMaxS(machInst, rd, rn, rm); 2705 case 0x14: // FMAX Dd = max(Dn, Dm) 2706 return new FMaxD(machInst, rd, rn, rm); 2707 case 0x05: // FMIN Sd = min(Sn, Sm) 2708 return new FMinS(machInst, rd, rn, rm); 2709 case 0x15: // FMIN Dd = min(Dn, Dm) 2710 return new FMinD(machInst, rd, rn, rm); 2711 case 0x06: // FMAXNM Sd = maxNum(Sn, Sm) 2712 return new FMaxNMS(machInst, rd, rn, rm); 2713 case 0x16: // FMAXNM Dd = maxNum(Dn, Dm) 2714 return new FMaxNMD(machInst, rd, rn, rm); 2715 case 0x07: // FMINNM Sd = minNum(Sn, Sm) 2716 return new FMinNMS(machInst, rd, rn, rm); 2717 case 0x17: // FMINNM Dd = minNum(Dn, Dm) 2718 return new FMinNMD(machInst, rd, rn, rm); 2719 case 0x08: // FNMUL Sd = -(Sn * Sm) 2720 return new FNMulS(machInst, rd, rn, rm); 2721 case 0x18: // FNMUL Dd = -(Dn * Dm) 2722 return new FNMulD(machInst, rd, rn, rm); 2723 default: 2724 return new Unknown64(machInst); 2725 } 2726 } 2727 case 0x3: 2728 { 2729 if (bits(machInst, 31) || bits(machInst, 29)) 2730 return new Unknown64(machInst); 2731 uint8_t type = bits(machInst, 23, 22); 2732 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 2733 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 2734 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 20, 16); 2735 ConditionCode cond = 2736 (ConditionCode)(uint8_t)(bits(machInst, 15, 12)); 2737 if (type == 0) // FCSEL Sd = if cond then Sn else Sm 2738 return new FCSelS(machInst, rd, rn, rm, cond); 2739 else if (type == 1) // FCSEL Dd = if cond then Dn else Dm 2740 return new FCSelD(machInst, rd, rn, rm, cond); 2741 else 2742 return new Unknown64(machInst); 2743 } 2744 default: 2745 M5_UNREACHABLE; 2746 } 2747 } 2748 M5_UNREACHABLE; 2749 } 2750} 2751}}; 2752 2753output decoder {{ 2754namespace Aarch64 2755{ 2756 StaticInstPtr 2757 decodeAdvSIMDScalar(ExtMachInst machInst) 2758 { 2759 if (bits(machInst, 24) == 1) { 2760 if (bits(machInst, 10) == 0) { 2761 return decodeNeonScIndexedElem(machInst); 2762 } else if (bits(machInst, 23) == 0) { 2763 return decodeNeonScShiftByImm(machInst); 2764 } 2765 } else if (bits(machInst, 21) == 1) { 2766 if (bits(machInst, 10) == 1) { 2767 return decodeNeonSc3Same(machInst); 2768 } else if (bits(machInst, 11) == 0) { 2769 return decodeNeonSc3Diff(machInst); 2770 } else if (bits(machInst, 20, 17) == 0x0) { 2771 return decodeNeonSc2RegMisc(machInst); 2772 } else if (bits(machInst, 20, 17) == 0x4) { 2773 return decodeCryptoTwoRegSHA(machInst); 2774 } else if (bits(machInst, 20, 17) == 0x8) { 2775 return decodeNeonScPwise(machInst); 2776 } else { 2777 return new Unknown64(machInst); 2778 } 2779 } else if (bits(machInst, 23, 22) == 0 && 2780 bits(machInst, 15) == 0) { 2781 if (bits(machInst, 10) == 1) { 2782 return decodeNeonScCopy(machInst); 2783 } else { 2784 return decodeCryptoThreeRegSHA(machInst); 2785 } 2786 } else { 2787 return new Unknown64(machInst); 2788 } 2789 return new FailUnimplemented("Unhandled Case6", machInst); 2790 } 2791} 2792}}; 2793 2794output decoder {{ 2795namespace Aarch64 2796{ 2797 template <typename DecoderFeatures> 2798 StaticInstPtr 2799 decodeFpAdvSIMD(ExtMachInst machInst) 2800 { 2801 2802 if (bits(machInst, 28) == 0) { 2803 if (bits(machInst, 31) == 0) { 2804 return decodeAdvSIMD<DecoderFeatures>(machInst); 2805 } else { 2806 return new Unknown64(machInst); 2807 } 2808 } else if (bits(machInst, 30) == 0) { 2809 return decodeFp(machInst); 2810 } else if (bits(machInst, 31) == 0) { 2811 return decodeAdvSIMDScalar(machInst); 2812 } else { 2813 return new Unknown64(machInst); 2814 } 2815 } 2816} 2817}}; 2818 2819let {{ 2820 decoder_output =''' 2821namespace Aarch64 2822{''' 2823 for decoderFlavour, type_dict in decoders.iteritems(): 2824 decoder_output +=''' 2825template StaticInstPtr decodeFpAdvSIMD<%(df)sDecoder>(ExtMachInst machInst); 2826''' % { "df" : decoderFlavour } 2827 decoder_output +=''' 2828}''' 2829}}; 2830 2831output decoder {{ 2832namespace Aarch64 2833{ 2834 StaticInstPtr 2835 decodeGem5Ops(ExtMachInst machInst) 2836 { 2837 const uint32_t m5func = bits(machInst, 23, 16); 2838 switch (m5func) { 2839 case M5OP_ARM: return new Arm(machInst); 2840 case M5OP_QUIESCE: return new Quiesce(machInst); 2841 case M5OP_QUIESCE_NS: return new QuiesceNs64(machInst); 2842 case M5OP_QUIESCE_CYCLE: return new QuiesceCycles64(machInst); 2843 case M5OP_QUIESCE_TIME: return new QuiesceTime64(machInst); 2844 case M5OP_RPNS: return new Rpns64(machInst); 2845 case M5OP_WAKE_CPU: return new WakeCPU64(machInst); 2846 case M5OP_DEPRECATED1: return new Deprecated_ivlb(machInst); 2847 case M5OP_DEPRECATED2: return new Deprecated_ivle(machInst); 2848 case M5OP_DEPRECATED3: return new Deprecated_exit (machInst); 2849 case M5OP_EXIT: return new M5exit64(machInst); 2850 case M5OP_FAIL: return new M5fail64(machInst); 2851 case M5OP_LOAD_SYMBOL: return new Loadsymbol(machInst); 2852 case M5OP_INIT_PARAM: return new Initparam64(machInst); 2853 case M5OP_RESET_STATS: return new Resetstats64(machInst); 2854 case M5OP_DUMP_STATS: return new Dumpstats64(machInst); 2855 case M5OP_DUMP_RESET_STATS: return new Dumpresetstats64(machInst); 2856 case M5OP_CHECKPOINT: return new M5checkpoint64(machInst); 2857 case M5OP_WRITE_FILE: return new M5writefile64(machInst); 2858 case M5OP_READ_FILE: return new M5readfile64(machInst); 2859 case M5OP_DEBUG_BREAK: return new M5break(machInst); 2860 case M5OP_SWITCH_CPU: return new M5switchcpu(machInst); 2861 case M5OP_ADD_SYMBOL: return new M5addsymbol64(machInst); 2862 case M5OP_PANIC: return new M5panic(machInst); 2863 case M5OP_WORK_BEGIN: return new M5workbegin64(machInst); 2864 case M5OP_WORK_END: return new M5workend64(machInst); 2865 default: return new Unknown64(machInst); 2866 } 2867 } 2868} 2869}}; 2870 2871def format Aarch64() {{ 2872 decode_block = ''' 2873 { 2874 using namespace Aarch64; 2875 if (bits(machInst, 27) == 0x0) { 2876 if (bits(machInst, 28) == 0x0) { 2877 if (bits(machInst, 26, 25) != 0x2) { 2878 return new Unknown64(machInst); 2879 } 2880 if (bits(machInst, 31) == 0x0) { 2881 switch (bits(machInst, 30, 29)) { 2882 case 0x0: 2883 case 0x1: 2884 case 0x2: 2885 return decodeSveInt(machInst); 2886 case 0x3: 2887 return decodeSveFp(machInst); 2888 } 2889 } else { 2890 return decodeSveMem(machInst); 2891 } 2892 } else if (bits(machInst, 26) == 0) 2893 // bit 28:26=100 2894 return decodeDataProcImm(machInst); 2895 else 2896 // bit 28:26=101 2897 return decodeBranchExcSys(machInst); 2898 } else if (bits(machInst, 25) == 0) { 2899 // bit 27=1, 25=0 2900 return decodeLoadsStores(machInst); 2901 } else if (bits(machInst, 26) == 0) { 2902 // bit 27:25=101 2903 return decodeDataProcReg(machInst); 2904 } else if (bits(machInst, 24) == 1 && 2905 bits(machInst, 31, 28) == 0xF) { 2906 return decodeGem5Ops(machInst); 2907 } else { 2908 // bit 27:25=111 2909 switch(decoderFlavour){ 2910 default: 2911 return decodeFpAdvSIMD<GenericDecoder>(machInst); 2912 } 2913 } 2914 } 2915 ''' 2916}};
| 1084 } 1085 default: 1086 return new Unknown64(machInst); 1087 } 1088 } 1089} 1090}}; 1091 1092 1093output decoder {{ 1094namespace Aarch64 1095{ 1096 1097 StaticInstPtr 1098 decodeLoadsStores(ExtMachInst machInst) 1099 { 1100 // bit 27,25=10 1101 switch (bits(machInst, 29, 28)) { 1102 case 0x0: 1103 if (bits(machInst, 26) == 0) { 1104 if (bits(machInst, 24) != 0) 1105 return new Unknown64(machInst); 1106 IntRegIndex rt = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 1107 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 1108 IntRegIndex rnsp = makeSP(rn); 1109 IntRegIndex rt2 = (IntRegIndex)(uint8_t)bits(machInst, 14, 10); 1110 IntRegIndex rs = (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 1111 uint8_t opc = (bits(machInst, 15) << 0) | 1112 (bits(machInst, 23, 21) << 1); 1113 uint8_t size = bits(machInst, 31, 30); 1114 switch (opc) { 1115 case 0x0: 1116 switch (size) { 1117 case 0x0: 1118 return new STXRB64(machInst, rt, rnsp, rs); 1119 case 0x1: 1120 return new STXRH64(machInst, rt, rnsp, rs); 1121 case 0x2: 1122 return new STXRW64(machInst, rt, rnsp, rs); 1123 case 0x3: 1124 return new STXRX64(machInst, rt, rnsp, rs); 1125 default: 1126 M5_UNREACHABLE; 1127 } 1128 case 0x1: 1129 switch (size) { 1130 case 0x0: 1131 return new STLXRB64(machInst, rt, rnsp, rs); 1132 case 0x1: 1133 return new STLXRH64(machInst, rt, rnsp, rs); 1134 case 0x2: 1135 return new STLXRW64(machInst, rt, rnsp, rs); 1136 case 0x3: 1137 return new STLXRX64(machInst, rt, rnsp, rs); 1138 default: 1139 M5_UNREACHABLE; 1140 } 1141 case 0x2: 1142 switch (size) { 1143 case 0x0: 1144 return new CASP32(machInst, rt, rnsp, rs); 1145 case 0x1: 1146 return new CASP64(machInst, rt, rnsp, rs); 1147 case 0x2: 1148 return new STXPW64(machInst, rs, rt, rt2, rnsp); 1149 case 0x3: 1150 return new STXPX64(machInst, rs, rt, rt2, rnsp); 1151 default: 1152 M5_UNREACHABLE; 1153 } 1154 1155 case 0x3: 1156 switch (size) { 1157 case 0x0: 1158 return new CASPL32(machInst, rt, rnsp, rs); 1159 case 0x1: 1160 return new CASPL64(machInst, rt, rnsp, rs); 1161 case 0x2: 1162 return new STLXPW64(machInst, rs, rt, rt2, rnsp); 1163 case 0x3: 1164 return new STLXPX64(machInst, rs, rt, rt2, rnsp); 1165 default: 1166 M5_UNREACHABLE; 1167 } 1168 1169 case 0x4: 1170 switch (size) { 1171 case 0x0: 1172 return new LDXRB64(machInst, rt, rnsp, rs); 1173 case 0x1: 1174 return new LDXRH64(machInst, rt, rnsp, rs); 1175 case 0x2: 1176 return new LDXRW64(machInst, rt, rnsp, rs); 1177 case 0x3: 1178 return new LDXRX64(machInst, rt, rnsp, rs); 1179 default: 1180 M5_UNREACHABLE; 1181 } 1182 case 0x5: 1183 switch (size) { 1184 case 0x0: 1185 return new LDAXRB64(machInst, rt, rnsp, rs); 1186 case 0x1: 1187 return new LDAXRH64(machInst, rt, rnsp, rs); 1188 case 0x2: 1189 return new LDAXRW64(machInst, rt, rnsp, rs); 1190 case 0x3: 1191 return new LDAXRX64(machInst, rt, rnsp, rs); 1192 default: 1193 M5_UNREACHABLE; 1194 } 1195 case 0x6: 1196 switch (size) { 1197 case 0x0: 1198 return new CASPA32(machInst, rt, rnsp, rs); 1199 case 0x1: 1200 return new CASPA64(machInst, rt, rnsp, rs); 1201 case 0x2: 1202 return new LDXPW64(machInst, rt, rt2, rnsp); 1203 case 0x3: 1204 return new LDXPX64(machInst, rt, rt2, rnsp); 1205 default: 1206 M5_UNREACHABLE; 1207 } 1208 case 0x7: 1209 switch (size) { 1210 case 0x0: 1211 return new CASPAL32(machInst, rt, rnsp, rs); 1212 case 0x1: 1213 return new CASPAL64(machInst, rt, rnsp, rs); 1214 case 0x2: 1215 return new LDAXPW64(machInst, rt, rt2, rnsp); 1216 case 0x3: 1217 return new LDAXPX64(machInst, rt, rt2, rnsp); 1218 default: 1219 M5_UNREACHABLE; 1220 } 1221 case 0x9: 1222 switch (size) { 1223 case 0x0: 1224 return new STLRB64(machInst, rt, rnsp); 1225 case 0x1: 1226 return new STLRH64(machInst, rt, rnsp); 1227 case 0x2: 1228 return new STLRW64(machInst, rt, rnsp); 1229 case 0x3: 1230 return new STLRX64(machInst, rt, rnsp); 1231 default: 1232 M5_UNREACHABLE; 1233 } 1234 case 0xa: 1235 switch (size) { 1236 case 0x0: 1237 return new CASB(machInst, rt, rnsp, rs); 1238 case 0x1: 1239 return new CASH(machInst, rt, rnsp, rs); 1240 case 0x2: 1241 return new CAS32(machInst, rt, rnsp, rs); 1242 case 0x3: 1243 return new CAS64(machInst, rt, rnsp, rs); 1244 default: 1245 M5_UNREACHABLE; 1246 } 1247 case 0xb: 1248 switch (size) { 1249 case 0x0: 1250 return new CASLB(machInst, rt, rnsp, rs); 1251 case 0x1: 1252 return new CASLH(machInst, rt, rnsp, rs); 1253 case 0x2: 1254 return new CASL32(machInst, rt, rnsp, rs); 1255 case 0x3: 1256 return new CASL64(machInst, rt, rnsp, rs); 1257 default: 1258 M5_UNREACHABLE; 1259 } 1260 case 0xd: 1261 switch (size) { 1262 case 0x0: 1263 return new LDARB64(machInst, rt, rnsp); 1264 case 0x1: 1265 return new LDARH64(machInst, rt, rnsp); 1266 case 0x2: 1267 return new LDARW64(machInst, rt, rnsp); 1268 case 0x3: 1269 return new LDARX64(machInst, rt, rnsp); 1270 default: 1271 M5_UNREACHABLE; 1272 } 1273 case 0xe: 1274 switch (size) { 1275 case 0x0: 1276 return new CASAB(machInst, rt, rnsp, rs); 1277 case 0x1: 1278 return new CASAH(machInst, rt, rnsp, rs); 1279 case 0x2: 1280 return new CASA32(machInst, rt, rnsp, rs); 1281 case 0x3: 1282 return new CASA64(machInst, rt, rnsp, rs); 1283 default: 1284 M5_UNREACHABLE; 1285 } 1286 case 0xf: 1287 switch (size) { 1288 case 0x0: 1289 return new CASALB(machInst, rt, rnsp, rs); 1290 case 0x1: 1291 return new CASALH(machInst, rt, rnsp, rs); 1292 case 0x2: 1293 return new CASAL32(machInst, rt, rnsp, rs); 1294 case 0x3: 1295 return new CASAL64(machInst, rt, rnsp, rs); 1296 default: 1297 M5_UNREACHABLE; 1298 } 1299 default: 1300 return new Unknown64(machInst); 1301 } 1302 } else if (bits(machInst, 31)) { 1303 return new Unknown64(machInst); 1304 } else { 1305 return decodeNeonMem(machInst); 1306 } 1307 case 0x1: 1308 { 1309 if (bits(machInst, 24) != 0) 1310 return new Unknown64(machInst); 1311 uint8_t switchVal = (bits(machInst, 26) << 0) | 1312 (bits(machInst, 31, 30) << 1); 1313 int64_t imm = sext<19>(bits(machInst, 23, 5)) << 2; 1314 IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 1315 switch (switchVal) { 1316 case 0x0: 1317 return new LDRWL64_LIT(machInst, rt, imm); 1318 case 0x1: 1319 return new LDRSFP64_LIT(machInst, rt, imm); 1320 case 0x2: 1321 return new LDRXL64_LIT(machInst, rt, imm); 1322 case 0x3: 1323 return new LDRDFP64_LIT(machInst, rt, imm); 1324 case 0x4: 1325 return new LDRSWL64_LIT(machInst, rt, imm); 1326 case 0x5: 1327 return new BigFpMemLit("ldr", machInst, rt, imm); 1328 case 0x6: 1329 return new PRFM64_LIT(machInst, rt, imm); 1330 default: 1331 return new Unknown64(machInst); 1332 } 1333 } 1334 case 0x2: 1335 { 1336 uint8_t opc = bits(machInst, 31, 30); 1337 if (opc >= 3) 1338 return new Unknown64(machInst); 1339 uint32_t size = 0; 1340 bool fp = bits(machInst, 26); 1341 bool load = bits(machInst, 22); 1342 if (fp) { 1343 size = 4 << opc; 1344 } else { 1345 if ((opc == 1) && !load) 1346 return new Unknown64(machInst); 1347 size = (opc == 0 || opc == 1) ? 4 : 8; 1348 } 1349 uint8_t type = bits(machInst, 24, 23); 1350 int64_t imm = sext<7>(bits(machInst, 21, 15)) * size; 1351 1352 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 1353 IntRegIndex rt = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 1354 IntRegIndex rt2 = (IntRegIndex)(uint8_t)bits(machInst, 14, 10); 1355 1356 bool noAlloc = (type == 0); 1357 bool signExt = !noAlloc && !fp && opc == 1; 1358 PairMemOp::AddrMode mode; 1359 const char *mnemonic = NULL; 1360 switch (type) { 1361 case 0x0: 1362 case 0x2: 1363 mode = PairMemOp::AddrMd_Offset; 1364 break; 1365 case 0x1: 1366 mode = PairMemOp::AddrMd_PostIndex; 1367 break; 1368 case 0x3: 1369 mode = PairMemOp::AddrMd_PreIndex; 1370 break; 1371 default: 1372 return new Unknown64(machInst); 1373 } 1374 if (load) { 1375 if (noAlloc) 1376 mnemonic = "ldnp"; 1377 else if (signExt) 1378 mnemonic = "ldpsw"; 1379 else 1380 mnemonic = "ldp"; 1381 } else { 1382 if (noAlloc) 1383 mnemonic = "stnp"; 1384 else 1385 mnemonic = "stp"; 1386 } 1387 1388 return new LdpStp(mnemonic, machInst, size, fp, load, noAlloc, 1389 signExt, false, false, imm, mode, rn, rt, rt2); 1390 } 1391 // bit 29:27=111, 25=0 1392 case 0x3: 1393 { 1394 uint8_t switchVal = (bits(machInst, 23, 22) << 0) | 1395 (bits(machInst, 26) << 2) | 1396 (bits(machInst, 31, 30) << 3); 1397 if (bits(machInst, 24) == 1) { 1398 uint64_t imm12 = bits(machInst, 21, 10); 1399 IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 1400 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 1401 IntRegIndex rnsp = makeSP(rn); 1402 switch (switchVal) { 1403 case 0x00: 1404 return new STRB64_IMM(machInst, rt, rnsp, imm12); 1405 case 0x01: 1406 return new LDRB64_IMM(machInst, rt, rnsp, imm12); 1407 case 0x02: 1408 return new LDRSBX64_IMM(machInst, rt, rnsp, imm12); 1409 case 0x03: 1410 return new LDRSBW64_IMM(machInst, rt, rnsp, imm12); 1411 case 0x04: 1412 return new STRBFP64_IMM(machInst, rt, rnsp, imm12); 1413 case 0x05: 1414 return new LDRBFP64_IMM(machInst, rt, rnsp, imm12); 1415 case 0x06: 1416 return new BigFpMemImm("str", machInst, false, 1417 rt, rnsp, imm12 << 4); 1418 case 0x07: 1419 return new BigFpMemImm("ldr", machInst, true, 1420 rt, rnsp, imm12 << 4); 1421 case 0x08: 1422 return new STRH64_IMM(machInst, rt, rnsp, imm12 << 1); 1423 case 0x09: 1424 return new LDRH64_IMM(machInst, rt, rnsp, imm12 << 1); 1425 case 0x0a: 1426 return new LDRSHX64_IMM(machInst, rt, rnsp, imm12 << 1); 1427 case 0x0b: 1428 return new LDRSHW64_IMM(machInst, rt, rnsp, imm12 << 1); 1429 case 0x0c: 1430 return new STRHFP64_IMM(machInst, rt, rnsp, imm12 << 1); 1431 case 0x0d: 1432 return new LDRHFP64_IMM(machInst, rt, rnsp, imm12 << 1); 1433 case 0x10: 1434 return new STRW64_IMM(machInst, rt, rnsp, imm12 << 2); 1435 case 0x11: 1436 return new LDRW64_IMM(machInst, rt, rnsp, imm12 << 2); 1437 case 0x12: 1438 return new LDRSW64_IMM(machInst, rt, rnsp, imm12 << 2); 1439 case 0x14: 1440 return new STRSFP64_IMM(machInst, rt, rnsp, imm12 << 2); 1441 case 0x15: 1442 return new LDRSFP64_IMM(machInst, rt, rnsp, imm12 << 2); 1443 case 0x18: 1444 return new STRX64_IMM(machInst, rt, rnsp, imm12 << 3); 1445 case 0x19: 1446 return new LDRX64_IMM(machInst, rt, rnsp, imm12 << 3); 1447 case 0x1a: 1448 return new PRFM64_IMM(machInst, rt, rnsp, imm12 << 3); 1449 case 0x1c: 1450 return new STRDFP64_IMM(machInst, rt, rnsp, imm12 << 3); 1451 case 0x1d: 1452 return new LDRDFP64_IMM(machInst, rt, rnsp, imm12 << 3); 1453 default: 1454 return new Unknown64(machInst); 1455 } 1456 } else if (bits(machInst, 21) == 1) { 1457 uint8_t group = bits(machInst, 11, 10); 1458 switch (group) { 1459 case 0x0: 1460 { 1461 if ((switchVal & 0x7) == 0x2 && 1462 bits(machInst, 20, 12) == 0x1fc) { 1463 IntRegIndex rt = (IntRegIndex)(uint32_t) 1464 bits(machInst, 4, 0); 1465 IntRegIndex rn = (IntRegIndex)(uint32_t) 1466 bits(machInst, 9, 5); 1467 IntRegIndex rnsp = makeSP(rn); 1468 uint8_t size = bits(machInst, 31, 30); 1469 switch (size) { 1470 case 0x0: 1471 return new LDAPRB64(machInst, rt, rnsp); 1472 case 0x1: 1473 return new LDAPRH64(machInst, rt, rnsp); 1474 case 0x2: 1475 return new LDAPRW64(machInst, rt, rnsp); 1476 case 0x3: 1477 return new LDAPRX64(machInst, rt, rnsp); 1478 default: 1479 M5_UNREACHABLE; 1480 } 1481 } else { 1482 return decodeAtomicArithOp(machInst); 1483 } 1484 } 1485 case 0x2: 1486 { 1487 if (!bits(machInst, 14)) 1488 return new Unknown64(machInst); 1489 IntRegIndex rt = (IntRegIndex)(uint32_t) 1490 bits(machInst, 4, 0); 1491 IntRegIndex rn = (IntRegIndex)(uint32_t) 1492 bits(machInst, 9, 5); 1493 IntRegIndex rnsp = makeSP(rn); 1494 IntRegIndex rm = (IntRegIndex)(uint32_t) 1495 bits(machInst, 20, 16); 1496 ArmExtendType type = 1497 (ArmExtendType)(uint32_t)bits(machInst, 15, 13); 1498 uint8_t s = bits(machInst, 12); 1499 switch (switchVal) { 1500 case 0x00: 1501 return new STRB64_REG(machInst, rt, rnsp, rm, 1502 type, 0); 1503 case 0x01: 1504 return new LDRB64_REG(machInst, rt, rnsp, rm, 1505 type, 0); 1506 case 0x02: 1507 return new LDRSBX64_REG(machInst, rt, rnsp, rm, 1508 type, 0); 1509 case 0x03: 1510 return new LDRSBW64_REG(machInst, rt, rnsp, rm, 1511 type, 0); 1512 case 0x04: 1513 return new STRBFP64_REG(machInst, rt, rnsp, rm, 1514 type, 0); 1515 case 0x05: 1516 return new LDRBFP64_REG(machInst, rt, rnsp, rm, 1517 type, 0); 1518 case 0x6: 1519 return new BigFpMemReg("str", machInst, false, 1520 rt, rnsp, rm, type, s * 4); 1521 case 0x7: 1522 return new BigFpMemReg("ldr", machInst, true, 1523 rt, rnsp, rm, type, s * 4); 1524 case 0x08: 1525 return new STRH64_REG(machInst, rt, rnsp, rm, 1526 type, s); 1527 case 0x09: 1528 return new LDRH64_REG(machInst, rt, rnsp, rm, 1529 type, s); 1530 case 0x0a: 1531 return new LDRSHX64_REG(machInst, rt, rnsp, rm, 1532 type, s); 1533 case 0x0b: 1534 return new LDRSHW64_REG(machInst, rt, rnsp, rm, 1535 type, s); 1536 case 0x0c: 1537 return new STRHFP64_REG(machInst, rt, rnsp, rm, 1538 type, s); 1539 case 0x0d: 1540 return new LDRHFP64_REG(machInst, rt, rnsp, rm, 1541 type, s); 1542 case 0x10: 1543 return new STRW64_REG(machInst, rt, rnsp, rm, 1544 type, s * 2); 1545 case 0x11: 1546 return new LDRW64_REG(machInst, rt, rnsp, rm, 1547 type, s * 2); 1548 case 0x12: 1549 return new LDRSW64_REG(machInst, rt, rnsp, rm, 1550 type, s * 2); 1551 case 0x14: 1552 return new STRSFP64_REG(machInst, rt, rnsp, rm, 1553 type, s * 2); 1554 case 0x15: 1555 return new LDRSFP64_REG(machInst, rt, rnsp, rm, 1556 type, s * 2); 1557 case 0x18: 1558 return new STRX64_REG(machInst, rt, rnsp, rm, 1559 type, s * 3); 1560 case 0x19: 1561 return new LDRX64_REG(machInst, rt, rnsp, rm, 1562 type, s * 3); 1563 case 0x1a: 1564 return new PRFM64_REG(machInst, rt, rnsp, rm, 1565 type, s * 3); 1566 case 0x1c: 1567 return new STRDFP64_REG(machInst, rt, rnsp, rm, 1568 type, s * 3); 1569 case 0x1d: 1570 return new LDRDFP64_REG(machInst, rt, rnsp, rm, 1571 type, s * 3); 1572 default: 1573 return new Unknown64(machInst); 1574 1575 } 1576 } 1577 default: 1578 return new Unknown64(machInst); 1579 } 1580 } else { 1581 // bit 29:27=111, 25:24=00, 21=0 1582 switch (bits(machInst, 11, 10)) { 1583 case 0x0: 1584 { 1585 IntRegIndex rt = 1586 (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 1587 IntRegIndex rn = 1588 (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 1589 IntRegIndex rnsp = makeSP(rn); 1590 uint64_t imm = sext<9>(bits(machInst, 20, 12)); 1591 switch (switchVal) { 1592 case 0x00: 1593 return new STURB64_IMM(machInst, rt, rnsp, imm); 1594 case 0x01: 1595 return new LDURB64_IMM(machInst, rt, rnsp, imm); 1596 case 0x02: 1597 return new LDURSBX64_IMM(machInst, rt, rnsp, imm); 1598 case 0x03: 1599 return new LDURSBW64_IMM(machInst, rt, rnsp, imm); 1600 case 0x04: 1601 return new STURBFP64_IMM(machInst, rt, rnsp, imm); 1602 case 0x05: 1603 return new LDURBFP64_IMM(machInst, rt, rnsp, imm); 1604 case 0x06: 1605 return new BigFpMemImm("stur", machInst, false, 1606 rt, rnsp, imm); 1607 case 0x07: 1608 return new BigFpMemImm("ldur", machInst, true, 1609 rt, rnsp, imm); 1610 case 0x08: 1611 return new STURH64_IMM(machInst, rt, rnsp, imm); 1612 case 0x09: 1613 return new LDURH64_IMM(machInst, rt, rnsp, imm); 1614 case 0x0a: 1615 return new LDURSHX64_IMM(machInst, rt, rnsp, imm); 1616 case 0x0b: 1617 return new LDURSHW64_IMM(machInst, rt, rnsp, imm); 1618 case 0x0c: 1619 return new STURHFP64_IMM(machInst, rt, rnsp, imm); 1620 case 0x0d: 1621 return new LDURHFP64_IMM(machInst, rt, rnsp, imm); 1622 case 0x10: 1623 return new STURW64_IMM(machInst, rt, rnsp, imm); 1624 case 0x11: 1625 return new LDURW64_IMM(machInst, rt, rnsp, imm); 1626 case 0x12: 1627 return new LDURSW64_IMM(machInst, rt, rnsp, imm); 1628 case 0x14: 1629 return new STURSFP64_IMM(machInst, rt, rnsp, imm); 1630 case 0x15: 1631 return new LDURSFP64_IMM(machInst, rt, rnsp, imm); 1632 case 0x18: 1633 return new STURX64_IMM(machInst, rt, rnsp, imm); 1634 case 0x19: 1635 return new LDURX64_IMM(machInst, rt, rnsp, imm); 1636 case 0x1a: 1637 return new PRFUM64_IMM(machInst, rt, rnsp, imm); 1638 case 0x1c: 1639 return new STURDFP64_IMM(machInst, rt, rnsp, imm); 1640 case 0x1d: 1641 return new LDURDFP64_IMM(machInst, rt, rnsp, imm); 1642 default: 1643 return new Unknown64(machInst); 1644 } 1645 } 1646 // bit 29:27=111, 25:24=00, 21=0, 11:10=01 1647 case 0x1: 1648 { 1649 IntRegIndex rt = 1650 (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 1651 IntRegIndex rn = 1652 (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 1653 IntRegIndex rnsp = makeSP(rn); 1654 uint64_t imm = sext<9>(bits(machInst, 20, 12)); 1655 switch (switchVal) { 1656 case 0x00: 1657 return new STRB64_POST(machInst, rt, rnsp, imm); 1658 case 0x01: 1659 return new LDRB64_POST(machInst, rt, rnsp, imm); 1660 case 0x02: 1661 return new LDRSBX64_POST(machInst, rt, rnsp, imm); 1662 case 0x03: 1663 return new LDRSBW64_POST(machInst, rt, rnsp, imm); 1664 case 0x04: 1665 return new STRBFP64_POST(machInst, rt, rnsp, imm); 1666 case 0x05: 1667 return new LDRBFP64_POST(machInst, rt, rnsp, imm); 1668 case 0x06: 1669 return new BigFpMemPost("str", machInst, false, 1670 rt, rnsp, imm); 1671 case 0x07: 1672 return new BigFpMemPost("ldr", machInst, true, 1673 rt, rnsp, imm); 1674 case 0x08: 1675 return new STRH64_POST(machInst, rt, rnsp, imm); 1676 case 0x09: 1677 return new LDRH64_POST(machInst, rt, rnsp, imm); 1678 case 0x0a: 1679 return new LDRSHX64_POST(machInst, rt, rnsp, imm); 1680 case 0x0b: 1681 return new LDRSHW64_POST(machInst, rt, rnsp, imm); 1682 case 0x0c: 1683 return new STRHFP64_POST(machInst, rt, rnsp, imm); 1684 case 0x0d: 1685 return new LDRHFP64_POST(machInst, rt, rnsp, imm); 1686 case 0x10: 1687 return new STRW64_POST(machInst, rt, rnsp, imm); 1688 case 0x11: 1689 return new LDRW64_POST(machInst, rt, rnsp, imm); 1690 case 0x12: 1691 return new LDRSW64_POST(machInst, rt, rnsp, imm); 1692 case 0x14: 1693 return new STRSFP64_POST(machInst, rt, rnsp, imm); 1694 case 0x15: 1695 return new LDRSFP64_POST(machInst, rt, rnsp, imm); 1696 case 0x18: 1697 return new STRX64_POST(machInst, rt, rnsp, imm); 1698 case 0x19: 1699 return new LDRX64_POST(machInst, rt, rnsp, imm); 1700 case 0x1c: 1701 return new STRDFP64_POST(machInst, rt, rnsp, imm); 1702 case 0x1d: 1703 return new LDRDFP64_POST(machInst, rt, rnsp, imm); 1704 default: 1705 return new Unknown64(machInst); 1706 } 1707 } 1708 case 0x2: 1709 { 1710 IntRegIndex rt = 1711 (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 1712 IntRegIndex rn = 1713 (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 1714 IntRegIndex rnsp = makeSP(rn); 1715 uint64_t imm = sext<9>(bits(machInst, 20, 12)); 1716 switch (switchVal) { 1717 case 0x00: 1718 return new STTRB64_IMM(machInst, rt, rnsp, imm); 1719 case 0x01: 1720 return new LDTRB64_IMM(machInst, rt, rnsp, imm); 1721 case 0x02: 1722 return new LDTRSBX64_IMM(machInst, rt, rnsp, imm); 1723 case 0x03: 1724 return new LDTRSBW64_IMM(machInst, rt, rnsp, imm); 1725 case 0x08: 1726 return new STTRH64_IMM(machInst, rt, rnsp, imm); 1727 case 0x09: 1728 return new LDTRH64_IMM(machInst, rt, rnsp, imm); 1729 case 0x0a: 1730 return new LDTRSHX64_IMM(machInst, rt, rnsp, imm); 1731 case 0x0b: 1732 return new LDTRSHW64_IMM(machInst, rt, rnsp, imm); 1733 case 0x10: 1734 return new STTRW64_IMM(machInst, rt, rnsp, imm); 1735 case 0x11: 1736 return new LDTRW64_IMM(machInst, rt, rnsp, imm); 1737 case 0x12: 1738 return new LDTRSW64_IMM(machInst, rt, rnsp, imm); 1739 case 0x18: 1740 return new STTRX64_IMM(machInst, rt, rnsp, imm); 1741 case 0x19: 1742 return new LDTRX64_IMM(machInst, rt, rnsp, imm); 1743 default: 1744 return new Unknown64(machInst); 1745 } 1746 } 1747 case 0x3: 1748 { 1749 IntRegIndex rt = 1750 (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 1751 IntRegIndex rn = 1752 (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 1753 IntRegIndex rnsp = makeSP(rn); 1754 uint64_t imm = sext<9>(bits(machInst, 20, 12)); 1755 switch (switchVal) { 1756 case 0x00: 1757 return new STRB64_PRE(machInst, rt, rnsp, imm); 1758 case 0x01: 1759 return new LDRB64_PRE(machInst, rt, rnsp, imm); 1760 case 0x02: 1761 return new LDRSBX64_PRE(machInst, rt, rnsp, imm); 1762 case 0x03: 1763 return new LDRSBW64_PRE(machInst, rt, rnsp, imm); 1764 case 0x04: 1765 return new STRBFP64_PRE(machInst, rt, rnsp, imm); 1766 case 0x05: 1767 return new LDRBFP64_PRE(machInst, rt, rnsp, imm); 1768 case 0x06: 1769 return new BigFpMemPre("str", machInst, false, 1770 rt, rnsp, imm); 1771 case 0x07: 1772 return new BigFpMemPre("ldr", machInst, true, 1773 rt, rnsp, imm); 1774 case 0x08: 1775 return new STRH64_PRE(machInst, rt, rnsp, imm); 1776 case 0x09: 1777 return new LDRH64_PRE(machInst, rt, rnsp, imm); 1778 case 0x0a: 1779 return new LDRSHX64_PRE(machInst, rt, rnsp, imm); 1780 case 0x0b: 1781 return new LDRSHW64_PRE(machInst, rt, rnsp, imm); 1782 case 0x0c: 1783 return new STRHFP64_PRE(machInst, rt, rnsp, imm); 1784 case 0x0d: 1785 return new LDRHFP64_PRE(machInst, rt, rnsp, imm); 1786 case 0x10: 1787 return new STRW64_PRE(machInst, rt, rnsp, imm); 1788 case 0x11: 1789 return new LDRW64_PRE(machInst, rt, rnsp, imm); 1790 case 0x12: 1791 return new LDRSW64_PRE(machInst, rt, rnsp, imm); 1792 case 0x14: 1793 return new STRSFP64_PRE(machInst, rt, rnsp, imm); 1794 case 0x15: 1795 return new LDRSFP64_PRE(machInst, rt, rnsp, imm); 1796 case 0x18: 1797 return new STRX64_PRE(machInst, rt, rnsp, imm); 1798 case 0x19: 1799 return new LDRX64_PRE(machInst, rt, rnsp, imm); 1800 case 0x1c: 1801 return new STRDFP64_PRE(machInst, rt, rnsp, imm); 1802 case 0x1d: 1803 return new LDRDFP64_PRE(machInst, rt, rnsp, imm); 1804 default: 1805 return new Unknown64(machInst); 1806 } 1807 } 1808 default: 1809 M5_UNREACHABLE; 1810 } 1811 } 1812 } 1813 default: 1814 M5_UNREACHABLE; 1815 } 1816 return new FailUnimplemented("Unhandled Case1", machInst); 1817 } 1818} 1819}}; 1820 1821output decoder {{ 1822namespace Aarch64 1823{ 1824 StaticInstPtr 1825 decodeDataProcReg(ExtMachInst machInst) 1826 { 1827 uint8_t switchVal = (bits(machInst, 28) << 1) | 1828 (bits(machInst, 24) << 0); 1829 switch (switchVal) { 1830 case 0x0: 1831 { 1832 uint8_t switchVal = (bits(machInst, 21) << 0) | 1833 (bits(machInst, 30, 29) << 1); 1834 ArmShiftType type = (ArmShiftType)(uint8_t)bits(machInst, 23, 22); 1835 uint8_t imm6 = bits(machInst, 15, 10); 1836 bool sf = bits(machInst, 31); 1837 if (!sf && (imm6 & 0x20)) 1838 return new Unknown64(machInst); 1839 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 1840 IntRegIndex rdzr = makeZero(rd); 1841 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 1842 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 1843 1844 switch (switchVal) { 1845 case 0x0: 1846 return new AndXSReg(machInst, rdzr, rn, rm, imm6, type); 1847 case 0x1: 1848 return new BicXSReg(machInst, rdzr, rn, rm, imm6, type); 1849 case 0x2: 1850 return new OrrXSReg(machInst, rdzr, rn, rm, imm6, type); 1851 case 0x3: 1852 return new OrnXSReg(machInst, rdzr, rn, rm, imm6, type); 1853 case 0x4: 1854 return new EorXSReg(machInst, rdzr, rn, rm, imm6, type); 1855 case 0x5: 1856 return new EonXSReg(machInst, rdzr, rn, rm, imm6, type); 1857 case 0x6: 1858 return new AndXSRegCc(machInst, rdzr, rn, rm, imm6, type); 1859 case 0x7: 1860 return new BicXSRegCc(machInst, rdzr, rn, rm, imm6, type); 1861 default: 1862 M5_UNREACHABLE; 1863 } 1864 } 1865 case 0x1: 1866 { 1867 uint8_t switchVal = bits(machInst, 30, 29); 1868 if (bits(machInst, 21) == 0) { 1869 ArmShiftType type = 1870 (ArmShiftType)(uint8_t)bits(machInst, 23, 22); 1871 if (type == ROR) 1872 return new Unknown64(machInst); 1873 uint8_t imm6 = bits(machInst, 15, 10); 1874 if (!bits(machInst, 31) && bits(imm6, 5)) 1875 return new Unknown64(machInst); 1876 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 1877 IntRegIndex rdzr = makeZero(rd); 1878 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 1879 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 1880 switch (switchVal) { 1881 case 0x0: 1882 return new AddXSReg(machInst, rdzr, rn, rm, imm6, type); 1883 case 0x1: 1884 return new AddXSRegCc(machInst, rdzr, rn, rm, imm6, type); 1885 case 0x2: 1886 return new SubXSReg(machInst, rdzr, rn, rm, imm6, type); 1887 case 0x3: 1888 return new SubXSRegCc(machInst, rdzr, rn, rm, imm6, type); 1889 default: 1890 M5_UNREACHABLE; 1891 } 1892 } else { 1893 if (bits(machInst, 23, 22) != 0 || bits(machInst, 12, 10) > 0x4) 1894 return new Unknown64(machInst); 1895 ArmExtendType type = 1896 (ArmExtendType)(uint8_t)bits(machInst, 15, 13); 1897 uint8_t imm3 = bits(machInst, 12, 10); 1898 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 1899 IntRegIndex rdsp = makeSP(rd); 1900 IntRegIndex rdzr = makeZero(rd); 1901 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 1902 IntRegIndex rnsp = makeSP(rn); 1903 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 1904 1905 switch (switchVal) { 1906 case 0x0: 1907 return new AddXEReg(machInst, rdsp, rnsp, rm, type, imm3); 1908 case 0x1: 1909 return new AddXERegCc(machInst, rdzr, rnsp, rm, type, imm3); 1910 case 0x2: 1911 return new SubXEReg(machInst, rdsp, rnsp, rm, type, imm3); 1912 case 0x3: 1913 return new SubXERegCc(machInst, rdzr, rnsp, rm, type, imm3); 1914 default: 1915 M5_UNREACHABLE; 1916 } 1917 } 1918 } 1919 case 0x2: 1920 { 1921 if (bits(machInst, 21) == 1) 1922 return new Unknown64(machInst); 1923 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 1924 IntRegIndex rdzr = makeZero(rd); 1925 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 1926 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 1927 switch (bits(machInst, 23, 22)) { 1928 case 0x0: 1929 { 1930 if (bits(machInst, 15, 10)) 1931 return new Unknown64(machInst); 1932 uint8_t switchVal = bits(machInst, 30, 29); 1933 switch (switchVal) { 1934 case 0x0: 1935 return new AdcXSReg(machInst, rdzr, rn, rm, 0, LSL); 1936 case 0x1: 1937 return new AdcXSRegCc(machInst, rdzr, rn, rm, 0, LSL); 1938 case 0x2: 1939 return new SbcXSReg(machInst, rdzr, rn, rm, 0, LSL); 1940 case 0x3: 1941 return new SbcXSRegCc(machInst, rdzr, rn, rm, 0, LSL); 1942 default: 1943 M5_UNREACHABLE; 1944 } 1945 } 1946 case 0x1: 1947 { 1948 if ((bits(machInst, 4) == 1) || 1949 (bits(machInst, 10) == 1) || 1950 (bits(machInst, 29) == 0)) { 1951 return new Unknown64(machInst); 1952 } 1953 ConditionCode cond = 1954 (ConditionCode)(uint8_t)bits(machInst, 15, 12); 1955 uint8_t flags = bits(machInst, 3, 0); 1956 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 1957 if (bits(machInst, 11) == 0) { 1958 IntRegIndex rm = 1959 (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 1960 if (bits(machInst, 30) == 0) { 1961 return new CcmnReg64(machInst, rn, rm, cond, flags); 1962 } else { 1963 return new CcmpReg64(machInst, rn, rm, cond, flags); 1964 } 1965 } else { 1966 uint8_t imm5 = bits(machInst, 20, 16); 1967 if (bits(machInst, 30) == 0) { 1968 return new CcmnImm64(machInst, rn, imm5, cond, flags); 1969 } else { 1970 return new CcmpImm64(machInst, rn, imm5, cond, flags); 1971 } 1972 } 1973 } 1974 case 0x2: 1975 { 1976 if (bits(machInst, 29) == 1 || 1977 bits(machInst, 11) == 1) { 1978 return new Unknown64(machInst); 1979 } 1980 uint8_t switchVal = (bits(machInst, 10) << 0) | 1981 (bits(machInst, 30) << 1); 1982 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 1983 IntRegIndex rdzr = makeZero(rd); 1984 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 1985 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 1986 ConditionCode cond = 1987 (ConditionCode)(uint8_t)bits(machInst, 15, 12); 1988 switch (switchVal) { 1989 case 0x0: 1990 return new Csel64(machInst, rdzr, rn, rm, cond); 1991 case 0x1: 1992 return new Csinc64(machInst, rdzr, rn, rm, cond); 1993 case 0x2: 1994 return new Csinv64(machInst, rdzr, rn, rm, cond); 1995 case 0x3: 1996 return new Csneg64(machInst, rdzr, rn, rm, cond); 1997 default: 1998 M5_UNREACHABLE; 1999 } 2000 } 2001 case 0x3: 2002 if (bits(machInst, 30) == 0) { 2003 if (bits(machInst, 29) != 0) 2004 return new Unknown64(machInst); 2005 uint8_t switchVal = bits(machInst, 15, 10); 2006 switch (switchVal) { 2007 case 0x2: 2008 return new Udiv64(machInst, rdzr, rn, rm); 2009 case 0x3: 2010 return new Sdiv64(machInst, rdzr, rn, rm); 2011 case 0x8: 2012 return new Lslv64(machInst, rdzr, rn, rm); 2013 case 0x9: 2014 return new Lsrv64(machInst, rdzr, rn, rm); 2015 case 0xa: 2016 return new Asrv64(machInst, rdzr, rn, rm); 2017 case 0xb: 2018 return new Rorv64(machInst, rdzr, rn, rm); 2019 case 0x10: 2020 return new Crc32b64(machInst, rdzr, rn, rm); 2021 case 0x11: 2022 return new Crc32h64(machInst, rdzr, rn, rm); 2023 case 0x12: 2024 return new Crc32w64(machInst, rdzr, rn, rm); 2025 case 0x13: 2026 return new Crc32x64(machInst, rdzr, rn, rm); 2027 case 0x14: 2028 return new Crc32cb64(machInst, rdzr, rn, rm); 2029 case 0x15: 2030 return new Crc32ch64(machInst, rdzr, rn, rm); 2031 case 0x16: 2032 return new Crc32cw64(machInst, rdzr, rn, rm); 2033 case 0x17: 2034 return new Crc32cx64(machInst, rdzr, rn, rm); 2035 default: 2036 return new Unknown64(machInst); 2037 } 2038 } else { 2039 if (bits(machInst, 20, 16) != 0 || 2040 bits(machInst, 29) != 0) { 2041 return new Unknown64(machInst); 2042 } 2043 uint8_t switchVal = bits(machInst, 15, 10); 2044 switch (switchVal) { 2045 case 0x0: 2046 return new Rbit64(machInst, rdzr, rn); 2047 case 0x1: 2048 return new Rev1664(machInst, rdzr, rn); 2049 case 0x2: 2050 if (bits(machInst, 31) == 0) 2051 return new Rev64(machInst, rdzr, rn); 2052 else 2053 return new Rev3264(machInst, rdzr, rn); 2054 case 0x3: 2055 if (bits(machInst, 31) != 1) 2056 return new Unknown64(machInst); 2057 return new Rev64(machInst, rdzr, rn); 2058 case 0x4: 2059 return new Clz64(machInst, rdzr, rn); 2060 case 0x5: 2061 return new Cls64(machInst, rdzr, rn); 2062 default: 2063 return new Unknown64(machInst); 2064 } 2065 } 2066 default: 2067 M5_UNREACHABLE; 2068 } 2069 } 2070 case 0x3: 2071 { 2072 if (bits(machInst, 30, 29) != 0x0 || 2073 (bits(machInst, 23, 21) != 0 && bits(machInst, 31) == 0)) 2074 return new Unknown64(machInst); 2075 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 2076 IntRegIndex rdzr = makeZero(rd); 2077 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 2078 IntRegIndex ra = (IntRegIndex)(uint8_t)bits(machInst, 14, 10); 2079 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 2080 switch (bits(machInst, 23, 21)) { 2081 case 0x0: 2082 if (bits(machInst, 15) == 0) 2083 return new Madd64(machInst, rdzr, ra, rn, rm); 2084 else 2085 return new Msub64(machInst, rdzr, ra, rn, rm); 2086 case 0x1: 2087 if (bits(machInst, 15) == 0) 2088 return new Smaddl64(machInst, rdzr, ra, rn, rm); 2089 else 2090 return new Smsubl64(machInst, rdzr, ra, rn, rm); 2091 case 0x2: 2092 if (bits(machInst, 15) != 0) 2093 return new Unknown64(machInst); 2094 return new Smulh64(machInst, rdzr, rn, rm); 2095 case 0x5: 2096 if (bits(machInst, 15) == 0) 2097 return new Umaddl64(machInst, rdzr, ra, rn, rm); 2098 else 2099 return new Umsubl64(machInst, rdzr, ra, rn, rm); 2100 case 0x6: 2101 if (bits(machInst, 15) != 0) 2102 return new Unknown64(machInst); 2103 return new Umulh64(machInst, rdzr, rn, rm); 2104 default: 2105 return new Unknown64(machInst); 2106 } 2107 } 2108 default: 2109 M5_UNREACHABLE; 2110 } 2111 return new FailUnimplemented("Unhandled Case2", machInst); 2112 } 2113} 2114}}; 2115 2116output decoder {{ 2117namespace Aarch64 2118{ 2119 template <typename DecoderFeatures> 2120 StaticInstPtr 2121 decodeAdvSIMD(ExtMachInst machInst) 2122 { 2123 if (bits(machInst, 24) == 1) { 2124 if (bits(machInst, 10) == 0) { 2125 return decodeNeonIndexedElem<DecoderFeatures>(machInst); 2126 } else if (bits(machInst, 23) == 1) { 2127 return new Unknown64(machInst); 2128 } else { 2129 if (bits(machInst, 22, 19)) { 2130 return decodeNeonShiftByImm(machInst); 2131 } else { 2132 return decodeNeonModImm(machInst); 2133 } 2134 } 2135 } else if (bits(machInst, 21) == 1) { 2136 if (bits(machInst, 10) == 1) { 2137 return decodeNeon3Same<DecoderFeatures>(machInst); 2138 } else if (bits(machInst, 11) == 0) { 2139 return decodeNeon3Diff(machInst); 2140 } else if (bits(machInst, 20, 17) == 0x0) { 2141 return decodeNeon2RegMisc(machInst); 2142 } else if (bits(machInst, 20, 17) == 0x4) { 2143 return decodeCryptoAES(machInst); 2144 } else if (bits(machInst, 20, 17) == 0x8) { 2145 return decodeNeonAcrossLanes(machInst); 2146 } else { 2147 return new Unknown64(machInst); 2148 } 2149 } else if (bits(machInst, 24) || 2150 bits(machInst, 21) || 2151 bits(machInst, 15)) { 2152 return new Unknown64(machInst); 2153 } else if (bits(machInst, 10) == 1) { 2154 if (bits(machInst, 23, 22)) 2155 return new Unknown64(machInst); 2156 return decodeNeonCopy(machInst); 2157 } else if (bits(machInst, 29) == 1) { 2158 return decodeNeonExt(machInst); 2159 } else if (bits(machInst, 11) == 1) { 2160 return decodeNeonZipUzpTrn(machInst); 2161 } else if (bits(machInst, 23, 22) == 0x0) { 2162 return decodeNeonTblTbx(machInst); 2163 } else { 2164 return new Unknown64(machInst); 2165 } 2166 return new FailUnimplemented("Unhandled Case3", machInst); 2167 } 2168} 2169}}; 2170 2171 2172output decoder {{ 2173namespace Aarch64 2174{ 2175 StaticInstPtr 2176 // bit 30=0, 28:25=1111 2177 decodeFp(ExtMachInst machInst) 2178 { 2179 if (bits(machInst, 24) == 1) { 2180 if (bits(machInst, 31) || bits(machInst, 29)) 2181 return new Unknown64(machInst); 2182 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 2183 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 2184 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 20, 16); 2185 IntRegIndex ra = (IntRegIndex)(uint32_t)bits(machInst, 14, 10); 2186 uint8_t switchVal = (bits(machInst, 23, 21) << 1) | 2187 (bits(machInst, 15) << 0); 2188 switch (switchVal) { 2189 case 0x0: // FMADD Sd = Sa + Sn*Sm 2190 return new FMAddS(machInst, rd, rn, rm, ra); 2191 case 0x1: // FMSUB Sd = Sa + (-Sn)*Sm 2192 return new FMSubS(machInst, rd, rn, rm, ra); 2193 case 0x2: // FNMADD Sd = (-Sa) + (-Sn)*Sm 2194 return new FNMAddS(machInst, rd, rn, rm, ra); 2195 case 0x3: // FNMSUB Sd = (-Sa) + Sn*Sm 2196 return new FNMSubS(machInst, rd, rn, rm, ra); 2197 case 0x4: // FMADD Dd = Da + Dn*Dm 2198 return new FMAddD(machInst, rd, rn, rm, ra); 2199 case 0x5: // FMSUB Dd = Da + (-Dn)*Dm 2200 return new FMSubD(machInst, rd, rn, rm, ra); 2201 case 0x6: // FNMADD Dd = (-Da) + (-Dn)*Dm 2202 return new FNMAddD(machInst, rd, rn, rm, ra); 2203 case 0x7: // FNMSUB Dd = (-Da) + Dn*Dm 2204 return new FNMSubD(machInst, rd, rn, rm, ra); 2205 default: 2206 return new Unknown64(machInst); 2207 } 2208 } else if (bits(machInst, 21) == 0) { 2209 bool s = bits(machInst, 29); 2210 if (s) 2211 return new Unknown64(machInst); 2212 uint8_t switchVal = bits(machInst, 20, 16); 2213 uint8_t type = bits(machInst, 23, 22); 2214 uint8_t scale = bits(machInst, 15, 10); 2215 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 2216 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 2217 if (bits(machInst, 18, 17) == 3 && scale != 0) 2218 return new Unknown64(machInst); 2219 // 30:24=0011110, 21=0 2220 switch (switchVal) { 2221 case 0x00: 2222 return new FailUnimplemented("fcvtns", machInst); 2223 case 0x01: 2224 return new FailUnimplemented("fcvtnu", machInst); 2225 case 0x02: 2226 switch ( (bits(machInst, 31) << 2) | type ) { 2227 case 0: // SCVTF Sd = convertFromInt(Wn/(2^fbits)) 2228 return new FcvtSFixedFpSW(machInst, rd, rn, scale); 2229 case 1: // SCVTF Dd = convertFromInt(Wn/(2^fbits)) 2230 return new FcvtSFixedFpDW(machInst, rd, rn, scale); 2231 case 4: // SCVTF Sd = convertFromInt(Xn/(2^fbits)) 2232 return new FcvtSFixedFpSX(machInst, rd, rn, scale); 2233 case 5: // SCVTF Dd = convertFromInt(Xn/(2^fbits)) 2234 return new FcvtSFixedFpDX(machInst, rd, rn, scale); 2235 default: 2236 return new Unknown64(machInst); 2237 } 2238 case 0x03: 2239 switch ( (bits(machInst, 31) << 2) | type ) { 2240 case 0: // UCVTF Sd = convertFromInt(Wn/(2^fbits)) 2241 return new FcvtUFixedFpSW(machInst, rd, rn, scale); 2242 case 1: // UCVTF Dd = convertFromInt(Wn/(2^fbits)) 2243 return new FcvtUFixedFpDW(machInst, rd, rn, scale); 2244 case 4: // UCVTF Sd = convertFromInt(Xn/(2^fbits)) 2245 return new FcvtUFixedFpSX(machInst, rd, rn, scale); 2246 case 5: // UCVTF Dd = convertFromInt(Xn/(2^fbits)) 2247 return new FcvtUFixedFpDX(machInst, rd, rn, scale); 2248 default: 2249 return new Unknown64(machInst); 2250 } 2251 case 0x04: 2252 return new FailUnimplemented("fcvtas", machInst); 2253 case 0x05: 2254 return new FailUnimplemented("fcvtau", machInst); 2255 case 0x08: 2256 return new FailUnimplemented("fcvtps", machInst); 2257 case 0x09: 2258 return new FailUnimplemented("fcvtpu", machInst); 2259 case 0x0e: 2260 return new FailUnimplemented("fmov elem. to 64", machInst); 2261 case 0x0f: 2262 return new FailUnimplemented("fmov 64 bit", machInst); 2263 case 0x10: 2264 return new FailUnimplemented("fcvtms", machInst); 2265 case 0x11: 2266 return new FailUnimplemented("fcvtmu", machInst); 2267 case 0x18: 2268 switch ( (bits(machInst, 31) << 2) | type ) { 2269 case 0: // FCVTZS Wd = convertToIntExactTowardZero(Sn*(2^fbits)) 2270 return new FcvtFpSFixedSW(machInst, rd, rn, scale); 2271 case 1: // FCVTZS Wd = convertToIntExactTowardZero(Dn*(2^fbits)) 2272 return new FcvtFpSFixedDW(machInst, rd, rn, scale); 2273 case 4: // FCVTZS Xd = convertToIntExactTowardZero(Sn*(2^fbits)) 2274 return new FcvtFpSFixedSX(machInst, rd, rn, scale); 2275 case 5: // FCVTZS Xd = convertToIntExactTowardZero(Dn*(2^fbits)) 2276 return new FcvtFpSFixedDX(machInst, rd, rn, scale); 2277 default: 2278 return new Unknown64(machInst); 2279 } 2280 case 0x19: 2281 switch ( (bits(machInst, 31) << 2) | type ) { 2282 case 0: // FCVTZU Wd = convertToIntExactTowardZero(Sn*(2^fbits)) 2283 return new FcvtFpUFixedSW(machInst, rd, rn, scale); 2284 case 1: // FCVTZU Wd = convertToIntExactTowardZero(Dn*(2^fbits)) 2285 return new FcvtFpUFixedDW(machInst, rd, rn, scale); 2286 case 4: // FCVTZU Xd = convertToIntExactTowardZero(Sn*(2^fbits)) 2287 return new FcvtFpUFixedSX(machInst, rd, rn, scale); 2288 case 5: // FCVTZU Xd = convertToIntExactTowardZero(Dn*(2^fbits)) 2289 return new FcvtFpUFixedDX(machInst, rd, rn, scale); 2290 default: 2291 return new Unknown64(machInst); 2292 } 2293 default: 2294 return new Unknown64(machInst); 2295 } 2296 } else { 2297 // 30=0, 28:24=11110, 21=1 2298 uint8_t type = bits(machInst, 23, 22); 2299 uint8_t imm8 = bits(machInst, 20, 13); 2300 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 2301 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 2302 switch (bits(machInst, 11, 10)) { 2303 case 0x0: 2304 if (bits(machInst, 12) == 1) { 2305 if (bits(machInst, 31) || 2306 bits(machInst, 29) || 2307 bits(machInst, 9, 5)) { 2308 return new Unknown64(machInst); 2309 } 2310 // 31:29=000, 28:24=11110, 21=1, 12:10=100 2311 if (type == 0) { 2312 // FMOV S[d] = imm8<7>:NOT(imm8<6>):Replicate(imm8<6>,5) 2313 // :imm8<5:0>:Zeros(19) 2314 uint32_t imm = vfp_modified_imm(imm8, 2315 FpDataType::Fp32); 2316 return new FmovImmS(machInst, rd, imm); 2317 } else if (type == 1) { 2318 // FMOV D[d] = imm8<7>:NOT(imm8<6>):Replicate(imm8<6>,8) 2319 // :imm8<5:0>:Zeros(48) 2320 uint64_t imm = vfp_modified_imm(imm8, 2321 FpDataType::Fp64); 2322 return new FmovImmD(machInst, rd, imm); 2323 } else { 2324 return new Unknown64(machInst); 2325 } 2326 } else if (bits(machInst, 13) == 1) { 2327 if (bits(machInst, 31) || 2328 bits(machInst, 29) || 2329 bits(machInst, 15, 14) || 2330 bits(machInst, 23) || 2331 bits(machInst, 2, 0)) { 2332 return new Unknown64(machInst); 2333 } 2334 uint8_t switchVal = (bits(machInst, 4, 3) << 0) | 2335 (bits(machInst, 22) << 2); 2336 IntRegIndex rm = (IntRegIndex)(uint32_t) 2337 bits(machInst, 20, 16); 2338 // 28:23=000111100, 21=1, 15:10=001000, 2:0=000 2339 switch (switchVal) { 2340 case 0x0: 2341 // FCMP flags = compareQuiet(Sn,Sm) 2342 return new FCmpRegS(machInst, rn, rm); 2343 case 0x1: 2344 // FCMP flags = compareQuiet(Sn,0.0) 2345 return new FCmpImmS(machInst, rn, 0); 2346 case 0x2: 2347 // FCMPE flags = compareSignaling(Sn,Sm) 2348 return new FCmpERegS(machInst, rn, rm); 2349 case 0x3: 2350 // FCMPE flags = compareSignaling(Sn,0.0) 2351 return new FCmpEImmS(machInst, rn, 0); 2352 case 0x4: 2353 // FCMP flags = compareQuiet(Dn,Dm) 2354 return new FCmpRegD(machInst, rn, rm); 2355 case 0x5: 2356 // FCMP flags = compareQuiet(Dn,0.0) 2357 return new FCmpImmD(machInst, rn, 0); 2358 case 0x6: 2359 // FCMPE flags = compareSignaling(Dn,Dm) 2360 return new FCmpERegD(machInst, rn, rm); 2361 case 0x7: 2362 // FCMPE flags = compareSignaling(Dn,0.0) 2363 return new FCmpEImmD(machInst, rn, 0); 2364 default: 2365 return new Unknown64(machInst); 2366 } 2367 } else if (bits(machInst, 14) == 1) { 2368 if (bits(machInst, 31) || bits(machInst, 29)) 2369 return new Unknown64(machInst); 2370 uint8_t opcode = bits(machInst, 20, 15); 2371 // Bits 31:24=00011110, 21=1, 14:10=10000 2372 switch (opcode) { 2373 case 0x0: 2374 if (type == 0) 2375 // FMOV Sd = Sn 2376 return new FmovRegS(machInst, rd, rn); 2377 else if (type == 1) 2378 // FMOV Dd = Dn 2379 return new FmovRegD(machInst, rd, rn); 2380 break; 2381 case 0x1: 2382 if (type == 0) 2383 // FABS Sd = abs(Sn) 2384 return new FAbsS(machInst, rd, rn); 2385 else if (type == 1) 2386 // FABS Dd = abs(Dn) 2387 return new FAbsD(machInst, rd, rn); 2388 break; 2389 case 0x2: 2390 if (type == 0) 2391 // FNEG Sd = -Sn 2392 return new FNegS(machInst, rd, rn); 2393 else if (type == 1) 2394 // FNEG Dd = -Dn 2395 return new FNegD(machInst, rd, rn); 2396 break; 2397 case 0x3: 2398 if (type == 0) 2399 // FSQRT Sd = sqrt(Sn) 2400 return new FSqrtS(machInst, rd, rn); 2401 else if (type == 1) 2402 // FSQRT Dd = sqrt(Dn) 2403 return new FSqrtD(machInst, rd, rn); 2404 break; 2405 case 0x4: 2406 if (type == 1) 2407 // FCVT Sd = convertFormat(Dn) 2408 return new FcvtFpDFpS(machInst, rd, rn); 2409 else if (type == 3) 2410 // FCVT Sd = convertFormat(Hn) 2411 return new FcvtFpHFpS(machInst, rd, rn); 2412 break; 2413 case 0x5: 2414 if (type == 0) 2415 // FCVT Dd = convertFormat(Sn) 2416 return new FCvtFpSFpD(machInst, rd, rn); 2417 else if (type == 3) 2418 // FCVT Dd = convertFormat(Hn) 2419 return new FcvtFpHFpD(machInst, rd, rn); 2420 break; 2421 case 0x7: 2422 if (type == 0) 2423 // FCVT Hd = convertFormat(Sn) 2424 return new FcvtFpSFpH(machInst, rd, rn); 2425 else if (type == 1) 2426 // FCVT Hd = convertFormat(Dn) 2427 return new FcvtFpDFpH(machInst, rd, rn); 2428 break; 2429 case 0x8: 2430 if (type == 0) // FRINTN Sd = roundToIntegralTiesToEven(Sn) 2431 return new FRIntNS(machInst, rd, rn); 2432 else if (type == 1) // FRINTN Dd = roundToIntegralTiesToEven(Dn) 2433 return new FRIntND(machInst, rd, rn); 2434 break; 2435 case 0x9: 2436 if (type == 0) // FRINTP Sd = roundToIntegralTowardPlusInf(Sn) 2437 return new FRIntPS(machInst, rd, rn); 2438 else if (type == 1) // FRINTP Dd = roundToIntegralTowardPlusInf(Dn) 2439 return new FRIntPD(machInst, rd, rn); 2440 break; 2441 case 0xa: 2442 if (type == 0) // FRINTM Sd = roundToIntegralTowardMinusInf(Sn) 2443 return new FRIntMS(machInst, rd, rn); 2444 else if (type == 1) // FRINTM Dd = roundToIntegralTowardMinusInf(Dn) 2445 return new FRIntMD(machInst, rd, rn); 2446 break; 2447 case 0xb: 2448 if (type == 0) // FRINTZ Sd = roundToIntegralTowardZero(Sn) 2449 return new FRIntZS(machInst, rd, rn); 2450 else if (type == 1) // FRINTZ Dd = roundToIntegralTowardZero(Dn) 2451 return new FRIntZD(machInst, rd, rn); 2452 break; 2453 case 0xc: 2454 if (type == 0) // FRINTA Sd = roundToIntegralTiesToAway(Sn) 2455 return new FRIntAS(machInst, rd, rn); 2456 else if (type == 1) // FRINTA Dd = roundToIntegralTiesToAway(Dn) 2457 return new FRIntAD(machInst, rd, rn); 2458 break; 2459 case 0xe: 2460 if (type == 0) // FRINTX Sd = roundToIntegralExact(Sn) 2461 return new FRIntXS(machInst, rd, rn); 2462 else if (type == 1) // FRINTX Dd = roundToIntegralExact(Dn) 2463 return new FRIntXD(machInst, rd, rn); 2464 break; 2465 case 0xf: 2466 if (type == 0) // FRINTI Sd = roundToIntegral(Sn) 2467 return new FRIntIS(machInst, rd, rn); 2468 else if (type == 1) // FRINTI Dd = roundToIntegral(Dn) 2469 return new FRIntID(machInst, rd, rn); 2470 break; 2471 default: 2472 return new Unknown64(machInst); 2473 } 2474 return new Unknown64(machInst); 2475 } else if (bits(machInst, 15) == 1) { 2476 return new Unknown64(machInst); 2477 } else { 2478 if (bits(machInst, 29)) 2479 return new Unknown64(machInst); 2480 uint8_t rmode = bits(machInst, 20, 19); 2481 uint8_t switchVal1 = bits(machInst, 18, 16); 2482 uint8_t switchVal2 = (type << 1) | bits(machInst, 31); 2483 // 30:24=0011110, 21=1, 15:10=000000 2484 switch (switchVal1) { 2485 case 0x0: 2486 switch ((switchVal2 << 2) | rmode) { 2487 case 0x0: //FCVTNS Wd = convertToIntExactTiesToEven(Sn) 2488 return new FcvtFpSIntWSN(machInst, rd, rn); 2489 case 0x1: //FCVTPS Wd = convertToIntExactTowardPlusInf(Sn) 2490 return new FcvtFpSIntWSP(machInst, rd, rn); 2491 case 0x2: //FCVTMS Wd = convertToIntExactTowardMinusInf(Sn) 2492 return new FcvtFpSIntWSM(machInst, rd, rn); 2493 case 0x3: //FCVTZS Wd = convertToIntExactTowardZero(Sn) 2494 return new FcvtFpSIntWSZ(machInst, rd, rn); 2495 case 0x4: //FCVTNS Xd = convertToIntExactTiesToEven(Sn) 2496 return new FcvtFpSIntXSN(machInst, rd, rn); 2497 case 0x5: //FCVTPS Xd = convertToIntExactTowardPlusInf(Sn) 2498 return new FcvtFpSIntXSP(machInst, rd, rn); 2499 case 0x6: //FCVTMS Xd = convertToIntExactTowardMinusInf(Sn) 2500 return new FcvtFpSIntXSM(machInst, rd, rn); 2501 case 0x7: //FCVTZS Xd = convertToIntExactTowardZero(Sn) 2502 return new FcvtFpSIntXSZ(machInst, rd, rn); 2503 case 0x8: //FCVTNS Wd = convertToIntExactTiesToEven(Dn) 2504 return new FcvtFpSIntWDN(machInst, rd, rn); 2505 case 0x9: //FCVTPS Wd = convertToIntExactTowardPlusInf(Dn) 2506 return new FcvtFpSIntWDP(machInst, rd, rn); 2507 case 0xA: //FCVTMS Wd = convertToIntExactTowardMinusInf(Dn) 2508 return new FcvtFpSIntWDM(machInst, rd, rn); 2509 case 0xB: //FCVTZS Wd = convertToIntExactTowardZero(Dn) 2510 return new FcvtFpSIntWDZ(machInst, rd, rn); 2511 case 0xC: //FCVTNS Xd = convertToIntExactTiesToEven(Dn) 2512 return new FcvtFpSIntXDN(machInst, rd, rn); 2513 case 0xD: //FCVTPS Xd = convertToIntExactTowardPlusInf(Dn) 2514 return new FcvtFpSIntXDP(machInst, rd, rn); 2515 case 0xE: //FCVTMS Xd = convertToIntExactTowardMinusInf(Dn) 2516 return new FcvtFpSIntXDM(machInst, rd, rn); 2517 case 0xF: //FCVTZS Xd = convertToIntExactTowardZero(Dn) 2518 return new FcvtFpSIntXDZ(machInst, rd, rn); 2519 default: 2520 return new Unknown64(machInst); 2521 } 2522 case 0x1: 2523 switch ((switchVal2 << 2) | rmode) { 2524 case 0x0: //FCVTNU Wd = convertToIntExactTiesToEven(Sn) 2525 return new FcvtFpUIntWSN(machInst, rd, rn); 2526 case 0x1: //FCVTPU Wd = convertToIntExactTowardPlusInf(Sn) 2527 return new FcvtFpUIntWSP(machInst, rd, rn); 2528 case 0x2: //FCVTMU Wd = convertToIntExactTowardMinusInf(Sn) 2529 return new FcvtFpUIntWSM(machInst, rd, rn); 2530 case 0x3: //FCVTZU Wd = convertToIntExactTowardZero(Sn) 2531 return new FcvtFpUIntWSZ(machInst, rd, rn); 2532 case 0x4: //FCVTNU Xd = convertToIntExactTiesToEven(Sn) 2533 return new FcvtFpUIntXSN(machInst, rd, rn); 2534 case 0x5: //FCVTPU Xd = convertToIntExactTowardPlusInf(Sn) 2535 return new FcvtFpUIntXSP(machInst, rd, rn); 2536 case 0x6: //FCVTMU Xd = convertToIntExactTowardMinusInf(Sn) 2537 return new FcvtFpUIntXSM(machInst, rd, rn); 2538 case 0x7: //FCVTZU Xd = convertToIntExactTowardZero(Sn) 2539 return new FcvtFpUIntXSZ(machInst, rd, rn); 2540 case 0x8: //FCVTNU Wd = convertToIntExactTiesToEven(Dn) 2541 return new FcvtFpUIntWDN(machInst, rd, rn); 2542 case 0x9: //FCVTPU Wd = convertToIntExactTowardPlusInf(Dn) 2543 return new FcvtFpUIntWDP(machInst, rd, rn); 2544 case 0xA: //FCVTMU Wd = convertToIntExactTowardMinusInf(Dn) 2545 return new FcvtFpUIntWDM(machInst, rd, rn); 2546 case 0xB: //FCVTZU Wd = convertToIntExactTowardZero(Dn) 2547 return new FcvtFpUIntWDZ(machInst, rd, rn); 2548 case 0xC: //FCVTNU Xd = convertToIntExactTiesToEven(Dn) 2549 return new FcvtFpUIntXDN(machInst, rd, rn); 2550 case 0xD: //FCVTPU Xd = convertToIntExactTowardPlusInf(Dn) 2551 return new FcvtFpUIntXDP(machInst, rd, rn); 2552 case 0xE: //FCVTMU Xd = convertToIntExactTowardMinusInf(Dn) 2553 return new FcvtFpUIntXDM(machInst, rd, rn); 2554 case 0xF: //FCVTZU Xd = convertToIntExactTowardZero(Dn) 2555 return new FcvtFpUIntXDZ(machInst, rd, rn); 2556 default: 2557 return new Unknown64(machInst); 2558 } 2559 case 0x2: 2560 if (rmode != 0) 2561 return new Unknown64(machInst); 2562 switch (switchVal2) { 2563 case 0: // SCVTF Sd = convertFromInt(Wn) 2564 return new FcvtWSIntFpS(machInst, rd, rn); 2565 case 1: // SCVTF Sd = convertFromInt(Xn) 2566 return new FcvtXSIntFpS(machInst, rd, rn); 2567 case 2: // SCVTF Dd = convertFromInt(Wn) 2568 return new FcvtWSIntFpD(machInst, rd, rn); 2569 case 3: // SCVTF Dd = convertFromInt(Xn) 2570 return new FcvtXSIntFpD(machInst, rd, rn); 2571 default: 2572 return new Unknown64(machInst); 2573 } 2574 case 0x3: 2575 switch (switchVal2) { 2576 case 0: // UCVTF Sd = convertFromInt(Wn) 2577 return new FcvtWUIntFpS(machInst, rd, rn); 2578 case 1: // UCVTF Sd = convertFromInt(Xn) 2579 return new FcvtXUIntFpS(machInst, rd, rn); 2580 case 2: // UCVTF Dd = convertFromInt(Wn) 2581 return new FcvtWUIntFpD(machInst, rd, rn); 2582 case 3: // UCVTF Dd = convertFromInt(Xn) 2583 return new FcvtXUIntFpD(machInst, rd, rn); 2584 default: 2585 return new Unknown64(machInst); 2586 } 2587 case 0x4: 2588 if (rmode != 0) 2589 return new Unknown64(machInst); 2590 switch (switchVal2) { 2591 case 0: // FCVTAS Wd = convertToIntExactTiesToAway(Sn) 2592 return new FcvtFpSIntWSA(machInst, rd, rn); 2593 case 1: // FCVTAS Xd = convertToIntExactTiesToAway(Sn) 2594 return new FcvtFpSIntXSA(machInst, rd, rn); 2595 case 2: // FCVTAS Wd = convertToIntExactTiesToAway(Dn) 2596 return new FcvtFpSIntWDA(machInst, rd, rn); 2597 case 3: // FCVTAS Wd = convertToIntExactTiesToAway(Dn) 2598 return new FcvtFpSIntXDA(machInst, rd, rn); 2599 default: 2600 return new Unknown64(machInst); 2601 } 2602 case 0x5: 2603 switch (switchVal2) { 2604 case 0: // FCVTAU Wd = convertToIntExactTiesToAway(Sn) 2605 return new FcvtFpUIntWSA(machInst, rd, rn); 2606 case 1: // FCVTAU Xd = convertToIntExactTiesToAway(Sn) 2607 return new FcvtFpUIntXSA(machInst, rd, rn); 2608 case 2: // FCVTAU Wd = convertToIntExactTiesToAway(Dn) 2609 return new FcvtFpUIntWDA(machInst, rd, rn); 2610 case 3: // FCVTAU Xd = convertToIntExactTiesToAway(Dn) 2611 return new FcvtFpUIntXDA(machInst, rd, rn); 2612 default: 2613 return new Unknown64(machInst); 2614 } 2615 case 0x06: 2616 switch (switchVal2) { 2617 case 0: // FMOV Wd = Sn 2618 if (rmode != 0) 2619 return new Unknown64(machInst); 2620 return new FmovRegCoreW(machInst, rd, rn); 2621 case 3: // FMOV Xd = Dn 2622 if (rmode != 0) 2623 return new Unknown64(machInst); 2624 return new FmovRegCoreX(machInst, rd, rn); 2625 case 5: // FMOV Xd = Vn<127:64> 2626 if (rmode != 1) 2627 return new Unknown64(machInst); 2628 return new FmovURegCoreX(machInst, rd, rn); 2629 default: 2630 return new Unknown64(machInst); 2631 } 2632 break; 2633 case 0x07: 2634 switch (switchVal2) { 2635 case 0: // FMOV Sd = Wn 2636 if (rmode != 0) 2637 return new Unknown64(machInst); 2638 return new FmovCoreRegW(machInst, rd, rn); 2639 case 3: // FMOV Xd = Dn 2640 if (rmode != 0) 2641 return new Unknown64(machInst); 2642 return new FmovCoreRegX(machInst, rd, rn); 2643 case 5: // FMOV Xd = Vn<127:64> 2644 if (rmode != 1) 2645 return new Unknown64(machInst); 2646 return new FmovUCoreRegX(machInst, rd, rn); 2647 default: 2648 return new Unknown64(machInst); 2649 } 2650 break; 2651 default: // Warning! missing cases in switch statement above, that still need to be added 2652 return new Unknown64(machInst); 2653 } 2654 } 2655 M5_UNREACHABLE; 2656 case 0x1: 2657 { 2658 if (bits(machInst, 31) || 2659 bits(machInst, 29) || 2660 bits(machInst, 23)) { 2661 return new Unknown64(machInst); 2662 } 2663 IntRegIndex rm = (IntRegIndex)(uint32_t) bits(machInst, 20, 16); 2664 IntRegIndex rn = (IntRegIndex)(uint32_t) bits(machInst, 9, 5); 2665 uint8_t imm = (IntRegIndex)(uint32_t) bits(machInst, 3, 0); 2666 ConditionCode cond = 2667 (ConditionCode)(uint8_t)(bits(machInst, 15, 12)); 2668 uint8_t switchVal = (bits(machInst, 4) << 0) | 2669 (bits(machInst, 22) << 1); 2670 // 31:23=000111100, 21=1, 11:10=01 2671 switch (switchVal) { 2672 case 0x0: 2673 // FCCMP flags = if cond the compareQuiet(Sn,Sm) else #nzcv 2674 return new FCCmpRegS(machInst, rn, rm, cond, imm); 2675 case 0x1: 2676 // FCCMP flags = if cond then compareSignaling(Sn,Sm) 2677 // else #nzcv 2678 return new FCCmpERegS(machInst, rn, rm, cond, imm); 2679 case 0x2: 2680 // FCCMP flags = if cond then compareQuiet(Dn,Dm) else #nzcv 2681 return new FCCmpRegD(machInst, rn, rm, cond, imm); 2682 case 0x3: 2683 // FCCMP flags = if cond then compareSignaling(Dn,Dm) 2684 // else #nzcv 2685 return new FCCmpERegD(machInst, rn, rm, cond, imm); 2686 default: 2687 return new Unknown64(machInst); 2688 } 2689 } 2690 case 0x2: 2691 { 2692 if (bits(machInst, 31) || 2693 bits(machInst, 29) || 2694 bits(machInst, 23)) { 2695 return new Unknown64(machInst); 2696 } 2697 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 2698 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 2699 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 20, 16); 2700 uint8_t switchVal = (bits(machInst, 15, 12) << 0) | 2701 (bits(machInst, 22) << 4); 2702 switch (switchVal) { 2703 case 0x00: // FMUL Sd = Sn * Sm 2704 return new FMulS(machInst, rd, rn, rm); 2705 case 0x10: // FMUL Dd = Dn * Dm 2706 return new FMulD(machInst, rd, rn, rm); 2707 case 0x01: // FDIV Sd = Sn / Sm 2708 return new FDivS(machInst, rd, rn, rm); 2709 case 0x11: // FDIV Dd = Dn / Dm 2710 return new FDivD(machInst, rd, rn, rm); 2711 case 0x02: // FADD Sd = Sn + Sm 2712 return new FAddS(machInst, rd, rn, rm); 2713 case 0x12: // FADD Dd = Dn + Dm 2714 return new FAddD(machInst, rd, rn, rm); 2715 case 0x03: // FSUB Sd = Sn - Sm 2716 return new FSubS(machInst, rd, rn, rm); 2717 case 0x13: // FSUB Dd = Dn - Dm 2718 return new FSubD(machInst, rd, rn, rm); 2719 case 0x04: // FMAX Sd = max(Sn, Sm) 2720 return new FMaxS(machInst, rd, rn, rm); 2721 case 0x14: // FMAX Dd = max(Dn, Dm) 2722 return new FMaxD(machInst, rd, rn, rm); 2723 case 0x05: // FMIN Sd = min(Sn, Sm) 2724 return new FMinS(machInst, rd, rn, rm); 2725 case 0x15: // FMIN Dd = min(Dn, Dm) 2726 return new FMinD(machInst, rd, rn, rm); 2727 case 0x06: // FMAXNM Sd = maxNum(Sn, Sm) 2728 return new FMaxNMS(machInst, rd, rn, rm); 2729 case 0x16: // FMAXNM Dd = maxNum(Dn, Dm) 2730 return new FMaxNMD(machInst, rd, rn, rm); 2731 case 0x07: // FMINNM Sd = minNum(Sn, Sm) 2732 return new FMinNMS(machInst, rd, rn, rm); 2733 case 0x17: // FMINNM Dd = minNum(Dn, Dm) 2734 return new FMinNMD(machInst, rd, rn, rm); 2735 case 0x08: // FNMUL Sd = -(Sn * Sm) 2736 return new FNMulS(machInst, rd, rn, rm); 2737 case 0x18: // FNMUL Dd = -(Dn * Dm) 2738 return new FNMulD(machInst, rd, rn, rm); 2739 default: 2740 return new Unknown64(machInst); 2741 } 2742 } 2743 case 0x3: 2744 { 2745 if (bits(machInst, 31) || bits(machInst, 29)) 2746 return new Unknown64(machInst); 2747 uint8_t type = bits(machInst, 23, 22); 2748 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 2749 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 2750 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 20, 16); 2751 ConditionCode cond = 2752 (ConditionCode)(uint8_t)(bits(machInst, 15, 12)); 2753 if (type == 0) // FCSEL Sd = if cond then Sn else Sm 2754 return new FCSelS(machInst, rd, rn, rm, cond); 2755 else if (type == 1) // FCSEL Dd = if cond then Dn else Dm 2756 return new FCSelD(machInst, rd, rn, rm, cond); 2757 else 2758 return new Unknown64(machInst); 2759 } 2760 default: 2761 M5_UNREACHABLE; 2762 } 2763 } 2764 M5_UNREACHABLE; 2765 } 2766} 2767}}; 2768 2769output decoder {{ 2770namespace Aarch64 2771{ 2772 StaticInstPtr 2773 decodeAdvSIMDScalar(ExtMachInst machInst) 2774 { 2775 if (bits(machInst, 24) == 1) { 2776 if (bits(machInst, 10) == 0) { 2777 return decodeNeonScIndexedElem(machInst); 2778 } else if (bits(machInst, 23) == 0) { 2779 return decodeNeonScShiftByImm(machInst); 2780 } 2781 } else if (bits(machInst, 21) == 1) { 2782 if (bits(machInst, 10) == 1) { 2783 return decodeNeonSc3Same(machInst); 2784 } else if (bits(machInst, 11) == 0) { 2785 return decodeNeonSc3Diff(machInst); 2786 } else if (bits(machInst, 20, 17) == 0x0) { 2787 return decodeNeonSc2RegMisc(machInst); 2788 } else if (bits(machInst, 20, 17) == 0x4) { 2789 return decodeCryptoTwoRegSHA(machInst); 2790 } else if (bits(machInst, 20, 17) == 0x8) { 2791 return decodeNeonScPwise(machInst); 2792 } else { 2793 return new Unknown64(machInst); 2794 } 2795 } else if (bits(machInst, 23, 22) == 0 && 2796 bits(machInst, 15) == 0) { 2797 if (bits(machInst, 10) == 1) { 2798 return decodeNeonScCopy(machInst); 2799 } else { 2800 return decodeCryptoThreeRegSHA(machInst); 2801 } 2802 } else { 2803 return new Unknown64(machInst); 2804 } 2805 return new FailUnimplemented("Unhandled Case6", machInst); 2806 } 2807} 2808}}; 2809 2810output decoder {{ 2811namespace Aarch64 2812{ 2813 template <typename DecoderFeatures> 2814 StaticInstPtr 2815 decodeFpAdvSIMD(ExtMachInst machInst) 2816 { 2817 2818 if (bits(machInst, 28) == 0) { 2819 if (bits(machInst, 31) == 0) { 2820 return decodeAdvSIMD<DecoderFeatures>(machInst); 2821 } else { 2822 return new Unknown64(machInst); 2823 } 2824 } else if (bits(machInst, 30) == 0) { 2825 return decodeFp(machInst); 2826 } else if (bits(machInst, 31) == 0) { 2827 return decodeAdvSIMDScalar(machInst); 2828 } else { 2829 return new Unknown64(machInst); 2830 } 2831 } 2832} 2833}}; 2834 2835let {{ 2836 decoder_output =''' 2837namespace Aarch64 2838{''' 2839 for decoderFlavour, type_dict in decoders.iteritems(): 2840 decoder_output +=''' 2841template StaticInstPtr decodeFpAdvSIMD<%(df)sDecoder>(ExtMachInst machInst); 2842''' % { "df" : decoderFlavour } 2843 decoder_output +=''' 2844}''' 2845}}; 2846 2847output decoder {{ 2848namespace Aarch64 2849{ 2850 StaticInstPtr 2851 decodeGem5Ops(ExtMachInst machInst) 2852 { 2853 const uint32_t m5func = bits(machInst, 23, 16); 2854 switch (m5func) { 2855 case M5OP_ARM: return new Arm(machInst); 2856 case M5OP_QUIESCE: return new Quiesce(machInst); 2857 case M5OP_QUIESCE_NS: return new QuiesceNs64(machInst); 2858 case M5OP_QUIESCE_CYCLE: return new QuiesceCycles64(machInst); 2859 case M5OP_QUIESCE_TIME: return new QuiesceTime64(machInst); 2860 case M5OP_RPNS: return new Rpns64(machInst); 2861 case M5OP_WAKE_CPU: return new WakeCPU64(machInst); 2862 case M5OP_DEPRECATED1: return new Deprecated_ivlb(machInst); 2863 case M5OP_DEPRECATED2: return new Deprecated_ivle(machInst); 2864 case M5OP_DEPRECATED3: return new Deprecated_exit (machInst); 2865 case M5OP_EXIT: return new M5exit64(machInst); 2866 case M5OP_FAIL: return new M5fail64(machInst); 2867 case M5OP_LOAD_SYMBOL: return new Loadsymbol(machInst); 2868 case M5OP_INIT_PARAM: return new Initparam64(machInst); 2869 case M5OP_RESET_STATS: return new Resetstats64(machInst); 2870 case M5OP_DUMP_STATS: return new Dumpstats64(machInst); 2871 case M5OP_DUMP_RESET_STATS: return new Dumpresetstats64(machInst); 2872 case M5OP_CHECKPOINT: return new M5checkpoint64(machInst); 2873 case M5OP_WRITE_FILE: return new M5writefile64(machInst); 2874 case M5OP_READ_FILE: return new M5readfile64(machInst); 2875 case M5OP_DEBUG_BREAK: return new M5break(machInst); 2876 case M5OP_SWITCH_CPU: return new M5switchcpu(machInst); 2877 case M5OP_ADD_SYMBOL: return new M5addsymbol64(machInst); 2878 case M5OP_PANIC: return new M5panic(machInst); 2879 case M5OP_WORK_BEGIN: return new M5workbegin64(machInst); 2880 case M5OP_WORK_END: return new M5workend64(machInst); 2881 default: return new Unknown64(machInst); 2882 } 2883 } 2884} 2885}}; 2886 2887def format Aarch64() {{ 2888 decode_block = ''' 2889 { 2890 using namespace Aarch64; 2891 if (bits(machInst, 27) == 0x0) { 2892 if (bits(machInst, 28) == 0x0) { 2893 if (bits(machInst, 26, 25) != 0x2) { 2894 return new Unknown64(machInst); 2895 } 2896 if (bits(machInst, 31) == 0x0) { 2897 switch (bits(machInst, 30, 29)) { 2898 case 0x0: 2899 case 0x1: 2900 case 0x2: 2901 return decodeSveInt(machInst); 2902 case 0x3: 2903 return decodeSveFp(machInst); 2904 } 2905 } else { 2906 return decodeSveMem(machInst); 2907 } 2908 } else if (bits(machInst, 26) == 0) 2909 // bit 28:26=100 2910 return decodeDataProcImm(machInst); 2911 else 2912 // bit 28:26=101 2913 return decodeBranchExcSys(machInst); 2914 } else if (bits(machInst, 25) == 0) { 2915 // bit 27=1, 25=0 2916 return decodeLoadsStores(machInst); 2917 } else if (bits(machInst, 26) == 0) { 2918 // bit 27:25=101 2919 return decodeDataProcReg(machInst); 2920 } else if (bits(machInst, 24) == 1 && 2921 bits(machInst, 31, 28) == 0xF) { 2922 return decodeGem5Ops(machInst); 2923 } else { 2924 // bit 27:25=111 2925 switch(decoderFlavour){ 2926 default: 2927 return decodeFpAdvSIMD<GenericDecoder>(machInst); 2928 } 2929 } 2930 } 2931 ''' 2932}};
|