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 "PPCMCCodeEmitter.h"
14 #include "MCTargetDesc/PPCFixupKinds.h"
15 #include "PPCMCTargetDesc.h"
16 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/ADT/Statistic.h"
18 #include "llvm/MC/MCExpr.h"
19 #include "llvm/MC/MCFixup.h"
20 #include "llvm/MC/MCInstrDesc.h"
21 #include "llvm/MC/MCRegisterInfo.h"
22 #include "llvm/Support/Casting.h"
23 #include "llvm/Support/EndianStream.h"
24 #include "llvm/Support/ErrorHandling.h"
25 #include "llvm/Support/MathExtras.h"
26 #include "llvm/TargetParser/Triple.h"
32 #define DEBUG_TYPE "mccodeemitter"
34 STATISTIC(MCNumEmitted
, "Number of MC instructions emitted");
36 MCCodeEmitter
*llvm::createPPCMCCodeEmitter(const MCInstrInfo
&MCII
,
38 return new PPCMCCodeEmitter(MCII
, Ctx
);
41 unsigned PPCMCCodeEmitter::
42 getDirectBrEncoding(const MCInst
&MI
, unsigned OpNo
,
43 SmallVectorImpl
<MCFixup
> &Fixups
,
44 const MCSubtargetInfo
&STI
) const {
45 const MCOperand
&MO
= MI
.getOperand(OpNo
);
47 if (MO
.isReg() || MO
.isImm())
48 return getMachineOpValue(MI
, MO
, Fixups
, STI
);
50 // Add a fixup for the branch target.
51 Fixups
.push_back(MCFixup::create(0, MO
.getExpr(),
53 ? (MCFixupKind
)PPC::fixup_ppc_br24_notoc
54 : (MCFixupKind
)PPC::fixup_ppc_br24
)));
58 /// Check if Opcode corresponds to a call instruction that should be marked
59 /// with the NOTOC relocation.
60 bool PPCMCCodeEmitter::isNoTOCCallInstr(const MCInst
&MI
) const {
61 unsigned Opcode
= MI
.getOpcode();
62 if (!MCII
.get(Opcode
).isCall())
68 llvm_unreachable("Unknown call opcode");
72 case PPC::BL8_NOTOC_TLS
:
73 case PPC::BL8_NOTOC_RM
:
88 case PPC::BL8_NOP_TLS
:
100 case PPC::BL8_NOP_RM
:
101 case PPC::BLA8_NOP_RM
:
103 case PPC::BCTRL8_LDinto_toc
:
104 case PPC::BCTRL8_LDinto_toc_RM
:
106 case PPC::TCRETURNdi8
:
107 case PPC::TCRETURNai8
:
108 case PPC::TCRETURNri8
:
139 case PPC::TCRETURNdi
:
140 case PPC::TCRETURNai
:
141 case PPC::TCRETURNri
:
142 case PPC::BCTRL_LWZinto_toc
:
143 case PPC::BCTRL_LWZinto_toc_RM
:
152 unsigned PPCMCCodeEmitter::getCondBrEncoding(const MCInst
&MI
, unsigned OpNo
,
153 SmallVectorImpl
<MCFixup
> &Fixups
,
154 const MCSubtargetInfo
&STI
) const {
155 const MCOperand
&MO
= MI
.getOperand(OpNo
);
156 if (MO
.isReg() || MO
.isImm()) return getMachineOpValue(MI
, MO
, Fixups
, STI
);
158 // Add a fixup for the branch target.
159 Fixups
.push_back(MCFixup::create(0, MO
.getExpr(),
160 (MCFixupKind
)PPC::fixup_ppc_brcond14
));
164 unsigned PPCMCCodeEmitter::
165 getAbsDirectBrEncoding(const MCInst
&MI
, unsigned OpNo
,
166 SmallVectorImpl
<MCFixup
> &Fixups
,
167 const MCSubtargetInfo
&STI
) const {
168 const MCOperand
&MO
= MI
.getOperand(OpNo
);
169 if (MO
.isReg() || MO
.isImm()) return getMachineOpValue(MI
, MO
, Fixups
, STI
);
171 // Add a fixup for the branch target.
172 Fixups
.push_back(MCFixup::create(0, MO
.getExpr(),
173 (MCFixupKind
)PPC::fixup_ppc_br24abs
));
177 unsigned PPCMCCodeEmitter::
178 getAbsCondBrEncoding(const MCInst
&MI
, unsigned OpNo
,
179 SmallVectorImpl
<MCFixup
> &Fixups
,
180 const MCSubtargetInfo
&STI
) const {
181 const MCOperand
&MO
= MI
.getOperand(OpNo
);
182 if (MO
.isReg() || MO
.isImm()) return getMachineOpValue(MI
, MO
, Fixups
, STI
);
184 // Add a fixup for the branch target.
185 Fixups
.push_back(MCFixup::create(0, MO
.getExpr(),
186 (MCFixupKind
)PPC::fixup_ppc_brcond14abs
));
191 PPCMCCodeEmitter::getVSRpEvenEncoding(const MCInst
&MI
, unsigned OpNo
,
192 SmallVectorImpl
<MCFixup
> &Fixups
,
193 const MCSubtargetInfo
&STI
) const {
194 assert(MI
.getOperand(OpNo
).isReg() && "Operand should be a register");
195 unsigned RegBits
= getMachineOpValue(MI
, MI
.getOperand(OpNo
), Fixups
, STI
)
200 unsigned PPCMCCodeEmitter::getImm16Encoding(const MCInst
&MI
, unsigned OpNo
,
201 SmallVectorImpl
<MCFixup
> &Fixups
,
202 const MCSubtargetInfo
&STI
) const {
203 const MCOperand
&MO
= MI
.getOperand(OpNo
);
204 if (MO
.isReg() || MO
.isImm()) return getMachineOpValue(MI
, MO
, Fixups
, STI
);
206 // Add a fixup for the immediate field.
207 Fixups
.push_back(MCFixup::create(IsLittleEndian
? 0 : 2, MO
.getExpr(),
208 (MCFixupKind
)PPC::fixup_ppc_half16
));
212 uint64_t PPCMCCodeEmitter::getImm34Encoding(const MCInst
&MI
, unsigned OpNo
,
213 SmallVectorImpl
<MCFixup
> &Fixups
,
214 const MCSubtargetInfo
&STI
,
215 MCFixupKind Fixup
) const {
216 const MCOperand
&MO
= MI
.getOperand(OpNo
);
217 assert(!MO
.isReg() && "Not expecting a register for this operand.");
219 return getMachineOpValue(MI
, MO
, Fixups
, STI
);
221 // Add a fixup for the immediate field.
222 Fixups
.push_back(MCFixup::create(0, MO
.getExpr(), Fixup
));
227 PPCMCCodeEmitter::getImm34EncodingNoPCRel(const MCInst
&MI
, unsigned OpNo
,
228 SmallVectorImpl
<MCFixup
> &Fixups
,
229 const MCSubtargetInfo
&STI
) const {
230 return getImm34Encoding(MI
, OpNo
, Fixups
, STI
,
231 (MCFixupKind
)PPC::fixup_ppc_imm34
);
235 PPCMCCodeEmitter::getImm34EncodingPCRel(const MCInst
&MI
, unsigned OpNo
,
236 SmallVectorImpl
<MCFixup
> &Fixups
,
237 const MCSubtargetInfo
&STI
) const {
238 return getImm34Encoding(MI
, OpNo
, Fixups
, STI
,
239 (MCFixupKind
)PPC::fixup_ppc_pcrel34
);
242 unsigned PPCMCCodeEmitter::getDispRIEncoding(const MCInst
&MI
, unsigned OpNo
,
243 SmallVectorImpl
<MCFixup
> &Fixups
,
244 const MCSubtargetInfo
&STI
) const {
245 const MCOperand
&MO
= MI
.getOperand(OpNo
);
247 return getMachineOpValue(MI
, MO
, Fixups
, STI
) & 0xFFFF;
249 // Add a fixup for the displacement field.
250 Fixups
.push_back(MCFixup::create(IsLittleEndian
? 0 : 2, MO
.getExpr(),
251 (MCFixupKind
)PPC::fixup_ppc_half16
));
256 PPCMCCodeEmitter::getDispRIXEncoding(const MCInst
&MI
, unsigned OpNo
,
257 SmallVectorImpl
<MCFixup
> &Fixups
,
258 const MCSubtargetInfo
&STI
) const {
259 const MCOperand
&MO
= MI
.getOperand(OpNo
);
261 return ((getMachineOpValue(MI
, MO
, Fixups
, STI
) >> 2) & 0x3FFF);
263 // Add a fixup for the displacement field.
264 Fixups
.push_back(MCFixup::create(IsLittleEndian
? 0 : 2, MO
.getExpr(),
265 (MCFixupKind
)PPC::fixup_ppc_half16ds
));
270 PPCMCCodeEmitter::getDispRIX16Encoding(const MCInst
&MI
, unsigned OpNo
,
271 SmallVectorImpl
<MCFixup
> &Fixups
,
272 const MCSubtargetInfo
&STI
) const {
273 const MCOperand
&MO
= MI
.getOperand(OpNo
);
275 assert(!(MO
.getImm() % 16) &&
276 "Expecting an immediate that is a multiple of 16");
277 return ((getMachineOpValue(MI
, MO
, Fixups
, STI
) >> 4) & 0xFFF);
280 // Otherwise add a fixup for the displacement field.
281 Fixups
.push_back(MCFixup::create(IsLittleEndian
? 0 : 2, MO
.getExpr(),
282 (MCFixupKind
)PPC::fixup_ppc_half16dq
));
287 PPCMCCodeEmitter::getDispRIHashEncoding(const MCInst
&MI
, unsigned OpNo
,
288 SmallVectorImpl
<MCFixup
> &Fixups
,
289 const MCSubtargetInfo
&STI
) const {
290 // Encode imm for the hash load/store to stack for the ROP Protection
292 const MCOperand
&MO
= MI
.getOperand(OpNo
);
294 assert(MO
.isImm() && "Expecting an immediate operand.");
295 assert(!(MO
.getImm() % 8) && "Expecting offset to be 8 byte aligned.");
297 unsigned DX
= (MO
.getImm() >> 3) & 0x3F;
302 PPCMCCodeEmitter::getDispRI34PCRelEncoding(const MCInst
&MI
, unsigned OpNo
,
303 SmallVectorImpl
<MCFixup
> &Fixups
,
304 const MCSubtargetInfo
&STI
) const {
305 // Encode the displacement part of pc-relative memri34, which is an imm34.
306 // The 34 bit immediate can fall into one of three cases:
307 // 1) It is a relocation to be filled in by the linker represented as:
308 // (MCExpr::SymbolRef)
309 // 2) It is a relocation + SignedOffset represented as:
310 // (MCExpr::Binary(MCExpr::SymbolRef + MCExpr::Constant))
311 // 3) It is a known value at compile time.
313 // If this is not a MCExpr then we are in case 3) and we are dealing with
314 // a value known at compile time, not a relocation.
315 const MCOperand
&MO
= MI
.getOperand(OpNo
);
317 return (getMachineOpValue(MI
, MO
, Fixups
, STI
)) & 0x3FFFFFFFFUL
;
319 // At this point in the function it is known that MO is of type MCExpr.
320 // Therefore we are dealing with either case 1) a symbol ref or
321 // case 2) a symbol ref plus a constant.
322 const MCExpr
*Expr
= MO
.getExpr();
323 switch (Expr
->getKind()) {
325 llvm_unreachable("Unsupported MCExpr for getMemRI34PCRelEncoding.");
326 case MCExpr::SymbolRef
: {
328 const MCSymbolRefExpr
*SRE
= cast
<MCSymbolRefExpr
>(Expr
);
330 // Currently these are the only valid PCRelative Relocations.
331 assert((SRE
->getKind() == MCSymbolRefExpr::VK_PCREL
||
332 SRE
->getKind() == MCSymbolRefExpr::VK_PPC_GOT_PCREL
||
333 SRE
->getKind() == MCSymbolRefExpr::VK_PPC_GOT_TLSGD_PCREL
||
334 SRE
->getKind() == MCSymbolRefExpr::VK_PPC_GOT_TLSLD_PCREL
||
335 SRE
->getKind() == MCSymbolRefExpr::VK_PPC_GOT_TPREL_PCREL
) &&
336 "VariantKind must be VK_PCREL or VK_PPC_GOT_PCREL or "
337 "VK_PPC_GOT_TLSGD_PCREL or VK_PPC_GOT_TLSLD_PCREL or "
338 "VK_PPC_GOT_TPREL_PCREL.");
339 // Generate the fixup for the relocation.
341 MCFixup::create(0, Expr
,
342 static_cast<MCFixupKind
>(PPC::fixup_ppc_pcrel34
)));
343 // Put zero in the location of the immediate. The linker will fill in the
344 // correct value based on the relocation.
347 case MCExpr::Binary
: {
348 // Relocation plus some offset.
349 const MCBinaryExpr
*BE
= cast
<MCBinaryExpr
>(Expr
);
350 assert(BE
->getOpcode() == MCBinaryExpr::Add
&&
351 "Binary expression opcode must be an add.");
353 const MCExpr
*LHS
= BE
->getLHS();
354 const MCExpr
*RHS
= BE
->getRHS();
356 // Need to check in both directions. Reloc+Offset and Offset+Reloc.
357 if (LHS
->getKind() != MCExpr::SymbolRef
)
360 if (LHS
->getKind() != MCExpr::SymbolRef
||
361 RHS
->getKind() != MCExpr::Constant
)
362 llvm_unreachable("Expecting to have one constant and one relocation.");
364 const MCSymbolRefExpr
*SRE
= cast
<MCSymbolRefExpr
>(LHS
);
366 assert(isInt
<34>(cast
<MCConstantExpr
>(RHS
)->getValue()) &&
367 "Value must fit in 34 bits.");
369 // Currently these are the only valid PCRelative Relocations.
370 assert((SRE
->getKind() == MCSymbolRefExpr::VK_PCREL
||
371 SRE
->getKind() == MCSymbolRefExpr::VK_PPC_GOT_PCREL
) &&
372 "VariantKind must be VK_PCREL or VK_PPC_GOT_PCREL");
373 // Generate the fixup for the relocation.
375 MCFixup::create(0, Expr
,
376 static_cast<MCFixupKind
>(PPC::fixup_ppc_pcrel34
)));
377 // Put zero in the location of the immediate. The linker will fill in the
378 // correct value based on the relocation.
385 PPCMCCodeEmitter::getDispRI34Encoding(const MCInst
&MI
, unsigned OpNo
,
386 SmallVectorImpl
<MCFixup
> &Fixups
,
387 const MCSubtargetInfo
&STI
) const {
388 // Encode the displacement part of a memri34.
389 const MCOperand
&MO
= MI
.getOperand(OpNo
);
390 return (getMachineOpValue(MI
, MO
, Fixups
, STI
)) & 0x3FFFFFFFFUL
;
394 PPCMCCodeEmitter::getDispSPE8Encoding(const MCInst
&MI
, unsigned OpNo
,
395 SmallVectorImpl
<MCFixup
> &Fixups
,
396 const MCSubtargetInfo
&STI
) const {
397 // Encode imm as a dispSPE8, which has the low 5-bits of (imm / 8).
398 const MCOperand
&MO
= MI
.getOperand(OpNo
);
400 return getMachineOpValue(MI
, MO
, Fixups
, STI
) >> 3;
404 PPCMCCodeEmitter::getDispSPE4Encoding(const MCInst
&MI
, unsigned OpNo
,
405 SmallVectorImpl
<MCFixup
> &Fixups
,
406 const MCSubtargetInfo
&STI
) const {
407 // Encode imm as a dispSPE8, which has the low 5-bits of (imm / 4).
408 const MCOperand
&MO
= MI
.getOperand(OpNo
);
410 return getMachineOpValue(MI
, MO
, Fixups
, STI
) >> 2;
414 PPCMCCodeEmitter::getDispSPE2Encoding(const MCInst
&MI
, unsigned OpNo
,
415 SmallVectorImpl
<MCFixup
> &Fixups
,
416 const MCSubtargetInfo
&STI
) const {
417 // Encode imm as a dispSPE8, which has the low 5-bits of (imm / 2).
418 const MCOperand
&MO
= MI
.getOperand(OpNo
);
420 return getMachineOpValue(MI
, MO
, Fixups
, STI
) >> 1;
423 unsigned PPCMCCodeEmitter::getTLSRegEncoding(const MCInst
&MI
, unsigned OpNo
,
424 SmallVectorImpl
<MCFixup
> &Fixups
,
425 const MCSubtargetInfo
&STI
) const {
426 const MCOperand
&MO
= MI
.getOperand(OpNo
);
427 if (MO
.isReg()) return getMachineOpValue(MI
, MO
, Fixups
, STI
);
429 // Add a fixup for the TLS register, which simply provides a relocation
430 // hint to the linker that this statement is part of a relocation sequence.
431 // Return the thread-pointer register's encoding. Add a one byte displacement
432 // if using PC relative memops.
433 const MCExpr
*Expr
= MO
.getExpr();
434 const MCSymbolRefExpr
*SRE
= cast
<MCSymbolRefExpr
>(Expr
);
435 bool IsPCRel
= SRE
->getKind() == MCSymbolRefExpr::VK_PPC_TLS_PCREL
;
436 Fixups
.push_back(MCFixup::create(IsPCRel
? 1 : 0, Expr
,
437 (MCFixupKind
)PPC::fixup_ppc_nofixup
));
438 const Triple
&TT
= STI
.getTargetTriple();
439 bool isPPC64
= TT
.isPPC64();
440 return CTX
.getRegisterInfo()->getEncodingValue(isPPC64
? PPC::X13
: PPC::R2
);
443 unsigned PPCMCCodeEmitter::getTLSCallEncoding(const MCInst
&MI
, unsigned OpNo
,
444 SmallVectorImpl
<MCFixup
> &Fixups
,
445 const MCSubtargetInfo
&STI
) const {
446 // For special TLS calls, we need two fixups; one for the branch target
447 // (__tls_get_addr), which we create via getDirectBrEncoding as usual,
448 // and one for the TLSGD or TLSLD symbol, which is emitted here.
449 const MCOperand
&MO
= MI
.getOperand(OpNo
+1);
450 Fixups
.push_back(MCFixup::create(0, MO
.getExpr(),
451 (MCFixupKind
)PPC::fixup_ppc_nofixup
));
452 return getDirectBrEncoding(MI
, OpNo
, Fixups
, STI
);
455 unsigned PPCMCCodeEmitter::
456 get_crbitm_encoding(const MCInst
&MI
, unsigned OpNo
,
457 SmallVectorImpl
<MCFixup
> &Fixups
,
458 const MCSubtargetInfo
&STI
) const {
459 const MCOperand
&MO
= MI
.getOperand(OpNo
);
460 assert((MI
.getOpcode() == PPC::MTOCRF
|| MI
.getOpcode() == PPC::MTOCRF8
||
461 MI
.getOpcode() == PPC::MFOCRF
|| MI
.getOpcode() == PPC::MFOCRF8
) &&
462 (MO
.getReg() >= PPC::CR0
&& MO
.getReg() <= PPC::CR7
));
463 return 0x80 >> CTX
.getRegisterInfo()->getEncodingValue(MO
.getReg());
466 // Get the index for this operand in this instruction. This is needed for
467 // computing the register number in PPC::getRegNumForOperand() for
468 // any instructions that use a different numbering scheme for registers in
469 // different operands.
470 static unsigned getOpIdxForMO(const MCInst
&MI
, const MCOperand
&MO
) {
471 for (unsigned i
= 0; i
< MI
.getNumOperands(); i
++) {
472 const MCOperand
&Op
= MI
.getOperand(i
);
476 llvm_unreachable("This operand is not part of this instruction");
477 return ~0U; // Silence any warnings about no return.
480 uint64_t PPCMCCodeEmitter::
481 getMachineOpValue(const MCInst
&MI
, const MCOperand
&MO
,
482 SmallVectorImpl
<MCFixup
> &Fixups
,
483 const MCSubtargetInfo
&STI
) const {
485 // MTOCRF/MFOCRF should go through get_crbitm_encoding for the CR operand.
486 // The GPR operand should come through here though.
487 assert((MI
.getOpcode() != PPC::MTOCRF
&& MI
.getOpcode() != PPC::MTOCRF8
&&
488 MI
.getOpcode() != PPC::MFOCRF
&& MI
.getOpcode() != PPC::MFOCRF8
) ||
489 MO
.getReg() < PPC::CR0
|| MO
.getReg() > PPC::CR7
);
490 unsigned OpNo
= getOpIdxForMO(MI
, MO
);
492 PPC::getRegNumForOperand(MCII
.get(MI
.getOpcode()), MO
.getReg(), OpNo
);
493 return CTX
.getRegisterInfo()->getEncodingValue(Reg
);
497 "Relocation required in an instruction that we cannot encode!");
501 void PPCMCCodeEmitter::encodeInstruction(const MCInst
&MI
,
502 SmallVectorImpl
<char> &CB
,
503 SmallVectorImpl
<MCFixup
> &Fixups
,
504 const MCSubtargetInfo
&STI
) const {
505 uint64_t Bits
= getBinaryCodeForInstr(MI
, Fixups
, STI
);
507 // Output the constant in big/little endian byte order.
508 unsigned Size
= getInstSizeInBytes(MI
);
510 IsLittleEndian
? llvm::endianness::little
: llvm::endianness::big
;
515 support::endian::write
<uint32_t>(CB
, Bits
, E
);
518 // If we emit a pair of instructions, the first one is
519 // always in the top 32 bits, even on little-endian.
520 support::endian::write
<uint32_t>(CB
, Bits
>> 32, E
);
521 support::endian::write
<uint32_t>(CB
, Bits
, E
);
524 llvm_unreachable("Invalid instruction size");
527 ++MCNumEmitted
; // Keep track of the # of mi's emitted.
530 // Get the number of bytes used to encode the given MCInst.
531 unsigned PPCMCCodeEmitter::getInstSizeInBytes(const MCInst
&MI
) const {
532 unsigned Opcode
= MI
.getOpcode();
533 const MCInstrDesc
&Desc
= MCII
.get(Opcode
);
534 return Desc
.getSize();
537 bool PPCMCCodeEmitter::isPrefixedInstruction(const MCInst
&MI
) const {
538 return MCII
.get(MI
.getOpcode()).TSFlags
& PPCII::Prefixed
;
541 #include "PPCGenMCCodeEmitter.inc"