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,
96 return new RISCVMCCodeEmitter(Ctx, MCII);
113 if (
MI.getOpcode() == RISCV::PseudoTAIL) {
114 Func =
MI.getOperand(0);
116 }
else if (
MI.getOpcode() == RISCV::PseudoCALLReg) {
118 Ra =
MI.getOperand(0).getReg();
119 }
else if (
MI.getOpcode() == RISCV::PseudoCALL) {
122 }
else if (
MI.getOpcode() == RISCV::PseudoJump) {
124 Ra =
MI.getOperand(0).getReg();
128 assert(
Func.isExpr() &&
"Expected expression");
134 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
137 if (
MI.getOpcode() == RISCV::PseudoTAIL ||
138 MI.getOpcode() == RISCV::PseudoJump)
144 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
156 "Expected thread pointer as second input to TP-relative add");
160 "Expected expression as third input to TP-relative add");
164 "Expected tprel_add relocation on TP-relative symbol");
190 case RISCV::PseudoLongBEQ:
192 case RISCV::PseudoLongBNE:
194 case RISCV::PseudoLongBLT:
196 case RISCV::PseudoLongBGE:
198 case RISCV::PseudoLongBLTU:
200 case RISCV::PseudoLongBGEU:
213 unsigned Opcode =
MI.getOpcode();
215 Opcode == RISCV::PseudoLongBNE || Opcode == RISCV::PseudoLongBEQ;
217 bool UseCompressedBr =
false;
218 if (IsEqTest && (STI.
hasFeature(RISCV::FeatureStdExtC) ||
220 if (RISCV::X8 <= SrcReg1.
id() && SrcReg1.
id() <= RISCV::X15 &&
221 SrcReg2.
id() == RISCV::X0) {
222 UseCompressedBr =
true;
223 }
else if (RISCV::X8 <= SrcReg2.
id() && SrcReg2.
id() <= RISCV::X15 &&
224 SrcReg1.
id() == RISCV::X0) {
226 UseCompressedBr =
true;
231 if (UseCompressedBr) {
233 Opcode == RISCV::PseudoLongBNE ? RISCV::C_BEQZ : RISCV::C_BNEZ;
271 switch (
MI.getOpcode()) {
274 case RISCV::PseudoCALLReg:
275 case RISCV::PseudoCALL:
276 case RISCV::PseudoTAIL:
277 case RISCV::PseudoJump:
278 expandFunctionCall(
MI,
OS, Fixups, STI);
281 case RISCV::PseudoAddTPRel:
282 expandAddTPRel(
MI,
OS, Fixups, STI);
285 case RISCV::PseudoLongBEQ:
286 case RISCV::PseudoLongBNE:
287 case RISCV::PseudoLongBLT:
288 case RISCV::PseudoLongBGE:
289 case RISCV::PseudoLongBLTU:
290 case RISCV::PseudoLongBGEU:
291 expandLongCondBr(
MI,
OS, Fixups, STI);
320 return Ctx.getRegisterInfo()->getEncodingValue(MO.
getReg());
323 return static_cast<unsigned>(MO.
getImm());
330RISCVMCCodeEmitter::getImmOpValueAsr1(
const MCInst &
MI,
unsigned OpNo,
336 unsigned Res = MO.
getImm();
337 assert((Res & 1) == 0 &&
"LSB is non-zero");
341 return getImmOpValue(
MI, OpNo, Fixups, STI);
344unsigned RISCVMCCodeEmitter::getImmOpValue(
const MCInst &
MI,
unsigned OpNo,
347 bool EnableRelax = STI.
hasFeature(RISCV::FeatureRelax);
358 "getImmOpValue expects only expressions or immediates");
362 bool RelaxCandidate =
false;
364 const RISCVMCExpr *RVExpr = cast<RISCVMCExpr>(Expr);
377 "VK_RISCV_TPREL_ADD should not represent an instruction operand");
385 RelaxCandidate =
true;
389 RelaxCandidate =
true;
398 "VK_RISCV_PCREL_LO used with unexpected instruction format");
399 RelaxCandidate =
true;
403 RelaxCandidate =
true;
415 "VK_RISCV_TPREL_LO used with unexpected instruction format");
416 RelaxCandidate =
true;
420 RelaxCandidate =
true;
430 RelaxCandidate =
true;
434 RelaxCandidate =
true;
459 if (EnableRelax && RelaxCandidate) {
470unsigned RISCVMCCodeEmitter::getVMaskReg(
const MCInst &
MI,
unsigned OpNo,
481 case RISCV::NoRegister:
486#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)
MCCodeEmitter - Generic instruction encoding interface.
virtual void encodeInstruction(const MCInst &Inst, raw_ostream &OS, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const =0
EncodeInstruction - Encode the given Inst to bytes on the output stream OS.
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.
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.
unsigned getSize() const
Return the number of bytes in the encoding of this instruction, or zero if the encoding size cannot b...
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.
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...
This class implements an extremely fast bulk output stream that can only output to a stream.
#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
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.