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     return MatchOperand_Success;
1272   }
1273   return MatchOperand_NoMatch;
1274 }
1275 
1276 MipsAsmParser::OperandMatchResultTy
1277 MipsAsmParser::parseCPU64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1278 
1279   if (!isMips64())
1280     return MatchOperand_NoMatch;
1281   return parseRegs(Operands, (int) MipsOperand::Kind_CPU64Regs);
1282 }
1283 
1284 MipsAsmParser::OperandMatchResultTy
1285 MipsAsmParser::parseCPURegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1286  return parseRegs(Operands, (int) MipsOperand::Kind_CPURegs);
1287 }
1288 
1289 MipsAsmParser::OperandMatchResultTy
1290 MipsAsmParser::parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1291 
1292   if (isFP64())
1293     return MatchOperand_NoMatch;
1294   // Double operand is expected, set appropriate format
1295   setFpFormat(FP_FORMAT_D);
1296 
1297   return parseRegs(Operands, (int) MipsOperand::Kind_AFGR64Regs);
1298 }
1299 
1300 MipsAsmParser::OperandMatchResultTy
1301 MipsAsmParser::parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1302   if (!isFP64())
1303     return MatchOperand_NoMatch;
1304   // Double operand is expected, set appropriate format
1305   setFpFormat(FP_FORMAT_D);
1306 
1307  return parseRegs(Operands, (int) MipsOperand::Kind_FGR64Regs);
1308 }
1309 
1310 MipsAsmParser::OperandMatchResultTy
1311 MipsAsmParser::parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1312  // Single operand is expected, set appropriate format
1313   setFpFormat(FP_FORMAT_S);
1314   return parseRegs(Operands, (int) MipsOperand::Kind_FGR32Regs);
1315 }
1316 
1317 bool MipsAsmParser::searchSymbolAlias(
1318     SmallVectorImpl<MCParsedAsmOperand*> &Operands, unsigned RegKind) {
1319 
1320   MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
1321   if (Sym) {
1322     SMLoc S = Parser.getTok().getLoc();
1323     const MCExpr *Expr;
1324     if (Sym->isVariable())
1325       Expr = Sym->getVariableValue();
1326     else
1327       return false;
1328     if (Expr->getKind() == MCExpr::SymbolRef) {
1329       MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind) RegKind;
1330       const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Expr);
1331       const StringRef DefSymbol = Ref->getSymbol().getName();
1332       if (DefSymbol.startswith("$")) {
1333         int RegNum = -1;
1334         APInt IntVal(32, -1);
1335         if (!DefSymbol.substr(1).getAsInteger(10, IntVal))
1336           RegNum = matchRegisterByNumber(IntVal.getZExtValue(),
1337                                      isMips64()
1338                                        ? Mips::CPU64RegsRegClassID
1339                                        : Mips::CPURegsRegClassID);
1340         else {
1341           // Lookup for the register with the corresponding name.
1342           switch (Kind) {
1343           case MipsOperand::Kind_AFGR64Regs:
1344           case MipsOperand::Kind_FGR64Regs:
1345             RegNum = matchFPURegisterName(DefSymbol.substr(1), FP_FORMAT_D);
1346             break;
1347           case MipsOperand::Kind_FGR32Regs:
1348             RegNum = matchFPURegisterName(DefSymbol.substr(1), FP_FORMAT_S);
1349             break;
1350           case MipsOperand::Kind_CPU64Regs:
1351           case MipsOperand::Kind_CPURegs:
1352           default:
1353             RegNum = matchRegisterName(DefSymbol.substr(1), isMips64());
1354             break;
1355           }
1356         }
1357         if (RegNum > -1) {
1358           Parser.Lex();
1359           MipsOperand *op = MipsOperand::CreateReg(RegNum, S,
1360                                                    Parser.getTok().getLoc());
1361           op->setRegKind(Kind);
1362           Operands.push_back(op);
1363           return true;
1364         }
1365       }
1366     } else if (Expr->getKind() == MCExpr::Constant) {
1367       Parser.Lex();
1368       const MCConstantExpr *Const = static_cast<const MCConstantExpr*>(Expr);
1369       MipsOperand *op = MipsOperand::CreateImm(Const, S,
1370           Parser.getTok().getLoc());
1371       Operands.push_back(op);
1372       return true;
1373     }
1374   }
1375   return false;
1376 }
1377 
1378 MipsAsmParser::OperandMatchResultTy
1379 MipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1380 
1381   if (isMips64())
1382     return MatchOperand_NoMatch;
1383 
1384   // If the first token is not '$' we have error.
1385   if (Parser.getTok().isNot(AsmToken::Dollar))
1386     return MatchOperand_NoMatch;
1387   SMLoc S = Parser.getTok().getLoc();
1388   Parser.Lex(); // Eat the '$'.
1389 
1390   const AsmToken &Tok = Parser.getTok(); // Get the next token.
1391   if (Tok.isNot(AsmToken::Integer))
1392     return MatchOperand_NoMatch;
1393 
1394   unsigned RegNum = Tok.getIntVal();
1395   // At the moment only hwreg29 is supported.
1396   if (RegNum != 29)
1397     return MatchOperand_ParseFail;
1398 
1399   MipsOperand *op = MipsOperand::CreateReg(Mips::HWR29, S,
1400       Parser.getTok().getLoc());
1401   op->setRegKind(MipsOperand::Kind_HWRegs);
1402   Operands.push_back(op);
1403 
1404   Parser.Lex(); // Eat the register number.
1405   return MatchOperand_Success;
1406 }
1407 
1408 MipsAsmParser::OperandMatchResultTy
1409 MipsAsmParser::parseHW64Regs(
1410     SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1411 
1412   if (!isMips64())
1413     return MatchOperand_NoMatch;
1414   // If the first token is not '$' we have an error.
1415   if (Parser.getTok().isNot(AsmToken::Dollar))
1416     return MatchOperand_NoMatch;
1417   SMLoc S = Parser.getTok().getLoc();
1418   Parser.Lex(); // Eat $
1419 
1420   const AsmToken &Tok = Parser.getTok(); // Get the next token.
1421   if (Tok.isNot(AsmToken::Integer))
1422     return MatchOperand_NoMatch;
1423 
1424   unsigned RegNum = Tok.getIntVal();
1425   // At the moment only hwreg29 is supported.
1426   if (RegNum != 29)
1427     return MatchOperand_ParseFail;
1428 
1429   MipsOperand *op = MipsOperand::CreateReg(Mips::HWR29_64, S,
1430                                            Parser.getTok().getLoc());
1431   op->setRegKind(MipsOperand::Kind_HW64Regs);
1432   Operands.push_back(op);
1433 
1434   Parser.Lex(); // Eat the register number.
1435   return MatchOperand_Success;
1436 }
1437 
1438 MipsAsmParser::OperandMatchResultTy
1439 MipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1440   unsigned RegNum;
1441   // If the first token is not '$' we have an error.
1442   if (Parser.getTok().isNot(AsmToken::Dollar))
1443     return MatchOperand_NoMatch;
1444   SMLoc S = Parser.getTok().getLoc();
1445   Parser.Lex(); // Eat the '$'
1446 
1447   const AsmToken &Tok = Parser.getTok(); // Get next token.
1448   if (Tok.is(AsmToken::Integer)) {
1449     RegNum = Tok.getIntVal();
1450     // At the moment only fcc0 is supported.
1451     if (RegNum != 0)
1452       return MatchOperand_ParseFail;
1453   } else if (Tok.is(AsmToken::Identifier)) {
1454     // At the moment only fcc0 is supported.
1455     if (Tok.getIdentifier() != "fcc0")
1456       return MatchOperand_ParseFail;
1457   } else
1458     return MatchOperand_NoMatch;
1459 
1460   MipsOperand *op = MipsOperand::CreateReg(Mips::FCC0, S,
1461                                            Parser.getTok().getLoc());
1462   op->setRegKind(MipsOperand::Kind_CCRRegs);
1463   Operands.push_back(op);
1464 
1465   Parser.Lex(); // Eat the register number.
1466   return MatchOperand_Success;
1467 }
1468 
1469 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
1470 
1471   MCSymbolRefExpr::VariantKind VK
1472                    = StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
1473     .Case("hi",          MCSymbolRefExpr::VK_Mips_ABS_HI)
1474     .Case("lo",          MCSymbolRefExpr::VK_Mips_ABS_LO)
1475     .Case("gp_rel",      MCSymbolRefExpr::VK_Mips_GPREL)
1476     .Case("call16",      MCSymbolRefExpr::VK_Mips_GOT_CALL)
1477     .Case("got",         MCSymbolRefExpr::VK_Mips_GOT)
1478     .Case("tlsgd",       MCSymbolRefExpr::VK_Mips_TLSGD)
1479     .Case("tlsldm",      MCSymbolRefExpr::VK_Mips_TLSLDM)
1480     .Case("dtprel_hi",   MCSymbolRefExpr::VK_Mips_DTPREL_HI)
1481     .Case("dtprel_lo",   MCSymbolRefExpr::VK_Mips_DTPREL_LO)
1482     .Case("gottprel",    MCSymbolRefExpr::VK_Mips_GOTTPREL)
1483     .Case("tprel_hi",    MCSymbolRefExpr::VK_Mips_TPREL_HI)
1484     .Case("tprel_lo",    MCSymbolRefExpr::VK_Mips_TPREL_LO)
1485     .Case("got_disp",    MCSymbolRefExpr::VK_Mips_GOT_DISP)
1486     .Case("got_page",    MCSymbolRefExpr::VK_Mips_GOT_PAGE)
1487     .Case("got_ofst",    MCSymbolRefExpr::VK_Mips_GOT_OFST)
1488     .Case("hi(%neg(%gp_rel",    MCSymbolRefExpr::VK_Mips_GPOFF_HI)
1489     .Case("lo(%neg(%gp_rel",    MCSymbolRefExpr::VK_Mips_GPOFF_LO)
1490     .Default(MCSymbolRefExpr::VK_None);
1491 
1492   return VK;
1493 }
1494 
1495 bool MipsAsmParser::
1496 ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
1497                  SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1498   // First operand in MCInst is instruction mnemonic.
1499   Operands.push_back(MipsOperand::CreateToken(Name, NameLoc));
1500 
1501   // Read the remaining operands.
1502   if (getLexer().isNot(AsmToken::EndOfStatement)) {
1503     // Read the first operand.
1504     if (ParseOperand(Operands, Name)) {
1505       SMLoc Loc = getLexer().getLoc();
1506       Parser.eatToEndOfStatement();
1507       return Error(Loc, "unexpected token in argument list");
1508     }
1509 
1510     while (getLexer().is(AsmToken::Comma)) {
1511       Parser.Lex(); // Eat the comma.
1512       // Parse and remember the operand.
1513       if (ParseOperand(Operands, Name)) {
1514         SMLoc Loc = getLexer().getLoc();
1515         Parser.eatToEndOfStatement();
1516         return Error(Loc, "unexpected token in argument list");
1517       }
1518     }
1519   }
1520   if (getLexer().isNot(AsmToken::EndOfStatement)) {
1521     SMLoc Loc = getLexer().getLoc();
1522     Parser.eatToEndOfStatement();
1523     return Error(Loc, "unexpected token in argument list");
1524   }
1525   Parser.Lex(); // Consume the EndOfStatement.
1526   return false;
1527 }
1528 
1529 bool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
1530   SMLoc Loc = getLexer().getLoc();
1531   Parser.eatToEndOfStatement();
1532   return Error(Loc, ErrorMsg);
1533 }
1534 
1535 bool MipsAsmParser::parseSetNoAtDirective() {
1536   // Line should look like: ".set noat".
1537   // set at reg to 0.
1538   Options.setATReg(0);
1539   // eat noat
1540   Parser.Lex();
1541   // If this is not the end of the statement, report an error.
1542   if (getLexer().isNot(AsmToken::EndOfStatement)) {
1543     reportParseError("unexpected token in statement");
1544     return false;
1545   }
1546   Parser.Lex(); // Consume the EndOfStatement.
1547   return false;
1548 }
1549 
1550 bool MipsAsmParser::parseSetAtDirective() {
1551   // Line can be .set at - defaults to $1
1552   // or .set at=$reg
1553   int AtRegNo;
1554   getParser().Lex();
1555   if (getLexer().is(AsmToken::EndOfStatement)) {
1556     Options.setATReg(1);
1557     Parser.Lex(); // Consume the EndOfStatement.
1558     return false;
1559   } else if (getLexer().is(AsmToken::Equal)) {
1560     getParser().Lex(); // Eat the '='.
1561     if (getLexer().isNot(AsmToken::Dollar)) {
1562       reportParseError("unexpected token in statement");
1563       return false;
1564     }
1565     Parser.Lex(); // Eat the '$'.
1566     const AsmToken &Reg = Parser.getTok();
1567     if (Reg.is(AsmToken::Identifier)) {
1568       AtRegNo = matchCPURegisterName(Reg.getIdentifier());
1569     } else if (Reg.is(AsmToken::Integer)) {
1570       AtRegNo = Reg.getIntVal();
1571     } else {
1572       reportParseError("unexpected token in statement");
1573       return false;
1574     }
1575 
1576     if (AtRegNo < 1 || AtRegNo > 31) {
1577       reportParseError("unexpected token in statement");
1578       return false;
1579     }
1580 
1581     if (!Options.setATReg(AtRegNo)) {
1582       reportParseError("unexpected token in statement");
1583       return false;
1584     }
1585     getParser().Lex(); // Eat the register.
1586 
1587     if (getLexer().isNot(AsmToken::EndOfStatement)) {
1588       reportParseError("unexpected token in statement");
1589       return false;
1590     }
1591     Parser.Lex(); // Consume the EndOfStatement.
1592     return false;
1593   } else {
1594     reportParseError("unexpected token in statement");
1595     return false;
1596   }
1597 }
1598 
1599 bool MipsAsmParser::parseSetReorderDirective() {
1600   Parser.Lex();
1601   // If this is not the end of the statement, report an error.
1602   if (getLexer().isNot(AsmToken::EndOfStatement)) {
1603     reportParseError("unexpected token in statement");
1604     return false;
1605   }
1606   Options.setReorder();
1607   Parser.Lex(); // Consume the EndOfStatement.
1608   return false;
1609 }
1610 
1611 bool MipsAsmParser::parseSetNoReorderDirective() {
1612   Parser.Lex();
1613   // If this is not the end of the statement, report an error.
1614   if (getLexer().isNot(AsmToken::EndOfStatement)) {
1615     reportParseError("unexpected token in statement");
1616     return false;
1617   }
1618   Options.setNoreorder();
1619   Parser.Lex(); // Consume the EndOfStatement.
1620   return false;
1621 }
1622 
1623 bool MipsAsmParser::parseSetMacroDirective() {
1624   Parser.Lex();
1625   // If this is not the end of the statement, report an error.
1626   if (getLexer().isNot(AsmToken::EndOfStatement)) {
1627     reportParseError("unexpected token in statement");
1628     return false;
1629   }
1630   Options.setMacro();
1631   Parser.Lex(); // Consume the EndOfStatement.
1632   return false;
1633 }
1634 
1635 bool MipsAsmParser::parseSetNoMacroDirective() {
1636   Parser.Lex();
1637   // If this is not the end of the statement, report an error.
1638   if (getLexer().isNot(AsmToken::EndOfStatement)) {
1639     reportParseError("`noreorder' must be set before `nomacro'");
1640     return false;
1641   }
1642   if (Options.isReorder()) {
1643     reportParseError("`noreorder' must be set before `nomacro'");
1644     return false;
1645   }
1646   Options.setNomacro();
1647   Parser.Lex(); // Consume the EndOfStatement.
1648   return false;
1649 }
1650 
1651 bool MipsAsmParser::parseSetAssignment() {
1652   StringRef Name;
1653   const MCExpr *Value;
1654 
1655   if (Parser.parseIdentifier(Name))
1656     reportParseError("expected identifier after .set");
1657 
1658   if (getLexer().isNot(AsmToken::Comma))
1659     return reportParseError("unexpected token in .set directive");
1660   Lex(); // Eat comma
1661 
1662   if (getLexer().is(AsmToken::Dollar)) {
1663     MCSymbol *Symbol;
1664     SMLoc DollarLoc = getLexer().getLoc();
1665     // Consume the dollar sign, and check for a following identifier.
1666     Parser.Lex();
1667     // We have a '$' followed by something, make sure they are adjacent.
1668     if (DollarLoc.getPointer() + 1 != getTok().getLoc().getPointer())
1669       return true;
1670     StringRef Res = StringRef(DollarLoc.getPointer(),
1671         getTok().getEndLoc().getPointer() - DollarLoc.getPointer());
1672     Symbol = getContext().GetOrCreateSymbol(Res);
1673     Parser.Lex();
1674     Value = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None,
1675                                     getContext());
1676   } else if (Parser.parseExpression(Value))
1677     return reportParseError("expected valid expression after comma");
1678 
1679   // Check if the Name already exists as a symbol.
1680   MCSymbol *Sym = getContext().LookupSymbol(Name);
1681   if (Sym)
1682     return reportParseError("symbol already defined");
1683   Sym = getContext().GetOrCreateSymbol(Name);
1684   Sym->setVariableValue(Value);
1685 
1686   return false;
1687 }
1688 
1689 bool MipsAsmParser::parseDirectiveSet() {
1690 
1691   // Get the next token.
1692   const AsmToken &Tok = Parser.getTok();
1693 
1694   if (Tok.getString() == "noat") {
1695     return parseSetNoAtDirective();
1696   } else if (Tok.getString() == "at") {
1697     return parseSetAtDirective();
1698   } else if (Tok.getString() == "reorder") {
1699     return parseSetReorderDirective();
1700   } else if (Tok.getString() == "noreorder") {
1701     return parseSetNoReorderDirective();
1702   } else if (Tok.getString() == "macro") {
1703     return parseSetMacroDirective();
1704   } else if (Tok.getString() == "nomacro") {
1705     return parseSetNoMacroDirective();
1706   } else if (Tok.getString() == "nomips16") {
1707     // Ignore this directive for now.
1708     Parser.eatToEndOfStatement();
1709     return false;
1710   } else if (Tok.getString() == "nomicromips") {
1711     // Ignore this directive for now.
1712     Parser.eatToEndOfStatement();
1713     return false;
1714   } else {
1715     // It is just an identifier, look for an assignment.
1716     parseSetAssignment();
1717     return false;
1718   }
1719 
1720   return true;
1721 }
1722 
1723 /// parseDirectiveWord
1724 ///  ::= .word [ expression (, expression)* ]
1725 bool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
1726   if (getLexer().isNot(AsmToken::EndOfStatement)) {
1727     for (;;) {
1728       const MCExpr *Value;
1729       if (getParser().parseExpression(Value))
1730         return true;
1731 
1732       getParser().getStreamer().EmitValue(Value, Size);
1733 
1734       if (getLexer().is(AsmToken::EndOfStatement))
1735         break;
1736 
1737       // FIXME: Improve diagnostic.
1738       if (getLexer().isNot(AsmToken::Comma))
1739         return Error(L, "unexpected token in directive");
1740       Parser.Lex();
1741     }
1742   }
1743 
1744   Parser.Lex();
1745   return false;
1746 }
1747 
1748 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
1749 
1750   StringRef IDVal = DirectiveID.getString();
1751 
1752   if (IDVal == ".ent") {
1753     // Ignore this directive for now.
1754     Parser.Lex();
1755     return false;
1756   }
1757 
1758   if (IDVal == ".end") {
1759     // Ignore this directive for now.
1760     Parser.Lex();
1761     return false;
1762   }
1763 
1764   if (IDVal == ".frame") {
1765     // Ignore this directive for now.
1766     Parser.eatToEndOfStatement();
1767     return false;
1768   }
1769 
1770   if (IDVal == ".set") {
1771     return parseDirectiveSet();
1772   }
1773 
1774   if (IDVal == ".fmask") {
1775     // Ignore this directive for now.
1776     Parser.eatToEndOfStatement();
1777     return false;
1778   }
1779 
1780   if (IDVal == ".mask") {
1781     // Ignore this directive for now.
1782     Parser.eatToEndOfStatement();
1783     return false;
1784   }
1785 
1786   if (IDVal == ".gpword") {
1787     // Ignore this directive for now.
1788     Parser.eatToEndOfStatement();
1789     return false;
1790   }
1791 
1792   if (IDVal == ".word") {
1793     parseDirectiveWord(4, DirectiveID.getLoc());
1794     return false;
1795   }
1796 
1797   return true;
1798 }
1799 
1800 extern "C" void LLVMInitializeMipsAsmParser() {
1801   RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
1802   RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
1803   RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
1804   RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
1805 }
1806 
1807 #define GET_REGISTER_MATCHER
1808 #define GET_MATCHER_IMPLEMENTATION
1809 #include "MipsGenAsmMatcher.inc"
1810