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