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