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:
PPCDisassembler(const MCSubtargetInfo & STI,MCContext & Ctx,bool IsLittleEndian)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
createPPCDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)42 static MCDisassembler *createPPCDisassembler(const Target &T,
43 const MCSubtargetInfo &STI,
44 MCContext &Ctx) {
45 return new PPCDisassembler(STI, Ctx, /*IsLittleEndian=*/false);
46 }
47
createPPCLEDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)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
LLVMInitializePowerPCDisassembler()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
decodeCondBrTarget(MCInst & Inst,unsigned Imm,uint64_t,const MCDisassembler *)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
decodeDirectBrTarget(MCInst & Inst,unsigned Imm,uint64_t,const MCDisassembler *)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>
decodeRegisterClass(MCInst & Inst,uint64_t RegNo,const MCPhysReg (& Regs)[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
DecodeCRRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)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
DecodeCRBITRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)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
DecodeF4RCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)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
DecodeF8RCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)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
DecodeFpRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)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
DecodeVFRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)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
DecodeVRRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)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
DecodeVSRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)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
DecodeVSFRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)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
DecodeVSSRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)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
DecodeGPRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)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
DecodeGPRC_NOR0RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)163 DecodeGPRC_NOR0RegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address,
164 const MCDisassembler *Decoder) {
165 return decodeRegisterClass(Inst, RegNo, RRegsNoR0);
166 }
167
DecodeG8RCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)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
DecodeG8pRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)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
DecodeG8RC_NOX0RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)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
DecodeSPERCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)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
DecodeACCRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)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
DecodeWACCRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)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
DecodeWACC_HIRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)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.
DecodeDMRROWRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)215 DecodeStatus DecodeDMRROWRCRegisterClass(MCInst &Inst, uint64_t RegNo,
216 uint64_t Address,
217 const void *Decoder) {
218 return decodeRegisterClass(Inst, RegNo, DMRROWRegs);
219 }
220
DecodeDMRROWpRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)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
DecodeDMRRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)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.
DecodeDMRpRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)235 DecodeStatus DecodeDMRpRCRegisterClass(MCInst &Inst, uint64_t RegNo,
236 uint64_t Address, const void *Decoder) {
237 return decodeRegisterClass(Inst, RegNo, DMRpRegs);
238 }
239
DecodeVSRpRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)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>
decodeUImmOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)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>
decodeSImmOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)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
decodeImmZeroOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)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
decodeVSRpEvenOperands(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)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
decodeDispRIXOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)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
decodeDispRIHashOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)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
decodeDispRIX16Operand(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)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
decodeDispSPE8Operand(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)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
decodeDispSPE4Operand(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)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
decodeDispSPE2Operand(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)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
decodeCRBitMOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)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
getInstruction(MCInst & MI,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & CS) const363 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