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