1 //===------ PPCDisassembler.cpp - Disassembler for PowerPC ------*- C++ -*-===// 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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "MCTargetDesc/PPCMCTargetDesc.h" 10 #include "TargetInfo/PowerPCTargetInfo.h" 11 #include "llvm/MC/MCDecoderOps.h" 12 #include "llvm/MC/MCDisassembler/MCDisassembler.h" 13 #include "llvm/MC/MCInst.h" 14 #include "llvm/MC/MCSubtargetInfo.h" 15 #include "llvm/MC/TargetRegistry.h" 16 #include "llvm/Support/Compiler.h" 17 #include "llvm/Support/Endian.h" 18 19 using namespace llvm; 20 21 DEFINE_PPC_REGCLASSES 22 23 #define DEBUG_TYPE "ppc-disassembler" 24 25 typedef MCDisassembler::DecodeStatus DecodeStatus; 26 27 namespace { 28 class PPCDisassembler : public MCDisassembler { 29 bool IsLittleEndian; 30 31 public: 32 PPCDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, 33 bool IsLittleEndian) 34 : MCDisassembler(STI, Ctx), IsLittleEndian(IsLittleEndian) {} 35 36 DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, 37 ArrayRef<uint8_t> Bytes, uint64_t Address, 38 raw_ostream &CStream) const override; 39 }; 40 } // end anonymous namespace 41 42 static MCDisassembler *createPPCDisassembler(const Target &T, 43 const MCSubtargetInfo &STI, 44 MCContext &Ctx) { 45 return new PPCDisassembler(STI, Ctx, /*IsLittleEndian=*/false); 46 } 47 48 static MCDisassembler *createPPCLEDisassembler(const Target &T, 49 const MCSubtargetInfo &STI, 50 MCContext &Ctx) { 51 return new PPCDisassembler(STI, Ctx, /*IsLittleEndian=*/true); 52 } 53 54 extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void 55 LLVMInitializePowerPCDisassembler() { 56 // Register the disassembler for each target. 57 TargetRegistry::RegisterMCDisassembler(getThePPC32Target(), 58 createPPCDisassembler); 59 TargetRegistry::RegisterMCDisassembler(getThePPC32LETarget(), 60 createPPCLEDisassembler); 61 TargetRegistry::RegisterMCDisassembler(getThePPC64Target(), 62 createPPCDisassembler); 63 TargetRegistry::RegisterMCDisassembler(getThePPC64LETarget(), 64 createPPCLEDisassembler); 65 } 66 67 static DecodeStatus decodeCondBrTarget(MCInst &Inst, unsigned Imm, 68 uint64_t /*Address*/, 69 const MCDisassembler * /*Decoder*/) { 70 Inst.addOperand(MCOperand::createImm(SignExtend32<14>(Imm))); 71 return MCDisassembler::Success; 72 } 73 74 static DecodeStatus decodeDirectBrTarget(MCInst &Inst, unsigned Imm, 75 uint64_t /*Address*/, 76 const MCDisassembler * /*Decoder*/) { 77 int32_t Offset = SignExtend32<24>(Imm); 78 Inst.addOperand(MCOperand::createImm(Offset)); 79 return MCDisassembler::Success; 80 } 81 82 // FIXME: These can be generated by TableGen from the existing register 83 // encoding values! 84 85 template <std::size_t N> 86 static DecodeStatus decodeRegisterClass(MCInst &Inst, uint64_t RegNo, 87 const MCPhysReg (&Regs)[N]) { 88 if (RegNo >= N) 89 return MCDisassembler::Fail; 90 Inst.addOperand(MCOperand::createReg(Regs[RegNo])); 91 return MCDisassembler::Success; 92 } 93 94 static DecodeStatus DecodeCRRCRegisterClass(MCInst &Inst, uint64_t RegNo, 95 uint64_t Address, 96 const MCDisassembler *Decoder) { 97 return decodeRegisterClass(Inst, RegNo, CRRegs); 98 } 99 100 static DecodeStatus DecodeCRBITRCRegisterClass(MCInst &Inst, uint64_t RegNo, 101 uint64_t Address, 102 const MCDisassembler *Decoder) { 103 return decodeRegisterClass(Inst, RegNo, CRBITRegs); 104 } 105 106 static DecodeStatus DecodeF4RCRegisterClass(MCInst &Inst, uint64_t RegNo, 107 uint64_t Address, 108 const MCDisassembler *Decoder) { 109 return decodeRegisterClass(Inst, RegNo, FRegs); 110 } 111 112 static DecodeStatus DecodeF8RCRegisterClass(MCInst &Inst, uint64_t RegNo, 113 uint64_t Address, 114 const MCDisassembler *Decoder) { 115 return decodeRegisterClass(Inst, RegNo, FRegs); 116 } 117 118 static DecodeStatus DecodeFpRCRegisterClass(MCInst &Inst, uint64_t RegNo, 119 uint64_t Address, 120 const MCDisassembler *Decoder) { 121 if (RegNo > 30 || (RegNo & 1)) 122 return MCDisassembler::Fail; 123 return decodeRegisterClass(Inst, RegNo >> 1, FpRegs); 124 } 125 126 static DecodeStatus DecodeVFRCRegisterClass(MCInst &Inst, uint64_t RegNo, 127 uint64_t Address, 128 const MCDisassembler *Decoder) { 129 return decodeRegisterClass(Inst, RegNo, VFRegs); 130 } 131 132 static DecodeStatus DecodeVRRCRegisterClass(MCInst &Inst, uint64_t RegNo, 133 uint64_t Address, 134 const MCDisassembler *Decoder) { 135 return decodeRegisterClass(Inst, RegNo, VRegs); 136 } 137 138 static DecodeStatus DecodeVSRCRegisterClass(MCInst &Inst, uint64_t RegNo, 139 uint64_t Address, 140 const MCDisassembler *Decoder) { 141 return decodeRegisterClass(Inst, RegNo, VSRegs); 142 } 143 144 static DecodeStatus DecodeVSFRCRegisterClass(MCInst &Inst, uint64_t RegNo, 145 uint64_t Address, 146 const MCDisassembler *Decoder) { 147 return decodeRegisterClass(Inst, RegNo, VSFRegs); 148 } 149 150 static DecodeStatus DecodeVSSRCRegisterClass(MCInst &Inst, uint64_t RegNo, 151 uint64_t Address, 152 const MCDisassembler *Decoder) { 153 return decodeRegisterClass(Inst, RegNo, VSSRegs); 154 } 155 156 static DecodeStatus DecodeGPRCRegisterClass(MCInst &Inst, uint64_t RegNo, 157 uint64_t Address, 158 const MCDisassembler *Decoder) { 159 return decodeRegisterClass(Inst, RegNo, RRegs); 160 } 161 162 static DecodeStatus 163 DecodeGPRC_NOR0RegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, 164 const MCDisassembler *Decoder) { 165 return decodeRegisterClass(Inst, RegNo, RRegsNoR0); 166 } 167 168 static DecodeStatus DecodeG8RCRegisterClass(MCInst &Inst, uint64_t RegNo, 169 uint64_t Address, 170 const MCDisassembler *Decoder) { 171 return decodeRegisterClass(Inst, RegNo, XRegs); 172 } 173 174 static DecodeStatus DecodeG8pRCRegisterClass(MCInst &Inst, uint64_t RegNo, 175 uint64_t Address, 176 const MCDisassembler *Decoder) { 177 return decodeRegisterClass(Inst, RegNo, XRegs); 178 } 179 180 static DecodeStatus 181 DecodeG8RC_NOX0RegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, 182 const MCDisassembler *Decoder) { 183 return decodeRegisterClass(Inst, RegNo, XRegsNoX0); 184 } 185 186 #define DecodePointerLikeRegClass0 DecodeGPRCRegisterClass 187 #define DecodePointerLikeRegClass1 DecodeGPRC_NOR0RegisterClass 188 189 static DecodeStatus DecodeSPERCRegisterClass(MCInst &Inst, uint64_t RegNo, 190 uint64_t Address, 191 const MCDisassembler *Decoder) { 192 return decodeRegisterClass(Inst, RegNo, SPERegs); 193 } 194 195 static DecodeStatus DecodeACCRCRegisterClass(MCInst &Inst, uint64_t RegNo, 196 uint64_t Address, 197 const MCDisassembler *Decoder) { 198 return decodeRegisterClass(Inst, RegNo, ACCRegs); 199 } 200 201 static DecodeStatus DecodeWACCRCRegisterClass(MCInst &Inst, uint64_t RegNo, 202 uint64_t Address, 203 const void *Decoder) { 204 return decodeRegisterClass(Inst, RegNo, WACCRegs); 205 } 206 207 static DecodeStatus DecodeWACC_HIRCRegisterClass(MCInst &Inst, uint64_t RegNo, 208 uint64_t Address, 209 const void *Decoder) { 210 return decodeRegisterClass(Inst, RegNo, WACC_HIRegs); 211 } 212 213 // TODO: Make this function static when the register class is used by a new 214 // instruction. 215 DecodeStatus DecodeDMRROWRCRegisterClass(MCInst &Inst, uint64_t RegNo, 216 uint64_t Address, 217 const void *Decoder) { 218 return decodeRegisterClass(Inst, RegNo, DMRROWRegs); 219 } 220 221 static DecodeStatus DecodeDMRROWpRCRegisterClass(MCInst &Inst, uint64_t RegNo, 222 uint64_t Address, 223 const void *Decoder) { 224 return decodeRegisterClass(Inst, RegNo, DMRROWpRegs); 225 } 226 227 static DecodeStatus DecodeDMRRCRegisterClass(MCInst &Inst, uint64_t RegNo, 228 uint64_t Address, 229 const void *Decoder) { 230 return decodeRegisterClass(Inst, RegNo, DMRRegs); 231 } 232 233 // TODO: Make this function static when the register class is used by a new 234 // instruction. 235 DecodeStatus DecodeDMRpRCRegisterClass(MCInst &Inst, uint64_t RegNo, 236 uint64_t Address, const void *Decoder) { 237 return decodeRegisterClass(Inst, RegNo, DMRpRegs); 238 } 239 240 static DecodeStatus DecodeVSRpRCRegisterClass(MCInst &Inst, uint64_t RegNo, 241 uint64_t Address, 242 const MCDisassembler *Decoder) { 243 return decodeRegisterClass(Inst, RegNo, VSRpRegs); 244 } 245 246 #define DecodeQSRCRegisterClass DecodeQFRCRegisterClass 247 #define DecodeQBRCRegisterClass DecodeQFRCRegisterClass 248 249 template <unsigned N> 250 static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm, 251 int64_t Address, 252 const MCDisassembler *Decoder) { 253 if (!isUInt<N>(Imm)) 254 return MCDisassembler::Fail; 255 Inst.addOperand(MCOperand::createImm(Imm)); 256 return MCDisassembler::Success; 257 } 258 259 template <unsigned N> 260 static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm, 261 int64_t Address, 262 const MCDisassembler *Decoder) { 263 if (!isUInt<N>(Imm)) 264 return MCDisassembler::Fail; 265 Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm))); 266 return MCDisassembler::Success; 267 } 268 269 static DecodeStatus decodeImmZeroOperand(MCInst &Inst, uint64_t Imm, 270 int64_t Address, 271 const MCDisassembler *Decoder) { 272 if (Imm != 0) 273 return MCDisassembler::Fail; 274 Inst.addOperand(MCOperand::createImm(Imm)); 275 return MCDisassembler::Success; 276 } 277 278 static DecodeStatus decodeVSRpEvenOperands(MCInst &Inst, uint64_t RegNo, 279 uint64_t Address, 280 const MCDisassembler *Decoder) { 281 if (RegNo & 1) 282 return MCDisassembler::Fail; 283 Inst.addOperand(MCOperand::createReg(VSRpRegs[RegNo >> 1])); 284 return MCDisassembler::Success; 285 } 286 287 static DecodeStatus decodeDispRIXOperand(MCInst &Inst, uint64_t Imm, 288 int64_t Address, 289 const MCDisassembler *Decoder) { 290 // The rix displacement is an immediate shifted by 2 291 Inst.addOperand(MCOperand::createImm(SignExtend64<16>(Imm << 2))); 292 return MCDisassembler::Success; 293 } 294 295 static DecodeStatus decodeDispRIHashOperand(MCInst &Inst, uint64_t Imm, 296 int64_t Address, 297 const MCDisassembler *Decoder) { 298 // Decode the disp field for a hash store or hash check operation. 299 // The field is composed of an immediate value that is 6 bits 300 // and covers the range -8 to -512. The immediate is always negative and 2s 301 // complement which is why we sign extend a 7 bit value. 302 const int64_t Disp = SignExtend64<7>((Imm & 0x3F) + 64) * 8; 303 304 Inst.addOperand(MCOperand::createImm(Disp)); 305 return MCDisassembler::Success; 306 } 307 308 static DecodeStatus decodeDispRIX16Operand(MCInst &Inst, uint64_t Imm, 309 int64_t Address, 310 const MCDisassembler *Decoder) { 311 // The rix16 displacement has 12-bits which are shifted by 4. 312 Inst.addOperand(MCOperand::createImm(SignExtend64<16>(Imm << 4))); 313 return MCDisassembler::Success; 314 } 315 316 static DecodeStatus decodeDispSPE8Operand(MCInst &Inst, uint64_t Imm, 317 int64_t Address, 318 const MCDisassembler *Decoder) { 319 // Decode the dispSPE8 field, which has 5-bits, 8-byte aligned. 320 321 uint64_t Disp = Imm & 0x1F; 322 323 Inst.addOperand(MCOperand::createImm(Disp << 3)); 324 return MCDisassembler::Success; 325 } 326 327 static DecodeStatus decodeDispSPE4Operand(MCInst &Inst, uint64_t Imm, 328 int64_t Address, 329 const MCDisassembler *Decoder) { 330 // Decode the dispSPE8 field, which has 5-bits, 4-byte aligned. 331 332 uint64_t Disp = Imm & 0x1F; 333 334 Inst.addOperand(MCOperand::createImm(Disp << 2)); 335 return MCDisassembler::Success; 336 } 337 338 static DecodeStatus decodeDispSPE2Operand(MCInst &Inst, uint64_t Imm, 339 int64_t Address, 340 const MCDisassembler *Decoder) { 341 // Decode the dispSPE8 field, which has 5-bits, 2-byte aligned. 342 343 uint64_t Disp = Imm & 0x1F; 344 Inst.addOperand(MCOperand::createImm(Disp << 1)); 345 return MCDisassembler::Success; 346 } 347 348 static DecodeStatus decodeCRBitMOperand(MCInst &Inst, uint64_t Imm, 349 int64_t Address, 350 const MCDisassembler *Decoder) { 351 // The cr bit encoding is 0x80 >> cr_reg_num. 352 353 unsigned Zeros = llvm::countr_zero(Imm); 354 if (Zeros >= 8) 355 return MCDisassembler::Fail; 356 357 Inst.addOperand(MCOperand::createReg(CRRegs[7 - Zeros])); 358 return MCDisassembler::Success; 359 } 360 361 #include "PPCGenDisassemblerTables.inc" 362 363 DecodeStatus PPCDisassembler::getInstruction(MCInst &MI, uint64_t &Size, 364 ArrayRef<uint8_t> Bytes, 365 uint64_t Address, 366 raw_ostream &CS) const { 367 auto *ReadFunc = IsLittleEndian ? support::endian::read32le 368 : support::endian::read32be; 369 370 // If this is an 8-byte prefixed instruction, handle it here. 371 // Note: prefixed instructions aren't technically 8-byte entities - the prefix 372 // appears in memory at an address 4 bytes prior to that of the base 373 // instruction regardless of endianness. So we read the two pieces and 374 // rebuild the 8-byte instruction. 375 // TODO: In this function we call decodeInstruction several times with 376 // different decoder tables. It may be possible to only call once by 377 // looking at the top 6 bits of the instruction. 378 if (STI.hasFeature(PPC::FeaturePrefixInstrs) && Bytes.size() >= 8) { 379 uint32_t Prefix = ReadFunc(Bytes.data()); 380 uint32_t BaseInst = ReadFunc(Bytes.data() + 4); 381 uint64_t Inst = BaseInst | (uint64_t)Prefix << 32; 382 DecodeStatus result = decodeInstruction(DecoderTable64, MI, Inst, Address, 383 this, STI); 384 if (result != MCDisassembler::Fail) { 385 Size = 8; 386 return result; 387 } 388 } 389 390 // Get the four bytes of the instruction. 391 Size = 4; 392 if (Bytes.size() < 4) { 393 Size = 0; 394 return MCDisassembler::Fail; 395 } 396 397 // Read the instruction in the proper endianness. 398 uint64_t Inst = ReadFunc(Bytes.data()); 399 400 if (STI.hasFeature(PPC::FeatureSPE)) { 401 DecodeStatus result = 402 decodeInstruction(DecoderTableSPE32, MI, Inst, Address, this, STI); 403 if (result != MCDisassembler::Fail) 404 return result; 405 } 406 407 return decodeInstruction(DecoderTable32, MI, Inst, Address, this, STI); 408 } 409