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