29#define DEBUG_TYPE "csky-mccode-emitter"
31STATISTIC(MCNumEmitted,
"Number of MC instructions emitted");
53 const MCInstrInfo &MII;
56 CSKYMCCodeEmitter(MCContext &Ctx,
const MCInstrInfo &MII)
57 : Ctx(Ctx), MII(MII) {}
59 ~CSKYMCCodeEmitter() {}
61 void encodeInstruction(
const MCInst &Inst, SmallVectorImpl<char> &CB,
62 SmallVectorImpl<MCFixup> &Fixups,
63 const MCSubtargetInfo &STI)
const override;
66 uint64_t getBinaryCodeForInstr(
const MCInst &
MI,
67 SmallVectorImpl<MCFixup> &Fixups,
68 const MCSubtargetInfo &STI)
const;
71 unsigned getMachineOpValue(
const MCInst &
MI,
const MCOperand &MO,
72 SmallVectorImpl<MCFixup> &Fixups,
73 const MCSubtargetInfo &STI)
const;
75 template <
int shift = 0>
76 unsigned getImmOpValue(
const MCInst &
MI,
unsigned Idx,
77 SmallVectorImpl<MCFixup> &Fixups,
78 const MCSubtargetInfo &STI)
const {
79 const MCOperand &MO =
MI.getOperand(Idx);
81 return (MO.
getImm() >> shift);
90 unsigned getRegSeqImmOpValue(
const MCInst &
MI,
unsigned Idx,
91 SmallVectorImpl<MCFixup> &Fixups,
92 const MCSubtargetInfo &STI)
const;
94 unsigned getRegisterSeqOpValue(
const MCInst &
MI,
unsigned Op,
95 SmallVectorImpl<MCFixup> &Fixups,
96 const MCSubtargetInfo &STI)
const;
98 unsigned getOImmOpValue(
const MCInst &
MI,
unsigned Idx,
99 SmallVectorImpl<MCFixup> &Fixups,
100 const MCSubtargetInfo &STI)
const;
102 unsigned getImmOpValueIDLY(
const MCInst &
MI,
unsigned Idx,
103 SmallVectorImpl<MCFixup> &Fixups,
104 const MCSubtargetInfo &STI)
const;
106 unsigned getImmJMPIX(
const MCInst &
MI,
unsigned Idx,
107 SmallVectorImpl<MCFixup> &Fixups,
108 const MCSubtargetInfo &STI)
const;
110 unsigned getImmOpValueMSBSize(
const MCInst &
MI,
unsigned Idx,
111 SmallVectorImpl<MCFixup> &Fixups,
112 const MCSubtargetInfo &STI)
const;
114 unsigned getImmShiftOpValue(
const MCInst &
MI,
unsigned Idx,
115 SmallVectorImpl<MCFixup> &Fixups,
116 const MCSubtargetInfo &STI)
const {
117 const MCOperand &MO =
MI.getOperand(Idx);
122 MCFixupKind getTargetFixup(
const MCExpr *Expr)
const;
124 template <llvm::CSKY::Fixups FIXUP>
125 unsigned getBranchSymbolOpValue(
const MCInst &
MI,
unsigned Idx,
126 SmallVectorImpl<MCFixup> &Fixups,
127 const MCSubtargetInfo &STI)
const {
128 const MCOperand &MO =
MI.getOperand(Idx);
143 template <llvm::CSKY::Fixups FIXUP>
144 unsigned getConstpoolSymbolOpValue(
const MCInst &
MI,
unsigned Idx,
145 SmallVectorImpl<MCFixup> &Fixups,
146 const MCSubtargetInfo &STI)
const {
147 const MCOperand &MO =
MI.getOperand(Idx);
158 template <llvm::CSKY::Fixups FIXUP>
159 unsigned getDataSymbolOpValue(
const MCInst &
MI,
unsigned Idx,
160 SmallVectorImpl<MCFixup> &Fixups,
161 const MCSubtargetInfo &STI)
const {
162 const MCOperand &MO =
MI.getOperand(Idx);
173 unsigned getCallSymbolOpValue(
const MCInst &
MI,
unsigned Idx,
174 SmallVectorImpl<MCFixup> &Fixups,
175 const MCSubtargetInfo &STI)
const {
176 const MCOperand &MO =
MI.getOperand(Idx);
187 unsigned getBareSymbolOpValue(
const MCInst &
MI,
unsigned Idx,
188 SmallVectorImpl<MCFixup> &Fixups,
189 const MCSubtargetInfo &STI)
const {
190 const MCOperand &MO =
MI.getOperand(Idx);
201 void expandJBTF(
const MCInst &
MI, SmallVectorImpl<char> &CB,
202 SmallVectorImpl<MCFixup> &Fixups,
203 const MCSubtargetInfo &STI)
const;
204 void expandNEG(
const MCInst &
MI, SmallVectorImpl<char> &CB,
205 SmallVectorImpl<MCFixup> &Fixups,
206 const MCSubtargetInfo &STI)
const;
207 void expandRSUBI(
const MCInst &
MI, SmallVectorImpl<char> &CB,
208 SmallVectorImpl<MCFixup> &Fixups,
209 const MCSubtargetInfo &STI)
const;
213unsigned CSKYMCCodeEmitter::getOImmOpValue(
const MCInst &
MI,
unsigned Idx,
216 const MCOperand &MO =
MI.getOperand(Idx);
222CSKYMCCodeEmitter::getImmOpValueIDLY(
const MCInst &
MI,
unsigned Idx,
223 SmallVectorImpl<MCFixup> &Fixups,
224 const MCSubtargetInfo &STI)
const {
225 const MCOperand &MO =
MI.getOperand(Idx);
233CSKYMCCodeEmitter::getImmOpValueMSBSize(
const MCInst &
MI,
unsigned Idx,
234 SmallVectorImpl<MCFixup> &Fixups,
235 const MCSubtargetInfo &STI)
const {
236 const MCOperand &MSB =
MI.getOperand(Idx);
237 const MCOperand &LSB =
MI.getOperand(Idx + 1);
251void CSKYMCCodeEmitter::expandJBTF(
const MCInst &
MI, SmallVectorImpl<char> &CB,
252 SmallVectorImpl<MCFixup> &Fixups,
253 const MCSubtargetInfo &STI)
const {
260 MCInstBuilder(
MI.getOpcode() == CSKY::JBT_E ? CSKY::BF16 : CSKY::BT16)
263 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
267 TmpInst = MCInstBuilder(CSKY::BR32)
269 .addOperand(
MI.getOperand(2));
271 TmpInst = MCInstBuilder(CSKY::JMPI32).
addOperand(
MI.getOperand(2));
272 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
277void CSKYMCCodeEmitter::expandNEG(
const MCInst &
MI, SmallVectorImpl<char> &CB,
278 SmallVectorImpl<MCFixup> &Fixups,
279 const MCSubtargetInfo &STI)
const {
283 unsigned Size =
MI.getOpcode() == CSKY::NEG32 ? 4 : 2;
285 TmpInst = MCInstBuilder(
Size == 4 ? CSKY::NOT32 : CSKY::NOT16)
287 .addOperand(
MI.getOperand(1));
288 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
291 TmpInst = MCInstBuilder(
Size == 4 ? CSKY::ADDI32 : CSKY::ADDI16)
293 .addOperand(
MI.getOperand(0))
295 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
299void CSKYMCCodeEmitter::expandRSUBI(
const MCInst &
MI, SmallVectorImpl<char> &CB,
300 SmallVectorImpl<MCFixup> &Fixups,
301 const MCSubtargetInfo &STI)
const {
305 unsigned Size =
MI.getOpcode() == CSKY::RSUBI32 ? 4 : 2;
307 TmpInst = MCInstBuilder(
Size == 4 ? CSKY::NOT32 : CSKY::NOT16)
309 .addOperand(
MI.getOperand(1));
310 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
313 TmpInst = MCInstBuilder(
Size == 4 ? CSKY::ADDI32 : CSKY::ADDI16)
315 .addOperand(
MI.getOperand(0))
316 .addImm(
MI.getOperand(2).getImm() + 1);
317 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
321void CSKYMCCodeEmitter::encodeInstruction(
const MCInst &
MI,
322 SmallVectorImpl<char> &CB,
323 SmallVectorImpl<MCFixup> &Fixups,
324 const MCSubtargetInfo &STI)
const {
325 const MCInstrDesc &
Desc = MII.
get(
MI.getOpcode());
330 switch (
MI.getOpcode()) {
336 expandJBTF(
MI, CB, Fixups, STI);
341 expandNEG(
MI, CB, Fixups, STI);
346 expandRSUBI(
MI, CB, Fixups, STI);
350 TmpInst = MCInstBuilder(CSKY::BSR32).
addOperand(
MI.getOperand(0));
353 TmpInst = MCInstBuilder(CSKY::BR16).
addOperand(
MI.getOperand(0));
356 TmpInst = MCInstBuilder(CSKY::BR32).
addOperand(
MI.getOperand(0));
359 TmpInst = MCInstBuilder(CSKY::BT16)
361 .addOperand(
MI.getOperand(1));
364 TmpInst = MCInstBuilder(CSKY::BT32)
366 .addOperand(
MI.getOperand(1));
369 TmpInst = MCInstBuilder(CSKY::BF16)
371 .addOperand(
MI.getOperand(1));
374 TmpInst = MCInstBuilder(CSKY::BF32)
376 .addOperand(
MI.getOperand(1));
378 case CSKY::LRW32_Gen:
379 TmpInst = MCInstBuilder(CSKY::LRW32)
381 .addOperand(
MI.getOperand(2));
383 case CSKY::LRW16_Gen:
384 TmpInst = MCInstBuilder(CSKY::LRW16)
386 .addOperand(
MI.getOperand(2));
389 TmpInst = MCInstBuilder(CSKY::CMPLTI32)
391 .addOperand(
MI.getOperand(1))
392 .addImm(
MI.getOperand(2).getImm() + 1);
395 TmpInst = MCInstBuilder(CSKY::CMPLTI16)
397 .addOperand(
MI.getOperand(1))
398 .addImm(
MI.getOperand(2).getImm() + 1);
401 TmpInst = MCInstBuilder(CSKY::ROTLI32)
403 .addOperand(
MI.getOperand(1))
404 .addImm(32 -
MI.getOperand(2).getImm());
407 auto V = 1 <<
MI.getOperand(1).getImm();
409 MCInstBuilder(CSKY::MOVI32).
addOperand(
MI.getOperand(0)).addImm(V);
414 writeData(getBinaryCodeForInstr(TmpInst, Fixups, STI),
Size, CB);
418CSKYMCCodeEmitter::getMachineOpValue(
const MCInst &
MI,
const MCOperand &MO,
419 SmallVectorImpl<MCFixup> &Fixups,
420 const MCSubtargetInfo &STI)
const {
425 return static_cast<unsigned>(MO.
getImm());
432CSKYMCCodeEmitter::getRegSeqImmOpValue(
const MCInst &
MI,
unsigned Idx,
433 SmallVectorImpl<MCFixup> &Fixups,
434 const MCSubtargetInfo &STI)
const {
435 assert(
MI.getOperand(Idx).isReg() &&
"Unexpected MO type.");
436 assert(
MI.getOperand(Idx + 1).isImm() &&
"Unexpected MO type.");
438 unsigned Ry =
MI.getOperand(Idx).getReg();
439 unsigned Rz =
MI.getOperand(Idx + 1).getImm();
448CSKYMCCodeEmitter::getRegisterSeqOpValue(
const MCInst &
MI,
unsigned Op,
449 SmallVectorImpl<MCFixup> &Fixups,
450 const MCSubtargetInfo &STI)
const {
456 unsigned Binary = ((Reg1 & 0x1f) << 5) | (Reg2 - Reg1);
461unsigned CSKYMCCodeEmitter::getImmJMPIX(
const MCInst &
MI,
unsigned Idx,
462 SmallVectorImpl<MCFixup> &Fixups,
463 const MCSubtargetInfo &STI)
const {
464 switch (
MI.getOperand(Idx).getImm()) {
478MCFixupKind CSKYMCCodeEmitter::getTargetFixup(
const MCExpr *Expr)
const {
480 switch (CSKYExpr->getSpecifier()) {
506 return new CSKYMCCodeEmitter(Ctx, MCII);
509#include "CSKYGenMCCodeEmitter.inc"
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static void writeData(uint32_t Bin, unsigned Size, SmallVectorImpl< char > &CB)
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.
Context object for machine code objects.
const MCRegisterInfo * getRegisterInfo() const
Base class for the full range of assembler expressions which are needed for parsing.
@ Specifier
Expression with a relocation specifier.
static MCFixup create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, bool PCRel=false)
Consider bit fields if we need more flags.
Instances of this class represent a single low-level machine instruction.
void addOperand(const MCOperand Op)
Interface to description of machine instruction set.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
MCRegister getReg() const
Returns the register number.
const MCExpr * getExpr() const
uint16_t getEncodingValue(MCRegister Reg) const
Returns the encoding for Reg.
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
LLVM Value Representation.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ fixup_csky_pcrel_imm10_scale2
@ fixup_csky_pcrel_uimm7_scale4
@ fixup_csky_pcrel_imm16_scale2
@ fixup_csky_pcrel_imm18_scale2
@ fixup_csky_pcrel_uimm16_scale4
@ fixup_csky_plt_imm18_scale4
@ fixup_csky_pcrel_imm26_scale2
@ fixup_csky_got_imm18_scale4
@ fixup_csky_pcrel_uimm8_scale4
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.
uint16_t MCFixupKind
Extensible enumeration to represent the type of a fixup.
static void addFixup(SmallVectorImpl< MCFixup > &Fixups, uint32_t Offset, const MCExpr *Value, uint16_t Kind)
MCCodeEmitter * createCSKYMCCodeEmitter(const MCInstrInfo &MCII, MCContext &Ctx)
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.