37 #define DEBUG_TYPE "mccodeemitter"
39 STATISTIC(MCNumEmitted,
"Number of MC instructions emitted.");
40 STATISTIC(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());
227 template<
unsigned FixupKind>
uint32_t
228 AArch64MCCodeEmitter::getLdStUImm12OpValue(
const MCInst &
MI,
unsigned OpIdx,
237 assert(MO.
isExpr() &&
"unable to encode load/store imm operand");
249 AArch64MCCodeEmitter::getAdrLabelOpValue(
const MCInst &
MI,
unsigned OpIdx,
275 AArch64MCCodeEmitter::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);
311 uint32_t AArch64MCCodeEmitter::getCondBranchTargetOpValue(
333 AArch64MCCodeEmitter::getLoadLiteralOpValue(
const MCInst &
MI,
unsigned OpIdx,
353 AArch64MCCodeEmitter::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;
362 AArch64MCCodeEmitter::getMoveWideImmOpValue(
const MCInst &
MI,
unsigned OpIdx,
369 assert(MO.
isExpr() &&
"Unexpected movz/movk immediate");
381 uint32_t AArch64MCCodeEmitter::getTestBranchTargetOpValue(
431 AArch64MCCodeEmitter::getVecShifterOpValue(
const MCInst &
MI,
unsigned OpIdx,
435 assert(MO.
isImm() &&
"Expected an immediate value for the shift amount!");
455 uint32_t AArch64MCCodeEmitter::getFixedPointScaleOpValue(
459 assert(MO.
isImm() &&
"Expected an immediate value for the scale amount!");
464 AArch64MCCodeEmitter::getVecShiftR64OpValue(
const MCInst &
MI,
unsigned OpIdx,
468 assert(MO.
isImm() &&
"Expected an immediate value for the scale amount!");
473 AArch64MCCodeEmitter::getVecShiftR32OpValue(
const MCInst &
MI,
unsigned OpIdx,
477 assert(MO.
isImm() &&
"Expected an immediate value for the scale amount!");
482 AArch64MCCodeEmitter::getVecShiftR16OpValue(
const MCInst &
MI,
unsigned OpIdx,
486 assert(MO.
isImm() &&
"Expected an immediate value for the scale amount!");
491 AArch64MCCodeEmitter::getVecShiftR8OpValue(
const MCInst &
MI,
unsigned OpIdx,
495 assert(MO.
isImm() &&
"Expected an immediate value for the scale amount!");
500 AArch64MCCodeEmitter::getVecShiftL64OpValue(
const MCInst &
MI,
unsigned OpIdx,
504 assert(MO.
isImm() &&
"Expected an immediate value for the scale amount!");
509 AArch64MCCodeEmitter::getVecShiftL32OpValue(
const MCInst &
MI,
unsigned OpIdx,
513 assert(MO.
isImm() &&
"Expected an immediate value for the scale amount!");
518 AArch64MCCodeEmitter::getVecShiftL16OpValue(
const MCInst &
MI,
unsigned OpIdx,
522 assert(MO.
isImm() &&
"Expected an immediate value for the scale amount!");
527 AArch64MCCodeEmitter::getVecShiftL8OpValue(
const MCInst &
MI,
unsigned OpIdx,
531 assert(MO.
isImm() &&
"Expected an immediate value for the scale amount!");
535 template <
unsigned Multiple>
537 AArch64MCCodeEmitter::EncodeRegAsMultipleOf(
const MCInst &
MI,
unsigned OpIdx,
541 auto RegOpnd =
MI.getOperand(OpIdx).getReg();
542 unsigned RegVal = Ctx.getRegisterInfo()->getEncodingValue(RegOpnd);
543 return RegVal / Multiple;
547 AArch64MCCodeEmitter::EncodePPR_p8to15(
const MCInst &
MI,
unsigned OpIdx,
550 auto RegOpnd =
MI.getOperand(OpIdx).getReg();
551 return RegOpnd - AArch64::P8;
554 uint32_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;
564 uint32_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;
574 uint32_t AArch64MCCodeEmitter::EncodeMatrixTileListRegisterClass(
577 unsigned RegMask =
MI.getOperand(OpIdx).getImm();
578 assert(RegMask <= 0xFF &&
"Invalid register mask!");
582 template <
unsigned BaseReg>
584 AArch64MCCodeEmitter::encodeMatrixIndexGPR32(
const MCInst &
MI,
unsigned OpIdx,
587 auto RegOpnd =
MI.getOperand(OpIdx).getReg();
588 return RegOpnd - BaseReg;
592 AArch64MCCodeEmitter::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));
610 AArch64MCCodeEmitter::getSVEIncDecImm(
const MCInst &
MI,
unsigned OpIdx,
614 assert(MO.
isImm() &&
"Expected an immediate value!");
621 uint32_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;
632 unsigned 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) {
691 AArch64MCCodeEmitter::fixMulHigh(
const MCInst &
MI,
692 unsigned EncodedValue,
696 EncodedValue |= 0x1f << 10;
700 template<
int hasRs,
int hasRt2>
unsigned
701 AArch64MCCodeEmitter::fixLoadStoreExclusive(
const MCInst &
MI,
702 unsigned EncodedValue,
704 if (!hasRs) EncodedValue |= 0x001F0000;
705 if (!hasRt2) EncodedValue |= 0x00007C00;
710 unsigned AArch64MCCodeEmitter::fixOneOperandFPComparison(
714 EncodedValue &= ~(0x1f << 16);
718 #include "AArch64GenMCCodeEmitter.inc"
722 return new AArch64MCCodeEmitter(MCII, Ctx);