30#define DEBUG_TYPE "mccodeemitter"
32STATISTIC(MCNumEmitted,
"Number of MC instructions emitted");
38class LanaiMCCodeEmitter :
public MCCodeEmitter {
40 LanaiMCCodeEmitter(
const MCInstrInfo &MCII, MCContext &
C) {}
41 LanaiMCCodeEmitter(
const LanaiMCCodeEmitter &) =
delete;
42 void operator=(
const LanaiMCCodeEmitter &) =
delete;
43 ~LanaiMCCodeEmitter()
override =
default;
50 uint64_t getBinaryCodeForInstr(
const MCInst &Inst,
51 SmallVectorImpl<MCFixup> &Fixups,
52 const MCSubtargetInfo &SubtargetInfo)
const;
56 unsigned getMachineOpValue(
const MCInst &Inst,
const MCOperand &MCOp,
57 SmallVectorImpl<MCFixup> &Fixups,
58 const MCSubtargetInfo &SubtargetInfo)
const;
60 unsigned getRiMemoryOpValue(
const MCInst &Inst,
unsigned OpNo,
61 SmallVectorImpl<MCFixup> &Fixups,
62 const MCSubtargetInfo &SubtargetInfo)
const;
64 unsigned getRrMemoryOpValue(
const MCInst &Inst,
unsigned OpNo,
65 SmallVectorImpl<MCFixup> &Fixups,
66 const MCSubtargetInfo &SubtargetInfo)
const;
68 unsigned getSplsOpValue(
const MCInst &Inst,
unsigned OpNo,
69 SmallVectorImpl<MCFixup> &Fixups,
70 const MCSubtargetInfo &SubtargetInfo)
const;
73 SmallVectorImpl<MCFixup> &Fixups,
74 const MCSubtargetInfo &SubtargetInfo)
const;
76 void encodeInstruction(
const MCInst &Inst, SmallVectorImpl<char> &CB,
77 SmallVectorImpl<MCFixup> &Fixups,
78 const MCSubtargetInfo &SubtargetInfo)
const override;
80 unsigned adjustPqBitsRmAndRrm(
const MCInst &Inst,
unsigned Value,
81 const MCSubtargetInfo &STI)
const;
83 unsigned adjustPqBitsSpls(
const MCInst &Inst,
unsigned Value,
84 const MCSubtargetInfo &STI)
const;
108unsigned LanaiMCCodeEmitter::getMachineOpValue(
109 const MCInst &Inst,
const MCOperand &MCOp, SmallVectorImpl<MCFixup> &Fixups,
110 const MCSubtargetInfo &SubtargetInfo)
const {
112 return getLanaiRegisterNumbering(MCOp.getReg());
114 return static_cast<unsigned>(MCOp.getImm());
118 const MCExpr *Expr = MCOp.getExpr();
121 if (Expr->getKind() == MCExpr::Binary) {
122 const MCBinaryExpr *
BinaryExpr =
static_cast<const MCBinaryExpr *
>(Expr);
126 assert(isa<MCSpecifierExpr>(Expr) || Expr->getKind() == MCExpr::SymbolRef);
135 unsigned PBitShift,
unsigned QBitShift) {
137 unsigned AluCode = AluOp.
getImm();
142 Value &= ~(1 << PBitShift);
146 Value |= (1 << PBitShift);
150 "Expected register operand.");
151 Value &= ~(1 << QBitShift);
154 Value |= (1 << QBitShift);
160LanaiMCCodeEmitter::adjustPqBitsRmAndRrm(
const MCInst &Inst,
unsigned Value,
161 const MCSubtargetInfo &STI)
const {
162 return adjustPqBits(Inst, Value, 17, 16);
166LanaiMCCodeEmitter::adjustPqBitsSpls(
const MCInst &Inst,
unsigned Value,
167 const MCSubtargetInfo &STI)
const {
171void LanaiMCCodeEmitter::encodeInstruction(
172 const MCInst &Inst, SmallVectorImpl<char> &CB,
173 SmallVectorImpl<MCFixup> &Fixups,
174 const MCSubtargetInfo &SubtargetInfo)
const {
176 unsigned Value = getBinaryCodeForInstr(Inst, Fixups, SubtargetInfo);
183unsigned LanaiMCCodeEmitter::getRiMemoryOpValue(
184 const MCInst &Inst,
unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups,
185 const MCSubtargetInfo &SubtargetInfo)
const {
187 const MCOperand Op1 = Inst.getOperand(OpNo + 0);
188 const MCOperand Op2 = Inst.getOperand(OpNo + 1);
189 const MCOperand AluOp = Inst.getOperand(OpNo + 2);
191 assert(Op1.isReg() &&
"First operand is not register.");
192 assert((Op2.isImm() || Op2.isExpr()) &&
193 "Second operand is neither an immediate nor an expression.");
194 assert((LPAC::getAluOp(AluOp.getImm()) == LPAC::ADD) &&
195 "Register immediate only supports addition operator");
197 Encoding = (getLanaiRegisterNumbering(Op1.getReg()) << 18);
199 assert(isInt<16>(Op2.getImm()) &&
200 "Constant value truncated (limited to 16-bit)");
202 Encoding |= (Op2.getImm() & 0xffff);
203 if (Op2.getImm() != 0) {
204 if (LPAC::isPreOp(AluOp.getImm()))
205 Encoding |= (0x3 << 16);
206 if (LPAC::isPostOp(AluOp.getImm()))
207 Encoding |= (0x1 << 16);
210 getMachineOpValue(Inst, Op2, Fixups, SubtargetInfo);
215unsigned LanaiMCCodeEmitter::getRrMemoryOpValue(
216 const MCInst &Inst,
unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups,
217 const MCSubtargetInfo &SubtargetInfo)
const {
219 const MCOperand Op1 = Inst.getOperand(OpNo + 0);
220 const MCOperand Op2 = Inst.getOperand(OpNo + 1);
221 const MCOperand AluMCOp = Inst.getOperand(OpNo + 2);
223 assert(Op1.isReg() &&
"First operand is not register.");
224 Encoding = (getLanaiRegisterNumbering(Op1.getReg()) << 15);
225 assert(Op2.isReg() &&
"Second operand is not register.");
226 Encoding |= (getLanaiRegisterNumbering(Op2.getReg()) << 10);
228 assert(AluMCOp.isImm() &&
"Third operator is not immediate.");
230 unsigned AluOp = AluMCOp.getImm();
231 Encoding |= LPAC::encodeLanaiAluCode(AluOp) << 5;
233 if (LPAC::isPreOp(AluOp))
234 Encoding |= (0x3 << 8);
235 if (LPAC::isPostOp(AluOp))
236 Encoding |= (0x1 << 8);
238 switch (LPAC::getAluOp(AluOp)) {
254LanaiMCCodeEmitter::getSplsOpValue(
const MCInst &Inst,
unsigned OpNo,
255 SmallVectorImpl<MCFixup> &Fixups,
256 const MCSubtargetInfo &SubtargetInfo)
const {
258 const MCOperand Op1 = Inst.getOperand(OpNo + 0);
259 const MCOperand Op2 = Inst.getOperand(OpNo + 1);
260 const MCOperand AluOp = Inst.getOperand(OpNo + 2);
262 assert(Op1.isReg() &&
"First operand is not register.");
263 assert((Op2.isImm() || Op2.isExpr()) &&
264 "Second operand is neither an immediate nor an expression.");
265 assert((LPAC::getAluOp(AluOp.getImm()) == LPAC::ADD) &&
266 "Register immediate only supports addition operator");
268 Encoding = (getLanaiRegisterNumbering(Op1.getReg()) << 12);
270 assert(isInt<10>(Op2.getImm()) &&
271 "Constant value truncated (limited to 10-bit)");
273 Encoding |= (Op2.getImm() & 0x3ff);
274 if (Op2.getImm() != 0) {
275 if (LPAC::isPreOp(AluOp.getImm()))
276 Encoding |= (0x3 << 10);
277 if (LPAC::isPostOp(AluOp.getImm()))
278 Encoding |= (0x1 << 10);
281 getMachineOpValue(Inst, Op2, Fixups, SubtargetInfo);
286unsigned LanaiMCCodeEmitter::getBranchTargetOpValue(
287 const MCInst &Inst,
unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups,
288 const MCSubtargetInfo &SubtargetInfo)
const {
289 const MCOperand &MCOp = Inst.getOperand(OpNo);
290 if (MCOp.isReg() || MCOp.isImm())
291 return getMachineOpValue(Inst, MCOp, Fixups, SubtargetInfo);
293 Fixups.push_back(MCFixup::create(0, MCOp.getExpr(), Lanai::FIXUP_LANAI_25));
298#include "LanaiGenMCCodeEmitter.inc"
305 return new LanaiMCCodeEmitter(InstrInfo, context);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, unsigned FixupKind, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI)
getBranchTargetOpValue - Helper function to get the branch target operand, which is either an immedia...
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
This file defines the SmallVector class.
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.
Base class for the full range of assembler expressions which are needed for parsing.
Instances of this class represent a single low-level machine instruction.
const MCOperand & getOperand(unsigned i) const
Interface to description of machine instruction set.
Instances of this class represent operands of the MCInst class.
MCRegister getReg() const
Returns the register number.
Extension point for target-specific MCExpr subclasses with a relocation specifier,...
LLVM Value Representation.
static bool isPostOp(unsigned AluOp)
static bool modifiesOp(unsigned AluOp)
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
MCCodeEmitter * createLanaiMCCodeEmitter(const MCInstrInfo &MCII, MCContext &Ctx)
uint16_t MCFixupKind
Extensible enumeration to represent the type of a fixup.
static Lanai::Fixups FixupKind(const MCExpr *Expr)
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
static unsigned adjustPqBits(const MCInst &Inst, unsigned Value, unsigned PBitShift, unsigned QBitShift)