34#define DEBUG_TYPE "mccodeemitter"
36STATISTIC(MCNumEmitted,
"Number of MC instructions emitted.");
37STATISTIC(MCNumFixups,
"Number of MC fixups created.");
46 AArch64MCCodeEmitter(
const AArch64MCCodeEmitter &) =
delete;
47 void operator=(
const AArch64MCCodeEmitter &) =
delete;
48 ~AArch64MCCodeEmitter()
override =
default;
65 template <u
int32_t FixupKind>
180 unsigned fixMOVZ(
const MCInst &
MI,
unsigned EncodedValue,
187 unsigned fixMulHigh(
const MCInst &
MI,
unsigned EncodedValue,
190 template<
int hasRs,
int hasRt2>
unsigned
191 fixLoadStoreExclusive(
const MCInst &
MI,
unsigned EncodedValue,
194 unsigned fixOneOperandFPComparison(
const MCInst &
MI,
unsigned EncodedValue,
197 template <
unsigned Multiple,
unsigned Min,
unsigned Max>
215 uint32_t EncodeMatrixTileListRegisterClass(
const MCInst &
MI,
unsigned OpIdx,
218 template <
unsigned BaseReg>
233 return Ctx.getRegisterInfo()->getEncodingValue(MO.
getReg());
235 assert(MO.
isImm() &&
"did not expect relocated expression");
236 return static_cast<unsigned>(MO.
getImm());
239template<
unsigned FixupKind>
uint32_t
240AArch64MCCodeEmitter::getLdStUImm12OpValue(
const MCInst &
MI,
unsigned OpIdx,
249 assert(MO.
isExpr() &&
"unable to encode load/store imm operand");
261AArch64MCCodeEmitter::getAdrLabelOpValue(
const MCInst &
MI,
unsigned OpIdx,
287AArch64MCCodeEmitter::getAddSubImmOpValue(
const MCInst &
MI,
unsigned OpIdx,
294 "unexpected shift type for add/sub immediate");
296 assert((ShiftVal == 0 || ShiftVal == 12) &&
297 "unexpected shift value for add/sub immediate");
299 return MO.
getImm() | (ShiftVal == 0 ? 0 : (1 << ShiftVal));
311 if (
const AArch64MCExpr *A64E = dyn_cast<AArch64MCExpr>(Expr)) {
318 return ShiftVal == 0 ? 0 : (1 << ShiftVal);
323uint32_t AArch64MCCodeEmitter::getCondBranchTargetOpValue(
344uint32_t AArch64MCCodeEmitter::getCondCompBranchTargetOpValue(
366AArch64MCCodeEmitter::getPAuthPCRelOpValue(
const MCInst &
MI,
unsigned OpIdx,
389AArch64MCCodeEmitter::getLoadLiteralOpValue(
const MCInst &
MI,
unsigned OpIdx,
409AArch64MCCodeEmitter::getMemExtendOpValue(
const MCInst &
MI,
unsigned OpIdx,
412 unsigned SignExtend =
MI.getOperand(OpIdx).getImm();
413 unsigned DoShift =
MI.getOperand(OpIdx + 1).getImm();
414 return (SignExtend << 1) | DoShift;
418AArch64MCCodeEmitter::getMoveWideImmOpValue(
const MCInst &
MI,
unsigned OpIdx,
425 assert(MO.
isExpr() &&
"Unexpected movz/movk immediate");
437uint32_t AArch64MCCodeEmitter::getTestBranchTargetOpValue(
459AArch64MCCodeEmitter::getBranchTargetOpValue(
const MCInst &
MI,
unsigned OpIdx,
487AArch64MCCodeEmitter::getVecShifterOpValue(
const MCInst &
MI,
unsigned OpIdx,
491 assert(MO.
isImm() &&
"Expected an immediate value for the shift amount!");
511uint32_t AArch64MCCodeEmitter::getFixedPointScaleOpValue(
515 assert(MO.
isImm() &&
"Expected an immediate value for the scale amount!");
520AArch64MCCodeEmitter::getVecShiftR64OpValue(
const MCInst &
MI,
unsigned OpIdx,
524 assert(MO.
isImm() &&
"Expected an immediate value for the scale amount!");
529AArch64MCCodeEmitter::getVecShiftR32OpValue(
const MCInst &
MI,
unsigned OpIdx,
533 assert(MO.
isImm() &&
"Expected an immediate value for the scale amount!");
538AArch64MCCodeEmitter::getVecShiftR16OpValue(
const MCInst &
MI,
unsigned OpIdx,
542 assert(MO.
isImm() &&
"Expected an immediate value for the scale amount!");
547AArch64MCCodeEmitter::getVecShiftR8OpValue(
const MCInst &
MI,
unsigned OpIdx,
551 assert(MO.
isImm() &&
"Expected an immediate value for the scale amount!");
556AArch64MCCodeEmitter::getVecShiftL64OpValue(
const MCInst &
MI,
unsigned OpIdx,
560 assert(MO.
isImm() &&
"Expected an immediate value for the scale amount!");
565AArch64MCCodeEmitter::getVecShiftL32OpValue(
const MCInst &
MI,
unsigned OpIdx,
569 assert(MO.
isImm() &&
"Expected an immediate value for the scale amount!");
574AArch64MCCodeEmitter::getVecShiftL16OpValue(
const MCInst &
MI,
unsigned OpIdx,
578 assert(MO.
isImm() &&
"Expected an immediate value for the scale amount!");
583AArch64MCCodeEmitter::getVecShiftL8OpValue(
const MCInst &
MI,
unsigned OpIdx,
587 assert(MO.
isImm() &&
"Expected an immediate value for the scale amount!");
591template <
unsigned Multiple,
unsigned Min,
unsigned Max>
593AArch64MCCodeEmitter::EncodeRegMul_MinMax(
const MCInst &
MI,
unsigned OpIdx,
597 auto RegOpnd =
MI.getOperand(OpIdx).getReg();
598 unsigned RegVal = Ctx.getRegisterInfo()->getEncodingValue(RegOpnd);
599 assert(RegVal >= Min && RegVal <= Max && (RegVal & (Multiple - 1)) == 0);
600 return (RegVal - Min) / Multiple;
609 auto RegOpnd =
MI.getOperand(OpIdx).getReg();
610 unsigned RegVal = Ctx.getRegisterInfo()->getEncodingValue(RegOpnd);
613 if (RegOpnd > AArch64::Z27)
614 return (RegVal - 24);
616 assert((RegOpnd > AArch64::Z19 && RegOpnd < AArch64::Z24) &&
617 "Expected ZK in Z20..Z23 or Z28..Z31");
619 return (RegVal - 20);
623AArch64MCCodeEmitter::EncodePNR_p8to15(
const MCInst &
MI,
unsigned OpIdx,
626 auto RegOpnd =
MI.getOperand(OpIdx).getReg();
627 return RegOpnd - AArch64::PN8;
630uint32_t AArch64MCCodeEmitter::EncodeZPR2StridedRegisterClass(
633 auto RegOpnd =
MI.getOperand(OpIdx).getReg();
634 unsigned RegVal = Ctx.getRegisterInfo()->getEncodingValue(RegOpnd);
635 unsigned T = (RegVal & 0x10) >> 1;
636 unsigned Zt = RegVal & 0x7;
640uint32_t AArch64MCCodeEmitter::EncodeZPR4StridedRegisterClass(
643 auto RegOpnd =
MI.getOperand(OpIdx).getReg();
644 unsigned RegVal = Ctx.getRegisterInfo()->getEncodingValue(RegOpnd);
645 unsigned T = (RegVal & 0x10) >> 2;
646 unsigned Zt = RegVal & 0x3;
650uint32_t AArch64MCCodeEmitter::EncodeMatrixTileListRegisterClass(
653 unsigned RegMask =
MI.getOperand(OpIdx).getImm();
654 assert(RegMask <= 0xFF &&
"Invalid register mask!");
658template <
unsigned BaseReg>
660AArch64MCCodeEmitter::encodeMatrixIndexGPR32(
const MCInst &
MI,
unsigned OpIdx,
663 auto RegOpnd =
MI.getOperand(OpIdx).getReg();
664 return RegOpnd - BaseReg;
668AArch64MCCodeEmitter::getImm8OptLsl(
const MCInst &
MI,
unsigned OpIdx,
672 auto ShiftOpnd =
MI.getOperand(OpIdx + 1).getImm();
674 "Unexpected shift type for imm8_opt_lsl immediate.");
677 assert((ShiftVal == 0 || ShiftVal == 8) &&
678 "Unexpected shift value for imm8_opt_lsl immediate.");
681 auto Immediate =
MI.getOperand(OpIdx).getImm();
682 return (Immediate & 0xff) | (ShiftVal == 0 ? 0 : (1 << ShiftVal));
686AArch64MCCodeEmitter::getSVEIncDecImm(
const MCInst &
MI,
unsigned OpIdx,
690 assert(MO.
isImm() &&
"Expected an immediate value!");
697uint32_t AArch64MCCodeEmitter::getMoveVecShifterOpValue(
702 "Expected an immediate value for the move shift amount!");
704 assert((ShiftVal == 8 || ShiftVal == 16) &&
"Invalid shift amount!");
705 return ShiftVal == 8 ? 0 : 1;
708unsigned AArch64MCCodeEmitter::fixMOVZ(
const MCInst &
MI,
unsigned EncodedValue,
717 if (UImm16MO.
isImm())
721 if (
const AArch64MCExpr *A64E = dyn_cast<AArch64MCExpr>(E)) {
722 switch (A64E->getKind()) {
730 return EncodedValue & ~(1u << 30);
740void AArch64MCCodeEmitter::encodeInstruction(
const MCInst &
MI,
745 if (
MI.getOpcode() == AArch64::TLSDESCCALL) {
750 ? ELF::R_AARCH64_P32_TLSDESC_CALL
751 : ELF::R_AARCH64_TLSDESC_CALL;
758 if (
MI.getOpcode() == AArch64::SPACE) {
769AArch64MCCodeEmitter::fixMulHigh(
const MCInst &
MI,
770 unsigned EncodedValue,
774 EncodedValue |= 0x1f << 10;
778template<
int hasRs,
int hasRt2>
unsigned
779AArch64MCCodeEmitter::fixLoadStoreExclusive(
const MCInst &
MI,
780 unsigned EncodedValue,
782 if (!hasRs) EncodedValue |= 0x001F0000;
783 if (!hasRt2) EncodedValue |= 0x00007C00;
788unsigned AArch64MCCodeEmitter::fixOneOperandFPComparison(
792 EncodedValue &= ~(0x1f << 16);
796#include "AArch64GenMCCodeEmitter.inc"
800 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...
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.
MCRegister 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_branch9
@ fixup_aarch64_pcrel_branch16
@ 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)