blob: 8f96951e26971fea427342f18147378301a3b0d9 [file] [log] [blame]
Hal Finkel23453472013-12-19 16:13:01 +00001//===------ PPCDisassembler.cpp - Disassembler for PowerPC ------*- C++ -*-===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Hal Finkel23453472013-12-19 16:13:01 +00006//
7//===----------------------------------------------------------------------===//
8
Benjamin Kramer27c769d2018-09-10 12:53:46 +00009#include "MCTargetDesc/PPCMCTargetDesc.h"
Benjamin Kramerf57c1972016-01-26 16:44:37 +000010#include "llvm/MC/MCDisassembler/MCDisassembler.h"
Hal Finkel23453472013-12-19 16:13:01 +000011#include "llvm/MC/MCFixedLenDisassembler.h"
12#include "llvm/MC/MCInst.h"
13#include "llvm/MC/MCSubtargetInfo.h"
Benjamin Kramerc11fd3e2015-07-15 12:56:19 +000014#include "llvm/Support/Endian.h"
Hal Finkel23453472013-12-19 16:13:01 +000015#include "llvm/Support/TargetRegistry.h"
16
17using namespace llvm;
18
Nemanja Ivanovic0dad9942018-12-29 16:13:11 +000019DEFINE_PPC_REGCLASSES;
20
Chandler Carruthe96dd892014-04-21 22:55:11 +000021#define DEBUG_TYPE "ppc-disassembler"
22
Hal Finkel23453472013-12-19 16:13:01 +000023typedef MCDisassembler::DecodeStatus DecodeStatus;
24
25namespace {
26class PPCDisassembler : public MCDisassembler {
Benjamin Kramerc11fd3e2015-07-15 12:56:19 +000027 bool IsLittleEndian;
28
Hal Finkel23453472013-12-19 16:13:01 +000029public:
Benjamin Kramerc11fd3e2015-07-15 12:56:19 +000030 PPCDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
31 bool IsLittleEndian)
32 : MCDisassembler(STI, Ctx), IsLittleEndian(IsLittleEndian) {}
Hal Finkel23453472013-12-19 16:13:01 +000033
Rafael Espindola4aa6bea2014-11-10 18:11:10 +000034 DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
Rafael Espindola7fc5b872014-11-12 02:04:27 +000035 ArrayRef<uint8_t> Bytes, uint64_t Address,
Rafael Espindola4aa6bea2014-11-10 18:11:10 +000036 raw_ostream &VStream,
37 raw_ostream &CStream) const override;
Hal Finkel23453472013-12-19 16:13:01 +000038};
39} // end anonymous namespace
40
41static MCDisassembler *createPPCDisassembler(const Target &T,
Lang Hamesa1bc0f52014-04-15 04:40:56 +000042 const MCSubtargetInfo &STI,
43 MCContext &Ctx) {
Benjamin Kramerc11fd3e2015-07-15 12:56:19 +000044 return new PPCDisassembler(STI, Ctx, /*IsLittleEndian=*/false);
45}
46
47static MCDisassembler *createPPCLEDisassembler(const Target &T,
48 const MCSubtargetInfo &STI,
49 MCContext &Ctx) {
50 return new PPCDisassembler(STI, Ctx, /*IsLittleEndian=*/true);
Hal Finkel23453472013-12-19 16:13:01 +000051}
52
53extern "C" void LLVMInitializePowerPCDisassembler() {
54 // Register the disassembler for each target.
Mehdi Aminif42454b2016-10-09 23:00:34 +000055 TargetRegistry::RegisterMCDisassembler(getThePPC32Target(),
Hal Finkel23453472013-12-19 16:13:01 +000056 createPPCDisassembler);
Mehdi Aminif42454b2016-10-09 23:00:34 +000057 TargetRegistry::RegisterMCDisassembler(getThePPC64Target(),
Hal Finkel23453472013-12-19 16:13:01 +000058 createPPCDisassembler);
Mehdi Aminif42454b2016-10-09 23:00:34 +000059 TargetRegistry::RegisterMCDisassembler(getThePPC64LETarget(),
Benjamin Kramerc11fd3e2015-07-15 12:56:19 +000060 createPPCLEDisassembler);
Hal Finkel23453472013-12-19 16:13:01 +000061}
62
63// FIXME: These can be generated by TableGen from the existing register
64// encoding values!
65
Hal Finkel23453472013-12-19 16:13:01 +000066template <std::size_t N>
67static DecodeStatus decodeRegisterClass(MCInst &Inst, uint64_t RegNo,
Nemanja Ivanovic0dad9942018-12-29 16:13:11 +000068 const MCPhysReg (&Regs)[N]) {
Hal Finkel23453472013-12-19 16:13:01 +000069 assert(RegNo < N && "Invalid register number");
Jim Grosbache9119e42015-05-13 18:37:00 +000070 Inst.addOperand(MCOperand::createReg(Regs[RegNo]));
Hal Finkel23453472013-12-19 16:13:01 +000071 return MCDisassembler::Success;
72}
73
74static DecodeStatus DecodeCRRCRegisterClass(MCInst &Inst, uint64_t RegNo,
75 uint64_t Address,
76 const void *Decoder) {
77 return decodeRegisterClass(Inst, RegNo, CRRegs);
78}
79
Kit Barton535e69d2015-03-25 19:36:23 +000080static DecodeStatus DecodeCRRC0RegisterClass(MCInst &Inst, uint64_t RegNo,
81 uint64_t Address,
82 const void *Decoder) {
83 return decodeRegisterClass(Inst, RegNo, CRRegs);
84}
85
Hal Finkel23453472013-12-19 16:13:01 +000086static DecodeStatus DecodeCRBITRCRegisterClass(MCInst &Inst, uint64_t RegNo,
87 uint64_t Address,
88 const void *Decoder) {
89 return decodeRegisterClass(Inst, RegNo, CRBITRegs);
90}
91
92static DecodeStatus DecodeF4RCRegisterClass(MCInst &Inst, uint64_t RegNo,
93 uint64_t Address,
94 const void *Decoder) {
95 return decodeRegisterClass(Inst, RegNo, FRegs);
96}
97
98static DecodeStatus DecodeF8RCRegisterClass(MCInst &Inst, uint64_t RegNo,
99 uint64_t Address,
100 const void *Decoder) {
101 return decodeRegisterClass(Inst, RegNo, FRegs);
102}
103
Nemanja Ivanovic11049f82016-10-04 06:59:23 +0000104static DecodeStatus DecodeVFRCRegisterClass(MCInst &Inst, uint64_t RegNo,
105 uint64_t Address,
106 const void *Decoder) {
107 return decodeRegisterClass(Inst, RegNo, VFRegs);
108}
109
Hal Finkel23453472013-12-19 16:13:01 +0000110static DecodeStatus DecodeVRRCRegisterClass(MCInst &Inst, uint64_t RegNo,
111 uint64_t Address,
112 const void *Decoder) {
113 return decodeRegisterClass(Inst, RegNo, VRegs);
114}
115
Hal Finkel27774d92014-03-13 07:58:58 +0000116static DecodeStatus DecodeVSRCRegisterClass(MCInst &Inst, uint64_t RegNo,
117 uint64_t Address,
118 const void *Decoder) {
119 return decodeRegisterClass(Inst, RegNo, VSRegs);
120}
121
Hal Finkel19be5062014-03-29 05:29:01 +0000122static DecodeStatus DecodeVSFRCRegisterClass(MCInst &Inst, uint64_t RegNo,
123 uint64_t Address,
124 const void *Decoder) {
125 return decodeRegisterClass(Inst, RegNo, VSFRegs);
126}
127
Nemanja Ivanovicf3c94b12015-05-07 18:24:05 +0000128static DecodeStatus DecodeVSSRCRegisterClass(MCInst &Inst, uint64_t RegNo,
129 uint64_t Address,
130 const void *Decoder) {
131 return decodeRegisterClass(Inst, RegNo, VSSRegs);
132}
133
Hal Finkel23453472013-12-19 16:13:01 +0000134static DecodeStatus DecodeGPRCRegisterClass(MCInst &Inst, uint64_t RegNo,
135 uint64_t Address,
136 const void *Decoder) {
Nemanja Ivanovic0dad9942018-12-29 16:13:11 +0000137 return decodeRegisterClass(Inst, RegNo, RRegs);
Hal Finkel23453472013-12-19 16:13:01 +0000138}
139
140static DecodeStatus DecodeGPRC_NOR0RegisterClass(MCInst &Inst, uint64_t RegNo,
141 uint64_t Address,
142 const void *Decoder) {
Nemanja Ivanovic0dad9942018-12-29 16:13:11 +0000143 return decodeRegisterClass(Inst, RegNo, RRegsNoR0);
Hal Finkel23453472013-12-19 16:13:01 +0000144}
145
146static DecodeStatus DecodeG8RCRegisterClass(MCInst &Inst, uint64_t RegNo,
147 uint64_t Address,
148 const void *Decoder) {
Nemanja Ivanovic0dad9942018-12-29 16:13:11 +0000149 return decodeRegisterClass(Inst, RegNo, XRegs);
Hal Finkel23453472013-12-19 16:13:01 +0000150}
151
Guozhi Wei22e7da92017-05-11 22:17:35 +0000152static DecodeStatus DecodeG8RC_NOX0RegisterClass(MCInst &Inst, uint64_t RegNo,
153 uint64_t Address,
154 const void *Decoder) {
Nemanja Ivanovic0dad9942018-12-29 16:13:11 +0000155 return decodeRegisterClass(Inst, RegNo, XRegsNoX0);
Guozhi Wei22e7da92017-05-11 22:17:35 +0000156}
157
Hal Finkel23453472013-12-19 16:13:01 +0000158#define DecodePointerLikeRegClass0 DecodeGPRCRegisterClass
159#define DecodePointerLikeRegClass1 DecodeGPRC_NOR0RegisterClass
160
Hal Finkelc93a9a22015-02-25 01:06:45 +0000161static DecodeStatus DecodeQFRCRegisterClass(MCInst &Inst, uint64_t RegNo,
162 uint64_t Address,
163 const void *Decoder) {
164 return decodeRegisterClass(Inst, RegNo, QFRegs);
165}
166
Justin Hibbitsd52990c2018-07-18 04:25:10 +0000167static DecodeStatus DecodeSPE4RCRegisterClass(MCInst &Inst, uint64_t RegNo,
168 uint64_t Address,
169 const void *Decoder) {
Nemanja Ivanovic0dad9942018-12-29 16:13:11 +0000170 return decodeRegisterClass(Inst, RegNo, RRegs);
Justin Hibbitsd52990c2018-07-18 04:25:10 +0000171}
172
173static DecodeStatus DecodeSPERCRegisterClass(MCInst &Inst, uint64_t RegNo,
174 uint64_t Address,
175 const void *Decoder) {
176 return decodeRegisterClass(Inst, RegNo, SPERegs);
177}
178
Hal Finkelc93a9a22015-02-25 01:06:45 +0000179#define DecodeQSRCRegisterClass DecodeQFRCRegisterClass
180#define DecodeQBRCRegisterClass DecodeQFRCRegisterClass
181
Hal Finkel23453472013-12-19 16:13:01 +0000182template<unsigned N>
183static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm,
184 int64_t Address, const void *Decoder) {
185 assert(isUInt<N>(Imm) && "Invalid immediate");
Jim Grosbache9119e42015-05-13 18:37:00 +0000186 Inst.addOperand(MCOperand::createImm(Imm));
Hal Finkel23453472013-12-19 16:13:01 +0000187 return MCDisassembler::Success;
188}
189
190template<unsigned N>
191static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm,
192 int64_t Address, const void *Decoder) {
193 assert(isUInt<N>(Imm) && "Invalid immediate");
Jim Grosbache9119e42015-05-13 18:37:00 +0000194 Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm)));
Hal Finkel23453472013-12-19 16:13:01 +0000195 return MCDisassembler::Success;
196}
197
198static DecodeStatus decodeMemRIOperands(MCInst &Inst, uint64_t Imm,
199 int64_t Address, const void *Decoder) {
200 // Decode the memri field (imm, reg), which has the low 16-bits as the
201 // displacement and the next 5 bits as the register #.
202
203 uint64_t Base = Imm >> 16;
204 uint64_t Disp = Imm & 0xFFFF;
205
206 assert(Base < 32 && "Invalid base register");
207
208 switch (Inst.getOpcode()) {
209 default: break;
210 case PPC::LBZU:
211 case PPC::LHAU:
212 case PPC::LHZU:
213 case PPC::LWZU:
214 case PPC::LFSU:
215 case PPC::LFDU:
216 // Add the tied output operand.
Nemanja Ivanovic0dad9942018-12-29 16:13:11 +0000217 Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
Hal Finkel23453472013-12-19 16:13:01 +0000218 break;
219 case PPC::STBU:
220 case PPC::STHU:
221 case PPC::STWU:
222 case PPC::STFSU:
223 case PPC::STFDU:
Nemanja Ivanovic0dad9942018-12-29 16:13:11 +0000224 Inst.insert(Inst.begin(), MCOperand::createReg(RRegsNoR0[Base]));
Hal Finkel23453472013-12-19 16:13:01 +0000225 break;
226 }
227
Jim Grosbache9119e42015-05-13 18:37:00 +0000228 Inst.addOperand(MCOperand::createImm(SignExtend64<16>(Disp)));
Nemanja Ivanovic0dad9942018-12-29 16:13:11 +0000229 Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
Hal Finkel23453472013-12-19 16:13:01 +0000230 return MCDisassembler::Success;
231}
232
233static DecodeStatus decodeMemRIXOperands(MCInst &Inst, uint64_t Imm,
234 int64_t Address, const void *Decoder) {
235 // Decode the memrix field (imm, reg), which has the low 14-bits as the
236 // displacement and the next 5 bits as the register #.
237
238 uint64_t Base = Imm >> 14;
239 uint64_t Disp = Imm & 0x3FFF;
240
241 assert(Base < 32 && "Invalid base register");
242
243 if (Inst.getOpcode() == PPC::LDU)
244 // Add the tied output operand.
Nemanja Ivanovic0dad9942018-12-29 16:13:11 +0000245 Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
Hal Finkel23453472013-12-19 16:13:01 +0000246 else if (Inst.getOpcode() == PPC::STDU)
Nemanja Ivanovic0dad9942018-12-29 16:13:11 +0000247 Inst.insert(Inst.begin(), MCOperand::createReg(RRegsNoR0[Base]));
Hal Finkel23453472013-12-19 16:13:01 +0000248
Jim Grosbache9119e42015-05-13 18:37:00 +0000249 Inst.addOperand(MCOperand::createImm(SignExtend64<16>(Disp << 2)));
Nemanja Ivanovic0dad9942018-12-29 16:13:11 +0000250 Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
Hal Finkel23453472013-12-19 16:13:01 +0000251 return MCDisassembler::Success;
252}
253
Kit Bartonba532dc2016-03-08 03:49:13 +0000254static DecodeStatus decodeMemRIX16Operands(MCInst &Inst, uint64_t Imm,
255 int64_t Address, const void *Decoder) {
256 // Decode the memrix16 field (imm, reg), which has the low 12-bits as the
257 // displacement with 16-byte aligned, and the next 5 bits as the register #.
258
259 uint64_t Base = Imm >> 12;
260 uint64_t Disp = Imm & 0xFFF;
261
262 assert(Base < 32 && "Invalid base register");
263
264 Inst.addOperand(MCOperand::createImm(SignExtend64<16>(Disp << 4)));
Nemanja Ivanovic0dad9942018-12-29 16:13:11 +0000265 Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
Kit Bartonba532dc2016-03-08 03:49:13 +0000266 return MCDisassembler::Success;
267}
268
Justin Hibbits4fa4fa62018-07-18 04:24:57 +0000269static DecodeStatus decodeSPE8Operands(MCInst &Inst, uint64_t Imm,
270 int64_t Address, const void *Decoder) {
271 // Decode the spe8disp field (imm, reg), which has the low 5-bits as the
272 // displacement with 8-byte aligned, and the next 5 bits as the register #.
273
274 uint64_t Base = Imm >> 5;
275 uint64_t Disp = Imm & 0x1F;
276
277 assert(Base < 32 && "Invalid base register");
278
279 Inst.addOperand(MCOperand::createImm(Disp << 3));
Nemanja Ivanovic0dad9942018-12-29 16:13:11 +0000280 Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
Justin Hibbits4fa4fa62018-07-18 04:24:57 +0000281 return MCDisassembler::Success;
282}
283
284static DecodeStatus decodeSPE4Operands(MCInst &Inst, uint64_t Imm,
285 int64_t Address, const void *Decoder) {
286 // Decode the spe4disp field (imm, reg), which has the low 5-bits as the
287 // displacement with 4-byte aligned, and the next 5 bits as the register #.
288
289 uint64_t Base = Imm >> 5;
290 uint64_t Disp = Imm & 0x1F;
291
292 assert(Base < 32 && "Invalid base register");
293
294 Inst.addOperand(MCOperand::createImm(Disp << 2));
Nemanja Ivanovic0dad9942018-12-29 16:13:11 +0000295 Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
Justin Hibbits4fa4fa62018-07-18 04:24:57 +0000296 return MCDisassembler::Success;
297}
298
299static DecodeStatus decodeSPE2Operands(MCInst &Inst, uint64_t Imm,
300 int64_t Address, const void *Decoder) {
301 // Decode the spe2disp field (imm, reg), which has the low 5-bits as the
302 // displacement with 2-byte aligned, and the next 5 bits as the register #.
303
304 uint64_t Base = Imm >> 5;
305 uint64_t Disp = Imm & 0x1F;
306
307 assert(Base < 32 && "Invalid base register");
308
309 Inst.addOperand(MCOperand::createImm(Disp << 1));
Nemanja Ivanovic0dad9942018-12-29 16:13:11 +0000310 Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
Justin Hibbits4fa4fa62018-07-18 04:24:57 +0000311 return MCDisassembler::Success;
312}
313
Hal Finkel23453472013-12-19 16:13:01 +0000314static DecodeStatus decodeCRBitMOperand(MCInst &Inst, uint64_t Imm,
315 int64_t Address, const void *Decoder) {
316 // The cr bit encoding is 0x80 >> cr_reg_num.
317
318 unsigned Zeros = countTrailingZeros(Imm);
319 assert(Zeros < 8 && "Invalid CR bit value");
320
Jim Grosbache9119e42015-05-13 18:37:00 +0000321 Inst.addOperand(MCOperand::createReg(CRRegs[7 - Zeros]));
Hal Finkel23453472013-12-19 16:13:01 +0000322 return MCDisassembler::Success;
323}
324
325#include "PPCGenDisassemblerTables.inc"
326
327DecodeStatus PPCDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
Rafael Espindola7fc5b872014-11-12 02:04:27 +0000328 ArrayRef<uint8_t> Bytes,
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000329 uint64_t Address, raw_ostream &OS,
330 raw_ostream &CS) const {
Hal Finkel23453472013-12-19 16:13:01 +0000331 // Get the four bytes of the instruction.
Hal Finkel23453472013-12-19 16:13:01 +0000332 Size = 4;
Rafael Espindola7fc5b872014-11-12 02:04:27 +0000333 if (Bytes.size() < 4) {
Hal Finkel23453472013-12-19 16:13:01 +0000334 Size = 0;
335 return MCDisassembler::Fail;
336 }
337
Benjamin Kramerc11fd3e2015-07-15 12:56:19 +0000338 // Read the instruction in the proper endianness.
339 uint32_t Inst = IsLittleEndian ? support::endian::read32le(Bytes.data())
340 : support::endian::read32be(Bytes.data());
Hal Finkel23453472013-12-19 16:13:01 +0000341
Michael Kupersteindb0712f2015-05-26 10:47:10 +0000342 if (STI.getFeatureBits()[PPC::FeatureQPX]) {
Hal Finkelc93a9a22015-02-25 01:06:45 +0000343 DecodeStatus result =
344 decodeInstruction(DecoderTableQPX32, MI, Inst, Address, this, STI);
345 if (result != MCDisassembler::Fail)
346 return result;
Justin Hibbits4fa4fa62018-07-18 04:24:57 +0000347 } else if (STI.getFeatureBits()[PPC::FeatureSPE]) {
348 DecodeStatus result =
349 decodeInstruction(DecoderTableSPE32, MI, Inst, Address, this, STI);
350 if (result != MCDisassembler::Fail)
351 return result;
Hal Finkelc93a9a22015-02-25 01:06:45 +0000352 }
353
Hal Finkel23453472013-12-19 16:13:01 +0000354 return decodeInstruction(DecoderTable32, MI, Inst, Address, this, STI);
355}
356