MipsAsmParser.cpp revision b15da6dc09fdf2699146cd4317f3a43e70397553
1//===-- MipsAsmParser.cpp - Parse Mips 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/MipsMCTargetDesc.h"
11#include "MipsRegisterInfo.h"
12#include "llvm/ADT/StringSwitch.h"
13#include "llvm/MC/MCContext.h"
14#include "llvm/MC/MCExpr.h"
15#include "llvm/MC/MCInst.h"
16#include "llvm/MC/MCParser/MCAsmLexer.h"
17#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
18#include "llvm/MC/MCStreamer.h"
19#include "llvm/MC/MCSubtargetInfo.h"
20#include "llvm/MC/MCSymbol.h"
21#include "llvm/MC/MCTargetAsmParser.h"
22#include "llvm/Support/TargetRegistry.h"
23#include "llvm/ADT/APInt.h"
24
25using namespace llvm;
26
27namespace {
28class MipsAssemblerOptions {
29public:
30  MipsAssemblerOptions():
31    aTReg(1), reorder(true), macro(true) {
32  }
33
34  unsigned getATRegNum() {return aTReg;}
35  bool setATReg(unsigned Reg);
36
37  bool isReorder() {return reorder;}
38  void setReorder() {reorder = true;}
39  void setNoreorder() {reorder = false;}
40
41  bool isMacro() {return macro;}
42  void setMacro() {macro = true;}
43  void setNomacro() {macro = false;}
44
45private:
46  unsigned aTReg;
47  bool reorder;
48  bool macro;
49};
50}
51
52namespace {
53class MipsAsmParser : public MCTargetAsmParser {
54
55  MCSubtargetInfo &STI;
56  MCAsmParser &Parser;
57  MipsAssemblerOptions Options;
58  bool hasConsumedDollar;
59
60#define GET_ASSEMBLER_HEADER
61#include "MipsGenAsmMatcher.inc"
62
63  bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
64                               SmallVectorImpl<MCParsedAsmOperand*> &Operands,
65                               MCStreamer &Out, unsigned &ErrorInfo,
66                               bool MatchingInlineAsm);
67
68  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
69
70  bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
71                        SMLoc NameLoc,
72                        SmallVectorImpl<MCParsedAsmOperand*> &Operands);
73
74  bool ParseDirective(AsmToken DirectiveID);
75
76  MipsAsmParser::OperandMatchResultTy
77  parseRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
78                         int RegKind);
79
80  MipsAsmParser::OperandMatchResultTy
81  parseMemOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
82
83  bool parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands, int RegKind);
84
85  MipsAsmParser::OperandMatchResultTy
86  parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
87
88  MipsAsmParser::OperandMatchResultTy
89  parseGPR32(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
90
91  MipsAsmParser::OperandMatchResultTy
92  parseGPR64(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
93
94  MipsAsmParser::OperandMatchResultTy
95  parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
96
97  MipsAsmParser::OperandMatchResultTy
98  parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
99
100  MipsAsmParser::OperandMatchResultTy
101  parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
102
103  MipsAsmParser::OperandMatchResultTy
104  parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
105
106  MipsAsmParser::OperandMatchResultTy
107  parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
108
109  MipsAsmParser::OperandMatchResultTy
110  parseFGRH32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
111
112  MipsAsmParser::OperandMatchResultTy
113  parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
114
115  MipsAsmParser::OperandMatchResultTy
116  parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
117
118  MipsAsmParser::OperandMatchResultTy
119  parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
120
121  MipsAsmParser::OperandMatchResultTy
122  parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
123
124  bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
125                         unsigned RegKind);
126
127  bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &,
128                    StringRef Mnemonic);
129
130  int tryParseRegister(bool is64BitReg);
131
132  bool tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
133                               bool is64BitReg);
134
135  bool needsExpansion(MCInst &Inst);
136
137  void expandInstruction(MCInst &Inst, SMLoc IDLoc,
138                         SmallVectorImpl<MCInst> &Instructions);
139  void expandLoadImm(MCInst &Inst, SMLoc IDLoc,
140                     SmallVectorImpl<MCInst> &Instructions);
141  void expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
142                            SmallVectorImpl<MCInst> &Instructions);
143  void expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
144                            SmallVectorImpl<MCInst> &Instructions);
145  void expandMemInst(MCInst &Inst, SMLoc IDLoc,
146                     SmallVectorImpl<MCInst> &Instructions,
147                     bool isLoad,bool isImmOpnd);
148  bool reportParseError(StringRef ErrorMsg);
149
150  bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
151  bool parseRelocOperand(const MCExpr *&Res);
152
153  const MCExpr* evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
154
155  bool isEvaluated(const MCExpr *Expr);
156  bool parseDirectiveSet();
157
158  bool parseSetAtDirective();
159  bool parseSetNoAtDirective();
160  bool parseSetMacroDirective();
161  bool parseSetNoMacroDirective();
162  bool parseSetReorderDirective();
163  bool parseSetNoReorderDirective();
164
165  bool parseSetAssignment();
166
167  bool parseDirectiveWord(unsigned Size, SMLoc L);
168
169  MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
170
171  bool isMips64() const {
172    return (STI.getFeatureBits() & Mips::FeatureMips64) != 0;
173  }
174
175  bool isFP64() const {
176    return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0;
177  }
178
179  bool isN64() const {
180    return STI.getFeatureBits() & Mips::FeatureN64;
181  }
182
183  int matchRegisterName(StringRef Symbol, bool is64BitReg);
184
185  int matchCPURegisterName(StringRef Symbol);
186
187  int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
188
189  int matchFPURegisterName(StringRef Name);
190
191  int matchFCCRegisterName(StringRef Name);
192
193  int matchACRegisterName(StringRef Name);
194
195  int regKindToRegClass(int RegKind);
196
197  unsigned getReg(int RC, int RegNo);
198
199  int getATReg();
200
201  bool processInstruction(MCInst &Inst, SMLoc IDLoc,
202                        SmallVectorImpl<MCInst> &Instructions);
203public:
204  MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser)
205    : MCTargetAsmParser(), STI(sti), Parser(parser), hasConsumedDollar(false) {
206    // Initialize the set of available features.
207    setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
208  }
209
210  MCAsmParser &getParser() const { return Parser; }
211  MCAsmLexer &getLexer() const { return Parser.getLexer(); }
212
213};
214}
215
216namespace {
217
218/// MipsOperand - Instances of this class represent a parsed Mips machine
219/// instruction.
220class MipsOperand : public MCParsedAsmOperand {
221
222public:
223  enum RegisterKind {
224    Kind_None,
225    Kind_GPR32,
226    Kind_GPR64,
227    Kind_HWRegs,
228    Kind_FGR32Regs,
229    Kind_FGRH32Regs,
230    Kind_FGR64Regs,
231    Kind_AFGR64Regs,
232    Kind_CCRRegs,
233    Kind_FCCRegs,
234    Kind_ACC64DSP,
235    Kind_LO32DSP,
236    Kind_HI32DSP
237  };
238
239private:
240  enum KindTy {
241    k_CondCode,
242    k_CoprocNum,
243    k_Immediate,
244    k_Memory,
245    k_PostIndexRegister,
246    k_Register,
247    k_PtrReg,
248    k_Token
249  } Kind;
250
251  MipsOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
252
253  struct Token {
254    const char *Data;
255    unsigned Length;
256  };
257
258  struct RegOp {
259    unsigned RegNum;
260    RegisterKind Kind;
261  };
262
263  struct ImmOp {
264    const MCExpr *Val;
265  };
266
267  struct MemOp {
268    unsigned Base;
269    const MCExpr *Off;
270  };
271
272  union {
273    struct Token Tok;
274    struct RegOp Reg;
275    struct ImmOp Imm;
276    struct MemOp Mem;
277  };
278
279  SMLoc StartLoc, EndLoc;
280
281public:
282  void addRegOperands(MCInst &Inst, unsigned N) const {
283    assert(N == 1 && "Invalid number of operands!");
284    Inst.addOperand(MCOperand::CreateReg(getReg()));
285  }
286
287  void addPtrRegOperands(MCInst &Inst, unsigned N) const {
288    assert(N == 1 && "Invalid number of operands!");
289    Inst.addOperand(MCOperand::CreateReg(getPtrReg()));
290  }
291
292  void addExpr(MCInst &Inst, const MCExpr *Expr) const{
293    // Add as immediate when possible.  Null MCExpr = 0.
294    if (Expr == 0)
295      Inst.addOperand(MCOperand::CreateImm(0));
296    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
297      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
298    else
299      Inst.addOperand(MCOperand::CreateExpr(Expr));
300  }
301
302  void addImmOperands(MCInst &Inst, unsigned N) const {
303    assert(N == 1 && "Invalid number of operands!");
304    const MCExpr *Expr = getImm();
305    addExpr(Inst, Expr);
306  }
307
308  void addMemOperands(MCInst &Inst, unsigned N) const {
309    assert(N == 2 && "Invalid number of operands!");
310
311    Inst.addOperand(MCOperand::CreateReg(getMemBase()));
312
313    const MCExpr *Expr = getMemOff();
314    addExpr(Inst, Expr);
315  }
316
317  bool isReg() const { return Kind == k_Register; }
318  bool isImm() const { return Kind == k_Immediate; }
319  bool isToken() const { return Kind == k_Token; }
320  bool isMem() const { return Kind == k_Memory; }
321  bool isPtrReg() const { return Kind == k_PtrReg; }
322
323  StringRef getToken() const {
324    assert(Kind == k_Token && "Invalid access!");
325    return StringRef(Tok.Data, Tok.Length);
326  }
327
328  unsigned getReg() const {
329    assert((Kind == k_Register) && "Invalid access!");
330    return Reg.RegNum;
331  }
332
333  unsigned getPtrReg() const {
334    assert((Kind == k_PtrReg) && "Invalid access!");
335    return Reg.RegNum;
336  }
337
338  void setRegKind(RegisterKind RegKind) {
339    assert((Kind == k_Register || Kind == k_PtrReg) && "Invalid access!");
340    Reg.Kind = RegKind;
341  }
342
343  const MCExpr *getImm() const {
344    assert((Kind == k_Immediate) && "Invalid access!");
345    return Imm.Val;
346  }
347
348  unsigned getMemBase() const {
349    assert((Kind == k_Memory) && "Invalid access!");
350    return Mem.Base;
351  }
352
353  const MCExpr *getMemOff() const {
354    assert((Kind == k_Memory) && "Invalid access!");
355    return Mem.Off;
356  }
357
358  static MipsOperand *CreateToken(StringRef Str, SMLoc S) {
359    MipsOperand *Op = new MipsOperand(k_Token);
360    Op->Tok.Data = Str.data();
361    Op->Tok.Length = Str.size();
362    Op->StartLoc = S;
363    Op->EndLoc = S;
364    return Op;
365  }
366
367  static MipsOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
368    MipsOperand *Op = new MipsOperand(k_Register);
369    Op->Reg.RegNum = RegNum;
370    Op->StartLoc = S;
371    Op->EndLoc = E;
372    return Op;
373  }
374
375  static MipsOperand *CreatePtrReg(unsigned RegNum, SMLoc S, SMLoc E) {
376    MipsOperand *Op = new MipsOperand(k_PtrReg);
377    Op->Reg.RegNum = RegNum;
378    Op->StartLoc = S;
379    Op->EndLoc = E;
380    return Op;
381  }
382
383  static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
384    MipsOperand *Op = new MipsOperand(k_Immediate);
385    Op->Imm.Val = Val;
386    Op->StartLoc = S;
387    Op->EndLoc = E;
388    return Op;
389  }
390
391  static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off,
392                                 SMLoc S, SMLoc E) {
393    MipsOperand *Op = new MipsOperand(k_Memory);
394    Op->Mem.Base = Base;
395    Op->Mem.Off = Off;
396    Op->StartLoc = S;
397    Op->EndLoc = E;
398    return Op;
399  }
400
401  bool isGPR32Asm() const {
402    return Kind == k_Register && Reg.Kind == Kind_GPR32;
403  }
404  void addRegAsmOperands(MCInst &Inst, unsigned N) const {
405    Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
406  }
407
408  bool isGPR64Asm() const {
409    return Kind == k_Register && Reg.Kind == Kind_GPR64;
410  }
411
412  bool isHWRegsAsm() const {
413    assert((Kind == k_Register) && "Invalid access!");
414    return Reg.Kind == Kind_HWRegs;
415  }
416
417  bool isCCRAsm() const {
418    assert((Kind == k_Register) && "Invalid access!");
419    return Reg.Kind == Kind_CCRRegs;
420  }
421
422   bool isAFGR64Asm() const {
423    return Kind == k_Register && Reg.Kind == Kind_AFGR64Regs;
424  }
425
426  bool isFGR64Asm() const {
427    return Kind == k_Register && Reg.Kind == Kind_FGR64Regs;
428  }
429
430  bool isFGR32Asm() const {
431    return (Kind == k_Register) && Reg.Kind == Kind_FGR32Regs;
432  }
433
434  bool isFGRH32Asm() const {
435    return (Kind == k_Register) && Reg.Kind == Kind_FGRH32Regs;
436  }
437
438  bool isFCCRegsAsm() const {
439    return (Kind == k_Register) && Reg.Kind == Kind_FCCRegs;
440  }
441
442  bool isACC64DSPAsm() const {
443    return Kind == k_Register && Reg.Kind == Kind_ACC64DSP;
444  }
445
446  bool isLO32DSPAsm() const {
447    return Kind == k_Register && Reg.Kind == Kind_LO32DSP;
448  }
449
450  bool isHI32DSPAsm() const {
451    return Kind == k_Register && Reg.Kind == Kind_HI32DSP;
452  }
453
454  /// getStartLoc - Get the location of the first token of this operand.
455  SMLoc getStartLoc() const {
456    return StartLoc;
457  }
458  /// getEndLoc - Get the location of the last token of this operand.
459  SMLoc getEndLoc() const {
460    return EndLoc;
461  }
462
463  virtual void print(raw_ostream &OS) const {
464    llvm_unreachable("unimplemented!");
465  }
466}; // class MipsOperand
467}  // namespace
468
469namespace llvm {
470extern const MCInstrDesc MipsInsts[];
471}
472static const MCInstrDesc &getInstDesc(unsigned Opcode) {
473  return MipsInsts[Opcode];
474}
475
476bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
477                                       SmallVectorImpl<MCInst> &Instructions) {
478  const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
479  Inst.setLoc(IDLoc);
480  if (MCID.hasDelaySlot() && Options.isReorder()) {
481    // If this instruction has a delay slot and .set reorder is active,
482    // emit a NOP after it.
483    Instructions.push_back(Inst);
484    MCInst NopInst;
485    NopInst.setOpcode(Mips::SLL);
486    NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
487    NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
488    NopInst.addOperand(MCOperand::CreateImm(0));
489    Instructions.push_back(NopInst);
490    return false;
491  }
492
493  if (MCID.mayLoad() || MCID.mayStore()) {
494    // Check the offset of memory operand, if it is a symbol
495    // reference or immediate we may have to expand instructions.
496    for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
497      const MCOperandInfo &OpInfo = MCID.OpInfo[i];
498      if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY)
499          || (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
500        MCOperand &Op = Inst.getOperand(i);
501        if (Op.isImm()) {
502          int MemOffset = Op.getImm();
503          if (MemOffset < -32768 || MemOffset > 32767) {
504            // Offset can't exceed 16bit value.
505            expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
506            return false;
507          }
508        } else if (Op.isExpr()) {
509          const MCExpr *Expr = Op.getExpr();
510          if (Expr->getKind() == MCExpr::SymbolRef) {
511            const MCSymbolRefExpr *SR =
512                static_cast<const MCSymbolRefExpr*>(Expr);
513            if (SR->getKind() == MCSymbolRefExpr::VK_None) {
514              // Expand symbol.
515              expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
516              return false;
517            }
518          } else if (!isEvaluated(Expr)) {
519            expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
520            return false;
521          }
522        }
523      }
524    } // for
525  } // if load/store
526
527  if (needsExpansion(Inst))
528    expandInstruction(Inst, IDLoc, Instructions);
529  else
530    Instructions.push_back(Inst);
531
532  return false;
533}
534
535bool MipsAsmParser::needsExpansion(MCInst &Inst) {
536
537  switch (Inst.getOpcode()) {
538  case Mips::LoadImm32Reg:
539  case Mips::LoadAddr32Imm:
540  case Mips::LoadAddr32Reg:
541    return true;
542  default:
543    return false;
544  }
545}
546
547void MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
548                                       SmallVectorImpl<MCInst> &Instructions) {
549  switch (Inst.getOpcode()) {
550  case Mips::LoadImm32Reg:
551    return expandLoadImm(Inst, IDLoc, Instructions);
552  case Mips::LoadAddr32Imm:
553    return expandLoadAddressImm(Inst, IDLoc, Instructions);
554  case Mips::LoadAddr32Reg:
555    return expandLoadAddressReg(Inst, IDLoc, Instructions);
556  }
557}
558
559void MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
560                                  SmallVectorImpl<MCInst> &Instructions) {
561  MCInst tmpInst;
562  const MCOperand &ImmOp = Inst.getOperand(1);
563  assert(ImmOp.isImm() && "expected immediate operand kind");
564  const MCOperand &RegOp = Inst.getOperand(0);
565  assert(RegOp.isReg() && "expected register operand kind");
566
567  int ImmValue = ImmOp.getImm();
568  tmpInst.setLoc(IDLoc);
569  if (0 <= ImmValue && ImmValue <= 65535) {
570    // For 0 <= j <= 65535.
571    // li d,j => ori d,$zero,j
572    tmpInst.setOpcode(Mips::ORi);
573    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
574    tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
575    tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
576    Instructions.push_back(tmpInst);
577  } else if (ImmValue < 0 && ImmValue >= -32768) {
578    // For -32768 <= j < 0.
579    // li d,j => addiu d,$zero,j
580    tmpInst.setOpcode(Mips::ADDiu);
581    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
582    tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
583    tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
584    Instructions.push_back(tmpInst);
585  } else {
586    // For any other value of j that is representable as a 32-bit integer.
587    // li d,j => lui d,hi16(j)
588    //           ori d,d,lo16(j)
589    tmpInst.setOpcode(Mips::LUi);
590    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
591    tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
592    Instructions.push_back(tmpInst);
593    tmpInst.clear();
594    tmpInst.setOpcode(Mips::ORi);
595    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
596    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
597    tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
598    tmpInst.setLoc(IDLoc);
599    Instructions.push_back(tmpInst);
600  }
601}
602
603void MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
604                                       SmallVectorImpl<MCInst> &Instructions) {
605  MCInst tmpInst;
606  const MCOperand &ImmOp = Inst.getOperand(2);
607  assert(ImmOp.isImm() && "expected immediate operand kind");
608  const MCOperand &SrcRegOp = Inst.getOperand(1);
609  assert(SrcRegOp.isReg() && "expected register operand kind");
610  const MCOperand &DstRegOp = Inst.getOperand(0);
611  assert(DstRegOp.isReg() && "expected register operand kind");
612  int ImmValue = ImmOp.getImm();
613  if (-32768 <= ImmValue && ImmValue <= 65535) {
614    // For -32768 <= j <= 65535.
615    // la d,j(s) => addiu d,s,j
616    tmpInst.setOpcode(Mips::ADDiu);
617    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
618    tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
619    tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
620    Instructions.push_back(tmpInst);
621  } else {
622    // For any other value of j that is representable as a 32-bit integer.
623    // la d,j(s) => lui d,hi16(j)
624    //              ori d,d,lo16(j)
625    //              addu d,d,s
626    tmpInst.setOpcode(Mips::LUi);
627    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
628    tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
629    Instructions.push_back(tmpInst);
630    tmpInst.clear();
631    tmpInst.setOpcode(Mips::ORi);
632    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
633    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
634    tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
635    Instructions.push_back(tmpInst);
636    tmpInst.clear();
637    tmpInst.setOpcode(Mips::ADDu);
638    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
639    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
640    tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
641    Instructions.push_back(tmpInst);
642  }
643}
644
645void MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
646                                       SmallVectorImpl<MCInst> &Instructions) {
647  MCInst tmpInst;
648  const MCOperand &ImmOp = Inst.getOperand(1);
649  assert(ImmOp.isImm() && "expected immediate operand kind");
650  const MCOperand &RegOp = Inst.getOperand(0);
651  assert(RegOp.isReg() && "expected register operand kind");
652  int ImmValue = ImmOp.getImm();
653  if (-32768 <= ImmValue && ImmValue <= 65535) {
654    // For -32768 <= j <= 65535.
655    // la d,j => addiu d,$zero,j
656    tmpInst.setOpcode(Mips::ADDiu);
657    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
658    tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
659    tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
660    Instructions.push_back(tmpInst);
661  } else {
662    // For any other value of j that is representable as a 32-bit integer.
663    // la d,j => lui d,hi16(j)
664    //           ori d,d,lo16(j)
665    tmpInst.setOpcode(Mips::LUi);
666    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
667    tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
668    Instructions.push_back(tmpInst);
669    tmpInst.clear();
670    tmpInst.setOpcode(Mips::ORi);
671    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
672    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
673    tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
674    Instructions.push_back(tmpInst);
675  }
676}
677
678void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
679          SmallVectorImpl<MCInst> &Instructions, bool isLoad, bool isImmOpnd) {
680  const MCSymbolRefExpr *SR;
681  MCInst TempInst;
682  unsigned ImmOffset, HiOffset, LoOffset;
683  const MCExpr *ExprOffset;
684  unsigned TmpRegNum;
685  unsigned AtRegNum = getReg((isMips64()) ? Mips::GPR64RegClassID
686                             : Mips::GPR32RegClassID, getATReg());
687  // 1st operand is either the source or destination register.
688  assert(Inst.getOperand(0).isReg() && "expected register operand kind");
689  unsigned RegOpNum = Inst.getOperand(0).getReg();
690  // 2nd operand is the base register.
691  assert(Inst.getOperand(1).isReg() && "expected register operand kind");
692  unsigned BaseRegNum = Inst.getOperand(1).getReg();
693  // 3rd operand is either an immediate or expression.
694  if (isImmOpnd) {
695    assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
696    ImmOffset = Inst.getOperand(2).getImm();
697    LoOffset = ImmOffset & 0x0000ffff;
698    HiOffset = (ImmOffset & 0xffff0000) >> 16;
699    // If msb of LoOffset is 1(negative number) we must increment HiOffset.
700    if (LoOffset & 0x8000)
701      HiOffset++;
702  } else
703    ExprOffset = Inst.getOperand(2).getExpr();
704  // All instructions will have the same location.
705  TempInst.setLoc(IDLoc);
706  // 1st instruction in expansion is LUi. For load instruction we can use
707  // the dst register as a temporary if base and dst are different,
708  // but for stores we must use $at.
709  TmpRegNum = (isLoad && (BaseRegNum != RegOpNum)) ? RegOpNum : AtRegNum;
710  TempInst.setOpcode(Mips::LUi);
711  TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
712  if (isImmOpnd)
713    TempInst.addOperand(MCOperand::CreateImm(HiOffset));
714  else {
715    if (ExprOffset->getKind() == MCExpr::SymbolRef) {
716      SR = static_cast<const MCSymbolRefExpr*>(ExprOffset);
717      const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
718          SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
719          getContext());
720      TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
721    } else {
722      const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
723      TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
724    }
725  }
726  // Add the instruction to the list.
727  Instructions.push_back(TempInst);
728  // Prepare TempInst for next instruction.
729  TempInst.clear();
730  // Add temp register to base.
731  TempInst.setOpcode(Mips::ADDu);
732  TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
733  TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
734  TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
735  Instructions.push_back(TempInst);
736  TempInst.clear();
737  // And finaly, create original instruction with low part
738  // of offset and new base.
739  TempInst.setOpcode(Inst.getOpcode());
740  TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
741  TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
742  if (isImmOpnd)
743    TempInst.addOperand(MCOperand::CreateImm(LoOffset));
744  else {
745    if (ExprOffset->getKind() == MCExpr::SymbolRef) {
746      const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
747          SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
748          getContext());
749      TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
750    } else {
751      const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
752      TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
753    }
754  }
755  Instructions.push_back(TempInst);
756  TempInst.clear();
757}
758
759bool MipsAsmParser::
760MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
761                        SmallVectorImpl<MCParsedAsmOperand*> &Operands,
762                        MCStreamer &Out, unsigned &ErrorInfo,
763                        bool MatchingInlineAsm) {
764  MCInst Inst;
765  SmallVector<MCInst, 8> Instructions;
766  unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
767                                              MatchingInlineAsm);
768
769  switch (MatchResult) {
770  default:
771    break;
772  case Match_Success: {
773    if (processInstruction(Inst, IDLoc, Instructions))
774      return true;
775    for (unsigned i = 0; i < Instructions.size(); i++)
776      Out.EmitInstruction(Instructions[i]);
777    return false;
778  }
779  case Match_MissingFeature:
780    Error(IDLoc, "instruction requires a CPU feature not currently enabled");
781    return true;
782  case Match_InvalidOperand: {
783    SMLoc ErrorLoc = IDLoc;
784    if (ErrorInfo != ~0U) {
785      if (ErrorInfo >= Operands.size())
786        return Error(IDLoc, "too few operands for instruction");
787
788      ErrorLoc = ((MipsOperand*) Operands[ErrorInfo])->getStartLoc();
789      if (ErrorLoc == SMLoc())
790        ErrorLoc = IDLoc;
791    }
792
793    return Error(ErrorLoc, "invalid operand for instruction");
794  }
795  case Match_MnemonicFail:
796    return Error(IDLoc, "invalid instruction");
797  }
798  return true;
799}
800
801int MipsAsmParser::matchCPURegisterName(StringRef Name) {
802   int CC;
803
804  if (Name == "at")
805    return getATReg();
806
807    CC = StringSwitch<unsigned>(Name)
808    .Case("zero", 0)
809    .Case("a0",   4)
810    .Case("a1",   5)
811    .Case("a2",   6)
812    .Case("a3",   7)
813    .Case("v0",   2)
814    .Case("v1",   3)
815    .Case("s0",  16)
816    .Case("s1",  17)
817    .Case("s2",  18)
818    .Case("s3",  19)
819    .Case("s4",  20)
820    .Case("s5",  21)
821    .Case("s6",  22)
822    .Case("s7",  23)
823    .Case("k0",  26)
824    .Case("k1",  27)
825    .Case("sp",  29)
826    .Case("fp",  30)
827    .Case("gp",  28)
828    .Case("ra",  31)
829    .Case("t0",   8)
830    .Case("t1",   9)
831    .Case("t2",  10)
832    .Case("t3",  11)
833    .Case("t4",  12)
834    .Case("t5",  13)
835    .Case("t6",  14)
836    .Case("t7",  15)
837    .Case("t8",  24)
838    .Case("t9",  25)
839    .Default(-1);
840
841  // Although SGI documentation just cuts out t0-t3 for n32/n64,
842  // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
843  // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
844  if (isMips64() && 8 <= CC && CC <= 11)
845    CC += 4;
846
847  if (CC == -1 && isMips64())
848    CC = StringSwitch<unsigned>(Name)
849      .Case("a4",   8)
850      .Case("a5",   9)
851      .Case("a6",  10)
852      .Case("a7",  11)
853      .Case("kt0", 26)
854      .Case("kt1", 27)
855      .Case("s8",  30)
856      .Default(-1);
857
858  return CC;
859}
860
861int MipsAsmParser::matchFPURegisterName(StringRef Name) {
862
863  if (Name[0] == 'f') {
864    StringRef NumString = Name.substr(1);
865    unsigned IntVal;
866    if (NumString.getAsInteger(10, IntVal))
867      return -1; // This is not an integer.
868    if (IntVal > 31) // Maximum index for fpu register.
869      return -1;
870    return IntVal;
871  }
872  return -1;
873}
874
875int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
876
877  if (Name.startswith("fcc")) {
878    StringRef NumString = Name.substr(3);
879    unsigned IntVal;
880    if (NumString.getAsInteger(10, IntVal))
881      return -1; // This is not an integer.
882    if (IntVal > 7) // There are only 8 fcc registers.
883      return -1;
884    return IntVal;
885  }
886  return -1;
887}
888
889int MipsAsmParser::matchACRegisterName(StringRef Name) {
890
891  if (Name.startswith("ac")) {
892    StringRef NumString = Name.substr(2);
893    unsigned IntVal;
894    if (NumString.getAsInteger(10, IntVal))
895      return -1; // This is not an integer.
896    if (IntVal > 3) // There are only 3 acc registers.
897      return -1;
898    return IntVal;
899  }
900  return -1;
901}
902
903int MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) {
904
905  int CC;
906  CC = matchCPURegisterName(Name);
907  if (CC != -1)
908    return matchRegisterByNumber(CC, is64BitReg ? Mips::GPR64RegClassID
909                                                : Mips::GPR32RegClassID);
910  CC= matchFPURegisterName(Name);
911  //TODO: decide about fpu register class
912  return matchRegisterByNumber(CC, isFP64() ? Mips::FGR64RegClassID
913                                                : Mips::FGR32RegClassID);
914}
915
916int MipsAsmParser::regKindToRegClass(int RegKind) {
917
918  switch (RegKind) {
919  case MipsOperand::Kind_GPR32: return Mips::GPR32RegClassID;
920  case MipsOperand::Kind_GPR64: return Mips::GPR64RegClassID;
921  case MipsOperand::Kind_HWRegs: return Mips::HWRegsRegClassID;
922  case MipsOperand::Kind_FGR32Regs: return Mips::FGR32RegClassID;
923  case MipsOperand::Kind_FGRH32Regs: return Mips::FGRH32RegClassID;
924  case MipsOperand::Kind_FGR64Regs: return Mips::FGR64RegClassID;
925  case MipsOperand::Kind_AFGR64Regs: return Mips::AFGR64RegClassID;
926  case MipsOperand::Kind_CCRRegs: return Mips::CCRRegClassID;
927  case MipsOperand::Kind_ACC64DSP: return Mips::ACC64DSPRegClassID;
928  case MipsOperand::Kind_FCCRegs: return Mips::FCCRegClassID;
929  default :return -1;
930  }
931
932}
933
934bool MipsAssemblerOptions::setATReg(unsigned Reg) {
935  if (Reg > 31)
936    return false;
937
938  aTReg = Reg;
939  return true;
940}
941
942int MipsAsmParser::getATReg() {
943  return Options.getATRegNum();
944}
945
946unsigned MipsAsmParser::getReg(int RC, int RegNo) {
947  return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
948}
949
950int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
951  if (RegNum >
952       getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs())
953    return -1;
954
955  return getReg(RegClass, RegNum);
956}
957
958int MipsAsmParser::tryParseRegister(bool is64BitReg) {
959  const AsmToken &Tok = Parser.getTok();
960  int RegNum = -1;
961
962  if (Tok.is(AsmToken::Identifier)) {
963    std::string lowerCase = Tok.getString().lower();
964    RegNum = matchRegisterName(lowerCase, is64BitReg);
965  } else if (Tok.is(AsmToken::Integer))
966    RegNum = matchRegisterByNumber(static_cast<unsigned>(Tok.getIntVal()),
967        is64BitReg ? Mips::GPR64RegClassID : Mips::GPR32RegClassID);
968  return RegNum;
969}
970
971bool MipsAsmParser::tryParseRegisterOperand(
972             SmallVectorImpl<MCParsedAsmOperand*> &Operands, bool is64BitReg) {
973
974  SMLoc S = Parser.getTok().getLoc();
975  int RegNo = -1;
976
977  RegNo = tryParseRegister(is64BitReg);
978  if (RegNo == -1)
979    return true;
980
981  Operands.push_back(MipsOperand::CreateReg(RegNo, S,
982                                            Parser.getTok().getLoc()));
983  Parser.Lex(); // Eat register token.
984  return false;
985}
986
987bool MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*>&Operands,
988                                 StringRef Mnemonic) {
989  // Check if the current operand has a custom associated parser, if so, try to
990  // custom parse the operand, or fallback to the general approach.
991  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
992  if (ResTy == MatchOperand_Success)
993    return false;
994  // If there wasn't a custom match, try the generic matcher below. Otherwise,
995  // there was a match, but an error occurred, in which case, just return that
996  // the operand parsing failed.
997  if (ResTy == MatchOperand_ParseFail)
998    return true;
999
1000  switch (getLexer().getKind()) {
1001  default:
1002    Error(Parser.getTok().getLoc(), "unexpected token in operand");
1003    return true;
1004  case AsmToken::Dollar: {
1005    // Parse the register.
1006    SMLoc S = Parser.getTok().getLoc();
1007    Parser.Lex(); // Eat dollar token.
1008    // Parse the register operand.
1009    if (!tryParseRegisterOperand(Operands, isMips64())) {
1010      if (getLexer().is(AsmToken::LParen)) {
1011        // Check if it is indexed addressing operand.
1012        Operands.push_back(MipsOperand::CreateToken("(", S));
1013        Parser.Lex(); // Eat the parenthesis.
1014        if (getLexer().isNot(AsmToken::Dollar))
1015          return true;
1016
1017        Parser.Lex(); // Eat the dollar
1018        if (tryParseRegisterOperand(Operands, isMips64()))
1019          return true;
1020
1021        if (!getLexer().is(AsmToken::RParen))
1022          return true;
1023
1024        S = Parser.getTok().getLoc();
1025        Operands.push_back(MipsOperand::CreateToken(")", S));
1026        Parser.Lex();
1027      }
1028      return false;
1029    }
1030    // Maybe it is a symbol reference.
1031    StringRef Identifier;
1032    if (Parser.parseIdentifier(Identifier))
1033      return true;
1034
1035    SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1036
1037    MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
1038
1039    // Otherwise create a symbol reference.
1040    const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
1041                                                getContext());
1042
1043    Operands.push_back(MipsOperand::CreateImm(Res, S, E));
1044    return false;
1045  }
1046  case AsmToken::Identifier:
1047    // Look for the existing symbol, we should check if
1048    // we need to assigne the propper RegisterKind.
1049    if (searchSymbolAlias(Operands, MipsOperand::Kind_None))
1050      return false;
1051    // Else drop to expression parsing.
1052  case AsmToken::LParen:
1053  case AsmToken::Minus:
1054  case AsmToken::Plus:
1055  case AsmToken::Integer:
1056  case AsmToken::String: {
1057    // Quoted label names.
1058    const MCExpr *IdVal;
1059    SMLoc S = Parser.getTok().getLoc();
1060    if (getParser().parseExpression(IdVal))
1061      return true;
1062    SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1063    Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1064    return false;
1065  }
1066  case AsmToken::Percent: {
1067    // It is a symbol reference or constant expression.
1068    const MCExpr *IdVal;
1069    SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
1070    if (parseRelocOperand(IdVal))
1071      return true;
1072
1073    SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1074
1075    Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1076    return false;
1077  } // case AsmToken::Percent
1078  } // switch(getLexer().getKind())
1079  return true;
1080}
1081
1082const MCExpr* MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
1083                                               StringRef RelocStr) {
1084  const MCExpr *Res;
1085  // Check the type of the expression.
1086  if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
1087    // It's a constant, evaluate lo or hi value.
1088    if (RelocStr == "lo") {
1089      short Val = MCE->getValue();
1090      Res = MCConstantExpr::Create(Val, getContext());
1091    } else if (RelocStr == "hi") {
1092      int Val = MCE->getValue();
1093      int LoSign = Val & 0x8000;
1094      Val = (Val & 0xffff0000) >> 16;
1095      // Lower part is treated as a signed int, so if it is negative
1096      // we must add 1 to the hi part to compensate.
1097      if (LoSign)
1098        Val++;
1099      Res = MCConstantExpr::Create(Val, getContext());
1100    } else {
1101      llvm_unreachable("Invalid RelocStr value");
1102    }
1103    return Res;
1104  }
1105
1106  if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
1107    // It's a symbol, create a symbolic expression from the symbol.
1108    StringRef Symbol = MSRE->getSymbol().getName();
1109    MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1110    Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
1111    return Res;
1112  }
1113
1114  if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1115    const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
1116    const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
1117    Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
1118    return Res;
1119  }
1120
1121  if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
1122    const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
1123    Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
1124    return Res;
1125  }
1126  // Just return the original expression.
1127  return Expr;
1128}
1129
1130bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
1131
1132  switch (Expr->getKind()) {
1133  case MCExpr::Constant:
1134    return true;
1135  case MCExpr::SymbolRef:
1136    return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1137  case MCExpr::Binary:
1138    if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1139      if (!isEvaluated(BE->getLHS()))
1140        return false;
1141      return isEvaluated(BE->getRHS());
1142    }
1143  case MCExpr::Unary:
1144    return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
1145  default:
1146    return false;
1147  }
1148  return false;
1149}
1150
1151bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
1152  Parser.Lex(); // Eat the % token.
1153  const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
1154  if (Tok.isNot(AsmToken::Identifier))
1155    return true;
1156
1157  std::string Str = Tok.getIdentifier().str();
1158
1159  Parser.Lex(); // Eat the identifier.
1160  // Now make an expression from the rest of the operand.
1161  const MCExpr *IdVal;
1162  SMLoc EndLoc;
1163
1164  if (getLexer().getKind() == AsmToken::LParen) {
1165    while (1) {
1166      Parser.Lex(); // Eat the '(' token.
1167      if (getLexer().getKind() == AsmToken::Percent) {
1168        Parser.Lex(); // Eat the % token.
1169        const AsmToken &nextTok = Parser.getTok();
1170        if (nextTok.isNot(AsmToken::Identifier))
1171          return true;
1172        Str += "(%";
1173        Str += nextTok.getIdentifier();
1174        Parser.Lex(); // Eat the identifier.
1175        if (getLexer().getKind() != AsmToken::LParen)
1176          return true;
1177      } else
1178        break;
1179    }
1180    if (getParser().parseParenExpression(IdVal, EndLoc))
1181      return true;
1182
1183    while (getLexer().getKind() == AsmToken::RParen)
1184      Parser.Lex(); // Eat the ')' token.
1185
1186  } else
1187    return true; // Parenthesis must follow the relocation operand.
1188
1189  Res = evaluateRelocExpr(IdVal, Str);
1190  return false;
1191}
1192
1193bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1194                                  SMLoc &EndLoc) {
1195  StartLoc = Parser.getTok().getLoc();
1196  RegNo = tryParseRegister(isMips64());
1197  EndLoc = Parser.getTok().getLoc();
1198  return (RegNo == (unsigned) -1);
1199}
1200
1201bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
1202  SMLoc S;
1203  bool Result = true;
1204
1205  while (getLexer().getKind() == AsmToken::LParen)
1206    Parser.Lex();
1207
1208  switch (getLexer().getKind()) {
1209  default:
1210    return true;
1211  case AsmToken::Identifier:
1212  case AsmToken::LParen:
1213  case AsmToken::Integer:
1214  case AsmToken::Minus:
1215  case AsmToken::Plus:
1216    if (isParenExpr)
1217      Result = getParser().parseParenExpression(Res, S);
1218    else
1219      Result = (getParser().parseExpression(Res));
1220    while (getLexer().getKind() == AsmToken::RParen)
1221      Parser.Lex();
1222    break;
1223  case AsmToken::Percent:
1224    Result = parseRelocOperand(Res);
1225  }
1226  return Result;
1227}
1228
1229MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
1230                               SmallVectorImpl<MCParsedAsmOperand*>&Operands) {
1231
1232  const MCExpr *IdVal = 0;
1233  SMLoc S;
1234  bool isParenExpr = false;
1235  MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
1236  // First operand is the offset.
1237  S = Parser.getTok().getLoc();
1238
1239  if (getLexer().getKind() == AsmToken::LParen) {
1240    Parser.Lex();
1241    isParenExpr = true;
1242  }
1243
1244  if (getLexer().getKind() != AsmToken::Dollar) {
1245    if (parseMemOffset(IdVal, isParenExpr))
1246      return MatchOperand_ParseFail;
1247
1248    const AsmToken &Tok = Parser.getTok(); // Get the next token.
1249    if (Tok.isNot(AsmToken::LParen)) {
1250      MipsOperand *Mnemonic = static_cast<MipsOperand*>(Operands[0]);
1251      if (Mnemonic->getToken() == "la") {
1252        SMLoc E = SMLoc::getFromPointer(
1253            Parser.getTok().getLoc().getPointer() - 1);
1254        Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1255        return MatchOperand_Success;
1256      }
1257      if (Tok.is(AsmToken::EndOfStatement)) {
1258        SMLoc E = SMLoc::getFromPointer(
1259            Parser.getTok().getLoc().getPointer() - 1);
1260
1261        // Zero register assumed, add a memory operand with ZERO as its base.
1262        Operands.push_back(MipsOperand::CreateMem(isMips64() ? Mips::ZERO_64
1263                                                             : Mips::ZERO,
1264                           IdVal, S, E));
1265        return MatchOperand_Success;
1266      }
1267      Error(Parser.getTok().getLoc(), "'(' expected");
1268      return MatchOperand_ParseFail;
1269    }
1270
1271    Parser.Lex(); // Eat the '(' token.
1272  }
1273
1274  Res = parseRegs(Operands, isMips64()? (int) MipsOperand::Kind_GPR64:
1275                                        (int) MipsOperand::Kind_GPR32);
1276  if (Res != MatchOperand_Success)
1277    return Res;
1278
1279  if (Parser.getTok().isNot(AsmToken::RParen)) {
1280    Error(Parser.getTok().getLoc(), "')' expected");
1281    return MatchOperand_ParseFail;
1282  }
1283
1284  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1285
1286  Parser.Lex(); // Eat the ')' token.
1287
1288  if (IdVal == 0)
1289    IdVal = MCConstantExpr::Create(0, getContext());
1290
1291  // Replace the register operand with the memory operand.
1292  MipsOperand* op = static_cast<MipsOperand*>(Operands.back());
1293  int RegNo = op->getReg();
1294  // Remove the register from the operands.
1295  Operands.pop_back();
1296  // Add the memory operand.
1297  if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
1298    int64_t Imm;
1299    if (IdVal->EvaluateAsAbsolute(Imm))
1300      IdVal = MCConstantExpr::Create(Imm, getContext());
1301    else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
1302      IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
1303                                   getContext());
1304  }
1305
1306  Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E));
1307  delete op;
1308  return MatchOperand_Success;
1309}
1310
1311bool
1312MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1313                           int RegKind) {
1314  // If the first token is not '$' we have an error.
1315  if (Parser.getTok().isNot(AsmToken::Dollar))
1316    return false;
1317
1318  SMLoc S = Parser.getTok().getLoc();
1319  Parser.Lex();
1320  AsmToken::TokenKind TkKind = getLexer().getKind();
1321  int Reg;
1322
1323  if (TkKind == AsmToken::Integer) {
1324    Reg = matchRegisterByNumber(Parser.getTok().getIntVal(),
1325                                regKindToRegClass(RegKind));
1326    if (Reg == -1)
1327      return false;
1328  } else if (TkKind == AsmToken::Identifier) {
1329    if ((Reg = matchCPURegisterName(Parser.getTok().getString().lower())) == -1)
1330      return false;
1331    Reg = getReg(regKindToRegClass(RegKind), Reg);
1332  } else {
1333    return false;
1334  }
1335
1336  MipsOperand *Op = MipsOperand::CreatePtrReg(Reg, S, Parser.getTok().getLoc());
1337  Op->setRegKind((MipsOperand::RegisterKind)RegKind);
1338  Operands.push_back(Op);
1339  Parser.Lex();
1340  return true;
1341}
1342
1343MipsAsmParser::OperandMatchResultTy
1344MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1345  MipsOperand::RegisterKind RegKind = isN64() ? MipsOperand::Kind_GPR64 :
1346                                                MipsOperand::Kind_GPR32;
1347
1348  // Parse index register.
1349  if (!parsePtrReg(Operands, RegKind))
1350    return MatchOperand_NoMatch;
1351
1352  // Parse '('.
1353  if (Parser.getTok().isNot(AsmToken::LParen))
1354    return MatchOperand_NoMatch;
1355
1356  Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1357  Parser.Lex();
1358
1359  // Parse base register.
1360  if (!parsePtrReg(Operands, RegKind))
1361    return MatchOperand_NoMatch;
1362
1363  // Parse ')'.
1364  if (Parser.getTok().isNot(AsmToken::RParen))
1365    return MatchOperand_NoMatch;
1366
1367  Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1368  Parser.Lex();
1369
1370  return MatchOperand_Success;
1371}
1372
1373MipsAsmParser::OperandMatchResultTy
1374MipsAsmParser::parseRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1375                         int RegKind) {
1376  MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1377  if (getLexer().getKind() == AsmToken::Identifier
1378       && !hasConsumedDollar) {
1379    if (searchSymbolAlias(Operands, Kind))
1380      return MatchOperand_Success;
1381    return MatchOperand_NoMatch;
1382  }
1383  SMLoc S = Parser.getTok().getLoc();
1384  // If the first token is not '$', we have an error.
1385  if (Parser.getTok().isNot(AsmToken::Dollar) && !hasConsumedDollar)
1386    return MatchOperand_NoMatch;
1387  if (!hasConsumedDollar) {
1388    Parser.Lex(); // Eat the '$'
1389    hasConsumedDollar = true;
1390  }
1391  if (getLexer().getKind() == AsmToken::Identifier) {
1392    int RegNum = -1;
1393    std::string RegName = Parser.getTok().getString().lower();
1394  // Match register by name
1395    switch (RegKind) {
1396    case MipsOperand::Kind_GPR32:
1397    case MipsOperand::Kind_GPR64:
1398      RegNum = matchCPURegisterName(RegName);
1399      break;
1400    case MipsOperand::Kind_AFGR64Regs:
1401    case MipsOperand::Kind_FGR64Regs:
1402    case MipsOperand::Kind_FGR32Regs:
1403    case MipsOperand::Kind_FGRH32Regs:
1404      RegNum = matchFPURegisterName(RegName);
1405      if (RegKind == MipsOperand::Kind_AFGR64Regs)
1406        RegNum /= 2;
1407      else if (RegKind == MipsOperand::Kind_FGRH32Regs
1408               && !isFP64())
1409        if (RegNum != -1 && RegNum %2 != 0)
1410          Warning(S, "Float register should be even.");
1411      break;
1412    case MipsOperand::Kind_FCCRegs:
1413      RegNum = matchFCCRegisterName(RegName);
1414      break;
1415    case MipsOperand::Kind_ACC64DSP:
1416      RegNum = matchACRegisterName(RegName);
1417      break;
1418    default: break; // No match, value is set to -1.
1419    }
1420    // No match found, return _NoMatch to give a chance to other round.
1421    if (RegNum < 0)
1422      return MatchOperand_NoMatch;
1423
1424    int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1425    if (RegVal == -1)
1426      return MatchOperand_NoMatch;
1427
1428    MipsOperand *Op = MipsOperand::CreateReg(RegVal, S,
1429                                             Parser.getTok().getLoc());
1430    Op->setRegKind(Kind);
1431    Operands.push_back(Op);
1432    hasConsumedDollar = false;
1433    Parser.Lex(); // Eat the register name.
1434    return MatchOperand_Success;
1435  } else if (getLexer().getKind() == AsmToken::Integer) {
1436    unsigned RegNum = Parser.getTok().getIntVal();
1437    if (Kind == MipsOperand::Kind_HWRegs) {
1438      if (RegNum != 29)
1439        return MatchOperand_NoMatch;
1440      // Only hwreg 29 is supported, found at index 0.
1441      RegNum = 0;
1442    }
1443    int Reg = matchRegisterByNumber(RegNum, regKindToRegClass(Kind));
1444    if (Reg == -1)
1445      return MatchOperand_NoMatch;
1446    MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1447    Op->setRegKind(Kind);
1448    Operands.push_back(Op);
1449    hasConsumedDollar = false;
1450    Parser.Lex(); // Eat the register number.
1451        if ((RegKind == MipsOperand::Kind_GPR32)
1452      && (getLexer().is(AsmToken::LParen))) {
1453      // Check if it is indexed addressing operand.
1454      Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1455      Parser.Lex(); // Eat the parenthesis.
1456      if (parseRegs(Operands,RegKind) != MatchOperand_Success)
1457        return MatchOperand_NoMatch;
1458      if (getLexer().isNot(AsmToken::RParen))
1459        return MatchOperand_NoMatch;
1460      Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1461      Parser.Lex();
1462    }
1463    return MatchOperand_Success;
1464  }
1465  return MatchOperand_NoMatch;
1466}
1467
1468MipsAsmParser::OperandMatchResultTy
1469MipsAsmParser::parseGPR64(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1470
1471  if (!isMips64())
1472    return MatchOperand_NoMatch;
1473  return parseRegs(Operands, (int) MipsOperand::Kind_GPR64);
1474}
1475
1476MipsAsmParser::OperandMatchResultTy
1477MipsAsmParser::parseGPR32(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1478 return parseRegs(Operands, (int) MipsOperand::Kind_GPR32);
1479}
1480
1481MipsAsmParser::OperandMatchResultTy
1482MipsAsmParser::parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1483
1484  if (isFP64())
1485    return MatchOperand_NoMatch;
1486  return parseRegs(Operands, (int) MipsOperand::Kind_AFGR64Regs);
1487}
1488
1489MipsAsmParser::OperandMatchResultTy
1490MipsAsmParser::parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1491  if (!isFP64())
1492    return MatchOperand_NoMatch;
1493 return parseRegs(Operands, (int) MipsOperand::Kind_FGR64Regs);
1494}
1495
1496MipsAsmParser::OperandMatchResultTy
1497MipsAsmParser::parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1498  return parseRegs(Operands, (int) MipsOperand::Kind_FGR32Regs);
1499}
1500
1501MipsAsmParser::OperandMatchResultTy
1502MipsAsmParser::parseFGRH32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1503  return parseRegs(Operands, (int) MipsOperand::Kind_FGRH32Regs);
1504}
1505
1506MipsAsmParser::OperandMatchResultTy
1507MipsAsmParser::parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1508  return parseRegs(Operands, (int) MipsOperand::Kind_FCCRegs);
1509}
1510
1511MipsAsmParser::OperandMatchResultTy
1512MipsAsmParser::parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1513  return parseRegs(Operands, (int) MipsOperand::Kind_ACC64DSP);
1514}
1515
1516MipsAsmParser::OperandMatchResultTy
1517MipsAsmParser::parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1518  // If the first token is not '$' we have an error.
1519  if (Parser.getTok().isNot(AsmToken::Dollar))
1520    return MatchOperand_NoMatch;
1521
1522  SMLoc S = Parser.getTok().getLoc();
1523  Parser.Lex(); // Eat the '$'
1524
1525  const AsmToken &Tok = Parser.getTok(); // Get next token.
1526
1527  if (Tok.isNot(AsmToken::Identifier))
1528    return MatchOperand_NoMatch;
1529
1530  if (!Tok.getIdentifier().startswith("ac"))
1531    return MatchOperand_NoMatch;
1532
1533  StringRef NumString = Tok.getIdentifier().substr(2);
1534
1535  unsigned IntVal;
1536  if (NumString.getAsInteger(10, IntVal))
1537    return MatchOperand_NoMatch;
1538
1539  unsigned Reg = matchRegisterByNumber(IntVal, Mips::LO32DSPRegClassID);
1540
1541  MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1542  Op->setRegKind(MipsOperand::Kind_LO32DSP);
1543  Operands.push_back(Op);
1544
1545  Parser.Lex(); // Eat the register number.
1546  return MatchOperand_Success;
1547}
1548
1549MipsAsmParser::OperandMatchResultTy
1550MipsAsmParser::parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1551  // If the first token is not '$' we have an error.
1552  if (Parser.getTok().isNot(AsmToken::Dollar))
1553    return MatchOperand_NoMatch;
1554
1555  SMLoc S = Parser.getTok().getLoc();
1556  Parser.Lex(); // Eat the '$'
1557
1558  const AsmToken &Tok = Parser.getTok(); // Get next token.
1559
1560  if (Tok.isNot(AsmToken::Identifier))
1561    return MatchOperand_NoMatch;
1562
1563  if (!Tok.getIdentifier().startswith("ac"))
1564    return MatchOperand_NoMatch;
1565
1566  StringRef NumString = Tok.getIdentifier().substr(2);
1567
1568  unsigned IntVal;
1569  if (NumString.getAsInteger(10, IntVal))
1570    return MatchOperand_NoMatch;
1571
1572  unsigned Reg = matchRegisterByNumber(IntVal, Mips::HI32DSPRegClassID);
1573
1574  MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1575  Op->setRegKind(MipsOperand::Kind_HI32DSP);
1576  Operands.push_back(Op);
1577
1578  Parser.Lex(); // Eat the register number.
1579  return MatchOperand_Success;
1580}
1581
1582bool MipsAsmParser::searchSymbolAlias(
1583    SmallVectorImpl<MCParsedAsmOperand*> &Operands, unsigned RegKind) {
1584
1585  MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
1586  if (Sym) {
1587    SMLoc S = Parser.getTok().getLoc();
1588    const MCExpr *Expr;
1589    if (Sym->isVariable())
1590      Expr = Sym->getVariableValue();
1591    else
1592      return false;
1593    if (Expr->getKind() == MCExpr::SymbolRef) {
1594      MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind) RegKind;
1595      const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Expr);
1596      const StringRef DefSymbol = Ref->getSymbol().getName();
1597      if (DefSymbol.startswith("$")) {
1598        int RegNum = -1;
1599        APInt IntVal(32, -1);
1600        if (!DefSymbol.substr(1).getAsInteger(10, IntVal))
1601          RegNum = matchRegisterByNumber(IntVal.getZExtValue(),
1602                                     isMips64()
1603                                       ? Mips::GPR64RegClassID
1604                                       : Mips::GPR32RegClassID);
1605        else {
1606          // Lookup for the register with the corresponding name.
1607          switch (Kind) {
1608          case MipsOperand::Kind_AFGR64Regs:
1609          case MipsOperand::Kind_FGR64Regs:
1610            RegNum = matchFPURegisterName(DefSymbol.substr(1));
1611            break;
1612          case MipsOperand::Kind_FGR32Regs:
1613            RegNum = matchFPURegisterName(DefSymbol.substr(1));
1614            break;
1615          case MipsOperand::Kind_GPR64:
1616          case MipsOperand::Kind_GPR32:
1617          default:
1618            RegNum = matchCPURegisterName(DefSymbol.substr(1));
1619            break;
1620          }
1621          if (RegNum > -1)
1622            RegNum = getReg(regKindToRegClass(Kind), RegNum);
1623        }
1624        if (RegNum > -1) {
1625          Parser.Lex();
1626          MipsOperand *op = MipsOperand::CreateReg(RegNum, S,
1627                                                   Parser.getTok().getLoc());
1628          op->setRegKind(Kind);
1629          Operands.push_back(op);
1630          return true;
1631        }
1632      }
1633    } else if (Expr->getKind() == MCExpr::Constant) {
1634      Parser.Lex();
1635      const MCConstantExpr *Const = static_cast<const MCConstantExpr*>(Expr);
1636      MipsOperand *op = MipsOperand::CreateImm(Const, S,
1637          Parser.getTok().getLoc());
1638      Operands.push_back(op);
1639      return true;
1640    }
1641  }
1642  return false;
1643}
1644
1645MipsAsmParser::OperandMatchResultTy
1646MipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1647  return parseRegs(Operands, (int) MipsOperand::Kind_HWRegs);
1648}
1649
1650MipsAsmParser::OperandMatchResultTy
1651MipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1652  return parseRegs(Operands, (int) MipsOperand::Kind_CCRRegs);
1653}
1654
1655MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
1656
1657  MCSymbolRefExpr::VariantKind VK
1658                   = StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
1659    .Case("hi",          MCSymbolRefExpr::VK_Mips_ABS_HI)
1660    .Case("lo",          MCSymbolRefExpr::VK_Mips_ABS_LO)
1661    .Case("gp_rel",      MCSymbolRefExpr::VK_Mips_GPREL)
1662    .Case("call16",      MCSymbolRefExpr::VK_Mips_GOT_CALL)
1663    .Case("got",         MCSymbolRefExpr::VK_Mips_GOT)
1664    .Case("tlsgd",       MCSymbolRefExpr::VK_Mips_TLSGD)
1665    .Case("tlsldm",      MCSymbolRefExpr::VK_Mips_TLSLDM)
1666    .Case("dtprel_hi",   MCSymbolRefExpr::VK_Mips_DTPREL_HI)
1667    .Case("dtprel_lo",   MCSymbolRefExpr::VK_Mips_DTPREL_LO)
1668    .Case("gottprel",    MCSymbolRefExpr::VK_Mips_GOTTPREL)
1669    .Case("tprel_hi",    MCSymbolRefExpr::VK_Mips_TPREL_HI)
1670    .Case("tprel_lo",    MCSymbolRefExpr::VK_Mips_TPREL_LO)
1671    .Case("got_disp",    MCSymbolRefExpr::VK_Mips_GOT_DISP)
1672    .Case("got_page",    MCSymbolRefExpr::VK_Mips_GOT_PAGE)
1673    .Case("got_ofst",    MCSymbolRefExpr::VK_Mips_GOT_OFST)
1674    .Case("hi(%neg(%gp_rel",    MCSymbolRefExpr::VK_Mips_GPOFF_HI)
1675    .Case("lo(%neg(%gp_rel",    MCSymbolRefExpr::VK_Mips_GPOFF_LO)
1676    .Default(MCSymbolRefExpr::VK_None);
1677
1678  return VK;
1679}
1680
1681bool MipsAsmParser::
1682ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
1683                 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1684  // Check if we have valid mnemonic
1685  if (!mnemonicIsValid(Name, 0)) {
1686    Parser.eatToEndOfStatement();
1687    return Error(NameLoc, "Unknown instruction");
1688  }
1689  // First operand in MCInst is instruction mnemonic.
1690  Operands.push_back(MipsOperand::CreateToken(Name, NameLoc));
1691
1692  // Read the remaining operands.
1693  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1694    // Read the first operand.
1695    if (ParseOperand(Operands, Name)) {
1696      SMLoc Loc = getLexer().getLoc();
1697      Parser.eatToEndOfStatement();
1698      return Error(Loc, "unexpected token in argument list");
1699    }
1700
1701    while (getLexer().is(AsmToken::Comma)) {
1702      Parser.Lex(); // Eat the comma.
1703      // Parse and remember the operand.
1704      if (ParseOperand(Operands, Name)) {
1705        SMLoc Loc = getLexer().getLoc();
1706        Parser.eatToEndOfStatement();
1707        return Error(Loc, "unexpected token in argument list");
1708      }
1709    }
1710  }
1711  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1712    SMLoc Loc = getLexer().getLoc();
1713    Parser.eatToEndOfStatement();
1714    return Error(Loc, "unexpected token in argument list");
1715  }
1716  Parser.Lex(); // Consume the EndOfStatement.
1717  return false;
1718}
1719
1720bool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
1721  SMLoc Loc = getLexer().getLoc();
1722  Parser.eatToEndOfStatement();
1723  return Error(Loc, ErrorMsg);
1724}
1725
1726bool MipsAsmParser::parseSetNoAtDirective() {
1727  // Line should look like: ".set noat".
1728  // set at reg to 0.
1729  Options.setATReg(0);
1730  // eat noat
1731  Parser.Lex();
1732  // If this is not the end of the statement, report an error.
1733  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1734    reportParseError("unexpected token in statement");
1735    return false;
1736  }
1737  Parser.Lex(); // Consume the EndOfStatement.
1738  return false;
1739}
1740
1741bool MipsAsmParser::parseSetAtDirective() {
1742  // Line can be .set at - defaults to $1
1743  // or .set at=$reg
1744  int AtRegNo;
1745  getParser().Lex();
1746  if (getLexer().is(AsmToken::EndOfStatement)) {
1747    Options.setATReg(1);
1748    Parser.Lex(); // Consume the EndOfStatement.
1749    return false;
1750  } else if (getLexer().is(AsmToken::Equal)) {
1751    getParser().Lex(); // Eat the '='.
1752    if (getLexer().isNot(AsmToken::Dollar)) {
1753      reportParseError("unexpected token in statement");
1754      return false;
1755    }
1756    Parser.Lex(); // Eat the '$'.
1757    const AsmToken &Reg = Parser.getTok();
1758    if (Reg.is(AsmToken::Identifier)) {
1759      AtRegNo = matchCPURegisterName(Reg.getIdentifier());
1760    } else if (Reg.is(AsmToken::Integer)) {
1761      AtRegNo = Reg.getIntVal();
1762    } else {
1763      reportParseError("unexpected token in statement");
1764      return false;
1765    }
1766
1767    if (AtRegNo < 1 || AtRegNo > 31) {
1768      reportParseError("unexpected token in statement");
1769      return false;
1770    }
1771
1772    if (!Options.setATReg(AtRegNo)) {
1773      reportParseError("unexpected token in statement");
1774      return false;
1775    }
1776    getParser().Lex(); // Eat the register.
1777
1778    if (getLexer().isNot(AsmToken::EndOfStatement)) {
1779      reportParseError("unexpected token in statement");
1780      return false;
1781    }
1782    Parser.Lex(); // Consume the EndOfStatement.
1783    return false;
1784  } else {
1785    reportParseError("unexpected token in statement");
1786    return false;
1787  }
1788}
1789
1790bool MipsAsmParser::parseSetReorderDirective() {
1791  Parser.Lex();
1792  // If this is not the end of the statement, report an error.
1793  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1794    reportParseError("unexpected token in statement");
1795    return false;
1796  }
1797  Options.setReorder();
1798  Parser.Lex(); // Consume the EndOfStatement.
1799  return false;
1800}
1801
1802bool MipsAsmParser::parseSetNoReorderDirective() {
1803  Parser.Lex();
1804  // If this is not the end of the statement, report an error.
1805  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1806    reportParseError("unexpected token in statement");
1807    return false;
1808  }
1809  Options.setNoreorder();
1810  Parser.Lex(); // Consume the EndOfStatement.
1811  return false;
1812}
1813
1814bool MipsAsmParser::parseSetMacroDirective() {
1815  Parser.Lex();
1816  // If this is not the end of the statement, report an error.
1817  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1818    reportParseError("unexpected token in statement");
1819    return false;
1820  }
1821  Options.setMacro();
1822  Parser.Lex(); // Consume the EndOfStatement.
1823  return false;
1824}
1825
1826bool MipsAsmParser::parseSetNoMacroDirective() {
1827  Parser.Lex();
1828  // If this is not the end of the statement, report an error.
1829  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1830    reportParseError("`noreorder' must be set before `nomacro'");
1831    return false;
1832  }
1833  if (Options.isReorder()) {
1834    reportParseError("`noreorder' must be set before `nomacro'");
1835    return false;
1836  }
1837  Options.setNomacro();
1838  Parser.Lex(); // Consume the EndOfStatement.
1839  return false;
1840}
1841
1842bool MipsAsmParser::parseSetAssignment() {
1843  StringRef Name;
1844  const MCExpr *Value;
1845
1846  if (Parser.parseIdentifier(Name))
1847    reportParseError("expected identifier after .set");
1848
1849  if (getLexer().isNot(AsmToken::Comma))
1850    return reportParseError("unexpected token in .set directive");
1851  Lex(); // Eat comma
1852
1853  if (getLexer().is(AsmToken::Dollar)) {
1854    MCSymbol *Symbol;
1855    SMLoc DollarLoc = getLexer().getLoc();
1856    // Consume the dollar sign, and check for a following identifier.
1857    Parser.Lex();
1858    // We have a '$' followed by something, make sure they are adjacent.
1859    if (DollarLoc.getPointer() + 1 != getTok().getLoc().getPointer())
1860      return true;
1861    StringRef Res = StringRef(DollarLoc.getPointer(),
1862        getTok().getEndLoc().getPointer() - DollarLoc.getPointer());
1863    Symbol = getContext().GetOrCreateSymbol(Res);
1864    Parser.Lex();
1865    Value = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None,
1866                                    getContext());
1867  } else if (Parser.parseExpression(Value))
1868    return reportParseError("expected valid expression after comma");
1869
1870  // Check if the Name already exists as a symbol.
1871  MCSymbol *Sym = getContext().LookupSymbol(Name);
1872  if (Sym)
1873    return reportParseError("symbol already defined");
1874  Sym = getContext().GetOrCreateSymbol(Name);
1875  Sym->setVariableValue(Value);
1876
1877  return false;
1878}
1879
1880bool MipsAsmParser::parseDirectiveSet() {
1881
1882  // Get the next token.
1883  const AsmToken &Tok = Parser.getTok();
1884
1885  if (Tok.getString() == "noat") {
1886    return parseSetNoAtDirective();
1887  } else if (Tok.getString() == "at") {
1888    return parseSetAtDirective();
1889  } else if (Tok.getString() == "reorder") {
1890    return parseSetReorderDirective();
1891  } else if (Tok.getString() == "noreorder") {
1892    return parseSetNoReorderDirective();
1893  } else if (Tok.getString() == "macro") {
1894    return parseSetMacroDirective();
1895  } else if (Tok.getString() == "nomacro") {
1896    return parseSetNoMacroDirective();
1897  } else if (Tok.getString() == "nomips16") {
1898    // Ignore this directive for now.
1899    Parser.eatToEndOfStatement();
1900    return false;
1901  } else if (Tok.getString() == "nomicromips") {
1902    // Ignore this directive for now.
1903    Parser.eatToEndOfStatement();
1904    return false;
1905  } else {
1906    // It is just an identifier, look for an assignment.
1907    parseSetAssignment();
1908    return false;
1909  }
1910
1911  return true;
1912}
1913
1914/// parseDirectiveWord
1915///  ::= .word [ expression (, expression)* ]
1916bool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
1917  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1918    for (;;) {
1919      const MCExpr *Value;
1920      if (getParser().parseExpression(Value))
1921        return true;
1922
1923      getParser().getStreamer().EmitValue(Value, Size);
1924
1925      if (getLexer().is(AsmToken::EndOfStatement))
1926        break;
1927
1928      // FIXME: Improve diagnostic.
1929      if (getLexer().isNot(AsmToken::Comma))
1930        return Error(L, "unexpected token in directive");
1931      Parser.Lex();
1932    }
1933  }
1934
1935  Parser.Lex();
1936  return false;
1937}
1938
1939bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
1940
1941  StringRef IDVal = DirectiveID.getString();
1942
1943  if (IDVal == ".ent") {
1944    // Ignore this directive for now.
1945    Parser.Lex();
1946    return false;
1947  }
1948
1949  if (IDVal == ".end") {
1950    // Ignore this directive for now.
1951    Parser.Lex();
1952    return false;
1953  }
1954
1955  if (IDVal == ".frame") {
1956    // Ignore this directive for now.
1957    Parser.eatToEndOfStatement();
1958    return false;
1959  }
1960
1961  if (IDVal == ".set") {
1962    return parseDirectiveSet();
1963  }
1964
1965  if (IDVal == ".fmask") {
1966    // Ignore this directive for now.
1967    Parser.eatToEndOfStatement();
1968    return false;
1969  }
1970
1971  if (IDVal == ".mask") {
1972    // Ignore this directive for now.
1973    Parser.eatToEndOfStatement();
1974    return false;
1975  }
1976
1977  if (IDVal == ".gpword") {
1978    // Ignore this directive for now.
1979    Parser.eatToEndOfStatement();
1980    return false;
1981  }
1982
1983  if (IDVal == ".word") {
1984    parseDirectiveWord(4, DirectiveID.getLoc());
1985    return false;
1986  }
1987
1988  return true;
1989}
1990
1991extern "C" void LLVMInitializeMipsAsmParser() {
1992  RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
1993  RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
1994  RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
1995  RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
1996}
1997
1998#define GET_REGISTER_MATCHER
1999#define GET_MATCHER_IMPLEMENTATION
2000#include "MipsGenAsmMatcher.inc"
2001