This patch implements parsing of mips FCC register operands. The example instructions...
[oota-llvm.git] / lib / Target / Mips / AsmParser / MipsAsmParser.cpp
1 //===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "MCTargetDesc/MipsMCTargetDesc.h"
11 #include "MipsRegisterInfo.h"
12 #include "llvm/ADT/StringSwitch.h"
13 #include "llvm/MC/MCContext.h"
14 #include "llvm/MC/MCExpr.h"
15 #include "llvm/MC/MCInst.h"
16 #include "llvm/MC/MCParser/MCAsmLexer.h"
17 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
18 #include "llvm/MC/MCStreamer.h"
19 #include "llvm/MC/MCSubtargetInfo.h"
20 #include "llvm/MC/MCSymbol.h"
21 #include "llvm/MC/MCTargetAsmParser.h"
22 #include "llvm/Support/TargetRegistry.h"
23 #include "llvm/ADT/APInt.h"
24
25 using namespace llvm;
26
27 namespace {
28 class MipsAssemblerOptions {
29 public:
30   MipsAssemblerOptions():
31     aTReg(1), reorder(true), macro(true) {
32   }
33
34   unsigned getATRegNum() {return aTReg;}
35   bool setATReg(unsigned Reg);
36
37   bool isReorder() {return reorder;}
38   void setReorder() {reorder = true;}
39   void setNoreorder() {reorder = false;}
40
41   bool isMacro() {return macro;}
42   void setMacro() {macro = true;}
43   void setNomacro() {macro = false;}
44
45 private:
46   unsigned aTReg;
47   bool reorder;
48   bool macro;
49 };
50 }
51
52 namespace {
53 class MipsAsmParser : public MCTargetAsmParser {
54
55   enum FpFormatTy {
56     FP_FORMAT_NONE = -1,
57     FP_FORMAT_S,
58     FP_FORMAT_D,
59     FP_FORMAT_L,
60     FP_FORMAT_W
61   } FpFormat;
62
63   MCSubtargetInfo &STI;
64   MCAsmParser &Parser;
65   MipsAssemblerOptions Options;
66
67 #define GET_ASSEMBLER_HEADER
68 #include "MipsGenAsmMatcher.inc"
69
70   bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
71                                SmallVectorImpl<MCParsedAsmOperand*> &Operands,
72                                MCStreamer &Out, unsigned &ErrorInfo,
73                                bool MatchingInlineAsm);
74
75   bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
76
77   bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
78                         SMLoc NameLoc,
79                         SmallVectorImpl<MCParsedAsmOperand*> &Operands);
80
81   bool ParseDirective(AsmToken DirectiveID);
82
83   MipsAsmParser::OperandMatchResultTy
84   parseRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
85                          int RegKind);
86
87   MipsAsmParser::OperandMatchResultTy
88   parseMemOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
89
90   MipsAsmParser::OperandMatchResultTy
91   parseCPURegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
92
93   MipsAsmParser::OperandMatchResultTy
94   parseCPU64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
95
96   MipsAsmParser::OperandMatchResultTy
97   parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
98
99   MipsAsmParser::OperandMatchResultTy
100   parseHW64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
101
102   MipsAsmParser::OperandMatchResultTy
103   parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
104
105   MipsAsmParser::OperandMatchResultTy
106   parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
107
108   MipsAsmParser::OperandMatchResultTy
109   parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
110
111   MipsAsmParser::OperandMatchResultTy
112   parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
113
114   MipsAsmParser::OperandMatchResultTy
115   parseFCCRegs(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_CPURegs,
219     Kind_CPU64Regs,
220     Kind_HWRegs,
221     Kind_HW64Regs,
222     Kind_FGR32Regs,
223     Kind_FGR64Regs,
224     Kind_AFGR64Regs,
225     Kind_CCRRegs,
226     Kind_FCCRegs
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 isCPURegsAsm() const {
372     return Kind == k_Register && Reg.Kind == Kind_CPURegs;
373   }
374   void addRegAsmOperands(MCInst &Inst, unsigned N) const {
375     Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
376   }
377
378   bool isCPU64RegsAsm() const {
379     return Kind == k_Register && Reg.Kind == Kind_CPU64Regs;
380   }
381
382   bool isHWRegsAsm() const {
383     assert((Kind == k_Register) && "Invalid access!");
384     return Reg.Kind == Kind_HWRegs;
385   }
386
387   bool isHW64RegsAsm() const {
388     assert((Kind == k_Register) && "Invalid access!");
389     return Reg.Kind == Kind_HW64Regs;
390   }
391
392   bool isCCRAsm() const {
393     assert((Kind == k_Register) && "Invalid access!");
394     return Reg.Kind == Kind_CCRRegs;
395   }
396
397    bool isAFGR64Asm() const {
398     return Kind == k_Register && Reg.Kind == Kind_AFGR64Regs;
399   }
400
401   bool isFGR64Asm() const {
402     return Kind == k_Register && Reg.Kind == Kind_FGR64Regs;
403   }
404
405   bool isFGR32Asm() const {
406     return (Kind == k_Register) && Reg.Kind == Kind_FGR32Regs;
407   }
408
409   bool isFCCRegsAsm() const {
410     return (Kind == k_Register) && Reg.Kind == Kind_FCCRegs;
411   }
412
413   /// getStartLoc - Get the location of the first token of this operand.
414   SMLoc getStartLoc() const {
415     return StartLoc;
416   }
417   /// getEndLoc - Get the location of the last token of this operand.
418   SMLoc getEndLoc() const {
419     return EndLoc;
420   }
421
422   virtual void print(raw_ostream &OS) const {
423     llvm_unreachable("unimplemented!");
424   }
425 }; // class MipsOperand
426 }  // namespace
427
428 namespace llvm {
429 extern const MCInstrDesc MipsInsts[];
430 }
431 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
432   return MipsInsts[Opcode];
433 }
434
435 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
436                                        SmallVectorImpl<MCInst> &Instructions) {
437   const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
438   Inst.setLoc(IDLoc);
439   if (MCID.hasDelaySlot() && Options.isReorder()) {
440     // If this instruction has a delay slot and .set reorder is active,
441     // emit a NOP after it.
442     Instructions.push_back(Inst);
443     MCInst NopInst;
444     NopInst.setOpcode(Mips::SLL);
445     NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
446     NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
447     NopInst.addOperand(MCOperand::CreateImm(0));
448     Instructions.push_back(NopInst);
449     return false;
450   }
451
452   if (MCID.mayLoad() || MCID.mayStore()) {
453     // Check the offset of memory operand, if it is a symbol
454     // reference or immediate we may have to expand instructions.
455     for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
456       const MCOperandInfo &OpInfo = MCID.OpInfo[i];
457       if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY)
458           || (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
459         MCOperand &Op = Inst.getOperand(i);
460         if (Op.isImm()) {
461           int MemOffset = Op.getImm();
462           if (MemOffset < -32768 || MemOffset > 32767) {
463             // Offset can't exceed 16bit value.
464             expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
465             return false;
466           }
467         } else if (Op.isExpr()) {
468           const MCExpr *Expr = Op.getExpr();
469           if (Expr->getKind() == MCExpr::SymbolRef) {
470             const MCSymbolRefExpr *SR =
471                 static_cast<const MCSymbolRefExpr*>(Expr);
472             if (SR->getKind() == MCSymbolRefExpr::VK_None) {
473               // Expand symbol.
474               expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
475               return false;
476             }
477           } else if (!isEvaluated(Expr)) {
478             expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
479             return false;
480           }
481         }
482       }
483     } // for
484   } // if load/store
485
486   if (needsExpansion(Inst))
487     expandInstruction(Inst, IDLoc, Instructions);
488   else
489     Instructions.push_back(Inst);
490
491   return false;
492 }
493
494 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
495
496   switch (Inst.getOpcode()) {
497   case Mips::LoadImm32Reg:
498   case Mips::LoadAddr32Imm:
499   case Mips::LoadAddr32Reg:
500     return true;
501   default:
502     return false;
503   }
504 }
505
506 void MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
507                                        SmallVectorImpl<MCInst> &Instructions) {
508   switch (Inst.getOpcode()) {
509   case Mips::LoadImm32Reg:
510     return expandLoadImm(Inst, IDLoc, Instructions);
511   case Mips::LoadAddr32Imm:
512     return expandLoadAddressImm(Inst, IDLoc, Instructions);
513   case Mips::LoadAddr32Reg:
514     return expandLoadAddressReg(Inst, IDLoc, Instructions);
515   }
516 }
517
518 void MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
519                                   SmallVectorImpl<MCInst> &Instructions) {
520   MCInst tmpInst;
521   const MCOperand &ImmOp = Inst.getOperand(1);
522   assert(ImmOp.isImm() && "expected immediate operand kind");
523   const MCOperand &RegOp = Inst.getOperand(0);
524   assert(RegOp.isReg() && "expected register operand kind");
525
526   int ImmValue = ImmOp.getImm();
527   tmpInst.setLoc(IDLoc);
528   if (0 <= ImmValue && ImmValue <= 65535) {
529     // For 0 <= j <= 65535.
530     // li d,j => ori d,$zero,j
531     tmpInst.setOpcode(Mips::ORi);
532     tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
533     tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
534     tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
535     Instructions.push_back(tmpInst);
536   } else if (ImmValue < 0 && ImmValue >= -32768) {
537     // For -32768 <= j < 0.
538     // li d,j => addiu d,$zero,j
539     tmpInst.setOpcode(Mips::ADDiu);
540     tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
541     tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
542     tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
543     Instructions.push_back(tmpInst);
544   } else {
545     // For any other value of j that is representable as a 32-bit integer.
546     // li d,j => lui d,hi16(j)
547     //           ori d,d,lo16(j)
548     tmpInst.setOpcode(Mips::LUi);
549     tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
550     tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
551     Instructions.push_back(tmpInst);
552     tmpInst.clear();
553     tmpInst.setOpcode(Mips::ORi);
554     tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
555     tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
556     tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
557     tmpInst.setLoc(IDLoc);
558     Instructions.push_back(tmpInst);
559   }
560 }
561
562 void MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
563                                        SmallVectorImpl<MCInst> &Instructions) {
564   MCInst tmpInst;
565   const MCOperand &ImmOp = Inst.getOperand(2);
566   assert(ImmOp.isImm() && "expected immediate operand kind");
567   const MCOperand &SrcRegOp = Inst.getOperand(1);
568   assert(SrcRegOp.isReg() && "expected register operand kind");
569   const MCOperand &DstRegOp = Inst.getOperand(0);
570   assert(DstRegOp.isReg() && "expected register operand kind");
571   int ImmValue = ImmOp.getImm();
572   if (-32768 <= ImmValue && ImmValue <= 65535) {
573     // For -32768 <= j <= 65535.
574     // la d,j(s) => addiu d,s,j
575     tmpInst.setOpcode(Mips::ADDiu);
576     tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
577     tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
578     tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
579     Instructions.push_back(tmpInst);
580   } else {
581     // For any other value of j that is representable as a 32-bit integer.
582     // la d,j(s) => lui d,hi16(j)
583     //              ori d,d,lo16(j)
584     //              addu d,d,s
585     tmpInst.setOpcode(Mips::LUi);
586     tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
587     tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
588     Instructions.push_back(tmpInst);
589     tmpInst.clear();
590     tmpInst.setOpcode(Mips::ORi);
591     tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
592     tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
593     tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
594     Instructions.push_back(tmpInst);
595     tmpInst.clear();
596     tmpInst.setOpcode(Mips::ADDu);
597     tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
598     tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
599     tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
600     Instructions.push_back(tmpInst);
601   }
602 }
603
604 void MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
605                                        SmallVectorImpl<MCInst> &Instructions) {
606   MCInst tmpInst;
607   const MCOperand &ImmOp = Inst.getOperand(1);
608   assert(ImmOp.isImm() && "expected immediate operand kind");
609   const MCOperand &RegOp = Inst.getOperand(0);
610   assert(RegOp.isReg() && "expected register operand kind");
611   int ImmValue = ImmOp.getImm();
612   if (-32768 <= ImmValue && ImmValue <= 65535) {
613     // For -32768 <= j <= 65535.
614     // la d,j => addiu d,$zero,j
615     tmpInst.setOpcode(Mips::ADDiu);
616     tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
617     tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
618     tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
619     Instructions.push_back(tmpInst);
620   } else {
621     // For any other value of j that is representable as a 32-bit integer.
622     // la d,j => lui d,hi16(j)
623     //           ori d,d,lo16(j)
624     tmpInst.setOpcode(Mips::LUi);
625     tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
626     tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
627     Instructions.push_back(tmpInst);
628     tmpInst.clear();
629     tmpInst.setOpcode(Mips::ORi);
630     tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
631     tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
632     tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
633     Instructions.push_back(tmpInst);
634   }
635 }
636
637 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
638           SmallVectorImpl<MCInst> &Instructions, bool isLoad, bool isImmOpnd) {
639   const MCSymbolRefExpr *SR;
640   MCInst TempInst;
641   unsigned ImmOffset, HiOffset, LoOffset;
642   const MCExpr *ExprOffset;
643   unsigned TmpRegNum;
644   unsigned AtRegNum = getReg((isMips64()) ? Mips::CPU64RegsRegClassID
645                              : Mips::CPURegsRegClassID, getATReg());
646   // 1st operand is either the source or destination register.
647   assert(Inst.getOperand(0).isReg() && "expected register operand kind");
648   unsigned RegOpNum = Inst.getOperand(0).getReg();
649   // 2nd operand is the base register.
650   assert(Inst.getOperand(1).isReg() && "expected register operand kind");
651   unsigned BaseRegNum = Inst.getOperand(1).getReg();
652   // 3rd operand is either an immediate or expression.
653   if (isImmOpnd) {
654     assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
655     ImmOffset = Inst.getOperand(2).getImm();
656     LoOffset = ImmOffset & 0x0000ffff;
657     HiOffset = (ImmOffset & 0xffff0000) >> 16;
658     // If msb of LoOffset is 1(negative number) we must increment HiOffset.
659     if (LoOffset & 0x8000)
660       HiOffset++;
661   } else
662     ExprOffset = Inst.getOperand(2).getExpr();
663   // All instructions will have the same location.
664   TempInst.setLoc(IDLoc);
665   // 1st instruction in expansion is LUi. For load instruction we can use
666   // the dst register as a temporary if base and dst are different,
667   // but for stores we must use $at.
668   TmpRegNum = (isLoad && (BaseRegNum != RegOpNum)) ? RegOpNum : AtRegNum;
669   TempInst.setOpcode(Mips::LUi);
670   TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
671   if (isImmOpnd)
672     TempInst.addOperand(MCOperand::CreateImm(HiOffset));
673   else {
674     if (ExprOffset->getKind() == MCExpr::SymbolRef) {
675       SR = static_cast<const MCSymbolRefExpr*>(ExprOffset);
676       const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
677           SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
678           getContext());
679       TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
680     } else {
681       const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
682       TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
683     }
684   }
685   // Add the instruction to the list.
686   Instructions.push_back(TempInst);
687   // Prepare TempInst for next instruction.
688   TempInst.clear();
689   // Add temp register to base.
690   TempInst.setOpcode(Mips::ADDu);
691   TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
692   TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
693   TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
694   Instructions.push_back(TempInst);
695   TempInst.clear();
696   // And finaly, create original instruction with low part
697   // of offset and new base.
698   TempInst.setOpcode(Inst.getOpcode());
699   TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
700   TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
701   if (isImmOpnd)
702     TempInst.addOperand(MCOperand::CreateImm(LoOffset));
703   else {
704     if (ExprOffset->getKind() == MCExpr::SymbolRef) {
705       const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
706           SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
707           getContext());
708       TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
709     } else {
710       const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
711       TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
712     }
713   }
714   Instructions.push_back(TempInst);
715   TempInst.clear();
716 }
717
718 bool MipsAsmParser::
719 MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
720                         SmallVectorImpl<MCParsedAsmOperand*> &Operands,
721                         MCStreamer &Out, unsigned &ErrorInfo,
722                         bool MatchingInlineAsm) {
723   MCInst Inst;
724   SmallVector<MCInst, 8> Instructions;
725   unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
726                                               MatchingInlineAsm);
727
728   switch (MatchResult) {
729   default:
730     break;
731   case Match_Success: {
732     if (processInstruction(Inst, IDLoc, Instructions))
733       return true;
734     for (unsigned i = 0; i < Instructions.size(); i++)
735       Out.EmitInstruction(Instructions[i]);
736     return false;
737   }
738   case Match_MissingFeature:
739     Error(IDLoc, "instruction requires a CPU feature not currently enabled");
740     return true;
741   case Match_InvalidOperand: {
742     SMLoc ErrorLoc = IDLoc;
743     if (ErrorInfo != ~0U) {
744       if (ErrorInfo >= Operands.size())
745         return Error(IDLoc, "too few operands for instruction");
746
747       ErrorLoc = ((MipsOperand*) Operands[ErrorInfo])->getStartLoc();
748       if (ErrorLoc == SMLoc())
749         ErrorLoc = IDLoc;
750     }
751
752     return Error(ErrorLoc, "invalid operand for instruction");
753   }
754   case Match_MnemonicFail:
755     return Error(IDLoc, "invalid instruction");
756   }
757   return true;
758 }
759
760 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
761    int CC;
762
763   if (Name == "at")
764     return getATReg();
765
766     CC = StringSwitch<unsigned>(Name)
767     .Case("zero", 0)
768     .Case("a0",   4)
769     .Case("a1",   5)
770     .Case("a2",   6)
771     .Case("a3",   7)
772     .Case("v0",   2)
773     .Case("v1",   3)
774     .Case("s0",  16)
775     .Case("s1",  17)
776     .Case("s2",  18)
777     .Case("s3",  19)
778     .Case("s4",  20)
779     .Case("s5",  21)
780     .Case("s6",  22)
781     .Case("s7",  23)
782     .Case("k0",  26)
783     .Case("k1",  27)
784     .Case("sp",  29)
785     .Case("fp",  30)
786     .Case("gp",  28)
787     .Case("ra",  31)
788     .Case("t0",   8)
789     .Case("t1",   9)
790     .Case("t2",  10)
791     .Case("t3",  11)
792     .Case("t4",  12)
793     .Case("t5",  13)
794     .Case("t6",  14)
795     .Case("t7",  15)
796     .Case("t8",  24)
797     .Case("t9",  25)
798     .Default(-1);
799
800   // Although SGI documentation just cuts out t0-t3 for n32/n64,
801   // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
802   // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
803   if (isMips64() && 8 <= CC && CC <= 11)
804     CC += 4;
805
806   if (CC == -1 && isMips64())
807     CC = StringSwitch<unsigned>(Name)
808       .Case("a4",   8)
809       .Case("a5",   9)
810       .Case("a6",  10)
811       .Case("a7",  11)
812       .Case("kt0", 26)
813       .Case("kt1", 27)
814       .Case("s8",  30)
815       .Default(-1);
816
817   return CC;
818 }
819
820 int MipsAsmParser::matchFPURegisterName(StringRef Name, FpFormatTy Format) {
821
822   if (Name[0] == 'f') {
823     StringRef NumString = Name.substr(1);
824     unsigned IntVal;
825     if (NumString.getAsInteger(10, IntVal))
826       return -1; // This is not an integer.
827     if (IntVal > 31)
828       return -1;
829
830     if (Format == FP_FORMAT_S || Format == FP_FORMAT_W)
831       return getReg(Mips::FGR32RegClassID, IntVal);
832     if (Format == FP_FORMAT_D) {
833       if (isFP64()) {
834         return getReg(Mips::FGR64RegClassID, IntVal);
835       }
836       // Only even numbers available as register pairs.
837       if ((IntVal > 31) || (IntVal % 2 != 0))
838         return -1;
839       return getReg(Mips::AFGR64RegClassID, IntVal / 2);
840     }
841   }
842   return -1;
843 }
844
845 int MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) {
846
847   if (Name.equals("fcc0"))
848     return Mips::FCC0;
849
850   int CC;
851   CC = matchCPURegisterName(Name);
852   if (CC != -1)
853     return matchRegisterByNumber(CC, is64BitReg ? Mips::CPU64RegsRegClassID
854                                                 : Mips::CPURegsRegClassID);
855   return matchFPURegisterName(Name, getFpFormat());
856 }
857
858 void MipsAsmParser::setDefaultFpFormat() {
859
860   if (isMips64() || isFP64())
861     FpFormat = FP_FORMAT_D;
862   else
863     FpFormat = FP_FORMAT_S;
864 }
865
866 void MipsAsmParser::setFpFormat(StringRef Format) {
867
868   FpFormat = StringSwitch<FpFormatTy>(Format.lower())
869     .Case(".s",  FP_FORMAT_S)
870     .Case(".d",  FP_FORMAT_D)
871     .Case(".l",  FP_FORMAT_L)
872     .Case(".w",  FP_FORMAT_W)
873     .Default(FP_FORMAT_NONE);
874 }
875
876 bool MipsAssemblerOptions::setATReg(unsigned Reg) {
877   if (Reg > 31)
878     return false;
879
880   aTReg = Reg;
881   return true;
882 }
883
884 int MipsAsmParser::getATReg() {
885   return Options.getATRegNum();
886 }
887
888 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
889   return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
890 }
891
892 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
893
894   if (RegNum > 31)
895     return -1;
896
897   return getReg(RegClass, RegNum);
898 }
899
900 int MipsAsmParser::tryParseRegister(bool is64BitReg) {
901   const AsmToken &Tok = Parser.getTok();
902   int RegNum = -1;
903
904   if (Tok.is(AsmToken::Identifier)) {
905     std::string lowerCase = Tok.getString().lower();
906     RegNum = matchRegisterName(lowerCase, is64BitReg);
907   } else if (Tok.is(AsmToken::Integer))
908     RegNum = matchRegisterByNumber(static_cast<unsigned>(Tok.getIntVal()),
909         is64BitReg ? Mips::CPU64RegsRegClassID : Mips::CPURegsRegClassID);
910   return RegNum;
911 }
912
913 bool MipsAsmParser::tryParseRegisterOperand(
914              SmallVectorImpl<MCParsedAsmOperand*> &Operands, bool is64BitReg) {
915
916   SMLoc S = Parser.getTok().getLoc();
917   int RegNo = -1;
918
919   RegNo = tryParseRegister(is64BitReg);
920   if (RegNo == -1)
921     return true;
922
923   Operands.push_back(MipsOperand::CreateReg(RegNo, S,
924                                             Parser.getTok().getLoc()));
925   Parser.Lex(); // Eat register token.
926   return false;
927 }
928
929 bool MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*>&Operands,
930                                  StringRef Mnemonic) {
931   // Check if the current operand has a custom associated parser, if so, try to
932   // custom parse the operand, or fallback to the general approach.
933   OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
934   if (ResTy == MatchOperand_Success)
935     return false;
936   // If there wasn't a custom match, try the generic matcher below. Otherwise,
937   // there was a match, but an error occurred, in which case, just return that
938   // the operand parsing failed.
939   if (ResTy == MatchOperand_ParseFail)
940     return true;
941
942   switch (getLexer().getKind()) {
943   default:
944     Error(Parser.getTok().getLoc(), "unexpected token in operand");
945     return true;
946   case AsmToken::Dollar: {
947     // Parse the register.
948     SMLoc S = Parser.getTok().getLoc();
949     Parser.Lex(); // Eat dollar token.
950     // Parse the register operand.
951     if (!tryParseRegisterOperand(Operands, isMips64())) {
952       if (getLexer().is(AsmToken::LParen)) {
953         // Check if it is indexed addressing operand.
954         Operands.push_back(MipsOperand::CreateToken("(", S));
955         Parser.Lex(); // Eat the parenthesis.
956         if (getLexer().isNot(AsmToken::Dollar))
957           return true;
958
959         Parser.Lex(); // Eat the dollar
960         if (tryParseRegisterOperand(Operands, isMips64()))
961           return true;
962
963         if (!getLexer().is(AsmToken::RParen))
964           return true;
965
966         S = Parser.getTok().getLoc();
967         Operands.push_back(MipsOperand::CreateToken(")", S));
968         Parser.Lex();
969       }
970       return false;
971     }
972     // Maybe it is a symbol reference.
973     StringRef Identifier;
974     if (Parser.parseIdentifier(Identifier))
975       return true;
976
977     SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
978
979     MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
980
981     // Otherwise create a symbol reference.
982     const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
983                                                 getContext());
984
985     Operands.push_back(MipsOperand::CreateImm(Res, S, E));
986     return false;
987   }
988   case AsmToken::Identifier:
989     // Look for the existing symbol, we should check if
990     // we need to assigne the propper RegisterKind.
991     if (searchSymbolAlias(Operands, MipsOperand::Kind_None))
992       return false;
993     // Else drop to expression parsing.
994   case AsmToken::LParen:
995   case AsmToken::Minus:
996   case AsmToken::Plus:
997   case AsmToken::Integer:
998   case AsmToken::String: {
999     // Quoted label names.
1000     const MCExpr *IdVal;
1001     SMLoc S = Parser.getTok().getLoc();
1002     if (getParser().parseExpression(IdVal))
1003       return true;
1004     SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1005     Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1006     return false;
1007   }
1008   case AsmToken::Percent: {
1009     // It is a symbol reference or constant expression.
1010     const MCExpr *IdVal;
1011     SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
1012     if (parseRelocOperand(IdVal))
1013       return true;
1014
1015     SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1016
1017     Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1018     return false;
1019   } // case AsmToken::Percent
1020   } // switch(getLexer().getKind())
1021   return true;
1022 }
1023
1024 const MCExpr* MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
1025                                                StringRef RelocStr) {
1026   const MCExpr *Res;
1027   // Check the type of the expression.
1028   if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
1029     // It's a constant, evaluate lo or hi value.
1030     if (RelocStr == "lo") {
1031       short Val = MCE->getValue();
1032       Res = MCConstantExpr::Create(Val, getContext());
1033     } else if (RelocStr == "hi") {
1034       int Val = MCE->getValue();
1035       int LoSign = Val & 0x8000;
1036       Val = (Val & 0xffff0000) >> 16;
1037       // Lower part is treated as a signed int, so if it is negative
1038       // we must add 1 to the hi part to compensate.
1039       if (LoSign)
1040         Val++;
1041       Res = MCConstantExpr::Create(Val, getContext());
1042     } else {
1043       llvm_unreachable("Invalid RelocStr value");
1044     }
1045     return Res;
1046   }
1047
1048   if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
1049     // It's a symbol, create a symbolic expression from the symbol.
1050     StringRef Symbol = MSRE->getSymbol().getName();
1051     MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1052     Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
1053     return Res;
1054   }
1055
1056   if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1057     const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
1058     const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
1059     Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
1060     return Res;
1061   }
1062
1063   if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
1064     const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
1065     Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
1066     return Res;
1067   }
1068   // Just return the original expression.
1069   return Expr;
1070 }
1071
1072 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
1073
1074   switch (Expr->getKind()) {
1075   case MCExpr::Constant:
1076     return true;
1077   case MCExpr::SymbolRef:
1078     return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1079   case MCExpr::Binary:
1080     if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1081       if (!isEvaluated(BE->getLHS()))
1082         return false;
1083       return isEvaluated(BE->getRHS());
1084     }
1085   case MCExpr::Unary:
1086     return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
1087   default:
1088     return false;
1089   }
1090   return false;
1091 }
1092
1093 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
1094   Parser.Lex(); // Eat the % token.
1095   const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
1096   if (Tok.isNot(AsmToken::Identifier))
1097     return true;
1098
1099   std::string Str = Tok.getIdentifier().str();
1100
1101   Parser.Lex(); // Eat the identifier.
1102   // Now make an expression from the rest of the operand.
1103   const MCExpr *IdVal;
1104   SMLoc EndLoc;
1105
1106   if (getLexer().getKind() == AsmToken::LParen) {
1107     while (1) {
1108       Parser.Lex(); // Eat the '(' token.
1109       if (getLexer().getKind() == AsmToken::Percent) {
1110         Parser.Lex(); // Eat the % token.
1111         const AsmToken &nextTok = Parser.getTok();
1112         if (nextTok.isNot(AsmToken::Identifier))
1113           return true;
1114         Str += "(%";
1115         Str += nextTok.getIdentifier();
1116         Parser.Lex(); // Eat the identifier.
1117         if (getLexer().getKind() != AsmToken::LParen)
1118           return true;
1119       } else
1120         break;
1121     }
1122     if (getParser().parseParenExpression(IdVal, EndLoc))
1123       return true;
1124
1125     while (getLexer().getKind() == AsmToken::RParen)
1126       Parser.Lex(); // Eat the ')' token.
1127
1128   } else
1129     return true; // Parenthesis must follow the relocation operand.
1130
1131   Res = evaluateRelocExpr(IdVal, Str);
1132   return false;
1133 }
1134
1135 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1136                                   SMLoc &EndLoc) {
1137   StartLoc = Parser.getTok().getLoc();
1138   RegNo = tryParseRegister(isMips64());
1139   EndLoc = Parser.getTok().getLoc();
1140   return (RegNo == (unsigned) -1);
1141 }
1142
1143 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
1144   SMLoc S;
1145   bool Result = true;
1146
1147   while (getLexer().getKind() == AsmToken::LParen)
1148     Parser.Lex();
1149
1150   switch (getLexer().getKind()) {
1151   default:
1152     return true;
1153   case AsmToken::Identifier:
1154   case AsmToken::LParen:
1155   case AsmToken::Integer:
1156   case AsmToken::Minus:
1157   case AsmToken::Plus:
1158     if (isParenExpr)
1159       Result = getParser().parseParenExpression(Res, S);
1160     else
1161       Result = (getParser().parseExpression(Res));
1162     while (getLexer().getKind() == AsmToken::RParen)
1163       Parser.Lex();
1164     break;
1165   case AsmToken::Percent:
1166     Result = parseRelocOperand(Res);
1167   }
1168   return Result;
1169 }
1170
1171 MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
1172                                SmallVectorImpl<MCParsedAsmOperand*>&Operands) {
1173
1174   const MCExpr *IdVal = 0;
1175   SMLoc S;
1176   bool isParenExpr = false;
1177   // First operand is the offset.
1178   S = Parser.getTok().getLoc();
1179
1180   if (getLexer().getKind() == AsmToken::LParen) {
1181     Parser.Lex();
1182     isParenExpr = true;
1183   }
1184
1185   if (getLexer().getKind() != AsmToken::Dollar) {
1186     if (parseMemOffset(IdVal, isParenExpr))
1187       return MatchOperand_ParseFail;
1188
1189     const AsmToken &Tok = Parser.getTok(); // Get the next token.
1190     if (Tok.isNot(AsmToken::LParen)) {
1191       MipsOperand *Mnemonic = static_cast<MipsOperand*>(Operands[0]);
1192       if (Mnemonic->getToken() == "la") {
1193         SMLoc E = SMLoc::getFromPointer(
1194             Parser.getTok().getLoc().getPointer() - 1);
1195         Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1196         return MatchOperand_Success;
1197       }
1198       if (Tok.is(AsmToken::EndOfStatement)) {
1199         SMLoc E = SMLoc::getFromPointer(
1200             Parser.getTok().getLoc().getPointer() - 1);
1201
1202         // Zero register assumed, add a memory operand with ZERO as its base.
1203         Operands.push_back(MipsOperand::CreateMem(isMips64() ? Mips::ZERO_64
1204                                                              : Mips::ZERO,
1205                            IdVal, S, E));
1206         return MatchOperand_Success;
1207       }
1208       Error(Parser.getTok().getLoc(), "'(' expected");
1209       return MatchOperand_ParseFail;
1210     }
1211
1212     Parser.Lex(); // Eat the '(' token.
1213   }
1214
1215   const AsmToken &Tok1 = Parser.getTok(); // Get next token
1216   if (Tok1.is(AsmToken::Dollar)) {
1217     Parser.Lex(); // Eat the '$' token.
1218     if (tryParseRegisterOperand(Operands, isMips64())) {
1219       Error(Parser.getTok().getLoc(), "unexpected token in operand");
1220       return MatchOperand_ParseFail;
1221     }
1222
1223   } else {
1224     Error(Parser.getTok().getLoc(), "unexpected token in operand");
1225     return MatchOperand_ParseFail;
1226   }
1227
1228   const AsmToken &Tok2 = Parser.getTok(); // Get next token.
1229   if (Tok2.isNot(AsmToken::RParen)) {
1230     Error(Parser.getTok().getLoc(), "')' expected");
1231     return MatchOperand_ParseFail;
1232   }
1233
1234   SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1235
1236   Parser.Lex(); // Eat the ')' token.
1237
1238   if (IdVal == 0)
1239     IdVal = MCConstantExpr::Create(0, getContext());
1240
1241   // Replace the register operand with the memory operand.
1242   MipsOperand* op = static_cast<MipsOperand*>(Operands.back());
1243   int RegNo = op->getReg();
1244   // Remove the register from the operands.
1245   Operands.pop_back();
1246   // Add the memory operand.
1247   if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
1248     int64_t Imm;
1249     if (IdVal->EvaluateAsAbsolute(Imm))
1250       IdVal = MCConstantExpr::Create(Imm, getContext());
1251     else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
1252       IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
1253                                    getContext());
1254   }
1255
1256   Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E));
1257   delete op;
1258   return MatchOperand_Success;
1259 }
1260
1261 MipsAsmParser::OperandMatchResultTy
1262 MipsAsmParser::parseRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1263                          int RegKind) {
1264   MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1265   if (getLexer().getKind() == AsmToken::Identifier) {
1266     if (searchSymbolAlias(Operands, Kind))
1267       return MatchOperand_Success;
1268     return MatchOperand_NoMatch;
1269   }
1270   // If the first token is not '$', we have an error.
1271   if (Parser.getTok().isNot(AsmToken::Dollar))
1272     return MatchOperand_NoMatch;
1273
1274   Parser.Lex(); // Eat $
1275   if (!tryParseRegisterOperand(Operands, isMips64())) {
1276     // Set the proper register kind.
1277     MipsOperand* op = static_cast<MipsOperand*>(Operands.back());
1278     op->setRegKind(Kind);
1279     if ((Kind == MipsOperand::Kind_CPURegs)
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::parseCPU64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1298
1299   if (!isMips64())
1300     return MatchOperand_NoMatch;
1301   return parseRegs(Operands, (int) MipsOperand::Kind_CPU64Regs);
1302 }
1303
1304 MipsAsmParser::OperandMatchResultTy
1305 MipsAsmParser::parseCPURegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1306  return parseRegs(Operands, (int) MipsOperand::Kind_CPURegs);
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 bool MipsAsmParser::searchSymbolAlias(
1371     SmallVectorImpl<MCParsedAsmOperand*> &Operands, unsigned RegKind) {
1372
1373   MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
1374   if (Sym) {
1375     SMLoc S = Parser.getTok().getLoc();
1376     const MCExpr *Expr;
1377     if (Sym->isVariable())
1378       Expr = Sym->getVariableValue();
1379     else
1380       return false;
1381     if (Expr->getKind() == MCExpr::SymbolRef) {
1382       MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind) RegKind;
1383       const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Expr);
1384       const StringRef DefSymbol = Ref->getSymbol().getName();
1385       if (DefSymbol.startswith("$")) {
1386         int RegNum = -1;
1387         APInt IntVal(32, -1);
1388         if (!DefSymbol.substr(1).getAsInteger(10, IntVal))
1389           RegNum = matchRegisterByNumber(IntVal.getZExtValue(),
1390                                      isMips64()
1391                                        ? Mips::CPU64RegsRegClassID
1392                                        : Mips::CPURegsRegClassID);
1393         else {
1394           // Lookup for the register with the corresponding name.
1395           switch (Kind) {
1396           case MipsOperand::Kind_AFGR64Regs:
1397           case MipsOperand::Kind_FGR64Regs:
1398             RegNum = matchFPURegisterName(DefSymbol.substr(1), FP_FORMAT_D);
1399             break;
1400           case MipsOperand::Kind_FGR32Regs:
1401             RegNum = matchFPURegisterName(DefSymbol.substr(1), FP_FORMAT_S);
1402             break;
1403           case MipsOperand::Kind_CPU64Regs:
1404           case MipsOperand::Kind_CPURegs:
1405           default:
1406             RegNum = matchRegisterName(DefSymbol.substr(1), isMips64());
1407             break;
1408           }
1409         }
1410         if (RegNum > -1) {
1411           Parser.Lex();
1412           MipsOperand *op = MipsOperand::CreateReg(RegNum, S,
1413                                                    Parser.getTok().getLoc());
1414           op->setRegKind(Kind);
1415           Operands.push_back(op);
1416           return true;
1417         }
1418       }
1419     } else if (Expr->getKind() == MCExpr::Constant) {
1420       Parser.Lex();
1421       const MCConstantExpr *Const = static_cast<const MCConstantExpr*>(Expr);
1422       MipsOperand *op = MipsOperand::CreateImm(Const, S,
1423           Parser.getTok().getLoc());
1424       Operands.push_back(op);
1425       return true;
1426     }
1427   }
1428   return false;
1429 }
1430
1431 MipsAsmParser::OperandMatchResultTy
1432 MipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1433
1434   if (isMips64())
1435     return MatchOperand_NoMatch;
1436
1437   // If the first token is not '$' we have error.
1438   if (Parser.getTok().isNot(AsmToken::Dollar))
1439     return MatchOperand_NoMatch;
1440   SMLoc S = Parser.getTok().getLoc();
1441   Parser.Lex(); // Eat the '$'.
1442
1443   const AsmToken &Tok = Parser.getTok(); // Get the next token.
1444   if (Tok.isNot(AsmToken::Integer))
1445     return MatchOperand_NoMatch;
1446
1447   unsigned RegNum = Tok.getIntVal();
1448   // At the moment only hwreg29 is supported.
1449   if (RegNum != 29)
1450     return MatchOperand_ParseFail;
1451
1452   MipsOperand *op = MipsOperand::CreateReg(Mips::HWR29, S,
1453       Parser.getTok().getLoc());
1454   op->setRegKind(MipsOperand::Kind_HWRegs);
1455   Operands.push_back(op);
1456
1457   Parser.Lex(); // Eat the register number.
1458   return MatchOperand_Success;
1459 }
1460
1461 MipsAsmParser::OperandMatchResultTy
1462 MipsAsmParser::parseHW64Regs(
1463     SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1464
1465   if (!isMips64())
1466     return MatchOperand_NoMatch;
1467   // If the first token is not '$' we have an error.
1468   if (Parser.getTok().isNot(AsmToken::Dollar))
1469     return MatchOperand_NoMatch;
1470   SMLoc S = Parser.getTok().getLoc();
1471   Parser.Lex(); // Eat $
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_64, S,
1483                                            Parser.getTok().getLoc());
1484   op->setRegKind(MipsOperand::Kind_HW64Regs);
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"