blob: 07758894775c0e4e1f3ff61760b4b2b93e3d7509 [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
10#include "MCTargetDesc/SparcMCTargetDesc.h"
Venkatraman Govindaraju559c4ac2014-01-07 08:00:49 +000011#include "MCTargetDesc/SparcMCExpr.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"
15#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
16#include "llvm/MC/MCStreamer.h"
17#include "llvm/MC/MCSubtargetInfo.h"
18#include "llvm/MC/MCTargetAsmParser.h"
19#include "llvm/Support/TargetRegistry.h"
20
21using namespace llvm;
22
23// The generated AsmMatcher SparcGenAsmMatcher uses "Sparc" as the target
24// namespace. But SPARC backend uses "SP" as its namespace.
25namespace llvm {
26 namespace Sparc {
27 using namespace SP;
28 }
29}
30
31namespace {
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +000032class SparcOperand;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +000033class SparcAsmParser : public MCTargetAsmParser {
34
35 MCSubtargetInfo &STI;
36 MCAsmParser &Parser;
37
38 /// @name Auto-generated Match Functions
39 /// {
40
41#define GET_ASSEMBLER_HEADER
42#include "SparcGenAsmMatcher.inc"
43
44 /// }
45
46 // public interface of the MCTargetAsmParser.
47 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
48 SmallVectorImpl<MCParsedAsmOperand*> &Operands,
49 MCStreamer &Out, unsigned &ErrorInfo,
50 bool MatchingInlineAsm);
51 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
52 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
53 SMLoc NameLoc,
54 SmallVectorImpl<MCParsedAsmOperand*> &Operands);
55 bool ParseDirective(AsmToken DirectiveID);
56
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +000057 virtual unsigned validateTargetOperandClass(MCParsedAsmOperand *Op,
58 unsigned Kind);
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +000059
60 // Custom parse functions for Sparc specific operands.
61 OperandMatchResultTy
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +000062 parseMEMOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +000063
64 OperandMatchResultTy
65 parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
66 StringRef Name);
67
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +000068 OperandMatchResultTy
69 parseSparcAsmOperand(SparcOperand *&Operand);
70
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +000071 // returns true if Tok is matched to a register and returns register in RegNo.
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +000072 bool matchRegisterName(const AsmToken &Tok, unsigned &RegNo,
73 unsigned &RegKind);
74
Venkatraman Govindaraju559c4ac2014-01-07 08:00:49 +000075 bool matchSparcAsmModifiers(const MCExpr *&EVal, SMLoc &EndLoc);
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +000076
77public:
78 SparcAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
79 const MCInstrInfo &MII)
80 : MCTargetAsmParser(), STI(sti), Parser(parser) {
81 // Initialize the set of available features.
82 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
83 }
84
85};
86
87 static unsigned IntRegs[32] = {
88 Sparc::G0, Sparc::G1, Sparc::G2, Sparc::G3,
89 Sparc::G4, Sparc::G5, Sparc::G6, Sparc::G7,
90 Sparc::O0, Sparc::O1, Sparc::O2, Sparc::O3,
91 Sparc::O4, Sparc::O5, Sparc::O6, Sparc::O7,
92 Sparc::L0, Sparc::L1, Sparc::L2, Sparc::L3,
93 Sparc::L4, Sparc::L5, Sparc::L6, Sparc::L7,
94 Sparc::I0, Sparc::I1, Sparc::I2, Sparc::I3,
95 Sparc::I4, Sparc::I5, Sparc::I6, Sparc::I7 };
96
97 static unsigned FloatRegs[32] = {
98 Sparc::F0, Sparc::F1, Sparc::F2, Sparc::F3,
99 Sparc::F4, Sparc::F5, Sparc::F6, Sparc::F7,
100 Sparc::F8, Sparc::F9, Sparc::F10, Sparc::F11,
101 Sparc::F12, Sparc::F13, Sparc::F14, Sparc::F15,
102 Sparc::F16, Sparc::F17, Sparc::F18, Sparc::F19,
103 Sparc::F20, Sparc::F21, Sparc::F22, Sparc::F23,
104 Sparc::F24, Sparc::F25, Sparc::F26, Sparc::F27,
105 Sparc::F28, Sparc::F29, Sparc::F30, Sparc::F31 };
106
107 static unsigned DoubleRegs[32] = {
108 Sparc::D0, Sparc::D1, Sparc::D2, Sparc::D3,
109 Sparc::D4, Sparc::D5, Sparc::D6, Sparc::D7,
110 Sparc::D8, Sparc::D7, Sparc::D8, Sparc::D9,
111 Sparc::D12, Sparc::D13, Sparc::D14, Sparc::D15,
112 Sparc::D16, Sparc::D17, Sparc::D18, Sparc::D19,
113 Sparc::D20, Sparc::D21, Sparc::D22, Sparc::D23,
114 Sparc::D24, Sparc::D25, Sparc::D26, Sparc::D27,
115 Sparc::D28, Sparc::D29, Sparc::D30, Sparc::D31 };
116
117 static unsigned QuadFPRegs[32] = {
118 Sparc::Q0, Sparc::Q1, Sparc::Q2, Sparc::Q3,
119 Sparc::Q4, Sparc::Q5, Sparc::Q6, Sparc::Q7,
120 Sparc::Q8, Sparc::Q7, Sparc::Q8, Sparc::Q9,
121 Sparc::Q12, Sparc::Q13, Sparc::Q14, Sparc::Q15 };
122
123
124/// SparcOperand - Instances of this class represent a parsed Sparc machine
125/// instruction.
126class SparcOperand : public MCParsedAsmOperand {
127public:
128 enum RegisterKind {
129 rk_None,
130 rk_IntReg,
131 rk_FloatReg,
132 rk_DoubleReg,
133 rk_QuadReg,
134 rk_CCReg,
135 rk_Y
136 };
137private:
138 enum KindTy {
139 k_Token,
140 k_Register,
141 k_Immediate,
142 k_MemoryReg,
143 k_MemoryImm
144 } Kind;
145
146 SMLoc StartLoc, EndLoc;
147
148 SparcOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
149
150 struct Token {
151 const char *Data;
152 unsigned Length;
153 };
154
155 struct RegOp {
156 unsigned RegNum;
157 RegisterKind Kind;
158 };
159
160 struct ImmOp {
161 const MCExpr *Val;
162 };
163
164 struct MemOp {
165 unsigned Base;
166 unsigned OffsetReg;
167 const MCExpr *Off;
168 };
169
170 union {
171 struct Token Tok;
172 struct RegOp Reg;
173 struct ImmOp Imm;
174 struct MemOp Mem;
175 };
176public:
177 bool isToken() const { return Kind == k_Token; }
178 bool isReg() const { return Kind == k_Register; }
179 bool isImm() const { return Kind == k_Immediate; }
180 bool isMem() const { return isMEMrr() || isMEMri(); }
181 bool isMEMrr() const { return Kind == k_MemoryReg; }
182 bool isMEMri() const { return Kind == k_MemoryImm; }
183
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000184 bool isFloatReg() const {
185 return (Kind == k_Register && Reg.Kind == rk_FloatReg);
186 }
187
188 bool isFloatOrDoubleReg() const {
189 return (Kind == k_Register && (Reg.Kind == rk_FloatReg
190 || Reg.Kind == rk_DoubleReg));
191 }
192
193
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000194 StringRef getToken() const {
195 assert(Kind == k_Token && "Invalid access!");
196 return StringRef(Tok.Data, Tok.Length);
197 }
198
199 unsigned getReg() const {
200 assert((Kind == k_Register) && "Invalid access!");
201 return Reg.RegNum;
202 }
203
204 const MCExpr *getImm() const {
205 assert((Kind == k_Immediate) && "Invalid access!");
206 return Imm.Val;
207 }
208
209 unsigned getMemBase() const {
210 assert((Kind == k_MemoryReg || Kind == k_MemoryImm) && "Invalid access!");
211 return Mem.Base;
212 }
213
214 unsigned getMemOffsetReg() const {
215 assert((Kind == k_MemoryReg) && "Invalid access!");
216 return Mem.OffsetReg;
217 }
218
219 const MCExpr *getMemOff() const {
220 assert((Kind == k_MemoryImm) && "Invalid access!");
221 return Mem.Off;
222 }
223
224 /// getStartLoc - Get the location of the first token of this operand.
225 SMLoc getStartLoc() const {
226 return StartLoc;
227 }
228 /// getEndLoc - Get the location of the last token of this operand.
229 SMLoc getEndLoc() const {
230 return EndLoc;
231 }
232
233 virtual void print(raw_ostream &OS) const {
234 switch (Kind) {
235 case k_Token: OS << "Token: " << getToken() << "\n"; break;
236 case k_Register: OS << "Reg: #" << getReg() << "\n"; break;
237 case k_Immediate: OS << "Imm: " << getImm() << "\n"; break;
238 case k_MemoryReg: OS << "Mem: " << getMemBase() << "+"
239 << getMemOffsetReg() << "\n"; break;
240 case k_MemoryImm: assert(getMemOff() != 0);
241 OS << "Mem: " << getMemBase()
242 << "+" << *getMemOff()
243 << "\n"; break;
244 }
245 }
246
247 void addRegOperands(MCInst &Inst, unsigned N) const {
248 assert(N == 1 && "Invalid number of operands!");
249 Inst.addOperand(MCOperand::CreateReg(getReg()));
250 }
251
252 void addImmOperands(MCInst &Inst, unsigned N) const {
253 assert(N == 1 && "Invalid number of operands!");
254 const MCExpr *Expr = getImm();
255 addExpr(Inst, Expr);
256 }
257
258 void addExpr(MCInst &Inst, const MCExpr *Expr) const{
259 // Add as immediate when possible. Null MCExpr = 0.
260 if (Expr == 0)
261 Inst.addOperand(MCOperand::CreateImm(0));
262 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
263 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
264 else
265 Inst.addOperand(MCOperand::CreateExpr(Expr));
266 }
267
268 void addMEMrrOperands(MCInst &Inst, unsigned N) const {
269 assert(N == 2 && "Invalid number of operands!");
270
271 Inst.addOperand(MCOperand::CreateReg(getMemBase()));
272
273 assert(getMemOffsetReg() != 0 && "Invalid offset");
274 Inst.addOperand(MCOperand::CreateReg(getMemOffsetReg()));
275 }
276
277 void addMEMriOperands(MCInst &Inst, unsigned N) const {
278 assert(N == 2 && "Invalid number of operands!");
279
280 Inst.addOperand(MCOperand::CreateReg(getMemBase()));
281
282 const MCExpr *Expr = getMemOff();
283 addExpr(Inst, Expr);
284 }
285
286 static SparcOperand *CreateToken(StringRef Str, SMLoc S) {
287 SparcOperand *Op = new SparcOperand(k_Token);
288 Op->Tok.Data = Str.data();
289 Op->Tok.Length = Str.size();
290 Op->StartLoc = S;
291 Op->EndLoc = S;
292 return Op;
293 }
294
295 static SparcOperand *CreateReg(unsigned RegNum,
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000296 unsigned Kind,
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000297 SMLoc S, SMLoc E) {
298 SparcOperand *Op = new SparcOperand(k_Register);
299 Op->Reg.RegNum = RegNum;
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000300 Op->Reg.Kind = (SparcOperand::RegisterKind)Kind;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000301 Op->StartLoc = S;
302 Op->EndLoc = E;
303 return Op;
304 }
305
306 static SparcOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
307 SparcOperand *Op = new SparcOperand(k_Immediate);
308 Op->Imm.Val = Val;
309 Op->StartLoc = S;
310 Op->EndLoc = E;
311 return Op;
312 }
313
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000314 static SparcOperand *MorphToDoubleReg(SparcOperand *Op) {
315 unsigned Reg = Op->getReg();
316 assert(Op->Reg.Kind == rk_FloatReg);
317 unsigned regIdx = Reg - Sparc::F0;
318 if (regIdx % 2 || regIdx > 31)
319 return 0;
320 Op->Reg.RegNum = DoubleRegs[regIdx / 2];
321 Op->Reg.Kind = rk_DoubleReg;
322 return Op;
323 }
324
325 static SparcOperand *MorphToQuadReg(SparcOperand *Op) {
326 unsigned Reg = Op->getReg();
327 unsigned regIdx = 0;
328 switch (Op->Reg.Kind) {
329 default: assert(0 && "Unexpected register kind!");
330 case rk_FloatReg:
331 regIdx = Reg - Sparc::F0;
332 if (regIdx % 4 || regIdx > 31)
333 return 0;
334 Reg = QuadFPRegs[regIdx / 4];
335 break;
336 case rk_DoubleReg:
337 regIdx = Reg - Sparc::D0;
338 if (regIdx % 2 || regIdx > 31)
339 return 0;
340 Reg = QuadFPRegs[regIdx / 2];
341 break;
342 }
343 Op->Reg.RegNum = Reg;
344 Op->Reg.Kind = rk_QuadReg;
345 return Op;
346 }
347
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000348 static SparcOperand *MorphToMEMrr(unsigned Base, SparcOperand *Op) {
349 unsigned offsetReg = Op->getReg();
350 Op->Kind = k_MemoryReg;
351 Op->Mem.Base = Base;
352 Op->Mem.OffsetReg = offsetReg;
353 Op->Mem.Off = 0;
354 return Op;
355 }
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000356
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000357 static SparcOperand *CreateMEMri(unsigned Base,
358 const MCExpr *Off,
359 SMLoc S, SMLoc E) {
360 SparcOperand *Op = new SparcOperand(k_MemoryImm);
361 Op->Mem.Base = Base;
362 Op->Mem.OffsetReg = 0;
363 Op->Mem.Off = Off;
364 Op->StartLoc = S;
365 Op->EndLoc = E;
366 return Op;
367 }
368
369 static SparcOperand *MorphToMEMri(unsigned Base, SparcOperand *Op) {
370 const MCExpr *Imm = Op->getImm();
371 Op->Kind = k_MemoryImm;
372 Op->Mem.Base = Base;
373 Op->Mem.OffsetReg = 0;
374 Op->Mem.Off = Imm;
375 return Op;
376 }
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000377};
378
379} // end namespace
380
381bool SparcAsmParser::
382MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
383 SmallVectorImpl<MCParsedAsmOperand*> &Operands,
384 MCStreamer &Out, unsigned &ErrorInfo,
385 bool MatchingInlineAsm) {
386 MCInst Inst;
387 SmallVector<MCInst, 8> Instructions;
388 unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
389 MatchingInlineAsm);
390 switch (MatchResult) {
391 default:
392 break;
393
394 case Match_Success: {
395 Inst.setLoc(IDLoc);
396 Out.EmitInstruction(Inst);
397 return false;
398 }
399
400 case Match_MissingFeature:
401 return Error(IDLoc,
402 "instruction requires a CPU feature not currently enabled");
403
404 case Match_InvalidOperand: {
405 SMLoc ErrorLoc = IDLoc;
406 if (ErrorInfo != ~0U) {
407 if (ErrorInfo >= Operands.size())
408 return Error(IDLoc, "too few operands for instruction");
409
410 ErrorLoc = ((SparcOperand*) Operands[ErrorInfo])->getStartLoc();
411 if (ErrorLoc == SMLoc())
412 ErrorLoc = IDLoc;
413 }
414
415 return Error(ErrorLoc, "invalid operand for instruction");
416 }
417 case Match_MnemonicFail:
418 return Error(IDLoc, "invalid instruction");
419 }
420 return true;
421}
422
423bool SparcAsmParser::
424ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc)
425{
426 const AsmToken &Tok = Parser.getTok();
427 StartLoc = Tok.getLoc();
428 EndLoc = Tok.getEndLoc();
429 RegNo = 0;
430 if (getLexer().getKind() != AsmToken::Percent)
431 return false;
432 Parser.Lex();
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000433 unsigned regKind = SparcOperand::rk_None;
434 if (matchRegisterName(Tok, RegNo, regKind)) {
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000435 Parser.Lex();
436 return false;
437 }
438
439 return Error(StartLoc, "invalid register name");
440}
441
442bool SparcAsmParser::
443ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
444 SMLoc NameLoc,
445 SmallVectorImpl<MCParsedAsmOperand*> &Operands)
446{
447 // Check if we have valid mnemonic.
448 if (!mnemonicIsValid(Name, 0)) {
449 Parser.eatToEndOfStatement();
450 return Error(NameLoc, "Unknown instruction");
451 }
452 // First operand in MCInst is instruction mnemonic.
453 Operands.push_back(SparcOperand::CreateToken(Name, NameLoc));
454
455 if (getLexer().isNot(AsmToken::EndOfStatement)) {
456 // Read the first operand.
457 if (parseOperand(Operands, Name) != MatchOperand_Success) {
458 SMLoc Loc = getLexer().getLoc();
459 Parser.eatToEndOfStatement();
460 return Error(Loc, "unexpected token");
461 }
462
463 while (getLexer().is(AsmToken::Comma)) {
464 Parser.Lex(); // Eat the comma.
465 // Parse and remember the operand.
466 if (parseOperand(Operands, Name) != MatchOperand_Success) {
467 SMLoc Loc = getLexer().getLoc();
468 Parser.eatToEndOfStatement();
469 return Error(Loc, "unexpected token");
470 }
471 }
472 }
473 if (getLexer().isNot(AsmToken::EndOfStatement)) {
474 SMLoc Loc = getLexer().getLoc();
475 Parser.eatToEndOfStatement();
476 return Error(Loc, "unexpected token");
477 }
478 Parser.Lex(); // Consume the EndOfStatement.
479 return false;
480}
481
482bool SparcAsmParser::
483ParseDirective(AsmToken DirectiveID)
484{
485 // Ignore all directives for now.
486 Parser.eatToEndOfStatement();
487 return false;
488}
489
490SparcAsmParser::OperandMatchResultTy SparcAsmParser::
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000491parseMEMOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands)
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000492{
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000493
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000494 SMLoc S, E;
495 unsigned BaseReg = 0;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000496
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000497 if (ParseRegister(BaseReg, S, E)) {
498 return MatchOperand_NoMatch;
499 }
500
501 switch (getLexer().getKind()) {
502 default: return MatchOperand_NoMatch;
503
Venkatraman Govindaraju0d288d32014-01-10 01:48:17 +0000504 case AsmToken::Comma:
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000505 case AsmToken::RBrac:
506 case AsmToken::EndOfStatement:
507 Operands.push_back(SparcOperand::CreateMEMri(BaseReg, 0, S, E));
508 return MatchOperand_Success;
509
510 case AsmToken:: Plus:
511 Parser.Lex(); // Eat the '+'
512 break;
513 case AsmToken::Minus:
514 break;
515 }
516
517 SparcOperand *Offset = 0;
518 OperandMatchResultTy ResTy = parseSparcAsmOperand(Offset);
519 if (ResTy != MatchOperand_Success || !Offset)
520 return MatchOperand_NoMatch;
521
522 Offset = (Offset->isImm()
523 ? SparcOperand::MorphToMEMri(BaseReg, Offset)
524 : SparcOperand::MorphToMEMrr(BaseReg, Offset));
525
526 Operands.push_back(Offset);
527 return MatchOperand_Success;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000528}
529
530SparcAsmParser::OperandMatchResultTy SparcAsmParser::
531parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
532 StringRef Mnemonic)
533{
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000534
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000535 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000536
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000537 // If there wasn't a custom match, try the generic matcher below. Otherwise,
538 // there was a match, but an error occurred, in which case, just return that
539 // the operand parsing failed.
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000540 if (ResTy == MatchOperand_Success || ResTy == MatchOperand_ParseFail)
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000541 return ResTy;
542
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000543 if (getLexer().is(AsmToken::LBrac)) {
544 // Memory operand
545 Operands.push_back(SparcOperand::CreateToken("[",
546 Parser.getTok().getLoc()));
547 Parser.Lex(); // Eat the [
548
549 ResTy = parseMEMOperand(Operands);
550 if (ResTy != MatchOperand_Success)
551 return ResTy;
552
553 if (!getLexer().is(AsmToken::RBrac))
554 return MatchOperand_ParseFail;
555
556 Operands.push_back(SparcOperand::CreateToken("]",
557 Parser.getTok().getLoc()));
558 Parser.Lex(); // Eat the ]
559 return MatchOperand_Success;
560 }
561
562 SparcOperand *Op = 0;
563 ResTy = parseSparcAsmOperand(Op);
564 if (ResTy != MatchOperand_Success || !Op)
565 return MatchOperand_ParseFail;
566
567 // Push the parsed operand into the list of operands
568 Operands.push_back(Op);
569
570 return MatchOperand_Success;
571}
572
573SparcAsmParser::OperandMatchResultTy
574SparcAsmParser::parseSparcAsmOperand(SparcOperand *&Op)
575{
576
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000577 SMLoc S = Parser.getTok().getLoc();
578 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
579 const MCExpr *EVal;
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000580
581 Op = 0;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000582 switch (getLexer().getKind()) {
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000583 default: break;
584
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000585 case AsmToken::Percent:
586 Parser.Lex(); // Eat the '%'.
587 unsigned RegNo;
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000588 unsigned RegKind;
589 if (matchRegisterName(Parser.getTok(), RegNo, RegKind)) {
Venkatraman Govindarajub3b7c382014-01-08 06:14:52 +0000590 StringRef name = Parser.getTok().getString();
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000591 Parser.Lex(); // Eat the identifier token.
Venkatraman Govindaraju559c4ac2014-01-07 08:00:49 +0000592 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Venkatraman Govindarajub3b7c382014-01-08 06:14:52 +0000593 switch (RegNo) {
594 default:
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000595 Op = SparcOperand::CreateReg(RegNo, RegKind, S, E);
Venkatraman Govindarajub3b7c382014-01-08 06:14:52 +0000596 break;
597 case Sparc::Y:
598 Op = SparcOperand::CreateToken("%y", S);
599 break;
600
601 case Sparc::ICC:
602 if (name == "xcc")
603 Op = SparcOperand::CreateToken("%xcc", S);
604 else
605 Op = SparcOperand::CreateToken("%icc", S);
606 break;
607
608 case Sparc::FCC:
609 assert(name == "fcc0" && "Cannot handle %fcc other than %fcc0 yet");
610 Op = SparcOperand::CreateToken("%fcc0", S);
611 break;
612 }
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000613 break;
614 }
Venkatraman Govindaraju559c4ac2014-01-07 08:00:49 +0000615 if (matchSparcAsmModifiers(EVal, E)) {
616 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
617 Op = SparcOperand::CreateImm(EVal, S, E);
618 }
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000619 break;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000620
621 case AsmToken::Minus:
622 case AsmToken::Integer:
Venkatraman Govindaraju559c4ac2014-01-07 08:00:49 +0000623 if (!getParser().parseExpression(EVal, E))
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000624 Op = SparcOperand::CreateImm(EVal, S, E);
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000625 break;
626
627 case AsmToken::Identifier: {
628 StringRef Identifier;
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000629 if (!getParser().parseIdentifier(Identifier)) {
Venkatraman Govindaraju559c4ac2014-01-07 08:00:49 +0000630 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000631 MCSymbol *Sym = getContext().GetOrCreateSymbol(Identifier);
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000632
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000633 const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
634 getContext());
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000635 Op = SparcOperand::CreateImm(Res, S, E);
636 }
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000637 break;
638 }
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000639 }
Venkatraman Govindaraju0458b592014-01-07 01:49:11 +0000640 return (Op) ? MatchOperand_Success : MatchOperand_ParseFail;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000641}
642
643bool SparcAsmParser::matchRegisterName(const AsmToken &Tok,
644 unsigned &RegNo,
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000645 unsigned &RegKind)
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000646{
647 int64_t intVal = 0;
648 RegNo = 0;
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000649 RegKind = SparcOperand::rk_None;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000650 if (Tok.is(AsmToken::Identifier)) {
651 StringRef name = Tok.getString();
652
653 // %fp
654 if (name.equals("fp")) {
655 RegNo = Sparc::I6;
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000656 RegKind = SparcOperand::rk_IntReg;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000657 return true;
658 }
659 // %sp
660 if (name.equals("sp")) {
661 RegNo = Sparc::O6;
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000662 RegKind = SparcOperand::rk_IntReg;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000663 return true;
664 }
665
666 if (name.equals("y")) {
667 RegNo = Sparc::Y;
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000668 RegKind = SparcOperand::rk_Y;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000669 return true;
670 }
671
672 if (name.equals("icc")) {
673 RegNo = Sparc::ICC;
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000674 RegKind = SparcOperand::rk_CCReg;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000675 return true;
676 }
677
678 if (name.equals("xcc")) {
679 // FIXME:: check 64bit.
680 RegNo = Sparc::ICC;
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000681 RegKind = SparcOperand::rk_CCReg;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000682 return true;
683 }
684
685 // %fcc0 - %fcc3
686 if (name.substr(0, 3).equals_lower("fcc")
687 && !name.substr(3).getAsInteger(10, intVal)
688 && intVal < 4) {
689 // FIXME: check 64bit and handle %fcc1 - %fcc3
690 RegNo = Sparc::FCC;
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000691 RegKind = SparcOperand::rk_CCReg;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000692 return true;
693 }
694
695 // %g0 - %g7
696 if (name.substr(0, 1).equals_lower("g")
697 && !name.substr(1).getAsInteger(10, intVal)
698 && intVal < 8) {
699 RegNo = IntRegs[intVal];
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000700 RegKind = SparcOperand::rk_IntReg;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000701 return true;
702 }
703 // %o0 - %o7
704 if (name.substr(0, 1).equals_lower("o")
705 && !name.substr(1).getAsInteger(10, intVal)
706 && intVal < 8) {
707 RegNo = IntRegs[8 + intVal];
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000708 RegKind = SparcOperand::rk_IntReg;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000709 return true;
710 }
711 if (name.substr(0, 1).equals_lower("l")
712 && !name.substr(1).getAsInteger(10, intVal)
713 && intVal < 8) {
714 RegNo = IntRegs[16 + intVal];
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000715 RegKind = SparcOperand::rk_IntReg;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000716 return true;
717 }
718 if (name.substr(0, 1).equals_lower("i")
719 && !name.substr(1).getAsInteger(10, intVal)
720 && intVal < 8) {
721 RegNo = IntRegs[24 + intVal];
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000722 RegKind = SparcOperand::rk_IntReg;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000723 return true;
724 }
725 // %f0 - %f31
726 if (name.substr(0, 1).equals_lower("f")
727 && !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 32) {
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000728 RegNo = FloatRegs[intVal];
729 RegKind = SparcOperand::rk_FloatReg;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000730 return true;
731 }
732 // %f32 - %f62
733 if (name.substr(0, 1).equals_lower("f")
734 && !name.substr(1, 2).getAsInteger(10, intVal)
735 && intVal >= 32 && intVal <= 62 && (intVal % 2 == 0)) {
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000736 // FIXME: Check V9
Eric Christopher7383d4a2014-01-23 21:41:10 +0000737 RegNo = DoubleRegs[intVal/2];
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000738 RegKind = SparcOperand::rk_DoubleReg;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000739 return true;
740 }
741
742 // %r0 - %r31
743 if (name.substr(0, 1).equals_lower("r")
744 && !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 31) {
745 RegNo = IntRegs[intVal];
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000746 RegKind = SparcOperand::rk_IntReg;
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000747 return true;
748 }
749 }
750 return false;
751}
752
753
Venkatraman Govindaraju559c4ac2014-01-07 08:00:49 +0000754bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal,
755 SMLoc &EndLoc)
756{
757 AsmToken Tok = Parser.getTok();
758 if (!Tok.is(AsmToken::Identifier))
759 return false;
760
761 StringRef name = Tok.getString();
762
763 SparcMCExpr::VariantKind VK = SparcMCExpr::parseVariantKind(name);
764
765 if (VK == SparcMCExpr::VK_Sparc_None)
766 return false;
767
768 Parser.Lex(); // Eat the identifier.
769 if (Parser.getTok().getKind() != AsmToken::LParen)
770 return false;
771
772 Parser.Lex(); // Eat the LParen token.
773 const MCExpr *subExpr;
774 if (Parser.parseParenExpression(subExpr, EndLoc))
775 return false;
776 EVal = SparcMCExpr::Create(VK, subExpr, getContext());
777 return true;
778}
779
Venkatraman Govindarajuc2dee7d2014-01-04 11:30:13 +0000780
781extern "C" void LLVMInitializeSparcAsmParser() {
782 RegisterMCAsmParser<SparcAsmParser> A(TheSparcTarget);
783 RegisterMCAsmParser<SparcAsmParser> B(TheSparcV9Target);
784}
785
786#define GET_REGISTER_MATCHER
787#define GET_MATCHER_IMPLEMENTATION
788#include "SparcGenAsmMatcher.inc"
Venkatraman Govindarajucd4d9ac2014-01-12 04:48:54 +0000789
790
791
792unsigned SparcAsmParser::
793validateTargetOperandClass(MCParsedAsmOperand *GOp,
794 unsigned Kind)
795{
796 SparcOperand *Op = (SparcOperand*)GOp;
797 if (Op->isFloatOrDoubleReg()) {
798 switch (Kind) {
799 default: break;
800 case MCK_DFPRegs:
801 if (!Op->isFloatReg() || SparcOperand::MorphToDoubleReg(Op))
802 return MCTargetAsmParser::Match_Success;
803 break;
804 case MCK_QFPRegs:
805 if (SparcOperand::MorphToQuadReg(Op))
806 return MCTargetAsmParser::Match_Success;
807 break;
808 }
809 }
810 return Match_InvalidOperand;
811}