blob: 96922b371eddf2be95729ddb0b2df6e39f46cfe1 [file] [log] [blame]
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +00001//===-- SparcAsmParser.cpp - Parse Sparc assembly to MCInst instructions --===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Venkatraman Govindaraju559c4ac2014-01-07 08:00:49 +000010#include "MCTargetDesc/SparcMCExpr.h"
Benjamin Kramerb3e8a6d2016-01-27 10:01:28 +000011#include "MCTargetDesc/SparcMCTargetDesc.h"
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +000012#include "llvm/ADT/STLExtras.h"
13#include "llvm/MC/MCContext.h"
14#include "llvm/MC/MCInst.h"
Venkatraman Govindaraju9fc29092014-03-01 05:07:21 +000015#include "llvm/MC/MCObjectFileInfo.h"
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +000016#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
Benjamin Kramerb3e8a6d2016-01-27 10:01:28 +000017#include "llvm/MC/MCParser/MCTargetAsmParser.h"
Craig Topper92cfdd72015-10-18 05:29:05 +000018#include "llvm/MC/MCRegisterInfo.h"
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +000019#include "llvm/MC/MCStreamer.h"
20#include "llvm/MC/MCSubtargetInfo.h"
Venkatraman Govindaraju9fc29092014-03-01 05:07:21 +000021#include "llvm/MC/MCSymbol.h"
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +000022#include "llvm/Support/TargetRegistry.h"
23
24using namespace llvm;
25
26// The generated AsmMatcher SparcGenAsmMatcher uses "Sparc" as the target
27// namespace. But SPARC backend uses "SP" as its namespace.
28namespace llvm {
29 namespace Sparc {
30 using namespace SP;
31 }
32}
33
34namespace {
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +000035class SparcOperand;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +000036class SparcAsmParser : public MCTargetAsmParser {
37
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +000038 MCAsmParser &Parser;
39
40 /// @name Auto-generated Match Functions
41 /// {
42
43#define GET_ASSEMBLER_HEADER
44#include "SparcGenAsmMatcher.inc"
45
46 /// }
47
48 // public interface of the MCTargetAsmParser.
49 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
David Blaikie960ea3f2014-06-08 16:18:35 +000050 OperandVector &Operands, MCStreamer &Out,
Tim Northover26bb14e2014-08-18 11:49:42 +000051 uint64_t &ErrorInfo,
Craig Topperb0c941b2014-04-29 07:57:13 +000052 bool MatchingInlineAsm) override;
53 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +000054 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
David Blaikie960ea3f2014-06-08 16:18:35 +000055 SMLoc NameLoc, OperandVector &Operands) override;
Craig Topperb0c941b2014-04-29 07:57:13 +000056 bool ParseDirective(AsmToken DirectiveID) override;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +000057
David Blaikie960ea3f2014-06-08 16:18:35 +000058 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
Craig Topperb0c941b2014-04-29 07:57:13 +000059 unsigned Kind) override;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +000060
61 // Custom parse functions for Sparc specific operands.
David Blaikie960ea3f2014-06-08 16:18:35 +000062 OperandMatchResultTy parseMEMOperand(OperandVector &Operands);
63
64 OperandMatchResultTy parseOperand(OperandVector &Operands, StringRef Name);
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +000065
66 OperandMatchResultTy
David Blaikie960ea3f2014-06-08 16:18:35 +000067 parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Operand,
68 bool isCall = false);
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +000069
David Blaikie960ea3f2014-06-08 16:18:35 +000070 OperandMatchResultTy parseBranchModifiers(OperandVector &Operands);
Venkatraman Govindaraju22868742014-03-01 20:08:48 +000071
Joerg Sonnenbergerc8d50d62015-10-01 22:08:20 +000072 // Helper function for dealing with %lo / %hi in PIC mode.
73 const SparcMCExpr *adjustPICRelocation(SparcMCExpr::VariantKind VK,
74 const MCExpr *subExpr);
75
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +000076 // returns true if Tok is matched to a register and returns register in RegNo.
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +000077 bool matchRegisterName(const AsmToken &Tok, unsigned &RegNo,
78 unsigned &RegKind);
79
Venkatraman Govindaraju559c4ac2014-01-07 08:00:49 +000080 bool matchSparcAsmModifiers(const MCExpr *&EVal, SMLoc &EndLoc);
Venkatraman Govindaraju6f2e08c2014-03-01 02:18:04 +000081 bool parseDirectiveWord(unsigned Size, SMLoc L);
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +000082
Daniel Sandersa73f1fd2015-06-10 12:11:26 +000083 bool is64Bit() const {
Akira Hatanakabd9fc282015-11-14 05:20:05 +000084 return getSTI().getTargetTriple().getArch() == Triple::sparcv9;
Daniel Sandersa73f1fd2015-06-10 12:11:26 +000085 }
James Y Knightc49e7882015-05-18 16:43:33 +000086
Nirav Dave2364748a2016-09-16 18:30:20 +000087 bool expandSET(MCInst &Inst, SMLoc IDLoc,
James Y Knightc49e7882015-05-18 16:43:33 +000088 SmallVectorImpl<MCInst> &Instructions);
89
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +000090public:
Akira Hatanakab11ef082015-11-14 06:35:56 +000091 SparcAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
Evgeniy Stepanov0a951b72014-04-23 11:16:03 +000092 const MCInstrInfo &MII,
93 const MCTargetOptions &Options)
Akira Hatanakabd9fc282015-11-14 05:20:05 +000094 : MCTargetAsmParser(Options, sti), Parser(parser) {
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +000095 // Initialize the set of available features.
Akira Hatanakabd9fc282015-11-14 05:20:05 +000096 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +000097 }
98
99};
100
Craig Topper92cfdd72015-10-18 05:29:05 +0000101 static const MCPhysReg IntRegs[32] = {
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000102 Sparc::G0, Sparc::G1, Sparc::G2, Sparc::G3,
103 Sparc::G4, Sparc::G5, Sparc::G6, Sparc::G7,
104 Sparc::O0, Sparc::O1, Sparc::O2, Sparc::O3,
105 Sparc::O4, Sparc::O5, Sparc::O6, Sparc::O7,
106 Sparc::L0, Sparc::L1, Sparc::L2, Sparc::L3,
107 Sparc::L4, Sparc::L5, Sparc::L6, Sparc::L7,
108 Sparc::I0, Sparc::I1, Sparc::I2, Sparc::I3,
109 Sparc::I4, Sparc::I5, Sparc::I6, Sparc::I7 };
110
Craig Topper92cfdd72015-10-18 05:29:05 +0000111 static const MCPhysReg FloatRegs[32] = {
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000112 Sparc::F0, Sparc::F1, Sparc::F2, Sparc::F3,
113 Sparc::F4, Sparc::F5, Sparc::F6, Sparc::F7,
114 Sparc::F8, Sparc::F9, Sparc::F10, Sparc::F11,
115 Sparc::F12, Sparc::F13, Sparc::F14, Sparc::F15,
116 Sparc::F16, Sparc::F17, Sparc::F18, Sparc::F19,
117 Sparc::F20, Sparc::F21, Sparc::F22, Sparc::F23,
118 Sparc::F24, Sparc::F25, Sparc::F26, Sparc::F27,
119 Sparc::F28, Sparc::F29, Sparc::F30, Sparc::F31 };
120
Craig Topper92cfdd72015-10-18 05:29:05 +0000121 static const MCPhysReg DoubleRegs[32] = {
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000122 Sparc::D0, Sparc::D1, Sparc::D2, Sparc::D3,
123 Sparc::D4, Sparc::D5, Sparc::D6, Sparc::D7,
124 Sparc::D8, Sparc::D7, Sparc::D8, Sparc::D9,
125 Sparc::D12, Sparc::D13, Sparc::D14, Sparc::D15,
126 Sparc::D16, Sparc::D17, Sparc::D18, Sparc::D19,
127 Sparc::D20, Sparc::D21, Sparc::D22, Sparc::D23,
128 Sparc::D24, Sparc::D25, Sparc::D26, Sparc::D27,
129 Sparc::D28, Sparc::D29, Sparc::D30, Sparc::D31 };
130
Craig Topper92cfdd72015-10-18 05:29:05 +0000131 static const MCPhysReg QuadFPRegs[32] = {
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000132 Sparc::Q0, Sparc::Q1, Sparc::Q2, Sparc::Q3,
133 Sparc::Q4, Sparc::Q5, Sparc::Q6, Sparc::Q7,
Venkatraman Govindaraju98aa7fa2014-01-24 05:24:01 +0000134 Sparc::Q8, Sparc::Q9, Sparc::Q10, Sparc::Q11,
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000135 Sparc::Q12, Sparc::Q13, Sparc::Q14, Sparc::Q15 };
136
Craig Topper92cfdd72015-10-18 05:29:05 +0000137 static const MCPhysReg ASRRegs[32] = {
James Y Knight807563d2015-05-18 16:29:48 +0000138 SP::Y, SP::ASR1, SP::ASR2, SP::ASR3,
139 SP::ASR4, SP::ASR5, SP::ASR6, SP::ASR7,
140 SP::ASR8, SP::ASR9, SP::ASR10, SP::ASR11,
141 SP::ASR12, SP::ASR13, SP::ASR14, SP::ASR15,
142 SP::ASR16, SP::ASR17, SP::ASR18, SP::ASR19,
143 SP::ASR20, SP::ASR21, SP::ASR22, SP::ASR23,
144 SP::ASR24, SP::ASR25, SP::ASR26, SP::ASR27,
145 SP::ASR28, SP::ASR29, SP::ASR30, SP::ASR31};
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000146
Craig Topper92cfdd72015-10-18 05:29:05 +0000147 static const MCPhysReg IntPairRegs[] = {
James Y Knight3994be82015-08-10 19:11:39 +0000148 Sparc::G0_G1, Sparc::G2_G3, Sparc::G4_G5, Sparc::G6_G7,
149 Sparc::O0_O1, Sparc::O2_O3, Sparc::O4_O5, Sparc::O6_O7,
150 Sparc::L0_L1, Sparc::L2_L3, Sparc::L4_L5, Sparc::L6_L7,
151 Sparc::I0_I1, Sparc::I2_I3, Sparc::I4_I5, Sparc::I6_I7};
152
Chris Dewhurst053826a2016-02-27 12:49:59 +0000153 static const MCPhysReg CoprocRegs[32] = {
154 Sparc::C0, Sparc::C1, Sparc::C2, Sparc::C3,
155 Sparc::C4, Sparc::C5, Sparc::C6, Sparc::C7,
156 Sparc::C8, Sparc::C9, Sparc::C10, Sparc::C11,
157 Sparc::C12, Sparc::C13, Sparc::C14, Sparc::C15,
158 Sparc::C16, Sparc::C17, Sparc::C18, Sparc::C19,
159 Sparc::C20, Sparc::C21, Sparc::C22, Sparc::C23,
160 Sparc::C24, Sparc::C25, Sparc::C26, Sparc::C27,
161 Sparc::C28, Sparc::C29, Sparc::C30, Sparc::C31 };
162
163 static const MCPhysReg CoprocPairRegs[] = {
164 Sparc::C0_C1, Sparc::C2_C3, Sparc::C4_C5, Sparc::C6_C7,
165 Sparc::C8_C9, Sparc::C10_C11, Sparc::C12_C13, Sparc::C14_C15,
166 Sparc::C16_C17, Sparc::C18_C19, Sparc::C20_C21, Sparc::C22_C23,
167 Sparc::C24_C25, Sparc::C26_C27, Sparc::C28_C29, Sparc::C30_C31};
168
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000169/// SparcOperand - Instances of this class represent a parsed Sparc machine
170/// instruction.
171class SparcOperand : public MCParsedAsmOperand {
172public:
173 enum RegisterKind {
174 rk_None,
175 rk_IntReg,
James Y Knight3994be82015-08-10 19:11:39 +0000176 rk_IntPairReg,
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000177 rk_FloatReg,
178 rk_DoubleReg,
179 rk_QuadReg,
Chris Dewhurst053826a2016-02-27 12:49:59 +0000180 rk_CoprocReg,
181 rk_CoprocPairReg,
James Y Knightf7e70172015-05-18 16:38:47 +0000182 rk_Special,
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000183 };
James Y Knightf7e70172015-05-18 16:38:47 +0000184
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000185private:
186 enum KindTy {
187 k_Token,
188 k_Register,
189 k_Immediate,
190 k_MemoryReg,
191 k_MemoryImm
192 } Kind;
193
194 SMLoc StartLoc, EndLoc;
195
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000196 struct Token {
197 const char *Data;
198 unsigned Length;
199 };
200
201 struct RegOp {
202 unsigned RegNum;
203 RegisterKind Kind;
204 };
205
206 struct ImmOp {
207 const MCExpr *Val;
208 };
209
210 struct MemOp {
211 unsigned Base;
212 unsigned OffsetReg;
213 const MCExpr *Off;
214 };
215
216 union {
217 struct Token Tok;
218 struct RegOp Reg;
219 struct ImmOp Imm;
220 struct MemOp Mem;
221 };
222public:
David Blaikie960ea3f2014-06-08 16:18:35 +0000223 SparcOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
224
Craig Topperb0c941b2014-04-29 07:57:13 +0000225 bool isToken() const override { return Kind == k_Token; }
226 bool isReg() const override { return Kind == k_Register; }
227 bool isImm() const override { return Kind == k_Immediate; }
228 bool isMem() const override { return isMEMrr() || isMEMri(); }
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000229 bool isMEMrr() const { return Kind == k_MemoryReg; }
230 bool isMEMri() const { return Kind == k_MemoryImm; }
231
James Y Knight3994be82015-08-10 19:11:39 +0000232 bool isIntReg() const {
233 return (Kind == k_Register && Reg.Kind == rk_IntReg);
234 }
235
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000236 bool isFloatReg() const {
237 return (Kind == k_Register && Reg.Kind == rk_FloatReg);
238 }
239
240 bool isFloatOrDoubleReg() const {
241 return (Kind == k_Register && (Reg.Kind == rk_FloatReg
242 || Reg.Kind == rk_DoubleReg));
243 }
244
Chris Dewhurst053826a2016-02-27 12:49:59 +0000245 bool isCoprocReg() const {
246 return (Kind == k_Register && Reg.Kind == rk_CoprocReg);
247 }
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000248
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000249 StringRef getToken() const {
250 assert(Kind == k_Token && "Invalid access!");
251 return StringRef(Tok.Data, Tok.Length);
252 }
253
Craig Topperb0c941b2014-04-29 07:57:13 +0000254 unsigned getReg() const override {
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000255 assert((Kind == k_Register) && "Invalid access!");
256 return Reg.RegNum;
257 }
258
259 const MCExpr *getImm() const {
260 assert((Kind == k_Immediate) && "Invalid access!");
261 return Imm.Val;
262 }
263
264 unsigned getMemBase() const {
265 assert((Kind == k_MemoryReg || Kind == k_MemoryImm) && "Invalid access!");
266 return Mem.Base;
267 }
268
269 unsigned getMemOffsetReg() const {
270 assert((Kind == k_MemoryReg) && "Invalid access!");
271 return Mem.OffsetReg;
272 }
273
274 const MCExpr *getMemOff() const {
275 assert((Kind == k_MemoryImm) && "Invalid access!");
276 return Mem.Off;
277 }
278
279 /// getStartLoc - Get the location of the first token of this operand.
Craig Topperb0c941b2014-04-29 07:57:13 +0000280 SMLoc getStartLoc() const override {
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000281 return StartLoc;
282 }
283 /// getEndLoc - Get the location of the last token of this operand.
Peter Collingbourne0da86302016-10-10 22:49:37 +0000284 SMLoc getEndLoc() const override {
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000285 return EndLoc;
286 }
287
Craig Topperb0c941b2014-04-29 07:57:13 +0000288 void print(raw_ostream &OS) const override {
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000289 switch (Kind) {
290 case k_Token: OS << "Token: " << getToken() << "\n"; break;
291 case k_Register: OS << "Reg: #" << getReg() << "\n"; break;
292 case k_Immediate: OS << "Imm: " << getImm() << "\n"; break;
293 case k_MemoryReg: OS << "Mem: " << getMemBase() << "+"
294 << getMemOffsetReg() << "\n"; break;
Craig Toppere73658d2014-04-28 04:05:08 +0000295 case k_MemoryImm: assert(getMemOff() != nullptr);
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000296 OS << "Mem: " << getMemBase()
297 << "+" << *getMemOff()
298 << "\n"; break;
299 }
300 }
301
302 void addRegOperands(MCInst &Inst, unsigned N) const {
303 assert(N == 1 && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000304 Inst.addOperand(MCOperand::createReg(getReg()));
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000305 }
306
307 void addImmOperands(MCInst &Inst, unsigned N) const {
308 assert(N == 1 && "Invalid number of operands!");
309 const MCExpr *Expr = getImm();
310 addExpr(Inst, Expr);
311 }
312
313 void addExpr(MCInst &Inst, const MCExpr *Expr) const{
314 // Add as immediate when possible. Null MCExpr = 0.
Craig Topper062a2ba2014-04-25 05:30:21 +0000315 if (!Expr)
Jim Grosbache9119e42015-05-13 18:37:00 +0000316 Inst.addOperand(MCOperand::createImm(0));
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000317 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
Jim Grosbache9119e42015-05-13 18:37:00 +0000318 Inst.addOperand(MCOperand::createImm(CE->getValue()));
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000319 else
Jim Grosbache9119e42015-05-13 18:37:00 +0000320 Inst.addOperand(MCOperand::createExpr(Expr));
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000321 }
322
323 void addMEMrrOperands(MCInst &Inst, unsigned N) const {
324 assert(N == 2 && "Invalid number of operands!");
325
Jim Grosbache9119e42015-05-13 18:37:00 +0000326 Inst.addOperand(MCOperand::createReg(getMemBase()));
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000327
328 assert(getMemOffsetReg() != 0 && "Invalid offset");
Jim Grosbache9119e42015-05-13 18:37:00 +0000329 Inst.addOperand(MCOperand::createReg(getMemOffsetReg()));
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000330 }
331
332 void addMEMriOperands(MCInst &Inst, unsigned N) const {
333 assert(N == 2 && "Invalid number of operands!");
334
Jim Grosbache9119e42015-05-13 18:37:00 +0000335 Inst.addOperand(MCOperand::createReg(getMemBase()));
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000336
337 const MCExpr *Expr = getMemOff();
338 addExpr(Inst, Expr);
339 }
340
David Blaikie960ea3f2014-06-08 16:18:35 +0000341 static std::unique_ptr<SparcOperand> CreateToken(StringRef Str, SMLoc S) {
342 auto Op = make_unique<SparcOperand>(k_Token);
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000343 Op->Tok.Data = Str.data();
344 Op->Tok.Length = Str.size();
345 Op->StartLoc = S;
346 Op->EndLoc = S;
347 return Op;
348 }
349
David Blaikie960ea3f2014-06-08 16:18:35 +0000350 static std::unique_ptr<SparcOperand> CreateReg(unsigned RegNum, unsigned Kind,
351 SMLoc S, SMLoc E) {
352 auto Op = make_unique<SparcOperand>(k_Register);
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000353 Op->Reg.RegNum = RegNum;
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000354 Op->Reg.Kind = (SparcOperand::RegisterKind)Kind;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000355 Op->StartLoc = S;
356 Op->EndLoc = E;
357 return Op;
358 }
359
David Blaikie960ea3f2014-06-08 16:18:35 +0000360 static std::unique_ptr<SparcOperand> CreateImm(const MCExpr *Val, SMLoc S,
361 SMLoc E) {
362 auto Op = make_unique<SparcOperand>(k_Immediate);
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000363 Op->Imm.Val = Val;
364 Op->StartLoc = S;
365 Op->EndLoc = E;
366 return Op;
367 }
368
James Y Knight3994be82015-08-10 19:11:39 +0000369 static bool MorphToIntPairReg(SparcOperand &Op) {
370 unsigned Reg = Op.getReg();
371 assert(Op.Reg.Kind == rk_IntReg);
372 unsigned regIdx = 32;
373 if (Reg >= Sparc::G0 && Reg <= Sparc::G7)
374 regIdx = Reg - Sparc::G0;
375 else if (Reg >= Sparc::O0 && Reg <= Sparc::O7)
376 regIdx = Reg - Sparc::O0 + 8;
377 else if (Reg >= Sparc::L0 && Reg <= Sparc::L7)
378 regIdx = Reg - Sparc::L0 + 16;
379 else if (Reg >= Sparc::I0 && Reg <= Sparc::I7)
380 regIdx = Reg - Sparc::I0 + 24;
381 if (regIdx % 2 || regIdx > 31)
382 return false;
383 Op.Reg.RegNum = IntPairRegs[regIdx / 2];
384 Op.Reg.Kind = rk_IntPairReg;
385 return true;
386 }
387
David Blaikie960ea3f2014-06-08 16:18:35 +0000388 static bool MorphToDoubleReg(SparcOperand &Op) {
389 unsigned Reg = Op.getReg();
390 assert(Op.Reg.Kind == rk_FloatReg);
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000391 unsigned regIdx = Reg - Sparc::F0;
392 if (regIdx % 2 || regIdx > 31)
David Blaikie960ea3f2014-06-08 16:18:35 +0000393 return false;
394 Op.Reg.RegNum = DoubleRegs[regIdx / 2];
395 Op.Reg.Kind = rk_DoubleReg;
396 return true;
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000397 }
398
David Blaikie960ea3f2014-06-08 16:18:35 +0000399 static bool MorphToQuadReg(SparcOperand &Op) {
400 unsigned Reg = Op.getReg();
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000401 unsigned regIdx = 0;
David Blaikie960ea3f2014-06-08 16:18:35 +0000402 switch (Op.Reg.Kind) {
Craig Topper2a30d782014-06-18 05:05:13 +0000403 default: llvm_unreachable("Unexpected register kind!");
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000404 case rk_FloatReg:
405 regIdx = Reg - Sparc::F0;
406 if (regIdx % 4 || regIdx > 31)
David Blaikie960ea3f2014-06-08 16:18:35 +0000407 return false;
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000408 Reg = QuadFPRegs[regIdx / 4];
409 break;
410 case rk_DoubleReg:
411 regIdx = Reg - Sparc::D0;
412 if (regIdx % 2 || regIdx > 31)
David Blaikie960ea3f2014-06-08 16:18:35 +0000413 return false;
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000414 Reg = QuadFPRegs[regIdx / 2];
415 break;
416 }
David Blaikie960ea3f2014-06-08 16:18:35 +0000417 Op.Reg.RegNum = Reg;
418 Op.Reg.Kind = rk_QuadReg;
419 return true;
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000420 }
421
Chris Dewhurst053826a2016-02-27 12:49:59 +0000422 static bool MorphToCoprocPairReg(SparcOperand &Op) {
423 unsigned Reg = Op.getReg();
424 assert(Op.Reg.Kind == rk_CoprocReg);
425 unsigned regIdx = 32;
426 if (Reg >= Sparc::C0 && Reg <= Sparc::C31)
427 regIdx = Reg - Sparc::C0;
428 if (regIdx % 2 || regIdx > 31)
429 return false;
430 Op.Reg.RegNum = CoprocPairRegs[regIdx / 2];
431 Op.Reg.Kind = rk_CoprocPairReg;
432 return true;
433 }
434
David Blaikie960ea3f2014-06-08 16:18:35 +0000435 static std::unique_ptr<SparcOperand>
436 MorphToMEMrr(unsigned Base, std::unique_ptr<SparcOperand> Op) {
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000437 unsigned offsetReg = Op->getReg();
438 Op->Kind = k_MemoryReg;
439 Op->Mem.Base = Base;
440 Op->Mem.OffsetReg = offsetReg;
Craig Topper062a2ba2014-04-25 05:30:21 +0000441 Op->Mem.Off = nullptr;
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000442 return Op;
443 }
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000444
David Blaikie960ea3f2014-06-08 16:18:35 +0000445 static std::unique_ptr<SparcOperand>
James Y Knightc09bdfa2015-04-29 14:54:44 +0000446 CreateMEMr(unsigned Base, SMLoc S, SMLoc E) {
447 auto Op = make_unique<SparcOperand>(k_MemoryReg);
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000448 Op->Mem.Base = Base;
James Y Knightc09bdfa2015-04-29 14:54:44 +0000449 Op->Mem.OffsetReg = Sparc::G0; // always 0
450 Op->Mem.Off = nullptr;
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000451 Op->StartLoc = S;
452 Op->EndLoc = E;
453 return Op;
454 }
455
David Blaikie960ea3f2014-06-08 16:18:35 +0000456 static std::unique_ptr<SparcOperand>
457 MorphToMEMri(unsigned Base, std::unique_ptr<SparcOperand> Op) {
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000458 const MCExpr *Imm = Op->getImm();
459 Op->Kind = k_MemoryImm;
460 Op->Mem.Base = Base;
461 Op->Mem.OffsetReg = 0;
462 Op->Mem.Off = Imm;
463 return Op;
464 }
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000465};
466
467} // end namespace
468
Nirav Dave2364748a2016-09-16 18:30:20 +0000469bool SparcAsmParser::expandSET(MCInst &Inst, SMLoc IDLoc,
James Y Knightc49e7882015-05-18 16:43:33 +0000470 SmallVectorImpl<MCInst> &Instructions) {
471 MCOperand MCRegOp = Inst.getOperand(0);
472 MCOperand MCValOp = Inst.getOperand(1);
473 assert(MCRegOp.isReg());
474 assert(MCValOp.isImm() || MCValOp.isExpr());
475
476 // the imm operand can be either an expression or an immediate.
477 bool IsImm = Inst.getOperand(1).isImm();
Douglas Katzman58195a22015-08-20 16:16:16 +0000478 int64_t RawImmValue = IsImm ? MCValOp.getImm() : 0;
479
480 // Allow either a signed or unsigned 32-bit immediate.
NAKAMURA Takumicf61aae2015-08-21 01:12:19 +0000481 if (RawImmValue < -2147483648LL || RawImmValue > 4294967295LL) {
Nirav Dave2364748a2016-09-16 18:30:20 +0000482 return Error(IDLoc,
483 "set: argument must be between -2147483648 and 4294967295");
Douglas Katzman58195a22015-08-20 16:16:16 +0000484 }
485
486 // If the value was expressed as a large unsigned number, that's ok.
487 // We want to see if it "looks like" a small signed number.
488 int32_t ImmValue = RawImmValue;
489 // For 'set' you can't use 'or' with a negative operand on V9 because
490 // that would splat the sign bit across the upper half of the destination
491 // register, whereas 'set' is defined to zero the high 32 bits.
492 bool IsEffectivelyImm13 =
493 IsImm && ((is64Bit() ? 0 : -4096) <= ImmValue && ImmValue < 4096);
James Y Knightc49e7882015-05-18 16:43:33 +0000494 const MCExpr *ValExpr;
495 if (IsImm)
Jim Grosbach13760bd2015-05-30 01:25:56 +0000496 ValExpr = MCConstantExpr::create(ImmValue, getContext());
James Y Knightc49e7882015-05-18 16:43:33 +0000497 else
498 ValExpr = MCValOp.getExpr();
499
500 MCOperand PrevReg = MCOperand::createReg(Sparc::G0);
501
Douglas Katzman58195a22015-08-20 16:16:16 +0000502 // If not just a signed imm13 value, then either we use a 'sethi' with a
503 // following 'or', or a 'sethi' by itself if there are no more 1 bits.
504 // In either case, start with the 'sethi'.
505 if (!IsEffectivelyImm13) {
James Y Knightc49e7882015-05-18 16:43:33 +0000506 MCInst TmpInst;
Joerg Sonnenbergerc8d50d62015-10-01 22:08:20 +0000507 const MCExpr *Expr = adjustPICRelocation(SparcMCExpr::VK_Sparc_HI, ValExpr);
James Y Knightc49e7882015-05-18 16:43:33 +0000508 TmpInst.setLoc(IDLoc);
509 TmpInst.setOpcode(SP::SETHIi);
510 TmpInst.addOperand(MCRegOp);
511 TmpInst.addOperand(MCOperand::createExpr(Expr));
512 Instructions.push_back(TmpInst);
513 PrevReg = MCRegOp;
514 }
515
Douglas Katzman58195a22015-08-20 16:16:16 +0000516 // The low bits require touching in 3 cases:
517 // * A non-immediate value will always require both instructions.
518 // * An effectively imm13 value needs only an 'or' instruction.
519 // * Otherwise, an immediate that is not effectively imm13 requires the
520 // 'or' only if bits remain after clearing the 22 bits that 'sethi' set.
521 // If the low bits are known zeros, there's nothing to do.
522 // In the second case, and only in that case, must we NOT clear
523 // bits of the immediate value via the %lo() assembler function.
524 // Note also, the 'or' instruction doesn't mind a large value in the case
525 // where the operand to 'set' was 0xFFFFFzzz - it does exactly what you mean.
526 if (!IsImm || IsEffectivelyImm13 || (ImmValue & 0x3ff)) {
James Y Knightc49e7882015-05-18 16:43:33 +0000527 MCInst TmpInst;
Douglas Katzman58195a22015-08-20 16:16:16 +0000528 const MCExpr *Expr;
529 if (IsEffectivelyImm13)
530 Expr = ValExpr;
531 else
Joerg Sonnenbergerc8d50d62015-10-01 22:08:20 +0000532 Expr = adjustPICRelocation(SparcMCExpr::VK_Sparc_LO, ValExpr);
James Y Knightc49e7882015-05-18 16:43:33 +0000533 TmpInst.setLoc(IDLoc);
534 TmpInst.setOpcode(SP::ORri);
535 TmpInst.addOperand(MCRegOp);
536 TmpInst.addOperand(PrevReg);
537 TmpInst.addOperand(MCOperand::createExpr(Expr));
538 Instructions.push_back(TmpInst);
539 }
Nirav Dave2364748a2016-09-16 18:30:20 +0000540 return false;
James Y Knightc49e7882015-05-18 16:43:33 +0000541}
542
David Blaikie960ea3f2014-06-08 16:18:35 +0000543bool SparcAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
544 OperandVector &Operands,
545 MCStreamer &Out,
Tim Northover26bb14e2014-08-18 11:49:42 +0000546 uint64_t &ErrorInfo,
David Blaikie960ea3f2014-06-08 16:18:35 +0000547 bool MatchingInlineAsm) {
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000548 MCInst Inst;
549 SmallVector<MCInst, 8> Instructions;
550 unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
551 MatchingInlineAsm);
552 switch (MatchResult) {
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000553 case Match_Success: {
James Y Knightc49e7882015-05-18 16:43:33 +0000554 switch (Inst.getOpcode()) {
555 default:
556 Inst.setLoc(IDLoc);
557 Instructions.push_back(Inst);
558 break;
559 case SP::SET:
Nirav Dave2364748a2016-09-16 18:30:20 +0000560 if (expandSET(Inst, IDLoc, Instructions))
561 return true;
James Y Knightc49e7882015-05-18 16:43:33 +0000562 break;
563 }
564
565 for (const MCInst &I : Instructions) {
Akira Hatanakabd9fc282015-11-14 05:20:05 +0000566 Out.EmitInstruction(I, getSTI());
James Y Knightc49e7882015-05-18 16:43:33 +0000567 }
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000568 return false;
569 }
570
571 case Match_MissingFeature:
572 return Error(IDLoc,
573 "instruction requires a CPU feature not currently enabled");
574
575 case Match_InvalidOperand: {
576 SMLoc ErrorLoc = IDLoc;
Tim Northover26bb14e2014-08-18 11:49:42 +0000577 if (ErrorInfo != ~0ULL) {
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000578 if (ErrorInfo >= Operands.size())
579 return Error(IDLoc, "too few operands for instruction");
580
David Blaikie960ea3f2014-06-08 16:18:35 +0000581 ErrorLoc = ((SparcOperand &)*Operands[ErrorInfo]).getStartLoc();
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000582 if (ErrorLoc == SMLoc())
583 ErrorLoc = IDLoc;
584 }
585
586 return Error(ErrorLoc, "invalid operand for instruction");
587 }
588 case Match_MnemonicFail:
Venkatraman Govindarajue0c5bff2014-03-01 18:54:52 +0000589 return Error(IDLoc, "invalid instruction mnemonic");
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000590 }
Craig Topper589ceee2015-01-03 08:16:34 +0000591 llvm_unreachable("Implement any new match types added!");
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000592}
593
594bool SparcAsmParser::
595ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc)
596{
597 const AsmToken &Tok = Parser.getTok();
598 StartLoc = Tok.getLoc();
599 EndLoc = Tok.getEndLoc();
600 RegNo = 0;
601 if (getLexer().getKind() != AsmToken::Percent)
602 return false;
603 Parser.Lex();
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000604 unsigned regKind = SparcOperand::rk_None;
605 if (matchRegisterName(Tok, RegNo, regKind)) {
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000606 Parser.Lex();
607 return false;
608 }
609
610 return Error(StartLoc, "invalid register name");
611}
612
Ranjeet Singh86ecbb72015-06-30 12:32:53 +0000613static void applyMnemonicAliases(StringRef &Mnemonic, uint64_t Features,
Venkatraman Govindaraju07d3af22014-03-02 22:55:53 +0000614 unsigned VariantID);
615
David Blaikie960ea3f2014-06-08 16:18:35 +0000616bool SparcAsmParser::ParseInstruction(ParseInstructionInfo &Info,
617 StringRef Name, SMLoc NameLoc,
618 OperandVector &Operands) {
Venkatraman Govindarajue0c5bff2014-03-01 18:54:52 +0000619
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000620 // First operand in MCInst is instruction mnemonic.
621 Operands.push_back(SparcOperand::CreateToken(Name, NameLoc));
622
Venkatraman Govindaraju07d3af22014-03-02 22:55:53 +0000623 // apply mnemonic aliases, if any, so that we can parse operands correctly.
624 applyMnemonicAliases(Name, getAvailableFeatures(), 0);
625
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000626 if (getLexer().isNot(AsmToken::EndOfStatement)) {
627 // Read the first operand.
Venkatraman Govindaraju22868742014-03-01 20:08:48 +0000628 if (getLexer().is(AsmToken::Comma)) {
629 if (parseBranchModifiers(Operands) != MatchOperand_Success) {
630 SMLoc Loc = getLexer().getLoc();
Venkatraman Govindaraju22868742014-03-01 20:08:48 +0000631 return Error(Loc, "unexpected token");
632 }
633 }
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000634 if (parseOperand(Operands, Name) != MatchOperand_Success) {
635 SMLoc Loc = getLexer().getLoc();
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000636 return Error(Loc, "unexpected token");
637 }
638
Chris Dewhurst52adb572016-03-09 18:20:21 +0000639 while (getLexer().is(AsmToken::Comma) || getLexer().is(AsmToken::Plus)) {
640 if (getLexer().is(AsmToken::Plus)) {
641 // Plus tokens are significant in software_traps (p83, sparcv8.pdf). We must capture them.
642 Operands.push_back(SparcOperand::CreateToken("+", Parser.getTok().getLoc()));
643 }
644 Parser.Lex(); // Eat the comma or plus.
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000645 // Parse and remember the operand.
646 if (parseOperand(Operands, Name) != MatchOperand_Success) {
647 SMLoc Loc = getLexer().getLoc();
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000648 return Error(Loc, "unexpected token");
649 }
650 }
651 }
652 if (getLexer().isNot(AsmToken::EndOfStatement)) {
653 SMLoc Loc = getLexer().getLoc();
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000654 return Error(Loc, "unexpected token");
655 }
656 Parser.Lex(); // Consume the EndOfStatement.
657 return false;
658}
659
660bool SparcAsmParser::
661ParseDirective(AsmToken DirectiveID)
662{
Venkatraman Govindaraju6f2e08c2014-03-01 02:18:04 +0000663 StringRef IDVal = DirectiveID.getString();
664
665 if (IDVal == ".byte")
666 return parseDirectiveWord(1, DirectiveID.getLoc());
667
668 if (IDVal == ".half")
669 return parseDirectiveWord(2, DirectiveID.getLoc());
670
671 if (IDVal == ".word")
672 return parseDirectiveWord(4, DirectiveID.getLoc());
673
674 if (IDVal == ".nword")
675 return parseDirectiveWord(is64Bit() ? 8 : 4, DirectiveID.getLoc());
676
677 if (is64Bit() && IDVal == ".xword")
678 return parseDirectiveWord(8, DirectiveID.getLoc());
679
680 if (IDVal == ".register") {
681 // For now, ignore .register directive.
682 Parser.eatToEndOfStatement();
683 return false;
684 }
Douglas Katzmand0c11cf2016-03-28 14:00:11 +0000685 if (IDVal == ".proc") {
686 // For compatibility, ignore this directive.
687 // (It's supposed to be an "optimization" in the Sun assembler)
688 Parser.eatToEndOfStatement();
689 return false;
690 }
Venkatraman Govindaraju6f2e08c2014-03-01 02:18:04 +0000691
692 // Let the MC layer to handle other directives.
693 return true;
694}
695
696bool SparcAsmParser:: parseDirectiveWord(unsigned Size, SMLoc L) {
697 if (getLexer().isNot(AsmToken::EndOfStatement)) {
698 for (;;) {
699 const MCExpr *Value;
700 if (getParser().parseExpression(Value))
701 return true;
702
703 getParser().getStreamer().EmitValue(Value, Size);
704
705 if (getLexer().is(AsmToken::EndOfStatement))
706 break;
707
708 // FIXME: Improve diagnostic.
709 if (getLexer().isNot(AsmToken::Comma))
710 return Error(L, "unexpected token in directive");
711 Parser.Lex();
712 }
713 }
714 Parser.Lex();
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000715 return false;
716}
717
Alex Bradbury58eba092016-11-01 16:32:05 +0000718OperandMatchResultTy
David Blaikie960ea3f2014-06-08 16:18:35 +0000719SparcAsmParser::parseMEMOperand(OperandVector &Operands) {
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000720
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000721 SMLoc S, E;
722 unsigned BaseReg = 0;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000723
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000724 if (ParseRegister(BaseReg, S, E)) {
725 return MatchOperand_NoMatch;
726 }
727
728 switch (getLexer().getKind()) {
729 default: return MatchOperand_NoMatch;
730
Venkatraman Govindaraju0d288d32014-01-10 01:48:17 +0000731 case AsmToken::Comma:
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000732 case AsmToken::RBrac:
733 case AsmToken::EndOfStatement:
James Y Knightc09bdfa2015-04-29 14:54:44 +0000734 Operands.push_back(SparcOperand::CreateMEMr(BaseReg, S, E));
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000735 return MatchOperand_Success;
736
737 case AsmToken:: Plus:
738 Parser.Lex(); // Eat the '+'
739 break;
740 case AsmToken::Minus:
741 break;
742 }
743
David Blaikie960ea3f2014-06-08 16:18:35 +0000744 std::unique_ptr<SparcOperand> Offset;
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000745 OperandMatchResultTy ResTy = parseSparcAsmOperand(Offset);
746 if (ResTy != MatchOperand_Success || !Offset)
747 return MatchOperand_NoMatch;
748
David Blaikie960ea3f2014-06-08 16:18:35 +0000749 Operands.push_back(
750 Offset->isImm() ? SparcOperand::MorphToMEMri(BaseReg, std::move(Offset))
751 : SparcOperand::MorphToMEMrr(BaseReg, std::move(Offset)));
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000752
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000753 return MatchOperand_Success;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000754}
755
Alex Bradbury58eba092016-11-01 16:32:05 +0000756OperandMatchResultTy
David Blaikie960ea3f2014-06-08 16:18:35 +0000757SparcAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000758
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000759 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000760
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000761 // If there wasn't a custom match, try the generic matcher below. Otherwise,
762 // there was a match, but an error occurred, in which case, just return that
763 // the operand parsing failed.
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000764 if (ResTy == MatchOperand_Success || ResTy == MatchOperand_ParseFail)
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000765 return ResTy;
766
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000767 if (getLexer().is(AsmToken::LBrac)) {
768 // Memory operand
769 Operands.push_back(SparcOperand::CreateToken("[",
770 Parser.getTok().getLoc()));
771 Parser.Lex(); // Eat the [
772
Chris Dewhurst7d8412f2016-05-16 11:02:00 +0000773 if (Mnemonic == "cas" || Mnemonic == "casx" || Mnemonic == "casa") {
Venkatraman Govindarajuced92262014-02-07 07:34:49 +0000774 SMLoc S = Parser.getTok().getLoc();
775 if (getLexer().getKind() != AsmToken::Percent)
776 return MatchOperand_NoMatch;
777 Parser.Lex(); // eat %
778
779 unsigned RegNo, RegKind;
780 if (!matchRegisterName(Parser.getTok(), RegNo, RegKind))
781 return MatchOperand_NoMatch;
782
783 Parser.Lex(); // Eat the identifier token.
784 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer()-1);
785 Operands.push_back(SparcOperand::CreateReg(RegNo, RegKind, S, E));
786 ResTy = MatchOperand_Success;
787 } else {
788 ResTy = parseMEMOperand(Operands);
789 }
790
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000791 if (ResTy != MatchOperand_Success)
792 return ResTy;
793
794 if (!getLexer().is(AsmToken::RBrac))
795 return MatchOperand_ParseFail;
796
797 Operands.push_back(SparcOperand::CreateToken("]",
798 Parser.getTok().getLoc()));
799 Parser.Lex(); // Eat the ]
James Y Knight24060be2015-05-18 16:35:04 +0000800
801 // Parse an optional address-space identifier after the address.
802 if (getLexer().is(AsmToken::Integer)) {
803 std::unique_ptr<SparcOperand> Op;
804 ResTy = parseSparcAsmOperand(Op, false);
805 if (ResTy != MatchOperand_Success || !Op)
806 return MatchOperand_ParseFail;
807 Operands.push_back(std::move(Op));
808 }
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000809 return MatchOperand_Success;
810 }
811
David Blaikie960ea3f2014-06-08 16:18:35 +0000812 std::unique_ptr<SparcOperand> Op;
Venkatraman Govindaraju81aae572014-03-02 03:39:39 +0000813
Venkatraman Govindaraju600f3902014-03-02 06:28:15 +0000814 ResTy = parseSparcAsmOperand(Op, (Mnemonic == "call"));
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000815 if (ResTy != MatchOperand_Success || !Op)
816 return MatchOperand_ParseFail;
817
818 // Push the parsed operand into the list of operands
David Blaikie960ea3f2014-06-08 16:18:35 +0000819 Operands.push_back(std::move(Op));
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000820
821 return MatchOperand_Success;
822}
823
Alex Bradbury58eba092016-11-01 16:32:05 +0000824OperandMatchResultTy
David Blaikie960ea3f2014-06-08 16:18:35 +0000825SparcAsmParser::parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Op,
826 bool isCall) {
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000827
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000828 SMLoc S = Parser.getTok().getLoc();
829 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
830 const MCExpr *EVal;
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000831
Craig Topper062a2ba2014-04-25 05:30:21 +0000832 Op = nullptr;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000833 switch (getLexer().getKind()) {
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000834 default: break;
835
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000836 case AsmToken::Percent:
837 Parser.Lex(); // Eat the '%'.
838 unsigned RegNo;
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000839 unsigned RegKind;
840 if (matchRegisterName(Parser.getTok(), RegNo, RegKind)) {
Venkatraman Govindarajub3b7c382014-01-08 06:14:52 +0000841 StringRef name = Parser.getTok().getString();
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000842 Parser.Lex(); // Eat the identifier token.
Venkatraman Govindaraju559c4ac2014-01-07 08:00:49 +0000843 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Venkatraman Govindarajub3b7c382014-01-08 06:14:52 +0000844 switch (RegNo) {
845 default:
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000846 Op = SparcOperand::CreateReg(RegNo, RegKind, S, E);
Venkatraman Govindarajub3b7c382014-01-08 06:14:52 +0000847 break;
James Y Knightf7e70172015-05-18 16:38:47 +0000848 case Sparc::PSR:
849 Op = SparcOperand::CreateToken("%psr", S);
850 break;
Douglas Katzmane5485c62015-08-19 18:34:48 +0000851 case Sparc::FSR:
852 Op = SparcOperand::CreateToken("%fsr", S);
853 break;
Chris Dewhurst053826a2016-02-27 12:49:59 +0000854 case Sparc::FQ:
855 Op = SparcOperand::CreateToken("%fq", S);
856 break;
857 case Sparc::CPSR:
858 Op = SparcOperand::CreateToken("%csr", S);
859 break;
860 case Sparc::CPQ:
861 Op = SparcOperand::CreateToken("%cq", S);
862 break;
James Y Knightf7e70172015-05-18 16:38:47 +0000863 case Sparc::WIM:
864 Op = SparcOperand::CreateToken("%wim", S);
865 break;
866 case Sparc::TBR:
867 Op = SparcOperand::CreateToken("%tbr", S);
868 break;
Venkatraman Govindarajub3b7c382014-01-08 06:14:52 +0000869 case Sparc::ICC:
870 if (name == "xcc")
871 Op = SparcOperand::CreateToken("%xcc", S);
872 else
873 Op = SparcOperand::CreateToken("%icc", S);
874 break;
Venkatraman Govindarajub3b7c382014-01-08 06:14:52 +0000875 }
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000876 break;
877 }
Venkatraman Govindaraju559c4ac2014-01-07 08:00:49 +0000878 if (matchSparcAsmModifiers(EVal, E)) {
879 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
880 Op = SparcOperand::CreateImm(EVal, S, E);
881 }
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000882 break;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000883
884 case AsmToken::Minus:
885 case AsmToken::Integer:
Douglas Katzman9cb88b72015-04-29 18:48:29 +0000886 case AsmToken::LParen:
Douglas Katzman685a7d12015-08-17 19:55:01 +0000887 case AsmToken::Dot:
Venkatraman Govindaraju559c4ac2014-01-07 08:00:49 +0000888 if (!getParser().parseExpression(EVal, E))
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000889 Op = SparcOperand::CreateImm(EVal, S, E);
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000890 break;
891
892 case AsmToken::Identifier: {
893 StringRef Identifier;
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000894 if (!getParser().parseIdentifier(Identifier)) {
Venkatraman Govindaraju559c4ac2014-01-07 08:00:49 +0000895 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Jim Grosbach6f482002015-05-18 18:43:14 +0000896 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000897
Jim Grosbach13760bd2015-05-30 01:25:56 +0000898 const MCExpr *Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None,
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000899 getContext());
Rafael Espindola699281c2016-05-18 11:58:50 +0000900 if (isCall && getContext().getObjectFileInfo()->isPositionIndependent())
Jim Grosbach13760bd2015-05-30 01:25:56 +0000901 Res = SparcMCExpr::create(SparcMCExpr::VK_Sparc_WPLT30, Res,
Venkatraman Govindaraju9fc29092014-03-01 05:07:21 +0000902 getContext());
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000903 Op = SparcOperand::CreateImm(Res, S, E);
904 }
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000905 break;
906 }
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000907 }
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000908 return (Op) ? MatchOperand_Success : MatchOperand_ParseFail;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000909}
910
Alex Bradbury58eba092016-11-01 16:32:05 +0000911OperandMatchResultTy
David Blaikie960ea3f2014-06-08 16:18:35 +0000912SparcAsmParser::parseBranchModifiers(OperandVector &Operands) {
Venkatraman Govindaraju22868742014-03-01 20:08:48 +0000913
914 // parse (,a|,pn|,pt)+
915
916 while (getLexer().is(AsmToken::Comma)) {
917
918 Parser.Lex(); // Eat the comma
919
920 if (!getLexer().is(AsmToken::Identifier))
921 return MatchOperand_ParseFail;
922 StringRef modName = Parser.getTok().getString();
923 if (modName == "a" || modName == "pn" || modName == "pt") {
924 Operands.push_back(SparcOperand::CreateToken(modName,
925 Parser.getTok().getLoc()));
926 Parser.Lex(); // eat the identifier.
927 }
928 }
929 return MatchOperand_Success;
930}
931
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000932bool SparcAsmParser::matchRegisterName(const AsmToken &Tok,
933 unsigned &RegNo,
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000934 unsigned &RegKind)
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000935{
936 int64_t intVal = 0;
937 RegNo = 0;
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000938 RegKind = SparcOperand::rk_None;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000939 if (Tok.is(AsmToken::Identifier)) {
940 StringRef name = Tok.getString();
941
942 // %fp
943 if (name.equals("fp")) {
944 RegNo = Sparc::I6;
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000945 RegKind = SparcOperand::rk_IntReg;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000946 return true;
947 }
948 // %sp
949 if (name.equals("sp")) {
950 RegNo = Sparc::O6;
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000951 RegKind = SparcOperand::rk_IntReg;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000952 return true;
953 }
954
955 if (name.equals("y")) {
956 RegNo = Sparc::Y;
James Y Knightf7e70172015-05-18 16:38:47 +0000957 RegKind = SparcOperand::rk_Special;
James Y Knight807563d2015-05-18 16:29:48 +0000958 return true;
959 }
960
961 if (name.substr(0, 3).equals_lower("asr")
962 && !name.substr(3).getAsInteger(10, intVal)
963 && intVal > 0 && intVal < 32) {
964 RegNo = ASRRegs[intVal];
James Y Knightf7e70172015-05-18 16:38:47 +0000965 RegKind = SparcOperand::rk_Special;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000966 return true;
967 }
968
Joerg Sonnenberger7d180c52015-08-19 13:55:14 +0000969 // %fprs is an alias of %asr6.
970 if (name.equals("fprs")) {
971 RegNo = ASRRegs[6];
972 RegKind = SparcOperand::rk_Special;
973 return true;
974 }
975
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000976 if (name.equals("icc")) {
977 RegNo = Sparc::ICC;
James Y Knightf7e70172015-05-18 16:38:47 +0000978 RegKind = SparcOperand::rk_Special;
979 return true;
980 }
981
982 if (name.equals("psr")) {
983 RegNo = Sparc::PSR;
984 RegKind = SparcOperand::rk_Special;
985 return true;
986 }
987
Douglas Katzmane5485c62015-08-19 18:34:48 +0000988 if (name.equals("fsr")) {
989 RegNo = Sparc::FSR;
990 RegKind = SparcOperand::rk_Special;
991 return true;
992 }
993
Chris Dewhurst053826a2016-02-27 12:49:59 +0000994 if (name.equals("fq")) {
995 RegNo = Sparc::FQ;
996 RegKind = SparcOperand::rk_Special;
997 return true;
998 }
999
1000 if (name.equals("csr")) {
1001 RegNo = Sparc::CPSR;
1002 RegKind = SparcOperand::rk_Special;
1003 return true;
1004 }
1005
1006 if (name.equals("cq")) {
1007 RegNo = Sparc::CPQ;
1008 RegKind = SparcOperand::rk_Special;
1009 return true;
1010 }
1011
James Y Knightf7e70172015-05-18 16:38:47 +00001012 if (name.equals("wim")) {
1013 RegNo = Sparc::WIM;
1014 RegKind = SparcOperand::rk_Special;
1015 return true;
1016 }
1017
1018 if (name.equals("tbr")) {
1019 RegNo = Sparc::TBR;
1020 RegKind = SparcOperand::rk_Special;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +00001021 return true;
1022 }
1023
1024 if (name.equals("xcc")) {
1025 // FIXME:: check 64bit.
1026 RegNo = Sparc::ICC;
James Y Knightf7e70172015-05-18 16:38:47 +00001027 RegKind = SparcOperand::rk_Special;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +00001028 return true;
1029 }
1030
1031 // %fcc0 - %fcc3
1032 if (name.substr(0, 3).equals_lower("fcc")
1033 && !name.substr(3).getAsInteger(10, intVal)
1034 && intVal < 4) {
1035 // FIXME: check 64bit and handle %fcc1 - %fcc3
Venkatraman Govindaraju81aae572014-03-02 03:39:39 +00001036 RegNo = Sparc::FCC0 + intVal;
James Y Knightf7e70172015-05-18 16:38:47 +00001037 RegKind = SparcOperand::rk_Special;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +00001038 return true;
1039 }
1040
1041 // %g0 - %g7
1042 if (name.substr(0, 1).equals_lower("g")
1043 && !name.substr(1).getAsInteger(10, intVal)
1044 && intVal < 8) {
1045 RegNo = IntRegs[intVal];
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +00001046 RegKind = SparcOperand::rk_IntReg;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +00001047 return true;
1048 }
1049 // %o0 - %o7
1050 if (name.substr(0, 1).equals_lower("o")
1051 && !name.substr(1).getAsInteger(10, intVal)
1052 && intVal < 8) {
1053 RegNo = IntRegs[8 + intVal];
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +00001054 RegKind = SparcOperand::rk_IntReg;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +00001055 return true;
1056 }
1057 if (name.substr(0, 1).equals_lower("l")
1058 && !name.substr(1).getAsInteger(10, intVal)
1059 && intVal < 8) {
1060 RegNo = IntRegs[16 + intVal];
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +00001061 RegKind = SparcOperand::rk_IntReg;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +00001062 return true;
1063 }
1064 if (name.substr(0, 1).equals_lower("i")
1065 && !name.substr(1).getAsInteger(10, intVal)
1066 && intVal < 8) {
1067 RegNo = IntRegs[24 + intVal];
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +00001068 RegKind = SparcOperand::rk_IntReg;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +00001069 return true;
1070 }
1071 // %f0 - %f31
1072 if (name.substr(0, 1).equals_lower("f")
1073 && !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 32) {
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +00001074 RegNo = FloatRegs[intVal];
1075 RegKind = SparcOperand::rk_FloatReg;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +00001076 return true;
1077 }
1078 // %f32 - %f62
1079 if (name.substr(0, 1).equals_lower("f")
1080 && !name.substr(1, 2).getAsInteger(10, intVal)
1081 && intVal >= 32 && intVal <= 62 && (intVal % 2 == 0)) {
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +00001082 // FIXME: Check V9
Eric Christopher7383d4a2014-01-23 21:41:10 +00001083 RegNo = DoubleRegs[intVal/2];
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +00001084 RegKind = SparcOperand::rk_DoubleReg;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +00001085 return true;
1086 }
1087
1088 // %r0 - %r31
1089 if (name.substr(0, 1).equals_lower("r")
1090 && !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 31) {
1091 RegNo = IntRegs[intVal];
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +00001092 RegKind = SparcOperand::rk_IntReg;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +00001093 return true;
1094 }
Joerg Sonnenberger726e6242015-10-04 09:11:22 +00001095
Chris Dewhurst053826a2016-02-27 12:49:59 +00001096 // %c0 - %c31
1097 if (name.substr(0, 1).equals_lower("c")
1098 && !name.substr(1).getAsInteger(10, intVal)
1099 && intVal < 32) {
1100 RegNo = CoprocRegs[intVal];
1101 RegKind = SparcOperand::rk_CoprocReg;
1102 return true;
1103 }
1104
Joerg Sonnenberger726e6242015-10-04 09:11:22 +00001105 if (name.equals("tpc")) {
1106 RegNo = Sparc::TPC;
1107 RegKind = SparcOperand::rk_Special;
1108 return true;
1109 }
1110 if (name.equals("tnpc")) {
1111 RegNo = Sparc::TNPC;
1112 RegKind = SparcOperand::rk_Special;
1113 return true;
1114 }
1115 if (name.equals("tstate")) {
1116 RegNo = Sparc::TSTATE;
1117 RegKind = SparcOperand::rk_Special;
1118 return true;
1119 }
1120 if (name.equals("tt")) {
1121 RegNo = Sparc::TT;
1122 RegKind = SparcOperand::rk_Special;
1123 return true;
1124 }
1125 if (name.equals("tick")) {
1126 RegNo = Sparc::TICK;
1127 RegKind = SparcOperand::rk_Special;
1128 return true;
1129 }
1130 if (name.equals("tba")) {
1131 RegNo = Sparc::TBA;
1132 RegKind = SparcOperand::rk_Special;
1133 return true;
1134 }
1135 if (name.equals("pstate")) {
1136 RegNo = Sparc::PSTATE;
1137 RegKind = SparcOperand::rk_Special;
1138 return true;
1139 }
1140 if (name.equals("tl")) {
1141 RegNo = Sparc::TL;
1142 RegKind = SparcOperand::rk_Special;
1143 return true;
1144 }
1145 if (name.equals("pil")) {
1146 RegNo = Sparc::PIL;
1147 RegKind = SparcOperand::rk_Special;
1148 return true;
1149 }
1150 if (name.equals("cwp")) {
1151 RegNo = Sparc::CWP;
1152 RegKind = SparcOperand::rk_Special;
1153 return true;
1154 }
1155 if (name.equals("cansave")) {
1156 RegNo = Sparc::CANSAVE;
1157 RegKind = SparcOperand::rk_Special;
1158 return true;
1159 }
1160 if (name.equals("canrestore")) {
1161 RegNo = Sparc::CANRESTORE;
1162 RegKind = SparcOperand::rk_Special;
1163 return true;
1164 }
1165 if (name.equals("cleanwin")) {
1166 RegNo = Sparc::CLEANWIN;
1167 RegKind = SparcOperand::rk_Special;
1168 return true;
1169 }
1170 if (name.equals("otherwin")) {
1171 RegNo = Sparc::OTHERWIN;
1172 RegKind = SparcOperand::rk_Special;
1173 return true;
1174 }
1175 if (name.equals("wstate")) {
1176 RegNo = Sparc::WSTATE;
1177 RegKind = SparcOperand::rk_Special;
1178 return true;
1179 }
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +00001180 }
1181 return false;
1182}
1183
James Y Knightf90346f2015-06-18 15:05:15 +00001184// Determine if an expression contains a reference to the symbol
1185// "_GLOBAL_OFFSET_TABLE_".
Venkatraman Govindaraju9fc29092014-03-01 05:07:21 +00001186static bool hasGOTReference(const MCExpr *Expr) {
1187 switch (Expr->getKind()) {
1188 case MCExpr::Target:
1189 if (const SparcMCExpr *SE = dyn_cast<SparcMCExpr>(Expr))
1190 return hasGOTReference(SE->getSubExpr());
1191 break;
1192
1193 case MCExpr::Constant:
1194 break;
1195
1196 case MCExpr::Binary: {
1197 const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);
1198 return hasGOTReference(BE->getLHS()) || hasGOTReference(BE->getRHS());
1199 }
1200
1201 case MCExpr::SymbolRef: {
1202 const MCSymbolRefExpr &SymRef = *cast<MCSymbolRefExpr>(Expr);
1203 return (SymRef.getSymbol().getName() == "_GLOBAL_OFFSET_TABLE_");
1204 }
1205
1206 case MCExpr::Unary:
1207 return hasGOTReference(cast<MCUnaryExpr>(Expr)->getSubExpr());
1208 }
1209 return false;
1210}
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +00001211
Joerg Sonnenbergerc8d50d62015-10-01 22:08:20 +00001212const SparcMCExpr *
1213SparcAsmParser::adjustPICRelocation(SparcMCExpr::VariantKind VK,
1214 const MCExpr *subExpr)
1215{
1216 // When in PIC mode, "%lo(...)" and "%hi(...)" behave differently.
1217 // If the expression refers contains _GLOBAL_OFFSETE_TABLE, it is
1218 // actually a %pc10 or %pc22 relocation. Otherwise, they are interpreted
1219 // as %got10 or %got22 relocation.
1220
Rafael Espindola699281c2016-05-18 11:58:50 +00001221 if (getContext().getObjectFileInfo()->isPositionIndependent()) {
Joerg Sonnenbergerc8d50d62015-10-01 22:08:20 +00001222 switch(VK) {
1223 default: break;
1224 case SparcMCExpr::VK_Sparc_LO:
1225 VK = (hasGOTReference(subExpr) ? SparcMCExpr::VK_Sparc_PC10
1226 : SparcMCExpr::VK_Sparc_GOT10);
1227 break;
1228 case SparcMCExpr::VK_Sparc_HI:
1229 VK = (hasGOTReference(subExpr) ? SparcMCExpr::VK_Sparc_PC22
1230 : SparcMCExpr::VK_Sparc_GOT22);
1231 break;
1232 }
1233 }
1234
1235 return SparcMCExpr::create(VK, subExpr, getContext());
1236}
1237
Venkatraman Govindaraju559c4ac2014-01-07 08:00:49 +00001238bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal,
1239 SMLoc &EndLoc)
1240{
1241 AsmToken Tok = Parser.getTok();
1242 if (!Tok.is(AsmToken::Identifier))
1243 return false;
1244
1245 StringRef name = Tok.getString();
1246
1247 SparcMCExpr::VariantKind VK = SparcMCExpr::parseVariantKind(name);
1248
1249 if (VK == SparcMCExpr::VK_Sparc_None)
1250 return false;
1251
1252 Parser.Lex(); // Eat the identifier.
1253 if (Parser.getTok().getKind() != AsmToken::LParen)
1254 return false;
1255
1256 Parser.Lex(); // Eat the LParen token.
1257 const MCExpr *subExpr;
1258 if (Parser.parseParenExpression(subExpr, EndLoc))
1259 return false;
Venkatraman Govindaraju9fc29092014-03-01 05:07:21 +00001260
Joerg Sonnenbergerc8d50d62015-10-01 22:08:20 +00001261 EVal = adjustPICRelocation(VK, subExpr);
Venkatraman Govindaraju559c4ac2014-01-07 08:00:49 +00001262 return true;
1263}
1264
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +00001265extern "C" void LLVMInitializeSparcAsmParser() {
Mehdi Aminif42454b2016-10-09 23:00:34 +00001266 RegisterMCAsmParser<SparcAsmParser> A(getTheSparcTarget());
1267 RegisterMCAsmParser<SparcAsmParser> B(getTheSparcV9Target());
1268 RegisterMCAsmParser<SparcAsmParser> C(getTheSparcelTarget());
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +00001269}
1270
1271#define GET_REGISTER_MATCHER
1272#define GET_MATCHER_IMPLEMENTATION
1273#include "SparcGenAsmMatcher.inc"
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +00001274
David Blaikie960ea3f2014-06-08 16:18:35 +00001275unsigned SparcAsmParser::validateTargetOperandClass(MCParsedAsmOperand &GOp,
1276 unsigned Kind) {
1277 SparcOperand &Op = (SparcOperand &)GOp;
1278 if (Op.isFloatOrDoubleReg()) {
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +00001279 switch (Kind) {
1280 default: break;
1281 case MCK_DFPRegs:
David Blaikie960ea3f2014-06-08 16:18:35 +00001282 if (!Op.isFloatReg() || SparcOperand::MorphToDoubleReg(Op))
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +00001283 return MCTargetAsmParser::Match_Success;
1284 break;
1285 case MCK_QFPRegs:
1286 if (SparcOperand::MorphToQuadReg(Op))
1287 return MCTargetAsmParser::Match_Success;
1288 break;
1289 }
1290 }
James Y Knight3994be82015-08-10 19:11:39 +00001291 if (Op.isIntReg() && Kind == MCK_IntPair) {
1292 if (SparcOperand::MorphToIntPairReg(Op))
1293 return MCTargetAsmParser::Match_Success;
1294 }
Chris Dewhurst053826a2016-02-27 12:49:59 +00001295 if (Op.isCoprocReg() && Kind == MCK_CoprocPair) {
1296 if (SparcOperand::MorphToCoprocPairReg(Op))
1297 return MCTargetAsmParser::Match_Success;
1298 }
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +00001299 return Match_InvalidOperand;
1300}