1697 lines · cpp
1//===- AArch64Disassembler.cpp - Disassembler for AArch64 -----------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9//10//===----------------------------------------------------------------------===//11 12#include "AArch64Disassembler.h"13#include "AArch64ExternalSymbolizer.h"14#include "MCTargetDesc/AArch64AddressingModes.h"15#include "MCTargetDesc/AArch64MCTargetDesc.h"16#include "TargetInfo/AArch64TargetInfo.h"17#include "Utils/AArch64BaseInfo.h"18#include "llvm/MC/MCDecoder.h"19#include "llvm/MC/MCDecoderOps.h"20#include "llvm/MC/MCDisassembler/MCRelocationInfo.h"21#include "llvm/MC/MCInst.h"22#include "llvm/MC/MCInstrDesc.h"23#include "llvm/MC/MCRegisterInfo.h"24#include "llvm/MC/MCSubtargetInfo.h"25#include "llvm/MC/TargetRegistry.h"26#include "llvm/Support/Compiler.h"27#include "llvm/Support/Debug.h"28#include <memory>29 30using namespace llvm;31using namespace llvm::MCD;32 33#define DEBUG_TYPE "aarch64-disassembler"34 35// Pull DecodeStatus and its enum values into the global namespace.36using DecodeStatus = MCDisassembler::DecodeStatus;37 38template <int Bits>39static DecodeStatus DecodeSImm(MCInst &Inst, uint64_t Imm, uint64_t Address,40 const MCDisassembler *Decoder);41 42#define Success MCDisassembler::Success43#define Fail MCDisassembler::Fail44#define SoftFail MCDisassembler::SoftFail45 46template <unsigned RegClassID, unsigned FirstReg, unsigned NumRegsInClass>47static DecodeStatus DecodeSimpleRegisterClass(MCInst &Inst, unsigned RegNo,48 uint64_t Address,49 const MCDisassembler *Decoder) {50 if (RegNo > NumRegsInClass - 1)51 return Fail;52 53 MCRegister Register =54 AArch64MCRegisterClasses[RegClassID].getRegister(RegNo + FirstReg);55 Inst.addOperand(MCOperand::createReg(Register));56 return Success;57}58 59static DecodeStatus60DecodeGPR64x8ClassRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,61 const MCDisassembler *Decoder) {62 if (RegNo > 22)63 return Fail;64 if (RegNo & 1)65 return Fail;66 67 MCRegister Register =68 AArch64MCRegisterClasses[AArch64::GPR64x8ClassRegClassID].getRegister(69 RegNo >> 1);70 Inst.addOperand(MCOperand::createReg(Register));71 return Success;72}73 74template <unsigned Min, unsigned Max>75static DecodeStatus DecodeZPRMul2_MinMax(MCInst &Inst, unsigned RegNo,76 uint64_t Address,77 const MCDisassembler *Decoder) {78 unsigned Reg = (RegNo * 2) + Min;79 if (Reg < Min || Reg > Max || (Reg & 1))80 return Fail;81 MCRegister Register =82 AArch64MCRegisterClasses[AArch64::ZPRRegClassID].getRegister(Reg);83 Inst.addOperand(MCOperand::createReg(Register));84 return Success;85}86 87template <unsigned Min, unsigned Max>88static DecodeStatus DecodeZPR2Mul2RegisterClass(MCInst &Inst, unsigned RegNo,89 uint64_t Address,90 const void *Decoder) {91 unsigned Reg = (RegNo * 2) + Min;92 if (Reg < Min || Reg > Max || (Reg & 1))93 return Fail;94 95 MCRegister Register =96 AArch64MCRegisterClasses[AArch64::ZPR2RegClassID].getRegister(Reg);97 Inst.addOperand(MCOperand::createReg(Register));98 return Success;99}100 101static DecodeStatus DecodeZK(MCInst &Inst, unsigned RegNo, uint64_t Address,102 const MCDisassembler *Decoder) {103 if (RegNo > 7)104 return Fail;105 106 MCRegister Register =107 AArch64MCRegisterClasses[AArch64::ZPR_KRegClassID].getRegister(RegNo);108 Inst.addOperand(MCOperand::createReg(Register));109 return Success;110}111 112static DecodeStatus DecodeZPR4Mul4RegisterClass(MCInst &Inst, unsigned RegNo,113 uint64_t Address,114 const void *Decoder) {115 if (RegNo * 4 > 28)116 return Fail;117 MCRegister Register =118 AArch64MCRegisterClasses[AArch64::ZPR4RegClassID].getRegister(RegNo * 4);119 Inst.addOperand(MCOperand::createReg(Register));120 return Success;121}122 123static DecodeStatus124DecodeMatrixTileListRegisterClass(MCInst &Inst, unsigned RegMask,125 uint64_t Address,126 const MCDisassembler *Decoder) {127 if (RegMask > 0xFF)128 return Fail;129 Inst.addOperand(MCOperand::createImm(RegMask));130 return Success;131}132 133static DecodeStatus DecodeZTRRegisterClass(MCInst &Inst,134 const MCDisassembler *Decoder) {135 Inst.addOperand(MCOperand::createReg(AArch64::ZT0));136 return Success;137}138 139static DecodeStatus DecodeMPRRegisterClass(MCInst &Inst,140 const MCDisassembler *Decoder) {141 Inst.addOperand(MCOperand::createReg(AArch64::ZA));142 return Success;143}144 145static DecodeStatus DecodeMPR8RegisterClass(MCInst &Inst,146 const MCDisassembler *Decoder) {147 Inst.addOperand(MCOperand::createReg(AArch64::ZAB0));148 return Success;149}150 151static DecodeStatus DecodeMPR16RegisterClass(MCInst &Inst, unsigned RegNo,152 uint64_t Address,153 const MCDisassembler *Decoder) {154 MCRegister Reg =155 AArch64MCRegisterClasses[AArch64::MPR16RegClassID].getRegister(RegNo);156 Inst.addOperand(MCOperand::createReg(Reg));157 return Success;158}159 160static DecodeStatus DecodeMPR32RegisterClass(MCInst &Inst, unsigned RegNo,161 uint64_t Address,162 const MCDisassembler *Decoder) {163 MCRegister Reg =164 AArch64MCRegisterClasses[AArch64::MPR32RegClassID].getRegister(RegNo);165 Inst.addOperand(MCOperand::createReg(Reg));166 return Success;167}168 169static DecodeStatus DecodeMPR64RegisterClass(MCInst &Inst, unsigned RegNo,170 uint64_t Address,171 const MCDisassembler *Decoder) {172 MCRegister Reg =173 AArch64MCRegisterClasses[AArch64::MPR64RegClassID].getRegister(RegNo);174 Inst.addOperand(MCOperand::createReg(Reg));175 return Success;176}177 178static DecodeStatus DecodeMPR128RegisterClass(MCInst &Inst, unsigned RegNo,179 uint64_t Address,180 const MCDisassembler *Decoder) {181 MCRegister Reg =182 AArch64MCRegisterClasses[AArch64::MPR128RegClassID].getRegister(RegNo);183 Inst.addOperand(MCOperand::createReg(Reg));184 return Success;185}186 187static DecodeStatus DecodePPR2Mul2RegisterClass(MCInst &Inst, unsigned RegNo,188 uint64_t Address,189 const void *Decoder) {190 if ((RegNo * 2) > 14)191 return Fail;192 MCRegister Register =193 AArch64MCRegisterClasses[AArch64::PPR2RegClassID].getRegister(RegNo * 2);194 Inst.addOperand(MCOperand::createReg(Register));195 return Success;196}197 198static DecodeStatus DecodeFixedPointScaleImm32(MCInst &Inst, unsigned Imm,199 uint64_t Addr,200 const MCDisassembler *Decoder) {201 // scale{5} is asserted as 1 in tblgen.202 Imm |= 0x20;203 Inst.addOperand(MCOperand::createImm(64 - Imm));204 return Success;205}206 207static DecodeStatus DecodeFixedPointScaleImm64(MCInst &Inst, unsigned Imm,208 uint64_t Addr,209 const MCDisassembler *Decoder) {210 Inst.addOperand(MCOperand::createImm(64 - Imm));211 return Success;212}213 214static DecodeStatus DecodePCRelLabel16(MCInst &Inst, unsigned Imm,215 uint64_t Addr,216 const MCDisassembler *Decoder) {217 // Immediate is encoded as the top 16-bits of an unsigned 18-bit negative218 // PC-relative offset.219 uint64_t ImmVal = Imm;220 if (ImmVal > (1 << 16))221 return Fail;222 ImmVal = -ImmVal;223 if (!Decoder->tryAddingSymbolicOperand(Inst, (ImmVal << 2), Addr,224 /*IsBranch=*/false, 0, 0, 4))225 Inst.addOperand(MCOperand::createImm(ImmVal));226 return Success;227}228 229static DecodeStatus DecodePCRelLabel19(MCInst &Inst, unsigned Imm,230 uint64_t Addr,231 const MCDisassembler *Decoder) {232 int64_t ImmVal = SignExtend64<19>(Imm);233 234 if (!Decoder->tryAddingSymbolicOperand(235 Inst, ImmVal * 4, Addr, Inst.getOpcode() != AArch64::LDRXl, 0, 0, 4))236 Inst.addOperand(MCOperand::createImm(ImmVal));237 return Success;238}239 240static DecodeStatus DecodePCRelLabel9(MCInst &Inst, unsigned Imm, uint64_t Addr,241 const MCDisassembler *Decoder) {242 int64_t ImmVal = SignExtend64<9>(Imm);243 244 if (!Decoder->tryAddingSymbolicOperand(Inst, (ImmVal * 4), Addr,245 /*IsBranch=*/true, 0, 0, 4))246 Inst.addOperand(MCOperand::createImm(ImmVal));247 return Success;248}249 250static DecodeStatus DecodeMemExtend(MCInst &Inst, unsigned Imm,251 uint64_t Address,252 const MCDisassembler *Decoder) {253 Inst.addOperand(MCOperand::createImm((Imm >> 1) & 1));254 Inst.addOperand(MCOperand::createImm(Imm & 1));255 return Success;256}257 258static DecodeStatus DecodeMRSSystemRegister(MCInst &Inst, unsigned Imm,259 uint64_t Address,260 const MCDisassembler *Decoder) {261 Inst.addOperand(MCOperand::createImm(Imm));262 263 // Every system register in the encoding space is valid with the syntax264 // S<op0>_<op1>_<Cn>_<Cm>_<op2>, so decoding system registers always succeeds.265 return Success;266}267 268static DecodeStatus DecodeMSRSystemRegister(MCInst &Inst, unsigned Imm,269 uint64_t Address,270 const MCDisassembler *Decoder) {271 Inst.addOperand(MCOperand::createImm(Imm));272 273 return Success;274}275 276static DecodeStatus DecodeFMOVLaneInstruction(MCInst &Inst, unsigned Insn,277 uint64_t Address,278 const MCDisassembler *Decoder) {279 // This decoder exists to add the dummy Lane operand to the MCInst, which must280 // be 1 in assembly but has no other real manifestation.281 unsigned Rd = fieldFromInstruction(Insn, 0, 5);282 unsigned Rn = fieldFromInstruction(Insn, 5, 5);283 unsigned IsToVec = fieldFromInstruction(Insn, 16, 1);284 285 if (IsToVec) {286 DecodeSimpleRegisterClass<AArch64::FPR128RegClassID, 0, 32>(287 Inst, Rd, Address, Decoder);288 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(289 Inst, Rn, Address, Decoder);290 } else {291 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(292 Inst, Rd, Address, Decoder);293 DecodeSimpleRegisterClass<AArch64::FPR128RegClassID, 0, 32>(294 Inst, Rn, Address, Decoder);295 }296 297 // Add the lane298 Inst.addOperand(MCOperand::createImm(1));299 300 return Success;301}302 303static DecodeStatus DecodeVecShiftRImm(MCInst &Inst, unsigned Imm,304 unsigned Add) {305 Inst.addOperand(MCOperand::createImm(Add - Imm));306 return Success;307}308 309static DecodeStatus DecodeVecShiftLImm(MCInst &Inst, unsigned Imm,310 unsigned Add) {311 Inst.addOperand(MCOperand::createImm((Imm + Add) & (Add - 1)));312 return Success;313}314 315static DecodeStatus DecodeVecShiftR64Imm(MCInst &Inst, unsigned Imm,316 uint64_t Addr,317 const MCDisassembler *Decoder) {318 return DecodeVecShiftRImm(Inst, Imm, 64);319}320 321static DecodeStatus DecodeVecShiftR64ImmNarrow(MCInst &Inst, unsigned Imm,322 uint64_t Addr,323 const MCDisassembler *Decoder) {324 return DecodeVecShiftRImm(Inst, Imm | 0x20, 64);325}326 327static DecodeStatus DecodeVecShiftR32Imm(MCInst &Inst, unsigned Imm,328 uint64_t Addr,329 const MCDisassembler *Decoder) {330 return DecodeVecShiftRImm(Inst, Imm, 32);331}332 333static DecodeStatus DecodeVecShiftR32ImmNarrow(MCInst &Inst, unsigned Imm,334 uint64_t Addr,335 const MCDisassembler *Decoder) {336 return DecodeVecShiftRImm(Inst, Imm | 0x10, 32);337}338 339static DecodeStatus DecodeVecShiftR16Imm(MCInst &Inst, unsigned Imm,340 uint64_t Addr,341 const MCDisassembler *Decoder) {342 return DecodeVecShiftRImm(Inst, Imm, 16);343}344 345static DecodeStatus DecodeVecShiftR16ImmNarrow(MCInst &Inst, unsigned Imm,346 uint64_t Addr,347 const MCDisassembler *Decoder) {348 return DecodeVecShiftRImm(Inst, Imm | 0x8, 16);349}350 351static DecodeStatus DecodeVecShiftR8Imm(MCInst &Inst, unsigned Imm,352 uint64_t Addr,353 const MCDisassembler *Decoder) {354 return DecodeVecShiftRImm(Inst, Imm, 8);355}356 357static DecodeStatus DecodeVecShiftL64Imm(MCInst &Inst, unsigned Imm,358 uint64_t Addr,359 const MCDisassembler *Decoder) {360 return DecodeVecShiftLImm(Inst, Imm, 64);361}362 363static DecodeStatus DecodeVecShiftL32Imm(MCInst &Inst, unsigned Imm,364 uint64_t Addr,365 const MCDisassembler *Decoder) {366 return DecodeVecShiftLImm(Inst, Imm, 32);367}368 369static DecodeStatus DecodeVecShiftL16Imm(MCInst &Inst, unsigned Imm,370 uint64_t Addr,371 const MCDisassembler *Decoder) {372 return DecodeVecShiftLImm(Inst, Imm, 16);373}374 375static DecodeStatus DecodeVecShiftL8Imm(MCInst &Inst, unsigned Imm,376 uint64_t Addr,377 const MCDisassembler *Decoder) {378 return DecodeVecShiftLImm(Inst, Imm, 8);379}380 381static DecodeStatus382DecodeThreeAddrSRegInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr,383 const MCDisassembler *Decoder) {384 unsigned Rd = fieldFromInstruction(insn, 0, 5);385 unsigned Rn = fieldFromInstruction(insn, 5, 5);386 unsigned Rm = fieldFromInstruction(insn, 16, 5);387 unsigned shiftHi = fieldFromInstruction(insn, 22, 2);388 unsigned shiftLo = fieldFromInstruction(insn, 10, 6);389 unsigned shift = (shiftHi << 6) | shiftLo;390 switch (Inst.getOpcode()) {391 default:392 return Fail;393 case AArch64::ADDWrs:394 case AArch64::ADDSWrs:395 case AArch64::SUBWrs:396 case AArch64::SUBSWrs:397 // if shift == '11' then ReservedValue()398 if (shiftHi == 0x3)399 return Fail;400 [[fallthrough]];401 case AArch64::ANDWrs:402 case AArch64::ANDSWrs:403 case AArch64::BICWrs:404 case AArch64::BICSWrs:405 case AArch64::ORRWrs:406 case AArch64::ORNWrs:407 case AArch64::EORWrs:408 case AArch64::EONWrs: {409 // if sf == '0' and imm6<5> == '1' then ReservedValue()410 if (shiftLo >> 5 == 1)411 return Fail;412 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rd, Addr,413 Decoder);414 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rn, Addr,415 Decoder);416 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rm, Addr,417 Decoder);418 break;419 }420 case AArch64::ADDXrs:421 case AArch64::ADDSXrs:422 case AArch64::SUBXrs:423 case AArch64::SUBSXrs:424 // if shift == '11' then ReservedValue()425 if (shiftHi == 0x3)426 return Fail;427 [[fallthrough]];428 case AArch64::ANDXrs:429 case AArch64::ANDSXrs:430 case AArch64::BICXrs:431 case AArch64::BICSXrs:432 case AArch64::ORRXrs:433 case AArch64::ORNXrs:434 case AArch64::EORXrs:435 case AArch64::EONXrs:436 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rd, Addr,437 Decoder);438 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rn, Addr,439 Decoder);440 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rm, Addr,441 Decoder);442 break;443 }444 445 Inst.addOperand(MCOperand::createImm(shift));446 return Success;447}448 449static DecodeStatus DecodeMoveImmInstruction(MCInst &Inst, uint32_t insn,450 uint64_t Addr,451 const MCDisassembler *Decoder) {452 unsigned Rd = fieldFromInstruction(insn, 0, 5);453 unsigned imm = fieldFromInstruction(insn, 5, 16);454 unsigned shift = fieldFromInstruction(insn, 21, 2);455 shift <<= 4;456 switch (Inst.getOpcode()) {457 default:458 return Fail;459 case AArch64::MOVZWi:460 case AArch64::MOVNWi:461 case AArch64::MOVKWi:462 if (shift & (1U << 5))463 return Fail;464 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rd, Addr,465 Decoder);466 break;467 case AArch64::MOVZXi:468 case AArch64::MOVNXi:469 case AArch64::MOVKXi:470 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rd, Addr,471 Decoder);472 break;473 }474 475 if (Inst.getOpcode() == AArch64::MOVKWi ||476 Inst.getOpcode() == AArch64::MOVKXi)477 Inst.addOperand(Inst.getOperand(0));478 479 if (!Decoder->tryAddingSymbolicOperand(Inst, imm, Addr, /*IsBranch*/ false, 0,480 0, 4))481 Inst.addOperand(MCOperand::createImm(imm));482 483 Inst.addOperand(MCOperand::createImm(shift));484 return Success;485}486 487static DecodeStatus488DecodeUnsignedLdStInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr,489 const MCDisassembler *Decoder) {490 unsigned Rt = fieldFromInstruction(insn, 0, 5);491 unsigned Rn = fieldFromInstruction(insn, 5, 5);492 unsigned offset = fieldFromInstruction(insn, 10, 12);493 494 switch (Inst.getOpcode()) {495 default:496 return Fail;497 case AArch64::PRFMui:498 // Rt is an immediate in prefetch.499 Inst.addOperand(MCOperand::createImm(Rt));500 break;501 case AArch64::STRBBui:502 case AArch64::LDRBBui:503 case AArch64::LDRSBWui:504 case AArch64::STRHHui:505 case AArch64::LDRHHui:506 case AArch64::LDRSHWui:507 case AArch64::STRWui:508 case AArch64::LDRWui:509 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rt, Addr,510 Decoder);511 break;512 case AArch64::LDRSBXui:513 case AArch64::LDRSHXui:514 case AArch64::LDRSWui:515 case AArch64::STRXui:516 case AArch64::LDRXui:517 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rt, Addr,518 Decoder);519 break;520 case AArch64::LDRQui:521 case AArch64::STRQui:522 DecodeSimpleRegisterClass<AArch64::FPR128RegClassID, 0, 32>(Inst, Rt, Addr,523 Decoder);524 break;525 case AArch64::LDRDui:526 case AArch64::STRDui:527 DecodeSimpleRegisterClass<AArch64::FPR64RegClassID, 0, 32>(Inst, Rt, Addr,528 Decoder);529 break;530 case AArch64::LDRSui:531 case AArch64::STRSui:532 DecodeSimpleRegisterClass<AArch64::FPR32RegClassID, 0, 32>(Inst, Rt, Addr,533 Decoder);534 break;535 case AArch64::LDRHui:536 case AArch64::STRHui:537 DecodeSimpleRegisterClass<AArch64::FPR16RegClassID, 0, 32>(Inst, Rt, Addr,538 Decoder);539 break;540 case AArch64::LDRBui:541 case AArch64::STRBui:542 DecodeSimpleRegisterClass<AArch64::FPR8RegClassID, 0, 32>(Inst, Rt, Addr,543 Decoder);544 break;545 }546 547 DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr,548 Decoder);549 if (!Decoder->tryAddingSymbolicOperand(Inst, offset, Addr, Fail, 0, 0, 4))550 Inst.addOperand(MCOperand::createImm(offset));551 return Success;552}553 554static DecodeStatus DecodeSignedLdStInstruction(MCInst &Inst, uint32_t insn,555 uint64_t Addr,556 const MCDisassembler *Decoder) {557 unsigned Rt = fieldFromInstruction(insn, 0, 5);558 unsigned Rn = fieldFromInstruction(insn, 5, 5);559 int64_t offset = SignExtend64<9>(fieldFromInstruction(insn, 12, 9));560 561 // First operand is always the writeback to the address register, if needed.562 switch (Inst.getOpcode()) {563 default:564 break;565 case AArch64::LDRSBWpre:566 case AArch64::LDRSHWpre:567 case AArch64::STRBBpre:568 case AArch64::LDRBBpre:569 case AArch64::STRHHpre:570 case AArch64::LDRHHpre:571 case AArch64::STRWpre:572 case AArch64::LDRWpre:573 case AArch64::LDRSBWpost:574 case AArch64::LDRSHWpost:575 case AArch64::STRBBpost:576 case AArch64::LDRBBpost:577 case AArch64::STRHHpost:578 case AArch64::LDRHHpost:579 case AArch64::STRWpost:580 case AArch64::LDRWpost:581 case AArch64::LDRSBXpre:582 case AArch64::LDRSHXpre:583 case AArch64::STRXpre:584 case AArch64::LDRSWpre:585 case AArch64::LDRXpre:586 case AArch64::LDRSBXpost:587 case AArch64::LDRSHXpost:588 case AArch64::STRXpost:589 case AArch64::LDRSWpost:590 case AArch64::LDRXpost:591 case AArch64::LDRQpre:592 case AArch64::STRQpre:593 case AArch64::LDRQpost:594 case AArch64::STRQpost:595 case AArch64::LDRDpre:596 case AArch64::STRDpre:597 case AArch64::LDRDpost:598 case AArch64::STRDpost:599 case AArch64::LDRSpre:600 case AArch64::STRSpre:601 case AArch64::LDRSpost:602 case AArch64::STRSpost:603 case AArch64::LDRHpre:604 case AArch64::STRHpre:605 case AArch64::LDRHpost:606 case AArch64::STRHpost:607 case AArch64::LDRBpre:608 case AArch64::STRBpre:609 case AArch64::LDRBpost:610 case AArch64::STRBpost:611 DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr,612 Decoder);613 break;614 }615 616 switch (Inst.getOpcode()) {617 default:618 return Fail;619 case AArch64::PRFUMi:620 // Rt is an immediate in prefetch.621 Inst.addOperand(MCOperand::createImm(Rt));622 break;623 case AArch64::STURBBi:624 case AArch64::LDURBBi:625 case AArch64::LDURSBWi:626 case AArch64::STURHHi:627 case AArch64::LDURHHi:628 case AArch64::LDURSHWi:629 case AArch64::STURWi:630 case AArch64::LDURWi:631 case AArch64::LDTRSBWi:632 case AArch64::LDTRSHWi:633 case AArch64::STTRWi:634 case AArch64::LDTRWi:635 case AArch64::STTRHi:636 case AArch64::LDTRHi:637 case AArch64::LDTRBi:638 case AArch64::STTRBi:639 case AArch64::LDRSBWpre:640 case AArch64::LDRSHWpre:641 case AArch64::STRBBpre:642 case AArch64::LDRBBpre:643 case AArch64::STRHHpre:644 case AArch64::LDRHHpre:645 case AArch64::STRWpre:646 case AArch64::LDRWpre:647 case AArch64::LDRSBWpost:648 case AArch64::LDRSHWpost:649 case AArch64::STRBBpost:650 case AArch64::LDRBBpost:651 case AArch64::STRHHpost:652 case AArch64::LDRHHpost:653 case AArch64::STRWpost:654 case AArch64::LDRWpost:655 case AArch64::STLURBi:656 case AArch64::STLURHi:657 case AArch64::STLURWi:658 case AArch64::LDAPURBi:659 case AArch64::LDAPURSBWi:660 case AArch64::LDAPURHi:661 case AArch64::LDAPURSHWi:662 case AArch64::LDAPURi:663 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rt, Addr,664 Decoder);665 break;666 case AArch64::LDURSBXi:667 case AArch64::LDURSHXi:668 case AArch64::LDURSWi:669 case AArch64::STURXi:670 case AArch64::LDURXi:671 case AArch64::LDTRSBXi:672 case AArch64::LDTRSHXi:673 case AArch64::LDTRSWi:674 case AArch64::STTRXi:675 case AArch64::LDTRXi:676 case AArch64::LDRSBXpre:677 case AArch64::LDRSHXpre:678 case AArch64::STRXpre:679 case AArch64::LDRSWpre:680 case AArch64::LDRXpre:681 case AArch64::LDRSBXpost:682 case AArch64::LDRSHXpost:683 case AArch64::STRXpost:684 case AArch64::LDRSWpost:685 case AArch64::LDRXpost:686 case AArch64::LDAPURSWi:687 case AArch64::LDAPURSHXi:688 case AArch64::LDAPURSBXi:689 case AArch64::STLURXi:690 case AArch64::LDAPURXi:691 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rt, Addr,692 Decoder);693 break;694 case AArch64::LDURQi:695 case AArch64::STURQi:696 case AArch64::LDRQpre:697 case AArch64::STRQpre:698 case AArch64::LDRQpost:699 case AArch64::STRQpost:700 DecodeSimpleRegisterClass<AArch64::FPR128RegClassID, 0, 32>(Inst, Rt, Addr,701 Decoder);702 break;703 case AArch64::LDURDi:704 case AArch64::STURDi:705 case AArch64::LDRDpre:706 case AArch64::STRDpre:707 case AArch64::LDRDpost:708 case AArch64::STRDpost:709 DecodeSimpleRegisterClass<AArch64::FPR64RegClassID, 0, 32>(Inst, Rt, Addr,710 Decoder);711 break;712 case AArch64::LDURSi:713 case AArch64::STURSi:714 case AArch64::LDRSpre:715 case AArch64::STRSpre:716 case AArch64::LDRSpost:717 case AArch64::STRSpost:718 DecodeSimpleRegisterClass<AArch64::FPR32RegClassID, 0, 32>(Inst, Rt, Addr,719 Decoder);720 break;721 case AArch64::LDURHi:722 case AArch64::STURHi:723 case AArch64::LDRHpre:724 case AArch64::STRHpre:725 case AArch64::LDRHpost:726 case AArch64::STRHpost:727 DecodeSimpleRegisterClass<AArch64::FPR16RegClassID, 0, 32>(Inst, Rt, Addr,728 Decoder);729 break;730 case AArch64::LDURBi:731 case AArch64::STURBi:732 case AArch64::LDRBpre:733 case AArch64::STRBpre:734 case AArch64::LDRBpost:735 case AArch64::STRBpost:736 DecodeSimpleRegisterClass<AArch64::FPR8RegClassID, 0, 32>(Inst, Rt, Addr,737 Decoder);738 break;739 }740 741 DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr,742 Decoder);743 Inst.addOperand(MCOperand::createImm(offset));744 745 bool IsLoad = fieldFromInstruction(insn, 22, 1);746 bool IsIndexed = fieldFromInstruction(insn, 10, 2) != 0;747 bool IsFP = fieldFromInstruction(insn, 26, 1);748 749 // Cannot write back to a transfer register (but xzr != sp).750 if (IsLoad && IsIndexed && !IsFP && Rn != 31 && Rt == Rn)751 return SoftFail;752 753 return Success;754}755 756static DecodeStatus757DecodeExclusiveLdStInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr,758 const MCDisassembler *Decoder) {759 unsigned Rt = fieldFromInstruction(insn, 0, 5);760 unsigned Rn = fieldFromInstruction(insn, 5, 5);761 unsigned Rt2 = fieldFromInstruction(insn, 10, 5);762 unsigned Rs = fieldFromInstruction(insn, 16, 5);763 764 unsigned Opcode = Inst.getOpcode();765 switch (Opcode) {766 default:767 return Fail;768 case AArch64::STLXRW:769 case AArch64::STLXRB:770 case AArch64::STLXRH:771 case AArch64::STXRW:772 case AArch64::STXRB:773 case AArch64::STXRH:774 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rs, Addr,775 Decoder);776 [[fallthrough]];777 case AArch64::LDARW:778 case AArch64::LDARB:779 case AArch64::LDARH:780 case AArch64::LDAXRW:781 case AArch64::LDAXRB:782 case AArch64::LDAXRH:783 case AArch64::LDXRW:784 case AArch64::LDXRB:785 case AArch64::LDXRH:786 case AArch64::STLRW:787 case AArch64::STLRB:788 case AArch64::STLRH:789 case AArch64::STLLRW:790 case AArch64::STLLRB:791 case AArch64::STLLRH:792 case AArch64::LDLARW:793 case AArch64::LDLARB:794 case AArch64::LDLARH:795 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rt, Addr,796 Decoder);797 break;798 case AArch64::STLXRX:799 case AArch64::STXRX:800 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rs, Addr,801 Decoder);802 [[fallthrough]];803 case AArch64::LDARX:804 case AArch64::LDAXRX:805 case AArch64::LDXRX:806 case AArch64::STLRX:807 case AArch64::LDLARX:808 case AArch64::STLLRX:809 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rt, Addr,810 Decoder);811 break;812 case AArch64::STLXPW:813 case AArch64::STXPW:814 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rs, Addr,815 Decoder);816 [[fallthrough]];817 case AArch64::LDAXPW:818 case AArch64::LDXPW:819 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rt, Addr,820 Decoder);821 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rt2, Addr,822 Decoder);823 break;824 case AArch64::STLXPX:825 case AArch64::STXPX:826 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rs, Addr,827 Decoder);828 [[fallthrough]];829 case AArch64::LDAXPX:830 case AArch64::LDXPX:831 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rt, Addr,832 Decoder);833 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rt2, Addr,834 Decoder);835 break;836 }837 838 DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr,839 Decoder);840 841 // You shouldn't load to the same register twice in an instruction...842 if ((Opcode == AArch64::LDAXPW || Opcode == AArch64::LDXPW ||843 Opcode == AArch64::LDAXPX || Opcode == AArch64::LDXPX) &&844 Rt == Rt2)845 return SoftFail;846 847 return Success;848}849 850static DecodeStatus DecodePairLdStInstruction(MCInst &Inst, uint32_t insn,851 uint64_t Addr,852 const MCDisassembler *Decoder) {853 unsigned Rt = fieldFromInstruction(insn, 0, 5);854 unsigned Rn = fieldFromInstruction(insn, 5, 5);855 unsigned Rt2 = fieldFromInstruction(insn, 10, 5);856 int64_t offset = SignExtend64<7>(fieldFromInstruction(insn, 15, 7));857 bool IsLoad = fieldFromInstruction(insn, 22, 1);858 859 unsigned Opcode = Inst.getOpcode();860 bool NeedsDisjointWritebackTransfer = false;861 862 // First operand is always writeback of base register.863 switch (Opcode) {864 default:865 break;866 case AArch64::LDPXpost:867 case AArch64::STPXpost:868 case AArch64::LDPSWpost:869 case AArch64::LDPXpre:870 case AArch64::STPXpre:871 case AArch64::LDPSWpre:872 case AArch64::LDPWpost:873 case AArch64::STPWpost:874 case AArch64::LDPWpre:875 case AArch64::STPWpre:876 case AArch64::LDPQpost:877 case AArch64::STPQpost:878 case AArch64::LDPQpre:879 case AArch64::STPQpre:880 case AArch64::LDPDpost:881 case AArch64::STPDpost:882 case AArch64::LDPDpre:883 case AArch64::STPDpre:884 case AArch64::LDPSpost:885 case AArch64::STPSpost:886 case AArch64::LDPSpre:887 case AArch64::STPSpre:888 case AArch64::STGPpre:889 case AArch64::STGPpost:890 case AArch64::LDTPpre:891 case AArch64::LDTPpost:892 case AArch64::LDTPQpost:893 case AArch64::LDTPQpre:894 case AArch64::STTPpost:895 case AArch64::STTPpre:896 case AArch64::STTPQpost:897 case AArch64::STTPQpre:898 DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr,899 Decoder);900 break;901 }902 903 switch (Opcode) {904 default:905 return Fail;906 case AArch64::LDPXpost:907 case AArch64::STPXpost:908 case AArch64::LDPSWpost:909 case AArch64::LDPXpre:910 case AArch64::STPXpre:911 case AArch64::LDPSWpre:912 case AArch64::STGPpre:913 case AArch64::STGPpost:914 case AArch64::LDTPpost:915 case AArch64::LDTPpre:916 case AArch64::STTPpost:917 case AArch64::STTPpre:918 NeedsDisjointWritebackTransfer = true;919 [[fallthrough]];920 case AArch64::LDNPXi:921 case AArch64::STNPXi:922 case AArch64::LDPXi:923 case AArch64::STPXi:924 case AArch64::LDPSWi:925 case AArch64::STGPi:926 case AArch64::LDTPi:927 case AArch64::STTPi:928 case AArch64::STTNPXi:929 case AArch64::LDTNPXi:930 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rt, Addr,931 Decoder);932 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rt2, Addr,933 Decoder);934 break;935 case AArch64::LDPWpost:936 case AArch64::STPWpost:937 case AArch64::LDPWpre:938 case AArch64::STPWpre:939 NeedsDisjointWritebackTransfer = true;940 [[fallthrough]];941 case AArch64::LDNPWi:942 case AArch64::STNPWi:943 case AArch64::LDPWi:944 case AArch64::STPWi:945 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rt, Addr,946 Decoder);947 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rt2, Addr,948 Decoder);949 break;950 case AArch64::LDNPQi:951 case AArch64::STNPQi:952 case AArch64::LDPQpost:953 case AArch64::STPQpost:954 case AArch64::LDPQi:955 case AArch64::STPQi:956 case AArch64::LDPQpre:957 case AArch64::STPQpre:958 case AArch64::LDTPQi:959 case AArch64::LDTPQpost:960 case AArch64::LDTPQpre:961 case AArch64::LDTNPQi:962 case AArch64::STTPQi:963 case AArch64::STTPQpost:964 case AArch64::STTPQpre:965 case AArch64::STTNPQi:966 DecodeSimpleRegisterClass<AArch64::FPR128RegClassID, 0, 32>(Inst, Rt, Addr,967 Decoder);968 DecodeSimpleRegisterClass<AArch64::FPR128RegClassID, 0, 32>(Inst, Rt2, Addr,969 Decoder);970 break;971 case AArch64::LDNPDi:972 case AArch64::STNPDi:973 case AArch64::LDPDpost:974 case AArch64::STPDpost:975 case AArch64::LDPDi:976 case AArch64::STPDi:977 case AArch64::LDPDpre:978 case AArch64::STPDpre:979 DecodeSimpleRegisterClass<AArch64::FPR64RegClassID, 0, 32>(Inst, Rt, Addr,980 Decoder);981 DecodeSimpleRegisterClass<AArch64::FPR64RegClassID, 0, 32>(Inst, Rt2, Addr,982 Decoder);983 break;984 case AArch64::LDNPSi:985 case AArch64::STNPSi:986 case AArch64::LDPSpost:987 case AArch64::STPSpost:988 case AArch64::LDPSi:989 case AArch64::STPSi:990 case AArch64::LDPSpre:991 case AArch64::STPSpre:992 DecodeSimpleRegisterClass<AArch64::FPR32RegClassID, 0, 32>(Inst, Rt, Addr,993 Decoder);994 DecodeSimpleRegisterClass<AArch64::FPR32RegClassID, 0, 32>(Inst, Rt2, Addr,995 Decoder);996 break;997 }998 999 DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr,1000 Decoder);1001 Inst.addOperand(MCOperand::createImm(offset));1002 1003 // You shouldn't load to the same register twice in an instruction...1004 if (IsLoad && Rt == Rt2)1005 return SoftFail;1006 1007 // ... or do any operation that writes-back to a transfer register. But note1008 // that "stp xzr, xzr, [sp], #4" is fine because xzr and sp are different.1009 if (NeedsDisjointWritebackTransfer && Rn != 31 && (Rt == Rn || Rt2 == Rn))1010 return SoftFail;1011 1012 return Success;1013}1014 1015static DecodeStatus DecodeAuthLoadInstruction(MCInst &Inst, uint32_t insn,1016 uint64_t Addr,1017 const MCDisassembler *Decoder) {1018 unsigned Rt = fieldFromInstruction(insn, 0, 5);1019 unsigned Rn = fieldFromInstruction(insn, 5, 5);1020 uint64_t offset = fieldFromInstruction(insn, 22, 1) << 9 |1021 fieldFromInstruction(insn, 12, 9);1022 unsigned writeback = fieldFromInstruction(insn, 11, 1);1023 1024 switch (Inst.getOpcode()) {1025 default:1026 return Fail;1027 case AArch64::LDRAAwriteback:1028 case AArch64::LDRABwriteback:1029 DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(1030 Inst, Rn /* writeback register */, Addr, Decoder);1031 break;1032 case AArch64::LDRAAindexed:1033 case AArch64::LDRABindexed:1034 break;1035 }1036 1037 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rt, Addr,1038 Decoder);1039 DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr,1040 Decoder);1041 DecodeSImm<10>(Inst, offset, Addr, Decoder);1042 1043 if (writeback && Rt == Rn && Rn != 31) {1044 return SoftFail;1045 }1046 1047 return Success;1048}1049 1050static DecodeStatus DecodeAddSubERegInstruction(MCInst &Inst, uint32_t insn,1051 uint64_t Addr,1052 const MCDisassembler *Decoder) {1053 unsigned Rd = fieldFromInstruction(insn, 0, 5);1054 unsigned Rn = fieldFromInstruction(insn, 5, 5);1055 unsigned Rm = fieldFromInstruction(insn, 16, 5);1056 unsigned extend = fieldFromInstruction(insn, 10, 6);1057 1058 unsigned shift = extend & 0x7;1059 if (shift > 4)1060 return Fail;1061 1062 switch (Inst.getOpcode()) {1063 default:1064 return Fail;1065 case AArch64::ADDWrx:1066 case AArch64::SUBWrx:1067 DecodeSimpleRegisterClass<AArch64::GPR32spRegClassID, 0, 32>(Inst, Rd, Addr,1068 Decoder);1069 DecodeSimpleRegisterClass<AArch64::GPR32spRegClassID, 0, 32>(Inst, Rn, Addr,1070 Decoder);1071 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rm, Addr,1072 Decoder);1073 break;1074 case AArch64::ADDSWrx:1075 case AArch64::SUBSWrx:1076 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rd, Addr,1077 Decoder);1078 DecodeSimpleRegisterClass<AArch64::GPR32spRegClassID, 0, 32>(Inst, Rn, Addr,1079 Decoder);1080 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rm, Addr,1081 Decoder);1082 break;1083 case AArch64::ADDXrx:1084 case AArch64::SUBXrx:1085 DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rd, Addr,1086 Decoder);1087 DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr,1088 Decoder);1089 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rm, Addr,1090 Decoder);1091 break;1092 case AArch64::ADDSXrx:1093 case AArch64::SUBSXrx:1094 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rd, Addr,1095 Decoder);1096 DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr,1097 Decoder);1098 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rm, Addr,1099 Decoder);1100 break;1101 case AArch64::ADDXrx64:1102 case AArch64::SUBXrx64:1103 DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rd, Addr,1104 Decoder);1105 DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr,1106 Decoder);1107 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rm, Addr,1108 Decoder);1109 break;1110 case AArch64::SUBSXrx64:1111 case AArch64::ADDSXrx64:1112 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rd, Addr,1113 Decoder);1114 DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr,1115 Decoder);1116 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rm, Addr,1117 Decoder);1118 break;1119 }1120 1121 Inst.addOperand(MCOperand::createImm(extend));1122 return Success;1123}1124 1125static DecodeStatus DecodeLogicalImmInstruction(MCInst &Inst, uint32_t insn,1126 uint64_t Addr,1127 const MCDisassembler *Decoder) {1128 unsigned Rd = fieldFromInstruction(insn, 0, 5);1129 unsigned Rn = fieldFromInstruction(insn, 5, 5);1130 unsigned Datasize = fieldFromInstruction(insn, 31, 1);1131 unsigned imm;1132 1133 if (Datasize) {1134 if (Inst.getOpcode() == AArch64::ANDSXri)1135 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rd, Addr,1136 Decoder);1137 else1138 DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(1139 Inst, Rd, Addr, Decoder);1140 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rn, Addr,1141 Decoder);1142 imm = fieldFromInstruction(insn, 10, 13);1143 if (!AArch64_AM::isValidDecodeLogicalImmediate(imm, 64))1144 return Fail;1145 } else {1146 if (Inst.getOpcode() == AArch64::ANDSWri)1147 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rd, Addr,1148 Decoder);1149 else1150 DecodeSimpleRegisterClass<AArch64::GPR32spRegClassID, 0, 32>(1151 Inst, Rd, Addr, Decoder);1152 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rn, Addr,1153 Decoder);1154 imm = fieldFromInstruction(insn, 10, 12);1155 if (!AArch64_AM::isValidDecodeLogicalImmediate(imm, 32))1156 return Fail;1157 }1158 Inst.addOperand(MCOperand::createImm(imm));1159 return Success;1160}1161 1162static DecodeStatus DecodeModImmInstruction(MCInst &Inst, uint32_t insn,1163 uint64_t Addr,1164 const MCDisassembler *Decoder) {1165 unsigned Rd = fieldFromInstruction(insn, 0, 5);1166 unsigned cmode = fieldFromInstruction(insn, 12, 4);1167 unsigned imm = fieldFromInstruction(insn, 16, 3) << 5;1168 imm |= fieldFromInstruction(insn, 5, 5);1169 1170 if (Inst.getOpcode() == AArch64::MOVID)1171 DecodeSimpleRegisterClass<AArch64::FPR64RegClassID, 0, 32>(Inst, Rd, Addr,1172 Decoder);1173 else1174 DecodeSimpleRegisterClass<AArch64::FPR128RegClassID, 0, 32>(Inst, Rd, Addr,1175 Decoder);1176 1177 Inst.addOperand(MCOperand::createImm(imm));1178 1179 switch (Inst.getOpcode()) {1180 default:1181 break;1182 case AArch64::MOVIv4i16:1183 case AArch64::MOVIv8i16:1184 case AArch64::MVNIv4i16:1185 case AArch64::MVNIv8i16:1186 case AArch64::MOVIv2i32:1187 case AArch64::MOVIv4i32:1188 case AArch64::MVNIv2i32:1189 case AArch64::MVNIv4i32:1190 Inst.addOperand(MCOperand::createImm((cmode & 6) << 2));1191 break;1192 case AArch64::MOVIv2s_msl:1193 case AArch64::MOVIv4s_msl:1194 case AArch64::MVNIv2s_msl:1195 case AArch64::MVNIv4s_msl:1196 Inst.addOperand(MCOperand::createImm((cmode & 1) ? 0x110 : 0x108));1197 break;1198 }1199 1200 return Success;1201}1202 1203static DecodeStatus DecodeModImmTiedInstruction(MCInst &Inst, uint32_t insn,1204 uint64_t Addr,1205 const MCDisassembler *Decoder) {1206 unsigned Rd = fieldFromInstruction(insn, 0, 5);1207 unsigned cmode = fieldFromInstruction(insn, 12, 4);1208 unsigned imm = fieldFromInstruction(insn, 16, 3) << 5;1209 imm |= fieldFromInstruction(insn, 5, 5);1210 1211 // Tied operands added twice.1212 DecodeSimpleRegisterClass<AArch64::FPR128RegClassID, 0, 32>(Inst, Rd, Addr,1213 Decoder);1214 DecodeSimpleRegisterClass<AArch64::FPR128RegClassID, 0, 32>(Inst, Rd, Addr,1215 Decoder);1216 1217 Inst.addOperand(MCOperand::createImm(imm));1218 Inst.addOperand(MCOperand::createImm((cmode & 6) << 2));1219 1220 return Success;1221}1222 1223static DecodeStatus DecodeAdrInstruction(MCInst &Inst, uint32_t insn,1224 uint64_t Addr,1225 const MCDisassembler *Decoder) {1226 unsigned Rd = fieldFromInstruction(insn, 0, 5);1227 int64_t imm = SignExtend64<21>((fieldFromInstruction(insn, 5, 19) << 2) |1228 fieldFromInstruction(insn, 29, 2));1229 1230 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rd, Addr,1231 Decoder);1232 if (!Decoder->tryAddingSymbolicOperand(Inst, imm, Addr, Fail, 0, 0, 4))1233 Inst.addOperand(MCOperand::createImm(imm));1234 1235 return Success;1236}1237 1238static DecodeStatus DecodeAddSubImmShift(MCInst &Inst, uint32_t insn,1239 uint64_t Addr,1240 const MCDisassembler *Decoder) {1241 unsigned Rd = fieldFromInstruction(insn, 0, 5);1242 unsigned Rn = fieldFromInstruction(insn, 5, 5);1243 unsigned Imm = fieldFromInstruction(insn, 10, 14);1244 unsigned S = fieldFromInstruction(insn, 29, 1);1245 unsigned Datasize = fieldFromInstruction(insn, 31, 1);1246 1247 unsigned ShifterVal = (Imm >> 12) & 3;1248 unsigned ImmVal = Imm & 0xFFF;1249 1250 if (ShifterVal != 0 && ShifterVal != 1)1251 return Fail;1252 1253 if (Datasize) {1254 if (Rd == 31 && !S)1255 DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(1256 Inst, Rd, Addr, Decoder);1257 else1258 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rd, Addr,1259 Decoder);1260 DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr,1261 Decoder);1262 } else {1263 if (Rd == 31 && !S)1264 DecodeSimpleRegisterClass<AArch64::GPR32spRegClassID, 0, 32>(1265 Inst, Rd, Addr, Decoder);1266 else1267 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rd, Addr,1268 Decoder);1269 DecodeSimpleRegisterClass<AArch64::GPR32spRegClassID, 0, 32>(Inst, Rn, Addr,1270 Decoder);1271 }1272 1273 if (!Decoder->tryAddingSymbolicOperand(Inst, Imm, Addr, Fail, 0, 0, 4))1274 Inst.addOperand(MCOperand::createImm(ImmVal));1275 Inst.addOperand(MCOperand::createImm(12 * ShifterVal));1276 return Success;1277}1278 1279static DecodeStatus DecodeUnconditionalBranch(MCInst &Inst, uint32_t insn,1280 uint64_t Addr,1281 const MCDisassembler *Decoder) {1282 int64_t imm = SignExtend64<26>(fieldFromInstruction(insn, 0, 26));1283 1284 if (!Decoder->tryAddingSymbolicOperand(Inst, imm * 4, Addr, true, 0, 0, 4))1285 Inst.addOperand(MCOperand::createImm(imm));1286 1287 return Success;1288}1289 1290static bool isInvalidPState(uint64_t Op1, uint64_t Op2) {1291 return Op1 == 0b000 && (Op2 == 0b000 || // CFINV1292 Op2 == 0b001 || // XAFlag1293 Op2 == 0b010); // AXFlag1294}1295 1296static DecodeStatus1297DecodeSystemPStateImm0_15Instruction(MCInst &Inst, uint32_t insn, uint64_t Addr,1298 const MCDisassembler *Decoder) {1299 uint64_t op1 = fieldFromInstruction(insn, 16, 3);1300 uint64_t op2 = fieldFromInstruction(insn, 5, 3);1301 uint64_t imm = fieldFromInstruction(insn, 8, 4);1302 uint64_t pstate_field = (op1 << 3) | op2;1303 1304 if (isInvalidPState(op1, op2))1305 return Fail;1306 1307 Inst.addOperand(MCOperand::createImm(pstate_field));1308 Inst.addOperand(MCOperand::createImm(imm));1309 1310 auto PState = AArch64PState::lookupPStateImm0_15ByEncoding(pstate_field);1311 if (PState &&1312 PState->haveFeatures(Decoder->getSubtargetInfo().getFeatureBits()))1313 return Success;1314 return Fail;1315}1316 1317static DecodeStatus1318DecodeSystemPStateImm0_1Instruction(MCInst &Inst, uint32_t insn, uint64_t Addr,1319 const MCDisassembler *Decoder) {1320 uint64_t op1 = fieldFromInstruction(insn, 16, 3);1321 uint64_t op2 = fieldFromInstruction(insn, 5, 3);1322 uint64_t crm_high = fieldFromInstruction(insn, 9, 3);1323 uint64_t imm = fieldFromInstruction(insn, 8, 1);1324 uint64_t pstate_field = (crm_high << 6) | (op1 << 3) | op2;1325 1326 if (isInvalidPState(op1, op2))1327 return Fail;1328 1329 Inst.addOperand(MCOperand::createImm(pstate_field));1330 Inst.addOperand(MCOperand::createImm(imm));1331 1332 auto PState = AArch64PState::lookupPStateImm0_1ByEncoding(pstate_field);1333 if (PState &&1334 PState->haveFeatures(Decoder->getSubtargetInfo().getFeatureBits()))1335 return Success;1336 return Fail;1337}1338 1339static DecodeStatus DecodeTestAndBranch(MCInst &Inst, uint32_t insn,1340 uint64_t Addr,1341 const MCDisassembler *Decoder) {1342 uint64_t Rt = fieldFromInstruction(insn, 0, 5);1343 uint64_t bit = fieldFromInstruction(insn, 31, 1) << 5;1344 bit |= fieldFromInstruction(insn, 19, 5);1345 int64_t dst = SignExtend64<14>(fieldFromInstruction(insn, 5, 14));1346 1347 if (fieldFromInstruction(insn, 31, 1) == 0)1348 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rt, Addr,1349 Decoder);1350 else1351 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rt, Addr,1352 Decoder);1353 Inst.addOperand(MCOperand::createImm(bit));1354 if (!Decoder->tryAddingSymbolicOperand(Inst, dst * 4, Addr, true, 0, 0, 4))1355 Inst.addOperand(MCOperand::createImm(dst));1356 1357 return Success;1358}1359 1360static DecodeStatus1361DecodeGPRSeqPairsClassRegisterClass(MCInst &Inst, unsigned RegClassID,1362 unsigned RegNo, uint64_t Addr,1363 const MCDisassembler *Decoder) {1364 // Register number must be even (see CASP instruction)1365 if (RegNo & 0x1)1366 return Fail;1367 1368 MCRegister Reg = AArch64MCRegisterClasses[RegClassID].getRegister(RegNo / 2);1369 Inst.addOperand(MCOperand::createReg(Reg));1370 return Success;1371}1372 1373static DecodeStatus1374DecodeWSeqPairsClassRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Addr,1375 const MCDisassembler *Decoder) {1376 return DecodeGPRSeqPairsClassRegisterClass(1377 Inst, AArch64::WSeqPairsClassRegClassID, RegNo, Addr, Decoder);1378}1379 1380static DecodeStatus1381DecodeXSeqPairsClassRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Addr,1382 const MCDisassembler *Decoder) {1383 return DecodeGPRSeqPairsClassRegisterClass(1384 Inst, AArch64::XSeqPairsClassRegClassID, RegNo, Addr, Decoder);1385}1386 1387static DecodeStatus DecodeSyspXzrInstruction(MCInst &Inst, uint32_t insn,1388 uint64_t Addr,1389 const MCDisassembler *Decoder) {1390 unsigned op1 = fieldFromInstruction(insn, 16, 3);1391 unsigned CRn = fieldFromInstruction(insn, 12, 4);1392 unsigned CRm = fieldFromInstruction(insn, 8, 4);1393 unsigned op2 = fieldFromInstruction(insn, 5, 3);1394 unsigned Rt = fieldFromInstruction(insn, 0, 5);1395 if (Rt != 0b11111)1396 return Fail;1397 1398 Inst.addOperand(MCOperand::createImm(op1));1399 Inst.addOperand(MCOperand::createImm(CRn));1400 Inst.addOperand(MCOperand::createImm(CRm));1401 Inst.addOperand(MCOperand::createImm(op2));1402 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rt, Addr,1403 Decoder);1404 1405 return Success;1406}1407 1408static DecodeStatus1409DecodeSVELogicalImmInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr,1410 const MCDisassembler *Decoder) {1411 unsigned Zdn = fieldFromInstruction(insn, 0, 5);1412 unsigned imm = fieldFromInstruction(insn, 5, 13);1413 if (!AArch64_AM::isValidDecodeLogicalImmediate(imm, 64))1414 return Fail;1415 1416 // The same (tied) operand is added twice to the instruction.1417 DecodeSimpleRegisterClass<AArch64::ZPRRegClassID, 0, 32>(Inst, Zdn, Addr,1418 Decoder);1419 if (Inst.getOpcode() != AArch64::DUPM_ZI)1420 DecodeSimpleRegisterClass<AArch64::ZPRRegClassID, 0, 32>(Inst, Zdn, Addr,1421 Decoder);1422 Inst.addOperand(MCOperand::createImm(imm));1423 return Success;1424}1425 1426static DecodeStatus DecodeZeroImm(MCInst &Inst, const MCDisassembler *Decoder) {1427 Inst.addOperand(MCOperand::createImm(0));1428 return Success;1429}1430 1431template <int Bits>1432static DecodeStatus DecodeSImm(MCInst &Inst, uint64_t Imm, uint64_t Address,1433 const MCDisassembler *Decoder) {1434 if (Imm & ~((1LL << Bits) - 1))1435 return Fail;1436 1437 // Imm is a signed immediate, so sign extend it.1438 if (Imm & (1 << (Bits - 1)))1439 Imm |= ~((1LL << Bits) - 1);1440 1441 Inst.addOperand(MCOperand::createImm(Imm));1442 return Success;1443}1444 1445// Decode 8-bit signed/unsigned immediate for a given element width.1446template <int ElementWidth>1447static DecodeStatus DecodeImm8OptLsl(MCInst &Inst, unsigned Imm, uint64_t Addr,1448 const MCDisassembler *Decoder) {1449 unsigned Val = (uint8_t)Imm;1450 unsigned Shift = (Imm & 0x100) ? 8 : 0;1451 if (ElementWidth == 8 && Shift)1452 return Fail;1453 Inst.addOperand(MCOperand::createImm(Val));1454 Inst.addOperand(MCOperand::createImm(Shift));1455 return Success;1456}1457 1458// Decode uimm4 ranged from 1-16.1459static DecodeStatus DecodeSVEIncDecImm(MCInst &Inst, unsigned Imm,1460 uint64_t Addr,1461 const MCDisassembler *Decoder) {1462 Inst.addOperand(MCOperand::createImm(Imm + 1));1463 return Success;1464}1465 1466static DecodeStatus DecodeSVCROp(MCInst &Inst, unsigned Imm, uint64_t Address,1467 const MCDisassembler *Decoder) {1468 if (AArch64SVCR::lookupSVCRByEncoding(Imm)) {1469 Inst.addOperand(MCOperand::createImm(Imm));1470 return Success;1471 }1472 return Fail;1473}1474 1475static DecodeStatus DecodeCPYMemOpInstruction(MCInst &Inst, uint32_t insn,1476 uint64_t Addr,1477 const MCDisassembler *Decoder) {1478 unsigned Rd = fieldFromInstruction(insn, 0, 5);1479 unsigned Rs = fieldFromInstruction(insn, 16, 5);1480 unsigned Rn = fieldFromInstruction(insn, 5, 5);1481 1482 // None of the registers may alias: if they do, then the instruction is not1483 // merely unpredictable but actually entirely unallocated.1484 if (Rd == Rs || Rs == Rn || Rd == Rn)1485 return MCDisassembler::Fail;1486 1487 // All three register operands are written back, so they all appear1488 // twice in the operand list, once as outputs and once as inputs.1489 if (!DecodeSimpleRegisterClass<AArch64::GPR64commonRegClassID, 0, 31>(1490 Inst, Rd, Addr, Decoder) ||1491 !DecodeSimpleRegisterClass<AArch64::GPR64commonRegClassID, 0, 31>(1492 Inst, Rs, Addr, Decoder) ||1493 !DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(1494 Inst, Rn, Addr, Decoder) ||1495 !DecodeSimpleRegisterClass<AArch64::GPR64commonRegClassID, 0, 31>(1496 Inst, Rd, Addr, Decoder) ||1497 !DecodeSimpleRegisterClass<AArch64::GPR64commonRegClassID, 0, 31>(1498 Inst, Rs, Addr, Decoder) ||1499 !DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(1500 Inst, Rn, Addr, Decoder))1501 return MCDisassembler::Fail;1502 1503 return MCDisassembler::Success;1504}1505 1506static DecodeStatus DecodeSETMemOpInstruction(MCInst &Inst, uint32_t insn,1507 uint64_t Addr,1508 const MCDisassembler *Decoder) {1509 unsigned Rd = fieldFromInstruction(insn, 0, 5);1510 unsigned Rm = fieldFromInstruction(insn, 16, 5);1511 unsigned Rn = fieldFromInstruction(insn, 5, 5);1512 1513 // None of the registers may alias: if they do, then the instruction is not1514 // merely unpredictable but actually entirely unallocated.1515 if (Rd == Rm || Rm == Rn || Rd == Rn)1516 return MCDisassembler::Fail;1517 1518 // Rd and Rn (not Rm) register operands are written back, so they appear1519 // twice in the operand list, once as outputs and once as inputs.1520 if (!DecodeSimpleRegisterClass<AArch64::GPR64commonRegClassID, 0, 31>(1521 Inst, Rd, Addr, Decoder) ||1522 !DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(1523 Inst, Rn, Addr, Decoder) ||1524 !DecodeSimpleRegisterClass<AArch64::GPR64commonRegClassID, 0, 31>(1525 Inst, Rd, Addr, Decoder) ||1526 !DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(1527 Inst, Rn, Addr, Decoder) ||1528 !DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(1529 Inst, Rm, Addr, Decoder))1530 return MCDisassembler::Fail;1531 1532 return MCDisassembler::Success;1533}1534 1535static DecodeStatus DecodeSETMemGoOpInstruction(MCInst &Inst, uint32_t insn,1536 uint64_t Addr,1537 const MCDisassembler *Decoder) {1538 unsigned Rd = fieldFromInstruction(insn, 0, 5);1539 unsigned Rn = fieldFromInstruction(insn, 5, 5);1540 1541 // None of the registers may alias: if they do, then the instruction is not1542 // merely unpredictable but actually entirely unallocated.1543 if (Rd == Rn)1544 return MCDisassembler::Fail;1545 1546 // Rd and Rn register operands are written back, so they appear1547 // twice in the operand list, once as outputs and once as inputs.1548 if (!DecodeSimpleRegisterClass<AArch64::GPR64commonRegClassID, 0, 31>(1549 Inst, Rd, Addr, Decoder) ||1550 !DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(1551 Inst, Rn, Addr, Decoder) ||1552 !DecodeSimpleRegisterClass<AArch64::GPR64commonRegClassID, 0, 31>(1553 Inst, Rd, Addr, Decoder) ||1554 !DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(1555 Inst, Rn, Addr, Decoder))1556 return MCDisassembler::Fail;1557 1558 return MCDisassembler::Success;1559}1560 1561static DecodeStatus DecodePRFMRegInstruction(MCInst &Inst, uint32_t insn,1562 uint64_t Addr,1563 const MCDisassembler *Decoder) {1564 // PRFM with Rt = '11xxx' should be decoded as RPRFM.1565 // Fail to decode and defer to fallback decoder table to decode RPRFM.1566 unsigned Mask = 0x18;1567 uint64_t Rt = fieldFromInstruction(insn, 0, 5);1568 if ((Rt & Mask) == Mask)1569 return Fail;1570 1571 uint64_t Rn = fieldFromInstruction(insn, 5, 5);1572 uint64_t Shift = fieldFromInstruction(insn, 12, 1);1573 uint64_t Extend = fieldFromInstruction(insn, 15, 1);1574 uint64_t Rm = fieldFromInstruction(insn, 16, 5);1575 1576 Inst.addOperand(MCOperand::createImm(Rt));1577 DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr,1578 Decoder);1579 1580 switch (Inst.getOpcode()) {1581 default:1582 return Fail;1583 case AArch64::PRFMroW:1584 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rm, Addr,1585 Decoder);1586 break;1587 case AArch64::PRFMroX:1588 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rm, Addr,1589 Decoder);1590 break;1591 }1592 1593 DecodeMemExtend(Inst, (Extend << 1) | Shift, Addr, Decoder);1594 1595 return Success;1596}1597 1598static DecodeStatus1599DecodeSMESpillFillInstruction(MCInst &Inst, uint32_t Bits, uint64_t Addr,1600 const MCDisassembler *Decoder) {1601 unsigned RvBits = fieldFromInstruction(Bits, 13, 2);1602 unsigned RnBits = fieldFromInstruction(Bits, 5, 5);1603 unsigned Imm4Bits = fieldFromInstruction(Bits, 0, 4);1604 1605 DecodeMPRRegisterClass(Inst, Decoder);1606 DecodeSimpleRegisterClass<AArch64::MatrixIndexGPR32_12_15RegClassID, 0, 4>(1607 Inst, RvBits, Addr, Decoder);1608 Inst.addOperand(MCOperand::createImm(Imm4Bits));1609 DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, RnBits,1610 Addr, Decoder);1611 // Spill and fill instructions have a single immediate used for both1612 // the vector select offset and optional memory offset. Replicate1613 // the decoded immediate.1614 Inst.addOperand(MCOperand::createImm(Imm4Bits));1615 return Success;1616}1617 1618#include "AArch64GenDisassemblerTables.inc"1619#include "AArch64GenInstrInfo.inc"1620 1621static MCDisassembler *createAArch64Disassembler(const Target &T,1622 const MCSubtargetInfo &STI,1623 MCContext &Ctx) {1624 1625 return new AArch64Disassembler(STI, Ctx, T.createMCInstrInfo());1626}1627 1628DecodeStatus AArch64Disassembler::getInstruction(MCInst &MI, uint64_t &Size,1629 ArrayRef<uint8_t> Bytes,1630 uint64_t Address,1631 raw_ostream &CS) const {1632 CommentStream = &CS;1633 1634 Size = 0;1635 // We want to read exactly 4 bytes of data.1636 if (Bytes.size() < 4)1637 return Fail;1638 Size = 4;1639 1640 // Encoded as a small-endian 32-bit word in the stream.1641 uint32_t Insn =1642 (Bytes[3] << 24) | (Bytes[2] << 16) | (Bytes[1] << 8) | (Bytes[0] << 0);1643 1644 const uint8_t *Tables[] = {DecoderTable32, DecoderTableFallback32};1645 1646 for (const auto *Table : Tables) {1647 DecodeStatus Result =1648 decodeInstruction(Table, MI, Insn, Address, this, STI);1649 if (Result != MCDisassembler::Fail)1650 return Result;1651 }1652 1653 return MCDisassembler::Fail;1654}1655 1656uint64_t AArch64Disassembler::suggestBytesToSkip(ArrayRef<uint8_t> Bytes,1657 uint64_t Address) const {1658 // AArch64 instructions are always 4 bytes wide, so there's no point1659 // in skipping any smaller number of bytes if an instruction can't1660 // be decoded.1661 return 4;1662}1663 1664static MCSymbolizer *1665createAArch64ExternalSymbolizer(const Triple &TT, LLVMOpInfoCallback GetOpInfo,1666 LLVMSymbolLookupCallback SymbolLookUp,1667 void *DisInfo, MCContext *Ctx,1668 std::unique_ptr<MCRelocationInfo> &&RelInfo) {1669 return new AArch64ExternalSymbolizer(*Ctx, std::move(RelInfo), GetOpInfo,1670 SymbolLookUp, DisInfo);1671}1672 1673extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void1674LLVMInitializeAArch64Disassembler() {1675 TargetRegistry::RegisterMCDisassembler(getTheAArch64leTarget(),1676 createAArch64Disassembler);1677 TargetRegistry::RegisterMCDisassembler(getTheAArch64beTarget(),1678 createAArch64Disassembler);1679 TargetRegistry::RegisterMCSymbolizer(getTheAArch64leTarget(),1680 createAArch64ExternalSymbolizer);1681 TargetRegistry::RegisterMCSymbolizer(getTheAArch64beTarget(),1682 createAArch64ExternalSymbolizer);1683 TargetRegistry::RegisterMCDisassembler(getTheAArch64_32Target(),1684 createAArch64Disassembler);1685 TargetRegistry::RegisterMCSymbolizer(getTheAArch64_32Target(),1686 createAArch64ExternalSymbolizer);1687 1688 TargetRegistry::RegisterMCDisassembler(getTheARM64Target(),1689 createAArch64Disassembler);1690 TargetRegistry::RegisterMCSymbolizer(getTheARM64Target(),1691 createAArch64ExternalSymbolizer);1692 TargetRegistry::RegisterMCDisassembler(getTheARM64_32Target(),1693 createAArch64Disassembler);1694 TargetRegistry::RegisterMCSymbolizer(getTheARM64_32Target(),1695 createAArch64ExternalSymbolizer);1696}1697