34#define DEBUG_TYPE "mccodeemitter"
36STATISTIC(MCNumEmitted,
"Number of MC instructions emitted");
37STATISTIC(MCNumFixups,
"Number of MC fixups created");
41 RISCVMCCodeEmitter(
const RISCVMCCodeEmitter &) =
delete;
42 void operator=(
const RISCVMCCodeEmitter &) =
delete;
48 : Ctx(ctx), MCII(MCII) {}
50 ~RISCVMCCodeEmitter()
override =
default;
84 unsigned getImmOpValueAsr1(
const MCInst &
MI,
unsigned OpNo,
88 unsigned getImmOpValue(
const MCInst &
MI,
unsigned OpNo,
92 unsigned getVMaskReg(
const MCInst &
MI,
unsigned OpNo,
96 unsigned getRlistOpValue(
const MCInst &
MI,
unsigned OpNo,
100 unsigned getRegReg(
const MCInst &
MI,
unsigned OpNo,
108 return new RISCVMCCodeEmitter(Ctx, MCII);
119void RISCVMCCodeEmitter::expandFunctionCall(
const MCInst &
MI,
126 if (
MI.getOpcode() == RISCV::PseudoTAIL) {
127 Func =
MI.getOperand(0);
131 if (STI.
hasFeature(RISCV::FeatureStdExtZicfilp))
133 }
else if (
MI.getOpcode() == RISCV::PseudoCALLReg) {
135 Ra =
MI.getOperand(0).getReg();
136 }
else if (
MI.getOpcode() == RISCV::PseudoCALL) {
139 }
else if (
MI.getOpcode() == RISCV::PseudoJump) {
141 Ra =
MI.getOperand(0).getReg();
145 assert(
Func.isExpr() &&
"Expected expression");
151 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
154 if (
MI.getOpcode() == RISCV::PseudoTAIL ||
155 MI.getOpcode() == RISCV::PseudoJump)
161 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
165void RISCVMCCodeEmitter::expandTLSDESCCall(
const MCInst &
MI,
171 "Expected expression as first input to TLSDESCCALL");
186void RISCVMCCodeEmitter::expandAddTPRel(
const MCInst &
MI,
194 "Expected thread pointer as second input to TP-relative add");
198 "Expected expression as third input to TP-relative add");
202 "Expected tprel_add relocation on TP-relative symbol");
228 case RISCV::PseudoLongBEQ:
230 case RISCV::PseudoLongBNE:
232 case RISCV::PseudoLongBLT:
234 case RISCV::PseudoLongBGE:
236 case RISCV::PseudoLongBLTU:
238 case RISCV::PseudoLongBGEU:
245void RISCVMCCodeEmitter::expandLongCondBr(
const MCInst &
MI,
252 unsigned Opcode =
MI.getOpcode();
254 Opcode == RISCV::PseudoLongBNE || Opcode == RISCV::PseudoLongBEQ;
256 bool UseCompressedBr =
false;
257 if (IsEqTest && (STI.
hasFeature(RISCV::FeatureStdExtC) ||
259 if (RISCV::X8 <= SrcReg1.
id() && SrcReg1.
id() <= RISCV::X15 &&
260 SrcReg2.
id() == RISCV::X0) {
261 UseCompressedBr =
true;
262 }
else if (RISCV::X8 <= SrcReg2.
id() && SrcReg2.
id() <= RISCV::X15 &&
263 SrcReg1.
id() == RISCV::X0) {
265 UseCompressedBr =
true;
270 if (UseCompressedBr) {
272 Opcode == RISCV::PseudoLongBNE ? RISCV::C_BEQZ : RISCV::C_BNEZ;
300void RISCVMCCodeEmitter::encodeInstruction(
const MCInst &
MI,
311 switch (
MI.getOpcode()) {
314 case RISCV::PseudoCALLReg:
315 case RISCV::PseudoCALL:
316 case RISCV::PseudoTAIL:
317 case RISCV::PseudoJump:
318 expandFunctionCall(
MI, CB, Fixups, STI);
321 case RISCV::PseudoAddTPRel:
322 expandAddTPRel(
MI, CB, Fixups, STI);
325 case RISCV::PseudoLongBEQ:
326 case RISCV::PseudoLongBNE:
327 case RISCV::PseudoLongBLT:
328 case RISCV::PseudoLongBGE:
329 case RISCV::PseudoLongBLTU:
330 case RISCV::PseudoLongBGEU:
331 expandLongCondBr(
MI, CB, Fixups, STI);
334 case RISCV::PseudoTLSDESCCall:
335 expandTLSDESCCall(
MI, CB, Fixups, STI);
364 return Ctx.getRegisterInfo()->getEncodingValue(MO.
getReg());
367 return static_cast<unsigned>(MO.
getImm());
374RISCVMCCodeEmitter::getImmOpValueAsr1(
const MCInst &
MI,
unsigned OpNo,
380 unsigned Res = MO.
getImm();
381 assert((Res & 1) == 0 &&
"LSB is non-zero");
385 return getImmOpValue(
MI, OpNo, Fixups, STI);
388unsigned RISCVMCCodeEmitter::getImmOpValue(
const MCInst &
MI,
unsigned OpNo,
391 bool EnableRelax = STI.
hasFeature(RISCV::FeatureRelax);
402 "getImmOpValue expects only expressions or immediates");
406 bool RelaxCandidate =
false;
408 const RISCVMCExpr *RVExpr = cast<RISCVMCExpr>(Expr);
421 "VK_RISCV_TPREL_ADD should not represent an instruction operand");
429 RelaxCandidate =
true;
433 RelaxCandidate =
true;
442 "VK_RISCV_PCREL_LO used with unexpected instruction format");
443 RelaxCandidate =
true;
447 RelaxCandidate =
true;
459 "VK_RISCV_TPREL_LO used with unexpected instruction format");
460 RelaxCandidate =
true;
464 RelaxCandidate =
true;
474 RelaxCandidate =
true;
478 RelaxCandidate =
true;
494 cast<MCSymbolRefExpr>(Expr)->getKind() ==
520 if (EnableRelax && RelaxCandidate) {
531unsigned RISCVMCCodeEmitter::getVMaskReg(
const MCInst &
MI,
unsigned OpNo,
542 case RISCV::NoRegister:
547unsigned RISCVMCCodeEmitter::getRlistOpValue(
const MCInst &
MI,
unsigned OpNo,
551 assert(MO.
isImm() &&
"Rlist operand must be immediate");
553 assert(Imm >= 4 &&
"EABI is currently not implemented");
557unsigned RISCVMCCodeEmitter::getRegReg(
const MCInst &
MI,
unsigned OpNo,
564 unsigned Op = Ctx.getRegisterInfo()->getEncodingValue(MO.
getReg());
565 unsigned Op1 = Ctx.getRegisterInfo()->getEncodingValue(MO1.
getReg());
567 return Op | Op1 << 5;
570#include "RISCVGenMCCodeEmitter.inc"
static unsigned getInvertedBranchOp(unsigned BrOp)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
This class represents an Operation in the Expression.
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
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
Base class for the full range of assembler expressions which are needed for parsing.
@ SymbolRef
References to labels and assigned expressions.
@ Target
Target specific expression.
@ Binary
Binary expressions.
static MCFixup create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, SMLoc Loc=SMLoc())
MCInstBuilder & addOperand(const MCOperand &Op)
Add an operand.
MCInstBuilder & addReg(unsigned Reg)
Add a new register operand.
MCInstBuilder & addImm(int64_t Val)
Add a new integer immediate operand.
MCInstBuilder & addExpr(const MCExpr *Val)
Add a new MCExpr operand.
Instances of this class represent a single low-level machine instruction.
Describe properties that are true of each instruction in the target description file.
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
Wrapper class representing physical registers. Should be passed by value.
constexpr unsigned id() const
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
VariantKind getKind() const
@ VK_RISCV_TLSDESC_ADD_LO
@ VK_RISCV_TLSDESC_LOAD_LO
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static unsigned getFormat(uint64_t TSFlags)
@ fixup_riscv_tprel_lo12_s
@ fixup_riscv_tls_got_hi20
@ fixup_riscv_tls_gd_hi20
@ fixup_riscv_pcrel_lo12_i
@ fixup_riscv_tlsdesc_call
@ fixup_riscv_pcrel_lo12_s
@ fixup_riscv_tprel_lo12_i
@ fixup_riscv_tlsdesc_load_lo12
@ fixup_riscv_tlsdesc_hi20
@ fixup_riscv_tlsdesc_add_lo12
NodeAddr< FuncNode * > Func
void write(void *memory, value_type value, endianness endian)
Write a value to memory with a particular endianness.
This is an optimization pass for GlobalISel generic memory operations.
MCCodeEmitter * createRISCVMCCodeEmitter(const MCInstrInfo &MCII, MCContext &Ctx)
MCFixupKind
Extensible enumeration to represent the type of a fixup.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Description of the encoding of one expression Op.