xref: /aosp_15_r20/external/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- SparcAsmParser.cpp - Parse Sparc assembly to MCInst instructions --===//
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 #include "MCTargetDesc/SparcMCExpr.h"
11*9880d681SAndroid Build Coastguard Worker #include "MCTargetDesc/SparcMCTargetDesc.h"
12*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/STLExtras.h"
13*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCContext.h"
14*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCInst.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCObjectFileInfo.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCParser/MCTargetAsmParser.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCRegisterInfo.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCStreamer.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSubtargetInfo.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSymbol.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/TargetRegistry.h"
23*9880d681SAndroid Build Coastguard Worker 
24*9880d681SAndroid Build Coastguard Worker using namespace llvm;
25*9880d681SAndroid Build Coastguard Worker 
26*9880d681SAndroid Build Coastguard Worker // The generated AsmMatcher SparcGenAsmMatcher uses "Sparc" as the target
27*9880d681SAndroid Build Coastguard Worker // namespace. But SPARC backend uses "SP" as its namespace.
28*9880d681SAndroid Build Coastguard Worker namespace llvm {
29*9880d681SAndroid Build Coastguard Worker   namespace Sparc {
30*9880d681SAndroid Build Coastguard Worker     using namespace SP;
31*9880d681SAndroid Build Coastguard Worker   }
32*9880d681SAndroid Build Coastguard Worker }
33*9880d681SAndroid Build Coastguard Worker 
34*9880d681SAndroid Build Coastguard Worker namespace {
35*9880d681SAndroid Build Coastguard Worker class SparcOperand;
36*9880d681SAndroid Build Coastguard Worker class SparcAsmParser : public MCTargetAsmParser {
37*9880d681SAndroid Build Coastguard Worker 
38*9880d681SAndroid Build Coastguard Worker   MCAsmParser &Parser;
39*9880d681SAndroid Build Coastguard Worker 
40*9880d681SAndroid Build Coastguard Worker   /// @name Auto-generated Match Functions
41*9880d681SAndroid Build Coastguard Worker   /// {
42*9880d681SAndroid Build Coastguard Worker 
43*9880d681SAndroid Build Coastguard Worker #define GET_ASSEMBLER_HEADER
44*9880d681SAndroid Build Coastguard Worker #include "SparcGenAsmMatcher.inc"
45*9880d681SAndroid Build Coastguard Worker 
46*9880d681SAndroid Build Coastguard Worker   /// }
47*9880d681SAndroid Build Coastguard Worker 
48*9880d681SAndroid Build Coastguard Worker   // public interface of the MCTargetAsmParser.
49*9880d681SAndroid Build Coastguard Worker   bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
50*9880d681SAndroid Build Coastguard Worker                                OperandVector &Operands, MCStreamer &Out,
51*9880d681SAndroid Build Coastguard Worker                                uint64_t &ErrorInfo,
52*9880d681SAndroid Build Coastguard Worker                                bool MatchingInlineAsm) override;
53*9880d681SAndroid Build Coastguard Worker   bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
54*9880d681SAndroid Build Coastguard Worker   bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
55*9880d681SAndroid Build Coastguard Worker                         SMLoc NameLoc, OperandVector &Operands) override;
56*9880d681SAndroid Build Coastguard Worker   bool ParseDirective(AsmToken DirectiveID) override;
57*9880d681SAndroid Build Coastguard Worker 
58*9880d681SAndroid Build Coastguard Worker   unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
59*9880d681SAndroid Build Coastguard Worker                                       unsigned Kind) override;
60*9880d681SAndroid Build Coastguard Worker 
61*9880d681SAndroid Build Coastguard Worker   // Custom parse functions for Sparc specific operands.
62*9880d681SAndroid Build Coastguard Worker   OperandMatchResultTy parseMEMOperand(OperandVector &Operands);
63*9880d681SAndroid Build Coastguard Worker 
64*9880d681SAndroid Build Coastguard Worker   OperandMatchResultTy parseOperand(OperandVector &Operands, StringRef Name);
65*9880d681SAndroid Build Coastguard Worker 
66*9880d681SAndroid Build Coastguard Worker   OperandMatchResultTy
67*9880d681SAndroid Build Coastguard Worker   parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Operand,
68*9880d681SAndroid Build Coastguard Worker                        bool isCall = false);
69*9880d681SAndroid Build Coastguard Worker 
70*9880d681SAndroid Build Coastguard Worker   OperandMatchResultTy parseBranchModifiers(OperandVector &Operands);
71*9880d681SAndroid Build Coastguard Worker 
72*9880d681SAndroid Build Coastguard Worker   // Helper function for dealing with %lo / %hi in PIC mode.
73*9880d681SAndroid Build Coastguard Worker   const SparcMCExpr *adjustPICRelocation(SparcMCExpr::VariantKind VK,
74*9880d681SAndroid Build Coastguard Worker                                          const MCExpr *subExpr);
75*9880d681SAndroid Build Coastguard Worker 
76*9880d681SAndroid Build Coastguard Worker   // returns true if Tok is matched to a register and returns register in RegNo.
77*9880d681SAndroid Build Coastguard Worker   bool matchRegisterName(const AsmToken &Tok, unsigned &RegNo,
78*9880d681SAndroid Build Coastguard Worker                          unsigned &RegKind);
79*9880d681SAndroid Build Coastguard Worker 
80*9880d681SAndroid Build Coastguard Worker   bool matchSparcAsmModifiers(const MCExpr *&EVal, SMLoc &EndLoc);
81*9880d681SAndroid Build Coastguard Worker   bool parseDirectiveWord(unsigned Size, SMLoc L);
82*9880d681SAndroid Build Coastguard Worker 
is64Bit() const83*9880d681SAndroid Build Coastguard Worker   bool is64Bit() const {
84*9880d681SAndroid Build Coastguard Worker     return getSTI().getTargetTriple().getArch() == Triple::sparcv9;
85*9880d681SAndroid Build Coastguard Worker   }
86*9880d681SAndroid Build Coastguard Worker 
87*9880d681SAndroid Build Coastguard Worker   void expandSET(MCInst &Inst, SMLoc IDLoc,
88*9880d681SAndroid Build Coastguard Worker                  SmallVectorImpl<MCInst> &Instructions);
89*9880d681SAndroid Build Coastguard Worker 
90*9880d681SAndroid Build Coastguard Worker public:
SparcAsmParser(const MCSubtargetInfo & sti,MCAsmParser & parser,const MCInstrInfo & MII,const MCTargetOptions & Options)91*9880d681SAndroid Build Coastguard Worker   SparcAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
92*9880d681SAndroid Build Coastguard Worker                 const MCInstrInfo &MII,
93*9880d681SAndroid Build Coastguard Worker                 const MCTargetOptions &Options)
94*9880d681SAndroid Build Coastguard Worker       : MCTargetAsmParser(Options, sti), Parser(parser) {
95*9880d681SAndroid Build Coastguard Worker     // Initialize the set of available features.
96*9880d681SAndroid Build Coastguard Worker     setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
97*9880d681SAndroid Build Coastguard Worker   }
98*9880d681SAndroid Build Coastguard Worker 
99*9880d681SAndroid Build Coastguard Worker };
100*9880d681SAndroid Build Coastguard Worker 
101*9880d681SAndroid Build Coastguard Worker   static const MCPhysReg IntRegs[32] = {
102*9880d681SAndroid Build Coastguard Worker     Sparc::G0, Sparc::G1, Sparc::G2, Sparc::G3,
103*9880d681SAndroid Build Coastguard Worker     Sparc::G4, Sparc::G5, Sparc::G6, Sparc::G7,
104*9880d681SAndroid Build Coastguard Worker     Sparc::O0, Sparc::O1, Sparc::O2, Sparc::O3,
105*9880d681SAndroid Build Coastguard Worker     Sparc::O4, Sparc::O5, Sparc::O6, Sparc::O7,
106*9880d681SAndroid Build Coastguard Worker     Sparc::L0, Sparc::L1, Sparc::L2, Sparc::L3,
107*9880d681SAndroid Build Coastguard Worker     Sparc::L4, Sparc::L5, Sparc::L6, Sparc::L7,
108*9880d681SAndroid Build Coastguard Worker     Sparc::I0, Sparc::I1, Sparc::I2, Sparc::I3,
109*9880d681SAndroid Build Coastguard Worker     Sparc::I4, Sparc::I5, Sparc::I6, Sparc::I7 };
110*9880d681SAndroid Build Coastguard Worker 
111*9880d681SAndroid Build Coastguard Worker   static const MCPhysReg FloatRegs[32] = {
112*9880d681SAndroid Build Coastguard Worker     Sparc::F0,  Sparc::F1,  Sparc::F2,  Sparc::F3,
113*9880d681SAndroid Build Coastguard Worker     Sparc::F4,  Sparc::F5,  Sparc::F6,  Sparc::F7,
114*9880d681SAndroid Build Coastguard Worker     Sparc::F8,  Sparc::F9,  Sparc::F10, Sparc::F11,
115*9880d681SAndroid Build Coastguard Worker     Sparc::F12, Sparc::F13, Sparc::F14, Sparc::F15,
116*9880d681SAndroid Build Coastguard Worker     Sparc::F16, Sparc::F17, Sparc::F18, Sparc::F19,
117*9880d681SAndroid Build Coastguard Worker     Sparc::F20, Sparc::F21, Sparc::F22, Sparc::F23,
118*9880d681SAndroid Build Coastguard Worker     Sparc::F24, Sparc::F25, Sparc::F26, Sparc::F27,
119*9880d681SAndroid Build Coastguard Worker     Sparc::F28, Sparc::F29, Sparc::F30, Sparc::F31 };
120*9880d681SAndroid Build Coastguard Worker 
121*9880d681SAndroid Build Coastguard Worker   static const MCPhysReg DoubleRegs[32] = {
122*9880d681SAndroid Build Coastguard Worker     Sparc::D0,  Sparc::D1,  Sparc::D2,  Sparc::D3,
123*9880d681SAndroid Build Coastguard Worker     Sparc::D4,  Sparc::D5,  Sparc::D6,  Sparc::D7,
124*9880d681SAndroid Build Coastguard Worker     Sparc::D8,  Sparc::D7,  Sparc::D8,  Sparc::D9,
125*9880d681SAndroid Build Coastguard Worker     Sparc::D12, Sparc::D13, Sparc::D14, Sparc::D15,
126*9880d681SAndroid Build Coastguard Worker     Sparc::D16, Sparc::D17, Sparc::D18, Sparc::D19,
127*9880d681SAndroid Build Coastguard Worker     Sparc::D20, Sparc::D21, Sparc::D22, Sparc::D23,
128*9880d681SAndroid Build Coastguard Worker     Sparc::D24, Sparc::D25, Sparc::D26, Sparc::D27,
129*9880d681SAndroid Build Coastguard Worker     Sparc::D28, Sparc::D29, Sparc::D30, Sparc::D31 };
130*9880d681SAndroid Build Coastguard Worker 
131*9880d681SAndroid Build Coastguard Worker   static const MCPhysReg QuadFPRegs[32] = {
132*9880d681SAndroid Build Coastguard Worker     Sparc::Q0,  Sparc::Q1,  Sparc::Q2,  Sparc::Q3,
133*9880d681SAndroid Build Coastguard Worker     Sparc::Q4,  Sparc::Q5,  Sparc::Q6,  Sparc::Q7,
134*9880d681SAndroid Build Coastguard Worker     Sparc::Q8,  Sparc::Q9,  Sparc::Q10, Sparc::Q11,
135*9880d681SAndroid Build Coastguard Worker     Sparc::Q12, Sparc::Q13, Sparc::Q14, Sparc::Q15 };
136*9880d681SAndroid Build Coastguard Worker 
137*9880d681SAndroid Build Coastguard Worker   static const MCPhysReg ASRRegs[32] = {
138*9880d681SAndroid Build Coastguard Worker     SP::Y,     SP::ASR1,  SP::ASR2,  SP::ASR3,
139*9880d681SAndroid Build Coastguard Worker     SP::ASR4,  SP::ASR5,  SP::ASR6, SP::ASR7,
140*9880d681SAndroid Build Coastguard Worker     SP::ASR8,  SP::ASR9,  SP::ASR10, SP::ASR11,
141*9880d681SAndroid Build Coastguard Worker     SP::ASR12, SP::ASR13, SP::ASR14, SP::ASR15,
142*9880d681SAndroid Build Coastguard Worker     SP::ASR16, SP::ASR17, SP::ASR18, SP::ASR19,
143*9880d681SAndroid Build Coastguard Worker     SP::ASR20, SP::ASR21, SP::ASR22, SP::ASR23,
144*9880d681SAndroid Build Coastguard Worker     SP::ASR24, SP::ASR25, SP::ASR26, SP::ASR27,
145*9880d681SAndroid Build Coastguard Worker     SP::ASR28, SP::ASR29, SP::ASR30, SP::ASR31};
146*9880d681SAndroid Build Coastguard Worker 
147*9880d681SAndroid Build Coastguard Worker   static const MCPhysReg IntPairRegs[] = {
148*9880d681SAndroid Build Coastguard Worker     Sparc::G0_G1, Sparc::G2_G3, Sparc::G4_G5, Sparc::G6_G7,
149*9880d681SAndroid Build Coastguard Worker     Sparc::O0_O1, Sparc::O2_O3, Sparc::O4_O5, Sparc::O6_O7,
150*9880d681SAndroid Build Coastguard Worker     Sparc::L0_L1, Sparc::L2_L3, Sparc::L4_L5, Sparc::L6_L7,
151*9880d681SAndroid Build Coastguard Worker     Sparc::I0_I1, Sparc::I2_I3, Sparc::I4_I5, Sparc::I6_I7};
152*9880d681SAndroid Build Coastguard Worker 
153*9880d681SAndroid Build Coastguard Worker   static const MCPhysReg CoprocRegs[32] = {
154*9880d681SAndroid Build Coastguard Worker     Sparc::C0,  Sparc::C1,  Sparc::C2,  Sparc::C3,
155*9880d681SAndroid Build Coastguard Worker     Sparc::C4,  Sparc::C5,  Sparc::C6,  Sparc::C7,
156*9880d681SAndroid Build Coastguard Worker     Sparc::C8,  Sparc::C9,  Sparc::C10, Sparc::C11,
157*9880d681SAndroid Build Coastguard Worker     Sparc::C12, Sparc::C13, Sparc::C14, Sparc::C15,
158*9880d681SAndroid Build Coastguard Worker     Sparc::C16, Sparc::C17, Sparc::C18, Sparc::C19,
159*9880d681SAndroid Build Coastguard Worker     Sparc::C20, Sparc::C21, Sparc::C22, Sparc::C23,
160*9880d681SAndroid Build Coastguard Worker     Sparc::C24, Sparc::C25, Sparc::C26, Sparc::C27,
161*9880d681SAndroid Build Coastguard Worker     Sparc::C28, Sparc::C29, Sparc::C30, Sparc::C31 };
162*9880d681SAndroid Build Coastguard Worker 
163*9880d681SAndroid Build Coastguard Worker   static const MCPhysReg CoprocPairRegs[] = {
164*9880d681SAndroid Build Coastguard Worker     Sparc::C0_C1,   Sparc::C2_C3,   Sparc::C4_C5,   Sparc::C6_C7,
165*9880d681SAndroid Build Coastguard Worker     Sparc::C8_C9,   Sparc::C10_C11, Sparc::C12_C13, Sparc::C14_C15,
166*9880d681SAndroid Build Coastguard Worker     Sparc::C16_C17, Sparc::C18_C19, Sparc::C20_C21, Sparc::C22_C23,
167*9880d681SAndroid Build Coastguard Worker     Sparc::C24_C25, Sparc::C26_C27, Sparc::C28_C29, Sparc::C30_C31};
168*9880d681SAndroid Build Coastguard Worker 
169*9880d681SAndroid Build Coastguard Worker /// SparcOperand - Instances of this class represent a parsed Sparc machine
170*9880d681SAndroid Build Coastguard Worker /// instruction.
171*9880d681SAndroid Build Coastguard Worker class SparcOperand : public MCParsedAsmOperand {
172*9880d681SAndroid Build Coastguard Worker public:
173*9880d681SAndroid Build Coastguard Worker   enum RegisterKind {
174*9880d681SAndroid Build Coastguard Worker     rk_None,
175*9880d681SAndroid Build Coastguard Worker     rk_IntReg,
176*9880d681SAndroid Build Coastguard Worker     rk_IntPairReg,
177*9880d681SAndroid Build Coastguard Worker     rk_FloatReg,
178*9880d681SAndroid Build Coastguard Worker     rk_DoubleReg,
179*9880d681SAndroid Build Coastguard Worker     rk_QuadReg,
180*9880d681SAndroid Build Coastguard Worker     rk_CoprocReg,
181*9880d681SAndroid Build Coastguard Worker     rk_CoprocPairReg,
182*9880d681SAndroid Build Coastguard Worker     rk_Special,
183*9880d681SAndroid Build Coastguard Worker   };
184*9880d681SAndroid Build Coastguard Worker 
185*9880d681SAndroid Build Coastguard Worker private:
186*9880d681SAndroid Build Coastguard Worker   enum KindTy {
187*9880d681SAndroid Build Coastguard Worker     k_Token,
188*9880d681SAndroid Build Coastguard Worker     k_Register,
189*9880d681SAndroid Build Coastguard Worker     k_Immediate,
190*9880d681SAndroid Build Coastguard Worker     k_MemoryReg,
191*9880d681SAndroid Build Coastguard Worker     k_MemoryImm
192*9880d681SAndroid Build Coastguard Worker   } Kind;
193*9880d681SAndroid Build Coastguard Worker 
194*9880d681SAndroid Build Coastguard Worker   SMLoc StartLoc, EndLoc;
195*9880d681SAndroid Build Coastguard Worker 
196*9880d681SAndroid Build Coastguard Worker   struct Token {
197*9880d681SAndroid Build Coastguard Worker     const char *Data;
198*9880d681SAndroid Build Coastguard Worker     unsigned Length;
199*9880d681SAndroid Build Coastguard Worker   };
200*9880d681SAndroid Build Coastguard Worker 
201*9880d681SAndroid Build Coastguard Worker   struct RegOp {
202*9880d681SAndroid Build Coastguard Worker     unsigned RegNum;
203*9880d681SAndroid Build Coastguard Worker     RegisterKind Kind;
204*9880d681SAndroid Build Coastguard Worker   };
205*9880d681SAndroid Build Coastguard Worker 
206*9880d681SAndroid Build Coastguard Worker   struct ImmOp {
207*9880d681SAndroid Build Coastguard Worker     const MCExpr *Val;
208*9880d681SAndroid Build Coastguard Worker   };
209*9880d681SAndroid Build Coastguard Worker 
210*9880d681SAndroid Build Coastguard Worker   struct MemOp {
211*9880d681SAndroid Build Coastguard Worker     unsigned Base;
212*9880d681SAndroid Build Coastguard Worker     unsigned OffsetReg;
213*9880d681SAndroid Build Coastguard Worker     const MCExpr *Off;
214*9880d681SAndroid Build Coastguard Worker   };
215*9880d681SAndroid Build Coastguard Worker 
216*9880d681SAndroid Build Coastguard Worker   union {
217*9880d681SAndroid Build Coastguard Worker     struct Token Tok;
218*9880d681SAndroid Build Coastguard Worker     struct RegOp Reg;
219*9880d681SAndroid Build Coastguard Worker     struct ImmOp Imm;
220*9880d681SAndroid Build Coastguard Worker     struct MemOp Mem;
221*9880d681SAndroid Build Coastguard Worker   };
222*9880d681SAndroid Build Coastguard Worker public:
SparcOperand(KindTy K)223*9880d681SAndroid Build Coastguard Worker   SparcOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
224*9880d681SAndroid Build Coastguard Worker 
isToken() const225*9880d681SAndroid Build Coastguard Worker   bool isToken() const override { return Kind == k_Token; }
isReg() const226*9880d681SAndroid Build Coastguard Worker   bool isReg() const override { return Kind == k_Register; }
isImm() const227*9880d681SAndroid Build Coastguard Worker   bool isImm() const override { return Kind == k_Immediate; }
isMem() const228*9880d681SAndroid Build Coastguard Worker   bool isMem() const override { return isMEMrr() || isMEMri(); }
isMEMrr() const229*9880d681SAndroid Build Coastguard Worker   bool isMEMrr() const { return Kind == k_MemoryReg; }
isMEMri() const230*9880d681SAndroid Build Coastguard Worker   bool isMEMri() const { return Kind == k_MemoryImm; }
231*9880d681SAndroid Build Coastguard Worker 
isIntReg() const232*9880d681SAndroid Build Coastguard Worker   bool isIntReg() const {
233*9880d681SAndroid Build Coastguard Worker     return (Kind == k_Register && Reg.Kind == rk_IntReg);
234*9880d681SAndroid Build Coastguard Worker   }
235*9880d681SAndroid Build Coastguard Worker 
isFloatReg() const236*9880d681SAndroid Build Coastguard Worker   bool isFloatReg() const {
237*9880d681SAndroid Build Coastguard Worker     return (Kind == k_Register && Reg.Kind == rk_FloatReg);
238*9880d681SAndroid Build Coastguard Worker   }
239*9880d681SAndroid Build Coastguard Worker 
isFloatOrDoubleReg() const240*9880d681SAndroid Build Coastguard Worker   bool isFloatOrDoubleReg() const {
241*9880d681SAndroid Build Coastguard Worker     return (Kind == k_Register && (Reg.Kind == rk_FloatReg
242*9880d681SAndroid Build Coastguard Worker                                    || Reg.Kind == rk_DoubleReg));
243*9880d681SAndroid Build Coastguard Worker   }
244*9880d681SAndroid Build Coastguard Worker 
isCoprocReg() const245*9880d681SAndroid Build Coastguard Worker   bool isCoprocReg() const {
246*9880d681SAndroid Build Coastguard Worker     return (Kind == k_Register && Reg.Kind == rk_CoprocReg);
247*9880d681SAndroid Build Coastguard Worker   }
248*9880d681SAndroid Build Coastguard Worker 
getToken() const249*9880d681SAndroid Build Coastguard Worker   StringRef getToken() const {
250*9880d681SAndroid Build Coastguard Worker     assert(Kind == k_Token && "Invalid access!");
251*9880d681SAndroid Build Coastguard Worker     return StringRef(Tok.Data, Tok.Length);
252*9880d681SAndroid Build Coastguard Worker   }
253*9880d681SAndroid Build Coastguard Worker 
getReg() const254*9880d681SAndroid Build Coastguard Worker   unsigned getReg() const override {
255*9880d681SAndroid Build Coastguard Worker     assert((Kind == k_Register) && "Invalid access!");
256*9880d681SAndroid Build Coastguard Worker     return Reg.RegNum;
257*9880d681SAndroid Build Coastguard Worker   }
258*9880d681SAndroid Build Coastguard Worker 
getImm() const259*9880d681SAndroid Build Coastguard Worker   const MCExpr *getImm() const {
260*9880d681SAndroid Build Coastguard Worker     assert((Kind == k_Immediate) && "Invalid access!");
261*9880d681SAndroid Build Coastguard Worker     return Imm.Val;
262*9880d681SAndroid Build Coastguard Worker   }
263*9880d681SAndroid Build Coastguard Worker 
getMemBase() const264*9880d681SAndroid Build Coastguard Worker   unsigned getMemBase() const {
265*9880d681SAndroid Build Coastguard Worker     assert((Kind == k_MemoryReg || Kind == k_MemoryImm) && "Invalid access!");
266*9880d681SAndroid Build Coastguard Worker     return Mem.Base;
267*9880d681SAndroid Build Coastguard Worker   }
268*9880d681SAndroid Build Coastguard Worker 
getMemOffsetReg() const269*9880d681SAndroid Build Coastguard Worker   unsigned getMemOffsetReg() const {
270*9880d681SAndroid Build Coastguard Worker     assert((Kind == k_MemoryReg) && "Invalid access!");
271*9880d681SAndroid Build Coastguard Worker     return Mem.OffsetReg;
272*9880d681SAndroid Build Coastguard Worker   }
273*9880d681SAndroid Build Coastguard Worker 
getMemOff() const274*9880d681SAndroid Build Coastguard Worker   const MCExpr *getMemOff() const {
275*9880d681SAndroid Build Coastguard Worker     assert((Kind == k_MemoryImm) && "Invalid access!");
276*9880d681SAndroid Build Coastguard Worker     return Mem.Off;
277*9880d681SAndroid Build Coastguard Worker   }
278*9880d681SAndroid Build Coastguard Worker 
279*9880d681SAndroid Build Coastguard Worker   /// getStartLoc - Get the location of the first token of this operand.
getStartLoc() const280*9880d681SAndroid Build Coastguard Worker   SMLoc getStartLoc() const override {
281*9880d681SAndroid Build Coastguard Worker     return StartLoc;
282*9880d681SAndroid Build Coastguard Worker   }
283*9880d681SAndroid Build Coastguard Worker   /// getEndLoc - Get the location of the last token of this operand.
getEndLoc() const284*9880d681SAndroid Build Coastguard Worker   SMLoc getEndLoc() const override {
285*9880d681SAndroid Build Coastguard Worker     return EndLoc;
286*9880d681SAndroid Build Coastguard Worker   }
287*9880d681SAndroid Build Coastguard Worker 
print(raw_ostream & OS) const288*9880d681SAndroid Build Coastguard Worker   void print(raw_ostream &OS) const override {
289*9880d681SAndroid Build Coastguard Worker     switch (Kind) {
290*9880d681SAndroid Build Coastguard Worker     case k_Token:     OS << "Token: " << getToken() << "\n"; break;
291*9880d681SAndroid Build Coastguard Worker     case k_Register:  OS << "Reg: #" << getReg() << "\n"; break;
292*9880d681SAndroid Build Coastguard Worker     case k_Immediate: OS << "Imm: " << getImm() << "\n"; break;
293*9880d681SAndroid Build Coastguard Worker     case k_MemoryReg: OS << "Mem: " << getMemBase() << "+"
294*9880d681SAndroid Build Coastguard Worker                          << getMemOffsetReg() << "\n"; break;
295*9880d681SAndroid Build Coastguard Worker     case k_MemoryImm: assert(getMemOff() != nullptr);
296*9880d681SAndroid Build Coastguard Worker       OS << "Mem: " << getMemBase()
297*9880d681SAndroid Build Coastguard Worker          << "+" << *getMemOff()
298*9880d681SAndroid Build Coastguard Worker          << "\n"; break;
299*9880d681SAndroid Build Coastguard Worker     }
300*9880d681SAndroid Build Coastguard Worker   }
301*9880d681SAndroid Build Coastguard Worker 
addRegOperands(MCInst & Inst,unsigned N) const302*9880d681SAndroid Build Coastguard Worker   void addRegOperands(MCInst &Inst, unsigned N) const {
303*9880d681SAndroid Build Coastguard Worker     assert(N == 1 && "Invalid number of operands!");
304*9880d681SAndroid Build Coastguard Worker     Inst.addOperand(MCOperand::createReg(getReg()));
305*9880d681SAndroid Build Coastguard Worker   }
306*9880d681SAndroid Build Coastguard Worker 
addImmOperands(MCInst & Inst,unsigned N) const307*9880d681SAndroid Build Coastguard Worker   void addImmOperands(MCInst &Inst, unsigned N) const {
308*9880d681SAndroid Build Coastguard Worker     assert(N == 1 && "Invalid number of operands!");
309*9880d681SAndroid Build Coastguard Worker     const MCExpr *Expr = getImm();
310*9880d681SAndroid Build Coastguard Worker     addExpr(Inst, Expr);
311*9880d681SAndroid Build Coastguard Worker   }
312*9880d681SAndroid Build Coastguard Worker 
addExpr(MCInst & Inst,const MCExpr * Expr) const313*9880d681SAndroid Build Coastguard Worker   void addExpr(MCInst &Inst, const MCExpr *Expr) const{
314*9880d681SAndroid Build Coastguard Worker     // Add as immediate when possible.  Null MCExpr = 0.
315*9880d681SAndroid Build Coastguard Worker     if (!Expr)
316*9880d681SAndroid Build Coastguard Worker       Inst.addOperand(MCOperand::createImm(0));
317*9880d681SAndroid Build Coastguard Worker     else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
318*9880d681SAndroid Build Coastguard Worker       Inst.addOperand(MCOperand::createImm(CE->getValue()));
319*9880d681SAndroid Build Coastguard Worker     else
320*9880d681SAndroid Build Coastguard Worker       Inst.addOperand(MCOperand::createExpr(Expr));
321*9880d681SAndroid Build Coastguard Worker   }
322*9880d681SAndroid Build Coastguard Worker 
addMEMrrOperands(MCInst & Inst,unsigned N) const323*9880d681SAndroid Build Coastguard Worker   void addMEMrrOperands(MCInst &Inst, unsigned N) const {
324*9880d681SAndroid Build Coastguard Worker     assert(N == 2 && "Invalid number of operands!");
325*9880d681SAndroid Build Coastguard Worker 
326*9880d681SAndroid Build Coastguard Worker     Inst.addOperand(MCOperand::createReg(getMemBase()));
327*9880d681SAndroid Build Coastguard Worker 
328*9880d681SAndroid Build Coastguard Worker     assert(getMemOffsetReg() != 0 && "Invalid offset");
329*9880d681SAndroid Build Coastguard Worker     Inst.addOperand(MCOperand::createReg(getMemOffsetReg()));
330*9880d681SAndroid Build Coastguard Worker   }
331*9880d681SAndroid Build Coastguard Worker 
addMEMriOperands(MCInst & Inst,unsigned N) const332*9880d681SAndroid Build Coastguard Worker   void addMEMriOperands(MCInst &Inst, unsigned N) const {
333*9880d681SAndroid Build Coastguard Worker     assert(N == 2 && "Invalid number of operands!");
334*9880d681SAndroid Build Coastguard Worker 
335*9880d681SAndroid Build Coastguard Worker     Inst.addOperand(MCOperand::createReg(getMemBase()));
336*9880d681SAndroid Build Coastguard Worker 
337*9880d681SAndroid Build Coastguard Worker     const MCExpr *Expr = getMemOff();
338*9880d681SAndroid Build Coastguard Worker     addExpr(Inst, Expr);
339*9880d681SAndroid Build Coastguard Worker   }
340*9880d681SAndroid Build Coastguard Worker 
CreateToken(StringRef Str,SMLoc S)341*9880d681SAndroid Build Coastguard Worker   static std::unique_ptr<SparcOperand> CreateToken(StringRef Str, SMLoc S) {
342*9880d681SAndroid Build Coastguard Worker     auto Op = make_unique<SparcOperand>(k_Token);
343*9880d681SAndroid Build Coastguard Worker     Op->Tok.Data = Str.data();
344*9880d681SAndroid Build Coastguard Worker     Op->Tok.Length = Str.size();
345*9880d681SAndroid Build Coastguard Worker     Op->StartLoc = S;
346*9880d681SAndroid Build Coastguard Worker     Op->EndLoc = S;
347*9880d681SAndroid Build Coastguard Worker     return Op;
348*9880d681SAndroid Build Coastguard Worker   }
349*9880d681SAndroid Build Coastguard Worker 
CreateReg(unsigned RegNum,unsigned Kind,SMLoc S,SMLoc E)350*9880d681SAndroid Build Coastguard Worker   static std::unique_ptr<SparcOperand> CreateReg(unsigned RegNum, unsigned Kind,
351*9880d681SAndroid Build Coastguard Worker                                                  SMLoc S, SMLoc E) {
352*9880d681SAndroid Build Coastguard Worker     auto Op = make_unique<SparcOperand>(k_Register);
353*9880d681SAndroid Build Coastguard Worker     Op->Reg.RegNum = RegNum;
354*9880d681SAndroid Build Coastguard Worker     Op->Reg.Kind   = (SparcOperand::RegisterKind)Kind;
355*9880d681SAndroid Build Coastguard Worker     Op->StartLoc = S;
356*9880d681SAndroid Build Coastguard Worker     Op->EndLoc = E;
357*9880d681SAndroid Build Coastguard Worker     return Op;
358*9880d681SAndroid Build Coastguard Worker   }
359*9880d681SAndroid Build Coastguard Worker 
CreateImm(const MCExpr * Val,SMLoc S,SMLoc E)360*9880d681SAndroid Build Coastguard Worker   static std::unique_ptr<SparcOperand> CreateImm(const MCExpr *Val, SMLoc S,
361*9880d681SAndroid Build Coastguard Worker                                                  SMLoc E) {
362*9880d681SAndroid Build Coastguard Worker     auto Op = make_unique<SparcOperand>(k_Immediate);
363*9880d681SAndroid Build Coastguard Worker     Op->Imm.Val = Val;
364*9880d681SAndroid Build Coastguard Worker     Op->StartLoc = S;
365*9880d681SAndroid Build Coastguard Worker     Op->EndLoc = E;
366*9880d681SAndroid Build Coastguard Worker     return Op;
367*9880d681SAndroid Build Coastguard Worker   }
368*9880d681SAndroid Build Coastguard Worker 
MorphToIntPairReg(SparcOperand & Op)369*9880d681SAndroid Build Coastguard Worker   static bool MorphToIntPairReg(SparcOperand &Op) {
370*9880d681SAndroid Build Coastguard Worker     unsigned Reg = Op.getReg();
371*9880d681SAndroid Build Coastguard Worker     assert(Op.Reg.Kind == rk_IntReg);
372*9880d681SAndroid Build Coastguard Worker     unsigned regIdx = 32;
373*9880d681SAndroid Build Coastguard Worker     if (Reg >= Sparc::G0 && Reg <= Sparc::G7)
374*9880d681SAndroid Build Coastguard Worker       regIdx = Reg - Sparc::G0;
375*9880d681SAndroid Build Coastguard Worker     else if (Reg >= Sparc::O0 && Reg <= Sparc::O7)
376*9880d681SAndroid Build Coastguard Worker       regIdx = Reg - Sparc::O0 + 8;
377*9880d681SAndroid Build Coastguard Worker     else if (Reg >= Sparc::L0 && Reg <= Sparc::L7)
378*9880d681SAndroid Build Coastguard Worker       regIdx = Reg - Sparc::L0 + 16;
379*9880d681SAndroid Build Coastguard Worker     else if (Reg >= Sparc::I0 && Reg <= Sparc::I7)
380*9880d681SAndroid Build Coastguard Worker       regIdx = Reg - Sparc::I0 + 24;
381*9880d681SAndroid Build Coastguard Worker     if (regIdx % 2 || regIdx > 31)
382*9880d681SAndroid Build Coastguard Worker       return false;
383*9880d681SAndroid Build Coastguard Worker     Op.Reg.RegNum = IntPairRegs[regIdx / 2];
384*9880d681SAndroid Build Coastguard Worker     Op.Reg.Kind = rk_IntPairReg;
385*9880d681SAndroid Build Coastguard Worker     return true;
386*9880d681SAndroid Build Coastguard Worker   }
387*9880d681SAndroid Build Coastguard Worker 
MorphToDoubleReg(SparcOperand & Op)388*9880d681SAndroid Build Coastguard Worker   static bool MorphToDoubleReg(SparcOperand &Op) {
389*9880d681SAndroid Build Coastguard Worker     unsigned Reg = Op.getReg();
390*9880d681SAndroid Build Coastguard Worker     assert(Op.Reg.Kind == rk_FloatReg);
391*9880d681SAndroid Build Coastguard Worker     unsigned regIdx = Reg - Sparc::F0;
392*9880d681SAndroid Build Coastguard Worker     if (regIdx % 2 || regIdx > 31)
393*9880d681SAndroid Build Coastguard Worker       return false;
394*9880d681SAndroid Build Coastguard Worker     Op.Reg.RegNum = DoubleRegs[regIdx / 2];
395*9880d681SAndroid Build Coastguard Worker     Op.Reg.Kind = rk_DoubleReg;
396*9880d681SAndroid Build Coastguard Worker     return true;
397*9880d681SAndroid Build Coastguard Worker   }
398*9880d681SAndroid Build Coastguard Worker 
MorphToQuadReg(SparcOperand & Op)399*9880d681SAndroid Build Coastguard Worker   static bool MorphToQuadReg(SparcOperand &Op) {
400*9880d681SAndroid Build Coastguard Worker     unsigned Reg = Op.getReg();
401*9880d681SAndroid Build Coastguard Worker     unsigned regIdx = 0;
402*9880d681SAndroid Build Coastguard Worker     switch (Op.Reg.Kind) {
403*9880d681SAndroid Build Coastguard Worker     default: llvm_unreachable("Unexpected register kind!");
404*9880d681SAndroid Build Coastguard Worker     case rk_FloatReg:
405*9880d681SAndroid Build Coastguard Worker       regIdx = Reg - Sparc::F0;
406*9880d681SAndroid Build Coastguard Worker       if (regIdx % 4 || regIdx > 31)
407*9880d681SAndroid Build Coastguard Worker         return false;
408*9880d681SAndroid Build Coastguard Worker       Reg = QuadFPRegs[regIdx / 4];
409*9880d681SAndroid Build Coastguard Worker       break;
410*9880d681SAndroid Build Coastguard Worker     case rk_DoubleReg:
411*9880d681SAndroid Build Coastguard Worker       regIdx =  Reg - Sparc::D0;
412*9880d681SAndroid Build Coastguard Worker       if (regIdx % 2 || regIdx > 31)
413*9880d681SAndroid Build Coastguard Worker         return false;
414*9880d681SAndroid Build Coastguard Worker       Reg = QuadFPRegs[regIdx / 2];
415*9880d681SAndroid Build Coastguard Worker       break;
416*9880d681SAndroid Build Coastguard Worker     }
417*9880d681SAndroid Build Coastguard Worker     Op.Reg.RegNum = Reg;
418*9880d681SAndroid Build Coastguard Worker     Op.Reg.Kind = rk_QuadReg;
419*9880d681SAndroid Build Coastguard Worker     return true;
420*9880d681SAndroid Build Coastguard Worker   }
421*9880d681SAndroid Build Coastguard Worker 
MorphToCoprocPairReg(SparcOperand & Op)422*9880d681SAndroid Build Coastguard Worker   static bool MorphToCoprocPairReg(SparcOperand &Op) {
423*9880d681SAndroid Build Coastguard Worker     unsigned Reg = Op.getReg();
424*9880d681SAndroid Build Coastguard Worker     assert(Op.Reg.Kind == rk_CoprocReg);
425*9880d681SAndroid Build Coastguard Worker     unsigned regIdx = 32;
426*9880d681SAndroid Build Coastguard Worker     if (Reg >= Sparc::C0 && Reg <= Sparc::C31)
427*9880d681SAndroid Build Coastguard Worker       regIdx = Reg - Sparc::C0;
428*9880d681SAndroid Build Coastguard Worker     if (regIdx % 2 || regIdx > 31)
429*9880d681SAndroid Build Coastguard Worker       return false;
430*9880d681SAndroid Build Coastguard Worker     Op.Reg.RegNum = CoprocPairRegs[regIdx / 2];
431*9880d681SAndroid Build Coastguard Worker     Op.Reg.Kind = rk_CoprocPairReg;
432*9880d681SAndroid Build Coastguard Worker     return true;
433*9880d681SAndroid Build Coastguard Worker   }
434*9880d681SAndroid Build Coastguard Worker 
435*9880d681SAndroid Build Coastguard Worker   static std::unique_ptr<SparcOperand>
MorphToMEMrr(unsigned Base,std::unique_ptr<SparcOperand> Op)436*9880d681SAndroid Build Coastguard Worker   MorphToMEMrr(unsigned Base, std::unique_ptr<SparcOperand> Op) {
437*9880d681SAndroid Build Coastguard Worker     unsigned offsetReg = Op->getReg();
438*9880d681SAndroid Build Coastguard Worker     Op->Kind = k_MemoryReg;
439*9880d681SAndroid Build Coastguard Worker     Op->Mem.Base = Base;
440*9880d681SAndroid Build Coastguard Worker     Op->Mem.OffsetReg = offsetReg;
441*9880d681SAndroid Build Coastguard Worker     Op->Mem.Off = nullptr;
442*9880d681SAndroid Build Coastguard Worker     return Op;
443*9880d681SAndroid Build Coastguard Worker   }
444*9880d681SAndroid Build Coastguard Worker 
445*9880d681SAndroid Build Coastguard Worker   static std::unique_ptr<SparcOperand>
CreateMEMr(unsigned Base,SMLoc S,SMLoc E)446*9880d681SAndroid Build Coastguard Worker   CreateMEMr(unsigned Base, SMLoc S, SMLoc E) {
447*9880d681SAndroid Build Coastguard Worker     auto Op = make_unique<SparcOperand>(k_MemoryReg);
448*9880d681SAndroid Build Coastguard Worker     Op->Mem.Base = Base;
449*9880d681SAndroid Build Coastguard Worker     Op->Mem.OffsetReg = Sparc::G0;  // always 0
450*9880d681SAndroid Build Coastguard Worker     Op->Mem.Off = nullptr;
451*9880d681SAndroid Build Coastguard Worker     Op->StartLoc = S;
452*9880d681SAndroid Build Coastguard Worker     Op->EndLoc = E;
453*9880d681SAndroid Build Coastguard Worker     return Op;
454*9880d681SAndroid Build Coastguard Worker   }
455*9880d681SAndroid Build Coastguard Worker 
456*9880d681SAndroid Build Coastguard Worker   static std::unique_ptr<SparcOperand>
MorphToMEMri(unsigned Base,std::unique_ptr<SparcOperand> Op)457*9880d681SAndroid Build Coastguard Worker   MorphToMEMri(unsigned Base, std::unique_ptr<SparcOperand> Op) {
458*9880d681SAndroid Build Coastguard Worker     const MCExpr *Imm  = Op->getImm();
459*9880d681SAndroid Build Coastguard Worker     Op->Kind = k_MemoryImm;
460*9880d681SAndroid Build Coastguard Worker     Op->Mem.Base = Base;
461*9880d681SAndroid Build Coastguard Worker     Op->Mem.OffsetReg = 0;
462*9880d681SAndroid Build Coastguard Worker     Op->Mem.Off = Imm;
463*9880d681SAndroid Build Coastguard Worker     return Op;
464*9880d681SAndroid Build Coastguard Worker   }
465*9880d681SAndroid Build Coastguard Worker };
466*9880d681SAndroid Build Coastguard Worker 
467*9880d681SAndroid Build Coastguard Worker } // end namespace
468*9880d681SAndroid Build Coastguard Worker 
expandSET(MCInst & Inst,SMLoc IDLoc,SmallVectorImpl<MCInst> & Instructions)469*9880d681SAndroid Build Coastguard Worker void SparcAsmParser::expandSET(MCInst &Inst, SMLoc IDLoc,
470*9880d681SAndroid Build Coastguard Worker                                SmallVectorImpl<MCInst> &Instructions) {
471*9880d681SAndroid Build Coastguard Worker   MCOperand MCRegOp = Inst.getOperand(0);
472*9880d681SAndroid Build Coastguard Worker   MCOperand MCValOp = Inst.getOperand(1);
473*9880d681SAndroid Build Coastguard Worker   assert(MCRegOp.isReg());
474*9880d681SAndroid Build Coastguard Worker   assert(MCValOp.isImm() || MCValOp.isExpr());
475*9880d681SAndroid Build Coastguard Worker 
476*9880d681SAndroid Build Coastguard Worker   // the imm operand can be either an expression or an immediate.
477*9880d681SAndroid Build Coastguard Worker   bool IsImm = Inst.getOperand(1).isImm();
478*9880d681SAndroid Build Coastguard Worker   int64_t RawImmValue = IsImm ? MCValOp.getImm() : 0;
479*9880d681SAndroid Build Coastguard Worker 
480*9880d681SAndroid Build Coastguard Worker   // Allow either a signed or unsigned 32-bit immediate.
481*9880d681SAndroid Build Coastguard Worker   if (RawImmValue < -2147483648LL || RawImmValue > 4294967295LL) {
482*9880d681SAndroid Build Coastguard Worker     Error(IDLoc, "set: argument must be between -2147483648 and 4294967295");
483*9880d681SAndroid Build Coastguard Worker     return;
484*9880d681SAndroid Build Coastguard Worker   }
485*9880d681SAndroid Build Coastguard Worker 
486*9880d681SAndroid Build Coastguard Worker   // If the value was expressed as a large unsigned number, that's ok.
487*9880d681SAndroid Build Coastguard Worker   // We want to see if it "looks like" a small signed number.
488*9880d681SAndroid Build Coastguard Worker   int32_t ImmValue = RawImmValue;
489*9880d681SAndroid Build Coastguard Worker   // For 'set' you can't use 'or' with a negative operand on V9 because
490*9880d681SAndroid Build Coastguard Worker   // that would splat the sign bit across the upper half of the destination
491*9880d681SAndroid Build Coastguard Worker   // register, whereas 'set' is defined to zero the high 32 bits.
492*9880d681SAndroid Build Coastguard Worker   bool IsEffectivelyImm13 =
493*9880d681SAndroid Build Coastguard Worker       IsImm && ((is64Bit() ? 0 : -4096) <= ImmValue && ImmValue < 4096);
494*9880d681SAndroid Build Coastguard Worker   const MCExpr *ValExpr;
495*9880d681SAndroid Build Coastguard Worker   if (IsImm)
496*9880d681SAndroid Build Coastguard Worker     ValExpr = MCConstantExpr::create(ImmValue, getContext());
497*9880d681SAndroid Build Coastguard Worker   else
498*9880d681SAndroid Build Coastguard Worker     ValExpr = MCValOp.getExpr();
499*9880d681SAndroid Build Coastguard Worker 
500*9880d681SAndroid Build Coastguard Worker   MCOperand PrevReg = MCOperand::createReg(Sparc::G0);
501*9880d681SAndroid Build Coastguard Worker 
502*9880d681SAndroid Build Coastguard Worker   // If not just a signed imm13 value, then either we use a 'sethi' with a
503*9880d681SAndroid Build Coastguard Worker   // following 'or', or a 'sethi' by itself if there are no more 1 bits.
504*9880d681SAndroid Build Coastguard Worker   // In either case, start with the 'sethi'.
505*9880d681SAndroid Build Coastguard Worker   if (!IsEffectivelyImm13) {
506*9880d681SAndroid Build Coastguard Worker     MCInst TmpInst;
507*9880d681SAndroid Build Coastguard Worker     const MCExpr *Expr = adjustPICRelocation(SparcMCExpr::VK_Sparc_HI, ValExpr);
508*9880d681SAndroid Build Coastguard Worker     TmpInst.setLoc(IDLoc);
509*9880d681SAndroid Build Coastguard Worker     TmpInst.setOpcode(SP::SETHIi);
510*9880d681SAndroid Build Coastguard Worker     TmpInst.addOperand(MCRegOp);
511*9880d681SAndroid Build Coastguard Worker     TmpInst.addOperand(MCOperand::createExpr(Expr));
512*9880d681SAndroid Build Coastguard Worker     Instructions.push_back(TmpInst);
513*9880d681SAndroid Build Coastguard Worker     PrevReg = MCRegOp;
514*9880d681SAndroid Build Coastguard Worker   }
515*9880d681SAndroid Build Coastguard Worker 
516*9880d681SAndroid Build Coastguard Worker   // The low bits require touching in 3 cases:
517*9880d681SAndroid Build Coastguard Worker   // * A non-immediate value will always require both instructions.
518*9880d681SAndroid Build Coastguard Worker   // * An effectively imm13 value needs only an 'or' instruction.
519*9880d681SAndroid Build Coastguard Worker   // * Otherwise, an immediate that is not effectively imm13 requires the
520*9880d681SAndroid Build Coastguard Worker   //   'or' only if bits remain after clearing the 22 bits that 'sethi' set.
521*9880d681SAndroid Build Coastguard Worker   // If the low bits are known zeros, there's nothing to do.
522*9880d681SAndroid Build Coastguard Worker   // In the second case, and only in that case, must we NOT clear
523*9880d681SAndroid Build Coastguard Worker   // bits of the immediate value via the %lo() assembler function.
524*9880d681SAndroid Build Coastguard Worker   // Note also, the 'or' instruction doesn't mind a large value in the case
525*9880d681SAndroid Build Coastguard Worker   // where the operand to 'set' was 0xFFFFFzzz - it does exactly what you mean.
526*9880d681SAndroid Build Coastguard Worker   if (!IsImm || IsEffectivelyImm13 || (ImmValue & 0x3ff)) {
527*9880d681SAndroid Build Coastguard Worker     MCInst TmpInst;
528*9880d681SAndroid Build Coastguard Worker     const MCExpr *Expr;
529*9880d681SAndroid Build Coastguard Worker     if (IsEffectivelyImm13)
530*9880d681SAndroid Build Coastguard Worker       Expr = ValExpr;
531*9880d681SAndroid Build Coastguard Worker     else
532*9880d681SAndroid Build Coastguard Worker       Expr = adjustPICRelocation(SparcMCExpr::VK_Sparc_LO, ValExpr);
533*9880d681SAndroid Build Coastguard Worker     TmpInst.setLoc(IDLoc);
534*9880d681SAndroid Build Coastguard Worker     TmpInst.setOpcode(SP::ORri);
535*9880d681SAndroid Build Coastguard Worker     TmpInst.addOperand(MCRegOp);
536*9880d681SAndroid Build Coastguard Worker     TmpInst.addOperand(PrevReg);
537*9880d681SAndroid Build Coastguard Worker     TmpInst.addOperand(MCOperand::createExpr(Expr));
538*9880d681SAndroid Build Coastguard Worker     Instructions.push_back(TmpInst);
539*9880d681SAndroid Build Coastguard Worker   }
540*9880d681SAndroid Build Coastguard Worker }
541*9880d681SAndroid Build Coastguard Worker 
MatchAndEmitInstruction(SMLoc IDLoc,unsigned & Opcode,OperandVector & Operands,MCStreamer & Out,uint64_t & ErrorInfo,bool MatchingInlineAsm)542*9880d681SAndroid Build Coastguard Worker bool SparcAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
543*9880d681SAndroid Build Coastguard Worker                                              OperandVector &Operands,
544*9880d681SAndroid Build Coastguard Worker                                              MCStreamer &Out,
545*9880d681SAndroid Build Coastguard Worker                                              uint64_t &ErrorInfo,
546*9880d681SAndroid Build Coastguard Worker                                              bool MatchingInlineAsm) {
547*9880d681SAndroid Build Coastguard Worker   MCInst Inst;
548*9880d681SAndroid Build Coastguard Worker   SmallVector<MCInst, 8> Instructions;
549*9880d681SAndroid Build Coastguard Worker   unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
550*9880d681SAndroid Build Coastguard Worker                                               MatchingInlineAsm);
551*9880d681SAndroid Build Coastguard Worker   switch (MatchResult) {
552*9880d681SAndroid Build Coastguard Worker   case Match_Success: {
553*9880d681SAndroid Build Coastguard Worker     switch (Inst.getOpcode()) {
554*9880d681SAndroid Build Coastguard Worker     default:
555*9880d681SAndroid Build Coastguard Worker       Inst.setLoc(IDLoc);
556*9880d681SAndroid Build Coastguard Worker       Instructions.push_back(Inst);
557*9880d681SAndroid Build Coastguard Worker       break;
558*9880d681SAndroid Build Coastguard Worker     case SP::SET:
559*9880d681SAndroid Build Coastguard Worker       expandSET(Inst, IDLoc, Instructions);
560*9880d681SAndroid Build Coastguard Worker       break;
561*9880d681SAndroid Build Coastguard Worker     }
562*9880d681SAndroid Build Coastguard Worker 
563*9880d681SAndroid Build Coastguard Worker     for (const MCInst &I : Instructions) {
564*9880d681SAndroid Build Coastguard Worker       Out.EmitInstruction(I, getSTI());
565*9880d681SAndroid Build Coastguard Worker     }
566*9880d681SAndroid Build Coastguard Worker     return false;
567*9880d681SAndroid Build Coastguard Worker   }
568*9880d681SAndroid Build Coastguard Worker 
569*9880d681SAndroid Build Coastguard Worker   case Match_MissingFeature:
570*9880d681SAndroid Build Coastguard Worker     return Error(IDLoc,
571*9880d681SAndroid Build Coastguard Worker                  "instruction requires a CPU feature not currently enabled");
572*9880d681SAndroid Build Coastguard Worker 
573*9880d681SAndroid Build Coastguard Worker   case Match_InvalidOperand: {
574*9880d681SAndroid Build Coastguard Worker     SMLoc ErrorLoc = IDLoc;
575*9880d681SAndroid Build Coastguard Worker     if (ErrorInfo != ~0ULL) {
576*9880d681SAndroid Build Coastguard Worker       if (ErrorInfo >= Operands.size())
577*9880d681SAndroid Build Coastguard Worker         return Error(IDLoc, "too few operands for instruction");
578*9880d681SAndroid Build Coastguard Worker 
579*9880d681SAndroid Build Coastguard Worker       ErrorLoc = ((SparcOperand &)*Operands[ErrorInfo]).getStartLoc();
580*9880d681SAndroid Build Coastguard Worker       if (ErrorLoc == SMLoc())
581*9880d681SAndroid Build Coastguard Worker         ErrorLoc = IDLoc;
582*9880d681SAndroid Build Coastguard Worker     }
583*9880d681SAndroid Build Coastguard Worker 
584*9880d681SAndroid Build Coastguard Worker     return Error(ErrorLoc, "invalid operand for instruction");
585*9880d681SAndroid Build Coastguard Worker   }
586*9880d681SAndroid Build Coastguard Worker   case Match_MnemonicFail:
587*9880d681SAndroid Build Coastguard Worker     return Error(IDLoc, "invalid instruction mnemonic");
588*9880d681SAndroid Build Coastguard Worker   }
589*9880d681SAndroid Build Coastguard Worker   llvm_unreachable("Implement any new match types added!");
590*9880d681SAndroid Build Coastguard Worker }
591*9880d681SAndroid Build Coastguard Worker 
592*9880d681SAndroid Build Coastguard Worker bool SparcAsmParser::
ParseRegister(unsigned & RegNo,SMLoc & StartLoc,SMLoc & EndLoc)593*9880d681SAndroid Build Coastguard Worker ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc)
594*9880d681SAndroid Build Coastguard Worker {
595*9880d681SAndroid Build Coastguard Worker   const AsmToken &Tok = Parser.getTok();
596*9880d681SAndroid Build Coastguard Worker   StartLoc = Tok.getLoc();
597*9880d681SAndroid Build Coastguard Worker   EndLoc = Tok.getEndLoc();
598*9880d681SAndroid Build Coastguard Worker   RegNo = 0;
599*9880d681SAndroid Build Coastguard Worker   if (getLexer().getKind() != AsmToken::Percent)
600*9880d681SAndroid Build Coastguard Worker     return false;
601*9880d681SAndroid Build Coastguard Worker   Parser.Lex();
602*9880d681SAndroid Build Coastguard Worker   unsigned regKind = SparcOperand::rk_None;
603*9880d681SAndroid Build Coastguard Worker   if (matchRegisterName(Tok, RegNo, regKind)) {
604*9880d681SAndroid Build Coastguard Worker     Parser.Lex();
605*9880d681SAndroid Build Coastguard Worker     return false;
606*9880d681SAndroid Build Coastguard Worker   }
607*9880d681SAndroid Build Coastguard Worker 
608*9880d681SAndroid Build Coastguard Worker   return Error(StartLoc, "invalid register name");
609*9880d681SAndroid Build Coastguard Worker }
610*9880d681SAndroid Build Coastguard Worker 
611*9880d681SAndroid Build Coastguard Worker static void applyMnemonicAliases(StringRef &Mnemonic, uint64_t Features,
612*9880d681SAndroid Build Coastguard Worker                                  unsigned VariantID);
613*9880d681SAndroid Build Coastguard Worker 
ParseInstruction(ParseInstructionInfo & Info,StringRef Name,SMLoc NameLoc,OperandVector & Operands)614*9880d681SAndroid Build Coastguard Worker bool SparcAsmParser::ParseInstruction(ParseInstructionInfo &Info,
615*9880d681SAndroid Build Coastguard Worker                                       StringRef Name, SMLoc NameLoc,
616*9880d681SAndroid Build Coastguard Worker                                       OperandVector &Operands) {
617*9880d681SAndroid Build Coastguard Worker 
618*9880d681SAndroid Build Coastguard Worker   // First operand in MCInst is instruction mnemonic.
619*9880d681SAndroid Build Coastguard Worker   Operands.push_back(SparcOperand::CreateToken(Name, NameLoc));
620*9880d681SAndroid Build Coastguard Worker 
621*9880d681SAndroid Build Coastguard Worker   // apply mnemonic aliases, if any, so that we can parse operands correctly.
622*9880d681SAndroid Build Coastguard Worker   applyMnemonicAliases(Name, getAvailableFeatures(), 0);
623*9880d681SAndroid Build Coastguard Worker 
624*9880d681SAndroid Build Coastguard Worker   if (getLexer().isNot(AsmToken::EndOfStatement)) {
625*9880d681SAndroid Build Coastguard Worker     // Read the first operand.
626*9880d681SAndroid Build Coastguard Worker     if (getLexer().is(AsmToken::Comma)) {
627*9880d681SAndroid Build Coastguard Worker       if (parseBranchModifiers(Operands) != MatchOperand_Success) {
628*9880d681SAndroid Build Coastguard Worker         SMLoc Loc = getLexer().getLoc();
629*9880d681SAndroid Build Coastguard Worker         Parser.eatToEndOfStatement();
630*9880d681SAndroid Build Coastguard Worker         return Error(Loc, "unexpected token");
631*9880d681SAndroid Build Coastguard Worker       }
632*9880d681SAndroid Build Coastguard Worker     }
633*9880d681SAndroid Build Coastguard Worker     if (parseOperand(Operands, Name) != MatchOperand_Success) {
634*9880d681SAndroid Build Coastguard Worker       SMLoc Loc = getLexer().getLoc();
635*9880d681SAndroid Build Coastguard Worker       Parser.eatToEndOfStatement();
636*9880d681SAndroid Build Coastguard Worker       return Error(Loc, "unexpected token");
637*9880d681SAndroid Build Coastguard Worker     }
638*9880d681SAndroid Build Coastguard Worker 
639*9880d681SAndroid Build Coastguard Worker     while (getLexer().is(AsmToken::Comma) || getLexer().is(AsmToken::Plus)) {
640*9880d681SAndroid Build Coastguard Worker       if (getLexer().is(AsmToken::Plus)) {
641*9880d681SAndroid Build Coastguard Worker       // Plus tokens are significant in software_traps (p83, sparcv8.pdf). We must capture them.
642*9880d681SAndroid Build Coastguard Worker         Operands.push_back(SparcOperand::CreateToken("+", Parser.getTok().getLoc()));
643*9880d681SAndroid Build Coastguard Worker       }
644*9880d681SAndroid Build Coastguard Worker       Parser.Lex(); // Eat the comma or plus.
645*9880d681SAndroid Build Coastguard Worker       // Parse and remember the operand.
646*9880d681SAndroid Build Coastguard Worker       if (parseOperand(Operands, Name) != MatchOperand_Success) {
647*9880d681SAndroid Build Coastguard Worker         SMLoc Loc = getLexer().getLoc();
648*9880d681SAndroid Build Coastguard Worker         Parser.eatToEndOfStatement();
649*9880d681SAndroid Build Coastguard Worker         return Error(Loc, "unexpected token");
650*9880d681SAndroid Build Coastguard Worker       }
651*9880d681SAndroid Build Coastguard Worker     }
652*9880d681SAndroid Build Coastguard Worker   }
653*9880d681SAndroid Build Coastguard Worker   if (getLexer().isNot(AsmToken::EndOfStatement)) {
654*9880d681SAndroid Build Coastguard Worker     SMLoc Loc = getLexer().getLoc();
655*9880d681SAndroid Build Coastguard Worker     Parser.eatToEndOfStatement();
656*9880d681SAndroid Build Coastguard Worker     return Error(Loc, "unexpected token");
657*9880d681SAndroid Build Coastguard Worker   }
658*9880d681SAndroid Build Coastguard Worker   Parser.Lex(); // Consume the EndOfStatement.
659*9880d681SAndroid Build Coastguard Worker   return false;
660*9880d681SAndroid Build Coastguard Worker }
661*9880d681SAndroid Build Coastguard Worker 
662*9880d681SAndroid Build Coastguard Worker bool SparcAsmParser::
ParseDirective(AsmToken DirectiveID)663*9880d681SAndroid Build Coastguard Worker ParseDirective(AsmToken DirectiveID)
664*9880d681SAndroid Build Coastguard Worker {
665*9880d681SAndroid Build Coastguard Worker   StringRef IDVal = DirectiveID.getString();
666*9880d681SAndroid Build Coastguard Worker 
667*9880d681SAndroid Build Coastguard Worker   if (IDVal == ".byte")
668*9880d681SAndroid Build Coastguard Worker     return parseDirectiveWord(1, DirectiveID.getLoc());
669*9880d681SAndroid Build Coastguard Worker 
670*9880d681SAndroid Build Coastguard Worker   if (IDVal == ".half")
671*9880d681SAndroid Build Coastguard Worker     return parseDirectiveWord(2, DirectiveID.getLoc());
672*9880d681SAndroid Build Coastguard Worker 
673*9880d681SAndroid Build Coastguard Worker   if (IDVal == ".word")
674*9880d681SAndroid Build Coastguard Worker     return parseDirectiveWord(4, DirectiveID.getLoc());
675*9880d681SAndroid Build Coastguard Worker 
676*9880d681SAndroid Build Coastguard Worker   if (IDVal == ".nword")
677*9880d681SAndroid Build Coastguard Worker     return parseDirectiveWord(is64Bit() ? 8 : 4, DirectiveID.getLoc());
678*9880d681SAndroid Build Coastguard Worker 
679*9880d681SAndroid Build Coastguard Worker   if (is64Bit() && IDVal == ".xword")
680*9880d681SAndroid Build Coastguard Worker     return parseDirectiveWord(8, DirectiveID.getLoc());
681*9880d681SAndroid Build Coastguard Worker 
682*9880d681SAndroid Build Coastguard Worker   if (IDVal == ".register") {
683*9880d681SAndroid Build Coastguard Worker     // For now, ignore .register directive.
684*9880d681SAndroid Build Coastguard Worker     Parser.eatToEndOfStatement();
685*9880d681SAndroid Build Coastguard Worker     return false;
686*9880d681SAndroid Build Coastguard Worker   }
687*9880d681SAndroid Build Coastguard Worker   if (IDVal == ".proc") {
688*9880d681SAndroid Build Coastguard Worker     // For compatibility, ignore this directive.
689*9880d681SAndroid Build Coastguard Worker     // (It's supposed to be an "optimization" in the Sun assembler)
690*9880d681SAndroid Build Coastguard Worker     Parser.eatToEndOfStatement();
691*9880d681SAndroid Build Coastguard Worker     return false;
692*9880d681SAndroid Build Coastguard Worker   }
693*9880d681SAndroid Build Coastguard Worker 
694*9880d681SAndroid Build Coastguard Worker   // Let the MC layer to handle other directives.
695*9880d681SAndroid Build Coastguard Worker   return true;
696*9880d681SAndroid Build Coastguard Worker }
697*9880d681SAndroid Build Coastguard Worker 
parseDirectiveWord(unsigned Size,SMLoc L)698*9880d681SAndroid Build Coastguard Worker bool SparcAsmParser:: parseDirectiveWord(unsigned Size, SMLoc L) {
699*9880d681SAndroid Build Coastguard Worker   if (getLexer().isNot(AsmToken::EndOfStatement)) {
700*9880d681SAndroid Build Coastguard Worker     for (;;) {
701*9880d681SAndroid Build Coastguard Worker       const MCExpr *Value;
702*9880d681SAndroid Build Coastguard Worker       if (getParser().parseExpression(Value))
703*9880d681SAndroid Build Coastguard Worker         return true;
704*9880d681SAndroid Build Coastguard Worker 
705*9880d681SAndroid Build Coastguard Worker       getParser().getStreamer().EmitValue(Value, Size);
706*9880d681SAndroid Build Coastguard Worker 
707*9880d681SAndroid Build Coastguard Worker       if (getLexer().is(AsmToken::EndOfStatement))
708*9880d681SAndroid Build Coastguard Worker         break;
709*9880d681SAndroid Build Coastguard Worker 
710*9880d681SAndroid Build Coastguard Worker       // FIXME: Improve diagnostic.
711*9880d681SAndroid Build Coastguard Worker       if (getLexer().isNot(AsmToken::Comma))
712*9880d681SAndroid Build Coastguard Worker         return Error(L, "unexpected token in directive");
713*9880d681SAndroid Build Coastguard Worker       Parser.Lex();
714*9880d681SAndroid Build Coastguard Worker     }
715*9880d681SAndroid Build Coastguard Worker   }
716*9880d681SAndroid Build Coastguard Worker   Parser.Lex();
717*9880d681SAndroid Build Coastguard Worker   return false;
718*9880d681SAndroid Build Coastguard Worker }
719*9880d681SAndroid Build Coastguard Worker 
720*9880d681SAndroid Build Coastguard Worker SparcAsmParser::OperandMatchResultTy
parseMEMOperand(OperandVector & Operands)721*9880d681SAndroid Build Coastguard Worker SparcAsmParser::parseMEMOperand(OperandVector &Operands) {
722*9880d681SAndroid Build Coastguard Worker 
723*9880d681SAndroid Build Coastguard Worker   SMLoc S, E;
724*9880d681SAndroid Build Coastguard Worker   unsigned BaseReg = 0;
725*9880d681SAndroid Build Coastguard Worker 
726*9880d681SAndroid Build Coastguard Worker   if (ParseRegister(BaseReg, S, E)) {
727*9880d681SAndroid Build Coastguard Worker     return MatchOperand_NoMatch;
728*9880d681SAndroid Build Coastguard Worker   }
729*9880d681SAndroid Build Coastguard Worker 
730*9880d681SAndroid Build Coastguard Worker   switch (getLexer().getKind()) {
731*9880d681SAndroid Build Coastguard Worker   default: return MatchOperand_NoMatch;
732*9880d681SAndroid Build Coastguard Worker 
733*9880d681SAndroid Build Coastguard Worker   case AsmToken::Comma:
734*9880d681SAndroid Build Coastguard Worker   case AsmToken::RBrac:
735*9880d681SAndroid Build Coastguard Worker   case AsmToken::EndOfStatement:
736*9880d681SAndroid Build Coastguard Worker     Operands.push_back(SparcOperand::CreateMEMr(BaseReg, S, E));
737*9880d681SAndroid Build Coastguard Worker     return MatchOperand_Success;
738*9880d681SAndroid Build Coastguard Worker 
739*9880d681SAndroid Build Coastguard Worker   case AsmToken:: Plus:
740*9880d681SAndroid Build Coastguard Worker     Parser.Lex(); // Eat the '+'
741*9880d681SAndroid Build Coastguard Worker     break;
742*9880d681SAndroid Build Coastguard Worker   case AsmToken::Minus:
743*9880d681SAndroid Build Coastguard Worker     break;
744*9880d681SAndroid Build Coastguard Worker   }
745*9880d681SAndroid Build Coastguard Worker 
746*9880d681SAndroid Build Coastguard Worker   std::unique_ptr<SparcOperand> Offset;
747*9880d681SAndroid Build Coastguard Worker   OperandMatchResultTy ResTy = parseSparcAsmOperand(Offset);
748*9880d681SAndroid Build Coastguard Worker   if (ResTy != MatchOperand_Success || !Offset)
749*9880d681SAndroid Build Coastguard Worker     return MatchOperand_NoMatch;
750*9880d681SAndroid Build Coastguard Worker 
751*9880d681SAndroid Build Coastguard Worker   Operands.push_back(
752*9880d681SAndroid Build Coastguard Worker       Offset->isImm() ? SparcOperand::MorphToMEMri(BaseReg, std::move(Offset))
753*9880d681SAndroid Build Coastguard Worker                       : SparcOperand::MorphToMEMrr(BaseReg, std::move(Offset)));
754*9880d681SAndroid Build Coastguard Worker 
755*9880d681SAndroid Build Coastguard Worker   return MatchOperand_Success;
756*9880d681SAndroid Build Coastguard Worker }
757*9880d681SAndroid Build Coastguard Worker 
758*9880d681SAndroid Build Coastguard Worker SparcAsmParser::OperandMatchResultTy
parseOperand(OperandVector & Operands,StringRef Mnemonic)759*9880d681SAndroid Build Coastguard Worker SparcAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
760*9880d681SAndroid Build Coastguard Worker 
761*9880d681SAndroid Build Coastguard Worker   OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
762*9880d681SAndroid Build Coastguard Worker 
763*9880d681SAndroid Build Coastguard Worker   // If there wasn't a custom match, try the generic matcher below. Otherwise,
764*9880d681SAndroid Build Coastguard Worker   // there was a match, but an error occurred, in which case, just return that
765*9880d681SAndroid Build Coastguard Worker   // the operand parsing failed.
766*9880d681SAndroid Build Coastguard Worker   if (ResTy == MatchOperand_Success || ResTy == MatchOperand_ParseFail)
767*9880d681SAndroid Build Coastguard Worker     return ResTy;
768*9880d681SAndroid Build Coastguard Worker 
769*9880d681SAndroid Build Coastguard Worker   if (getLexer().is(AsmToken::LBrac)) {
770*9880d681SAndroid Build Coastguard Worker     // Memory operand
771*9880d681SAndroid Build Coastguard Worker     Operands.push_back(SparcOperand::CreateToken("[",
772*9880d681SAndroid Build Coastguard Worker                                                  Parser.getTok().getLoc()));
773*9880d681SAndroid Build Coastguard Worker     Parser.Lex(); // Eat the [
774*9880d681SAndroid Build Coastguard Worker 
775*9880d681SAndroid Build Coastguard Worker     if (Mnemonic == "cas" || Mnemonic == "casx" || Mnemonic == "casa") {
776*9880d681SAndroid Build Coastguard Worker       SMLoc S = Parser.getTok().getLoc();
777*9880d681SAndroid Build Coastguard Worker       if (getLexer().getKind() != AsmToken::Percent)
778*9880d681SAndroid Build Coastguard Worker         return MatchOperand_NoMatch;
779*9880d681SAndroid Build Coastguard Worker       Parser.Lex(); // eat %
780*9880d681SAndroid Build Coastguard Worker 
781*9880d681SAndroid Build Coastguard Worker       unsigned RegNo, RegKind;
782*9880d681SAndroid Build Coastguard Worker       if (!matchRegisterName(Parser.getTok(), RegNo, RegKind))
783*9880d681SAndroid Build Coastguard Worker         return MatchOperand_NoMatch;
784*9880d681SAndroid Build Coastguard Worker 
785*9880d681SAndroid Build Coastguard Worker       Parser.Lex(); // Eat the identifier token.
786*9880d681SAndroid Build Coastguard Worker       SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer()-1);
787*9880d681SAndroid Build Coastguard Worker       Operands.push_back(SparcOperand::CreateReg(RegNo, RegKind, S, E));
788*9880d681SAndroid Build Coastguard Worker       ResTy = MatchOperand_Success;
789*9880d681SAndroid Build Coastguard Worker     } else {
790*9880d681SAndroid Build Coastguard Worker       ResTy = parseMEMOperand(Operands);
791*9880d681SAndroid Build Coastguard Worker     }
792*9880d681SAndroid Build Coastguard Worker 
793*9880d681SAndroid Build Coastguard Worker     if (ResTy != MatchOperand_Success)
794*9880d681SAndroid Build Coastguard Worker       return ResTy;
795*9880d681SAndroid Build Coastguard Worker 
796*9880d681SAndroid Build Coastguard Worker     if (!getLexer().is(AsmToken::RBrac))
797*9880d681SAndroid Build Coastguard Worker       return MatchOperand_ParseFail;
798*9880d681SAndroid Build Coastguard Worker 
799*9880d681SAndroid Build Coastguard Worker     Operands.push_back(SparcOperand::CreateToken("]",
800*9880d681SAndroid Build Coastguard Worker                                                  Parser.getTok().getLoc()));
801*9880d681SAndroid Build Coastguard Worker     Parser.Lex(); // Eat the ]
802*9880d681SAndroid Build Coastguard Worker 
803*9880d681SAndroid Build Coastguard Worker     // Parse an optional address-space identifier after the address.
804*9880d681SAndroid Build Coastguard Worker     if (getLexer().is(AsmToken::Integer)) {
805*9880d681SAndroid Build Coastguard Worker       std::unique_ptr<SparcOperand> Op;
806*9880d681SAndroid Build Coastguard Worker       ResTy = parseSparcAsmOperand(Op, false);
807*9880d681SAndroid Build Coastguard Worker       if (ResTy != MatchOperand_Success || !Op)
808*9880d681SAndroid Build Coastguard Worker         return MatchOperand_ParseFail;
809*9880d681SAndroid Build Coastguard Worker       Operands.push_back(std::move(Op));
810*9880d681SAndroid Build Coastguard Worker     }
811*9880d681SAndroid Build Coastguard Worker     return MatchOperand_Success;
812*9880d681SAndroid Build Coastguard Worker   }
813*9880d681SAndroid Build Coastguard Worker 
814*9880d681SAndroid Build Coastguard Worker   std::unique_ptr<SparcOperand> Op;
815*9880d681SAndroid Build Coastguard Worker 
816*9880d681SAndroid Build Coastguard Worker   ResTy = parseSparcAsmOperand(Op, (Mnemonic == "call"));
817*9880d681SAndroid Build Coastguard Worker   if (ResTy != MatchOperand_Success || !Op)
818*9880d681SAndroid Build Coastguard Worker     return MatchOperand_ParseFail;
819*9880d681SAndroid Build Coastguard Worker 
820*9880d681SAndroid Build Coastguard Worker   // Push the parsed operand into the list of operands
821*9880d681SAndroid Build Coastguard Worker   Operands.push_back(std::move(Op));
822*9880d681SAndroid Build Coastguard Worker 
823*9880d681SAndroid Build Coastguard Worker   return MatchOperand_Success;
824*9880d681SAndroid Build Coastguard Worker }
825*9880d681SAndroid Build Coastguard Worker 
826*9880d681SAndroid Build Coastguard Worker SparcAsmParser::OperandMatchResultTy
parseSparcAsmOperand(std::unique_ptr<SparcOperand> & Op,bool isCall)827*9880d681SAndroid Build Coastguard Worker SparcAsmParser::parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Op,
828*9880d681SAndroid Build Coastguard Worker                                      bool isCall) {
829*9880d681SAndroid Build Coastguard Worker 
830*9880d681SAndroid Build Coastguard Worker   SMLoc S = Parser.getTok().getLoc();
831*9880d681SAndroid Build Coastguard Worker   SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
832*9880d681SAndroid Build Coastguard Worker   const MCExpr *EVal;
833*9880d681SAndroid Build Coastguard Worker 
834*9880d681SAndroid Build Coastguard Worker   Op = nullptr;
835*9880d681SAndroid Build Coastguard Worker   switch (getLexer().getKind()) {
836*9880d681SAndroid Build Coastguard Worker   default:  break;
837*9880d681SAndroid Build Coastguard Worker 
838*9880d681SAndroid Build Coastguard Worker   case AsmToken::Percent:
839*9880d681SAndroid Build Coastguard Worker     Parser.Lex(); // Eat the '%'.
840*9880d681SAndroid Build Coastguard Worker     unsigned RegNo;
841*9880d681SAndroid Build Coastguard Worker     unsigned RegKind;
842*9880d681SAndroid Build Coastguard Worker     if (matchRegisterName(Parser.getTok(), RegNo, RegKind)) {
843*9880d681SAndroid Build Coastguard Worker       StringRef name = Parser.getTok().getString();
844*9880d681SAndroid Build Coastguard Worker       Parser.Lex(); // Eat the identifier token.
845*9880d681SAndroid Build Coastguard Worker       E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
846*9880d681SAndroid Build Coastguard Worker       switch (RegNo) {
847*9880d681SAndroid Build Coastguard Worker       default:
848*9880d681SAndroid Build Coastguard Worker         Op = SparcOperand::CreateReg(RegNo, RegKind, S, E);
849*9880d681SAndroid Build Coastguard Worker         break;
850*9880d681SAndroid Build Coastguard Worker       case Sparc::PSR:
851*9880d681SAndroid Build Coastguard Worker         Op = SparcOperand::CreateToken("%psr", S);
852*9880d681SAndroid Build Coastguard Worker         break;
853*9880d681SAndroid Build Coastguard Worker       case Sparc::FSR:
854*9880d681SAndroid Build Coastguard Worker         Op = SparcOperand::CreateToken("%fsr", S);
855*9880d681SAndroid Build Coastguard Worker         break;
856*9880d681SAndroid Build Coastguard Worker       case Sparc::FQ:
857*9880d681SAndroid Build Coastguard Worker         Op = SparcOperand::CreateToken("%fq", S);
858*9880d681SAndroid Build Coastguard Worker         break;
859*9880d681SAndroid Build Coastguard Worker       case Sparc::CPSR:
860*9880d681SAndroid Build Coastguard Worker         Op = SparcOperand::CreateToken("%csr", S);
861*9880d681SAndroid Build Coastguard Worker         break;
862*9880d681SAndroid Build Coastguard Worker       case Sparc::CPQ:
863*9880d681SAndroid Build Coastguard Worker         Op = SparcOperand::CreateToken("%cq", S);
864*9880d681SAndroid Build Coastguard Worker         break;
865*9880d681SAndroid Build Coastguard Worker       case Sparc::WIM:
866*9880d681SAndroid Build Coastguard Worker         Op = SparcOperand::CreateToken("%wim", S);
867*9880d681SAndroid Build Coastguard Worker         break;
868*9880d681SAndroid Build Coastguard Worker       case Sparc::TBR:
869*9880d681SAndroid Build Coastguard Worker         Op = SparcOperand::CreateToken("%tbr", S);
870*9880d681SAndroid Build Coastguard Worker         break;
871*9880d681SAndroid Build Coastguard Worker       case Sparc::ICC:
872*9880d681SAndroid Build Coastguard Worker         if (name == "xcc")
873*9880d681SAndroid Build Coastguard Worker           Op = SparcOperand::CreateToken("%xcc", S);
874*9880d681SAndroid Build Coastguard Worker         else
875*9880d681SAndroid Build Coastguard Worker           Op = SparcOperand::CreateToken("%icc", S);
876*9880d681SAndroid Build Coastguard Worker         break;
877*9880d681SAndroid Build Coastguard Worker       }
878*9880d681SAndroid Build Coastguard Worker       break;
879*9880d681SAndroid Build Coastguard Worker     }
880*9880d681SAndroid Build Coastguard Worker     if (matchSparcAsmModifiers(EVal, E)) {
881*9880d681SAndroid Build Coastguard Worker       E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
882*9880d681SAndroid Build Coastguard Worker       Op = SparcOperand::CreateImm(EVal, S, E);
883*9880d681SAndroid Build Coastguard Worker     }
884*9880d681SAndroid Build Coastguard Worker     break;
885*9880d681SAndroid Build Coastguard Worker 
886*9880d681SAndroid Build Coastguard Worker   case AsmToken::Minus:
887*9880d681SAndroid Build Coastguard Worker   case AsmToken::Integer:
888*9880d681SAndroid Build Coastguard Worker   case AsmToken::LParen:
889*9880d681SAndroid Build Coastguard Worker   case AsmToken::Dot:
890*9880d681SAndroid Build Coastguard Worker     if (!getParser().parseExpression(EVal, E))
891*9880d681SAndroid Build Coastguard Worker       Op = SparcOperand::CreateImm(EVal, S, E);
892*9880d681SAndroid Build Coastguard Worker     break;
893*9880d681SAndroid Build Coastguard Worker 
894*9880d681SAndroid Build Coastguard Worker   case AsmToken::Identifier: {
895*9880d681SAndroid Build Coastguard Worker     StringRef Identifier;
896*9880d681SAndroid Build Coastguard Worker     if (!getParser().parseIdentifier(Identifier)) {
897*9880d681SAndroid Build Coastguard Worker       E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
898*9880d681SAndroid Build Coastguard Worker       MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
899*9880d681SAndroid Build Coastguard Worker 
900*9880d681SAndroid Build Coastguard Worker       const MCExpr *Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None,
901*9880d681SAndroid Build Coastguard Worker                                                   getContext());
902*9880d681SAndroid Build Coastguard Worker       if (isCall && getContext().getObjectFileInfo()->isPositionIndependent())
903*9880d681SAndroid Build Coastguard Worker         Res = SparcMCExpr::create(SparcMCExpr::VK_Sparc_WPLT30, Res,
904*9880d681SAndroid Build Coastguard Worker                                   getContext());
905*9880d681SAndroid Build Coastguard Worker       Op = SparcOperand::CreateImm(Res, S, E);
906*9880d681SAndroid Build Coastguard Worker     }
907*9880d681SAndroid Build Coastguard Worker     break;
908*9880d681SAndroid Build Coastguard Worker   }
909*9880d681SAndroid Build Coastguard Worker   }
910*9880d681SAndroid Build Coastguard Worker   return (Op) ? MatchOperand_Success : MatchOperand_ParseFail;
911*9880d681SAndroid Build Coastguard Worker }
912*9880d681SAndroid Build Coastguard Worker 
913*9880d681SAndroid Build Coastguard Worker SparcAsmParser::OperandMatchResultTy
parseBranchModifiers(OperandVector & Operands)914*9880d681SAndroid Build Coastguard Worker SparcAsmParser::parseBranchModifiers(OperandVector &Operands) {
915*9880d681SAndroid Build Coastguard Worker 
916*9880d681SAndroid Build Coastguard Worker   // parse (,a|,pn|,pt)+
917*9880d681SAndroid Build Coastguard Worker 
918*9880d681SAndroid Build Coastguard Worker   while (getLexer().is(AsmToken::Comma)) {
919*9880d681SAndroid Build Coastguard Worker 
920*9880d681SAndroid Build Coastguard Worker     Parser.Lex(); // Eat the comma
921*9880d681SAndroid Build Coastguard Worker 
922*9880d681SAndroid Build Coastguard Worker     if (!getLexer().is(AsmToken::Identifier))
923*9880d681SAndroid Build Coastguard Worker       return MatchOperand_ParseFail;
924*9880d681SAndroid Build Coastguard Worker     StringRef modName = Parser.getTok().getString();
925*9880d681SAndroid Build Coastguard Worker     if (modName == "a" || modName == "pn" || modName == "pt") {
926*9880d681SAndroid Build Coastguard Worker       Operands.push_back(SparcOperand::CreateToken(modName,
927*9880d681SAndroid Build Coastguard Worker                                                    Parser.getTok().getLoc()));
928*9880d681SAndroid Build Coastguard Worker       Parser.Lex(); // eat the identifier.
929*9880d681SAndroid Build Coastguard Worker     }
930*9880d681SAndroid Build Coastguard Worker   }
931*9880d681SAndroid Build Coastguard Worker   return MatchOperand_Success;
932*9880d681SAndroid Build Coastguard Worker }
933*9880d681SAndroid Build Coastguard Worker 
matchRegisterName(const AsmToken & Tok,unsigned & RegNo,unsigned & RegKind)934*9880d681SAndroid Build Coastguard Worker bool SparcAsmParser::matchRegisterName(const AsmToken &Tok,
935*9880d681SAndroid Build Coastguard Worker                                        unsigned &RegNo,
936*9880d681SAndroid Build Coastguard Worker                                        unsigned &RegKind)
937*9880d681SAndroid Build Coastguard Worker {
938*9880d681SAndroid Build Coastguard Worker   int64_t intVal = 0;
939*9880d681SAndroid Build Coastguard Worker   RegNo = 0;
940*9880d681SAndroid Build Coastguard Worker   RegKind = SparcOperand::rk_None;
941*9880d681SAndroid Build Coastguard Worker   if (Tok.is(AsmToken::Identifier)) {
942*9880d681SAndroid Build Coastguard Worker     StringRef name = Tok.getString();
943*9880d681SAndroid Build Coastguard Worker 
944*9880d681SAndroid Build Coastguard Worker     // %fp
945*9880d681SAndroid Build Coastguard Worker     if (name.equals("fp")) {
946*9880d681SAndroid Build Coastguard Worker       RegNo = Sparc::I6;
947*9880d681SAndroid Build Coastguard Worker       RegKind = SparcOperand::rk_IntReg;
948*9880d681SAndroid Build Coastguard Worker       return true;
949*9880d681SAndroid Build Coastguard Worker     }
950*9880d681SAndroid Build Coastguard Worker     // %sp
951*9880d681SAndroid Build Coastguard Worker     if (name.equals("sp")) {
952*9880d681SAndroid Build Coastguard Worker       RegNo = Sparc::O6;
953*9880d681SAndroid Build Coastguard Worker       RegKind = SparcOperand::rk_IntReg;
954*9880d681SAndroid Build Coastguard Worker       return true;
955*9880d681SAndroid Build Coastguard Worker     }
956*9880d681SAndroid Build Coastguard Worker 
957*9880d681SAndroid Build Coastguard Worker     if (name.equals("y")) {
958*9880d681SAndroid Build Coastguard Worker       RegNo = Sparc::Y;
959*9880d681SAndroid Build Coastguard Worker       RegKind = SparcOperand::rk_Special;
960*9880d681SAndroid Build Coastguard Worker       return true;
961*9880d681SAndroid Build Coastguard Worker     }
962*9880d681SAndroid Build Coastguard Worker 
963*9880d681SAndroid Build Coastguard Worker     if (name.substr(0, 3).equals_lower("asr")
964*9880d681SAndroid Build Coastguard Worker         && !name.substr(3).getAsInteger(10, intVal)
965*9880d681SAndroid Build Coastguard Worker         && intVal > 0 && intVal < 32) {
966*9880d681SAndroid Build Coastguard Worker       RegNo = ASRRegs[intVal];
967*9880d681SAndroid Build Coastguard Worker       RegKind = SparcOperand::rk_Special;
968*9880d681SAndroid Build Coastguard Worker       return true;
969*9880d681SAndroid Build Coastguard Worker     }
970*9880d681SAndroid Build Coastguard Worker 
971*9880d681SAndroid Build Coastguard Worker     // %fprs is an alias of %asr6.
972*9880d681SAndroid Build Coastguard Worker     if (name.equals("fprs")) {
973*9880d681SAndroid Build Coastguard Worker       RegNo = ASRRegs[6];
974*9880d681SAndroid Build Coastguard Worker       RegKind = SparcOperand::rk_Special;
975*9880d681SAndroid Build Coastguard Worker       return true;
976*9880d681SAndroid Build Coastguard Worker     }
977*9880d681SAndroid Build Coastguard Worker 
978*9880d681SAndroid Build Coastguard Worker     if (name.equals("icc")) {
979*9880d681SAndroid Build Coastguard Worker       RegNo = Sparc::ICC;
980*9880d681SAndroid Build Coastguard Worker       RegKind = SparcOperand::rk_Special;
981*9880d681SAndroid Build Coastguard Worker       return true;
982*9880d681SAndroid Build Coastguard Worker     }
983*9880d681SAndroid Build Coastguard Worker 
984*9880d681SAndroid Build Coastguard Worker     if (name.equals("psr")) {
985*9880d681SAndroid Build Coastguard Worker       RegNo = Sparc::PSR;
986*9880d681SAndroid Build Coastguard Worker       RegKind = SparcOperand::rk_Special;
987*9880d681SAndroid Build Coastguard Worker       return true;
988*9880d681SAndroid Build Coastguard Worker     }
989*9880d681SAndroid Build Coastguard Worker 
990*9880d681SAndroid Build Coastguard Worker     if (name.equals("fsr")) {
991*9880d681SAndroid Build Coastguard Worker       RegNo = Sparc::FSR;
992*9880d681SAndroid Build Coastguard Worker       RegKind = SparcOperand::rk_Special;
993*9880d681SAndroid Build Coastguard Worker       return true;
994*9880d681SAndroid Build Coastguard Worker     }
995*9880d681SAndroid Build Coastguard Worker 
996*9880d681SAndroid Build Coastguard Worker     if (name.equals("fq")) {
997*9880d681SAndroid Build Coastguard Worker       RegNo = Sparc::FQ;
998*9880d681SAndroid Build Coastguard Worker       RegKind = SparcOperand::rk_Special;
999*9880d681SAndroid Build Coastguard Worker       return true;
1000*9880d681SAndroid Build Coastguard Worker     }
1001*9880d681SAndroid Build Coastguard Worker 
1002*9880d681SAndroid Build Coastguard Worker     if (name.equals("csr")) {
1003*9880d681SAndroid Build Coastguard Worker       RegNo = Sparc::CPSR;
1004*9880d681SAndroid Build Coastguard Worker       RegKind = SparcOperand::rk_Special;
1005*9880d681SAndroid Build Coastguard Worker       return true;
1006*9880d681SAndroid Build Coastguard Worker     }
1007*9880d681SAndroid Build Coastguard Worker 
1008*9880d681SAndroid Build Coastguard Worker     if (name.equals("cq")) {
1009*9880d681SAndroid Build Coastguard Worker       RegNo = Sparc::CPQ;
1010*9880d681SAndroid Build Coastguard Worker       RegKind = SparcOperand::rk_Special;
1011*9880d681SAndroid Build Coastguard Worker       return true;
1012*9880d681SAndroid Build Coastguard Worker     }
1013*9880d681SAndroid Build Coastguard Worker 
1014*9880d681SAndroid Build Coastguard Worker     if (name.equals("wim")) {
1015*9880d681SAndroid Build Coastguard Worker       RegNo = Sparc::WIM;
1016*9880d681SAndroid Build Coastguard Worker       RegKind = SparcOperand::rk_Special;
1017*9880d681SAndroid Build Coastguard Worker       return true;
1018*9880d681SAndroid Build Coastguard Worker     }
1019*9880d681SAndroid Build Coastguard Worker 
1020*9880d681SAndroid Build Coastguard Worker     if (name.equals("tbr")) {
1021*9880d681SAndroid Build Coastguard Worker       RegNo = Sparc::TBR;
1022*9880d681SAndroid Build Coastguard Worker       RegKind = SparcOperand::rk_Special;
1023*9880d681SAndroid Build Coastguard Worker       return true;
1024*9880d681SAndroid Build Coastguard Worker     }
1025*9880d681SAndroid Build Coastguard Worker 
1026*9880d681SAndroid Build Coastguard Worker     if (name.equals("xcc")) {
1027*9880d681SAndroid Build Coastguard Worker       // FIXME:: check 64bit.
1028*9880d681SAndroid Build Coastguard Worker       RegNo = Sparc::ICC;
1029*9880d681SAndroid Build Coastguard Worker       RegKind = SparcOperand::rk_Special;
1030*9880d681SAndroid Build Coastguard Worker       return true;
1031*9880d681SAndroid Build Coastguard Worker     }
1032*9880d681SAndroid Build Coastguard Worker 
1033*9880d681SAndroid Build Coastguard Worker     // %fcc0 - %fcc3
1034*9880d681SAndroid Build Coastguard Worker     if (name.substr(0, 3).equals_lower("fcc")
1035*9880d681SAndroid Build Coastguard Worker         && !name.substr(3).getAsInteger(10, intVal)
1036*9880d681SAndroid Build Coastguard Worker         && intVal < 4) {
1037*9880d681SAndroid Build Coastguard Worker       // FIXME: check 64bit and  handle %fcc1 - %fcc3
1038*9880d681SAndroid Build Coastguard Worker       RegNo = Sparc::FCC0 + intVal;
1039*9880d681SAndroid Build Coastguard Worker       RegKind = SparcOperand::rk_Special;
1040*9880d681SAndroid Build Coastguard Worker       return true;
1041*9880d681SAndroid Build Coastguard Worker     }
1042*9880d681SAndroid Build Coastguard Worker 
1043*9880d681SAndroid Build Coastguard Worker     // %g0 - %g7
1044*9880d681SAndroid Build Coastguard Worker     if (name.substr(0, 1).equals_lower("g")
1045*9880d681SAndroid Build Coastguard Worker         && !name.substr(1).getAsInteger(10, intVal)
1046*9880d681SAndroid Build Coastguard Worker         && intVal < 8) {
1047*9880d681SAndroid Build Coastguard Worker       RegNo = IntRegs[intVal];
1048*9880d681SAndroid Build Coastguard Worker       RegKind = SparcOperand::rk_IntReg;
1049*9880d681SAndroid Build Coastguard Worker       return true;
1050*9880d681SAndroid Build Coastguard Worker     }
1051*9880d681SAndroid Build Coastguard Worker     // %o0 - %o7
1052*9880d681SAndroid Build Coastguard Worker     if (name.substr(0, 1).equals_lower("o")
1053*9880d681SAndroid Build Coastguard Worker         && !name.substr(1).getAsInteger(10, intVal)
1054*9880d681SAndroid Build Coastguard Worker         && intVal < 8) {
1055*9880d681SAndroid Build Coastguard Worker       RegNo = IntRegs[8 + intVal];
1056*9880d681SAndroid Build Coastguard Worker       RegKind = SparcOperand::rk_IntReg;
1057*9880d681SAndroid Build Coastguard Worker       return true;
1058*9880d681SAndroid Build Coastguard Worker     }
1059*9880d681SAndroid Build Coastguard Worker     if (name.substr(0, 1).equals_lower("l")
1060*9880d681SAndroid Build Coastguard Worker         && !name.substr(1).getAsInteger(10, intVal)
1061*9880d681SAndroid Build Coastguard Worker         && intVal < 8) {
1062*9880d681SAndroid Build Coastguard Worker       RegNo = IntRegs[16 + intVal];
1063*9880d681SAndroid Build Coastguard Worker       RegKind = SparcOperand::rk_IntReg;
1064*9880d681SAndroid Build Coastguard Worker       return true;
1065*9880d681SAndroid Build Coastguard Worker     }
1066*9880d681SAndroid Build Coastguard Worker     if (name.substr(0, 1).equals_lower("i")
1067*9880d681SAndroid Build Coastguard Worker         && !name.substr(1).getAsInteger(10, intVal)
1068*9880d681SAndroid Build Coastguard Worker         && intVal < 8) {
1069*9880d681SAndroid Build Coastguard Worker       RegNo = IntRegs[24 + intVal];
1070*9880d681SAndroid Build Coastguard Worker       RegKind = SparcOperand::rk_IntReg;
1071*9880d681SAndroid Build Coastguard Worker       return true;
1072*9880d681SAndroid Build Coastguard Worker     }
1073*9880d681SAndroid Build Coastguard Worker     // %f0 - %f31
1074*9880d681SAndroid Build Coastguard Worker     if (name.substr(0, 1).equals_lower("f")
1075*9880d681SAndroid Build Coastguard Worker         && !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 32) {
1076*9880d681SAndroid Build Coastguard Worker       RegNo = FloatRegs[intVal];
1077*9880d681SAndroid Build Coastguard Worker       RegKind = SparcOperand::rk_FloatReg;
1078*9880d681SAndroid Build Coastguard Worker       return true;
1079*9880d681SAndroid Build Coastguard Worker     }
1080*9880d681SAndroid Build Coastguard Worker     // %f32 - %f62
1081*9880d681SAndroid Build Coastguard Worker     if (name.substr(0, 1).equals_lower("f")
1082*9880d681SAndroid Build Coastguard Worker         && !name.substr(1, 2).getAsInteger(10, intVal)
1083*9880d681SAndroid Build Coastguard Worker         && intVal >= 32 && intVal <= 62 && (intVal % 2 == 0)) {
1084*9880d681SAndroid Build Coastguard Worker       // FIXME: Check V9
1085*9880d681SAndroid Build Coastguard Worker       RegNo = DoubleRegs[intVal/2];
1086*9880d681SAndroid Build Coastguard Worker       RegKind = SparcOperand::rk_DoubleReg;
1087*9880d681SAndroid Build Coastguard Worker       return true;
1088*9880d681SAndroid Build Coastguard Worker     }
1089*9880d681SAndroid Build Coastguard Worker 
1090*9880d681SAndroid Build Coastguard Worker     // %r0 - %r31
1091*9880d681SAndroid Build Coastguard Worker     if (name.substr(0, 1).equals_lower("r")
1092*9880d681SAndroid Build Coastguard Worker         && !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 31) {
1093*9880d681SAndroid Build Coastguard Worker       RegNo = IntRegs[intVal];
1094*9880d681SAndroid Build Coastguard Worker       RegKind = SparcOperand::rk_IntReg;
1095*9880d681SAndroid Build Coastguard Worker       return true;
1096*9880d681SAndroid Build Coastguard Worker     }
1097*9880d681SAndroid Build Coastguard Worker 
1098*9880d681SAndroid Build Coastguard Worker     // %c0 - %c31
1099*9880d681SAndroid Build Coastguard Worker     if (name.substr(0, 1).equals_lower("c")
1100*9880d681SAndroid Build Coastguard Worker         && !name.substr(1).getAsInteger(10, intVal)
1101*9880d681SAndroid Build Coastguard Worker         && intVal < 32) {
1102*9880d681SAndroid Build Coastguard Worker       RegNo = CoprocRegs[intVal];
1103*9880d681SAndroid Build Coastguard Worker       RegKind = SparcOperand::rk_CoprocReg;
1104*9880d681SAndroid Build Coastguard Worker       return true;
1105*9880d681SAndroid Build Coastguard Worker     }
1106*9880d681SAndroid Build Coastguard Worker 
1107*9880d681SAndroid Build Coastguard Worker     if (name.equals("tpc")) {
1108*9880d681SAndroid Build Coastguard Worker       RegNo = Sparc::TPC;
1109*9880d681SAndroid Build Coastguard Worker       RegKind = SparcOperand::rk_Special;
1110*9880d681SAndroid Build Coastguard Worker       return true;
1111*9880d681SAndroid Build Coastguard Worker     }
1112*9880d681SAndroid Build Coastguard Worker     if (name.equals("tnpc")) {
1113*9880d681SAndroid Build Coastguard Worker       RegNo = Sparc::TNPC;
1114*9880d681SAndroid Build Coastguard Worker       RegKind = SparcOperand::rk_Special;
1115*9880d681SAndroid Build Coastguard Worker       return true;
1116*9880d681SAndroid Build Coastguard Worker     }
1117*9880d681SAndroid Build Coastguard Worker     if (name.equals("tstate")) {
1118*9880d681SAndroid Build Coastguard Worker       RegNo = Sparc::TSTATE;
1119*9880d681SAndroid Build Coastguard Worker       RegKind = SparcOperand::rk_Special;
1120*9880d681SAndroid Build Coastguard Worker       return true;
1121*9880d681SAndroid Build Coastguard Worker     }
1122*9880d681SAndroid Build Coastguard Worker     if (name.equals("tt")) {
1123*9880d681SAndroid Build Coastguard Worker       RegNo = Sparc::TT;
1124*9880d681SAndroid Build Coastguard Worker       RegKind = SparcOperand::rk_Special;
1125*9880d681SAndroid Build Coastguard Worker       return true;
1126*9880d681SAndroid Build Coastguard Worker     }
1127*9880d681SAndroid Build Coastguard Worker     if (name.equals("tick")) {
1128*9880d681SAndroid Build Coastguard Worker       RegNo = Sparc::TICK;
1129*9880d681SAndroid Build Coastguard Worker       RegKind = SparcOperand::rk_Special;
1130*9880d681SAndroid Build Coastguard Worker       return true;
1131*9880d681SAndroid Build Coastguard Worker     }
1132*9880d681SAndroid Build Coastguard Worker     if (name.equals("tba")) {
1133*9880d681SAndroid Build Coastguard Worker       RegNo = Sparc::TBA;
1134*9880d681SAndroid Build Coastguard Worker       RegKind = SparcOperand::rk_Special;
1135*9880d681SAndroid Build Coastguard Worker       return true;
1136*9880d681SAndroid Build Coastguard Worker     }
1137*9880d681SAndroid Build Coastguard Worker     if (name.equals("pstate")) {
1138*9880d681SAndroid Build Coastguard Worker       RegNo = Sparc::PSTATE;
1139*9880d681SAndroid Build Coastguard Worker       RegKind = SparcOperand::rk_Special;
1140*9880d681SAndroid Build Coastguard Worker       return true;
1141*9880d681SAndroid Build Coastguard Worker     }
1142*9880d681SAndroid Build Coastguard Worker     if (name.equals("tl")) {
1143*9880d681SAndroid Build Coastguard Worker       RegNo = Sparc::TL;
1144*9880d681SAndroid Build Coastguard Worker       RegKind = SparcOperand::rk_Special;
1145*9880d681SAndroid Build Coastguard Worker       return true;
1146*9880d681SAndroid Build Coastguard Worker     }
1147*9880d681SAndroid Build Coastguard Worker     if (name.equals("pil")) {
1148*9880d681SAndroid Build Coastguard Worker       RegNo = Sparc::PIL;
1149*9880d681SAndroid Build Coastguard Worker       RegKind = SparcOperand::rk_Special;
1150*9880d681SAndroid Build Coastguard Worker       return true;
1151*9880d681SAndroid Build Coastguard Worker     }
1152*9880d681SAndroid Build Coastguard Worker     if (name.equals("cwp")) {
1153*9880d681SAndroid Build Coastguard Worker       RegNo = Sparc::CWP;
1154*9880d681SAndroid Build Coastguard Worker       RegKind = SparcOperand::rk_Special;
1155*9880d681SAndroid Build Coastguard Worker       return true;
1156*9880d681SAndroid Build Coastguard Worker     }
1157*9880d681SAndroid Build Coastguard Worker     if (name.equals("cansave")) {
1158*9880d681SAndroid Build Coastguard Worker       RegNo = Sparc::CANSAVE;
1159*9880d681SAndroid Build Coastguard Worker       RegKind = SparcOperand::rk_Special;
1160*9880d681SAndroid Build Coastguard Worker       return true;
1161*9880d681SAndroid Build Coastguard Worker     }
1162*9880d681SAndroid Build Coastguard Worker     if (name.equals("canrestore")) {
1163*9880d681SAndroid Build Coastguard Worker       RegNo = Sparc::CANRESTORE;
1164*9880d681SAndroid Build Coastguard Worker       RegKind = SparcOperand::rk_Special;
1165*9880d681SAndroid Build Coastguard Worker       return true;
1166*9880d681SAndroid Build Coastguard Worker     }
1167*9880d681SAndroid Build Coastguard Worker     if (name.equals("cleanwin")) {
1168*9880d681SAndroid Build Coastguard Worker       RegNo = Sparc::CLEANWIN;
1169*9880d681SAndroid Build Coastguard Worker       RegKind = SparcOperand::rk_Special;
1170*9880d681SAndroid Build Coastguard Worker       return true;
1171*9880d681SAndroid Build Coastguard Worker     }
1172*9880d681SAndroid Build Coastguard Worker     if (name.equals("otherwin")) {
1173*9880d681SAndroid Build Coastguard Worker       RegNo = Sparc::OTHERWIN;
1174*9880d681SAndroid Build Coastguard Worker       RegKind = SparcOperand::rk_Special;
1175*9880d681SAndroid Build Coastguard Worker       return true;
1176*9880d681SAndroid Build Coastguard Worker     }
1177*9880d681SAndroid Build Coastguard Worker     if (name.equals("wstate")) {
1178*9880d681SAndroid Build Coastguard Worker       RegNo = Sparc::WSTATE;
1179*9880d681SAndroid Build Coastguard Worker       RegKind = SparcOperand::rk_Special;
1180*9880d681SAndroid Build Coastguard Worker       return true;
1181*9880d681SAndroid Build Coastguard Worker     }
1182*9880d681SAndroid Build Coastguard Worker   }
1183*9880d681SAndroid Build Coastguard Worker   return false;
1184*9880d681SAndroid Build Coastguard Worker }
1185*9880d681SAndroid Build Coastguard Worker 
1186*9880d681SAndroid Build Coastguard Worker // Determine if an expression contains a reference to the symbol
1187*9880d681SAndroid Build Coastguard Worker // "_GLOBAL_OFFSET_TABLE_".
hasGOTReference(const MCExpr * Expr)1188*9880d681SAndroid Build Coastguard Worker static bool hasGOTReference(const MCExpr *Expr) {
1189*9880d681SAndroid Build Coastguard Worker   switch (Expr->getKind()) {
1190*9880d681SAndroid Build Coastguard Worker   case MCExpr::Target:
1191*9880d681SAndroid Build Coastguard Worker     if (const SparcMCExpr *SE = dyn_cast<SparcMCExpr>(Expr))
1192*9880d681SAndroid Build Coastguard Worker       return hasGOTReference(SE->getSubExpr());
1193*9880d681SAndroid Build Coastguard Worker     break;
1194*9880d681SAndroid Build Coastguard Worker 
1195*9880d681SAndroid Build Coastguard Worker   case MCExpr::Constant:
1196*9880d681SAndroid Build Coastguard Worker     break;
1197*9880d681SAndroid Build Coastguard Worker 
1198*9880d681SAndroid Build Coastguard Worker   case MCExpr::Binary: {
1199*9880d681SAndroid Build Coastguard Worker     const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);
1200*9880d681SAndroid Build Coastguard Worker     return hasGOTReference(BE->getLHS()) || hasGOTReference(BE->getRHS());
1201*9880d681SAndroid Build Coastguard Worker   }
1202*9880d681SAndroid Build Coastguard Worker 
1203*9880d681SAndroid Build Coastguard Worker   case MCExpr::SymbolRef: {
1204*9880d681SAndroid Build Coastguard Worker     const MCSymbolRefExpr &SymRef = *cast<MCSymbolRefExpr>(Expr);
1205*9880d681SAndroid Build Coastguard Worker     return (SymRef.getSymbol().getName() == "_GLOBAL_OFFSET_TABLE_");
1206*9880d681SAndroid Build Coastguard Worker   }
1207*9880d681SAndroid Build Coastguard Worker 
1208*9880d681SAndroid Build Coastguard Worker   case MCExpr::Unary:
1209*9880d681SAndroid Build Coastguard Worker     return hasGOTReference(cast<MCUnaryExpr>(Expr)->getSubExpr());
1210*9880d681SAndroid Build Coastguard Worker   }
1211*9880d681SAndroid Build Coastguard Worker   return false;
1212*9880d681SAndroid Build Coastguard Worker }
1213*9880d681SAndroid Build Coastguard Worker 
1214*9880d681SAndroid Build Coastguard Worker const SparcMCExpr *
adjustPICRelocation(SparcMCExpr::VariantKind VK,const MCExpr * subExpr)1215*9880d681SAndroid Build Coastguard Worker SparcAsmParser::adjustPICRelocation(SparcMCExpr::VariantKind VK,
1216*9880d681SAndroid Build Coastguard Worker                                     const MCExpr *subExpr)
1217*9880d681SAndroid Build Coastguard Worker {
1218*9880d681SAndroid Build Coastguard Worker   // When in PIC mode, "%lo(...)" and "%hi(...)" behave differently.
1219*9880d681SAndroid Build Coastguard Worker   // If the expression refers contains _GLOBAL_OFFSETE_TABLE, it is
1220*9880d681SAndroid Build Coastguard Worker   // actually a %pc10 or %pc22 relocation. Otherwise, they are interpreted
1221*9880d681SAndroid Build Coastguard Worker   // as %got10 or %got22 relocation.
1222*9880d681SAndroid Build Coastguard Worker 
1223*9880d681SAndroid Build Coastguard Worker   if (getContext().getObjectFileInfo()->isPositionIndependent()) {
1224*9880d681SAndroid Build Coastguard Worker     switch(VK) {
1225*9880d681SAndroid Build Coastguard Worker     default: break;
1226*9880d681SAndroid Build Coastguard Worker     case SparcMCExpr::VK_Sparc_LO:
1227*9880d681SAndroid Build Coastguard Worker       VK = (hasGOTReference(subExpr) ? SparcMCExpr::VK_Sparc_PC10
1228*9880d681SAndroid Build Coastguard Worker                                      : SparcMCExpr::VK_Sparc_GOT10);
1229*9880d681SAndroid Build Coastguard Worker       break;
1230*9880d681SAndroid Build Coastguard Worker     case SparcMCExpr::VK_Sparc_HI:
1231*9880d681SAndroid Build Coastguard Worker       VK = (hasGOTReference(subExpr) ? SparcMCExpr::VK_Sparc_PC22
1232*9880d681SAndroid Build Coastguard Worker                                      : SparcMCExpr::VK_Sparc_GOT22);
1233*9880d681SAndroid Build Coastguard Worker       break;
1234*9880d681SAndroid Build Coastguard Worker     }
1235*9880d681SAndroid Build Coastguard Worker   }
1236*9880d681SAndroid Build Coastguard Worker 
1237*9880d681SAndroid Build Coastguard Worker   return SparcMCExpr::create(VK, subExpr, getContext());
1238*9880d681SAndroid Build Coastguard Worker }
1239*9880d681SAndroid Build Coastguard Worker 
matchSparcAsmModifiers(const MCExpr * & EVal,SMLoc & EndLoc)1240*9880d681SAndroid Build Coastguard Worker bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal,
1241*9880d681SAndroid Build Coastguard Worker                                             SMLoc &EndLoc)
1242*9880d681SAndroid Build Coastguard Worker {
1243*9880d681SAndroid Build Coastguard Worker   AsmToken Tok = Parser.getTok();
1244*9880d681SAndroid Build Coastguard Worker   if (!Tok.is(AsmToken::Identifier))
1245*9880d681SAndroid Build Coastguard Worker     return false;
1246*9880d681SAndroid Build Coastguard Worker 
1247*9880d681SAndroid Build Coastguard Worker   StringRef name = Tok.getString();
1248*9880d681SAndroid Build Coastguard Worker 
1249*9880d681SAndroid Build Coastguard Worker   SparcMCExpr::VariantKind VK = SparcMCExpr::parseVariantKind(name);
1250*9880d681SAndroid Build Coastguard Worker 
1251*9880d681SAndroid Build Coastguard Worker   if (VK == SparcMCExpr::VK_Sparc_None)
1252*9880d681SAndroid Build Coastguard Worker     return false;
1253*9880d681SAndroid Build Coastguard Worker 
1254*9880d681SAndroid Build Coastguard Worker   Parser.Lex(); // Eat the identifier.
1255*9880d681SAndroid Build Coastguard Worker   if (Parser.getTok().getKind() != AsmToken::LParen)
1256*9880d681SAndroid Build Coastguard Worker     return false;
1257*9880d681SAndroid Build Coastguard Worker 
1258*9880d681SAndroid Build Coastguard Worker   Parser.Lex(); // Eat the LParen token.
1259*9880d681SAndroid Build Coastguard Worker   const MCExpr *subExpr;
1260*9880d681SAndroid Build Coastguard Worker   if (Parser.parseParenExpression(subExpr, EndLoc))
1261*9880d681SAndroid Build Coastguard Worker     return false;
1262*9880d681SAndroid Build Coastguard Worker 
1263*9880d681SAndroid Build Coastguard Worker   EVal = adjustPICRelocation(VK, subExpr);
1264*9880d681SAndroid Build Coastguard Worker   return true;
1265*9880d681SAndroid Build Coastguard Worker }
1266*9880d681SAndroid Build Coastguard Worker 
LLVMInitializeSparcAsmParser()1267*9880d681SAndroid Build Coastguard Worker extern "C" void LLVMInitializeSparcAsmParser() {
1268*9880d681SAndroid Build Coastguard Worker   RegisterMCAsmParser<SparcAsmParser> A(TheSparcTarget);
1269*9880d681SAndroid Build Coastguard Worker   RegisterMCAsmParser<SparcAsmParser> B(TheSparcV9Target);
1270*9880d681SAndroid Build Coastguard Worker   RegisterMCAsmParser<SparcAsmParser> C(TheSparcelTarget);
1271*9880d681SAndroid Build Coastguard Worker }
1272*9880d681SAndroid Build Coastguard Worker 
1273*9880d681SAndroid Build Coastguard Worker #define GET_REGISTER_MATCHER
1274*9880d681SAndroid Build Coastguard Worker #define GET_MATCHER_IMPLEMENTATION
1275*9880d681SAndroid Build Coastguard Worker #include "SparcGenAsmMatcher.inc"
1276*9880d681SAndroid Build Coastguard Worker 
validateTargetOperandClass(MCParsedAsmOperand & GOp,unsigned Kind)1277*9880d681SAndroid Build Coastguard Worker unsigned SparcAsmParser::validateTargetOperandClass(MCParsedAsmOperand &GOp,
1278*9880d681SAndroid Build Coastguard Worker                                                     unsigned Kind) {
1279*9880d681SAndroid Build Coastguard Worker   SparcOperand &Op = (SparcOperand &)GOp;
1280*9880d681SAndroid Build Coastguard Worker   if (Op.isFloatOrDoubleReg()) {
1281*9880d681SAndroid Build Coastguard Worker     switch (Kind) {
1282*9880d681SAndroid Build Coastguard Worker     default: break;
1283*9880d681SAndroid Build Coastguard Worker     case MCK_DFPRegs:
1284*9880d681SAndroid Build Coastguard Worker       if (!Op.isFloatReg() || SparcOperand::MorphToDoubleReg(Op))
1285*9880d681SAndroid Build Coastguard Worker         return MCTargetAsmParser::Match_Success;
1286*9880d681SAndroid Build Coastguard Worker       break;
1287*9880d681SAndroid Build Coastguard Worker     case MCK_QFPRegs:
1288*9880d681SAndroid Build Coastguard Worker       if (SparcOperand::MorphToQuadReg(Op))
1289*9880d681SAndroid Build Coastguard Worker         return MCTargetAsmParser::Match_Success;
1290*9880d681SAndroid Build Coastguard Worker       break;
1291*9880d681SAndroid Build Coastguard Worker     }
1292*9880d681SAndroid Build Coastguard Worker   }
1293*9880d681SAndroid Build Coastguard Worker   if (Op.isIntReg() && Kind == MCK_IntPair) {
1294*9880d681SAndroid Build Coastguard Worker     if (SparcOperand::MorphToIntPairReg(Op))
1295*9880d681SAndroid Build Coastguard Worker       return MCTargetAsmParser::Match_Success;
1296*9880d681SAndroid Build Coastguard Worker   }
1297*9880d681SAndroid Build Coastguard Worker   if (Op.isCoprocReg() && Kind == MCK_CoprocPair) {
1298*9880d681SAndroid Build Coastguard Worker      if (SparcOperand::MorphToCoprocPairReg(Op))
1299*9880d681SAndroid Build Coastguard Worker        return MCTargetAsmParser::Match_Success;
1300*9880d681SAndroid Build Coastguard Worker    }
1301*9880d681SAndroid Build Coastguard Worker   return Match_InvalidOperand;
1302*9880d681SAndroid Build Coastguard Worker }
1303