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