1*9880d681SAndroid Build Coastguard Worker //===-- LanaiMCCodeEmitter.cpp - Convert Lanai code to machine code -------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file implements the LanaiMCCodeEmitter class.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker
14*9880d681SAndroid Build Coastguard Worker #include "Lanai.h"
15*9880d681SAndroid Build Coastguard Worker #include "MCTargetDesc/LanaiBaseInfo.h"
16*9880d681SAndroid Build Coastguard Worker #include "MCTargetDesc/LanaiFixupKinds.h"
17*9880d681SAndroid Build Coastguard Worker #include "MCTargetDesc/LanaiMCExpr.h"
18*9880d681SAndroid Build Coastguard Worker #include "MCTargetDesc/LanaiMCTargetDesc.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/Statistic.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCCodeEmitter.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCFixup.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCInst.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCInstrInfo.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCRegisterInfo.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSubtargetInfo.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSymbol.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
28*9880d681SAndroid Build Coastguard Worker
29*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "mccodeemitter"
30*9880d681SAndroid Build Coastguard Worker
31*9880d681SAndroid Build Coastguard Worker STATISTIC(MCNumEmitted, "Number of MC instructions emitted");
32*9880d681SAndroid Build Coastguard Worker
33*9880d681SAndroid Build Coastguard Worker namespace llvm {
34*9880d681SAndroid Build Coastguard Worker namespace {
35*9880d681SAndroid Build Coastguard Worker class LanaiMCCodeEmitter : public MCCodeEmitter {
36*9880d681SAndroid Build Coastguard Worker LanaiMCCodeEmitter(const LanaiMCCodeEmitter &); // DO NOT IMPLEMENT
37*9880d681SAndroid Build Coastguard Worker void operator=(const LanaiMCCodeEmitter &); // DO NOT IMPLEMENT
38*9880d681SAndroid Build Coastguard Worker const MCInstrInfo &InstrInfo;
39*9880d681SAndroid Build Coastguard Worker MCContext &Context;
40*9880d681SAndroid Build Coastguard Worker
41*9880d681SAndroid Build Coastguard Worker public:
LanaiMCCodeEmitter(const MCInstrInfo & MCII,MCContext & C)42*9880d681SAndroid Build Coastguard Worker LanaiMCCodeEmitter(const MCInstrInfo &MCII, MCContext &C)
43*9880d681SAndroid Build Coastguard Worker : InstrInfo(MCII), Context(C) {}
44*9880d681SAndroid Build Coastguard Worker
~LanaiMCCodeEmitter()45*9880d681SAndroid Build Coastguard Worker ~LanaiMCCodeEmitter() override {}
46*9880d681SAndroid Build Coastguard Worker
47*9880d681SAndroid Build Coastguard Worker // The functions below are called by TableGen generated functions for getting
48*9880d681SAndroid Build Coastguard Worker // the binary encoding of instructions/opereands.
49*9880d681SAndroid Build Coastguard Worker
50*9880d681SAndroid Build Coastguard Worker // getBinaryCodeForInstr - TableGen'erated function for getting the
51*9880d681SAndroid Build Coastguard Worker // binary encoding for an instruction.
52*9880d681SAndroid Build Coastguard Worker uint64_t getBinaryCodeForInstr(const MCInst &Inst,
53*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<MCFixup> &Fixups,
54*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &SubtargetInfo) const;
55*9880d681SAndroid Build Coastguard Worker
56*9880d681SAndroid Build Coastguard Worker // getMachineOpValue - Return binary encoding of operand. If the machine
57*9880d681SAndroid Build Coastguard Worker // operand requires relocation, record the relocation and return zero.
58*9880d681SAndroid Build Coastguard Worker unsigned getMachineOpValue(const MCInst &Inst, const MCOperand &MCOp,
59*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<MCFixup> &Fixups,
60*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &SubtargetInfo) const;
61*9880d681SAndroid Build Coastguard Worker
62*9880d681SAndroid Build Coastguard Worker unsigned getRiMemoryOpValue(const MCInst &Inst, unsigned OpNo,
63*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<MCFixup> &Fixups,
64*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &SubtargetInfo) const;
65*9880d681SAndroid Build Coastguard Worker
66*9880d681SAndroid Build Coastguard Worker unsigned getRrMemoryOpValue(const MCInst &Inst, unsigned OpNo,
67*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<MCFixup> &Fixups,
68*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &SubtargetInfo) const;
69*9880d681SAndroid Build Coastguard Worker
70*9880d681SAndroid Build Coastguard Worker unsigned getSplsOpValue(const MCInst &Inst, unsigned OpNo,
71*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<MCFixup> &Fixups,
72*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &SubtargetInfo) const;
73*9880d681SAndroid Build Coastguard Worker
74*9880d681SAndroid Build Coastguard Worker unsigned getBranchTargetOpValue(const MCInst &Inst, unsigned OpNo,
75*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<MCFixup> &Fixups,
76*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &SubtargetInfo) const;
77*9880d681SAndroid Build Coastguard Worker
78*9880d681SAndroid Build Coastguard Worker unsigned getCallTargetOpValue(const MCInst &Inst, unsigned OpNo,
79*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<MCFixup> &Fixups,
80*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &SubtargetInfo) const;
81*9880d681SAndroid Build Coastguard Worker
82*9880d681SAndroid Build Coastguard Worker void encodeInstruction(const MCInst &Inst, raw_ostream &Ostream,
83*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<MCFixup> &Fixups,
84*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &SubtargetInfo) const override;
85*9880d681SAndroid Build Coastguard Worker
86*9880d681SAndroid Build Coastguard Worker unsigned adjustPqBitsRmAndRrm(const MCInst &Inst, unsigned Value,
87*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI) const;
88*9880d681SAndroid Build Coastguard Worker
89*9880d681SAndroid Build Coastguard Worker unsigned adjustPqBitsSpls(const MCInst &Inst, unsigned Value,
90*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI) const;
91*9880d681SAndroid Build Coastguard Worker };
92*9880d681SAndroid Build Coastguard Worker
FixupKind(const MCExpr * Expr)93*9880d681SAndroid Build Coastguard Worker Lanai::Fixups FixupKind(const MCExpr *Expr) {
94*9880d681SAndroid Build Coastguard Worker if (isa<MCSymbolRefExpr>(Expr))
95*9880d681SAndroid Build Coastguard Worker return Lanai::FIXUP_LANAI_21;
96*9880d681SAndroid Build Coastguard Worker if (const LanaiMCExpr *McExpr = dyn_cast<LanaiMCExpr>(Expr)) {
97*9880d681SAndroid Build Coastguard Worker LanaiMCExpr::VariantKind ExprKind = McExpr->getKind();
98*9880d681SAndroid Build Coastguard Worker switch (ExprKind) {
99*9880d681SAndroid Build Coastguard Worker case LanaiMCExpr::VK_Lanai_None:
100*9880d681SAndroid Build Coastguard Worker return Lanai::FIXUP_LANAI_21;
101*9880d681SAndroid Build Coastguard Worker case LanaiMCExpr::VK_Lanai_ABS_HI:
102*9880d681SAndroid Build Coastguard Worker return Lanai::FIXUP_LANAI_HI16;
103*9880d681SAndroid Build Coastguard Worker case LanaiMCExpr::VK_Lanai_ABS_LO:
104*9880d681SAndroid Build Coastguard Worker return Lanai::FIXUP_LANAI_LO16;
105*9880d681SAndroid Build Coastguard Worker }
106*9880d681SAndroid Build Coastguard Worker }
107*9880d681SAndroid Build Coastguard Worker return Lanai::Fixups(0);
108*9880d681SAndroid Build Coastguard Worker }
109*9880d681SAndroid Build Coastguard Worker
110*9880d681SAndroid Build Coastguard Worker // getMachineOpValue - Return binary encoding of operand. If the machine
111*9880d681SAndroid Build Coastguard Worker // operand requires relocation, record the relocation and return zero.
getMachineOpValue(const MCInst & Inst,const MCOperand & MCOp,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & SubtargetInfo) const112*9880d681SAndroid Build Coastguard Worker unsigned LanaiMCCodeEmitter::getMachineOpValue(
113*9880d681SAndroid Build Coastguard Worker const MCInst &Inst, const MCOperand &MCOp, SmallVectorImpl<MCFixup> &Fixups,
114*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &SubtargetInfo) const {
115*9880d681SAndroid Build Coastguard Worker if (MCOp.isReg())
116*9880d681SAndroid Build Coastguard Worker return getLanaiRegisterNumbering(MCOp.getReg());
117*9880d681SAndroid Build Coastguard Worker if (MCOp.isImm())
118*9880d681SAndroid Build Coastguard Worker return static_cast<unsigned>(MCOp.getImm());
119*9880d681SAndroid Build Coastguard Worker
120*9880d681SAndroid Build Coastguard Worker // MCOp must be an expression
121*9880d681SAndroid Build Coastguard Worker assert(MCOp.isExpr());
122*9880d681SAndroid Build Coastguard Worker const MCExpr *Expr = MCOp.getExpr();
123*9880d681SAndroid Build Coastguard Worker
124*9880d681SAndroid Build Coastguard Worker // Extract the symbolic reference side of a binary expression.
125*9880d681SAndroid Build Coastguard Worker if (Expr->getKind() == MCExpr::Binary) {
126*9880d681SAndroid Build Coastguard Worker const MCBinaryExpr *BinaryExpr = static_cast<const MCBinaryExpr *>(Expr);
127*9880d681SAndroid Build Coastguard Worker Expr = BinaryExpr->getLHS();
128*9880d681SAndroid Build Coastguard Worker }
129*9880d681SAndroid Build Coastguard Worker
130*9880d681SAndroid Build Coastguard Worker assert(isa<LanaiMCExpr>(Expr) || Expr->getKind() == MCExpr::SymbolRef);
131*9880d681SAndroid Build Coastguard Worker // Push fixup (all info is contained within)
132*9880d681SAndroid Build Coastguard Worker Fixups.push_back(
133*9880d681SAndroid Build Coastguard Worker MCFixup::create(0, MCOp.getExpr(), MCFixupKind(FixupKind(Expr))));
134*9880d681SAndroid Build Coastguard Worker return 0;
135*9880d681SAndroid Build Coastguard Worker }
136*9880d681SAndroid Build Coastguard Worker
137*9880d681SAndroid Build Coastguard Worker // Helper function to adjust P and Q bits on load and store instructions.
adjustPqBits(const MCInst & Inst,unsigned Value,unsigned PBitShift,unsigned QBitShift)138*9880d681SAndroid Build Coastguard Worker unsigned adjustPqBits(const MCInst &Inst, unsigned Value, unsigned PBitShift,
139*9880d681SAndroid Build Coastguard Worker unsigned QBitShift) {
140*9880d681SAndroid Build Coastguard Worker const MCOperand AluOp = Inst.getOperand(3);
141*9880d681SAndroid Build Coastguard Worker unsigned AluCode = AluOp.getImm();
142*9880d681SAndroid Build Coastguard Worker
143*9880d681SAndroid Build Coastguard Worker // Set the P bit to one iff the immediate is nonzero and not a post-op
144*9880d681SAndroid Build Coastguard Worker // instruction.
145*9880d681SAndroid Build Coastguard Worker const MCOperand Op2 = Inst.getOperand(2);
146*9880d681SAndroid Build Coastguard Worker Value &= ~(1 << PBitShift);
147*9880d681SAndroid Build Coastguard Worker if (!LPAC::isPostOp(AluCode) &&
148*9880d681SAndroid Build Coastguard Worker ((Op2.isImm() && Op2.getImm() != 0) ||
149*9880d681SAndroid Build Coastguard Worker (Op2.isReg() && Op2.getReg() != Lanai::R0) || (Op2.isExpr())))
150*9880d681SAndroid Build Coastguard Worker Value |= (1 << PBitShift);
151*9880d681SAndroid Build Coastguard Worker
152*9880d681SAndroid Build Coastguard Worker // Set the Q bit to one iff it is a post- or pre-op instruction.
153*9880d681SAndroid Build Coastguard Worker assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() &&
154*9880d681SAndroid Build Coastguard Worker "Expected register operand.");
155*9880d681SAndroid Build Coastguard Worker Value &= ~(1 << QBitShift);
156*9880d681SAndroid Build Coastguard Worker if (LPAC::modifiesOp(AluCode) && ((Op2.isImm() && Op2.getImm() != 0) ||
157*9880d681SAndroid Build Coastguard Worker (Op2.isReg() && Op2.getReg() != Lanai::R0)))
158*9880d681SAndroid Build Coastguard Worker Value |= (1 << QBitShift);
159*9880d681SAndroid Build Coastguard Worker
160*9880d681SAndroid Build Coastguard Worker return Value;
161*9880d681SAndroid Build Coastguard Worker }
162*9880d681SAndroid Build Coastguard Worker
163*9880d681SAndroid Build Coastguard Worker unsigned
adjustPqBitsRmAndRrm(const MCInst & Inst,unsigned Value,const MCSubtargetInfo & STI) const164*9880d681SAndroid Build Coastguard Worker LanaiMCCodeEmitter::adjustPqBitsRmAndRrm(const MCInst &Inst, unsigned Value,
165*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI) const {
166*9880d681SAndroid Build Coastguard Worker return adjustPqBits(Inst, Value, 17, 16);
167*9880d681SAndroid Build Coastguard Worker }
168*9880d681SAndroid Build Coastguard Worker
169*9880d681SAndroid Build Coastguard Worker unsigned
adjustPqBitsSpls(const MCInst & Inst,unsigned Value,const MCSubtargetInfo & STI) const170*9880d681SAndroid Build Coastguard Worker LanaiMCCodeEmitter::adjustPqBitsSpls(const MCInst &Inst, unsigned Value,
171*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI) const {
172*9880d681SAndroid Build Coastguard Worker return adjustPqBits(Inst, Value, 11, 10);
173*9880d681SAndroid Build Coastguard Worker }
174*9880d681SAndroid Build Coastguard Worker
encodeInstruction(const MCInst & Inst,raw_ostream & Ostream,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & SubtargetInfo) const175*9880d681SAndroid Build Coastguard Worker void LanaiMCCodeEmitter::encodeInstruction(
176*9880d681SAndroid Build Coastguard Worker const MCInst &Inst, raw_ostream &Ostream, SmallVectorImpl<MCFixup> &Fixups,
177*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &SubtargetInfo) const {
178*9880d681SAndroid Build Coastguard Worker // Get instruction encoding and emit it
179*9880d681SAndroid Build Coastguard Worker unsigned Value = getBinaryCodeForInstr(Inst, Fixups, SubtargetInfo);
180*9880d681SAndroid Build Coastguard Worker ++MCNumEmitted; // Keep track of the number of emitted insns.
181*9880d681SAndroid Build Coastguard Worker
182*9880d681SAndroid Build Coastguard Worker // Emit bytes in big-endian
183*9880d681SAndroid Build Coastguard Worker for (int i = (4 - 1) * 8; i >= 0; i -= 8)
184*9880d681SAndroid Build Coastguard Worker Ostream << static_cast<char>((Value >> i) & 0xff);
185*9880d681SAndroid Build Coastguard Worker }
186*9880d681SAndroid Build Coastguard Worker
187*9880d681SAndroid Build Coastguard Worker // Encode Lanai Memory Operand
getRiMemoryOpValue(const MCInst & Inst,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & SubtargetInfo) const188*9880d681SAndroid Build Coastguard Worker unsigned LanaiMCCodeEmitter::getRiMemoryOpValue(
189*9880d681SAndroid Build Coastguard Worker const MCInst &Inst, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups,
190*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &SubtargetInfo) const {
191*9880d681SAndroid Build Coastguard Worker unsigned Encoding;
192*9880d681SAndroid Build Coastguard Worker const MCOperand Op1 = Inst.getOperand(OpNo + 0);
193*9880d681SAndroid Build Coastguard Worker const MCOperand Op2 = Inst.getOperand(OpNo + 1);
194*9880d681SAndroid Build Coastguard Worker const MCOperand AluOp = Inst.getOperand(OpNo + 2);
195*9880d681SAndroid Build Coastguard Worker
196*9880d681SAndroid Build Coastguard Worker assert(Op1.isReg() && "First operand is not register.");
197*9880d681SAndroid Build Coastguard Worker assert((Op2.isImm() || Op2.isExpr()) &&
198*9880d681SAndroid Build Coastguard Worker "Second operand is neither an immediate nor an expression.");
199*9880d681SAndroid Build Coastguard Worker assert((LPAC::getAluOp(AluOp.getImm()) == LPAC::ADD) &&
200*9880d681SAndroid Build Coastguard Worker "Register immediate only supports addition operator");
201*9880d681SAndroid Build Coastguard Worker
202*9880d681SAndroid Build Coastguard Worker Encoding = (getLanaiRegisterNumbering(Op1.getReg()) << 18);
203*9880d681SAndroid Build Coastguard Worker if (Op2.isImm()) {
204*9880d681SAndroid Build Coastguard Worker assert(isInt<16>(Op2.getImm()) &&
205*9880d681SAndroid Build Coastguard Worker "Constant value truncated (limited to 16-bit)");
206*9880d681SAndroid Build Coastguard Worker
207*9880d681SAndroid Build Coastguard Worker Encoding |= (Op2.getImm() & 0xffff);
208*9880d681SAndroid Build Coastguard Worker if (Op2.getImm() != 0) {
209*9880d681SAndroid Build Coastguard Worker if (LPAC::isPreOp(AluOp.getImm()))
210*9880d681SAndroid Build Coastguard Worker Encoding |= (0x3 << 16);
211*9880d681SAndroid Build Coastguard Worker if (LPAC::isPostOp(AluOp.getImm()))
212*9880d681SAndroid Build Coastguard Worker Encoding |= (0x1 << 16);
213*9880d681SAndroid Build Coastguard Worker }
214*9880d681SAndroid Build Coastguard Worker } else
215*9880d681SAndroid Build Coastguard Worker getMachineOpValue(Inst, Op2, Fixups, SubtargetInfo);
216*9880d681SAndroid Build Coastguard Worker
217*9880d681SAndroid Build Coastguard Worker return Encoding;
218*9880d681SAndroid Build Coastguard Worker }
219*9880d681SAndroid Build Coastguard Worker
getRrMemoryOpValue(const MCInst & Inst,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & SubtargetInfo) const220*9880d681SAndroid Build Coastguard Worker unsigned LanaiMCCodeEmitter::getRrMemoryOpValue(
221*9880d681SAndroid Build Coastguard Worker const MCInst &Inst, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups,
222*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &SubtargetInfo) const {
223*9880d681SAndroid Build Coastguard Worker unsigned Encoding;
224*9880d681SAndroid Build Coastguard Worker const MCOperand Op1 = Inst.getOperand(OpNo + 0);
225*9880d681SAndroid Build Coastguard Worker const MCOperand Op2 = Inst.getOperand(OpNo + 1);
226*9880d681SAndroid Build Coastguard Worker const MCOperand AluMCOp = Inst.getOperand(OpNo + 2);
227*9880d681SAndroid Build Coastguard Worker
228*9880d681SAndroid Build Coastguard Worker assert(Op1.isReg() && "First operand is not register.");
229*9880d681SAndroid Build Coastguard Worker Encoding = (getLanaiRegisterNumbering(Op1.getReg()) << 15);
230*9880d681SAndroid Build Coastguard Worker assert(Op2.isReg() && "Second operand is not register.");
231*9880d681SAndroid Build Coastguard Worker Encoding |= (getLanaiRegisterNumbering(Op2.getReg()) << 10);
232*9880d681SAndroid Build Coastguard Worker
233*9880d681SAndroid Build Coastguard Worker assert(AluMCOp.isImm() && "Third operator is not immediate.");
234*9880d681SAndroid Build Coastguard Worker // Set BBB
235*9880d681SAndroid Build Coastguard Worker unsigned AluOp = AluMCOp.getImm();
236*9880d681SAndroid Build Coastguard Worker Encoding |= LPAC::encodeLanaiAluCode(AluOp) << 5;
237*9880d681SAndroid Build Coastguard Worker // Set P and Q
238*9880d681SAndroid Build Coastguard Worker if (LPAC::isPreOp(AluOp))
239*9880d681SAndroid Build Coastguard Worker Encoding |= (0x3 << 8);
240*9880d681SAndroid Build Coastguard Worker if (LPAC::isPostOp(AluOp))
241*9880d681SAndroid Build Coastguard Worker Encoding |= (0x1 << 8);
242*9880d681SAndroid Build Coastguard Worker // Set JJJJ
243*9880d681SAndroid Build Coastguard Worker switch (LPAC::getAluOp(AluOp)) {
244*9880d681SAndroid Build Coastguard Worker case LPAC::SHL:
245*9880d681SAndroid Build Coastguard Worker case LPAC::SRL:
246*9880d681SAndroid Build Coastguard Worker Encoding |= 0x10;
247*9880d681SAndroid Build Coastguard Worker break;
248*9880d681SAndroid Build Coastguard Worker case LPAC::SRA:
249*9880d681SAndroid Build Coastguard Worker Encoding |= 0x18;
250*9880d681SAndroid Build Coastguard Worker break;
251*9880d681SAndroid Build Coastguard Worker default:
252*9880d681SAndroid Build Coastguard Worker break;
253*9880d681SAndroid Build Coastguard Worker }
254*9880d681SAndroid Build Coastguard Worker
255*9880d681SAndroid Build Coastguard Worker return Encoding;
256*9880d681SAndroid Build Coastguard Worker }
257*9880d681SAndroid Build Coastguard Worker
258*9880d681SAndroid Build Coastguard Worker unsigned
getSplsOpValue(const MCInst & Inst,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & SubtargetInfo) const259*9880d681SAndroid Build Coastguard Worker LanaiMCCodeEmitter::getSplsOpValue(const MCInst &Inst, unsigned OpNo,
260*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<MCFixup> &Fixups,
261*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &SubtargetInfo) const {
262*9880d681SAndroid Build Coastguard Worker unsigned Encoding;
263*9880d681SAndroid Build Coastguard Worker const MCOperand Op1 = Inst.getOperand(OpNo + 0);
264*9880d681SAndroid Build Coastguard Worker const MCOperand Op2 = Inst.getOperand(OpNo + 1);
265*9880d681SAndroid Build Coastguard Worker const MCOperand AluOp = Inst.getOperand(OpNo + 2);
266*9880d681SAndroid Build Coastguard Worker
267*9880d681SAndroid Build Coastguard Worker assert(Op1.isReg() && "First operand is not register.");
268*9880d681SAndroid Build Coastguard Worker assert((Op2.isImm() || Op2.isExpr()) &&
269*9880d681SAndroid Build Coastguard Worker "Second operand is neither an immediate nor an expression.");
270*9880d681SAndroid Build Coastguard Worker assert((LPAC::getAluOp(AluOp.getImm()) == LPAC::ADD) &&
271*9880d681SAndroid Build Coastguard Worker "Register immediate only supports addition operator");
272*9880d681SAndroid Build Coastguard Worker
273*9880d681SAndroid Build Coastguard Worker Encoding = (getLanaiRegisterNumbering(Op1.getReg()) << 12);
274*9880d681SAndroid Build Coastguard Worker if (Op2.isImm()) {
275*9880d681SAndroid Build Coastguard Worker assert(isInt<10>(Op2.getImm()) &&
276*9880d681SAndroid Build Coastguard Worker "Constant value truncated (limited to 10-bit)");
277*9880d681SAndroid Build Coastguard Worker
278*9880d681SAndroid Build Coastguard Worker Encoding |= (Op2.getImm() & 0x3ff);
279*9880d681SAndroid Build Coastguard Worker if (Op2.getImm() != 0) {
280*9880d681SAndroid Build Coastguard Worker if (LPAC::isPreOp(AluOp.getImm()))
281*9880d681SAndroid Build Coastguard Worker Encoding |= (0x3 << 10);
282*9880d681SAndroid Build Coastguard Worker if (LPAC::isPostOp(AluOp.getImm()))
283*9880d681SAndroid Build Coastguard Worker Encoding |= (0x1 << 10);
284*9880d681SAndroid Build Coastguard Worker }
285*9880d681SAndroid Build Coastguard Worker } else
286*9880d681SAndroid Build Coastguard Worker getMachineOpValue(Inst, Op2, Fixups, SubtargetInfo);
287*9880d681SAndroid Build Coastguard Worker
288*9880d681SAndroid Build Coastguard Worker return Encoding;
289*9880d681SAndroid Build Coastguard Worker }
290*9880d681SAndroid Build Coastguard Worker
getCallTargetOpValue(const MCInst & Inst,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & SubtargetInfo) const291*9880d681SAndroid Build Coastguard Worker unsigned LanaiMCCodeEmitter::getCallTargetOpValue(
292*9880d681SAndroid Build Coastguard Worker const MCInst &Inst, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups,
293*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &SubtargetInfo) const {
294*9880d681SAndroid Build Coastguard Worker const MCOperand &MCOp = Inst.getOperand(OpNo);
295*9880d681SAndroid Build Coastguard Worker if (MCOp.isReg() || MCOp.isImm())
296*9880d681SAndroid Build Coastguard Worker return getMachineOpValue(Inst, MCOp, Fixups, SubtargetInfo);
297*9880d681SAndroid Build Coastguard Worker
298*9880d681SAndroid Build Coastguard Worker Fixups.push_back(MCFixup::create(
299*9880d681SAndroid Build Coastguard Worker 0, MCOp.getExpr(), static_cast<MCFixupKind>(Lanai::FIXUP_LANAI_25)));
300*9880d681SAndroid Build Coastguard Worker
301*9880d681SAndroid Build Coastguard Worker return 0;
302*9880d681SAndroid Build Coastguard Worker }
303*9880d681SAndroid Build Coastguard Worker
getBranchTargetOpValue(const MCInst & Inst,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & SubtargetInfo) const304*9880d681SAndroid Build Coastguard Worker unsigned LanaiMCCodeEmitter::getBranchTargetOpValue(
305*9880d681SAndroid Build Coastguard Worker const MCInst &Inst, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups,
306*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &SubtargetInfo) const {
307*9880d681SAndroid Build Coastguard Worker const MCOperand &MCOp = Inst.getOperand(OpNo);
308*9880d681SAndroid Build Coastguard Worker if (MCOp.isReg() || MCOp.isImm())
309*9880d681SAndroid Build Coastguard Worker return getMachineOpValue(Inst, MCOp, Fixups, SubtargetInfo);
310*9880d681SAndroid Build Coastguard Worker
311*9880d681SAndroid Build Coastguard Worker Fixups.push_back(MCFixup::create(
312*9880d681SAndroid Build Coastguard Worker 0, MCOp.getExpr(), static_cast<MCFixupKind>(Lanai::FIXUP_LANAI_25)));
313*9880d681SAndroid Build Coastguard Worker
314*9880d681SAndroid Build Coastguard Worker return 0;
315*9880d681SAndroid Build Coastguard Worker }
316*9880d681SAndroid Build Coastguard Worker
317*9880d681SAndroid Build Coastguard Worker #include "LanaiGenMCCodeEmitter.inc"
318*9880d681SAndroid Build Coastguard Worker } // namespace
319*9880d681SAndroid Build Coastguard Worker } // namespace llvm
320*9880d681SAndroid Build Coastguard Worker
321*9880d681SAndroid Build Coastguard Worker llvm::MCCodeEmitter *
createLanaiMCCodeEmitter(const MCInstrInfo & InstrInfo,const MCRegisterInfo & MRI,MCContext & context)322*9880d681SAndroid Build Coastguard Worker llvm::createLanaiMCCodeEmitter(const MCInstrInfo &InstrInfo,
323*9880d681SAndroid Build Coastguard Worker const MCRegisterInfo &MRI, MCContext &context) {
324*9880d681SAndroid Build Coastguard Worker return new LanaiMCCodeEmitter(InstrInfo, context);
325*9880d681SAndroid Build Coastguard Worker }
326