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