LLVM  9.0.0svn
PPCDisassembler.cpp
Go to the documentation of this file.
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 
12 #include "llvm/MC/MCInst.h"
14 #include "llvm/Support/Endian.h"
16 
17 using namespace llvm;
18 
20 
21 #define DEBUG_TYPE "ppc-disassembler"
22 
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 
42  const MCSubtargetInfo &STI,
43  MCContext &Ctx) {
44  return new PPCDisassembler(STI, Ctx, /*IsLittleEndian=*/false);
45 }
46 
48  const MCSubtargetInfo &STI,
49  MCContext &Ctx) {
50  return new PPCDisassembler(STI, Ctx, /*IsLittleEndian=*/true);
51 }
52 
54  // Register the disassembler for each target.
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));
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]));
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));
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)));
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]));
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]));
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]));
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]));
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]));
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]));
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]));
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 
iterator begin()
Definition: MCInst.h:191
static DecodeStatus DecodeVSFRCRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder)
static DecodeStatus DecodeCRRC0RegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder)
static DecodeStatus decodeSPE8Operands(MCInst &Inst, uint64_t Imm, int64_t Address, const void *Decoder)
This class represents lattice values for constants.
Definition: AllocatorList.h:23
static DecodeStatus DecodeCRBITRCRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder)
DecodeStatus
Ternary decode status.
Superclass for all disassemblers.
Target & getThePPC32Target()
static DecodeStatus decodeCRBitMOperand(MCInst &Inst, uint64_t Imm, int64_t Address, const void *Decoder)
static DecodeStatus DecodeVRRCRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder)
static DecodeStatus DecodeG8RCRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder)
static void RegisterMCDisassembler(Target &T, Target::MCDisassemblerCtorTy Fn)
RegisterMCDisassembler - Register a MCDisassembler implementation for the given target.
static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm, int64_t Address, const void *Decoder)
static DecodeStatus DecodeVSSRCRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder)
static MCDisassembler * createPPCDisassembler(const Target &T, const MCSubtargetInfo &STI, MCContext &Ctx)
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:115
uint32_t read32be(const void *P)
Definition: Endian.h:371
static DecodeStatus DecodeVSRCRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder)
static MCDisassembler * createPPCLEDisassembler(const Target &T, const MCSubtargetInfo &STI, MCContext &Ctx)
static DecodeStatus DecodePCRel24BranchTarget(MCInst &Inst, unsigned Imm, uint64_t Addr, const void *Decoder)
static DecodeStatus DecodeSPERCRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder)
Context object for machine code objects.
Definition: MCContext.h:62
int decodeInstruction(InternalInstruction *insn, byteReader_t reader, const void *readerArg, dlog_t logger, void *loggerArg, const void *miiArg, uint64_t startLoc, DisassemblerMode mode)
Decode one instruction and store the decoding results in a buffer provided by the consumer...
Target & getThePPC64Target()
static DecodeStatus decodeMemRIXOperands(MCInst &Inst, uint64_t Imm, int64_t Address, const void *Decoder)
static DecodeStatus DecodeVFRCRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder)
iterator insert(iterator I, const MCOperand &Op)
Definition: MCInst.h:196
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:158
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
MCDisassembler::DecodeStatus DecodeStatus
static DecodeStatus DecodeF4RCRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder)
static DecodeStatus decodeMemRIOperands(MCInst &Inst, uint64_t Imm, int64_t Address, const void *Decoder)
std::size_t countTrailingZeros(T Val, ZeroBehavior ZB=ZB_Width)
Count number of 0&#39;s from the least significant bit to the most stopping at the first 1...
Definition: MathExtras.h:119
static DecodeStatus DecodeCRRCRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder)
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:148
static DecodeStatus DecodeF8RCRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder)
static DecodeStatus DecodeQFRCRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder)
static DecodeStatus DecodeGPRCRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder)
const T * data() const
Definition: ArrayRef.h:145
static DecodeStatus decodeRegisterClass(MCInst &Inst, uint64_t RegNo, const MCPhysReg(&Regs)[N])
static DecodeStatus decodeSPE4Operands(MCInst &Inst, uint64_t Imm, int64_t Address, const void *Decoder)
static DecodeStatus decodeSPE2Operands(MCInst &Inst, uint64_t Imm, int64_t Address, const void *Decoder)
DEFINE_PPC_REGCLASSES
Target - Wrapper for Target specific information.
Target & getThePPC64LETarget()
void LLVMInitializePowerPCDisassembler()
static DecodeStatus DecodeSPE4RCRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder)
#define N
uint32_t read32le(const void *P)
Definition: Endian.h:368
Generic base class for all target subtargets.
static DecodeStatus decodeMemRIX16Operands(MCInst &Inst, uint64_t Imm, int64_t Address, const void *Decoder)
uint32_t Size
Definition: Profile.cpp:46
static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm, int64_t Address, const void *Decoder)
static DecodeStatus DecodeGPRC_NOR0RegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:45
static DecodeStatus DecodeG8RC_NOX0RegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder)
IRTranslator LLVM IR MI
void addOperand(const MCOperand &Op)
Definition: MCInst.h:183
unsigned getOpcode() const
Definition: MCInst.h:171
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:122