33#define DEBUG_TYPE "mccodeemitter"
35STATISTIC(MCNumEmitted,
"Number of MC instructions emitted");
36STATISTIC(MCNumFixups,
"Number of MC fixups created");
40 RISCVMCCodeEmitter(
const RISCVMCCodeEmitter &) =
delete;
41 void operator=(
const RISCVMCCodeEmitter &) =
delete;
47 : Ctx(ctx), MCII(MCII) {}
49 ~RISCVMCCodeEmitter()
override =
default;
83 unsigned getImmOpValueAsr1(
const MCInst &
MI,
unsigned OpNo,
87 unsigned getImmOpValue(
const MCInst &
MI,
unsigned OpNo,
91 unsigned getVMaskReg(
const MCInst &
MI,
unsigned OpNo,
95 unsigned getRlistOpValue(
const MCInst &
MI,
unsigned OpNo,
99 unsigned getRegReg(
const MCInst &
MI,
unsigned OpNo,
107 return new RISCVMCCodeEmitter(Ctx, MCII);
118void RISCVMCCodeEmitter::expandFunctionCall(
const MCInst &
MI,
125 if (
MI.getOpcode() == RISCV::PseudoTAIL) {
126 Func =
MI.getOperand(0);
128 }
else if (
MI.getOpcode() == RISCV::PseudoCALLReg) {
130 Ra =
MI.getOperand(0).getReg();
131 }
else if (
MI.getOpcode() == RISCV::PseudoCALL) {
134 }
else if (
MI.getOpcode() == RISCV::PseudoJump) {
136 Ra =
MI.getOperand(0).getReg();
140 assert(
Func.isExpr() &&
"Expected expression");
146 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
149 if (
MI.getOpcode() == RISCV::PseudoTAIL ||
150 MI.getOpcode() == RISCV::PseudoJump)
156 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
160void RISCVMCCodeEmitter::expandTLSDESCCall(
const MCInst &
MI,
166 "Expected expression as first input to TLSDESCCALL");
170 int64_t
Imm =
MI.getOperand(2).getImm();
181void RISCVMCCodeEmitter::expandAddTPRel(
const MCInst &
MI,
189 "Expected thread pointer as second input to TP-relative add");
193 "Expected expression as third input to TP-relative add");
197 "Expected tprel_add relocation on TP-relative symbol");
223 case RISCV::PseudoLongBEQ:
225 case RISCV::PseudoLongBNE:
227 case RISCV::PseudoLongBLT:
229 case RISCV::PseudoLongBGE:
231 case RISCV::PseudoLongBLTU:
233 case RISCV::PseudoLongBGEU:
240void RISCVMCCodeEmitter::expandLongCondBr(
const MCInst &
MI,
247 unsigned Opcode =
MI.getOpcode();
249 Opcode == RISCV::PseudoLongBNE || Opcode == RISCV::PseudoLongBEQ;
251 bool UseCompressedBr =
false;
252 if (IsEqTest && (STI.
hasFeature(RISCV::FeatureStdExtC) ||
254 if (RISCV::X8 <= SrcReg1.
id() && SrcReg1.
id() <= RISCV::X15 &&
255 SrcReg2.
id() == RISCV::X0) {
256 UseCompressedBr =
true;
257 }
else if (RISCV::X8 <= SrcReg2.
id() && SrcReg2.
id() <= RISCV::X15 &&
258 SrcReg1.
id() == RISCV::X0) {
260 UseCompressedBr =
true;
265 if (UseCompressedBr) {
267 Opcode == RISCV::PseudoLongBNE ? RISCV::C_BEQZ : RISCV::C_BNEZ;
282 size_t FixupStartIndex =
Fixups.size();
291 Fixups.resize(FixupStartIndex);
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);
354 uint64_t Bits = getBinaryCodeForInstr(
MI, Fixups, STI) & 0xffff'ffff'ffffu;
357 assert(Encoding[6] == 0 && Encoding[7] == 0 &&
358 "Unexpected encoding for 48-bit instruction");
379 return Ctx.getRegisterInfo()->getEncodingValue(MO.
getReg());
389RISCVMCCodeEmitter::getImmOpValueAsr1(
const MCInst &
MI,
unsigned OpNo,
395 unsigned Res = MO.
getImm();
396 assert((Res & 1) == 0 &&
"LSB is non-zero");
400 return getImmOpValue(
MI, OpNo, Fixups, STI);
403unsigned RISCVMCCodeEmitter::getImmOpValue(
const MCInst &
MI,
unsigned OpNo,
406 bool EnableRelax = STI.
hasFeature(RISCV::FeatureRelax);
417 "getImmOpValue expects only expressions or immediates");
421 bool RelaxCandidate =
false;
423 const RISCVMCExpr *RVExpr = cast<RISCVMCExpr>(Expr);
436 "VK_RISCV_TPREL_ADD should not represent an instruction operand");
444 RelaxCandidate =
true;
448 RelaxCandidate =
true;
457 "VK_RISCV_PCREL_LO used with unexpected instruction format");
458 RelaxCandidate =
true;
462 RelaxCandidate =
true;
474 "VK_RISCV_TPREL_LO used with unexpected instruction format");
475 RelaxCandidate =
true;
479 RelaxCandidate =
true;
489 RelaxCandidate =
true;
493 RelaxCandidate =
true;
509 cast<MCSymbolRefExpr>(Expr)->getKind() ==
535 if (EnableRelax && RelaxCandidate) {
546unsigned RISCVMCCodeEmitter::getVMaskReg(
const MCInst &
MI,
unsigned OpNo,
557 case RISCV::NoRegister:
562unsigned RISCVMCCodeEmitter::getRlistOpValue(
const MCInst &
MI,
unsigned OpNo,
566 assert(MO.
isImm() &&
"Rlist operand must be immediate");
568 assert(Imm >= 4 &&
"EABI is currently not implemented");
572unsigned RISCVMCCodeEmitter::getRegReg(
const MCInst &
MI,
unsigned OpNo,
579 unsigned Op = Ctx.getRegisterInfo()->getEncodingValue(MO.
getReg());
580 unsigned Op1 = Ctx.getRegisterInfo()->getEncodingValue(MO1.
getReg());
582 return Op | Op1 << 5;
585#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 & addReg(MCRegister Reg)
Add a new register operand.
MCInstBuilder & addOperand(const MCOperand &Op)
Add an 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.
MCRegister 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
const FeatureBitset & getFeatureBits() 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...
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void truncate(size_type N)
Like resize, but requires that N is less than size().
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static unsigned getFormat(uint64_t TSFlags)
static unsigned getTailExpandUseRegNo(const FeatureBitset &FeatureBits)
@ 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.