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