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>
206 uint32_t EncodeMatrixTileListRegisterClass(
const MCInst &
MI,
unsigned OpIdx,
209 template <
unsigned BaseReg>
224 return Ctx.getRegisterInfo()->getEncodingValue(MO.
getReg());
226 assert(MO.
isImm() &&
"did not expect relocated expression");
227 return static_cast<unsigned>(MO.
getImm());
230template<
unsigned FixupKind>
uint32_t
231AArch64MCCodeEmitter::getLdStUImm12OpValue(
const MCInst &
MI,
unsigned OpIdx,
240 assert(MO.
isExpr() &&
"unable to encode load/store imm operand");
252AArch64MCCodeEmitter::getAdrLabelOpValue(
const MCInst &
MI,
unsigned OpIdx,
278AArch64MCCodeEmitter::getAddSubImmOpValue(
const MCInst &
MI,
unsigned OpIdx,
285 "unexpected shift type for add/sub immediate");
287 assert((ShiftVal == 0 || ShiftVal == 12) &&
288 "unexpected shift value for add/sub immediate");
290 return MO.
getImm() | (ShiftVal == 0 ? 0 : (1 << ShiftVal));
302 if (
const AArch64MCExpr *A64E = dyn_cast<AArch64MCExpr>(Expr)) {
309 return ShiftVal == 0 ? 0 : (1 << ShiftVal);
314uint32_t AArch64MCCodeEmitter::getCondBranchTargetOpValue(
336AArch64MCCodeEmitter::getLoadLiteralOpValue(
const MCInst &
MI,
unsigned OpIdx,
356AArch64MCCodeEmitter::getMemExtendOpValue(
const MCInst &
MI,
unsigned OpIdx,
359 unsigned SignExtend =
MI.getOperand(OpIdx).getImm();
360 unsigned DoShift =
MI.getOperand(OpIdx + 1).getImm();
361 return (SignExtend << 1) | DoShift;
365AArch64MCCodeEmitter::getMoveWideImmOpValue(
const MCInst &
MI,
unsigned OpIdx,
372 assert(MO.
isExpr() &&
"Unexpected movz/movk immediate");
384uint32_t AArch64MCCodeEmitter::getTestBranchTargetOpValue(
406AArch64MCCodeEmitter::getBranchTargetOpValue(
const MCInst &
MI,
unsigned OpIdx,
434AArch64MCCodeEmitter::getVecShifterOpValue(
const MCInst &
MI,
unsigned OpIdx,
438 assert(MO.
isImm() &&
"Expected an immediate value for the shift amount!");
458uint32_t AArch64MCCodeEmitter::getFixedPointScaleOpValue(
462 assert(MO.
isImm() &&
"Expected an immediate value for the scale amount!");
467AArch64MCCodeEmitter::getVecShiftR64OpValue(
const MCInst &
MI,
unsigned OpIdx,
471 assert(MO.
isImm() &&
"Expected an immediate value for the scale amount!");
476AArch64MCCodeEmitter::getVecShiftR32OpValue(
const MCInst &
MI,
unsigned OpIdx,
480 assert(MO.
isImm() &&
"Expected an immediate value for the scale amount!");
485AArch64MCCodeEmitter::getVecShiftR16OpValue(
const MCInst &
MI,
unsigned OpIdx,
489 assert(MO.
isImm() &&
"Expected an immediate value for the scale amount!");
494AArch64MCCodeEmitter::getVecShiftR8OpValue(
const MCInst &
MI,
unsigned OpIdx,
498 assert(MO.
isImm() &&
"Expected an immediate value for the scale amount!");
503AArch64MCCodeEmitter::getVecShiftL64OpValue(
const MCInst &
MI,
unsigned OpIdx,
507 assert(MO.
isImm() &&
"Expected an immediate value for the scale amount!");
512AArch64MCCodeEmitter::getVecShiftL32OpValue(
const MCInst &
MI,
unsigned OpIdx,
516 assert(MO.
isImm() &&
"Expected an immediate value for the scale amount!");
521AArch64MCCodeEmitter::getVecShiftL16OpValue(
const MCInst &
MI,
unsigned OpIdx,
525 assert(MO.
isImm() &&
"Expected an immediate value for the scale amount!");
530AArch64MCCodeEmitter::getVecShiftL8OpValue(
const MCInst &
MI,
unsigned OpIdx,
534 assert(MO.
isImm() &&
"Expected an immediate value for the scale amount!");
538template <
unsigned Multiple>
540AArch64MCCodeEmitter::EncodeRegAsMultipleOf(
const MCInst &
MI,
unsigned OpIdx,
544 auto RegOpnd =
MI.getOperand(OpIdx).getReg();
545 unsigned RegVal = Ctx.getRegisterInfo()->getEncodingValue(RegOpnd);
546 return RegVal / Multiple;
550AArch64MCCodeEmitter::EncodePPR_p8to15(
const MCInst &
MI,
unsigned OpIdx,
553 auto RegOpnd =
MI.getOperand(OpIdx).getReg();
554 return RegOpnd - AArch64::P8;
558AArch64MCCodeEmitter::EncodePNR_p8to15(
const MCInst &
MI,
unsigned OpIdx,
561 auto RegOpnd =
MI.getOperand(OpIdx).getReg();
562 return RegOpnd - AArch64::PN8;
565uint32_t AArch64MCCodeEmitter::EncodeZPR2StridedRegisterClass(
568 auto RegOpnd =
MI.getOperand(OpIdx).getReg();
569 unsigned RegVal = Ctx.getRegisterInfo()->getEncodingValue(RegOpnd);
570 unsigned T = (RegVal & 0x10) >> 1;
571 unsigned Zt = RegVal & 0x7;
575uint32_t AArch64MCCodeEmitter::EncodeZPR4StridedRegisterClass(
578 auto RegOpnd =
MI.getOperand(OpIdx).getReg();
579 unsigned RegVal = Ctx.getRegisterInfo()->getEncodingValue(RegOpnd);
580 unsigned T = (RegVal & 0x10) >> 2;
581 unsigned Zt = RegVal & 0x3;
585uint32_t AArch64MCCodeEmitter::EncodeMatrixTileListRegisterClass(
588 unsigned RegMask =
MI.getOperand(OpIdx).getImm();
589 assert(RegMask <= 0xFF &&
"Invalid register mask!");
593template <
unsigned BaseReg>
595AArch64MCCodeEmitter::encodeMatrixIndexGPR32(
const MCInst &
MI,
unsigned OpIdx,
598 auto RegOpnd =
MI.getOperand(OpIdx).getReg();
599 return RegOpnd - BaseReg;
603AArch64MCCodeEmitter::getImm8OptLsl(
const MCInst &
MI,
unsigned OpIdx,
607 auto ShiftOpnd =
MI.getOperand(OpIdx + 1).getImm();
609 "Unexpected shift type for imm8_opt_lsl immediate.");
612 assert((ShiftVal == 0 || ShiftVal == 8) &&
613 "Unexpected shift value for imm8_opt_lsl immediate.");
616 auto Immediate =
MI.getOperand(OpIdx).getImm();
617 return (Immediate & 0xff) | (ShiftVal == 0 ? 0 : (1 << ShiftVal));
621AArch64MCCodeEmitter::getSVEIncDecImm(
const MCInst &
MI,
unsigned OpIdx,
625 assert(MO.
isImm() &&
"Expected an immediate value!");
632uint32_t AArch64MCCodeEmitter::getMoveVecShifterOpValue(
637 "Expected an immediate value for the move shift amount!");
639 assert((ShiftVal == 8 || ShiftVal == 16) &&
"Invalid shift amount!");
640 return ShiftVal == 8 ? 0 : 1;
643unsigned AArch64MCCodeEmitter::fixMOVZ(
const MCInst &
MI,
unsigned EncodedValue,
652 if (UImm16MO.
isImm())
657 switch (A64E->getKind()) {
665 return EncodedValue & ~(1u << 30);
675void AArch64MCCodeEmitter::encodeInstruction(
const MCInst &
MI,
680 if (
MI.getOpcode() == AArch64::TLSDESCCALL) {
685 ? ELF::R_AARCH64_P32_TLSDESC_CALL
686 : ELF::R_AARCH64_TLSDESC_CALL;
693 if (
MI.getOpcode() == AArch64::SPACE) {
704AArch64MCCodeEmitter::fixMulHigh(
const MCInst &
MI,
705 unsigned EncodedValue,
709 EncodedValue |= 0x1f << 10;
713template<
int hasRs,
int hasRt2>
unsigned
714AArch64MCCodeEmitter::fixLoadStoreExclusive(
const MCInst &
MI,
715 unsigned EncodedValue,
717 if (!hasRs) EncodedValue |= 0x001F0000;
718 if (!hasRt2) EncodedValue |= 0x00007C00;
723unsigned AArch64MCCodeEmitter::fixOneOperandFPComparison(
727 EncodedValue &= ~(0x1f << 16);
731#include "AArch64GenMCCodeEmitter.inc"
735 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.
virtual void encodeInstruction(const MCInst &Inst, SmallVectorImpl< char > &CB, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const =0
Encode the given Inst to bytes and append to CB.
MCCodeEmitter & operator=(const MCCodeEmitter &)=delete
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.
#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)