xref: /llvm-project/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp (revision 0dad994a102cd91354327991444c8a4d68ae4a56)
1 //===------ PPCDisassembler.cpp - Disassembler for PowerPC ------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "MCTargetDesc/PPCMCTargetDesc.h"
11 #include "llvm/MC/MCDisassembler/MCDisassembler.h"
12 #include "llvm/MC/MCFixedLenDisassembler.h"
13 #include "llvm/MC/MCInst.h"
14 #include "llvm/MC/MCSubtargetInfo.h"
15 #include "llvm/Support/Endian.h"
16 #include "llvm/Support/TargetRegistry.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 &VStream,
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" void LLVMInitializePowerPCDisassembler() {
55   // Register the disassembler for each target.
56   TargetRegistry::RegisterMCDisassembler(getThePPC32Target(),
57                                          createPPCDisassembler);
58   TargetRegistry::RegisterMCDisassembler(getThePPC64Target(),
59                                          createPPCDisassembler);
60   TargetRegistry::RegisterMCDisassembler(getThePPC64LETarget(),
61                                          createPPCLEDisassembler);
62 }
63 
64 // FIXME: These can be generated by TableGen from the existing register
65 // encoding values!
66 
67 template <std::size_t N>
68 static DecodeStatus decodeRegisterClass(MCInst &Inst, uint64_t RegNo,
69                                         const MCPhysReg (&Regs)[N]) {
70   assert(RegNo < N && "Invalid register number");
71   Inst.addOperand(MCOperand::createReg(Regs[RegNo]));
72   return MCDisassembler::Success;
73 }
74 
75 static DecodeStatus DecodeCRRCRegisterClass(MCInst &Inst, uint64_t RegNo,
76                                             uint64_t Address,
77                                             const void *Decoder) {
78   return decodeRegisterClass(Inst, RegNo, CRRegs);
79 }
80 
81 static DecodeStatus DecodeCRRC0RegisterClass(MCInst &Inst, uint64_t RegNo,
82                                             uint64_t Address,
83                                             const void *Decoder) {
84   return decodeRegisterClass(Inst, RegNo, CRRegs);
85 }
86 
87 static DecodeStatus DecodeCRBITRCRegisterClass(MCInst &Inst, uint64_t RegNo,
88                                             uint64_t Address,
89                                             const void *Decoder) {
90   return decodeRegisterClass(Inst, RegNo, CRBITRegs);
91 }
92 
93 static DecodeStatus DecodeF4RCRegisterClass(MCInst &Inst, uint64_t RegNo,
94                                             uint64_t Address,
95                                             const void *Decoder) {
96   return decodeRegisterClass(Inst, RegNo, FRegs);
97 }
98 
99 static DecodeStatus DecodeF8RCRegisterClass(MCInst &Inst, uint64_t RegNo,
100                                             uint64_t Address,
101                                             const void *Decoder) {
102   return decodeRegisterClass(Inst, RegNo, FRegs);
103 }
104 
105 static DecodeStatus DecodeVFRCRegisterClass(MCInst &Inst, uint64_t RegNo,
106                                             uint64_t Address,
107                                             const void *Decoder) {
108   return decodeRegisterClass(Inst, RegNo, VFRegs);
109 }
110 
111 static DecodeStatus DecodeVRRCRegisterClass(MCInst &Inst, uint64_t RegNo,
112                                             uint64_t Address,
113                                             const void *Decoder) {
114   return decodeRegisterClass(Inst, RegNo, VRegs);
115 }
116 
117 static DecodeStatus DecodeVSRCRegisterClass(MCInst &Inst, uint64_t RegNo,
118                                             uint64_t Address,
119                                             const void *Decoder) {
120   return decodeRegisterClass(Inst, RegNo, VSRegs);
121 }
122 
123 static DecodeStatus DecodeVSFRCRegisterClass(MCInst &Inst, uint64_t RegNo,
124                                             uint64_t Address,
125                                             const void *Decoder) {
126   return decodeRegisterClass(Inst, RegNo, VSFRegs);
127 }
128 
129 static DecodeStatus DecodeVSSRCRegisterClass(MCInst &Inst, uint64_t RegNo,
130                                             uint64_t Address,
131                                             const void *Decoder) {
132   return decodeRegisterClass(Inst, RegNo, VSSRegs);
133 }
134 
135 static DecodeStatus DecodeGPRCRegisterClass(MCInst &Inst, uint64_t RegNo,
136                                             uint64_t Address,
137                                             const void *Decoder) {
138   return decodeRegisterClass(Inst, RegNo, RRegs);
139 }
140 
141 static DecodeStatus DecodeGPRC_NOR0RegisterClass(MCInst &Inst, uint64_t RegNo,
142                                             uint64_t Address,
143                                             const void *Decoder) {
144   return decodeRegisterClass(Inst, RegNo, RRegsNoR0);
145 }
146 
147 static DecodeStatus DecodeG8RCRegisterClass(MCInst &Inst, uint64_t RegNo,
148                                             uint64_t Address,
149                                             const void *Decoder) {
150   return decodeRegisterClass(Inst, RegNo, XRegs);
151 }
152 
153 static DecodeStatus DecodeG8RC_NOX0RegisterClass(MCInst &Inst, uint64_t RegNo,
154                                             uint64_t Address,
155                                             const void *Decoder) {
156   return decodeRegisterClass(Inst, RegNo, XRegsNoX0);
157 }
158 
159 #define DecodePointerLikeRegClass0 DecodeGPRCRegisterClass
160 #define DecodePointerLikeRegClass1 DecodeGPRC_NOR0RegisterClass
161 
162 static DecodeStatus DecodeQFRCRegisterClass(MCInst &Inst, uint64_t RegNo,
163                                             uint64_t Address,
164                                             const void *Decoder) {
165   return decodeRegisterClass(Inst, RegNo, QFRegs);
166 }
167 
168 static DecodeStatus DecodeSPE4RCRegisterClass(MCInst &Inst, uint64_t RegNo,
169                                             uint64_t Address,
170                                             const void *Decoder) {
171   return decodeRegisterClass(Inst, RegNo, RRegs);
172 }
173 
174 static DecodeStatus DecodeSPERCRegisterClass(MCInst &Inst, uint64_t RegNo,
175                                             uint64_t Address,
176                                             const void *Decoder) {
177   return decodeRegisterClass(Inst, RegNo, SPERegs);
178 }
179 
180 #define DecodeQSRCRegisterClass DecodeQFRCRegisterClass
181 #define DecodeQBRCRegisterClass DecodeQFRCRegisterClass
182 
183 template<unsigned N>
184 static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm,
185                                       int64_t Address, const void *Decoder) {
186   assert(isUInt<N>(Imm) && "Invalid immediate");
187   Inst.addOperand(MCOperand::createImm(Imm));
188   return MCDisassembler::Success;
189 }
190 
191 template<unsigned N>
192 static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm,
193                                       int64_t Address, const void *Decoder) {
194   assert(isUInt<N>(Imm) && "Invalid immediate");
195   Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm)));
196   return MCDisassembler::Success;
197 }
198 
199 static DecodeStatus decodeMemRIOperands(MCInst &Inst, uint64_t Imm,
200                                         int64_t Address, const void *Decoder) {
201   // Decode the memri field (imm, reg), which has the low 16-bits as the
202   // displacement and the next 5 bits as the register #.
203 
204   uint64_t Base = Imm >> 16;
205   uint64_t Disp = Imm & 0xFFFF;
206 
207   assert(Base < 32 && "Invalid base register");
208 
209   switch (Inst.getOpcode()) {
210   default: break;
211   case PPC::LBZU:
212   case PPC::LHAU:
213   case PPC::LHZU:
214   case PPC::LWZU:
215   case PPC::LFSU:
216   case PPC::LFDU:
217     // Add the tied output operand.
218     Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
219     break;
220   case PPC::STBU:
221   case PPC::STHU:
222   case PPC::STWU:
223   case PPC::STFSU:
224   case PPC::STFDU:
225     Inst.insert(Inst.begin(), MCOperand::createReg(RRegsNoR0[Base]));
226     break;
227   }
228 
229   Inst.addOperand(MCOperand::createImm(SignExtend64<16>(Disp)));
230   Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
231   return MCDisassembler::Success;
232 }
233 
234 static DecodeStatus decodeMemRIXOperands(MCInst &Inst, uint64_t Imm,
235                                          int64_t Address, const void *Decoder) {
236   // Decode the memrix field (imm, reg), which has the low 14-bits as the
237   // displacement and the next 5 bits as the register #.
238 
239   uint64_t Base = Imm >> 14;
240   uint64_t Disp = Imm & 0x3FFF;
241 
242   assert(Base < 32 && "Invalid base register");
243 
244   if (Inst.getOpcode() == PPC::LDU)
245     // Add the tied output operand.
246     Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
247   else if (Inst.getOpcode() == PPC::STDU)
248     Inst.insert(Inst.begin(), MCOperand::createReg(RRegsNoR0[Base]));
249 
250   Inst.addOperand(MCOperand::createImm(SignExtend64<16>(Disp << 2)));
251   Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
252   return MCDisassembler::Success;
253 }
254 
255 static DecodeStatus decodeMemRIX16Operands(MCInst &Inst, uint64_t Imm,
256                                          int64_t Address, const void *Decoder) {
257   // Decode the memrix16 field (imm, reg), which has the low 12-bits as the
258   // displacement with 16-byte aligned, and the next 5 bits as the register #.
259 
260   uint64_t Base = Imm >> 12;
261   uint64_t Disp = Imm & 0xFFF;
262 
263   assert(Base < 32 && "Invalid base register");
264 
265   Inst.addOperand(MCOperand::createImm(SignExtend64<16>(Disp << 4)));
266   Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
267   return MCDisassembler::Success;
268 }
269 
270 static DecodeStatus decodeSPE8Operands(MCInst &Inst, uint64_t Imm,
271                                          int64_t Address, const void *Decoder) {
272   // Decode the spe8disp field (imm, reg), which has the low 5-bits as the
273   // displacement with 8-byte aligned, and the next 5 bits as the register #.
274 
275   uint64_t Base = Imm >> 5;
276   uint64_t Disp = Imm & 0x1F;
277 
278   assert(Base < 32 && "Invalid base register");
279 
280   Inst.addOperand(MCOperand::createImm(Disp << 3));
281   Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
282   return MCDisassembler::Success;
283 }
284 
285 static DecodeStatus decodeSPE4Operands(MCInst &Inst, uint64_t Imm,
286                                          int64_t Address, const void *Decoder) {
287   // Decode the spe4disp field (imm, reg), which has the low 5-bits as the
288   // displacement with 4-byte aligned, and the next 5 bits as the register #.
289 
290   uint64_t Base = Imm >> 5;
291   uint64_t Disp = Imm & 0x1F;
292 
293   assert(Base < 32 && "Invalid base register");
294 
295   Inst.addOperand(MCOperand::createImm(Disp << 2));
296   Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
297   return MCDisassembler::Success;
298 }
299 
300 static DecodeStatus decodeSPE2Operands(MCInst &Inst, uint64_t Imm,
301                                          int64_t Address, const void *Decoder) {
302   // Decode the spe2disp field (imm, reg), which has the low 5-bits as the
303   // displacement with 2-byte aligned, and the next 5 bits as the register #.
304 
305   uint64_t Base = Imm >> 5;
306   uint64_t Disp = Imm & 0x1F;
307 
308   assert(Base < 32 && "Invalid base register");
309 
310   Inst.addOperand(MCOperand::createImm(Disp << 1));
311   Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
312   return MCDisassembler::Success;
313 }
314 
315 static DecodeStatus decodeCRBitMOperand(MCInst &Inst, uint64_t Imm,
316                                         int64_t Address, const void *Decoder) {
317   // The cr bit encoding is 0x80 >> cr_reg_num.
318 
319   unsigned Zeros = countTrailingZeros(Imm);
320   assert(Zeros < 8 && "Invalid CR bit value");
321 
322   Inst.addOperand(MCOperand::createReg(CRRegs[7 - Zeros]));
323   return MCDisassembler::Success;
324 }
325 
326 #include "PPCGenDisassemblerTables.inc"
327 
328 DecodeStatus PPCDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
329                                              ArrayRef<uint8_t> Bytes,
330                                              uint64_t Address, raw_ostream &OS,
331                                              raw_ostream &CS) const {
332   // Get the four bytes of the instruction.
333   Size = 4;
334   if (Bytes.size() < 4) {
335     Size = 0;
336     return MCDisassembler::Fail;
337   }
338 
339   // Read the instruction in the proper endianness.
340   uint32_t Inst = IsLittleEndian ? support::endian::read32le(Bytes.data())
341                                  : support::endian::read32be(Bytes.data());
342 
343   if (STI.getFeatureBits()[PPC::FeatureQPX]) {
344     DecodeStatus result =
345       decodeInstruction(DecoderTableQPX32, MI, Inst, Address, this, STI);
346     if (result != MCDisassembler::Fail)
347       return result;
348   } else if (STI.getFeatureBits()[PPC::FeatureSPE]) {
349     DecodeStatus result =
350       decodeInstruction(DecoderTableSPE32, MI, Inst, Address, this, STI);
351     if (result != MCDisassembler::Fail)
352       return result;
353   }
354 
355   return decodeInstruction(DecoderTable32, MI, Inst, Address, this, STI);
356 }
357 
358