SparcAsmParser.cpp revision 36b56886974eae4f9c5ebc96befd3e7bfe5de338
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/MCObjectFileInfo.h"
16#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
17#include "llvm/MC/MCStreamer.h"
18#include "llvm/MC/MCSubtargetInfo.h"
19#include "llvm/MC/MCSymbol.h"
20#include "llvm/MC/MCTargetAsmParser.h"
21#include "llvm/Support/TargetRegistry.h"
22
23using namespace llvm;
24
25// The generated AsmMatcher SparcGenAsmMatcher uses "Sparc" as the target
26// namespace. But SPARC backend uses "SP" as its namespace.
27namespace llvm {
28  namespace Sparc {
29    using namespace SP;
30  }
31}
32
33namespace {
34class SparcOperand;
35class SparcAsmParser : public MCTargetAsmParser {
36
37  MCSubtargetInfo &STI;
38  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,
50                               SmallVectorImpl<MCParsedAsmOperand*> &Operands,
51                               MCStreamer &Out, unsigned &ErrorInfo,
52                               bool MatchingInlineAsm);
53  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
54  bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
55                        SMLoc NameLoc,
56                        SmallVectorImpl<MCParsedAsmOperand*> &Operands);
57  bool ParseDirective(AsmToken DirectiveID);
58
59  virtual unsigned validateTargetOperandClass(MCParsedAsmOperand *Op,
60                                              unsigned Kind);
61
62  // Custom parse functions for Sparc specific operands.
63  OperandMatchResultTy
64  parseMEMOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
65
66  OperandMatchResultTy
67  parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
68               StringRef Name);
69
70  OperandMatchResultTy
71  parseSparcAsmOperand(SparcOperand *&Operand, bool isCall = false);
72
73  OperandMatchResultTy
74  parseBranchModifiers(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
75
76  // returns true if Tok is matched to a register and returns register in RegNo.
77  bool matchRegisterName(const AsmToken &Tok, unsigned &RegNo,
78                         unsigned &RegKind);
79
80  bool matchSparcAsmModifiers(const MCExpr *&EVal, SMLoc &EndLoc);
81  bool parseDirectiveWord(unsigned Size, SMLoc L);
82
83  bool is64Bit() const { return STI.getTargetTriple().startswith("sparcv9"); }
84public:
85  SparcAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
86                const MCInstrInfo &MII)
87      : MCTargetAsmParser(), STI(sti), Parser(parser) {
88    // Initialize the set of available features.
89    setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
90  }
91
92};
93
94  static unsigned IntRegs[32] = {
95    Sparc::G0, Sparc::G1, Sparc::G2, Sparc::G3,
96    Sparc::G4, Sparc::G5, Sparc::G6, Sparc::G7,
97    Sparc::O0, Sparc::O1, Sparc::O2, Sparc::O3,
98    Sparc::O4, Sparc::O5, Sparc::O6, Sparc::O7,
99    Sparc::L0, Sparc::L1, Sparc::L2, Sparc::L3,
100    Sparc::L4, Sparc::L5, Sparc::L6, Sparc::L7,
101    Sparc::I0, Sparc::I1, Sparc::I2, Sparc::I3,
102    Sparc::I4, Sparc::I5, Sparc::I6, Sparc::I7 };
103
104  static unsigned FloatRegs[32] = {
105    Sparc::F0,  Sparc::F1,  Sparc::F2,  Sparc::F3,
106    Sparc::F4,  Sparc::F5,  Sparc::F6,  Sparc::F7,
107    Sparc::F8,  Sparc::F9,  Sparc::F10, Sparc::F11,
108    Sparc::F12, Sparc::F13, Sparc::F14, Sparc::F15,
109    Sparc::F16, Sparc::F17, Sparc::F18, Sparc::F19,
110    Sparc::F20, Sparc::F21, Sparc::F22, Sparc::F23,
111    Sparc::F24, Sparc::F25, Sparc::F26, Sparc::F27,
112    Sparc::F28, Sparc::F29, Sparc::F30, Sparc::F31 };
113
114  static unsigned DoubleRegs[32] = {
115    Sparc::D0,  Sparc::D1,  Sparc::D2,  Sparc::D3,
116    Sparc::D4,  Sparc::D5,  Sparc::D6,  Sparc::D7,
117    Sparc::D8,  Sparc::D7,  Sparc::D8,  Sparc::D9,
118    Sparc::D12, Sparc::D13, Sparc::D14, Sparc::D15,
119    Sparc::D16, Sparc::D17, Sparc::D18, Sparc::D19,
120    Sparc::D20, Sparc::D21, Sparc::D22, Sparc::D23,
121    Sparc::D24, Sparc::D25, Sparc::D26, Sparc::D27,
122    Sparc::D28, Sparc::D29, Sparc::D30, Sparc::D31 };
123
124  static unsigned QuadFPRegs[32] = {
125    Sparc::Q0,  Sparc::Q1,  Sparc::Q2,  Sparc::Q3,
126    Sparc::Q4,  Sparc::Q5,  Sparc::Q6,  Sparc::Q7,
127    Sparc::Q8,  Sparc::Q9,  Sparc::Q10, Sparc::Q11,
128    Sparc::Q12, Sparc::Q13, Sparc::Q14, Sparc::Q15 };
129
130
131/// SparcOperand - Instances of this class represent a parsed Sparc machine
132/// instruction.
133class SparcOperand : public MCParsedAsmOperand {
134public:
135  enum RegisterKind {
136    rk_None,
137    rk_IntReg,
138    rk_FloatReg,
139    rk_DoubleReg,
140    rk_QuadReg,
141    rk_CCReg,
142    rk_Y
143  };
144private:
145  enum KindTy {
146    k_Token,
147    k_Register,
148    k_Immediate,
149    k_MemoryReg,
150    k_MemoryImm
151  } Kind;
152
153  SMLoc StartLoc, EndLoc;
154
155  SparcOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
156
157  struct Token {
158    const char *Data;
159    unsigned Length;
160  };
161
162  struct RegOp {
163    unsigned RegNum;
164    RegisterKind Kind;
165  };
166
167  struct ImmOp {
168    const MCExpr *Val;
169  };
170
171  struct MemOp {
172    unsigned Base;
173    unsigned OffsetReg;
174    const MCExpr *Off;
175  };
176
177  union {
178    struct Token Tok;
179    struct RegOp Reg;
180    struct ImmOp Imm;
181    struct MemOp Mem;
182  };
183public:
184  bool isToken() const { return Kind == k_Token; }
185  bool isReg() const { return Kind == k_Register; }
186  bool isImm() const { return Kind == k_Immediate; }
187  bool isMem() const { return isMEMrr() || isMEMri(); }
188  bool isMEMrr() const { return Kind == k_MemoryReg; }
189  bool isMEMri() const { return Kind == k_MemoryImm; }
190
191  bool isFloatReg() const {
192    return (Kind == k_Register && Reg.Kind == rk_FloatReg);
193  }
194
195  bool isFloatOrDoubleReg() const {
196    return (Kind == k_Register && (Reg.Kind == rk_FloatReg
197                                   || Reg.Kind == rk_DoubleReg));
198  }
199
200
201  StringRef getToken() const {
202    assert(Kind == k_Token && "Invalid access!");
203    return StringRef(Tok.Data, Tok.Length);
204  }
205
206  unsigned getReg() const {
207    assert((Kind == k_Register) && "Invalid access!");
208    return Reg.RegNum;
209  }
210
211  const MCExpr *getImm() const {
212    assert((Kind == k_Immediate) && "Invalid access!");
213    return Imm.Val;
214  }
215
216  unsigned getMemBase() const {
217    assert((Kind == k_MemoryReg || Kind == k_MemoryImm) && "Invalid access!");
218    return Mem.Base;
219  }
220
221  unsigned getMemOffsetReg() const {
222    assert((Kind == k_MemoryReg) && "Invalid access!");
223    return Mem.OffsetReg;
224  }
225
226  const MCExpr *getMemOff() const {
227    assert((Kind == k_MemoryImm) && "Invalid access!");
228    return Mem.Off;
229  }
230
231  /// getStartLoc - Get the location of the first token of this operand.
232  SMLoc getStartLoc() const {
233    return StartLoc;
234  }
235  /// getEndLoc - Get the location of the last token of this operand.
236  SMLoc getEndLoc() const {
237    return EndLoc;
238  }
239
240  virtual void print(raw_ostream &OS) const {
241    switch (Kind) {
242    case k_Token:     OS << "Token: " << getToken() << "\n"; break;
243    case k_Register:  OS << "Reg: #" << getReg() << "\n"; break;
244    case k_Immediate: OS << "Imm: " << getImm() << "\n"; break;
245    case k_MemoryReg: OS << "Mem: " << getMemBase() << "+"
246                         << getMemOffsetReg() << "\n"; break;
247    case k_MemoryImm: assert(getMemOff() != 0);
248      OS << "Mem: " << getMemBase()
249         << "+" << *getMemOff()
250         << "\n"; break;
251    }
252  }
253
254  void addRegOperands(MCInst &Inst, unsigned N) const {
255    assert(N == 1 && "Invalid number of operands!");
256    Inst.addOperand(MCOperand::CreateReg(getReg()));
257  }
258
259  void addImmOperands(MCInst &Inst, unsigned N) const {
260    assert(N == 1 && "Invalid number of operands!");
261    const MCExpr *Expr = getImm();
262    addExpr(Inst, Expr);
263  }
264
265  void addExpr(MCInst &Inst, const MCExpr *Expr) const{
266    // Add as immediate when possible.  Null MCExpr = 0.
267    if (Expr == 0)
268      Inst.addOperand(MCOperand::CreateImm(0));
269    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
270      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
271    else
272      Inst.addOperand(MCOperand::CreateExpr(Expr));
273  }
274
275  void addMEMrrOperands(MCInst &Inst, unsigned N) const {
276    assert(N == 2 && "Invalid number of operands!");
277
278    Inst.addOperand(MCOperand::CreateReg(getMemBase()));
279
280    assert(getMemOffsetReg() != 0 && "Invalid offset");
281    Inst.addOperand(MCOperand::CreateReg(getMemOffsetReg()));
282  }
283
284  void addMEMriOperands(MCInst &Inst, unsigned N) const {
285    assert(N == 2 && "Invalid number of operands!");
286
287    Inst.addOperand(MCOperand::CreateReg(getMemBase()));
288
289    const MCExpr *Expr = getMemOff();
290    addExpr(Inst, Expr);
291  }
292
293  static SparcOperand *CreateToken(StringRef Str, SMLoc S) {
294    SparcOperand *Op = new SparcOperand(k_Token);
295    Op->Tok.Data = Str.data();
296    Op->Tok.Length = Str.size();
297    Op->StartLoc = S;
298    Op->EndLoc = S;
299    return Op;
300  }
301
302  static SparcOperand *CreateReg(unsigned RegNum,
303                                 unsigned Kind,
304                                 SMLoc S, SMLoc E) {
305    SparcOperand *Op = new SparcOperand(k_Register);
306    Op->Reg.RegNum = RegNum;
307    Op->Reg.Kind   = (SparcOperand::RegisterKind)Kind;
308    Op->StartLoc = S;
309    Op->EndLoc = E;
310    return Op;
311  }
312
313  static SparcOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
314    SparcOperand *Op = new SparcOperand(k_Immediate);
315    Op->Imm.Val = Val;
316    Op->StartLoc = S;
317    Op->EndLoc = E;
318    return Op;
319  }
320
321  static SparcOperand *MorphToDoubleReg(SparcOperand *Op) {
322    unsigned Reg = Op->getReg();
323    assert(Op->Reg.Kind == rk_FloatReg);
324    unsigned regIdx = Reg - Sparc::F0;
325    if (regIdx % 2 || regIdx > 31)
326      return 0;
327    Op->Reg.RegNum = DoubleRegs[regIdx / 2];
328    Op->Reg.Kind = rk_DoubleReg;
329    return Op;
330  }
331
332  static SparcOperand *MorphToQuadReg(SparcOperand *Op) {
333    unsigned Reg = Op->getReg();
334    unsigned regIdx = 0;
335    switch (Op->Reg.Kind) {
336    default: assert(0 && "Unexpected register kind!");
337    case rk_FloatReg:
338      regIdx = Reg - Sparc::F0;
339      if (regIdx % 4 || regIdx > 31)
340        return 0;
341      Reg = QuadFPRegs[regIdx / 4];
342      break;
343    case rk_DoubleReg:
344      regIdx =  Reg - Sparc::D0;
345      if (regIdx % 2 || regIdx > 31)
346        return 0;
347      Reg = QuadFPRegs[regIdx / 2];
348      break;
349    }
350    Op->Reg.RegNum  = Reg;
351    Op->Reg.Kind = rk_QuadReg;
352    return Op;
353  }
354
355  static SparcOperand *MorphToMEMrr(unsigned Base, SparcOperand *Op) {
356    unsigned offsetReg = Op->getReg();
357    Op->Kind = k_MemoryReg;
358    Op->Mem.Base = Base;
359    Op->Mem.OffsetReg = offsetReg;
360    Op->Mem.Off = 0;
361    return Op;
362  }
363
364  static SparcOperand *CreateMEMri(unsigned Base,
365                                 const MCExpr *Off,
366                                 SMLoc S, SMLoc E) {
367    SparcOperand *Op = new SparcOperand(k_MemoryImm);
368    Op->Mem.Base = Base;
369    Op->Mem.OffsetReg = 0;
370    Op->Mem.Off = Off;
371    Op->StartLoc = S;
372    Op->EndLoc = E;
373    return Op;
374  }
375
376  static SparcOperand *MorphToMEMri(unsigned Base, SparcOperand *Op) {
377    const MCExpr *Imm  = Op->getImm();
378    Op->Kind = k_MemoryImm;
379    Op->Mem.Base = Base;
380    Op->Mem.OffsetReg = 0;
381    Op->Mem.Off = Imm;
382    return Op;
383  }
384};
385
386} // end namespace
387
388bool SparcAsmParser::
389MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
390                        SmallVectorImpl<MCParsedAsmOperand*> &Operands,
391                        MCStreamer &Out, unsigned &ErrorInfo,
392                        bool MatchingInlineAsm) {
393  MCInst Inst;
394  SmallVector<MCInst, 8> Instructions;
395  unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
396                                              MatchingInlineAsm);
397  switch (MatchResult) {
398  default:
399    break;
400
401  case Match_Success: {
402    Inst.setLoc(IDLoc);
403    Out.EmitInstruction(Inst, STI);
404    return false;
405  }
406
407  case Match_MissingFeature:
408    return Error(IDLoc,
409                 "instruction requires a CPU feature not currently enabled");
410
411  case Match_InvalidOperand: {
412    SMLoc ErrorLoc = IDLoc;
413    if (ErrorInfo != ~0U) {
414      if (ErrorInfo >= Operands.size())
415        return Error(IDLoc, "too few operands for instruction");
416
417      ErrorLoc = ((SparcOperand*) Operands[ErrorInfo])->getStartLoc();
418      if (ErrorLoc == SMLoc())
419        ErrorLoc = IDLoc;
420    }
421
422    return Error(ErrorLoc, "invalid operand for instruction");
423  }
424  case Match_MnemonicFail:
425    return Error(IDLoc, "invalid instruction mnemonic");
426  }
427  return true;
428}
429
430bool SparcAsmParser::
431ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc)
432{
433  const AsmToken &Tok = Parser.getTok();
434  StartLoc = Tok.getLoc();
435  EndLoc = Tok.getEndLoc();
436  RegNo = 0;
437  if (getLexer().getKind() != AsmToken::Percent)
438    return false;
439  Parser.Lex();
440  unsigned regKind = SparcOperand::rk_None;
441  if (matchRegisterName(Tok, RegNo, regKind)) {
442    Parser.Lex();
443    return false;
444  }
445
446  return Error(StartLoc, "invalid register name");
447}
448
449static void applyMnemonicAliases(StringRef &Mnemonic, unsigned Features,
450                                 unsigned VariantID);
451
452bool SparcAsmParser::
453ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
454                 SMLoc NameLoc,
455                 SmallVectorImpl<MCParsedAsmOperand*> &Operands)
456{
457
458  // First operand in MCInst is instruction mnemonic.
459  Operands.push_back(SparcOperand::CreateToken(Name, NameLoc));
460
461  // apply mnemonic aliases, if any, so that we can parse operands correctly.
462  applyMnemonicAliases(Name, getAvailableFeatures(), 0);
463
464  if (getLexer().isNot(AsmToken::EndOfStatement)) {
465    // Read the first operand.
466    if (getLexer().is(AsmToken::Comma)) {
467      if (parseBranchModifiers(Operands) != MatchOperand_Success) {
468        SMLoc Loc = getLexer().getLoc();
469        Parser.eatToEndOfStatement();
470        return Error(Loc, "unexpected token");
471      }
472    }
473    if (parseOperand(Operands, Name) != MatchOperand_Success) {
474      SMLoc Loc = getLexer().getLoc();
475      Parser.eatToEndOfStatement();
476      return Error(Loc, "unexpected token");
477    }
478
479    while (getLexer().is(AsmToken::Comma)) {
480      Parser.Lex(); // Eat the comma.
481      // Parse and remember the operand.
482      if (parseOperand(Operands, Name) != MatchOperand_Success) {
483        SMLoc Loc = getLexer().getLoc();
484        Parser.eatToEndOfStatement();
485        return Error(Loc, "unexpected token");
486      }
487    }
488  }
489  if (getLexer().isNot(AsmToken::EndOfStatement)) {
490    SMLoc Loc = getLexer().getLoc();
491    Parser.eatToEndOfStatement();
492    return Error(Loc, "unexpected token");
493  }
494  Parser.Lex(); // Consume the EndOfStatement.
495  return false;
496}
497
498bool SparcAsmParser::
499ParseDirective(AsmToken DirectiveID)
500{
501  StringRef IDVal = DirectiveID.getString();
502
503  if (IDVal == ".byte")
504    return parseDirectiveWord(1, DirectiveID.getLoc());
505
506  if (IDVal == ".half")
507    return parseDirectiveWord(2, DirectiveID.getLoc());
508
509  if (IDVal == ".word")
510    return parseDirectiveWord(4, DirectiveID.getLoc());
511
512  if (IDVal == ".nword")
513    return parseDirectiveWord(is64Bit() ? 8 : 4, DirectiveID.getLoc());
514
515  if (is64Bit() && IDVal == ".xword")
516    return parseDirectiveWord(8, DirectiveID.getLoc());
517
518  if (IDVal == ".register") {
519    // For now, ignore .register directive.
520    Parser.eatToEndOfStatement();
521    return false;
522  }
523
524  // Let the MC layer to handle other directives.
525  return true;
526}
527
528bool SparcAsmParser:: parseDirectiveWord(unsigned Size, SMLoc L) {
529  if (getLexer().isNot(AsmToken::EndOfStatement)) {
530    for (;;) {
531      const MCExpr *Value;
532      if (getParser().parseExpression(Value))
533        return true;
534
535      getParser().getStreamer().EmitValue(Value, Size);
536
537      if (getLexer().is(AsmToken::EndOfStatement))
538        break;
539
540      // FIXME: Improve diagnostic.
541      if (getLexer().isNot(AsmToken::Comma))
542        return Error(L, "unexpected token in directive");
543      Parser.Lex();
544    }
545  }
546  Parser.Lex();
547  return false;
548}
549
550SparcAsmParser::OperandMatchResultTy SparcAsmParser::
551parseMEMOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands)
552{
553
554  SMLoc S, E;
555  unsigned BaseReg = 0;
556
557  if (ParseRegister(BaseReg, S, E)) {
558    return MatchOperand_NoMatch;
559  }
560
561  switch (getLexer().getKind()) {
562  default: return MatchOperand_NoMatch;
563
564  case AsmToken::Comma:
565  case AsmToken::RBrac:
566  case AsmToken::EndOfStatement:
567    Operands.push_back(SparcOperand::CreateMEMri(BaseReg, 0, S, E));
568    return MatchOperand_Success;
569
570  case AsmToken:: Plus:
571    Parser.Lex(); // Eat the '+'
572    break;
573  case AsmToken::Minus:
574    break;
575  }
576
577  SparcOperand *Offset = 0;
578  OperandMatchResultTy ResTy = parseSparcAsmOperand(Offset);
579  if (ResTy != MatchOperand_Success || !Offset)
580    return MatchOperand_NoMatch;
581
582  Offset = (Offset->isImm()
583            ? SparcOperand::MorphToMEMri(BaseReg, Offset)
584            : SparcOperand::MorphToMEMrr(BaseReg, Offset));
585
586  Operands.push_back(Offset);
587  return MatchOperand_Success;
588}
589
590SparcAsmParser::OperandMatchResultTy SparcAsmParser::
591parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
592             StringRef Mnemonic)
593{
594
595  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
596
597  // If there wasn't a custom match, try the generic matcher below. Otherwise,
598  // there was a match, but an error occurred, in which case, just return that
599  // the operand parsing failed.
600  if (ResTy == MatchOperand_Success || ResTy == MatchOperand_ParseFail)
601    return ResTy;
602
603  if (getLexer().is(AsmToken::LBrac)) {
604    // Memory operand
605    Operands.push_back(SparcOperand::CreateToken("[",
606                                                 Parser.getTok().getLoc()));
607    Parser.Lex(); // Eat the [
608
609    if (Mnemonic == "cas" || Mnemonic == "casx") {
610      SMLoc S = Parser.getTok().getLoc();
611      if (getLexer().getKind() != AsmToken::Percent)
612        return MatchOperand_NoMatch;
613      Parser.Lex(); // eat %
614
615      unsigned RegNo, RegKind;
616      if (!matchRegisterName(Parser.getTok(), RegNo, RegKind))
617        return MatchOperand_NoMatch;
618
619      Parser.Lex(); // Eat the identifier token.
620      SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer()-1);
621      Operands.push_back(SparcOperand::CreateReg(RegNo, RegKind, S, E));
622      ResTy = MatchOperand_Success;
623    } else {
624      ResTy = parseMEMOperand(Operands);
625    }
626
627    if (ResTy != MatchOperand_Success)
628      return ResTy;
629
630    if (!getLexer().is(AsmToken::RBrac))
631      return MatchOperand_ParseFail;
632
633    Operands.push_back(SparcOperand::CreateToken("]",
634                                                 Parser.getTok().getLoc()));
635    Parser.Lex(); // Eat the ]
636    return MatchOperand_Success;
637  }
638
639  SparcOperand *Op = 0;
640
641  ResTy = parseSparcAsmOperand(Op, (Mnemonic == "call"));
642  if (ResTy != MatchOperand_Success || !Op)
643    return MatchOperand_ParseFail;
644
645  // Push the parsed operand into the list of operands
646  Operands.push_back(Op);
647
648  return MatchOperand_Success;
649}
650
651SparcAsmParser::OperandMatchResultTy
652SparcAsmParser::parseSparcAsmOperand(SparcOperand *&Op, bool isCall)
653{
654
655  SMLoc S = Parser.getTok().getLoc();
656  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
657  const MCExpr *EVal;
658
659  Op = 0;
660  switch (getLexer().getKind()) {
661  default:  break;
662
663  case AsmToken::Percent:
664    Parser.Lex(); // Eat the '%'.
665    unsigned RegNo;
666    unsigned RegKind;
667    if (matchRegisterName(Parser.getTok(), RegNo, RegKind)) {
668      StringRef name = Parser.getTok().getString();
669      Parser.Lex(); // Eat the identifier token.
670      E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
671      switch (RegNo) {
672      default:
673        Op = SparcOperand::CreateReg(RegNo, RegKind, S, E);
674        break;
675      case Sparc::Y:
676        Op = SparcOperand::CreateToken("%y", S);
677        break;
678
679      case Sparc::ICC:
680        if (name == "xcc")
681          Op = SparcOperand::CreateToken("%xcc", S);
682        else
683          Op = SparcOperand::CreateToken("%icc", S);
684        break;
685      }
686      break;
687    }
688    if (matchSparcAsmModifiers(EVal, E)) {
689      E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
690      Op = SparcOperand::CreateImm(EVal, S, E);
691    }
692    break;
693
694  case AsmToken::Minus:
695  case AsmToken::Integer:
696    if (!getParser().parseExpression(EVal, E))
697      Op = SparcOperand::CreateImm(EVal, S, E);
698    break;
699
700  case AsmToken::Identifier: {
701    StringRef Identifier;
702    if (!getParser().parseIdentifier(Identifier)) {
703      E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
704      MCSymbol *Sym = getContext().GetOrCreateSymbol(Identifier);
705
706      const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
707                                                  getContext());
708      if (isCall &&
709          getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_)
710        Res = SparcMCExpr::Create(SparcMCExpr::VK_Sparc_WPLT30, Res,
711                                  getContext());
712      Op = SparcOperand::CreateImm(Res, S, E);
713    }
714    break;
715  }
716  }
717  return (Op) ? MatchOperand_Success : MatchOperand_ParseFail;
718}
719
720SparcAsmParser::OperandMatchResultTy SparcAsmParser::
721parseBranchModifiers(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
722
723  // parse (,a|,pn|,pt)+
724
725  while (getLexer().is(AsmToken::Comma)) {
726
727    Parser.Lex(); // Eat the comma
728
729    if (!getLexer().is(AsmToken::Identifier))
730      return MatchOperand_ParseFail;
731    StringRef modName = Parser.getTok().getString();
732    if (modName == "a" || modName == "pn" || modName == "pt") {
733      Operands.push_back(SparcOperand::CreateToken(modName,
734                                                   Parser.getTok().getLoc()));
735      Parser.Lex(); // eat the identifier.
736    }
737  }
738  return MatchOperand_Success;
739}
740
741bool SparcAsmParser::matchRegisterName(const AsmToken &Tok,
742                                       unsigned &RegNo,
743                                       unsigned &RegKind)
744{
745  int64_t intVal = 0;
746  RegNo = 0;
747  RegKind = SparcOperand::rk_None;
748  if (Tok.is(AsmToken::Identifier)) {
749    StringRef name = Tok.getString();
750
751    // %fp
752    if (name.equals("fp")) {
753      RegNo = Sparc::I6;
754      RegKind = SparcOperand::rk_IntReg;
755      return true;
756    }
757    // %sp
758    if (name.equals("sp")) {
759      RegNo = Sparc::O6;
760      RegKind = SparcOperand::rk_IntReg;
761      return true;
762    }
763
764    if (name.equals("y")) {
765      RegNo = Sparc::Y;
766      RegKind = SparcOperand::rk_Y;
767      return true;
768    }
769
770    if (name.equals("icc")) {
771      RegNo = Sparc::ICC;
772      RegKind = SparcOperand::rk_CCReg;
773      return true;
774    }
775
776    if (name.equals("xcc")) {
777      // FIXME:: check 64bit.
778      RegNo = Sparc::ICC;
779      RegKind = SparcOperand::rk_CCReg;
780      return true;
781    }
782
783    // %fcc0 - %fcc3
784    if (name.substr(0, 3).equals_lower("fcc")
785        && !name.substr(3).getAsInteger(10, intVal)
786        && intVal < 4) {
787      // FIXME: check 64bit and  handle %fcc1 - %fcc3
788      RegNo = Sparc::FCC0 + intVal;
789      RegKind = SparcOperand::rk_CCReg;
790      return true;
791    }
792
793    // %g0 - %g7
794    if (name.substr(0, 1).equals_lower("g")
795        && !name.substr(1).getAsInteger(10, intVal)
796        && intVal < 8) {
797      RegNo = IntRegs[intVal];
798      RegKind = SparcOperand::rk_IntReg;
799      return true;
800    }
801    // %o0 - %o7
802    if (name.substr(0, 1).equals_lower("o")
803        && !name.substr(1).getAsInteger(10, intVal)
804        && intVal < 8) {
805      RegNo = IntRegs[8 + intVal];
806      RegKind = SparcOperand::rk_IntReg;
807      return true;
808    }
809    if (name.substr(0, 1).equals_lower("l")
810        && !name.substr(1).getAsInteger(10, intVal)
811        && intVal < 8) {
812      RegNo = IntRegs[16 + intVal];
813      RegKind = SparcOperand::rk_IntReg;
814      return true;
815    }
816    if (name.substr(0, 1).equals_lower("i")
817        && !name.substr(1).getAsInteger(10, intVal)
818        && intVal < 8) {
819      RegNo = IntRegs[24 + intVal];
820      RegKind = SparcOperand::rk_IntReg;
821      return true;
822    }
823    // %f0 - %f31
824    if (name.substr(0, 1).equals_lower("f")
825        && !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 32) {
826      RegNo = FloatRegs[intVal];
827      RegKind = SparcOperand::rk_FloatReg;
828      return true;
829    }
830    // %f32 - %f62
831    if (name.substr(0, 1).equals_lower("f")
832        && !name.substr(1, 2).getAsInteger(10, intVal)
833        && intVal >= 32 && intVal <= 62 && (intVal % 2 == 0)) {
834      // FIXME: Check V9
835      RegNo = DoubleRegs[intVal/2];
836      RegKind = SparcOperand::rk_DoubleReg;
837      return true;
838    }
839
840    // %r0 - %r31
841    if (name.substr(0, 1).equals_lower("r")
842        && !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 31) {
843      RegNo = IntRegs[intVal];
844      RegKind = SparcOperand::rk_IntReg;
845      return true;
846    }
847  }
848  return false;
849}
850
851static bool hasGOTReference(const MCExpr *Expr) {
852  switch (Expr->getKind()) {
853  case MCExpr::Target:
854    if (const SparcMCExpr *SE = dyn_cast<SparcMCExpr>(Expr))
855      return hasGOTReference(SE->getSubExpr());
856    break;
857
858  case MCExpr::Constant:
859    break;
860
861  case MCExpr::Binary: {
862    const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);
863    return hasGOTReference(BE->getLHS()) || hasGOTReference(BE->getRHS());
864  }
865
866  case MCExpr::SymbolRef: {
867    const MCSymbolRefExpr &SymRef = *cast<MCSymbolRefExpr>(Expr);
868    return (SymRef.getSymbol().getName() == "_GLOBAL_OFFSET_TABLE_");
869  }
870
871  case MCExpr::Unary:
872    return hasGOTReference(cast<MCUnaryExpr>(Expr)->getSubExpr());
873  }
874  return false;
875}
876
877bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal,
878                                            SMLoc &EndLoc)
879{
880  AsmToken Tok = Parser.getTok();
881  if (!Tok.is(AsmToken::Identifier))
882    return false;
883
884  StringRef name = Tok.getString();
885
886  SparcMCExpr::VariantKind VK = SparcMCExpr::parseVariantKind(name);
887
888  if (VK == SparcMCExpr::VK_Sparc_None)
889    return false;
890
891  Parser.Lex(); // Eat the identifier.
892  if (Parser.getTok().getKind() != AsmToken::LParen)
893    return false;
894
895  Parser.Lex(); // Eat the LParen token.
896  const MCExpr *subExpr;
897  if (Parser.parseParenExpression(subExpr, EndLoc))
898    return false;
899
900  bool isPIC = getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_;
901
902  switch(VK) {
903  default: break;
904  case SparcMCExpr::VK_Sparc_LO:
905    VK =  (hasGOTReference(subExpr)
906           ? SparcMCExpr::VK_Sparc_PC10
907           : (isPIC ? SparcMCExpr::VK_Sparc_GOT10 : VK));
908    break;
909  case SparcMCExpr::VK_Sparc_HI:
910    VK =  (hasGOTReference(subExpr)
911           ? SparcMCExpr::VK_Sparc_PC22
912           : (isPIC ? SparcMCExpr::VK_Sparc_GOT22 : VK));
913    break;
914  }
915
916  EVal = SparcMCExpr::Create(VK, subExpr, getContext());
917  return true;
918}
919
920
921extern "C" void LLVMInitializeSparcAsmParser() {
922  RegisterMCAsmParser<SparcAsmParser> A(TheSparcTarget);
923  RegisterMCAsmParser<SparcAsmParser> B(TheSparcV9Target);
924}
925
926#define GET_REGISTER_MATCHER
927#define GET_MATCHER_IMPLEMENTATION
928#include "SparcGenAsmMatcher.inc"
929
930
931
932unsigned SparcAsmParser::
933validateTargetOperandClass(MCParsedAsmOperand *GOp,
934                           unsigned Kind)
935{
936  SparcOperand *Op = (SparcOperand*)GOp;
937  if (Op->isFloatOrDoubleReg()) {
938    switch (Kind) {
939    default: break;
940    case MCK_DFPRegs:
941      if (!Op->isFloatReg() || SparcOperand::MorphToDoubleReg(Op))
942        return MCTargetAsmParser::Match_Success;
943      break;
944    case MCK_QFPRegs:
945      if (SparcOperand::MorphToQuadReg(Op))
946        return MCTargetAsmParser::Match_Success;
947      break;
948    }
949  }
950  return Match_InvalidOperand;
951}
952