1 //===-- PPCMCCodeEmitter.cpp - Convert PPC code to machine code -----------===//
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 // This file implements the PPCMCCodeEmitter class.
11 //===----------------------------------------------------------------------===//
13 #include "MCTargetDesc/PPCFixupKinds.h"
14 #include "PPCInstrInfo.h"
15 #include "PPCMCCodeEmitter.h"
16 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/ADT/Statistic.h"
18 #include "llvm/ADT/Triple.h"
19 #include "llvm/MC/MCFixup.h"
20 #include "llvm/MC/MCInstrDesc.h"
21 #include "llvm/MC/MCRegisterInfo.h"
22 #include "llvm/Support/Endian.h"
23 #include "llvm/Support/EndianStream.h"
24 #include "llvm/Support/ErrorHandling.h"
25 #include "llvm/Support/MathExtras.h"
26 #include "llvm/Support/raw_ostream.h"
32 #define DEBUG_TYPE "mccodeemitter"
34 STATISTIC(MCNumEmitted
, "Number of MC instructions emitted");
36 MCCodeEmitter
*llvm::createPPCMCCodeEmitter(const MCInstrInfo
&MCII
,
37 const MCRegisterInfo
&MRI
,
39 return new PPCMCCodeEmitter(MCII
, Ctx
);
42 unsigned PPCMCCodeEmitter::
43 getDirectBrEncoding(const MCInst
&MI
, unsigned OpNo
,
44 SmallVectorImpl
<MCFixup
> &Fixups
,
45 const MCSubtargetInfo
&STI
) const {
46 const MCOperand
&MO
= MI
.getOperand(OpNo
);
47 if (MO
.isReg() || MO
.isImm()) return getMachineOpValue(MI
, MO
, Fixups
, STI
);
49 // Add a fixup for the branch target.
50 Fixups
.push_back(MCFixup::create(0, MO
.getExpr(),
51 (MCFixupKind
)PPC::fixup_ppc_br24
));
55 unsigned PPCMCCodeEmitter::getCondBrEncoding(const MCInst
&MI
, unsigned OpNo
,
56 SmallVectorImpl
<MCFixup
> &Fixups
,
57 const MCSubtargetInfo
&STI
) const {
58 const MCOperand
&MO
= MI
.getOperand(OpNo
);
59 if (MO
.isReg() || MO
.isImm()) return getMachineOpValue(MI
, MO
, Fixups
, STI
);
61 // Add a fixup for the branch target.
62 Fixups
.push_back(MCFixup::create(0, MO
.getExpr(),
63 (MCFixupKind
)PPC::fixup_ppc_brcond14
));
67 unsigned PPCMCCodeEmitter::
68 getAbsDirectBrEncoding(const MCInst
&MI
, unsigned OpNo
,
69 SmallVectorImpl
<MCFixup
> &Fixups
,
70 const MCSubtargetInfo
&STI
) const {
71 const MCOperand
&MO
= MI
.getOperand(OpNo
);
72 if (MO
.isReg() || MO
.isImm()) return getMachineOpValue(MI
, MO
, Fixups
, STI
);
74 // Add a fixup for the branch target.
75 Fixups
.push_back(MCFixup::create(0, MO
.getExpr(),
76 (MCFixupKind
)PPC::fixup_ppc_br24abs
));
80 unsigned PPCMCCodeEmitter::
81 getAbsCondBrEncoding(const MCInst
&MI
, unsigned OpNo
,
82 SmallVectorImpl
<MCFixup
> &Fixups
,
83 const MCSubtargetInfo
&STI
) const {
84 const MCOperand
&MO
= MI
.getOperand(OpNo
);
85 if (MO
.isReg() || MO
.isImm()) return getMachineOpValue(MI
, MO
, Fixups
, STI
);
87 // Add a fixup for the branch target.
88 Fixups
.push_back(MCFixup::create(0, MO
.getExpr(),
89 (MCFixupKind
)PPC::fixup_ppc_brcond14abs
));
93 unsigned PPCMCCodeEmitter::getImm16Encoding(const MCInst
&MI
, unsigned OpNo
,
94 SmallVectorImpl
<MCFixup
> &Fixups
,
95 const MCSubtargetInfo
&STI
) const {
96 const MCOperand
&MO
= MI
.getOperand(OpNo
);
97 if (MO
.isReg() || MO
.isImm()) return getMachineOpValue(MI
, MO
, Fixups
, STI
);
99 // Add a fixup for the immediate field.
100 Fixups
.push_back(MCFixup::create(IsLittleEndian
? 0 : 2, MO
.getExpr(),
101 (MCFixupKind
)PPC::fixup_ppc_half16
));
105 unsigned PPCMCCodeEmitter::getMemRIEncoding(const MCInst
&MI
, unsigned OpNo
,
106 SmallVectorImpl
<MCFixup
> &Fixups
,
107 const MCSubtargetInfo
&STI
) const {
108 // Encode (imm, reg) as a memri, which has the low 16-bits as the
109 // displacement and the next 5 bits as the register #.
110 assert(MI
.getOperand(OpNo
+1).isReg());
111 unsigned RegBits
= getMachineOpValue(MI
, MI
.getOperand(OpNo
+1), Fixups
, STI
) << 16;
113 const MCOperand
&MO
= MI
.getOperand(OpNo
);
115 return (getMachineOpValue(MI
, MO
, Fixups
, STI
) & 0xFFFF) | RegBits
;
117 // Add a fixup for the displacement field.
118 Fixups
.push_back(MCFixup::create(IsLittleEndian
? 0 : 2, MO
.getExpr(),
119 (MCFixupKind
)PPC::fixup_ppc_half16
));
123 unsigned PPCMCCodeEmitter::getMemRIXEncoding(const MCInst
&MI
, unsigned OpNo
,
124 SmallVectorImpl
<MCFixup
> &Fixups
,
125 const MCSubtargetInfo
&STI
) const {
126 // Encode (imm, reg) as a memrix, which has the low 14-bits as the
127 // displacement and the next 5 bits as the register #.
128 assert(MI
.getOperand(OpNo
+1).isReg());
129 unsigned RegBits
= getMachineOpValue(MI
, MI
.getOperand(OpNo
+1), Fixups
, STI
) << 14;
131 const MCOperand
&MO
= MI
.getOperand(OpNo
);
133 return ((getMachineOpValue(MI
, MO
, Fixups
, STI
) >> 2) & 0x3FFF) | RegBits
;
135 // Add a fixup for the displacement field.
136 Fixups
.push_back(MCFixup::create(IsLittleEndian
? 0 : 2, MO
.getExpr(),
137 (MCFixupKind
)PPC::fixup_ppc_half16ds
));
141 unsigned PPCMCCodeEmitter::getMemRIX16Encoding(const MCInst
&MI
, unsigned OpNo
,
142 SmallVectorImpl
<MCFixup
> &Fixups
,
143 const MCSubtargetInfo
&STI
) const {
144 // Encode (imm, reg) as a memrix16, which has the low 12-bits as the
145 // displacement and the next 5 bits as the register #.
146 assert(MI
.getOperand(OpNo
+1).isReg());
147 unsigned RegBits
= getMachineOpValue(MI
, MI
.getOperand(OpNo
+1), Fixups
, STI
) << 12;
149 const MCOperand
&MO
= MI
.getOperand(OpNo
);
151 assert(!(MO
.getImm() % 16) &&
152 "Expecting an immediate that is a multiple of 16");
153 return ((getMachineOpValue(MI
, MO
, Fixups
, STI
) >> 4) & 0xFFF) | RegBits
;
156 // Otherwise add a fixup for the displacement field.
157 Fixups
.push_back(MCFixup::create(IsLittleEndian
? 0 : 2, MO
.getExpr(),
158 (MCFixupKind
)PPC::fixup_ppc_half16ds
));
162 unsigned PPCMCCodeEmitter::getSPE8DisEncoding(const MCInst
&MI
, unsigned OpNo
,
163 SmallVectorImpl
<MCFixup
> &Fixups
,
164 const MCSubtargetInfo
&STI
)
166 // Encode (imm, reg) as a spe8dis, which has the low 5-bits of (imm / 8)
167 // as the displacement and the next 5 bits as the register #.
168 assert(MI
.getOperand(OpNo
+1).isReg());
169 uint32_t RegBits
= getMachineOpValue(MI
, MI
.getOperand(OpNo
+1), Fixups
, STI
) << 5;
171 const MCOperand
&MO
= MI
.getOperand(OpNo
);
173 uint32_t Imm
= getMachineOpValue(MI
, MO
, Fixups
, STI
) >> 3;
174 return reverseBits(Imm
| RegBits
) >> 22;
177 unsigned PPCMCCodeEmitter::getSPE4DisEncoding(const MCInst
&MI
, unsigned OpNo
,
178 SmallVectorImpl
<MCFixup
> &Fixups
,
179 const MCSubtargetInfo
&STI
)
181 // Encode (imm, reg) as a spe4dis, which has the low 5-bits of (imm / 4)
182 // as the displacement and the next 5 bits as the register #.
183 assert(MI
.getOperand(OpNo
+1).isReg());
184 uint32_t RegBits
= getMachineOpValue(MI
, MI
.getOperand(OpNo
+1), Fixups
, STI
) << 5;
186 const MCOperand
&MO
= MI
.getOperand(OpNo
);
188 uint32_t Imm
= getMachineOpValue(MI
, MO
, Fixups
, STI
) >> 2;
189 return reverseBits(Imm
| RegBits
) >> 22;
192 unsigned PPCMCCodeEmitter::getSPE2DisEncoding(const MCInst
&MI
, unsigned OpNo
,
193 SmallVectorImpl
<MCFixup
> &Fixups
,
194 const MCSubtargetInfo
&STI
)
196 // Encode (imm, reg) as a spe2dis, which has the low 5-bits of (imm / 2)
197 // as the displacement and the next 5 bits as the register #.
198 assert(MI
.getOperand(OpNo
+1).isReg());
199 uint32_t RegBits
= getMachineOpValue(MI
, MI
.getOperand(OpNo
+1), Fixups
, STI
) << 5;
201 const MCOperand
&MO
= MI
.getOperand(OpNo
);
203 uint32_t Imm
= getMachineOpValue(MI
, MO
, Fixups
, STI
) >> 1;
204 return reverseBits(Imm
| RegBits
) >> 22;
207 unsigned PPCMCCodeEmitter::getTLSRegEncoding(const MCInst
&MI
, unsigned OpNo
,
208 SmallVectorImpl
<MCFixup
> &Fixups
,
209 const MCSubtargetInfo
&STI
) const {
210 const MCOperand
&MO
= MI
.getOperand(OpNo
);
211 if (MO
.isReg()) return getMachineOpValue(MI
, MO
, Fixups
, STI
);
213 // Add a fixup for the TLS register, which simply provides a relocation
214 // hint to the linker that this statement is part of a relocation sequence.
215 // Return the thread-pointer register's encoding.
216 Fixups
.push_back(MCFixup::create(0, MO
.getExpr(),
217 (MCFixupKind
)PPC::fixup_ppc_nofixup
));
218 const Triple
&TT
= STI
.getTargetTriple();
219 bool isPPC64
= TT
.isPPC64();
220 return CTX
.getRegisterInfo()->getEncodingValue(isPPC64
? PPC::X13
: PPC::R2
);
223 unsigned PPCMCCodeEmitter::getTLSCallEncoding(const MCInst
&MI
, unsigned OpNo
,
224 SmallVectorImpl
<MCFixup
> &Fixups
,
225 const MCSubtargetInfo
&STI
) const {
226 // For special TLS calls, we need two fixups; one for the branch target
227 // (__tls_get_addr), which we create via getDirectBrEncoding as usual,
228 // and one for the TLSGD or TLSLD symbol, which is emitted here.
229 const MCOperand
&MO
= MI
.getOperand(OpNo
+1);
230 Fixups
.push_back(MCFixup::create(0, MO
.getExpr(),
231 (MCFixupKind
)PPC::fixup_ppc_nofixup
));
232 return getDirectBrEncoding(MI
, OpNo
, Fixups
, STI
);
235 unsigned PPCMCCodeEmitter::
236 get_crbitm_encoding(const MCInst
&MI
, unsigned OpNo
,
237 SmallVectorImpl
<MCFixup
> &Fixups
,
238 const MCSubtargetInfo
&STI
) const {
239 const MCOperand
&MO
= MI
.getOperand(OpNo
);
240 assert((MI
.getOpcode() == PPC::MTOCRF
|| MI
.getOpcode() == PPC::MTOCRF8
||
241 MI
.getOpcode() == PPC::MFOCRF
|| MI
.getOpcode() == PPC::MFOCRF8
) &&
242 (MO
.getReg() >= PPC::CR0
&& MO
.getReg() <= PPC::CR7
));
243 return 0x80 >> CTX
.getRegisterInfo()->getEncodingValue(MO
.getReg());
246 // Get the index for this operand in this instruction. This is needed for
247 // computing the register number in PPCInstrInfo::getRegNumForOperand() for
248 // any instructions that use a different numbering scheme for registers in
249 // different operands.
250 static unsigned getOpIdxForMO(const MCInst
&MI
, const MCOperand
&MO
) {
251 for (unsigned i
= 0; i
< MI
.getNumOperands(); i
++) {
252 const MCOperand
&Op
= MI
.getOperand(i
);
256 llvm_unreachable("This operand is not part of this instruction");
257 return ~0U; // Silence any warnings about no return.
260 unsigned PPCMCCodeEmitter::
261 getMachineOpValue(const MCInst
&MI
, const MCOperand
&MO
,
262 SmallVectorImpl
<MCFixup
> &Fixups
,
263 const MCSubtargetInfo
&STI
) const {
265 // MTOCRF/MFOCRF should go through get_crbitm_encoding for the CR operand.
266 // The GPR operand should come through here though.
267 assert((MI
.getOpcode() != PPC::MTOCRF
&& MI
.getOpcode() != PPC::MTOCRF8
&&
268 MI
.getOpcode() != PPC::MFOCRF
&& MI
.getOpcode() != PPC::MFOCRF8
) ||
269 MO
.getReg() < PPC::CR0
|| MO
.getReg() > PPC::CR7
);
270 unsigned OpNo
= getOpIdxForMO(MI
, MO
);
272 PPCInstrInfo::getRegNumForOperand(MCII
.get(MI
.getOpcode()),
274 return CTX
.getRegisterInfo()->getEncodingValue(Reg
);
278 "Relocation required in an instruction that we cannot encode!");
282 void PPCMCCodeEmitter::encodeInstruction(
283 const MCInst
&MI
, raw_ostream
&OS
, SmallVectorImpl
<MCFixup
> &Fixups
,
284 const MCSubtargetInfo
&STI
) const {
285 verifyInstructionPredicates(MI
,
286 computeAvailableFeatures(STI
.getFeatureBits()));
288 uint64_t Bits
= getBinaryCodeForInstr(MI
, Fixups
, STI
);
290 // Output the constant in big/little endian byte order.
291 unsigned Size
= getInstSizeInBytes(MI
);
292 support::endianness E
= IsLittleEndian
? support::little
: support::big
;
297 support::endian::write
<uint32_t>(OS
, Bits
, E
);
300 // If we emit a pair of instructions, the first one is
301 // always in the top 32 bits, even on little-endian.
302 support::endian::write
<uint32_t>(OS
, Bits
>> 32, E
);
303 support::endian::write
<uint32_t>(OS
, Bits
, E
);
306 llvm_unreachable("Invalid instruction size");
309 ++MCNumEmitted
; // Keep track of the # of mi's emitted.
312 // Get the number of bytes used to encode the given MCInst.
313 unsigned PPCMCCodeEmitter::getInstSizeInBytes(const MCInst
&MI
) const {
314 unsigned Opcode
= MI
.getOpcode();
315 const MCInstrDesc
&Desc
= MCII
.get(Opcode
);
316 return Desc
.getSize();
319 #define ENABLE_INSTR_PREDICATE_VERIFIER
320 #include "PPCGenMCCodeEmitter.inc"