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