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