37#define DEBUG_TYPE "mccodeemitter"
39STATISTIC(MCNumEmitted,
"Number of MC instructions emitted.");
40STATISTIC(MCNumFixups,
"Number of MC fixups created.");
49 AArch64MCCodeEmitter(
const AArch64MCCodeEmitter &) =
delete;
50 void operator=(
const AArch64MCCodeEmitter &) =
delete;
51 ~AArch64MCCodeEmitter()
override =
default;
68 template <u
int32_t FixupKind>
171 unsigned fixMOVZ(
const MCInst &
MI,
unsigned EncodedValue,
178 unsigned fixMulHigh(
const MCInst &
MI,
unsigned EncodedValue,
181 template<
int hasRs,
int hasRt2>
unsigned
182 fixLoadStoreExclusive(
const MCInst &
MI,
unsigned EncodedValue,
185 unsigned fixOneOperandFPComparison(
const MCInst &
MI,
unsigned EncodedValue,
188 template <
unsigned Multiple>
203 uint32_t EncodeMatrixTileListRegisterClass(
const MCInst &
MI,
unsigned OpIdx,
206 template <
unsigned BaseReg>
221 return Ctx.getRegisterInfo()->getEncodingValue(MO.
getReg());
223 assert(MO.
isImm() &&
"did not expect relocated expression");
224 return static_cast<unsigned>(MO.
getImm());
227template<
unsigned FixupKind>
uint32_t
228AArch64MCCodeEmitter::getLdStUImm12OpValue(
const MCInst &
MI,
unsigned OpIdx,
237 assert(MO.
isExpr() &&
"unable to encode load/store imm operand");
249AArch64MCCodeEmitter::getAdrLabelOpValue(
const MCInst &
MI,
unsigned OpIdx,
275AArch64MCCodeEmitter::getAddSubImmOpValue(
const MCInst &
MI,
unsigned OpIdx,
282 "unexpected shift type for add/sub immediate");
284 assert((ShiftVal == 0 || ShiftVal == 12) &&
285 "unexpected shift value for add/sub immediate");
287 return MO.
getImm() | (ShiftVal == 0 ? 0 : (1 << ShiftVal));
299 if (
const AArch64MCExpr *A64E = dyn_cast<AArch64MCExpr>(Expr)) {
306 return ShiftVal == 0 ? 0 : (1 << ShiftVal);
311uint32_t AArch64MCCodeEmitter::getCondBranchTargetOpValue(
333AArch64MCCodeEmitter::getLoadLiteralOpValue(
const MCInst &
MI,
unsigned OpIdx,
353AArch64MCCodeEmitter::getMemExtendOpValue(
const MCInst &
MI,
unsigned OpIdx,
356 unsigned SignExtend =
MI.getOperand(OpIdx).getImm();
357 unsigned DoShift =
MI.getOperand(OpIdx + 1).getImm();
358 return (SignExtend << 1) | DoShift;
362AArch64MCCodeEmitter::getMoveWideImmOpValue(
const MCInst &
MI,
unsigned OpIdx,
369 assert(MO.
isExpr() &&
"Unexpected movz/movk immediate");
381uint32_t AArch64MCCodeEmitter::getTestBranchTargetOpValue(
403AArch64MCCodeEmitter::getBranchTargetOpValue(
const MCInst &
MI,
unsigned OpIdx,
431AArch64MCCodeEmitter::getVecShifterOpValue(
const MCInst &
MI,
unsigned OpIdx,
435 assert(MO.
isImm() &&
"Expected an immediate value for the shift amount!");
455uint32_t AArch64MCCodeEmitter::getFixedPointScaleOpValue(
459 assert(MO.
isImm() &&
"Expected an immediate value for the scale amount!");
464AArch64MCCodeEmitter::getVecShiftR64OpValue(
const MCInst &
MI,
unsigned OpIdx,
468 assert(MO.
isImm() &&
"Expected an immediate value for the scale amount!");
473AArch64MCCodeEmitter::getVecShiftR32OpValue(
const MCInst &
MI,
unsigned OpIdx,
477 assert(MO.
isImm() &&
"Expected an immediate value for the scale amount!");
482AArch64MCCodeEmitter::getVecShiftR16OpValue(
const MCInst &
MI,
unsigned OpIdx,
486 assert(MO.
isImm() &&
"Expected an immediate value for the scale amount!");
491AArch64MCCodeEmitter::getVecShiftR8OpValue(
const MCInst &
MI,
unsigned OpIdx,
495 assert(MO.
isImm() &&
"Expected an immediate value for the scale amount!");
500AArch64MCCodeEmitter::getVecShiftL64OpValue(
const MCInst &
MI,
unsigned OpIdx,
504 assert(MO.
isImm() &&
"Expected an immediate value for the scale amount!");
509AArch64MCCodeEmitter::getVecShiftL32OpValue(
const MCInst &
MI,
unsigned OpIdx,
513 assert(MO.
isImm() &&
"Expected an immediate value for the scale amount!");
518AArch64MCCodeEmitter::getVecShiftL16OpValue(
const MCInst &
MI,
unsigned OpIdx,
522 assert(MO.
isImm() &&
"Expected an immediate value for the scale amount!");
527AArch64MCCodeEmitter::getVecShiftL8OpValue(
const MCInst &
MI,
unsigned OpIdx,
531 assert(MO.
isImm() &&
"Expected an immediate value for the scale amount!");
535template <
unsigned Multiple>
537AArch64MCCodeEmitter::EncodeRegAsMultipleOf(
const MCInst &
MI,
unsigned OpIdx,
541 auto RegOpnd =
MI.getOperand(OpIdx).getReg();
542 unsigned RegVal = Ctx.getRegisterInfo()->getEncodingValue(RegOpnd);
543 return RegVal / Multiple;
547AArch64MCCodeEmitter::EncodePPR_p8to15(
const MCInst &
MI,
unsigned OpIdx,
550 auto RegOpnd =
MI.getOperand(OpIdx).getReg();
551 return RegOpnd - AArch64::P8;
554uint32_t AArch64MCCodeEmitter::EncodeZPR2StridedRegisterClass(
557 auto RegOpnd =
MI.getOperand(OpIdx).getReg();
558 unsigned RegVal = Ctx.getRegisterInfo()->getEncodingValue(RegOpnd);
559 unsigned T = (RegVal & 0x10) >> 1;
560 unsigned Zt = RegVal & 0x7;
564uint32_t AArch64MCCodeEmitter::EncodeZPR4StridedRegisterClass(
567 auto RegOpnd =
MI.getOperand(OpIdx).getReg();
568 unsigned RegVal = Ctx.getRegisterInfo()->getEncodingValue(RegOpnd);
569 unsigned T = (RegVal & 0x10) >> 2;
570 unsigned Zt = RegVal & 0x3;
574uint32_t AArch64MCCodeEmitter::EncodeMatrixTileListRegisterClass(
577 unsigned RegMask =
MI.getOperand(OpIdx).getImm();
578 assert(RegMask <= 0xFF &&
"Invalid register mask!");
582template <
unsigned BaseReg>
584AArch64MCCodeEmitter::encodeMatrixIndexGPR32(
const MCInst &
MI,
unsigned OpIdx,
587 auto RegOpnd =
MI.getOperand(OpIdx).getReg();
588 return RegOpnd - BaseReg;
592AArch64MCCodeEmitter::getImm8OptLsl(
const MCInst &
MI,
unsigned OpIdx,
596 auto ShiftOpnd =
MI.getOperand(OpIdx + 1).getImm();
598 "Unexpected shift type for imm8_opt_lsl immediate.");
601 assert((ShiftVal == 0 || ShiftVal == 8) &&
602 "Unexpected shift value for imm8_opt_lsl immediate.");
605 auto Immediate =
MI.getOperand(OpIdx).getImm();
606 return (Immediate & 0xff) | (ShiftVal == 0 ? 0 : (1 << ShiftVal));
610AArch64MCCodeEmitter::getSVEIncDecImm(
const MCInst &
MI,
unsigned OpIdx,
614 assert(MO.
isImm() &&
"Expected an immediate value!");
621uint32_t AArch64MCCodeEmitter::getMoveVecShifterOpValue(
626 "Expected an immediate value for the move shift amount!");
628 assert((ShiftVal == 8 || ShiftVal == 16) &&
"Invalid shift amount!");
629 return ShiftVal == 8 ? 0 : 1;
632unsigned AArch64MCCodeEmitter::fixMOVZ(
const MCInst &
MI,
unsigned EncodedValue,
641 if (UImm16MO.
isImm())
646 switch (A64E->getKind()) {
654 return EncodedValue & ~(1u << 30);
667 if (
MI.getOpcode() == AArch64::TLSDESCCALL) {
672 ? ELF::R_AARCH64_P32_TLSDESC_CALL
673 : ELF::R_AARCH64_TLSDESC_CALL;
680 if (
MI.getOpcode() == AArch64::SPACE) {
691AArch64MCCodeEmitter::fixMulHigh(
const MCInst &
MI,
692 unsigned EncodedValue,
696 EncodedValue |= 0x1f << 10;
700template<
int hasRs,
int hasRt2>
unsigned
701AArch64MCCodeEmitter::fixLoadStoreExclusive(
const MCInst &
MI,
702 unsigned EncodedValue,
704 if (!hasRs) EncodedValue |= 0x001F0000;
705 if (!hasRt2) EncodedValue |= 0x00007C00;
710unsigned AArch64MCCodeEmitter::fixOneOperandFPComparison(
714 EncodedValue &= ~(0x1f << 16);
718#include "AArch64GenMCCodeEmitter.inc"
722 return new AArch64MCCodeEmitter(MCII, Ctx);
static uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, unsigned FixupKind, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI)
getBranchTargetOpValue - Helper function to get the branch target operand, which is either an immedia...
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
MCCodeEmitter - Generic instruction encoding interface.
MCCodeEmitter & operator=(const MCCodeEmitter &)=delete
virtual void encodeInstruction(const MCInst &Inst, raw_ostream &OS, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
EncodeInstruction - Encode the given Inst to bytes on the output stream OS.
Context object for machine code objects.
Base class for the full range of assembler expressions which are needed for parsing.
static MCFixup create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, SMLoc Loc=SMLoc())
Instances of this class represent a single low-level machine instruction.
Interface to description of machine instruction set.
Instances of this class represent operands of the MCInst class.
unsigned getReg() const
Returns the register number.
const MCExpr * getExpr() const
Generic base class for all target subtargets.
const Triple & getTargetTriple() const
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
EnvironmentType getEnvironment() const
Get the parsed environment type of this triple.
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static unsigned getShiftValue(unsigned Imm)
getShiftValue - Extract the shift value.
static AArch64_AM::ShiftExtendType getShiftType(unsigned Imm)
getShiftType - Extract the shift type.
@ fixup_aarch64_pcrel_call26
@ fixup_aarch64_pcrel_branch26
@ fixup_aarch64_pcrel_branch19
@ fixup_aarch64_ldr_pcrel_imm19
@ fixup_aarch64_pcrel_adr_imm21
@ fixup_aarch64_pcrel_branch14
@ fixup_aarch64_pcrel_adrp_imm21
@ fixup_aarch64_add_imm12
This is an optimization pass for GlobalISel generic memory operations.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
MCFixupKind
Extensible enumeration to represent the type of a fixup.
@ FirstLiteralRelocationKind
The range [FirstLiteralRelocationKind, MaxTargetFixupKind) is used for relocations coming from ....
MCCodeEmitter * createAArch64MCCodeEmitter(const MCInstrInfo &MCII, MCContext &Ctx)