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("ac")) {
865     StringRef NumString = Name.substr(2);
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"
1913