blob: 26869f2508231d265eb781135bae6451f86c77da [file] [log] [blame]
Hal Finkel23453472013-12-19 16:13:01 +00001//===------ 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
Benjamin Kramer27c769d2018-09-10 12:53:46 +000010#include "MCTargetDesc/PPCMCTargetDesc.h"
Benjamin Kramerf57c1972016-01-26 16:44:37 +000011#include "llvm/MC/MCDisassembler/MCDisassembler.h"
Hal Finkel23453472013-12-19 16:13:01 +000012#include "llvm/MC/MCFixedLenDisassembler.h"
13#include "llvm/MC/MCInst.h"
14#include "llvm/MC/MCSubtargetInfo.h"
Benjamin Kramerc11fd3e2015-07-15 12:56:19 +000015#include "llvm/Support/Endian.h"
Hal Finkel23453472013-12-19 16:13:01 +000016#include "llvm/Support/TargetRegistry.h"
17
18using namespace llvm;
19
Nemanja Ivanovic0dad9942018-12-29 16:13:11 +000020DEFINE_PPC_REGCLASSES;
21
Chandler Carruthe96dd892014-04-21 22:55:11 +000022#define DEBUG_TYPE "ppc-disassembler"
23
Hal Finkel23453472013-12-19 16:13:01 +000024typedef MCDisassembler::DecodeStatus DecodeStatus;
25
26namespace {
27class PPCDisassembler : public MCDisassembler {
Benjamin Kramerc11fd3e2015-07-15 12:56:19 +000028 bool IsLittleEndian;
29
Hal Finkel23453472013-12-19 16:13:01 +000030public:
Benjamin Kramerc11fd3e2015-07-15 12:56:19 +000031 PPCDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
32 bool IsLittleEndian)
33 : MCDisassembler(STI, Ctx), IsLittleEndian(IsLittleEndian) {}
Hal Finkel23453472013-12-19 16:13:01 +000034
Rafael Espindola4aa6bea2014-11-10 18:11:10 +000035 DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
Rafael Espindola7fc5b872014-11-12 02:04:27 +000036 ArrayRef<uint8_t> Bytes, uint64_t Address,
Rafael Espindola4aa6bea2014-11-10 18:11:10 +000037 raw_ostream &VStream,
38 raw_ostream &CStream) const override;
Hal Finkel23453472013-12-19 16:13:01 +000039};
40} // end anonymous namespace
41
42static MCDisassembler *createPPCDisassembler(const Target &T,
Lang Hamesa1bc0f52014-04-15 04:40:56 +000043 const MCSubtargetInfo &STI,
44 MCContext &Ctx) {
Benjamin Kramerc11fd3e2015-07-15 12:56:19 +000045 return new PPCDisassembler(STI, Ctx, /*IsLittleEndian=*/false);
46}
47
48static MCDisassembler *createPPCLEDisassembler(const Target &T,
49 const MCSubtargetInfo &STI,
50 MCContext &Ctx) {
51 return new PPCDisassembler(STI, Ctx, /*IsLittleEndian=*/true);
Hal Finkel23453472013-12-19 16:13:01 +000052}
53
54extern "C" void LLVMInitializePowerPCDisassembler() {
55 // Register the disassembler for each target.
Mehdi Aminif42454b2016-10-09 23:00:34 +000056 TargetRegistry::RegisterMCDisassembler(getThePPC32Target(),
Hal Finkel23453472013-12-19 16:13:01 +000057 createPPCDisassembler);
Mehdi Aminif42454b2016-10-09 23:00:34 +000058 TargetRegistry::RegisterMCDisassembler(getThePPC64Target(),
Hal Finkel23453472013-12-19 16:13:01 +000059 createPPCDisassembler);
Mehdi Aminif42454b2016-10-09 23:00:34 +000060 TargetRegistry::RegisterMCDisassembler(getThePPC64LETarget(),
Benjamin Kramerc11fd3e2015-07-15 12:56:19 +000061 createPPCLEDisassembler);
Hal Finkel23453472013-12-19 16:13:01 +000062}
63
64// FIXME: These can be generated by TableGen from the existing register
65// encoding values!
66
Hal Finkel23453472013-12-19 16:13:01 +000067template <std::size_t N>
68static DecodeStatus decodeRegisterClass(MCInst &Inst, uint64_t RegNo,
Nemanja Ivanovic0dad9942018-12-29 16:13:11 +000069 const MCPhysReg (&Regs)[N]) {
Hal Finkel23453472013-12-19 16:13:01 +000070 assert(RegNo < N && "Invalid register number");
Jim Grosbache9119e42015-05-13 18:37:00 +000071 Inst.addOperand(MCOperand::createReg(Regs[RegNo]));
Hal Finkel23453472013-12-19 16:13:01 +000072 return MCDisassembler::Success;
73}
74
75static DecodeStatus DecodeCRRCRegisterClass(MCInst &Inst, uint64_t RegNo,
76 uint64_t Address,
77 const void *Decoder) {
78 return decodeRegisterClass(Inst, RegNo, CRRegs);
79}
80
Kit Barton535e69d2015-03-25 19:36:23 +000081static DecodeStatus DecodeCRRC0RegisterClass(MCInst &Inst, uint64_t RegNo,
82 uint64_t Address,
83 const void *Decoder) {
84 return decodeRegisterClass(Inst, RegNo, CRRegs);
85}
86
Hal Finkel23453472013-12-19 16:13:01 +000087static DecodeStatus DecodeCRBITRCRegisterClass(MCInst &Inst, uint64_t RegNo,
88 uint64_t Address,
89 const void *Decoder) {
90 return decodeRegisterClass(Inst, RegNo, CRBITRegs);
91}
92
93static DecodeStatus DecodeF4RCRegisterClass(MCInst &Inst, uint64_t RegNo,
94 uint64_t Address,
95 const void *Decoder) {
96 return decodeRegisterClass(Inst, RegNo, FRegs);
97}
98
99static DecodeStatus DecodeF8RCRegisterClass(MCInst &Inst, uint64_t RegNo,
100 uint64_t Address,
101 const void *Decoder) {
102 return decodeRegisterClass(Inst, RegNo, FRegs);
103}
104
Nemanja Ivanovic11049f82016-10-04 06:59:23 +0000105static DecodeStatus DecodeVFRCRegisterClass(MCInst &Inst, uint64_t RegNo,
106 uint64_t Address,
107 const void *Decoder) {
108 return decodeRegisterClass(Inst, RegNo, VFRegs);
109}
110
Hal Finkel23453472013-12-19 16:13:01 +0000111static DecodeStatus DecodeVRRCRegisterClass(MCInst &Inst, uint64_t RegNo,
112 uint64_t Address,
113 const void *Decoder) {
114 return decodeRegisterClass(Inst, RegNo, VRegs);
115}
116
Hal Finkel27774d92014-03-13 07:58:58 +0000117static DecodeStatus DecodeVSRCRegisterClass(MCInst &Inst, uint64_t RegNo,
118 uint64_t Address,
119 const void *Decoder) {
120 return decodeRegisterClass(Inst, RegNo, VSRegs);
121}
122
Hal Finkel19be5062014-03-29 05:29:01 +0000123static DecodeStatus DecodeVSFRCRegisterClass(MCInst &Inst, uint64_t RegNo,
124 uint64_t Address,
125 const void *Decoder) {
126 return decodeRegisterClass(Inst, RegNo, VSFRegs);
127}
128
Nemanja Ivanovicf3c94b12015-05-07 18:24:05 +0000129static DecodeStatus DecodeVSSRCRegisterClass(MCInst &Inst, uint64_t RegNo,
130 uint64_t Address,
131 const void *Decoder) {
132 return decodeRegisterClass(Inst, RegNo, VSSRegs);
133}
134
Hal Finkel23453472013-12-19 16:13:01 +0000135static DecodeStatus DecodeGPRCRegisterClass(MCInst &Inst, uint64_t RegNo,
136 uint64_t Address,
137 const void *Decoder) {
Nemanja Ivanovic0dad9942018-12-29 16:13:11 +0000138 return decodeRegisterClass(Inst, RegNo, RRegs);
Hal Finkel23453472013-12-19 16:13:01 +0000139}
140
141static DecodeStatus DecodeGPRC_NOR0RegisterClass(MCInst &Inst, uint64_t RegNo,
142 uint64_t Address,
143 const void *Decoder) {
Nemanja Ivanovic0dad9942018-12-29 16:13:11 +0000144 return decodeRegisterClass(Inst, RegNo, RRegsNoR0);
Hal Finkel23453472013-12-19 16:13:01 +0000145}
146
147static DecodeStatus DecodeG8RCRegisterClass(MCInst &Inst, uint64_t RegNo,
148 uint64_t Address,
149 const void *Decoder) {
Nemanja Ivanovic0dad9942018-12-29 16:13:11 +0000150 return decodeRegisterClass(Inst, RegNo, XRegs);
Hal Finkel23453472013-12-19 16:13:01 +0000151}
152
Guozhi Wei22e7da92017-05-11 22:17:35 +0000153static DecodeStatus DecodeG8RC_NOX0RegisterClass(MCInst &Inst, uint64_t RegNo,
154 uint64_t Address,
155 const void *Decoder) {
Nemanja Ivanovic0dad9942018-12-29 16:13:11 +0000156 return decodeRegisterClass(Inst, RegNo, XRegsNoX0);
Guozhi Wei22e7da92017-05-11 22:17:35 +0000157}
158
Hal Finkel23453472013-12-19 16:13:01 +0000159#define DecodePointerLikeRegClass0 DecodeGPRCRegisterClass
160#define DecodePointerLikeRegClass1 DecodeGPRC_NOR0RegisterClass
161
Hal Finkelc93a9a22015-02-25 01:06:45 +0000162static DecodeStatus DecodeQFRCRegisterClass(MCInst &Inst, uint64_t RegNo,
163 uint64_t Address,
164 const void *Decoder) {
165 return decodeRegisterClass(Inst, RegNo, QFRegs);
166}
167
Justin Hibbitsd52990c2018-07-18 04:25:10 +0000168static DecodeStatus DecodeSPE4RCRegisterClass(MCInst &Inst, uint64_t RegNo,
169 uint64_t Address,
170 const void *Decoder) {
Nemanja Ivanovic0dad9942018-12-29 16:13:11 +0000171 return decodeRegisterClass(Inst, RegNo, RRegs);
Justin Hibbitsd52990c2018-07-18 04:25:10 +0000172}
173
174static DecodeStatus DecodeSPERCRegisterClass(MCInst &Inst, uint64_t RegNo,
175 uint64_t Address,
176 const void *Decoder) {
177 return decodeRegisterClass(Inst, RegNo, SPERegs);
178}
179
Hal Finkelc93a9a22015-02-25 01:06:45 +0000180#define DecodeQSRCRegisterClass DecodeQFRCRegisterClass
181#define DecodeQBRCRegisterClass DecodeQFRCRegisterClass
182
Hal Finkel23453472013-12-19 16:13:01 +0000183template<unsigned N>
184static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm,
185 int64_t Address, const void *Decoder) {
186 assert(isUInt<N>(Imm) && "Invalid immediate");
Jim Grosbache9119e42015-05-13 18:37:00 +0000187 Inst.addOperand(MCOperand::createImm(Imm));
Hal Finkel23453472013-12-19 16:13:01 +0000188 return MCDisassembler::Success;
189}
190
191template<unsigned N>
192static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm,
193 int64_t Address, const void *Decoder) {
194 assert(isUInt<N>(Imm) && "Invalid immediate");
Jim Grosbache9119e42015-05-13 18:37:00 +0000195 Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm)));
Hal Finkel23453472013-12-19 16:13:01 +0000196 return MCDisassembler::Success;
197}
198
199static 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.
Nemanja Ivanovic0dad9942018-12-29 16:13:11 +0000218 Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
Hal Finkel23453472013-12-19 16:13:01 +0000219 break;
220 case PPC::STBU:
221 case PPC::STHU:
222 case PPC::STWU:
223 case PPC::STFSU:
224 case PPC::STFDU:
Nemanja Ivanovic0dad9942018-12-29 16:13:11 +0000225 Inst.insert(Inst.begin(), MCOperand::createReg(RRegsNoR0[Base]));
Hal Finkel23453472013-12-19 16:13:01 +0000226 break;
227 }
228
Jim Grosbache9119e42015-05-13 18:37:00 +0000229 Inst.addOperand(MCOperand::createImm(SignExtend64<16>(Disp)));
Nemanja Ivanovic0dad9942018-12-29 16:13:11 +0000230 Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
Hal Finkel23453472013-12-19 16:13:01 +0000231 return MCDisassembler::Success;
232}
233
234static 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.
Nemanja Ivanovic0dad9942018-12-29 16:13:11 +0000246 Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
Hal Finkel23453472013-12-19 16:13:01 +0000247 else if (Inst.getOpcode() == PPC::STDU)
Nemanja Ivanovic0dad9942018-12-29 16:13:11 +0000248 Inst.insert(Inst.begin(), MCOperand::createReg(RRegsNoR0[Base]));
Hal Finkel23453472013-12-19 16:13:01 +0000249
Jim Grosbache9119e42015-05-13 18:37:00 +0000250 Inst.addOperand(MCOperand::createImm(SignExtend64<16>(Disp << 2)));
Nemanja Ivanovic0dad9942018-12-29 16:13:11 +0000251 Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
Hal Finkel23453472013-12-19 16:13:01 +0000252 return MCDisassembler::Success;
253}
254
Kit Bartonba532dc2016-03-08 03:49:13 +0000255static 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)));
Nemanja Ivanovic0dad9942018-12-29 16:13:11 +0000266 Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
Kit Bartonba532dc2016-03-08 03:49:13 +0000267 return MCDisassembler::Success;
268}
269
Justin Hibbits4fa4fa62018-07-18 04:24:57 +0000270static 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));
Nemanja Ivanovic0dad9942018-12-29 16:13:11 +0000281 Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
Justin Hibbits4fa4fa62018-07-18 04:24:57 +0000282 return MCDisassembler::Success;
283}
284
285static 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));
Nemanja Ivanovic0dad9942018-12-29 16:13:11 +0000296 Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
Justin Hibbits4fa4fa62018-07-18 04:24:57 +0000297 return MCDisassembler::Success;
298}
299
300static 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));
Nemanja Ivanovic0dad9942018-12-29 16:13:11 +0000311 Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
Justin Hibbits4fa4fa62018-07-18 04:24:57 +0000312 return MCDisassembler::Success;
313}
314
Hal Finkel23453472013-12-19 16:13:01 +0000315static 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
Jim Grosbache9119e42015-05-13 18:37:00 +0000322 Inst.addOperand(MCOperand::createReg(CRRegs[7 - Zeros]));
Hal Finkel23453472013-12-19 16:13:01 +0000323 return MCDisassembler::Success;
324}
325
326#include "PPCGenDisassemblerTables.inc"
327
328DecodeStatus PPCDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
Rafael Espindola7fc5b872014-11-12 02:04:27 +0000329 ArrayRef<uint8_t> Bytes,
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000330 uint64_t Address, raw_ostream &OS,
331 raw_ostream &CS) const {
Hal Finkel23453472013-12-19 16:13:01 +0000332 // Get the four bytes of the instruction.
Hal Finkel23453472013-12-19 16:13:01 +0000333 Size = 4;
Rafael Espindola7fc5b872014-11-12 02:04:27 +0000334 if (Bytes.size() < 4) {
Hal Finkel23453472013-12-19 16:13:01 +0000335 Size = 0;
336 return MCDisassembler::Fail;
337 }
338
Benjamin Kramerc11fd3e2015-07-15 12:56:19 +0000339 // Read the instruction in the proper endianness.
340 uint32_t Inst = IsLittleEndian ? support::endian::read32le(Bytes.data())
341 : support::endian::read32be(Bytes.data());
Hal Finkel23453472013-12-19 16:13:01 +0000342
Michael Kupersteindb0712f2015-05-26 10:47:10 +0000343 if (STI.getFeatureBits()[PPC::FeatureQPX]) {
Hal Finkelc93a9a22015-02-25 01:06:45 +0000344 DecodeStatus result =
345 decodeInstruction(DecoderTableQPX32, MI, Inst, Address, this, STI);
346 if (result != MCDisassembler::Fail)
347 return result;
Justin Hibbits4fa4fa62018-07-18 04:24:57 +0000348 } 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;
Hal Finkelc93a9a22015-02-25 01:06:45 +0000353 }
354
Hal Finkel23453472013-12-19 16:13:01 +0000355 return decodeInstruction(DecoderTable32, MI, Inst, Address, this, STI);
356}
357