xref: /aosp_15_r20/external/llvm/lib/Target/Lanai/MCTargetDesc/LanaiMCCodeEmitter.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
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