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