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