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