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