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