1//===-- 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"
11#include "MCTargetDesc/SparcMCExpr.h"
12#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 {
32class SparcOperand;
33class 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
57  virtual unsigned validateTargetOperandClass(MCParsedAsmOperand *Op,
58                                              unsigned Kind);
59
60  // Custom parse functions for Sparc specific operands.
61  OperandMatchResultTy
62  parseMEMOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
63
64  OperandMatchResultTy
65  parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
66               StringRef Name);
67
68  OperandMatchResultTy
69  parseSparcAsmOperand(SparcOperand *&Operand);
70
71  // returns true if Tok is matched to a register and returns register in RegNo.
72  bool matchRegisterName(const AsmToken &Tok, unsigned &RegNo,
73                         unsigned &RegKind);
74
75  bool matchSparcAsmModifiers(const MCExpr *&EVal, SMLoc &EndLoc);
76
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::Q9,  Sparc::Q10, Sparc::Q11,
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
184  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
194  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,
296                                 unsigned Kind,
297                                 SMLoc S, SMLoc E) {
298    SparcOperand *Op = new SparcOperand(k_Register);
299    Op->Reg.RegNum = RegNum;
300    Op->Reg.Kind   = (SparcOperand::RegisterKind)Kind;
301    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
314  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
348  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  }
356
357  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  }
377};
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();
433  unsigned regKind = SparcOperand::rk_None;
434  if (matchRegisterName(Tok, RegNo, regKind)) {
435    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::
491parseMEMOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands)
492{
493
494  SMLoc S, E;
495  unsigned BaseReg = 0;
496
497  if (ParseRegister(BaseReg, S, E)) {
498    return MatchOperand_NoMatch;
499  }
500
501  switch (getLexer().getKind()) {
502  default: return MatchOperand_NoMatch;
503
504  case AsmToken::Comma:
505  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;
528}
529
530SparcAsmParser::OperandMatchResultTy SparcAsmParser::
531parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
532             StringRef Mnemonic)
533{
534
535  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
536
537  // 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.
540  if (ResTy == MatchOperand_Success || ResTy == MatchOperand_ParseFail)
541    return ResTy;
542
543  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    if (Mnemonic == "cas" || Mnemonic == "casx") {
550      SMLoc S = Parser.getTok().getLoc();
551      if (getLexer().getKind() != AsmToken::Percent)
552        return MatchOperand_NoMatch;
553      Parser.Lex(); // eat %
554
555      unsigned RegNo, RegKind;
556      if (!matchRegisterName(Parser.getTok(), RegNo, RegKind))
557        return MatchOperand_NoMatch;
558
559      Parser.Lex(); // Eat the identifier token.
560      SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer()-1);
561      Operands.push_back(SparcOperand::CreateReg(RegNo, RegKind, S, E));
562      ResTy = MatchOperand_Success;
563    } else {
564      ResTy = parseMEMOperand(Operands);
565    }
566
567    if (ResTy != MatchOperand_Success)
568      return ResTy;
569
570    if (!getLexer().is(AsmToken::RBrac))
571      return MatchOperand_ParseFail;
572
573    Operands.push_back(SparcOperand::CreateToken("]",
574                                                 Parser.getTok().getLoc()));
575    Parser.Lex(); // Eat the ]
576    return MatchOperand_Success;
577  }
578
579  SparcOperand *Op = 0;
580  ResTy = parseSparcAsmOperand(Op);
581  if (ResTy != MatchOperand_Success || !Op)
582    return MatchOperand_ParseFail;
583
584  // Push the parsed operand into the list of operands
585  Operands.push_back(Op);
586
587  return MatchOperand_Success;
588}
589
590SparcAsmParser::OperandMatchResultTy
591SparcAsmParser::parseSparcAsmOperand(SparcOperand *&Op)
592{
593
594  SMLoc S = Parser.getTok().getLoc();
595  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
596  const MCExpr *EVal;
597
598  Op = 0;
599  switch (getLexer().getKind()) {
600  default:  break;
601
602  case AsmToken::Percent:
603    Parser.Lex(); // Eat the '%'.
604    unsigned RegNo;
605    unsigned RegKind;
606    if (matchRegisterName(Parser.getTok(), RegNo, RegKind)) {
607      StringRef name = Parser.getTok().getString();
608      Parser.Lex(); // Eat the identifier token.
609      E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
610      switch (RegNo) {
611      default:
612        Op = SparcOperand::CreateReg(RegNo, RegKind, S, E);
613        break;
614      case Sparc::Y:
615        Op = SparcOperand::CreateToken("%y", S);
616        break;
617
618      case Sparc::ICC:
619        if (name == "xcc")
620          Op = SparcOperand::CreateToken("%xcc", S);
621        else
622          Op = SparcOperand::CreateToken("%icc", S);
623        break;
624
625      case Sparc::FCC:
626        assert(name == "fcc0" && "Cannot handle %fcc other than %fcc0 yet");
627        Op = SparcOperand::CreateToken("%fcc0", S);
628        break;
629      }
630      break;
631    }
632    if (matchSparcAsmModifiers(EVal, E)) {
633      E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
634      Op = SparcOperand::CreateImm(EVal, S, E);
635    }
636    break;
637
638  case AsmToken::Minus:
639  case AsmToken::Integer:
640    if (!getParser().parseExpression(EVal, E))
641      Op = SparcOperand::CreateImm(EVal, S, E);
642    break;
643
644  case AsmToken::Identifier: {
645    StringRef Identifier;
646    if (!getParser().parseIdentifier(Identifier)) {
647      E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
648      MCSymbol *Sym = getContext().GetOrCreateSymbol(Identifier);
649
650      const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
651                                                  getContext());
652      Op = SparcOperand::CreateImm(Res, S, E);
653    }
654    break;
655  }
656  }
657  return (Op) ? MatchOperand_Success : MatchOperand_ParseFail;
658}
659
660bool SparcAsmParser::matchRegisterName(const AsmToken &Tok,
661                                       unsigned &RegNo,
662                                       unsigned &RegKind)
663{
664  int64_t intVal = 0;
665  RegNo = 0;
666  RegKind = SparcOperand::rk_None;
667  if (Tok.is(AsmToken::Identifier)) {
668    StringRef name = Tok.getString();
669
670    // %fp
671    if (name.equals("fp")) {
672      RegNo = Sparc::I6;
673      RegKind = SparcOperand::rk_IntReg;
674      return true;
675    }
676    // %sp
677    if (name.equals("sp")) {
678      RegNo = Sparc::O6;
679      RegKind = SparcOperand::rk_IntReg;
680      return true;
681    }
682
683    if (name.equals("y")) {
684      RegNo = Sparc::Y;
685      RegKind = SparcOperand::rk_Y;
686      return true;
687    }
688
689    if (name.equals("icc")) {
690      RegNo = Sparc::ICC;
691      RegKind = SparcOperand::rk_CCReg;
692      return true;
693    }
694
695    if (name.equals("xcc")) {
696      // FIXME:: check 64bit.
697      RegNo = Sparc::ICC;
698      RegKind = SparcOperand::rk_CCReg;
699      return true;
700    }
701
702    // %fcc0 - %fcc3
703    if (name.substr(0, 3).equals_lower("fcc")
704        && !name.substr(3).getAsInteger(10, intVal)
705        && intVal < 4) {
706      // FIXME: check 64bit and  handle %fcc1 - %fcc3
707      RegNo = Sparc::FCC;
708      RegKind = SparcOperand::rk_CCReg;
709      return true;
710    }
711
712    // %g0 - %g7
713    if (name.substr(0, 1).equals_lower("g")
714        && !name.substr(1).getAsInteger(10, intVal)
715        && intVal < 8) {
716      RegNo = IntRegs[intVal];
717      RegKind = SparcOperand::rk_IntReg;
718      return true;
719    }
720    // %o0 - %o7
721    if (name.substr(0, 1).equals_lower("o")
722        && !name.substr(1).getAsInteger(10, intVal)
723        && intVal < 8) {
724      RegNo = IntRegs[8 + intVal];
725      RegKind = SparcOperand::rk_IntReg;
726      return true;
727    }
728    if (name.substr(0, 1).equals_lower("l")
729        && !name.substr(1).getAsInteger(10, intVal)
730        && intVal < 8) {
731      RegNo = IntRegs[16 + intVal];
732      RegKind = SparcOperand::rk_IntReg;
733      return true;
734    }
735    if (name.substr(0, 1).equals_lower("i")
736        && !name.substr(1).getAsInteger(10, intVal)
737        && intVal < 8) {
738      RegNo = IntRegs[24 + intVal];
739      RegKind = SparcOperand::rk_IntReg;
740      return true;
741    }
742    // %f0 - %f31
743    if (name.substr(0, 1).equals_lower("f")
744        && !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 32) {
745      RegNo = FloatRegs[intVal];
746      RegKind = SparcOperand::rk_FloatReg;
747      return true;
748    }
749    // %f32 - %f62
750    if (name.substr(0, 1).equals_lower("f")
751        && !name.substr(1, 2).getAsInteger(10, intVal)
752        && intVal >= 32 && intVal <= 62 && (intVal % 2 == 0)) {
753      // FIXME: Check V9
754      RegNo = DoubleRegs[intVal/2];
755      RegKind = SparcOperand::rk_DoubleReg;
756      return true;
757    }
758
759    // %r0 - %r31
760    if (name.substr(0, 1).equals_lower("r")
761        && !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 31) {
762      RegNo = IntRegs[intVal];
763      RegKind = SparcOperand::rk_IntReg;
764      return true;
765    }
766  }
767  return false;
768}
769
770
771bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal,
772                                            SMLoc &EndLoc)
773{
774  AsmToken Tok = Parser.getTok();
775  if (!Tok.is(AsmToken::Identifier))
776    return false;
777
778  StringRef name = Tok.getString();
779
780  SparcMCExpr::VariantKind VK = SparcMCExpr::parseVariantKind(name);
781
782  if (VK == SparcMCExpr::VK_Sparc_None)
783    return false;
784
785  Parser.Lex(); // Eat the identifier.
786  if (Parser.getTok().getKind() != AsmToken::LParen)
787    return false;
788
789  Parser.Lex(); // Eat the LParen token.
790  const MCExpr *subExpr;
791  if (Parser.parseParenExpression(subExpr, EndLoc))
792    return false;
793  EVal = SparcMCExpr::Create(VK, subExpr, getContext());
794  return true;
795}
796
797
798extern "C" void LLVMInitializeSparcAsmParser() {
799  RegisterMCAsmParser<SparcAsmParser> A(TheSparcTarget);
800  RegisterMCAsmParser<SparcAsmParser> B(TheSparcV9Target);
801}
802
803#define GET_REGISTER_MATCHER
804#define GET_MATCHER_IMPLEMENTATION
805#include "SparcGenAsmMatcher.inc"
806
807
808
809unsigned SparcAsmParser::
810validateTargetOperandClass(MCParsedAsmOperand *GOp,
811                           unsigned Kind)
812{
813  SparcOperand *Op = (SparcOperand*)GOp;
814  if (Op->isFloatOrDoubleReg()) {
815    switch (Kind) {
816    default: break;
817    case MCK_DFPRegs:
818      if (!Op->isFloatReg() || SparcOperand::MorphToDoubleReg(Op))
819        return MCTargetAsmParser::Match_Success;
820      break;
821    case MCK_QFPRegs:
822      if (SparcOperand::MorphToQuadReg(Op))
823        return MCTargetAsmParser::Match_Success;
824      break;
825    }
826  }
827  return Match_InvalidOperand;
828}
829