xref: /aosp_15_r20/external/llvm/lib/Target/AMDGPU/MCTargetDesc/SIMCCodeEmitter.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- SIMCCodeEmitter.cpp - SI Code Emitter -------------------------------===//
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 /// \file
11*9880d681SAndroid Build Coastguard Worker /// \brief The SI code emitter produces machine code that can be executed
12*9880d681SAndroid Build Coastguard Worker /// directly on the GPU device.
13*9880d681SAndroid Build Coastguard Worker //
14*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
15*9880d681SAndroid Build Coastguard Worker 
16*9880d681SAndroid Build Coastguard Worker #include "AMDGPU.h"
17*9880d681SAndroid Build Coastguard Worker #include "MCTargetDesc/AMDGPUFixupKinds.h"
18*9880d681SAndroid Build Coastguard Worker #include "MCTargetDesc/AMDGPUMCCodeEmitter.h"
19*9880d681SAndroid Build Coastguard Worker #include "MCTargetDesc/AMDGPUMCTargetDesc.h"
20*9880d681SAndroid Build Coastguard Worker #include "SIDefines.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCCodeEmitter.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCContext.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCFixup.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCInst.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCInstrInfo.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCRegisterInfo.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSubtargetInfo.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
29*9880d681SAndroid Build Coastguard Worker 
30*9880d681SAndroid Build Coastguard Worker using namespace llvm;
31*9880d681SAndroid Build Coastguard Worker 
32*9880d681SAndroid Build Coastguard Worker namespace {
33*9880d681SAndroid Build Coastguard Worker 
34*9880d681SAndroid Build Coastguard Worker class SIMCCodeEmitter : public  AMDGPUMCCodeEmitter {
35*9880d681SAndroid Build Coastguard Worker   SIMCCodeEmitter(const SIMCCodeEmitter &) = delete;
36*9880d681SAndroid Build Coastguard Worker   void operator=(const SIMCCodeEmitter &) = delete;
37*9880d681SAndroid Build Coastguard Worker   const MCInstrInfo &MCII;
38*9880d681SAndroid Build Coastguard Worker   const MCRegisterInfo &MRI;
39*9880d681SAndroid Build Coastguard Worker 
40*9880d681SAndroid Build Coastguard Worker   /// \brief Can this operand also contain immediate values?
41*9880d681SAndroid Build Coastguard Worker   bool isSrcOperand(const MCInstrDesc &Desc, unsigned OpNo) const;
42*9880d681SAndroid Build Coastguard Worker 
43*9880d681SAndroid Build Coastguard Worker   /// \brief Encode an fp or int literal
44*9880d681SAndroid Build Coastguard Worker   uint32_t getLitEncoding(const MCOperand &MO, unsigned OpSize) const;
45*9880d681SAndroid Build Coastguard Worker 
46*9880d681SAndroid Build Coastguard Worker public:
SIMCCodeEmitter(const MCInstrInfo & mcii,const MCRegisterInfo & mri,MCContext & ctx)47*9880d681SAndroid Build Coastguard Worker   SIMCCodeEmitter(const MCInstrInfo &mcii, const MCRegisterInfo &mri,
48*9880d681SAndroid Build Coastguard Worker                   MCContext &ctx)
49*9880d681SAndroid Build Coastguard Worker     : MCII(mcii), MRI(mri) { }
50*9880d681SAndroid Build Coastguard Worker 
~SIMCCodeEmitter()51*9880d681SAndroid Build Coastguard Worker   ~SIMCCodeEmitter() override {}
52*9880d681SAndroid Build Coastguard Worker 
53*9880d681SAndroid Build Coastguard Worker   /// \brief Encode the instruction and write it to the OS.
54*9880d681SAndroid Build Coastguard Worker   void encodeInstruction(const MCInst &MI, raw_ostream &OS,
55*9880d681SAndroid Build Coastguard Worker                          SmallVectorImpl<MCFixup> &Fixups,
56*9880d681SAndroid Build Coastguard Worker                          const MCSubtargetInfo &STI) const override;
57*9880d681SAndroid Build Coastguard Worker 
58*9880d681SAndroid Build Coastguard Worker   /// \returns the encoding for an MCOperand.
59*9880d681SAndroid Build Coastguard Worker   uint64_t getMachineOpValue(const MCInst &MI, const MCOperand &MO,
60*9880d681SAndroid Build Coastguard Worker                              SmallVectorImpl<MCFixup> &Fixups,
61*9880d681SAndroid Build Coastguard Worker                              const MCSubtargetInfo &STI) const override;
62*9880d681SAndroid Build Coastguard Worker 
63*9880d681SAndroid Build Coastguard Worker   /// \brief Use a fixup to encode the simm16 field for SOPP branch
64*9880d681SAndroid Build Coastguard Worker   ///        instructions.
65*9880d681SAndroid Build Coastguard Worker   unsigned getSOPPBrEncoding(const MCInst &MI, unsigned OpNo,
66*9880d681SAndroid Build Coastguard Worker                              SmallVectorImpl<MCFixup> &Fixups,
67*9880d681SAndroid Build Coastguard Worker                              const MCSubtargetInfo &STI) const override;
68*9880d681SAndroid Build Coastguard Worker };
69*9880d681SAndroid Build Coastguard Worker 
70*9880d681SAndroid Build Coastguard Worker } // End anonymous namespace
71*9880d681SAndroid Build Coastguard Worker 
createSIMCCodeEmitter(const MCInstrInfo & MCII,const MCRegisterInfo & MRI,MCContext & Ctx)72*9880d681SAndroid Build Coastguard Worker MCCodeEmitter *llvm::createSIMCCodeEmitter(const MCInstrInfo &MCII,
73*9880d681SAndroid Build Coastguard Worker                                            const MCRegisterInfo &MRI,
74*9880d681SAndroid Build Coastguard Worker                                            MCContext &Ctx) {
75*9880d681SAndroid Build Coastguard Worker   return new SIMCCodeEmitter(MCII, MRI, Ctx);
76*9880d681SAndroid Build Coastguard Worker }
77*9880d681SAndroid Build Coastguard Worker 
isSrcOperand(const MCInstrDesc & Desc,unsigned OpNo) const78*9880d681SAndroid Build Coastguard Worker bool SIMCCodeEmitter::isSrcOperand(const MCInstrDesc &Desc,
79*9880d681SAndroid Build Coastguard Worker                                    unsigned OpNo) const {
80*9880d681SAndroid Build Coastguard Worker   unsigned OpType = Desc.OpInfo[OpNo].OperandType;
81*9880d681SAndroid Build Coastguard Worker 
82*9880d681SAndroid Build Coastguard Worker   return OpType == AMDGPU::OPERAND_REG_IMM32 ||
83*9880d681SAndroid Build Coastguard Worker          OpType == AMDGPU::OPERAND_REG_INLINE_C;
84*9880d681SAndroid Build Coastguard Worker }
85*9880d681SAndroid Build Coastguard Worker 
86*9880d681SAndroid Build Coastguard Worker // Returns the encoding value to use if the given integer is an integer inline
87*9880d681SAndroid Build Coastguard Worker // immediate value, or 0 if it is not.
88*9880d681SAndroid Build Coastguard Worker template <typename IntTy>
getIntInlineImmEncoding(IntTy Imm)89*9880d681SAndroid Build Coastguard Worker static uint32_t getIntInlineImmEncoding(IntTy Imm) {
90*9880d681SAndroid Build Coastguard Worker   if (Imm >= 0 && Imm <= 64)
91*9880d681SAndroid Build Coastguard Worker     return 128 + Imm;
92*9880d681SAndroid Build Coastguard Worker 
93*9880d681SAndroid Build Coastguard Worker   if (Imm >= -16 && Imm <= -1)
94*9880d681SAndroid Build Coastguard Worker     return 192 + std::abs(Imm);
95*9880d681SAndroid Build Coastguard Worker 
96*9880d681SAndroid Build Coastguard Worker   return 0;
97*9880d681SAndroid Build Coastguard Worker }
98*9880d681SAndroid Build Coastguard Worker 
getLit32Encoding(uint32_t Val)99*9880d681SAndroid Build Coastguard Worker static uint32_t getLit32Encoding(uint32_t Val) {
100*9880d681SAndroid Build Coastguard Worker   uint32_t IntImm = getIntInlineImmEncoding(static_cast<int32_t>(Val));
101*9880d681SAndroid Build Coastguard Worker   if (IntImm != 0)
102*9880d681SAndroid Build Coastguard Worker     return IntImm;
103*9880d681SAndroid Build Coastguard Worker 
104*9880d681SAndroid Build Coastguard Worker   if (Val == FloatToBits(0.5f))
105*9880d681SAndroid Build Coastguard Worker     return 240;
106*9880d681SAndroid Build Coastguard Worker 
107*9880d681SAndroid Build Coastguard Worker   if (Val == FloatToBits(-0.5f))
108*9880d681SAndroid Build Coastguard Worker     return 241;
109*9880d681SAndroid Build Coastguard Worker 
110*9880d681SAndroid Build Coastguard Worker   if (Val == FloatToBits(1.0f))
111*9880d681SAndroid Build Coastguard Worker     return 242;
112*9880d681SAndroid Build Coastguard Worker 
113*9880d681SAndroid Build Coastguard Worker   if (Val == FloatToBits(-1.0f))
114*9880d681SAndroid Build Coastguard Worker     return 243;
115*9880d681SAndroid Build Coastguard Worker 
116*9880d681SAndroid Build Coastguard Worker   if (Val == FloatToBits(2.0f))
117*9880d681SAndroid Build Coastguard Worker     return 244;
118*9880d681SAndroid Build Coastguard Worker 
119*9880d681SAndroid Build Coastguard Worker   if (Val == FloatToBits(-2.0f))
120*9880d681SAndroid Build Coastguard Worker     return 245;
121*9880d681SAndroid Build Coastguard Worker 
122*9880d681SAndroid Build Coastguard Worker   if (Val == FloatToBits(4.0f))
123*9880d681SAndroid Build Coastguard Worker     return 246;
124*9880d681SAndroid Build Coastguard Worker 
125*9880d681SAndroid Build Coastguard Worker   if (Val == FloatToBits(-4.0f))
126*9880d681SAndroid Build Coastguard Worker     return 247;
127*9880d681SAndroid Build Coastguard Worker 
128*9880d681SAndroid Build Coastguard Worker   return 255;
129*9880d681SAndroid Build Coastguard Worker }
130*9880d681SAndroid Build Coastguard Worker 
getLit64Encoding(uint64_t Val)131*9880d681SAndroid Build Coastguard Worker static uint32_t getLit64Encoding(uint64_t Val) {
132*9880d681SAndroid Build Coastguard Worker   uint32_t IntImm = getIntInlineImmEncoding(static_cast<int64_t>(Val));
133*9880d681SAndroid Build Coastguard Worker   if (IntImm != 0)
134*9880d681SAndroid Build Coastguard Worker     return IntImm;
135*9880d681SAndroid Build Coastguard Worker 
136*9880d681SAndroid Build Coastguard Worker   if (Val == DoubleToBits(0.5))
137*9880d681SAndroid Build Coastguard Worker     return 240;
138*9880d681SAndroid Build Coastguard Worker 
139*9880d681SAndroid Build Coastguard Worker   if (Val == DoubleToBits(-0.5))
140*9880d681SAndroid Build Coastguard Worker     return 241;
141*9880d681SAndroid Build Coastguard Worker 
142*9880d681SAndroid Build Coastguard Worker   if (Val == DoubleToBits(1.0))
143*9880d681SAndroid Build Coastguard Worker     return 242;
144*9880d681SAndroid Build Coastguard Worker 
145*9880d681SAndroid Build Coastguard Worker   if (Val == DoubleToBits(-1.0))
146*9880d681SAndroid Build Coastguard Worker     return 243;
147*9880d681SAndroid Build Coastguard Worker 
148*9880d681SAndroid Build Coastguard Worker   if (Val == DoubleToBits(2.0))
149*9880d681SAndroid Build Coastguard Worker     return 244;
150*9880d681SAndroid Build Coastguard Worker 
151*9880d681SAndroid Build Coastguard Worker   if (Val == DoubleToBits(-2.0))
152*9880d681SAndroid Build Coastguard Worker     return 245;
153*9880d681SAndroid Build Coastguard Worker 
154*9880d681SAndroid Build Coastguard Worker   if (Val == DoubleToBits(4.0))
155*9880d681SAndroid Build Coastguard Worker     return 246;
156*9880d681SAndroid Build Coastguard Worker 
157*9880d681SAndroid Build Coastguard Worker   if (Val == DoubleToBits(-4.0))
158*9880d681SAndroid Build Coastguard Worker     return 247;
159*9880d681SAndroid Build Coastguard Worker 
160*9880d681SAndroid Build Coastguard Worker   return 255;
161*9880d681SAndroid Build Coastguard Worker }
162*9880d681SAndroid Build Coastguard Worker 
getLitEncoding(const MCOperand & MO,unsigned OpSize) const163*9880d681SAndroid Build Coastguard Worker uint32_t SIMCCodeEmitter::getLitEncoding(const MCOperand &MO,
164*9880d681SAndroid Build Coastguard Worker                                          unsigned OpSize) const {
165*9880d681SAndroid Build Coastguard Worker 
166*9880d681SAndroid Build Coastguard Worker   int64_t Imm;
167*9880d681SAndroid Build Coastguard Worker   if (MO.isExpr()) {
168*9880d681SAndroid Build Coastguard Worker     const MCConstantExpr *C = dyn_cast<MCConstantExpr>(MO.getExpr());
169*9880d681SAndroid Build Coastguard Worker     if (!C)
170*9880d681SAndroid Build Coastguard Worker       return 255;
171*9880d681SAndroid Build Coastguard Worker 
172*9880d681SAndroid Build Coastguard Worker     Imm = C->getValue();
173*9880d681SAndroid Build Coastguard Worker   } else {
174*9880d681SAndroid Build Coastguard Worker 
175*9880d681SAndroid Build Coastguard Worker     assert(!MO.isFPImm());
176*9880d681SAndroid Build Coastguard Worker 
177*9880d681SAndroid Build Coastguard Worker     if (!MO.isImm())
178*9880d681SAndroid Build Coastguard Worker       return ~0;
179*9880d681SAndroid Build Coastguard Worker 
180*9880d681SAndroid Build Coastguard Worker     Imm = MO.getImm();
181*9880d681SAndroid Build Coastguard Worker   }
182*9880d681SAndroid Build Coastguard Worker 
183*9880d681SAndroid Build Coastguard Worker   if (OpSize == 4)
184*9880d681SAndroid Build Coastguard Worker     return getLit32Encoding(static_cast<uint32_t>(Imm));
185*9880d681SAndroid Build Coastguard Worker 
186*9880d681SAndroid Build Coastguard Worker   assert(OpSize == 8);
187*9880d681SAndroid Build Coastguard Worker 
188*9880d681SAndroid Build Coastguard Worker   return getLit64Encoding(static_cast<uint64_t>(Imm));
189*9880d681SAndroid Build Coastguard Worker }
190*9880d681SAndroid Build Coastguard Worker 
encodeInstruction(const MCInst & MI,raw_ostream & OS,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const191*9880d681SAndroid Build Coastguard Worker void SIMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
192*9880d681SAndroid Build Coastguard Worker                                        SmallVectorImpl<MCFixup> &Fixups,
193*9880d681SAndroid Build Coastguard Worker                                        const MCSubtargetInfo &STI) const {
194*9880d681SAndroid Build Coastguard Worker 
195*9880d681SAndroid Build Coastguard Worker   uint64_t Encoding = getBinaryCodeForInstr(MI, Fixups, STI);
196*9880d681SAndroid Build Coastguard Worker   const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
197*9880d681SAndroid Build Coastguard Worker   unsigned bytes = Desc.getSize();
198*9880d681SAndroid Build Coastguard Worker 
199*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0; i < bytes; i++) {
200*9880d681SAndroid Build Coastguard Worker     OS.write((uint8_t) ((Encoding >> (8 * i)) & 0xff));
201*9880d681SAndroid Build Coastguard Worker   }
202*9880d681SAndroid Build Coastguard Worker 
203*9880d681SAndroid Build Coastguard Worker   if (bytes > 4)
204*9880d681SAndroid Build Coastguard Worker     return;
205*9880d681SAndroid Build Coastguard Worker 
206*9880d681SAndroid Build Coastguard Worker   // Check for additional literals in SRC0/1/2 (Op 1/2/3)
207*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, e = MI.getNumOperands(); i < e; ++i) {
208*9880d681SAndroid Build Coastguard Worker 
209*9880d681SAndroid Build Coastguard Worker     // Check if this operand should be encoded as [SV]Src
210*9880d681SAndroid Build Coastguard Worker     if (!isSrcOperand(Desc, i))
211*9880d681SAndroid Build Coastguard Worker       continue;
212*9880d681SAndroid Build Coastguard Worker 
213*9880d681SAndroid Build Coastguard Worker     int RCID = Desc.OpInfo[i].RegClass;
214*9880d681SAndroid Build Coastguard Worker     const MCRegisterClass &RC = MRI.getRegClass(RCID);
215*9880d681SAndroid Build Coastguard Worker 
216*9880d681SAndroid Build Coastguard Worker     // Is this operand a literal immediate?
217*9880d681SAndroid Build Coastguard Worker     const MCOperand &Op = MI.getOperand(i);
218*9880d681SAndroid Build Coastguard Worker     if (getLitEncoding(Op, RC.getSize()) != 255)
219*9880d681SAndroid Build Coastguard Worker       continue;
220*9880d681SAndroid Build Coastguard Worker 
221*9880d681SAndroid Build Coastguard Worker     // Yes! Encode it
222*9880d681SAndroid Build Coastguard Worker     int64_t Imm = 0;
223*9880d681SAndroid Build Coastguard Worker 
224*9880d681SAndroid Build Coastguard Worker     if (Op.isImm())
225*9880d681SAndroid Build Coastguard Worker       Imm = Op.getImm();
226*9880d681SAndroid Build Coastguard Worker     else if (Op.isExpr()) {
227*9880d681SAndroid Build Coastguard Worker       if (const MCConstantExpr *C = dyn_cast<MCConstantExpr>(Op.getExpr()))
228*9880d681SAndroid Build Coastguard Worker         Imm = C->getValue();
229*9880d681SAndroid Build Coastguard Worker 
230*9880d681SAndroid Build Coastguard Worker     } else if (!Op.isExpr()) // Exprs will be replaced with a fixup value.
231*9880d681SAndroid Build Coastguard Worker       llvm_unreachable("Must be immediate or expr");
232*9880d681SAndroid Build Coastguard Worker 
233*9880d681SAndroid Build Coastguard Worker     for (unsigned j = 0; j < 4; j++) {
234*9880d681SAndroid Build Coastguard Worker       OS.write((uint8_t) ((Imm >> (8 * j)) & 0xff));
235*9880d681SAndroid Build Coastguard Worker     }
236*9880d681SAndroid Build Coastguard Worker 
237*9880d681SAndroid Build Coastguard Worker     // Only one literal value allowed
238*9880d681SAndroid Build Coastguard Worker     break;
239*9880d681SAndroid Build Coastguard Worker   }
240*9880d681SAndroid Build Coastguard Worker }
241*9880d681SAndroid Build Coastguard Worker 
getSOPPBrEncoding(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const242*9880d681SAndroid Build Coastguard Worker unsigned SIMCCodeEmitter::getSOPPBrEncoding(const MCInst &MI, unsigned OpNo,
243*9880d681SAndroid Build Coastguard Worker                                             SmallVectorImpl<MCFixup> &Fixups,
244*9880d681SAndroid Build Coastguard Worker                                             const MCSubtargetInfo &STI) const {
245*9880d681SAndroid Build Coastguard Worker   const MCOperand &MO = MI.getOperand(OpNo);
246*9880d681SAndroid Build Coastguard Worker 
247*9880d681SAndroid Build Coastguard Worker   if (MO.isExpr()) {
248*9880d681SAndroid Build Coastguard Worker     const MCExpr *Expr = MO.getExpr();
249*9880d681SAndroid Build Coastguard Worker     MCFixupKind Kind = (MCFixupKind)AMDGPU::fixup_si_sopp_br;
250*9880d681SAndroid Build Coastguard Worker     Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc()));
251*9880d681SAndroid Build Coastguard Worker     return 0;
252*9880d681SAndroid Build Coastguard Worker   }
253*9880d681SAndroid Build Coastguard Worker 
254*9880d681SAndroid Build Coastguard Worker   return getMachineOpValue(MI, MO, Fixups, STI);
255*9880d681SAndroid Build Coastguard Worker }
256*9880d681SAndroid Build Coastguard Worker 
getMachineOpValue(const MCInst & MI,const MCOperand & MO,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const257*9880d681SAndroid Build Coastguard Worker uint64_t SIMCCodeEmitter::getMachineOpValue(const MCInst &MI,
258*9880d681SAndroid Build Coastguard Worker                                             const MCOperand &MO,
259*9880d681SAndroid Build Coastguard Worker                                        SmallVectorImpl<MCFixup> &Fixups,
260*9880d681SAndroid Build Coastguard Worker                                        const MCSubtargetInfo &STI) const {
261*9880d681SAndroid Build Coastguard Worker   if (MO.isReg())
262*9880d681SAndroid Build Coastguard Worker     return MRI.getEncodingValue(MO.getReg());
263*9880d681SAndroid Build Coastguard Worker 
264*9880d681SAndroid Build Coastguard Worker   if (MO.isExpr() && MO.getExpr()->getKind() != MCExpr::Constant) {
265*9880d681SAndroid Build Coastguard Worker     const MCSymbolRefExpr *Expr = dyn_cast<MCSymbolRefExpr>(MO.getExpr());
266*9880d681SAndroid Build Coastguard Worker     MCFixupKind Kind;
267*9880d681SAndroid Build Coastguard Worker     if (Expr && Expr->getSymbol().isExternal())
268*9880d681SAndroid Build Coastguard Worker       Kind = FK_Data_4;
269*9880d681SAndroid Build Coastguard Worker     else
270*9880d681SAndroid Build Coastguard Worker       Kind = FK_PCRel_4;
271*9880d681SAndroid Build Coastguard Worker     Fixups.push_back(MCFixup::create(4, MO.getExpr(), Kind, MI.getLoc()));
272*9880d681SAndroid Build Coastguard Worker   }
273*9880d681SAndroid Build Coastguard Worker 
274*9880d681SAndroid Build Coastguard Worker   // Figure out the operand number, needed for isSrcOperand check
275*9880d681SAndroid Build Coastguard Worker   unsigned OpNo = 0;
276*9880d681SAndroid Build Coastguard Worker   for (unsigned e = MI.getNumOperands(); OpNo < e; ++OpNo) {
277*9880d681SAndroid Build Coastguard Worker     if (&MO == &MI.getOperand(OpNo))
278*9880d681SAndroid Build Coastguard Worker       break;
279*9880d681SAndroid Build Coastguard Worker   }
280*9880d681SAndroid Build Coastguard Worker 
281*9880d681SAndroid Build Coastguard Worker   const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
282*9880d681SAndroid Build Coastguard Worker   if (isSrcOperand(Desc, OpNo)) {
283*9880d681SAndroid Build Coastguard Worker     int RCID = Desc.OpInfo[OpNo].RegClass;
284*9880d681SAndroid Build Coastguard Worker     const MCRegisterClass &RC = MRI.getRegClass(RCID);
285*9880d681SAndroid Build Coastguard Worker 
286*9880d681SAndroid Build Coastguard Worker     uint32_t Enc = getLitEncoding(MO, RC.getSize());
287*9880d681SAndroid Build Coastguard Worker     if (Enc != ~0U && (Enc != 255 || Desc.getSize() == 4))
288*9880d681SAndroid Build Coastguard Worker       return Enc;
289*9880d681SAndroid Build Coastguard Worker 
290*9880d681SAndroid Build Coastguard Worker   } else if (MO.isImm())
291*9880d681SAndroid Build Coastguard Worker     return MO.getImm();
292*9880d681SAndroid Build Coastguard Worker 
293*9880d681SAndroid Build Coastguard Worker   llvm_unreachable("Encoding of this operand type is not supported yet.");
294*9880d681SAndroid Build Coastguard Worker   return 0;
295*9880d681SAndroid Build Coastguard Worker }
296*9880d681SAndroid Build Coastguard Worker 
297