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>
177 unsigned fixMOVZ(
const MCInst &
MI,
unsigned EncodedValue,
184 unsigned fixMulHigh(
const MCInst &
MI,
unsigned EncodedValue,
187 template<
int hasRs,
int hasRt2>
unsigned
188 fixLoadStoreExclusive(
const MCInst &
MI,
unsigned EncodedValue,
191 unsigned fixOneOperandFPComparison(
const MCInst &
MI,
unsigned EncodedValue,
194 template <
unsigned Multiple>
209 uint32_t EncodeMatrixTileListRegisterClass(
const MCInst &
MI,
unsigned OpIdx,
212 template <
unsigned BaseReg>
227 return Ctx.getRegisterInfo()->getEncodingValue(MO.
getReg());
229 assert(MO.
isImm() &&
"did not expect relocated expression");
230 return static_cast<unsigned>(MO.
getImm());
233template<
unsigned FixupKind>
uint32_t
234AArch64MCCodeEmitter::getLdStUImm12OpValue(
const MCInst &
MI,
unsigned OpIdx,
243 assert(MO.
isExpr() &&
"unable to encode load/store imm operand");
255AArch64MCCodeEmitter::getAdrLabelOpValue(
const MCInst &
MI,
unsigned OpIdx,
281AArch64MCCodeEmitter::getAddSubImmOpValue(
const MCInst &
MI,
unsigned OpIdx,
288 "unexpected shift type for add/sub immediate");
290 assert((ShiftVal == 0 || ShiftVal == 12) &&
291 "unexpected shift value for add/sub immediate");
293 return MO.
getImm() | (ShiftVal == 0 ? 0 : (1 << ShiftVal));
305 if (
const AArch64MCExpr *A64E = dyn_cast<AArch64MCExpr>(Expr)) {
312 return ShiftVal == 0 ? 0 : (1 << ShiftVal);
317uint32_t AArch64MCCodeEmitter::getCondBranchTargetOpValue(
339AArch64MCCodeEmitter::getPAuthPCRelOpValue(
const MCInst &
MI,
unsigned OpIdx,
362AArch64MCCodeEmitter::getLoadLiteralOpValue(
const MCInst &
MI,
unsigned OpIdx,
382AArch64MCCodeEmitter::getMemExtendOpValue(
const MCInst &
MI,
unsigned OpIdx,
385 unsigned SignExtend =
MI.getOperand(OpIdx).getImm();
386 unsigned DoShift =
MI.getOperand(OpIdx + 1).getImm();
387 return (SignExtend << 1) | DoShift;
391AArch64MCCodeEmitter::getMoveWideImmOpValue(
const MCInst &
MI,
unsigned OpIdx,
398 assert(MO.
isExpr() &&
"Unexpected movz/movk immediate");
410uint32_t AArch64MCCodeEmitter::getTestBranchTargetOpValue(
432AArch64MCCodeEmitter::getBranchTargetOpValue(
const MCInst &
MI,
unsigned OpIdx,
460AArch64MCCodeEmitter::getVecShifterOpValue(
const MCInst &
MI,
unsigned OpIdx,
464 assert(MO.
isImm() &&
"Expected an immediate value for the shift amount!");
484uint32_t AArch64MCCodeEmitter::getFixedPointScaleOpValue(
488 assert(MO.
isImm() &&
"Expected an immediate value for the scale amount!");
493AArch64MCCodeEmitter::getVecShiftR64OpValue(
const MCInst &
MI,
unsigned OpIdx,
497 assert(MO.
isImm() &&
"Expected an immediate value for the scale amount!");
502AArch64MCCodeEmitter::getVecShiftR32OpValue(
const MCInst &
MI,
unsigned OpIdx,
506 assert(MO.
isImm() &&
"Expected an immediate value for the scale amount!");
511AArch64MCCodeEmitter::getVecShiftR16OpValue(
const MCInst &
MI,
unsigned OpIdx,
515 assert(MO.
isImm() &&
"Expected an immediate value for the scale amount!");
520AArch64MCCodeEmitter::getVecShiftR8OpValue(
const MCInst &
MI,
unsigned OpIdx,
524 assert(MO.
isImm() &&
"Expected an immediate value for the scale amount!");
529AArch64MCCodeEmitter::getVecShiftL64OpValue(
const MCInst &
MI,
unsigned OpIdx,
533 assert(MO.
isImm() &&
"Expected an immediate value for the scale amount!");
538AArch64MCCodeEmitter::getVecShiftL32OpValue(
const MCInst &
MI,
unsigned OpIdx,
542 assert(MO.
isImm() &&
"Expected an immediate value for the scale amount!");
547AArch64MCCodeEmitter::getVecShiftL16OpValue(
const MCInst &
MI,
unsigned OpIdx,
551 assert(MO.
isImm() &&
"Expected an immediate value for the scale amount!");
556AArch64MCCodeEmitter::getVecShiftL8OpValue(
const MCInst &
MI,
unsigned OpIdx,
560 assert(MO.
isImm() &&
"Expected an immediate value for the scale amount!");
564template <
unsigned Multiple>
566AArch64MCCodeEmitter::EncodeRegAsMultipleOf(
const MCInst &
MI,
unsigned OpIdx,
570 auto RegOpnd =
MI.getOperand(OpIdx).getReg();
571 unsigned RegVal = Ctx.getRegisterInfo()->getEncodingValue(RegOpnd);
572 return RegVal / Multiple;
576AArch64MCCodeEmitter::EncodePNR_p8to15(
const MCInst &
MI,
unsigned OpIdx,
579 auto RegOpnd =
MI.getOperand(OpIdx).getReg();
580 return RegOpnd - AArch64::PN8;
583uint32_t AArch64MCCodeEmitter::EncodeZPR2StridedRegisterClass(
586 auto RegOpnd =
MI.getOperand(OpIdx).getReg();
587 unsigned RegVal = Ctx.getRegisterInfo()->getEncodingValue(RegOpnd);
588 unsigned T = (RegVal & 0x10) >> 1;
589 unsigned Zt = RegVal & 0x7;
593uint32_t AArch64MCCodeEmitter::EncodeZPR4StridedRegisterClass(
596 auto RegOpnd =
MI.getOperand(OpIdx).getReg();
597 unsigned RegVal = Ctx.getRegisterInfo()->getEncodingValue(RegOpnd);
598 unsigned T = (RegVal & 0x10) >> 2;
599 unsigned Zt = RegVal & 0x3;
603uint32_t AArch64MCCodeEmitter::EncodeMatrixTileListRegisterClass(
606 unsigned RegMask =
MI.getOperand(OpIdx).getImm();
607 assert(RegMask <= 0xFF &&
"Invalid register mask!");
611template <
unsigned BaseReg>
613AArch64MCCodeEmitter::encodeMatrixIndexGPR32(
const MCInst &
MI,
unsigned OpIdx,
616 auto RegOpnd =
MI.getOperand(OpIdx).getReg();
617 return RegOpnd - BaseReg;
621AArch64MCCodeEmitter::getImm8OptLsl(
const MCInst &
MI,
unsigned OpIdx,
625 auto ShiftOpnd =
MI.getOperand(OpIdx + 1).getImm();
627 "Unexpected shift type for imm8_opt_lsl immediate.");
630 assert((ShiftVal == 0 || ShiftVal == 8) &&
631 "Unexpected shift value for imm8_opt_lsl immediate.");
634 auto Immediate =
MI.getOperand(OpIdx).getImm();
635 return (Immediate & 0xff) | (ShiftVal == 0 ? 0 : (1 << ShiftVal));
639AArch64MCCodeEmitter::getSVEIncDecImm(
const MCInst &
MI,
unsigned OpIdx,
643 assert(MO.
isImm() &&
"Expected an immediate value!");
650uint32_t AArch64MCCodeEmitter::getMoveVecShifterOpValue(
655 "Expected an immediate value for the move shift amount!");
657 assert((ShiftVal == 8 || ShiftVal == 16) &&
"Invalid shift amount!");
658 return ShiftVal == 8 ? 0 : 1;
661unsigned AArch64MCCodeEmitter::fixMOVZ(
const MCInst &
MI,
unsigned EncodedValue,
670 if (UImm16MO.
isImm())
674 if (
const AArch64MCExpr *A64E = dyn_cast<AArch64MCExpr>(E)) {
675 switch (A64E->getKind()) {
683 return EncodedValue & ~(1u << 30);
693void AArch64MCCodeEmitter::encodeInstruction(
const MCInst &
MI,
698 if (
MI.getOpcode() == AArch64::TLSDESCCALL) {
703 ? ELF::R_AARCH64_P32_TLSDESC_CALL
704 : ELF::R_AARCH64_TLSDESC_CALL;
711 if (
MI.getOpcode() == AArch64::SPACE) {
722AArch64MCCodeEmitter::fixMulHigh(
const MCInst &
MI,
723 unsigned EncodedValue,
727 EncodedValue |= 0x1f << 10;
731template<
int hasRs,
int hasRt2>
unsigned
732AArch64MCCodeEmitter::fixLoadStoreExclusive(
const MCInst &
MI,
733 unsigned EncodedValue,
735 if (!hasRs) EncodedValue |= 0x001F0000;
736 if (!hasRt2) EncodedValue |= 0x00007C00;
741unsigned AArch64MCCodeEmitter::fixOneOperandFPComparison(
745 EncodedValue &= ~(0x1f << 16);
749#include "AArch64GenMCCodeEmitter.inc"
753 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.
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_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)