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