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