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
DecodeSPERCRegisterClass(MCInst
&Inst
, uint64_t RegNo
,
172 const void *Decoder
) {
173 return decodeRegisterClass(Inst
, RegNo
, SPERegs
);
176 #define DecodeQSRCRegisterClass DecodeQFRCRegisterClass
177 #define DecodeQBRCRegisterClass DecodeQFRCRegisterClass
180 static DecodeStatus
decodeUImmOperand(MCInst
&Inst
, uint64_t Imm
,
181 int64_t Address
, const void *Decoder
) {
182 assert(isUInt
<N
>(Imm
) && "Invalid immediate");
183 Inst
.addOperand(MCOperand::createImm(Imm
));
184 return MCDisassembler::Success
;
188 static DecodeStatus
decodeSImmOperand(MCInst
&Inst
, uint64_t Imm
,
189 int64_t Address
, const void *Decoder
) {
190 assert(isUInt
<N
>(Imm
) && "Invalid immediate");
191 Inst
.addOperand(MCOperand::createImm(SignExtend64
<N
>(Imm
)));
192 return MCDisassembler::Success
;
195 static DecodeStatus
decodeMemRIOperands(MCInst
&Inst
, uint64_t Imm
,
196 int64_t Address
, const void *Decoder
) {
197 // Decode the memri field (imm, reg), which has the low 16-bits as the
198 // displacement and the next 5 bits as the register #.
200 uint64_t Base
= Imm
>> 16;
201 uint64_t Disp
= Imm
& 0xFFFF;
203 assert(Base
< 32 && "Invalid base register");
205 switch (Inst
.getOpcode()) {
213 // Add the tied output operand.
214 Inst
.addOperand(MCOperand::createReg(RRegsNoR0
[Base
]));
221 Inst
.insert(Inst
.begin(), MCOperand::createReg(RRegsNoR0
[Base
]));
225 Inst
.addOperand(MCOperand::createImm(SignExtend64
<16>(Disp
)));
226 Inst
.addOperand(MCOperand::createReg(RRegsNoR0
[Base
]));
227 return MCDisassembler::Success
;
230 static DecodeStatus
decodeMemRIXOperands(MCInst
&Inst
, uint64_t Imm
,
231 int64_t Address
, const void *Decoder
) {
232 // Decode the memrix field (imm, reg), which has the low 14-bits as the
233 // displacement and the next 5 bits as the register #.
235 uint64_t Base
= Imm
>> 14;
236 uint64_t Disp
= Imm
& 0x3FFF;
238 assert(Base
< 32 && "Invalid base register");
240 if (Inst
.getOpcode() == PPC::LDU
)
241 // Add the tied output operand.
242 Inst
.addOperand(MCOperand::createReg(RRegsNoR0
[Base
]));
243 else if (Inst
.getOpcode() == PPC::STDU
)
244 Inst
.insert(Inst
.begin(), MCOperand::createReg(RRegsNoR0
[Base
]));
246 Inst
.addOperand(MCOperand::createImm(SignExtend64
<16>(Disp
<< 2)));
247 Inst
.addOperand(MCOperand::createReg(RRegsNoR0
[Base
]));
248 return MCDisassembler::Success
;
251 static DecodeStatus
decodeMemRIX16Operands(MCInst
&Inst
, uint64_t Imm
,
252 int64_t Address
, const void *Decoder
) {
253 // Decode the memrix16 field (imm, reg), which has the low 12-bits as the
254 // displacement with 16-byte aligned, and the next 5 bits as the register #.
256 uint64_t Base
= Imm
>> 12;
257 uint64_t Disp
= Imm
& 0xFFF;
259 assert(Base
< 32 && "Invalid base register");
261 Inst
.addOperand(MCOperand::createImm(SignExtend64
<16>(Disp
<< 4)));
262 Inst
.addOperand(MCOperand::createReg(RRegsNoR0
[Base
]));
263 return MCDisassembler::Success
;
266 static DecodeStatus
decodeSPE8Operands(MCInst
&Inst
, uint64_t Imm
,
267 int64_t Address
, const void *Decoder
) {
268 // Decode the spe8disp field (imm, reg), which has the low 5-bits as the
269 // displacement with 8-byte aligned, and the next 5 bits as the register #.
271 uint64_t Base
= Imm
>> 5;
272 uint64_t Disp
= Imm
& 0x1F;
274 assert(Base
< 32 && "Invalid base register");
276 Inst
.addOperand(MCOperand::createImm(Disp
<< 3));
277 Inst
.addOperand(MCOperand::createReg(RRegsNoR0
[Base
]));
278 return MCDisassembler::Success
;
281 static DecodeStatus
decodeSPE4Operands(MCInst
&Inst
, uint64_t Imm
,
282 int64_t Address
, const void *Decoder
) {
283 // Decode the spe4disp field (imm, reg), which has the low 5-bits as the
284 // displacement with 4-byte aligned, and the next 5 bits as the register #.
286 uint64_t Base
= Imm
>> 5;
287 uint64_t Disp
= Imm
& 0x1F;
289 assert(Base
< 32 && "Invalid base register");
291 Inst
.addOperand(MCOperand::createImm(Disp
<< 2));
292 Inst
.addOperand(MCOperand::createReg(RRegsNoR0
[Base
]));
293 return MCDisassembler::Success
;
296 static DecodeStatus
decodeSPE2Operands(MCInst
&Inst
, uint64_t Imm
,
297 int64_t Address
, const void *Decoder
) {
298 // Decode the spe2disp field (imm, reg), which has the low 5-bits as the
299 // displacement with 2-byte aligned, and the next 5 bits as the register #.
301 uint64_t Base
= Imm
>> 5;
302 uint64_t Disp
= Imm
& 0x1F;
304 assert(Base
< 32 && "Invalid base register");
306 Inst
.addOperand(MCOperand::createImm(Disp
<< 1));
307 Inst
.addOperand(MCOperand::createReg(RRegsNoR0
[Base
]));
308 return MCDisassembler::Success
;
311 static DecodeStatus
decodeCRBitMOperand(MCInst
&Inst
, uint64_t Imm
,
312 int64_t Address
, const void *Decoder
) {
313 // The cr bit encoding is 0x80 >> cr_reg_num.
315 unsigned Zeros
= countTrailingZeros(Imm
);
316 assert(Zeros
< 8 && "Invalid CR bit value");
318 Inst
.addOperand(MCOperand::createReg(CRRegs
[7 - Zeros
]));
319 return MCDisassembler::Success
;
322 #include "PPCGenDisassemblerTables.inc"
324 DecodeStatus
PPCDisassembler::getInstruction(MCInst
&MI
, uint64_t &Size
,
325 ArrayRef
<uint8_t> Bytes
,
326 uint64_t Address
, raw_ostream
&OS
,
327 raw_ostream
&CS
) const {
328 // Get the four bytes of the instruction.
330 if (Bytes
.size() < 4) {
332 return MCDisassembler::Fail
;
335 // Read the instruction in the proper endianness.
336 uint32_t Inst
= IsLittleEndian
? support::endian::read32le(Bytes
.data())
337 : support::endian::read32be(Bytes
.data());
339 if (STI
.getFeatureBits()[PPC::FeatureQPX
]) {
340 DecodeStatus result
=
341 decodeInstruction(DecoderTableQPX32
, MI
, Inst
, Address
, this, STI
);
342 if (result
!= MCDisassembler::Fail
)
344 } else if (STI
.getFeatureBits()[PPC::FeatureSPE
]) {
345 DecodeStatus result
=
346 decodeInstruction(DecoderTableSPE32
, MI
, Inst
, Address
, this, STI
);
347 if (result
!= MCDisassembler::Fail
)
351 return decodeInstruction(DecoderTable32
, MI
, Inst
, Address
, this, STI
);