1 //===------ PPCDisassembler.cpp - Disassembler for PowerPC ------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
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"
20 DEFINE_PPC_REGCLASSES
;
22 #define DEBUG_TYPE "ppc-disassembler"
24 typedef MCDisassembler::DecodeStatus DecodeStatus
;
27 class PPCDisassembler
: public MCDisassembler
{
31 PPCDisassembler(const MCSubtargetInfo
&STI
, MCContext
&Ctx
,
33 : MCDisassembler(STI
, Ctx
), IsLittleEndian(IsLittleEndian
) {}
35 DecodeStatus
getInstruction(MCInst
&Instr
, uint64_t &Size
,
36 ArrayRef
<uint8_t> Bytes
, uint64_t Address
,
38 raw_ostream
&CStream
) const override
;
40 } // end anonymous namespace
42 static MCDisassembler
*createPPCDisassembler(const Target
&T
,
43 const MCSubtargetInfo
&STI
,
45 return new PPCDisassembler(STI
, Ctx
, /*IsLittleEndian=*/false);
48 static MCDisassembler
*createPPCLEDisassembler(const Target
&T
,
49 const MCSubtargetInfo
&STI
,
51 return new PPCDisassembler(STI
, Ctx
, /*IsLittleEndian=*/true);
54 extern "C" void LLVMInitializePowerPCDisassembler() {
55 // Register the disassembler for each target.
56 TargetRegistry::RegisterMCDisassembler(getThePPC32Target(),
57 createPPCDisassembler
);
58 TargetRegistry::RegisterMCDisassembler(getThePPC64Target(),
59 createPPCDisassembler
);
60 TargetRegistry::RegisterMCDisassembler(getThePPC64LETarget(),
61 createPPCLEDisassembler
);
64 static DecodeStatus
DecodePCRel24BranchTarget(MCInst
&Inst
, unsigned Imm
,
66 const void *Decoder
) {
67 int32_t Offset
= SignExtend32
<24>(Imm
);
68 Inst
.addOperand(MCOperand::createImm(Offset
));
69 return MCDisassembler::Success
;
72 // FIXME: These can be generated by TableGen from the existing register
75 template <std::size_t N
>
76 static DecodeStatus
decodeRegisterClass(MCInst
&Inst
, uint64_t RegNo
,
77 const MCPhysReg (&Regs
)[N
]) {
78 assert(RegNo
< N
&& "Invalid register number");
79 Inst
.addOperand(MCOperand::createReg(Regs
[RegNo
]));
80 return MCDisassembler::Success
;
83 static DecodeStatus
DecodeCRRCRegisterClass(MCInst
&Inst
, uint64_t RegNo
,
85 const void *Decoder
) {
86 return decodeRegisterClass(Inst
, RegNo
, CRRegs
);
89 static DecodeStatus
DecodeCRBITRCRegisterClass(MCInst
&Inst
, uint64_t RegNo
,
91 const void *Decoder
) {
92 return decodeRegisterClass(Inst
, RegNo
, CRBITRegs
);
95 static DecodeStatus
DecodeF4RCRegisterClass(MCInst
&Inst
, uint64_t RegNo
,
97 const void *Decoder
) {
98 return decodeRegisterClass(Inst
, RegNo
, FRegs
);
101 static DecodeStatus
DecodeF8RCRegisterClass(MCInst
&Inst
, uint64_t RegNo
,
103 const void *Decoder
) {
104 return decodeRegisterClass(Inst
, RegNo
, FRegs
);
107 static DecodeStatus
DecodeVFRCRegisterClass(MCInst
&Inst
, uint64_t RegNo
,
109 const void *Decoder
) {
110 return decodeRegisterClass(Inst
, RegNo
, VFRegs
);
113 static DecodeStatus
DecodeVRRCRegisterClass(MCInst
&Inst
, uint64_t RegNo
,
115 const void *Decoder
) {
116 return decodeRegisterClass(Inst
, RegNo
, VRegs
);
119 static DecodeStatus
DecodeVSRCRegisterClass(MCInst
&Inst
, uint64_t RegNo
,
121 const void *Decoder
) {
122 return decodeRegisterClass(Inst
, RegNo
, VSRegs
);
125 static DecodeStatus
DecodeVSFRCRegisterClass(MCInst
&Inst
, uint64_t RegNo
,
127 const void *Decoder
) {
128 return decodeRegisterClass(Inst
, RegNo
, VSFRegs
);
131 static DecodeStatus
DecodeVSSRCRegisterClass(MCInst
&Inst
, uint64_t RegNo
,
133 const void *Decoder
) {
134 return decodeRegisterClass(Inst
, RegNo
, VSSRegs
);
137 static DecodeStatus
DecodeGPRCRegisterClass(MCInst
&Inst
, uint64_t RegNo
,
139 const void *Decoder
) {
140 return decodeRegisterClass(Inst
, RegNo
, RRegs
);
143 static DecodeStatus
DecodeGPRC_NOR0RegisterClass(MCInst
&Inst
, uint64_t RegNo
,
145 const void *Decoder
) {
146 return decodeRegisterClass(Inst
, RegNo
, RRegsNoR0
);
149 static DecodeStatus
DecodeG8RCRegisterClass(MCInst
&Inst
, uint64_t RegNo
,
151 const void *Decoder
) {
152 return decodeRegisterClass(Inst
, RegNo
, XRegs
);
155 static DecodeStatus
DecodeG8RC_NOX0RegisterClass(MCInst
&Inst
, uint64_t RegNo
,
157 const void *Decoder
) {
158 return decodeRegisterClass(Inst
, RegNo
, XRegsNoX0
);
161 #define DecodePointerLikeRegClass0 DecodeGPRCRegisterClass
162 #define DecodePointerLikeRegClass1 DecodeGPRC_NOR0RegisterClass
164 static DecodeStatus
DecodeQFRCRegisterClass(MCInst
&Inst
, uint64_t RegNo
,
166 const void *Decoder
) {
167 return decodeRegisterClass(Inst
, RegNo
, QFRegs
);
170 static DecodeStatus
DecodeSPE4RCRegisterClass(MCInst
&Inst
, uint64_t RegNo
,
172 const void *Decoder
) {
173 return decodeRegisterClass(Inst
, RegNo
, RRegs
);
176 static DecodeStatus
DecodeSPERCRegisterClass(MCInst
&Inst
, uint64_t RegNo
,
178 const void *Decoder
) {
179 return decodeRegisterClass(Inst
, RegNo
, SPERegs
);
182 #define DecodeQSRCRegisterClass DecodeQFRCRegisterClass
183 #define DecodeQBRCRegisterClass DecodeQFRCRegisterClass
186 static DecodeStatus
decodeUImmOperand(MCInst
&Inst
, uint64_t Imm
,
187 int64_t Address
, const void *Decoder
) {
188 assert(isUInt
<N
>(Imm
) && "Invalid immediate");
189 Inst
.addOperand(MCOperand::createImm(Imm
));
190 return MCDisassembler::Success
;
194 static DecodeStatus
decodeSImmOperand(MCInst
&Inst
, uint64_t Imm
,
195 int64_t Address
, const void *Decoder
) {
196 assert(isUInt
<N
>(Imm
) && "Invalid immediate");
197 Inst
.addOperand(MCOperand::createImm(SignExtend64
<N
>(Imm
)));
198 return MCDisassembler::Success
;
201 static DecodeStatus
decodeMemRIOperands(MCInst
&Inst
, uint64_t Imm
,
202 int64_t Address
, const void *Decoder
) {
203 // Decode the memri field (imm, reg), which has the low 16-bits as the
204 // displacement and the next 5 bits as the register #.
206 uint64_t Base
= Imm
>> 16;
207 uint64_t Disp
= Imm
& 0xFFFF;
209 assert(Base
< 32 && "Invalid base register");
211 switch (Inst
.getOpcode()) {
219 // Add the tied output operand.
220 Inst
.addOperand(MCOperand::createReg(RRegsNoR0
[Base
]));
227 Inst
.insert(Inst
.begin(), MCOperand::createReg(RRegsNoR0
[Base
]));
231 Inst
.addOperand(MCOperand::createImm(SignExtend64
<16>(Disp
)));
232 Inst
.addOperand(MCOperand::createReg(RRegsNoR0
[Base
]));
233 return MCDisassembler::Success
;
236 static DecodeStatus
decodeMemRIXOperands(MCInst
&Inst
, uint64_t Imm
,
237 int64_t Address
, const void *Decoder
) {
238 // Decode the memrix field (imm, reg), which has the low 14-bits as the
239 // displacement and the next 5 bits as the register #.
241 uint64_t Base
= Imm
>> 14;
242 uint64_t Disp
= Imm
& 0x3FFF;
244 assert(Base
< 32 && "Invalid base register");
246 if (Inst
.getOpcode() == PPC::LDU
)
247 // Add the tied output operand.
248 Inst
.addOperand(MCOperand::createReg(RRegsNoR0
[Base
]));
249 else if (Inst
.getOpcode() == PPC::STDU
)
250 Inst
.insert(Inst
.begin(), MCOperand::createReg(RRegsNoR0
[Base
]));
252 Inst
.addOperand(MCOperand::createImm(SignExtend64
<16>(Disp
<< 2)));
253 Inst
.addOperand(MCOperand::createReg(RRegsNoR0
[Base
]));
254 return MCDisassembler::Success
;
257 static DecodeStatus
decodeMemRIX16Operands(MCInst
&Inst
, uint64_t Imm
,
258 int64_t Address
, const void *Decoder
) {
259 // Decode the memrix16 field (imm, reg), which has the low 12-bits as the
260 // displacement with 16-byte aligned, and the next 5 bits as the register #.
262 uint64_t Base
= Imm
>> 12;
263 uint64_t Disp
= Imm
& 0xFFF;
265 assert(Base
< 32 && "Invalid base register");
267 Inst
.addOperand(MCOperand::createImm(SignExtend64
<16>(Disp
<< 4)));
268 Inst
.addOperand(MCOperand::createReg(RRegsNoR0
[Base
]));
269 return MCDisassembler::Success
;
272 static DecodeStatus
decodeSPE8Operands(MCInst
&Inst
, uint64_t Imm
,
273 int64_t Address
, const void *Decoder
) {
274 // Decode the spe8disp field (imm, reg), which has the low 5-bits as the
275 // displacement with 8-byte aligned, and the next 5 bits as the register #.
277 uint64_t Base
= Imm
>> 5;
278 uint64_t Disp
= Imm
& 0x1F;
280 assert(Base
< 32 && "Invalid base register");
282 Inst
.addOperand(MCOperand::createImm(Disp
<< 3));
283 Inst
.addOperand(MCOperand::createReg(RRegsNoR0
[Base
]));
284 return MCDisassembler::Success
;
287 static DecodeStatus
decodeSPE4Operands(MCInst
&Inst
, uint64_t Imm
,
288 int64_t Address
, const void *Decoder
) {
289 // Decode the spe4disp field (imm, reg), which has the low 5-bits as the
290 // displacement with 4-byte aligned, and the next 5 bits as the register #.
292 uint64_t Base
= Imm
>> 5;
293 uint64_t Disp
= Imm
& 0x1F;
295 assert(Base
< 32 && "Invalid base register");
297 Inst
.addOperand(MCOperand::createImm(Disp
<< 2));
298 Inst
.addOperand(MCOperand::createReg(RRegsNoR0
[Base
]));
299 return MCDisassembler::Success
;
302 static DecodeStatus
decodeSPE2Operands(MCInst
&Inst
, uint64_t Imm
,
303 int64_t Address
, const void *Decoder
) {
304 // Decode the spe2disp field (imm, reg), which has the low 5-bits as the
305 // displacement with 2-byte aligned, and the next 5 bits as the register #.
307 uint64_t Base
= Imm
>> 5;
308 uint64_t Disp
= Imm
& 0x1F;
310 assert(Base
< 32 && "Invalid base register");
312 Inst
.addOperand(MCOperand::createImm(Disp
<< 1));
313 Inst
.addOperand(MCOperand::createReg(RRegsNoR0
[Base
]));
314 return MCDisassembler::Success
;
317 static DecodeStatus
decodeCRBitMOperand(MCInst
&Inst
, uint64_t Imm
,
318 int64_t Address
, const void *Decoder
) {
319 // The cr bit encoding is 0x80 >> cr_reg_num.
321 unsigned Zeros
= countTrailingZeros(Imm
);
322 assert(Zeros
< 8 && "Invalid CR bit value");
324 Inst
.addOperand(MCOperand::createReg(CRRegs
[7 - Zeros
]));
325 return MCDisassembler::Success
;
328 #include "PPCGenDisassemblerTables.inc"
330 DecodeStatus
PPCDisassembler::getInstruction(MCInst
&MI
, uint64_t &Size
,
331 ArrayRef
<uint8_t> Bytes
,
332 uint64_t Address
, raw_ostream
&OS
,
333 raw_ostream
&CS
) const {
334 // Get the four bytes of the instruction.
336 if (Bytes
.size() < 4) {
338 return MCDisassembler::Fail
;
341 // Read the instruction in the proper endianness.
342 uint32_t Inst
= IsLittleEndian
? support::endian::read32le(Bytes
.data())
343 : support::endian::read32be(Bytes
.data());
345 if (STI
.getFeatureBits()[PPC::FeatureQPX
]) {
346 DecodeStatus result
=
347 decodeInstruction(DecoderTableQPX32
, MI
, Inst
, Address
, this, STI
);
348 if (result
!= MCDisassembler::Fail
)
350 } else if (STI
.getFeatureBits()[PPC::FeatureSPE
]) {
351 DecodeStatus result
=
352 decodeInstruction(DecoderTableSPE32
, MI
, Inst
, Address
, this, STI
);
353 if (result
!= MCDisassembler::Fail
)
357 return decodeInstruction(DecoderTable32
, MI
, Inst
, Address
, this, STI
);