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