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