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);
129 }
else if (
MI.getOpcode() == RISCV::PseudoCALLReg) {
131 Ra =
MI.getOperand(0).getReg();
132 }
else if (
MI.getOpcode() == RISCV::PseudoCALL) {
135 }
else if (
MI.getOpcode() == RISCV::PseudoJump) {
137 Ra =
MI.getOperand(0).getReg();
141 assert(
Func.isExpr() &&
"Expected expression");
147 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
150 if (
MI.getOpcode() == RISCV::PseudoTAIL ||
151 MI.getOpcode() == RISCV::PseudoJump)
157 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
161void RISCVMCCodeEmitter::expandTLSDESCCall(
const MCInst &
MI,
167 "Expected expression as first input to TLSDESCCALL");
182void RISCVMCCodeEmitter::expandAddTPRel(
const MCInst &
MI,
190 "Expected thread pointer as second input to TP-relative add");
194 "Expected expression as third input to TP-relative add");
198 "Expected tprel_add relocation on TP-relative symbol");
224 case RISCV::PseudoLongBEQ:
226 case RISCV::PseudoLongBNE:
228 case RISCV::PseudoLongBLT:
230 case RISCV::PseudoLongBGE:
232 case RISCV::PseudoLongBLTU:
234 case RISCV::PseudoLongBGEU:
241void RISCVMCCodeEmitter::expandLongCondBr(
const MCInst &
MI,
248 unsigned Opcode =
MI.getOpcode();
250 Opcode == RISCV::PseudoLongBNE || Opcode == RISCV::PseudoLongBEQ;
252 bool UseCompressedBr =
false;
253 if (IsEqTest && (STI.
hasFeature(RISCV::FeatureStdExtC) ||
255 if (RISCV::X8 <= SrcReg1.
id() && SrcReg1.
id() <= RISCV::X15 &&
256 SrcReg2.
id() == RISCV::X0) {
257 UseCompressedBr =
true;
258 }
else if (RISCV::X8 <= SrcReg2.
id() && SrcReg2.
id() <= RISCV::X15 &&
259 SrcReg1.
id() == RISCV::X0) {
261 UseCompressedBr =
true;
266 if (UseCompressedBr) {
268 Opcode == RISCV::PseudoLongBNE ? RISCV::C_BEQZ : RISCV::C_BNEZ;
296void RISCVMCCodeEmitter::encodeInstruction(
const MCInst &
MI,
307 switch (
MI.getOpcode()) {
310 case RISCV::PseudoCALLReg:
311 case RISCV::PseudoCALL:
312 case RISCV::PseudoTAIL:
313 case RISCV::PseudoJump:
314 expandFunctionCall(
MI, CB, Fixups, STI);
317 case RISCV::PseudoAddTPRel:
318 expandAddTPRel(
MI, CB, Fixups, STI);
321 case RISCV::PseudoLongBEQ:
322 case RISCV::PseudoLongBNE:
323 case RISCV::PseudoLongBLT:
324 case RISCV::PseudoLongBGE:
325 case RISCV::PseudoLongBLTU:
326 case RISCV::PseudoLongBGEU:
327 expandLongCondBr(
MI, CB, Fixups, STI);
330 case RISCV::PseudoTLSDESCCall:
331 expandTLSDESCCall(
MI, CB, Fixups, STI);
360 return Ctx.getRegisterInfo()->getEncodingValue(MO.
getReg());
363 return static_cast<unsigned>(MO.
getImm());
370RISCVMCCodeEmitter::getImmOpValueAsr1(
const MCInst &
MI,
unsigned OpNo,
376 unsigned Res = MO.
getImm();
377 assert((Res & 1) == 0 &&
"LSB is non-zero");
381 return getImmOpValue(
MI, OpNo, Fixups, STI);
384unsigned RISCVMCCodeEmitter::getImmOpValue(
const MCInst &
MI,
unsigned OpNo,
387 bool EnableRelax = STI.
hasFeature(RISCV::FeatureRelax);
398 "getImmOpValue expects only expressions or immediates");
402 bool RelaxCandidate =
false;
404 const RISCVMCExpr *RVExpr = cast<RISCVMCExpr>(Expr);
417 "VK_RISCV_TPREL_ADD should not represent an instruction operand");
425 RelaxCandidate =
true;
429 RelaxCandidate =
true;
438 "VK_RISCV_PCREL_LO used with unexpected instruction format");
439 RelaxCandidate =
true;
443 RelaxCandidate =
true;
455 "VK_RISCV_TPREL_LO used with unexpected instruction format");
456 RelaxCandidate =
true;
460 RelaxCandidate =
true;
470 RelaxCandidate =
true;
474 RelaxCandidate =
true;
490 cast<MCSymbolRefExpr>(Expr)->getKind() ==
516 if (EnableRelax && RelaxCandidate) {
527unsigned RISCVMCCodeEmitter::getVMaskReg(
const MCInst &
MI,
unsigned OpNo,
538 case RISCV::NoRegister:
543unsigned RISCVMCCodeEmitter::getRlistOpValue(
const MCInst &
MI,
unsigned OpNo,
547 assert(MO.
isImm() &&
"Rlist operand must be immediate");
549 assert(Imm >= 4 &&
"EABI is currently not implemented");
553unsigned RISCVMCCodeEmitter::getRegReg(
const MCInst &
MI,
unsigned OpNo,
560 unsigned Op = Ctx.getRegisterInfo()->getEncodingValue(MO.
getReg());
561 unsigned Op1 = Ctx.getRegisterInfo()->getEncodingValue(MO1.
getReg());
563 return Op | Op1 << 5;
566#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.