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