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