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