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