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;
80 unsigned getImmOpValueAsr1(
const MCInst &
MI,
unsigned OpNo,
84 unsigned getImmOpValue(
const MCInst &
MI,
unsigned OpNo,
88 unsigned getVMaskReg(
const MCInst &
MI,
unsigned OpNo,
92 unsigned getRlistOpValue(
const MCInst &
MI,
unsigned OpNo,
96 unsigned getRegReg(
const MCInst &
MI,
unsigned OpNo,
104 return new RISCVMCCodeEmitter(Ctx, MCII);
115void RISCVMCCodeEmitter::expandFunctionCall(
const MCInst &
MI,
122 if (
MI.getOpcode() == RISCV::PseudoTAIL) {
123 Func =
MI.getOperand(0);
125 }
else if (
MI.getOpcode() == RISCV::PseudoCALLReg) {
127 Ra =
MI.getOperand(0).getReg();
128 }
else if (
MI.getOpcode() == RISCV::PseudoCALL) {
131 }
else if (
MI.getOpcode() == RISCV::PseudoJump) {
133 Ra =
MI.getOperand(0).getReg();
137 assert(
Func.isExpr() &&
"Expected expression");
143 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
146 if (
MI.getOpcode() == RISCV::PseudoTAIL ||
147 MI.getOpcode() == RISCV::PseudoJump)
153 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
158void RISCVMCCodeEmitter::expandAddTPRel(
const MCInst &
MI,
166 "Expected thread pointer as second input to TP-relative add");
170 "Expected expression as third input to TP-relative add");
174 "Expected tprel_add relocation on TP-relative symbol");
200 case RISCV::PseudoLongBEQ:
202 case RISCV::PseudoLongBNE:
204 case RISCV::PseudoLongBLT:
206 case RISCV::PseudoLongBGE:
208 case RISCV::PseudoLongBLTU:
210 case RISCV::PseudoLongBGEU:
217void RISCVMCCodeEmitter::expandLongCondBr(
const MCInst &
MI,
226 Opcode == RISCV::PseudoLongBNE ||
Opcode == RISCV::PseudoLongBEQ;
228 bool UseCompressedBr =
false;
229 if (IsEqTest && (STI.
hasFeature(RISCV::FeatureStdExtC) ||
231 if (RISCV::X8 <= SrcReg1.
id() && SrcReg1.
id() <= RISCV::X15 &&
232 SrcReg2.
id() == RISCV::X0) {
233 UseCompressedBr =
true;
234 }
else if (RISCV::X8 <= SrcReg2.
id() && SrcReg2.
id() <= RISCV::X15 &&
235 SrcReg1.
id() == RISCV::X0) {
237 UseCompressedBr =
true;
242 if (UseCompressedBr) {
244 Opcode == RISCV::PseudoLongBNE ? RISCV::C_BEQZ : RISCV::C_BNEZ;
272void RISCVMCCodeEmitter::encodeInstruction(
const MCInst &
MI,
283 switch (
MI.getOpcode()) {
286 case RISCV::PseudoCALLReg:
287 case RISCV::PseudoCALL:
288 case RISCV::PseudoTAIL:
289 case RISCV::PseudoJump:
290 expandFunctionCall(
MI, CB, Fixups, STI);
293 case RISCV::PseudoAddTPRel:
294 expandAddTPRel(
MI, CB, Fixups, STI);
297 case RISCV::PseudoLongBEQ:
298 case RISCV::PseudoLongBNE:
299 case RISCV::PseudoLongBLT:
300 case RISCV::PseudoLongBGE:
301 case RISCV::PseudoLongBLTU:
302 case RISCV::PseudoLongBGEU:
303 expandLongCondBr(
MI, CB, Fixups, STI);
332 return Ctx.getRegisterInfo()->getEncodingValue(MO.
getReg());
335 return static_cast<unsigned>(MO.
getImm());
342RISCVMCCodeEmitter::getImmOpValueAsr1(
const MCInst &
MI,
unsigned OpNo,
348 unsigned Res = MO.
getImm();
349 assert((Res & 1) == 0 &&
"LSB is non-zero");
353 return getImmOpValue(
MI, OpNo, Fixups, STI);
356unsigned RISCVMCCodeEmitter::getImmOpValue(
const MCInst &
MI,
unsigned OpNo,
359 bool EnableRelax = STI.
hasFeature(RISCV::FeatureRelax);
370 "getImmOpValue expects only expressions or immediates");
374 bool RelaxCandidate =
false;
376 const RISCVMCExpr *RVExpr = cast<RISCVMCExpr>(Expr);
389 "VK_RISCV_TPREL_ADD should not represent an instruction operand");
397 RelaxCandidate =
true;
401 RelaxCandidate =
true;
410 "VK_RISCV_PCREL_LO used with unexpected instruction format");
411 RelaxCandidate =
true;
415 RelaxCandidate =
true;
427 "VK_RISCV_TPREL_LO used with unexpected instruction format");
428 RelaxCandidate =
true;
432 RelaxCandidate =
true;
442 RelaxCandidate =
true;
446 RelaxCandidate =
true;
450 cast<MCSymbolRefExpr>(Expr)->getKind() ==
476 if (EnableRelax && RelaxCandidate) {
487unsigned RISCVMCCodeEmitter::getVMaskReg(
const MCInst &
MI,
unsigned OpNo,
498 case RISCV::NoRegister:
503unsigned RISCVMCCodeEmitter::getRlistOpValue(
const MCInst &
MI,
unsigned OpNo,
507 assert(MO.
isImm() &&
"Rlist operand must be immediate");
509 assert(Imm >= 4 &&
"EABI is currently not implemented");
513unsigned RISCVMCCodeEmitter::getRegReg(
const MCInst &
MI,
unsigned OpNo,
520 unsigned Op = Ctx.getRegisterInfo()->getEncodingValue(MO.
getReg());
521 unsigned Op1 = Ctx.getRegisterInfo()->getEncodingValue(MO1.
getReg());
523 return Op | Op1 << 5;
526#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)
static constexpr uint32_t Opcode
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
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_pcrel_lo12_s
@ fixup_riscv_tprel_lo12_i
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.