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