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