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/MipsMCExpr.h"
11 #include "MCTargetDesc/MipsMCTargetDesc.h"
12 #include "MipsRegisterInfo.h"
13 #include "MipsTargetStreamer.h"
14 #include "llvm/ADT/APInt.h"
15 #include "llvm/ADT/StringSwitch.h"
16 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/MC/MCContext.h"
18 #include "llvm/MC/MCExpr.h"
19 #include "llvm/MC/MCInst.h"
20 #include "llvm/MC/MCInstBuilder.h"
21 #include "llvm/MC/MCParser/MCAsmLexer.h"
22 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
23 #include "llvm/MC/MCStreamer.h"
24 #include "llvm/MC/MCSubtargetInfo.h"
25 #include "llvm/MC/MCSymbol.h"
26 #include "llvm/MC/MCTargetAsmParser.h"
27 #include "llvm/Support/Debug.h"
28 #include "llvm/Support/MathExtras.h"
29 #include "llvm/Support/TargetRegistry.h"
30 #include "llvm/Support/SourceMgr.h"
31 #include <memory>
32 
33 using namespace llvm;
34 
35 #define DEBUG_TYPE "mips-asm-parser"
36 
37 namespace llvm {
38 class MCInstrInfo;
39 }
40 
41 namespace {
42 class MipsAssemblerOptions {
43 public:
44   MipsAssemblerOptions(uint64_t Features_) :
45     ATReg(1), Reorder(true), Macro(true), Features(Features_) {}
46 
47   MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
48     ATReg = Opts->getATRegNum();
49     Reorder = Opts->isReorder();
50     Macro = Opts->isMacro();
51     Features = Opts->getFeatures();
52   }
53 
54   unsigned getATRegNum() const { return ATReg; }
55   bool setATReg(unsigned Reg);
56 
57   bool isReorder() const { return Reorder; }
58   void setReorder() { Reorder = true; }
59   void setNoReorder() { Reorder = false; }
60 
61   bool isMacro() const { return Macro; }
62   void setMacro() { Macro = true; }
63   void setNoMacro() { Macro = false; }
64 
65   uint64_t getFeatures() const { return Features; }
66   void setFeatures(uint64_t Features_) { Features = Features_; }
67 
68   // Set of features that are either architecture features or referenced
69   // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
70   // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
71   // The reason we need this mask is explained in the selectArch function.
72   // FIXME: Ideally we would like TableGen to generate this information.
73   static const uint64_t AllArchRelatedMask =
74       Mips::FeatureMips1 | Mips::FeatureMips2 | Mips::FeatureMips3 |
75       Mips::FeatureMips3_32 | Mips::FeatureMips3_32r2 | Mips::FeatureMips4 |
76       Mips::FeatureMips4_32 | Mips::FeatureMips4_32r2 | Mips::FeatureMips5 |
77       Mips::FeatureMips5_32r2 | Mips::FeatureMips32 | Mips::FeatureMips32r2 |
78       Mips::FeatureMips32r6 | Mips::FeatureMips64 | Mips::FeatureMips64r2 |
79       Mips::FeatureMips64r6 | Mips::FeatureCnMips | Mips::FeatureFP64Bit |
80       Mips::FeatureGP64Bit | Mips::FeatureNaN2008;
81 
82 private:
83   unsigned ATReg;
84   bool Reorder;
85   bool Macro;
86   uint64_t Features;
87 };
88 }
89 
90 namespace {
91 class MipsAsmParser : public MCTargetAsmParser {
92   MipsTargetStreamer &getTargetStreamer() {
93     MCTargetStreamer &TS = *Parser.getStreamer().getTargetStreamer();
94     return static_cast<MipsTargetStreamer &>(TS);
95   }
96 
97   MCSubtargetInfo &STI;
98   MCAsmParser &Parser;
99   SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
100   MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
101                        // nullptr, which indicates that no function is currently
102                        // selected. This usually happens after an '.end func'
103                        // directive.
104 
105   // Print a warning along with its fix-it message at the given range.
106   void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
107                              SMRange Range, bool ShowColors = true);
108 
109 #define GET_ASSEMBLER_HEADER
110 #include "MipsGenAsmMatcher.inc"
111 
112   unsigned checkTargetMatchPredicate(MCInst &Inst) override;
113 
114   bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
115                                OperandVector &Operands, MCStreamer &Out,
116                                uint64_t &ErrorInfo,
117                                bool MatchingInlineAsm) override;
118 
119   /// Parse a register as used in CFI directives
120   bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
121 
122   bool parseParenSuffix(StringRef Name, OperandVector &Operands);
123 
124   bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
125 
126   bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
127                         SMLoc NameLoc, OperandVector &Operands) override;
128 
129   bool ParseDirective(AsmToken DirectiveID) override;
130 
131   MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands);
132 
133   MipsAsmParser::OperandMatchResultTy
134   matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
135                                     StringRef Identifier, SMLoc S);
136 
137   MipsAsmParser::OperandMatchResultTy
138   matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
139 
140   MipsAsmParser::OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
141 
142   MipsAsmParser::OperandMatchResultTy parseImm(OperandVector &Operands);
143 
144   MipsAsmParser::OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
145 
146   MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands);
147 
148   MipsAsmParser::OperandMatchResultTy parseLSAImm(OperandVector &Operands);
149 
150   bool searchSymbolAlias(OperandVector &Operands);
151 
152   bool parseOperand(OperandVector &, StringRef Mnemonic);
153 
154   bool needsExpansion(MCInst &Inst);
155 
156   // Expands assembly pseudo instructions.
157   // Returns false on success, true otherwise.
158   bool expandInstruction(MCInst &Inst, SMLoc IDLoc,
159                          SmallVectorImpl<MCInst> &Instructions);
160 
161   bool expandLoadImm(MCInst &Inst, SMLoc IDLoc,
162                      SmallVectorImpl<MCInst> &Instructions);
163 
164   bool expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
165                             SmallVectorImpl<MCInst> &Instructions);
166 
167   bool expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
168                             SmallVectorImpl<MCInst> &Instructions);
169 
170   void expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
171                             SmallVectorImpl<MCInst> &Instructions);
172 
173   void expandMemInst(MCInst &Inst, SMLoc IDLoc,
174                      SmallVectorImpl<MCInst> &Instructions, bool isLoad,
175                      bool isImmOpnd);
176   bool reportParseError(Twine ErrorMsg);
177   bool reportParseError(SMLoc Loc, Twine ErrorMsg);
178 
179   bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
180   bool parseRelocOperand(const MCExpr *&Res);
181 
182   const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
183 
184   bool isEvaluated(const MCExpr *Expr);
185   bool parseSetMips0Directive();
186   bool parseSetArchDirective();
187   bool parseSetFeature(uint64_t Feature);
188   bool parseDirectiveCpLoad(SMLoc Loc);
189   bool parseDirectiveCPSetup();
190   bool parseDirectiveNaN();
191   bool parseDirectiveSet();
192   bool parseDirectiveOption();
193 
194   bool parseSetAtDirective();
195   bool parseSetNoAtDirective();
196   bool parseSetMacroDirective();
197   bool parseSetNoMacroDirective();
198   bool parseSetMsaDirective();
199   bool parseSetNoMsaDirective();
200   bool parseSetNoDspDirective();
201   bool parseSetReorderDirective();
202   bool parseSetNoReorderDirective();
203   bool parseSetNoMips16Directive();
204   bool parseSetFpDirective();
205   bool parseSetPopDirective();
206   bool parseSetPushDirective();
207 
208   bool parseSetAssignment();
209 
210   bool parseDataDirective(unsigned Size, SMLoc L);
211   bool parseDirectiveGpWord();
212   bool parseDirectiveGpDWord();
213   bool parseDirectiveModule();
214   bool parseDirectiveModuleFP();
215   bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
216                        StringRef Directive);
217 
218   MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
219 
220   bool eatComma(StringRef ErrorStr);
221 
222   int matchCPURegisterName(StringRef Symbol);
223 
224   int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
225 
226   int matchFPURegisterName(StringRef Name);
227 
228   int matchFCCRegisterName(StringRef Name);
229 
230   int matchACRegisterName(StringRef Name);
231 
232   int matchMSA128RegisterName(StringRef Name);
233 
234   int matchMSA128CtrlRegisterName(StringRef Name);
235 
236   unsigned getReg(int RC, int RegNo);
237 
238   unsigned getGPR(int RegNo);
239 
240   int getATReg(SMLoc Loc);
241 
242   bool processInstruction(MCInst &Inst, SMLoc IDLoc,
243                           SmallVectorImpl<MCInst> &Instructions);
244 
245   // Helper function that checks if the value of a vector index is within the
246   // boundaries of accepted values for each RegisterKind
247   // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
248   bool validateMSAIndex(int Val, int RegKind);
249 
250   // Selects a new architecture by updating the FeatureBits with the necessary
251   // info including implied dependencies.
252   // Internally, it clears all the feature bits related to *any* architecture
253   // and selects the new one using the ToggleFeature functionality of the
254   // MCSubtargetInfo object that handles implied dependencies. The reason we
255   // clear all the arch related bits manually is because ToggleFeature only
256   // clears the features that imply the feature being cleared and not the
257   // features implied by the feature being cleared. This is easier to see
258   // with an example:
259   //  --------------------------------------------------
260   // | Feature         | Implies                        |
261   // | -------------------------------------------------|
262   // | FeatureMips1    | None                           |
263   // | FeatureMips2    | FeatureMips1                   |
264   // | FeatureMips3    | FeatureMips2 | FeatureMipsGP64 |
265   // | FeatureMips4    | FeatureMips3                   |
266   // | ...             |                                |
267   //  --------------------------------------------------
268   //
269   // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
270   // FeatureMipsGP64 | FeatureMips1)
271   // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
272   void selectArch(StringRef ArchFeature) {
273     uint64_t FeatureBits = STI.getFeatureBits();
274     FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
275     STI.setFeatureBits(FeatureBits);
276     setAvailableFeatures(
277         ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
278     AssemblerOptions.back()->setFeatures(getAvailableFeatures());
279   }
280 
281   void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
282     if (!(STI.getFeatureBits() & Feature)) {
283       setAvailableFeatures(
284           ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
285     }
286     AssemblerOptions.back()->setFeatures(getAvailableFeatures());
287   }
288 
289   void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
290     if (STI.getFeatureBits() & Feature) {
291       setAvailableFeatures(
292           ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
293     }
294     AssemblerOptions.back()->setFeatures(getAvailableFeatures());
295   }
296 
297 public:
298   enum MipsMatchResultTy {
299     Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
300 #define GET_OPERAND_DIAGNOSTIC_TYPES
301 #include "MipsGenAsmMatcher.inc"
302 #undef GET_OPERAND_DIAGNOSTIC_TYPES
303 
304   };
305 
306   MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
307                 const MCInstrInfo &MII, const MCTargetOptions &Options)
308       : MCTargetAsmParser(), STI(sti), Parser(parser) {
309     // Initialize the set of available features.
310     setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
311 
312     // Remember the initial assembler options. The user can not modify these.
313     AssemblerOptions.push_back(
314                      make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
315 
316     // Create an assembler options environment for the user to modify.
317     AssemblerOptions.push_back(
318                      make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
319 
320     getTargetStreamer().updateABIInfo(*this);
321 
322     // Assert exactly one ABI was chosen.
323     assert((((STI.getFeatureBits() & Mips::FeatureO32) != 0) +
324             ((STI.getFeatureBits() & Mips::FeatureEABI) != 0) +
325             ((STI.getFeatureBits() & Mips::FeatureN32) != 0) +
326             ((STI.getFeatureBits() & Mips::FeatureN64) != 0)) == 1);
327 
328     if (!isABI_O32() && !useOddSPReg() != 0)
329       report_fatal_error("-mno-odd-spreg requires the O32 ABI");
330 
331     CurrentFn = nullptr;
332   }
333 
334   MCAsmParser &getParser() const { return Parser; }
335   MCAsmLexer &getLexer() const { return Parser.getLexer(); }
336 
337   /// True if all of $fcc0 - $fcc7 exist for the current ISA.
338   bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
339 
340   bool isGP64bit() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; }
341   bool isFP64bit() const { return STI.getFeatureBits() & Mips::FeatureFP64Bit; }
342   bool isABI_N32() const { return STI.getFeatureBits() & Mips::FeatureN32; }
343   bool isABI_N64() const { return STI.getFeatureBits() & Mips::FeatureN64; }
344   bool isABI_O32() const { return STI.getFeatureBits() & Mips::FeatureO32; }
345   bool isABI_FPXX() const { return STI.getFeatureBits() & Mips::FeatureFPXX; }
346 
347   bool useOddSPReg() const {
348     return !(STI.getFeatureBits() & Mips::FeatureNoOddSPReg);
349   }
350 
351   bool inMicroMipsMode() const {
352     return STI.getFeatureBits() & Mips::FeatureMicroMips;
353   }
354   bool hasMips1() const { return STI.getFeatureBits() & Mips::FeatureMips1; }
355   bool hasMips2() const { return STI.getFeatureBits() & Mips::FeatureMips2; }
356   bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; }
357   bool hasMips4() const { return STI.getFeatureBits() & Mips::FeatureMips4; }
358   bool hasMips5() const { return STI.getFeatureBits() & Mips::FeatureMips5; }
359   bool hasMips32() const {
360     return (STI.getFeatureBits() & Mips::FeatureMips32);
361   }
362   bool hasMips64() const {
363     return (STI.getFeatureBits() & Mips::FeatureMips64);
364   }
365   bool hasMips32r2() const {
366     return (STI.getFeatureBits() & Mips::FeatureMips32r2);
367   }
368   bool hasMips64r2() const {
369     return (STI.getFeatureBits() & Mips::FeatureMips64r2);
370   }
371   bool hasMips32r6() const {
372     return (STI.getFeatureBits() & Mips::FeatureMips32r6);
373   }
374   bool hasMips64r6() const {
375     return (STI.getFeatureBits() & Mips::FeatureMips64r6);
376   }
377   bool hasDSP() const { return (STI.getFeatureBits() & Mips::FeatureDSP); }
378   bool hasDSPR2() const { return (STI.getFeatureBits() & Mips::FeatureDSPR2); }
379   bool hasMSA() const { return (STI.getFeatureBits() & Mips::FeatureMSA); }
380 
381   bool inMips16Mode() const {
382     return STI.getFeatureBits() & Mips::FeatureMips16;
383   }
384   // TODO: see how can we get this info.
385   bool abiUsesSoftFloat() const { return false; }
386 
387   /// Warn if RegNo is the current assembler temporary.
388   void warnIfAssemblerTemporary(int RegNo, SMLoc Loc);
389 };
390 }
391 
392 namespace {
393 
394 /// MipsOperand - Instances of this class represent a parsed Mips machine
395 /// instruction.
396 class MipsOperand : public MCParsedAsmOperand {
397 public:
398   /// Broad categories of register classes
399   /// The exact class is finalized by the render method.
400   enum RegKind {
401     RegKind_GPR = 1,      /// GPR32 and GPR64 (depending on isGP64bit())
402     RegKind_FGR = 2,      /// FGR32, FGR64, AFGR64 (depending on context and
403                           /// isFP64bit())
404     RegKind_FCC = 4,      /// FCC
405     RegKind_MSA128 = 8,   /// MSA128[BHWD] (makes no difference which)
406     RegKind_MSACtrl = 16, /// MSA control registers
407     RegKind_COP2 = 32,    /// COP2
408     RegKind_ACC = 64,     /// HI32DSP, LO32DSP, and ACC64DSP (depending on
409                           /// context).
410     RegKind_CCR = 128,    /// CCR
411     RegKind_HWRegs = 256, /// HWRegs
412     RegKind_COP3 = 512,   /// COP3
413 
414     /// Potentially any (e.g. $1)
415     RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
416                       RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
417                       RegKind_CCR | RegKind_HWRegs | RegKind_COP3
418   };
419 
420 private:
421   enum KindTy {
422     k_Immediate,     /// An immediate (possibly involving symbol references)
423     k_Memory,        /// Base + Offset Memory Address
424     k_PhysRegister,  /// A physical register from the Mips namespace
425     k_RegisterIndex, /// A register index in one or more RegKind.
426     k_Token          /// A simple token
427   } Kind;
428 
429 public:
430   MipsOperand(KindTy K, MipsAsmParser &Parser)
431       : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
432 
433 private:
434   /// For diagnostics, and checking the assembler temporary
435   MipsAsmParser &AsmParser;
436 
437   struct Token {
438     const char *Data;
439     unsigned Length;
440   };
441 
442   struct PhysRegOp {
443     unsigned Num; /// Register Number
444   };
445 
446   struct RegIdxOp {
447     unsigned Index; /// Index into the register class
448     RegKind Kind;   /// Bitfield of the kinds it could possibly be
449     const MCRegisterInfo *RegInfo;
450   };
451 
452   struct ImmOp {
453     const MCExpr *Val;
454   };
455 
456   struct MemOp {
457     MipsOperand *Base;
458     const MCExpr *Off;
459   };
460 
461   union {
462     struct Token Tok;
463     struct PhysRegOp PhysReg;
464     struct RegIdxOp RegIdx;
465     struct ImmOp Imm;
466     struct MemOp Mem;
467   };
468 
469   SMLoc StartLoc, EndLoc;
470 
471   /// Internal constructor for register kinds
472   static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
473                                                 const MCRegisterInfo *RegInfo,
474                                                 SMLoc S, SMLoc E,
475                                                 MipsAsmParser &Parser) {
476     auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
477     Op->RegIdx.Index = Index;
478     Op->RegIdx.RegInfo = RegInfo;
479     Op->RegIdx.Kind = RegKind;
480     Op->StartLoc = S;
481     Op->EndLoc = E;
482     return Op;
483   }
484 
485 public:
486   /// Coerce the register to GPR32 and return the real register for the current
487   /// target.
488   unsigned getGPR32Reg() const {
489     assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
490     AsmParser.warnIfAssemblerTemporary(RegIdx.Index, StartLoc);
491     unsigned ClassID = Mips::GPR32RegClassID;
492     return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
493   }
494 
495   /// Coerce the register to GPR64 and return the real register for the current
496   /// target.
497   unsigned getGPR64Reg() const {
498     assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
499     unsigned ClassID = Mips::GPR64RegClassID;
500     return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
501   }
502 
503 private:
504   /// Coerce the register to AFGR64 and return the real register for the current
505   /// target.
506   unsigned getAFGR64Reg() const {
507     assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
508     if (RegIdx.Index % 2 != 0)
509       AsmParser.Warning(StartLoc, "Float register should be even.");
510     return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
511         .getRegister(RegIdx.Index / 2);
512   }
513 
514   /// Coerce the register to FGR64 and return the real register for the current
515   /// target.
516   unsigned getFGR64Reg() const {
517     assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
518     return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
519         .getRegister(RegIdx.Index);
520   }
521 
522   /// Coerce the register to FGR32 and return the real register for the current
523   /// target.
524   unsigned getFGR32Reg() const {
525     assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
526     return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
527         .getRegister(RegIdx.Index);
528   }
529 
530   /// Coerce the register to FGRH32 and return the real register for the current
531   /// target.
532   unsigned getFGRH32Reg() const {
533     assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
534     return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
535         .getRegister(RegIdx.Index);
536   }
537 
538   /// Coerce the register to FCC and return the real register for the current
539   /// target.
540   unsigned getFCCReg() const {
541     assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
542     return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
543         .getRegister(RegIdx.Index);
544   }
545 
546   /// Coerce the register to MSA128 and return the real register for the current
547   /// target.
548   unsigned getMSA128Reg() const {
549     assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
550     // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
551     // identical
552     unsigned ClassID = Mips::MSA128BRegClassID;
553     return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
554   }
555 
556   /// Coerce the register to MSACtrl and return the real register for the
557   /// current target.
558   unsigned getMSACtrlReg() const {
559     assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
560     unsigned ClassID = Mips::MSACtrlRegClassID;
561     return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
562   }
563 
564   /// Coerce the register to COP2 and return the real register for the
565   /// current target.
566   unsigned getCOP2Reg() const {
567     assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
568     unsigned ClassID = Mips::COP2RegClassID;
569     return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
570   }
571 
572   /// Coerce the register to COP3 and return the real register for the
573   /// current target.
574   unsigned getCOP3Reg() const {
575     assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
576     unsigned ClassID = Mips::COP3RegClassID;
577     return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
578   }
579 
580   /// Coerce the register to ACC64DSP and return the real register for the
581   /// current target.
582   unsigned getACC64DSPReg() const {
583     assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
584     unsigned ClassID = Mips::ACC64DSPRegClassID;
585     return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
586   }
587 
588   /// Coerce the register to HI32DSP and return the real register for the
589   /// current target.
590   unsigned getHI32DSPReg() const {
591     assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
592     unsigned ClassID = Mips::HI32DSPRegClassID;
593     return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
594   }
595 
596   /// Coerce the register to LO32DSP and return the real register for the
597   /// current target.
598   unsigned getLO32DSPReg() const {
599     assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
600     unsigned ClassID = Mips::LO32DSPRegClassID;
601     return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
602   }
603 
604   /// Coerce the register to CCR and return the real register for the
605   /// current target.
606   unsigned getCCRReg() const {
607     assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
608     unsigned ClassID = Mips::CCRRegClassID;
609     return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
610   }
611 
612   /// Coerce the register to HWRegs and return the real register for the
613   /// current target.
614   unsigned getHWRegsReg() const {
615     assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
616     unsigned ClassID = Mips::HWRegsRegClassID;
617     return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
618   }
619 
620 public:
621   void addExpr(MCInst &Inst, const MCExpr *Expr) const {
622     // Add as immediate when possible.  Null MCExpr = 0.
623     if (!Expr)
624       Inst.addOperand(MCOperand::CreateImm(0));
625     else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
626       Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
627     else
628       Inst.addOperand(MCOperand::CreateExpr(Expr));
629   }
630 
631   void addRegOperands(MCInst &Inst, unsigned N) const {
632     llvm_unreachable("Use a custom parser instead");
633   }
634 
635   /// Render the operand to an MCInst as a GPR32
636   /// Asserts if the wrong number of operands are requested, or the operand
637   /// is not a k_RegisterIndex compatible with RegKind_GPR
638   void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
639     assert(N == 1 && "Invalid number of operands!");
640     Inst.addOperand(MCOperand::CreateReg(getGPR32Reg()));
641   }
642 
643   /// Render the operand to an MCInst as a GPR64
644   /// Asserts if the wrong number of operands are requested, or the operand
645   /// is not a k_RegisterIndex compatible with RegKind_GPR
646   void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
647     assert(N == 1 && "Invalid number of operands!");
648     Inst.addOperand(MCOperand::CreateReg(getGPR64Reg()));
649   }
650 
651   void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
652     assert(N == 1 && "Invalid number of operands!");
653     Inst.addOperand(MCOperand::CreateReg(getAFGR64Reg()));
654   }
655 
656   void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
657     assert(N == 1 && "Invalid number of operands!");
658     Inst.addOperand(MCOperand::CreateReg(getFGR64Reg()));
659   }
660 
661   void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
662     assert(N == 1 && "Invalid number of operands!");
663     Inst.addOperand(MCOperand::CreateReg(getFGR32Reg()));
664     // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
665     if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
666       AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
667                                 "registers");
668   }
669 
670   void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
671     assert(N == 1 && "Invalid number of operands!");
672     Inst.addOperand(MCOperand::CreateReg(getFGRH32Reg()));
673   }
674 
675   void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
676     assert(N == 1 && "Invalid number of operands!");
677     Inst.addOperand(MCOperand::CreateReg(getFCCReg()));
678   }
679 
680   void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
681     assert(N == 1 && "Invalid number of operands!");
682     Inst.addOperand(MCOperand::CreateReg(getMSA128Reg()));
683   }
684 
685   void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
686     assert(N == 1 && "Invalid number of operands!");
687     Inst.addOperand(MCOperand::CreateReg(getMSACtrlReg()));
688   }
689 
690   void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
691     assert(N == 1 && "Invalid number of operands!");
692     Inst.addOperand(MCOperand::CreateReg(getCOP2Reg()));
693   }
694 
695   void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
696     assert(N == 1 && "Invalid number of operands!");
697     Inst.addOperand(MCOperand::CreateReg(getCOP3Reg()));
698   }
699 
700   void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
701     assert(N == 1 && "Invalid number of operands!");
702     Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg()));
703   }
704 
705   void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
706     assert(N == 1 && "Invalid number of operands!");
707     Inst.addOperand(MCOperand::CreateReg(getHI32DSPReg()));
708   }
709 
710   void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
711     assert(N == 1 && "Invalid number of operands!");
712     Inst.addOperand(MCOperand::CreateReg(getLO32DSPReg()));
713   }
714 
715   void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
716     assert(N == 1 && "Invalid number of operands!");
717     Inst.addOperand(MCOperand::CreateReg(getCCRReg()));
718   }
719 
720   void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
721     assert(N == 1 && "Invalid number of operands!");
722     Inst.addOperand(MCOperand::CreateReg(getHWRegsReg()));
723   }
724 
725   void addImmOperands(MCInst &Inst, unsigned N) const {
726     assert(N == 1 && "Invalid number of operands!");
727     const MCExpr *Expr = getImm();
728     addExpr(Inst, Expr);
729   }
730 
731   void addMemOperands(MCInst &Inst, unsigned N) const {
732     assert(N == 2 && "Invalid number of operands!");
733 
734     Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPR32Reg()));
735 
736     const MCExpr *Expr = getMemOff();
737     addExpr(Inst, Expr);
738   }
739 
740   bool isReg() const override {
741     // As a special case until we sort out the definition of div/divu, pretend
742     // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
743     if (isGPRAsmReg() && RegIdx.Index == 0)
744       return true;
745 
746     return Kind == k_PhysRegister;
747   }
748   bool isRegIdx() const { return Kind == k_RegisterIndex; }
749   bool isImm() const override { return Kind == k_Immediate; }
750   bool isConstantImm() const {
751     return isImm() && dyn_cast<MCConstantExpr>(getImm());
752   }
753   bool isToken() const override {
754     // Note: It's not possible to pretend that other operand kinds are tokens.
755     // The matcher emitter checks tokens first.
756     return Kind == k_Token;
757   }
758   bool isMem() const override { return Kind == k_Memory; }
759   bool isConstantMemOff() const {
760     return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
761   }
762   template <unsigned Bits> bool isMemWithSimmOffset() const {
763     return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
764   }
765   bool isInvNum() const { return Kind == k_Immediate; }
766   bool isLSAImm() const {
767     if (!isConstantImm())
768       return false;
769     int64_t Val = getConstantImm();
770     return 1 <= Val && Val <= 4;
771   }
772 
773   StringRef getToken() const {
774     assert(Kind == k_Token && "Invalid access!");
775     return StringRef(Tok.Data, Tok.Length);
776   }
777 
778   unsigned getReg() const override {
779     // As a special case until we sort out the definition of div/divu, pretend
780     // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
781     if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
782         RegIdx.Kind & RegKind_GPR)
783       return getGPR32Reg(); // FIXME: GPR64 too
784 
785     assert(Kind == k_PhysRegister && "Invalid access!");
786     return PhysReg.Num;
787   }
788 
789   const MCExpr *getImm() const {
790     assert((Kind == k_Immediate) && "Invalid access!");
791     return Imm.Val;
792   }
793 
794   int64_t getConstantImm() const {
795     const MCExpr *Val = getImm();
796     return static_cast<const MCConstantExpr *>(Val)->getValue();
797   }
798 
799   MipsOperand *getMemBase() const {
800     assert((Kind == k_Memory) && "Invalid access!");
801     return Mem.Base;
802   }
803 
804   const MCExpr *getMemOff() const {
805     assert((Kind == k_Memory) && "Invalid access!");
806     return Mem.Off;
807   }
808 
809   int64_t getConstantMemOff() const {
810     return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
811   }
812 
813   static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
814                                                   MipsAsmParser &Parser) {
815     auto Op = make_unique<MipsOperand>(k_Token, Parser);
816     Op->Tok.Data = Str.data();
817     Op->Tok.Length = Str.size();
818     Op->StartLoc = S;
819     Op->EndLoc = S;
820     return Op;
821   }
822 
823   /// Create a numeric register (e.g. $1). The exact register remains
824   /// unresolved until an instruction successfully matches
825   static std::unique_ptr<MipsOperand>
826   createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
827                    SMLoc E, MipsAsmParser &Parser) {
828     DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
829     return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
830   }
831 
832   /// Create a register that is definitely a GPR.
833   /// This is typically only used for named registers such as $gp.
834   static std::unique_ptr<MipsOperand>
835   createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
836                MipsAsmParser &Parser) {
837     return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
838   }
839 
840   /// Create a register that is definitely a FGR.
841   /// This is typically only used for named registers such as $f0.
842   static std::unique_ptr<MipsOperand>
843   createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
844                MipsAsmParser &Parser) {
845     return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
846   }
847 
848   /// Create a register that is definitely an FCC.
849   /// This is typically only used for named registers such as $fcc0.
850   static std::unique_ptr<MipsOperand>
851   createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
852                MipsAsmParser &Parser) {
853     return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
854   }
855 
856   /// Create a register that is definitely an ACC.
857   /// This is typically only used for named registers such as $ac0.
858   static std::unique_ptr<MipsOperand>
859   createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
860                MipsAsmParser &Parser) {
861     return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
862   }
863 
864   /// Create a register that is definitely an MSA128.
865   /// This is typically only used for named registers such as $w0.
866   static std::unique_ptr<MipsOperand>
867   createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
868                   SMLoc E, MipsAsmParser &Parser) {
869     return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
870   }
871 
872   /// Create a register that is definitely an MSACtrl.
873   /// This is typically only used for named registers such as $msaaccess.
874   static std::unique_ptr<MipsOperand>
875   createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
876                    SMLoc E, MipsAsmParser &Parser) {
877     return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
878   }
879 
880   static std::unique_ptr<MipsOperand>
881   CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
882     auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
883     Op->Imm.Val = Val;
884     Op->StartLoc = S;
885     Op->EndLoc = E;
886     return Op;
887   }
888 
889   static std::unique_ptr<MipsOperand>
890   CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
891             SMLoc E, MipsAsmParser &Parser) {
892     auto Op = make_unique<MipsOperand>(k_Memory, Parser);
893     Op->Mem.Base = Base.release();
894     Op->Mem.Off = Off;
895     Op->StartLoc = S;
896     Op->EndLoc = E;
897     return Op;
898   }
899 
900   bool isGPRAsmReg() const {
901     return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
902   }
903   bool isFGRAsmReg() const {
904     // AFGR64 is $0-$15 but we handle this in getAFGR64()
905     return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
906   }
907   bool isHWRegsAsmReg() const {
908     return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
909   }
910   bool isCCRAsmReg() const {
911     return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
912   }
913   bool isFCCAsmReg() const {
914     if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
915       return false;
916     if (!AsmParser.hasEightFccRegisters())
917       return RegIdx.Index == 0;
918     return RegIdx.Index <= 7;
919   }
920   bool isACCAsmReg() const {
921     return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
922   }
923   bool isCOP2AsmReg() const {
924     return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
925   }
926   bool isCOP3AsmReg() const {
927     return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
928   }
929   bool isMSA128AsmReg() const {
930     return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
931   }
932   bool isMSACtrlAsmReg() const {
933     return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
934   }
935 
936   /// getStartLoc - Get the location of the first token of this operand.
937   SMLoc getStartLoc() const override { return StartLoc; }
938   /// getEndLoc - Get the location of the last token of this operand.
939   SMLoc getEndLoc() const override { return EndLoc; }
940 
941   virtual ~MipsOperand() {
942     switch (Kind) {
943     case k_Immediate:
944       break;
945     case k_Memory:
946       delete Mem.Base;
947       break;
948     case k_PhysRegister:
949     case k_RegisterIndex:
950     case k_Token:
951       break;
952     }
953   }
954 
955   void print(raw_ostream &OS) const override {
956     switch (Kind) {
957     case k_Immediate:
958       OS << "Imm<";
959       Imm.Val->print(OS);
960       OS << ">";
961       break;
962     case k_Memory:
963       OS << "Mem<";
964       Mem.Base->print(OS);
965       OS << ", ";
966       Mem.Off->print(OS);
967       OS << ">";
968       break;
969     case k_PhysRegister:
970       OS << "PhysReg<" << PhysReg.Num << ">";
971       break;
972     case k_RegisterIndex:
973       OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
974       break;
975     case k_Token:
976       OS << Tok.Data;
977       break;
978     }
979   }
980 }; // class MipsOperand
981 } // namespace
982 
983 namespace llvm {
984 extern const MCInstrDesc MipsInsts[];
985 }
986 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
987   return MipsInsts[Opcode];
988 }
989 
990 static bool hasShortDelaySlot(unsigned Opcode) {
991   switch (Opcode) {
992     case Mips::JALS_MM:
993     case Mips::JALRS_MM:
994     case Mips::BGEZALS_MM:
995     case Mips::BLTZALS_MM:
996       return true;
997     default:
998       return false;
999   }
1000 }
1001 
1002 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1003                                        SmallVectorImpl<MCInst> &Instructions) {
1004   const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1005 
1006   Inst.setLoc(IDLoc);
1007 
1008   if (MCID.isBranch() || MCID.isCall()) {
1009     const unsigned Opcode = Inst.getOpcode();
1010     MCOperand Offset;
1011 
1012     switch (Opcode) {
1013     default:
1014       break;
1015     case Mips::BEQ:
1016     case Mips::BNE:
1017     case Mips::BEQ_MM:
1018     case Mips::BNE_MM:
1019       assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1020       Offset = Inst.getOperand(2);
1021       if (!Offset.isImm())
1022         break; // We'll deal with this situation later on when applying fixups.
1023       if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1024         return Error(IDLoc, "branch target out of range");
1025       if (OffsetToAlignment(Offset.getImm(),
1026                             1LL << (inMicroMipsMode() ? 1 : 2)))
1027         return Error(IDLoc, "branch to misaligned address");
1028       break;
1029     case Mips::BGEZ:
1030     case Mips::BGTZ:
1031     case Mips::BLEZ:
1032     case Mips::BLTZ:
1033     case Mips::BGEZAL:
1034     case Mips::BLTZAL:
1035     case Mips::BC1F:
1036     case Mips::BC1T:
1037     case Mips::BGEZ_MM:
1038     case Mips::BGTZ_MM:
1039     case Mips::BLEZ_MM:
1040     case Mips::BLTZ_MM:
1041     case Mips::BGEZAL_MM:
1042     case Mips::BLTZAL_MM:
1043     case Mips::BC1F_MM:
1044     case Mips::BC1T_MM:
1045       assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1046       Offset = Inst.getOperand(1);
1047       if (!Offset.isImm())
1048         break; // We'll deal with this situation later on when applying fixups.
1049       if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1050         return Error(IDLoc, "branch target out of range");
1051       if (OffsetToAlignment(Offset.getImm(),
1052                             1LL << (inMicroMipsMode() ? 1 : 2)))
1053         return Error(IDLoc, "branch to misaligned address");
1054       break;
1055     }
1056   }
1057 
1058   // SSNOP is deprecated on MIPS32r6/MIPS64r6
1059   // We still accept it but it is a normal nop.
1060   if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1061     std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1062     Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1063                                                       "nop instruction");
1064   }
1065 
1066   if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) {
1067     // If this instruction has a delay slot and .set reorder is active,
1068     // emit a NOP after it.
1069     Instructions.push_back(Inst);
1070     MCInst NopInst;
1071     if (hasShortDelaySlot(Inst.getOpcode())) {
1072       NopInst.setOpcode(Mips::MOVE16_MM);
1073       NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1074       NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1075     } else {
1076       NopInst.setOpcode(Mips::SLL);
1077       NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1078       NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1079       NopInst.addOperand(MCOperand::CreateImm(0));
1080     }
1081     Instructions.push_back(NopInst);
1082     return false;
1083   }
1084 
1085   if (MCID.mayLoad() || MCID.mayStore()) {
1086     // Check the offset of memory operand, if it is a symbol
1087     // reference or immediate we may have to expand instructions.
1088     for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1089       const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1090       if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1091           (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1092         MCOperand &Op = Inst.getOperand(i);
1093         if (Op.isImm()) {
1094           int MemOffset = Op.getImm();
1095           if (MemOffset < -32768 || MemOffset > 32767) {
1096             // Offset can't exceed 16bit value.
1097             expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1098             return false;
1099           }
1100         } else if (Op.isExpr()) {
1101           const MCExpr *Expr = Op.getExpr();
1102           if (Expr->getKind() == MCExpr::SymbolRef) {
1103             const MCSymbolRefExpr *SR =
1104                 static_cast<const MCSymbolRefExpr *>(Expr);
1105             if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1106               // Expand symbol.
1107               expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1108               return false;
1109             }
1110           } else if (!isEvaluated(Expr)) {
1111             expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1112             return false;
1113           }
1114         }
1115       }
1116     } // for
1117   }   // if load/store
1118 
1119   if (needsExpansion(Inst))
1120     return expandInstruction(Inst, IDLoc, Instructions);
1121   else
1122     Instructions.push_back(Inst);
1123 
1124   return false;
1125 }
1126 
1127 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1128 
1129   switch (Inst.getOpcode()) {
1130   case Mips::LoadImm32Reg:
1131   case Mips::LoadAddr32Imm:
1132   case Mips::LoadAddr32Reg:
1133   case Mips::LoadImm64Reg:
1134     return true;
1135   default:
1136     return false;
1137   }
1138 }
1139 
1140 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1141                                       SmallVectorImpl<MCInst> &Instructions) {
1142   switch (Inst.getOpcode()) {
1143   default:
1144     assert(0 && "unimplemented expansion");
1145     return true;
1146   case Mips::LoadImm32Reg:
1147     return expandLoadImm(Inst, IDLoc, Instructions);
1148   case Mips::LoadImm64Reg:
1149     if (!isGP64bit()) {
1150       Error(IDLoc, "instruction requires a 64-bit architecture");
1151       return true;
1152     }
1153     return expandLoadImm(Inst, IDLoc, Instructions);
1154   case Mips::LoadAddr32Imm:
1155     return expandLoadAddressImm(Inst, IDLoc, Instructions);
1156   case Mips::LoadAddr32Reg:
1157     return expandLoadAddressReg(Inst, IDLoc, Instructions);
1158   }
1159 }
1160 
1161 namespace {
1162 template <bool PerformShift>
1163 void createShiftOr(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1164                    SmallVectorImpl<MCInst> &Instructions) {
1165   MCInst tmpInst;
1166   if (PerformShift) {
1167     tmpInst.setOpcode(Mips::DSLL);
1168     tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1169     tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1170     tmpInst.addOperand(MCOperand::CreateImm(16));
1171     tmpInst.setLoc(IDLoc);
1172     Instructions.push_back(tmpInst);
1173     tmpInst.clear();
1174   }
1175   tmpInst.setOpcode(Mips::ORi);
1176   tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1177   tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1178   tmpInst.addOperand(Operand);
1179   tmpInst.setLoc(IDLoc);
1180   Instructions.push_back(tmpInst);
1181 }
1182 
1183 template <int Shift, bool PerformShift>
1184 void createShiftOr(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1185                    SmallVectorImpl<MCInst> &Instructions) {
1186   createShiftOr<PerformShift>(
1187       MCOperand::CreateImm(((Value & (0xffffLL << Shift)) >> Shift)), RegNo,
1188       IDLoc, Instructions);
1189 }
1190 }
1191 
1192 bool MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
1193                                   SmallVectorImpl<MCInst> &Instructions) {
1194   MCInst tmpInst;
1195   const MCOperand &ImmOp = Inst.getOperand(1);
1196   assert(ImmOp.isImm() && "expected immediate operand kind");
1197   const MCOperand &RegOp = Inst.getOperand(0);
1198   assert(RegOp.isReg() && "expected register operand kind");
1199 
1200   int64_t ImmValue = ImmOp.getImm();
1201   tmpInst.setLoc(IDLoc);
1202   // FIXME: gas has a special case for values that are 000...1111, which
1203   // becomes a li -1 and then a dsrl
1204   if (0 <= ImmValue && ImmValue <= 65535) {
1205     // For 0 <= j <= 65535.
1206     // li d,j => ori d,$zero,j
1207     tmpInst.setOpcode(Mips::ORi);
1208     tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1209     tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1210     tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1211     Instructions.push_back(tmpInst);
1212   } else if (ImmValue < 0 && ImmValue >= -32768) {
1213     // For -32768 <= j < 0.
1214     // li d,j => addiu d,$zero,j
1215     tmpInst.setOpcode(Mips::ADDiu);
1216     tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1217     tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1218     tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1219     Instructions.push_back(tmpInst);
1220   } else if ((ImmValue & 0xffffffff) == ImmValue) {
1221     // For any value of j that is representable as a 32-bit integer, create
1222     // a sequence of:
1223     // li d,j => lui d,hi16(j)
1224     //           ori d,d,lo16(j)
1225     tmpInst.setOpcode(Mips::LUi);
1226     tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1227     tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1228     Instructions.push_back(tmpInst);
1229     createShiftOr<0, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1230   } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1231     if (!isGP64bit()) {
1232       Error(IDLoc, "instruction requires a 64-bit architecture");
1233       return true;
1234     }
1235 
1236     //            <-------  lo32 ------>
1237     // <-------  hi32 ------>
1238     // <- hi16 ->             <- lo16 ->
1239     //  _________________________________
1240     // |          |          |          |
1241     // | 16-bytes | 16-bytes | 16-bytes |
1242     // |__________|__________|__________|
1243     //
1244     // For any value of j that is representable as a 48-bit integer, create
1245     // a sequence of:
1246     // li d,j => lui d,hi16(j)
1247     //           ori d,d,hi16(lo32(j))
1248     //           dsll d,d,16
1249     //           ori d,d,lo16(lo32(j))
1250     tmpInst.setOpcode(Mips::LUi);
1251     tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1252     tmpInst.addOperand(
1253         MCOperand::CreateImm((ImmValue & (0xffffLL << 32)) >> 32));
1254     Instructions.push_back(tmpInst);
1255     createShiftOr<16, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1256     createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1257   } else {
1258     if (!isGP64bit()) {
1259       Error(IDLoc, "instruction requires a 64-bit architecture");
1260       return true;
1261     }
1262 
1263     // <-------  hi32 ------> <-------  lo32 ------>
1264     // <- hi16 ->                        <- lo16 ->
1265     //  ___________________________________________
1266     // |          |          |          |          |
1267     // | 16-bytes | 16-bytes | 16-bytes | 16-bytes |
1268     // |__________|__________|__________|__________|
1269     //
1270     // For any value of j that isn't representable as a 48-bit integer.
1271     // li d,j => lui d,hi16(j)
1272     //           ori d,d,lo16(hi32(j))
1273     //           dsll d,d,16
1274     //           ori d,d,hi16(lo32(j))
1275     //           dsll d,d,16
1276     //           ori d,d,lo16(lo32(j))
1277     tmpInst.setOpcode(Mips::LUi);
1278     tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1279     tmpInst.addOperand(
1280         MCOperand::CreateImm((ImmValue & (0xffffLL << 48)) >> 48));
1281     Instructions.push_back(tmpInst);
1282     createShiftOr<32, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1283     createShiftOr<16, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1284     createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1285   }
1286   return false;
1287 }
1288 
1289 bool
1290 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
1291                                     SmallVectorImpl<MCInst> &Instructions) {
1292   MCInst tmpInst;
1293   const MCOperand &ImmOp = Inst.getOperand(2);
1294   assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1295          "expected immediate operand kind");
1296   if (!ImmOp.isImm()) {
1297     expandLoadAddressSym(Inst, IDLoc, Instructions);
1298     return false;
1299   }
1300   const MCOperand &SrcRegOp = Inst.getOperand(1);
1301   assert(SrcRegOp.isReg() && "expected register operand kind");
1302   const MCOperand &DstRegOp = Inst.getOperand(0);
1303   assert(DstRegOp.isReg() && "expected register operand kind");
1304   int ImmValue = ImmOp.getImm();
1305   if (-32768 <= ImmValue && ImmValue <= 65535) {
1306     // For -32768 <= j <= 65535.
1307     // la d,j(s) => addiu d,s,j
1308     tmpInst.setOpcode(Mips::ADDiu);
1309     tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1310     tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1311     tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1312     Instructions.push_back(tmpInst);
1313   } else {
1314     // For any other value of j that is representable as a 32-bit integer.
1315     // la d,j(s) => lui d,hi16(j)
1316     //              ori d,d,lo16(j)
1317     //              addu d,d,s
1318     tmpInst.setOpcode(Mips::LUi);
1319     tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1320     tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1321     Instructions.push_back(tmpInst);
1322     tmpInst.clear();
1323     tmpInst.setOpcode(Mips::ORi);
1324     tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1325     tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1326     tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1327     Instructions.push_back(tmpInst);
1328     tmpInst.clear();
1329     tmpInst.setOpcode(Mips::ADDu);
1330     tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1331     tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1332     tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1333     Instructions.push_back(tmpInst);
1334   }
1335   return false;
1336 }
1337 
1338 bool
1339 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1340                                     SmallVectorImpl<MCInst> &Instructions) {
1341   MCInst tmpInst;
1342   const MCOperand &ImmOp = Inst.getOperand(1);
1343   assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1344          "expected immediate operand kind");
1345   if (!ImmOp.isImm()) {
1346     expandLoadAddressSym(Inst, IDLoc, Instructions);
1347     return false;
1348   }
1349   const MCOperand &RegOp = Inst.getOperand(0);
1350   assert(RegOp.isReg() && "expected register operand kind");
1351   int ImmValue = ImmOp.getImm();
1352   if (-32768 <= ImmValue && ImmValue <= 65535) {
1353     // For -32768 <= j <= 65535.
1354     // la d,j => addiu d,$zero,j
1355     tmpInst.setOpcode(Mips::ADDiu);
1356     tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1357     tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1358     tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1359     Instructions.push_back(tmpInst);
1360   } else {
1361     // For any other value of j that is representable as a 32-bit integer.
1362     // la d,j => lui d,hi16(j)
1363     //           ori d,d,lo16(j)
1364     tmpInst.setOpcode(Mips::LUi);
1365     tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1366     tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1367     Instructions.push_back(tmpInst);
1368     tmpInst.clear();
1369     tmpInst.setOpcode(Mips::ORi);
1370     tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1371     tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1372     tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1373     Instructions.push_back(tmpInst);
1374   }
1375   return false;
1376 }
1377 
1378 void
1379 MipsAsmParser::expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
1380                                     SmallVectorImpl<MCInst> &Instructions) {
1381   // FIXME: If we do have a valid at register to use, we should generate a
1382   // slightly shorter sequence here.
1383   MCInst tmpInst;
1384   int ExprOperandNo = 1;
1385   // Sometimes the assembly parser will get the immediate expression as
1386   // a $zero + an immediate.
1387   if (Inst.getNumOperands() == 3) {
1388     assert(Inst.getOperand(1).getReg() ==
1389            (isGP64bit() ? Mips::ZERO_64 : Mips::ZERO));
1390     ExprOperandNo = 2;
1391   }
1392   const MCOperand &SymOp = Inst.getOperand(ExprOperandNo);
1393   assert(SymOp.isExpr() && "expected symbol operand kind");
1394   const MCOperand &RegOp = Inst.getOperand(0);
1395   unsigned RegNo = RegOp.getReg();
1396   const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymOp.getExpr());
1397   const MCSymbolRefExpr *HiExpr =
1398       MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1399                               MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
1400   const MCSymbolRefExpr *LoExpr =
1401       MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1402                               MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
1403   if (isGP64bit()) {
1404     // If it's a 64-bit architecture, expand to:
1405     // la d,sym => lui  d,highest(sym)
1406     //             ori  d,d,higher(sym)
1407     //             dsll d,d,16
1408     //             ori  d,d,hi16(sym)
1409     //             dsll d,d,16
1410     //             ori  d,d,lo16(sym)
1411     const MCSymbolRefExpr *HighestExpr =
1412         MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1413                                 MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
1414     const MCSymbolRefExpr *HigherExpr =
1415         MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1416                                 MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
1417 
1418     tmpInst.setOpcode(Mips::LUi);
1419     tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1420     tmpInst.addOperand(MCOperand::CreateExpr(HighestExpr));
1421     Instructions.push_back(tmpInst);
1422 
1423     createShiftOr<false>(MCOperand::CreateExpr(HigherExpr), RegNo, SMLoc(),
1424                          Instructions);
1425     createShiftOr<true>(MCOperand::CreateExpr(HiExpr), RegNo, SMLoc(),
1426                         Instructions);
1427     createShiftOr<true>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1428                         Instructions);
1429   } else {
1430     // Otherwise, expand to:
1431     // la d,sym => lui  d,hi16(sym)
1432     //             ori  d,d,lo16(sym)
1433     tmpInst.setOpcode(Mips::LUi);
1434     tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1435     tmpInst.addOperand(MCOperand::CreateExpr(HiExpr));
1436     Instructions.push_back(tmpInst);
1437 
1438     createShiftOr<false>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1439                          Instructions);
1440   }
1441 }
1442 
1443 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
1444                                   SmallVectorImpl<MCInst> &Instructions,
1445                                   bool isLoad, bool isImmOpnd) {
1446   const MCSymbolRefExpr *SR;
1447   MCInst TempInst;
1448   unsigned ImmOffset, HiOffset, LoOffset;
1449   const MCExpr *ExprOffset;
1450   unsigned TmpRegNum;
1451   // 1st operand is either the source or destination register.
1452   assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1453   unsigned RegOpNum = Inst.getOperand(0).getReg();
1454   // 2nd operand is the base register.
1455   assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1456   unsigned BaseRegNum = Inst.getOperand(1).getReg();
1457   // 3rd operand is either an immediate or expression.
1458   if (isImmOpnd) {
1459     assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
1460     ImmOffset = Inst.getOperand(2).getImm();
1461     LoOffset = ImmOffset & 0x0000ffff;
1462     HiOffset = (ImmOffset & 0xffff0000) >> 16;
1463     // If msb of LoOffset is 1(negative number) we must increment HiOffset.
1464     if (LoOffset & 0x8000)
1465       HiOffset++;
1466   } else
1467     ExprOffset = Inst.getOperand(2).getExpr();
1468   // All instructions will have the same location.
1469   TempInst.setLoc(IDLoc);
1470   // These are some of the types of expansions we perform here:
1471   // 1) lw $8, sym        => lui $8, %hi(sym)
1472   //                         lw $8, %lo(sym)($8)
1473   // 2) lw $8, offset($9) => lui $8, %hi(offset)
1474   //                         add $8, $8, $9
1475   //                         lw $8, %lo(offset)($9)
1476   // 3) lw $8, offset($8) => lui $at, %hi(offset)
1477   //                         add $at, $at, $8
1478   //                         lw $8, %lo(offset)($at)
1479   // 4) sw $8, sym        => lui $at, %hi(sym)
1480   //                         sw $8, %lo(sym)($at)
1481   // 5) sw $8, offset($8) => lui $at, %hi(offset)
1482   //                         add $at, $at, $8
1483   //                         sw $8, %lo(offset)($at)
1484   // 6) ldc1 $f0, sym     => lui $at, %hi(sym)
1485   //                         ldc1 $f0, %lo(sym)($at)
1486   //
1487   // For load instructions we can use the destination register as a temporary
1488   // if base and dst are different (examples 1 and 2) and if the base register
1489   // is general purpose otherwise we must use $at (example 6) and error if it's
1490   // not available. For stores we must use $at (examples 4 and 5) because we
1491   // must not clobber the source register setting up the offset.
1492   const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
1493   int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
1494   unsigned RegClassIDOp0 =
1495       getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
1496   bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
1497                (RegClassIDOp0 == Mips::GPR64RegClassID);
1498   if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
1499     TmpRegNum = RegOpNum;
1500   else {
1501     int AT = getATReg(IDLoc);
1502     // At this point we need AT to perform the expansions and we exit if it is
1503     // not available.
1504     if (!AT)
1505       return;
1506     TmpRegNum = getReg(
1507         (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, AT);
1508   }
1509 
1510   TempInst.setOpcode(Mips::LUi);
1511   TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1512   if (isImmOpnd)
1513     TempInst.addOperand(MCOperand::CreateImm(HiOffset));
1514   else {
1515     if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1516       SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
1517       const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
1518           SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
1519           getContext());
1520       TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1521     } else {
1522       const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
1523       TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1524     }
1525   }
1526   // Add the instruction to the list.
1527   Instructions.push_back(TempInst);
1528   // Prepare TempInst for next instruction.
1529   TempInst.clear();
1530   // Add temp register to base.
1531   TempInst.setOpcode(Mips::ADDu);
1532   TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1533   TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1534   TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
1535   Instructions.push_back(TempInst);
1536   TempInst.clear();
1537   // And finally, create original instruction with low part
1538   // of offset and new base.
1539   TempInst.setOpcode(Inst.getOpcode());
1540   TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
1541   TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1542   if (isImmOpnd)
1543     TempInst.addOperand(MCOperand::CreateImm(LoOffset));
1544   else {
1545     if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1546       const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
1547           SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
1548           getContext());
1549       TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1550     } else {
1551       const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
1552       TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1553     }
1554   }
1555   Instructions.push_back(TempInst);
1556   TempInst.clear();
1557 }
1558 
1559 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
1560   // As described by the Mips32r2 spec, the registers Rd and Rs for
1561   // jalr.hb must be different.
1562   unsigned Opcode = Inst.getOpcode();
1563 
1564   if (Opcode == Mips::JALR_HB &&
1565       (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
1566     return Match_RequiresDifferentSrcAndDst;
1567 
1568   return Match_Success;
1569 }
1570 
1571 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1572                                             OperandVector &Operands,
1573                                             MCStreamer &Out,
1574                                             uint64_t &ErrorInfo,
1575                                             bool MatchingInlineAsm) {
1576 
1577   MCInst Inst;
1578   SmallVector<MCInst, 8> Instructions;
1579   unsigned MatchResult =
1580       MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
1581 
1582   switch (MatchResult) {
1583   default:
1584     break;
1585   case Match_Success: {
1586     if (processInstruction(Inst, IDLoc, Instructions))
1587       return true;
1588     for (unsigned i = 0; i < Instructions.size(); i++)
1589       Out.EmitInstruction(Instructions[i], STI);
1590     return false;
1591   }
1592   case Match_MissingFeature:
1593     Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1594     return true;
1595   case Match_InvalidOperand: {
1596     SMLoc ErrorLoc = IDLoc;
1597     if (ErrorInfo != ~0ULL) {
1598       if (ErrorInfo >= Operands.size())
1599         return Error(IDLoc, "too few operands for instruction");
1600 
1601       ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
1602       if (ErrorLoc == SMLoc())
1603         ErrorLoc = IDLoc;
1604     }
1605 
1606     return Error(ErrorLoc, "invalid operand for instruction");
1607   }
1608   case Match_MnemonicFail:
1609     return Error(IDLoc, "invalid instruction");
1610   case Match_RequiresDifferentSrcAndDst:
1611     return Error(IDLoc, "source and destination must be different");
1612   }
1613   return true;
1614 }
1615 
1616 void MipsAsmParser::warnIfAssemblerTemporary(int RegIndex, SMLoc Loc) {
1617   if ((RegIndex != 0) &&
1618       ((int)AssemblerOptions.back()->getATRegNum() == RegIndex)) {
1619     if (RegIndex == 1)
1620       Warning(Loc, "used $at without \".set noat\"");
1621     else
1622       Warning(Loc, Twine("used $") + Twine(RegIndex) + " with \".set at=$" +
1623                        Twine(RegIndex) + "\"");
1624   }
1625 }
1626 
1627 void
1628 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
1629                                      SMRange Range, bool ShowColors) {
1630   getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
1631                                   Range, SMFixIt(Range, FixMsg),
1632                                   ShowColors);
1633 }
1634 
1635 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
1636   int CC;
1637 
1638   CC = StringSwitch<unsigned>(Name)
1639            .Case("zero", 0)
1640            .Case("at", 1)
1641            .Case("a0", 4)
1642            .Case("a1", 5)
1643            .Case("a2", 6)
1644            .Case("a3", 7)
1645            .Case("v0", 2)
1646            .Case("v1", 3)
1647            .Case("s0", 16)
1648            .Case("s1", 17)
1649            .Case("s2", 18)
1650            .Case("s3", 19)
1651            .Case("s4", 20)
1652            .Case("s5", 21)
1653            .Case("s6", 22)
1654            .Case("s7", 23)
1655            .Case("k0", 26)
1656            .Case("k1", 27)
1657            .Case("gp", 28)
1658            .Case("sp", 29)
1659            .Case("fp", 30)
1660            .Case("s8", 30)
1661            .Case("ra", 31)
1662            .Case("t0", 8)
1663            .Case("t1", 9)
1664            .Case("t2", 10)
1665            .Case("t3", 11)
1666            .Case("t4", 12)
1667            .Case("t5", 13)
1668            .Case("t6", 14)
1669            .Case("t7", 15)
1670            .Case("t8", 24)
1671            .Case("t9", 25)
1672            .Default(-1);
1673 
1674   if (!(isABI_N32() || isABI_N64()))
1675     return CC;
1676 
1677   if (12 <= CC && CC <= 15) {
1678     // Name is one of t4-t7
1679     AsmToken RegTok = getLexer().peekTok();
1680     SMRange RegRange = RegTok.getLocRange();
1681 
1682     StringRef FixedName = StringSwitch<StringRef>(Name)
1683                               .Case("t4", "t0")
1684                               .Case("t5", "t1")
1685                               .Case("t6", "t2")
1686                               .Case("t7", "t3")
1687                               .Default("");
1688     assert(FixedName != "" &&  "Register name is not one of t4-t7.");
1689 
1690     printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
1691                           "Did you mean $" + FixedName + "?", RegRange);
1692   }
1693 
1694   // Although SGI documentation just cuts out t0-t3 for n32/n64,
1695   // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
1696   // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
1697   if (8 <= CC && CC <= 11)
1698     CC += 4;
1699 
1700   if (CC == -1)
1701     CC = StringSwitch<unsigned>(Name)
1702              .Case("a4", 8)
1703              .Case("a5", 9)
1704              .Case("a6", 10)
1705              .Case("a7", 11)
1706              .Case("kt0", 26)
1707              .Case("kt1", 27)
1708              .Default(-1);
1709 
1710   return CC;
1711 }
1712 
1713 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
1714 
1715   if (Name[0] == 'f') {
1716     StringRef NumString = Name.substr(1);
1717     unsigned IntVal;
1718     if (NumString.getAsInteger(10, IntVal))
1719       return -1;     // This is not an integer.
1720     if (IntVal > 31) // Maximum index for fpu register.
1721       return -1;
1722     return IntVal;
1723   }
1724   return -1;
1725 }
1726 
1727 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
1728 
1729   if (Name.startswith("fcc")) {
1730     StringRef NumString = Name.substr(3);
1731     unsigned IntVal;
1732     if (NumString.getAsInteger(10, IntVal))
1733       return -1;    // This is not an integer.
1734     if (IntVal > 7) // There are only 8 fcc registers.
1735       return -1;
1736     return IntVal;
1737   }
1738   return -1;
1739 }
1740 
1741 int MipsAsmParser::matchACRegisterName(StringRef Name) {
1742 
1743   if (Name.startswith("ac")) {
1744     StringRef NumString = Name.substr(2);
1745     unsigned IntVal;
1746     if (NumString.getAsInteger(10, IntVal))
1747       return -1;    // This is not an integer.
1748     if (IntVal > 3) // There are only 3 acc registers.
1749       return -1;
1750     return IntVal;
1751   }
1752   return -1;
1753 }
1754 
1755 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
1756   unsigned IntVal;
1757 
1758   if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
1759     return -1;
1760 
1761   if (IntVal > 31)
1762     return -1;
1763 
1764   return IntVal;
1765 }
1766 
1767 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
1768   int CC;
1769 
1770   CC = StringSwitch<unsigned>(Name)
1771            .Case("msair", 0)
1772            .Case("msacsr", 1)
1773            .Case("msaaccess", 2)
1774            .Case("msasave", 3)
1775            .Case("msamodify", 4)
1776            .Case("msarequest", 5)
1777            .Case("msamap", 6)
1778            .Case("msaunmap", 7)
1779            .Default(-1);
1780 
1781   return CC;
1782 }
1783 
1784 bool MipsAssemblerOptions::setATReg(unsigned Reg) {
1785   if (Reg > 31)
1786     return false;
1787 
1788   ATReg = Reg;
1789   return true;
1790 }
1791 
1792 int MipsAsmParser::getATReg(SMLoc Loc) {
1793   int AT = AssemblerOptions.back()->getATRegNum();
1794   if (AT == 0)
1795     reportParseError(Loc,
1796                      "pseudo-instruction requires $at, which is not available");
1797   return AT;
1798 }
1799 
1800 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
1801   return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
1802 }
1803 
1804 unsigned MipsAsmParser::getGPR(int RegNo) {
1805   return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
1806                 RegNo);
1807 }
1808 
1809 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
1810   if (RegNum >
1811       getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
1812     return -1;
1813 
1814   return getReg(RegClass, RegNum);
1815 }
1816 
1817 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
1818   DEBUG(dbgs() << "parseOperand\n");
1819 
1820   // Check if the current operand has a custom associated parser, if so, try to
1821   // custom parse the operand, or fallback to the general approach.
1822   OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1823   if (ResTy == MatchOperand_Success)
1824     return false;
1825   // If there wasn't a custom match, try the generic matcher below. Otherwise,
1826   // there was a match, but an error occurred, in which case, just return that
1827   // the operand parsing failed.
1828   if (ResTy == MatchOperand_ParseFail)
1829     return true;
1830 
1831   DEBUG(dbgs() << ".. Generic Parser\n");
1832 
1833   switch (getLexer().getKind()) {
1834   default:
1835     Error(Parser.getTok().getLoc(), "unexpected token in operand");
1836     return true;
1837   case AsmToken::Dollar: {
1838     // Parse the register.
1839     SMLoc S = Parser.getTok().getLoc();
1840 
1841     // Almost all registers have been parsed by custom parsers. There is only
1842     // one exception to this. $zero (and it's alias $0) will reach this point
1843     // for div, divu, and similar instructions because it is not an operand
1844     // to the instruction definition but an explicit register. Special case
1845     // this situation for now.
1846     if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
1847       return false;
1848 
1849     // Maybe it is a symbol reference.
1850     StringRef Identifier;
1851     if (Parser.parseIdentifier(Identifier))
1852       return true;
1853 
1854     SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1855     MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
1856     // Otherwise create a symbol reference.
1857     const MCExpr *Res =
1858         MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
1859 
1860     Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
1861     return false;
1862   }
1863   // Else drop to expression parsing.
1864   case AsmToken::LParen:
1865   case AsmToken::Minus:
1866   case AsmToken::Plus:
1867   case AsmToken::Integer:
1868   case AsmToken::Tilde:
1869   case AsmToken::String: {
1870     DEBUG(dbgs() << ".. generic integer\n");
1871     OperandMatchResultTy ResTy = parseImm(Operands);
1872     return ResTy != MatchOperand_Success;
1873   }
1874   case AsmToken::Percent: {
1875     // It is a symbol reference or constant expression.
1876     const MCExpr *IdVal;
1877     SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
1878     if (parseRelocOperand(IdVal))
1879       return true;
1880 
1881     SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1882 
1883     Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
1884     return false;
1885   } // case AsmToken::Percent
1886   } // switch(getLexer().getKind())
1887   return true;
1888 }
1889 
1890 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
1891                                                StringRef RelocStr) {
1892   const MCExpr *Res;
1893   // Check the type of the expression.
1894   if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
1895     // It's a constant, evaluate reloc value.
1896     int16_t Val;
1897     switch (getVariantKind(RelocStr)) {
1898     case MCSymbolRefExpr::VK_Mips_ABS_LO:
1899       // Get the 1st 16-bits.
1900       Val = MCE->getValue() & 0xffff;
1901       break;
1902     case MCSymbolRefExpr::VK_Mips_ABS_HI:
1903       // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
1904       // 16 bits being negative.
1905       Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
1906       break;
1907     case MCSymbolRefExpr::VK_Mips_HIGHER:
1908       // Get the 3rd 16-bits.
1909       Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
1910       break;
1911     case MCSymbolRefExpr::VK_Mips_HIGHEST:
1912       // Get the 4th 16-bits.
1913       Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
1914       break;
1915     default:
1916       report_fatal_error("unsupported reloc value");
1917     }
1918     return MCConstantExpr::Create(Val, getContext());
1919   }
1920 
1921   if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
1922     // It's a symbol, create a symbolic expression from the symbol.
1923     StringRef Symbol = MSRE->getSymbol().getName();
1924     MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1925     Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
1926     return Res;
1927   }
1928 
1929   if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1930     MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1931 
1932     // Try to create target expression.
1933     if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
1934       return MipsMCExpr::Create(VK, Expr, getContext());
1935 
1936     const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
1937     const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
1938     Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
1939     return Res;
1940   }
1941 
1942   if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
1943     const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
1944     Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
1945     return Res;
1946   }
1947   // Just return the original expression.
1948   return Expr;
1949 }
1950 
1951 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
1952 
1953   switch (Expr->getKind()) {
1954   case MCExpr::Constant:
1955     return true;
1956   case MCExpr::SymbolRef:
1957     return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1958   case MCExpr::Binary:
1959     if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1960       if (!isEvaluated(BE->getLHS()))
1961         return false;
1962       return isEvaluated(BE->getRHS());
1963     }
1964   case MCExpr::Unary:
1965     return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
1966   case MCExpr::Target:
1967     return true;
1968   }
1969   return false;
1970 }
1971 
1972 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
1973   Parser.Lex();                          // Eat the % token.
1974   const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
1975   if (Tok.isNot(AsmToken::Identifier))
1976     return true;
1977 
1978   std::string Str = Tok.getIdentifier().str();
1979 
1980   Parser.Lex(); // Eat the identifier.
1981   // Now make an expression from the rest of the operand.
1982   const MCExpr *IdVal;
1983   SMLoc EndLoc;
1984 
1985   if (getLexer().getKind() == AsmToken::LParen) {
1986     while (1) {
1987       Parser.Lex(); // Eat the '(' token.
1988       if (getLexer().getKind() == AsmToken::Percent) {
1989         Parser.Lex(); // Eat the % token.
1990         const AsmToken &nextTok = Parser.getTok();
1991         if (nextTok.isNot(AsmToken::Identifier))
1992           return true;
1993         Str += "(%";
1994         Str += nextTok.getIdentifier();
1995         Parser.Lex(); // Eat the identifier.
1996         if (getLexer().getKind() != AsmToken::LParen)
1997           return true;
1998       } else
1999         break;
2000     }
2001     if (getParser().parseParenExpression(IdVal, EndLoc))
2002       return true;
2003 
2004     while (getLexer().getKind() == AsmToken::RParen)
2005       Parser.Lex(); // Eat the ')' token.
2006 
2007   } else
2008     return true; // Parenthesis must follow the relocation operand.
2009 
2010   Res = evaluateRelocExpr(IdVal, Str);
2011   return false;
2012 }
2013 
2014 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
2015                                   SMLoc &EndLoc) {
2016   SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
2017   OperandMatchResultTy ResTy = parseAnyRegister(Operands);
2018   if (ResTy == MatchOperand_Success) {
2019     assert(Operands.size() == 1);
2020     MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
2021     StartLoc = Operand.getStartLoc();
2022     EndLoc = Operand.getEndLoc();
2023 
2024     // AFAIK, we only support numeric registers and named GPR's in CFI
2025     // directives.
2026     // Don't worry about eating tokens before failing. Using an unrecognised
2027     // register is a parse error.
2028     if (Operand.isGPRAsmReg()) {
2029       // Resolve to GPR32 or GPR64 appropriately.
2030       RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
2031     }
2032 
2033     return (RegNo == (unsigned)-1);
2034   }
2035 
2036   assert(Operands.size() == 0);
2037   return (RegNo == (unsigned)-1);
2038 }
2039 
2040 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
2041   SMLoc S;
2042   bool Result = true;
2043 
2044   while (getLexer().getKind() == AsmToken::LParen)
2045     Parser.Lex();
2046 
2047   switch (getLexer().getKind()) {
2048   default:
2049     return true;
2050   case AsmToken::Identifier:
2051   case AsmToken::LParen:
2052   case AsmToken::Integer:
2053   case AsmToken::Minus:
2054   case AsmToken::Plus:
2055     if (isParenExpr)
2056       Result = getParser().parseParenExpression(Res, S);
2057     else
2058       Result = (getParser().parseExpression(Res));
2059     while (getLexer().getKind() == AsmToken::RParen)
2060       Parser.Lex();
2061     break;
2062   case AsmToken::Percent:
2063     Result = parseRelocOperand(Res);
2064   }
2065   return Result;
2066 }
2067 
2068 MipsAsmParser::OperandMatchResultTy
2069 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
2070   DEBUG(dbgs() << "parseMemOperand\n");
2071   const MCExpr *IdVal = nullptr;
2072   SMLoc S;
2073   bool isParenExpr = false;
2074   MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
2075   // First operand is the offset.
2076   S = Parser.getTok().getLoc();
2077 
2078   if (getLexer().getKind() == AsmToken::LParen) {
2079     Parser.Lex();
2080     isParenExpr = true;
2081   }
2082 
2083   if (getLexer().getKind() != AsmToken::Dollar) {
2084     if (parseMemOffset(IdVal, isParenExpr))
2085       return MatchOperand_ParseFail;
2086 
2087     const AsmToken &Tok = Parser.getTok(); // Get the next token.
2088     if (Tok.isNot(AsmToken::LParen)) {
2089       MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
2090       if (Mnemonic.getToken() == "la") {
2091         SMLoc E =
2092             SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2093         Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2094         return MatchOperand_Success;
2095       }
2096       if (Tok.is(AsmToken::EndOfStatement)) {
2097         SMLoc E =
2098             SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2099 
2100         // Zero register assumed, add a memory operand with ZERO as its base.
2101         // "Base" will be managed by k_Memory.
2102         auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
2103                                               S, E, *this);
2104         Operands.push_back(
2105             MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
2106         return MatchOperand_Success;
2107       }
2108       Error(Parser.getTok().getLoc(), "'(' expected");
2109       return MatchOperand_ParseFail;
2110     }
2111 
2112     Parser.Lex(); // Eat the '(' token.
2113   }
2114 
2115   Res = parseAnyRegister(Operands);
2116   if (Res != MatchOperand_Success)
2117     return Res;
2118 
2119   if (Parser.getTok().isNot(AsmToken::RParen)) {
2120     Error(Parser.getTok().getLoc(), "')' expected");
2121     return MatchOperand_ParseFail;
2122   }
2123 
2124   SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2125 
2126   Parser.Lex(); // Eat the ')' token.
2127 
2128   if (!IdVal)
2129     IdVal = MCConstantExpr::Create(0, getContext());
2130 
2131   // Replace the register operand with the memory operand.
2132   std::unique_ptr<MipsOperand> op(
2133       static_cast<MipsOperand *>(Operands.back().release()));
2134   // Remove the register from the operands.
2135   // "op" will be managed by k_Memory.
2136   Operands.pop_back();
2137   // Add the memory operand.
2138   if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
2139     int64_t Imm;
2140     if (IdVal->EvaluateAsAbsolute(Imm))
2141       IdVal = MCConstantExpr::Create(Imm, getContext());
2142     else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
2143       IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
2144                                    getContext());
2145   }
2146 
2147   Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
2148   return MatchOperand_Success;
2149 }
2150 
2151 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
2152 
2153   MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
2154   if (Sym) {
2155     SMLoc S = Parser.getTok().getLoc();
2156     const MCExpr *Expr;
2157     if (Sym->isVariable())
2158       Expr = Sym->getVariableValue();
2159     else
2160       return false;
2161     if (Expr->getKind() == MCExpr::SymbolRef) {
2162       const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
2163       StringRef DefSymbol = Ref->getSymbol().getName();
2164       if (DefSymbol.startswith("$")) {
2165         OperandMatchResultTy ResTy =
2166             matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
2167         if (ResTy == MatchOperand_Success) {
2168           Parser.Lex();
2169           return true;
2170         } else if (ResTy == MatchOperand_ParseFail)
2171           llvm_unreachable("Should never ParseFail");
2172         return false;
2173       }
2174     } else if (Expr->getKind() == MCExpr::Constant) {
2175       Parser.Lex();
2176       const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2177       Operands.push_back(
2178           MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
2179       return true;
2180     }
2181   }
2182   return false;
2183 }
2184 
2185 MipsAsmParser::OperandMatchResultTy
2186 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
2187                                                  StringRef Identifier,
2188                                                  SMLoc S) {
2189   int Index = matchCPURegisterName(Identifier);
2190   if (Index != -1) {
2191     Operands.push_back(MipsOperand::createGPRReg(
2192         Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2193     return MatchOperand_Success;
2194   }
2195 
2196   Index = matchFPURegisterName(Identifier);
2197   if (Index != -1) {
2198     Operands.push_back(MipsOperand::createFGRReg(
2199         Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2200     return MatchOperand_Success;
2201   }
2202 
2203   Index = matchFCCRegisterName(Identifier);
2204   if (Index != -1) {
2205     Operands.push_back(MipsOperand::createFCCReg(
2206         Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2207     return MatchOperand_Success;
2208   }
2209 
2210   Index = matchACRegisterName(Identifier);
2211   if (Index != -1) {
2212     Operands.push_back(MipsOperand::createACCReg(
2213         Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2214     return MatchOperand_Success;
2215   }
2216 
2217   Index = matchMSA128RegisterName(Identifier);
2218   if (Index != -1) {
2219     Operands.push_back(MipsOperand::createMSA128Reg(
2220         Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2221     return MatchOperand_Success;
2222   }
2223 
2224   Index = matchMSA128CtrlRegisterName(Identifier);
2225   if (Index != -1) {
2226     Operands.push_back(MipsOperand::createMSACtrlReg(
2227         Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2228     return MatchOperand_Success;
2229   }
2230 
2231   return MatchOperand_NoMatch;
2232 }
2233 
2234 MipsAsmParser::OperandMatchResultTy
2235 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2236   auto Token = Parser.getLexer().peekTok(false);
2237 
2238   if (Token.is(AsmToken::Identifier)) {
2239     DEBUG(dbgs() << ".. identifier\n");
2240     StringRef Identifier = Token.getIdentifier();
2241     OperandMatchResultTy ResTy =
2242         matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2243     return ResTy;
2244   } else if (Token.is(AsmToken::Integer)) {
2245     DEBUG(dbgs() << ".. integer\n");
2246     Operands.push_back(MipsOperand::createNumericReg(
2247         Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2248         *this));
2249     return MatchOperand_Success;
2250   }
2251 
2252   DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2253 
2254   return MatchOperand_NoMatch;
2255 }
2256 
2257 MipsAsmParser::OperandMatchResultTy
2258 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
2259   DEBUG(dbgs() << "parseAnyRegister\n");
2260 
2261   auto Token = Parser.getTok();
2262 
2263   SMLoc S = Token.getLoc();
2264 
2265   if (Token.isNot(AsmToken::Dollar)) {
2266     DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
2267     if (Token.is(AsmToken::Identifier)) {
2268       if (searchSymbolAlias(Operands))
2269         return MatchOperand_Success;
2270     }
2271     DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
2272     return MatchOperand_NoMatch;
2273   }
2274   DEBUG(dbgs() << ".. $\n");
2275 
2276   OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
2277   if (ResTy == MatchOperand_Success) {
2278     Parser.Lex(); // $
2279     Parser.Lex(); // identifier
2280   }
2281   return ResTy;
2282 }
2283 
2284 MipsAsmParser::OperandMatchResultTy
2285 MipsAsmParser::parseImm(OperandVector &Operands) {
2286   switch (getLexer().getKind()) {
2287   default:
2288     return MatchOperand_NoMatch;
2289   case AsmToken::LParen:
2290   case AsmToken::Minus:
2291   case AsmToken::Plus:
2292   case AsmToken::Integer:
2293   case AsmToken::Tilde:
2294   case AsmToken::String:
2295     break;
2296   }
2297 
2298   const MCExpr *IdVal;
2299   SMLoc S = Parser.getTok().getLoc();
2300   if (getParser().parseExpression(IdVal))
2301     return MatchOperand_ParseFail;
2302 
2303   SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2304   Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2305   return MatchOperand_Success;
2306 }
2307 
2308 MipsAsmParser::OperandMatchResultTy
2309 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
2310   DEBUG(dbgs() << "parseJumpTarget\n");
2311 
2312   SMLoc S = getLexer().getLoc();
2313 
2314   // Integers and expressions are acceptable
2315   OperandMatchResultTy ResTy = parseImm(Operands);
2316   if (ResTy != MatchOperand_NoMatch)
2317     return ResTy;
2318 
2319   // Registers are a valid target and have priority over symbols.
2320   ResTy = parseAnyRegister(Operands);
2321   if (ResTy != MatchOperand_NoMatch)
2322     return ResTy;
2323 
2324   const MCExpr *Expr = nullptr;
2325   if (Parser.parseExpression(Expr)) {
2326     // We have no way of knowing if a symbol was consumed so we must ParseFail
2327     return MatchOperand_ParseFail;
2328   }
2329   Operands.push_back(
2330       MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
2331   return MatchOperand_Success;
2332 }
2333 
2334 MipsAsmParser::OperandMatchResultTy
2335 MipsAsmParser::parseInvNum(OperandVector &Operands) {
2336   const MCExpr *IdVal;
2337   // If the first token is '$' we may have register operand.
2338   if (Parser.getTok().is(AsmToken::Dollar))
2339     return MatchOperand_NoMatch;
2340   SMLoc S = Parser.getTok().getLoc();
2341   if (getParser().parseExpression(IdVal))
2342     return MatchOperand_ParseFail;
2343   const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
2344   assert(MCE && "Unexpected MCExpr type.");
2345   int64_t Val = MCE->getValue();
2346   SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2347   Operands.push_back(MipsOperand::CreateImm(
2348       MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
2349   return MatchOperand_Success;
2350 }
2351 
2352 MipsAsmParser::OperandMatchResultTy
2353 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
2354   switch (getLexer().getKind()) {
2355   default:
2356     return MatchOperand_NoMatch;
2357   case AsmToken::LParen:
2358   case AsmToken::Plus:
2359   case AsmToken::Minus:
2360   case AsmToken::Integer:
2361     break;
2362   }
2363 
2364   const MCExpr *Expr;
2365   SMLoc S = Parser.getTok().getLoc();
2366 
2367   if (getParser().parseExpression(Expr))
2368     return MatchOperand_ParseFail;
2369 
2370   int64_t Val;
2371   if (!Expr->EvaluateAsAbsolute(Val)) {
2372     Error(S, "expected immediate value");
2373     return MatchOperand_ParseFail;
2374   }
2375 
2376   // The LSA instruction allows a 2-bit unsigned immediate. For this reason
2377   // and because the CPU always adds one to the immediate field, the allowed
2378   // range becomes 1..4. We'll only check the range here and will deal
2379   // with the addition/subtraction when actually decoding/encoding
2380   // the instruction.
2381   if (Val < 1 || Val > 4) {
2382     Error(S, "immediate not in range (1..4)");
2383     return MatchOperand_ParseFail;
2384   }
2385 
2386   Operands.push_back(
2387       MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
2388   return MatchOperand_Success;
2389 }
2390 
2391 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
2392 
2393   MCSymbolRefExpr::VariantKind VK =
2394       StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
2395           .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
2396           .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
2397           .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
2398           .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
2399           .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
2400           .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
2401           .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
2402           .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
2403           .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
2404           .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
2405           .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
2406           .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
2407           .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
2408           .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
2409           .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
2410           .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
2411           .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
2412           .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
2413           .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
2414           .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
2415           .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
2416           .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
2417           .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
2418           .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
2419           .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
2420           .Default(MCSymbolRefExpr::VK_None);
2421 
2422   assert(VK != MCSymbolRefExpr::VK_None);
2423 
2424   return VK;
2425 }
2426 
2427 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
2428 /// either this.
2429 /// ::= '(', register, ')'
2430 /// handle it before we iterate so we don't get tripped up by the lack of
2431 /// a comma.
2432 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
2433   if (getLexer().is(AsmToken::LParen)) {
2434     Operands.push_back(
2435         MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
2436     Parser.Lex();
2437     if (parseOperand(Operands, Name)) {
2438       SMLoc Loc = getLexer().getLoc();
2439       Parser.eatToEndOfStatement();
2440       return Error(Loc, "unexpected token in argument list");
2441     }
2442     if (Parser.getTok().isNot(AsmToken::RParen)) {
2443       SMLoc Loc = getLexer().getLoc();
2444       Parser.eatToEndOfStatement();
2445       return Error(Loc, "unexpected token, expected ')'");
2446     }
2447     Operands.push_back(
2448         MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
2449     Parser.Lex();
2450   }
2451   return false;
2452 }
2453 
2454 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
2455 /// either one of these.
2456 /// ::= '[', register, ']'
2457 /// ::= '[', integer, ']'
2458 /// handle it before we iterate so we don't get tripped up by the lack of
2459 /// a comma.
2460 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
2461                                        OperandVector &Operands) {
2462   if (getLexer().is(AsmToken::LBrac)) {
2463     Operands.push_back(
2464         MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
2465     Parser.Lex();
2466     if (parseOperand(Operands, Name)) {
2467       SMLoc Loc = getLexer().getLoc();
2468       Parser.eatToEndOfStatement();
2469       return Error(Loc, "unexpected token in argument list");
2470     }
2471     if (Parser.getTok().isNot(AsmToken::RBrac)) {
2472       SMLoc Loc = getLexer().getLoc();
2473       Parser.eatToEndOfStatement();
2474       return Error(Loc, "unexpected token, expected ']'");
2475     }
2476     Operands.push_back(
2477         MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
2478     Parser.Lex();
2479   }
2480   return false;
2481 }
2482 
2483 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
2484                                      SMLoc NameLoc, OperandVector &Operands) {
2485   DEBUG(dbgs() << "ParseInstruction\n");
2486 
2487   // We have reached first instruction, module directive are now forbidden.
2488   getTargetStreamer().forbidModuleDirective();
2489 
2490   // Check if we have valid mnemonic
2491   if (!mnemonicIsValid(Name, 0)) {
2492     Parser.eatToEndOfStatement();
2493     return Error(NameLoc, "unknown instruction");
2494   }
2495   // First operand in MCInst is instruction mnemonic.
2496   Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
2497 
2498   // Read the remaining operands.
2499   if (getLexer().isNot(AsmToken::EndOfStatement)) {
2500     // Read the first operand.
2501     if (parseOperand(Operands, Name)) {
2502       SMLoc Loc = getLexer().getLoc();
2503       Parser.eatToEndOfStatement();
2504       return Error(Loc, "unexpected token in argument list");
2505     }
2506     if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
2507       return true;
2508     // AFAIK, parenthesis suffixes are never on the first operand
2509 
2510     while (getLexer().is(AsmToken::Comma)) {
2511       Parser.Lex(); // Eat the comma.
2512       // Parse and remember the operand.
2513       if (parseOperand(Operands, Name)) {
2514         SMLoc Loc = getLexer().getLoc();
2515         Parser.eatToEndOfStatement();
2516         return Error(Loc, "unexpected token in argument list");
2517       }
2518       // Parse bracket and parenthesis suffixes before we iterate
2519       if (getLexer().is(AsmToken::LBrac)) {
2520         if (parseBracketSuffix(Name, Operands))
2521           return true;
2522       } else if (getLexer().is(AsmToken::LParen) &&
2523                  parseParenSuffix(Name, Operands))
2524         return true;
2525     }
2526   }
2527   if (getLexer().isNot(AsmToken::EndOfStatement)) {
2528     SMLoc Loc = getLexer().getLoc();
2529     Parser.eatToEndOfStatement();
2530     return Error(Loc, "unexpected token in argument list");
2531   }
2532   Parser.Lex(); // Consume the EndOfStatement.
2533   return false;
2534 }
2535 
2536 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
2537   SMLoc Loc = getLexer().getLoc();
2538   Parser.eatToEndOfStatement();
2539   return Error(Loc, ErrorMsg);
2540 }
2541 
2542 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
2543   return Error(Loc, ErrorMsg);
2544 }
2545 
2546 bool MipsAsmParser::parseSetNoAtDirective() {
2547   // Line should look like: ".set noat".
2548   // set at reg to 0.
2549   AssemblerOptions.back()->setATReg(0);
2550   // eat noat
2551   Parser.Lex();
2552   // If this is not the end of the statement, report an error.
2553   if (getLexer().isNot(AsmToken::EndOfStatement)) {
2554     reportParseError("unexpected token, expected end of statement");
2555     return false;
2556   }
2557   Parser.Lex(); // Consume the EndOfStatement.
2558   return false;
2559 }
2560 
2561 bool MipsAsmParser::parseSetAtDirective() {
2562   // Line can be .set at - defaults to $1
2563   // or .set at=$reg
2564   int AtRegNo;
2565   getParser().Lex();
2566   if (getLexer().is(AsmToken::EndOfStatement)) {
2567     AssemblerOptions.back()->setATReg(1);
2568     Parser.Lex(); // Consume the EndOfStatement.
2569     return false;
2570   } else if (getLexer().is(AsmToken::Equal)) {
2571     getParser().Lex(); // Eat the '='.
2572     if (getLexer().isNot(AsmToken::Dollar)) {
2573       reportParseError("unexpected token, expected dollar sign '$'");
2574       return false;
2575     }
2576     Parser.Lex(); // Eat the '$'.
2577     const AsmToken &Reg = Parser.getTok();
2578     if (Reg.is(AsmToken::Identifier)) {
2579       AtRegNo = matchCPURegisterName(Reg.getIdentifier());
2580     } else if (Reg.is(AsmToken::Integer)) {
2581       AtRegNo = Reg.getIntVal();
2582     } else {
2583       reportParseError("unexpected token, expected identifier or integer");
2584       return false;
2585     }
2586 
2587     if (AtRegNo < 0 || AtRegNo > 31) {
2588       reportParseError("unexpected token in statement");
2589       return false;
2590     }
2591 
2592     if (!AssemblerOptions.back()->setATReg(AtRegNo)) {
2593       reportParseError("invalid register");
2594       return false;
2595     }
2596     getParser().Lex(); // Eat the register.
2597 
2598     if (getLexer().isNot(AsmToken::EndOfStatement)) {
2599       reportParseError("unexpected token, expected end of statement");
2600       return false;
2601     }
2602     Parser.Lex(); // Consume the EndOfStatement.
2603     return false;
2604   } else {
2605     reportParseError("unexpected token in statement");
2606     return false;
2607   }
2608 }
2609 
2610 bool MipsAsmParser::parseSetReorderDirective() {
2611   Parser.Lex();
2612   // If this is not the end of the statement, report an error.
2613   if (getLexer().isNot(AsmToken::EndOfStatement)) {
2614     reportParseError("unexpected token, expected end of statement");
2615     return false;
2616   }
2617   AssemblerOptions.back()->setReorder();
2618   getTargetStreamer().emitDirectiveSetReorder();
2619   Parser.Lex(); // Consume the EndOfStatement.
2620   return false;
2621 }
2622 
2623 bool MipsAsmParser::parseSetNoReorderDirective() {
2624   Parser.Lex();
2625   // If this is not the end of the statement, report an error.
2626   if (getLexer().isNot(AsmToken::EndOfStatement)) {
2627     reportParseError("unexpected token, expected end of statement");
2628     return false;
2629   }
2630   AssemblerOptions.back()->setNoReorder();
2631   getTargetStreamer().emitDirectiveSetNoReorder();
2632   Parser.Lex(); // Consume the EndOfStatement.
2633   return false;
2634 }
2635 
2636 bool MipsAsmParser::parseSetMacroDirective() {
2637   Parser.Lex();
2638   // If this is not the end of the statement, report an error.
2639   if (getLexer().isNot(AsmToken::EndOfStatement)) {
2640     reportParseError("unexpected token, expected end of statement");
2641     return false;
2642   }
2643   AssemblerOptions.back()->setMacro();
2644   Parser.Lex(); // Consume the EndOfStatement.
2645   return false;
2646 }
2647 
2648 bool MipsAsmParser::parseSetNoMacroDirective() {
2649   Parser.Lex();
2650   // If this is not the end of the statement, report an error.
2651   if (getLexer().isNot(AsmToken::EndOfStatement)) {
2652     reportParseError("unexpected token, expected end of statement");
2653     return false;
2654   }
2655   if (AssemblerOptions.back()->isReorder()) {
2656     reportParseError("`noreorder' must be set before `nomacro'");
2657     return false;
2658   }
2659   AssemblerOptions.back()->setNoMacro();
2660   Parser.Lex(); // Consume the EndOfStatement.
2661   return false;
2662 }
2663 
2664 bool MipsAsmParser::parseSetMsaDirective() {
2665   Parser.Lex();
2666 
2667   // If this is not the end of the statement, report an error.
2668   if (getLexer().isNot(AsmToken::EndOfStatement))
2669     return reportParseError("unexpected token, expected end of statement");
2670 
2671   setFeatureBits(Mips::FeatureMSA, "msa");
2672   getTargetStreamer().emitDirectiveSetMsa();
2673   return false;
2674 }
2675 
2676 bool MipsAsmParser::parseSetNoMsaDirective() {
2677   Parser.Lex();
2678 
2679   // If this is not the end of the statement, report an error.
2680   if (getLexer().isNot(AsmToken::EndOfStatement))
2681     return reportParseError("unexpected token, expected end of statement");
2682 
2683   clearFeatureBits(Mips::FeatureMSA, "msa");
2684   getTargetStreamer().emitDirectiveSetNoMsa();
2685   return false;
2686 }
2687 
2688 bool MipsAsmParser::parseSetNoDspDirective() {
2689   Parser.Lex(); // Eat "nodsp".
2690 
2691   // If this is not the end of the statement, report an error.
2692   if (getLexer().isNot(AsmToken::EndOfStatement)) {
2693     reportParseError("unexpected token, expected end of statement");
2694     return false;
2695   }
2696 
2697   clearFeatureBits(Mips::FeatureDSP, "dsp");
2698   getTargetStreamer().emitDirectiveSetNoDsp();
2699   return false;
2700 }
2701 
2702 bool MipsAsmParser::parseSetNoMips16Directive() {
2703   Parser.Lex();
2704   // If this is not the end of the statement, report an error.
2705   if (getLexer().isNot(AsmToken::EndOfStatement)) {
2706     reportParseError("unexpected token, expected end of statement");
2707     return false;
2708   }
2709   // For now do nothing.
2710   Parser.Lex(); // Consume the EndOfStatement.
2711   return false;
2712 }
2713 
2714 bool MipsAsmParser::parseSetFpDirective() {
2715   MipsABIFlagsSection::FpABIKind FpAbiVal;
2716   // Line can be: .set fp=32
2717   //              .set fp=xx
2718   //              .set fp=64
2719   Parser.Lex(); // Eat fp token
2720   AsmToken Tok = Parser.getTok();
2721   if (Tok.isNot(AsmToken::Equal)) {
2722     reportParseError("unexpected token, expected equals sign '='");
2723     return false;
2724   }
2725   Parser.Lex(); // Eat '=' token.
2726   Tok = Parser.getTok();
2727 
2728   if (!parseFpABIValue(FpAbiVal, ".set"))
2729     return false;
2730 
2731   if (getLexer().isNot(AsmToken::EndOfStatement)) {
2732     reportParseError("unexpected token, expected end of statement");
2733     return false;
2734   }
2735   getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
2736   Parser.Lex(); // Consume the EndOfStatement.
2737   return false;
2738 }
2739 
2740 bool MipsAsmParser::parseSetPopDirective() {
2741   SMLoc Loc = getLexer().getLoc();
2742 
2743   Parser.Lex();
2744   if (getLexer().isNot(AsmToken::EndOfStatement))
2745     return reportParseError("unexpected token, expected end of statement");
2746 
2747   // Always keep an element on the options "stack" to prevent the user
2748   // from changing the initial options. This is how we remember them.
2749   if (AssemblerOptions.size() == 2)
2750     return reportParseError(Loc, ".set pop with no .set push");
2751 
2752   AssemblerOptions.pop_back();
2753   setAvailableFeatures(AssemblerOptions.back()->getFeatures());
2754 
2755   getTargetStreamer().emitDirectiveSetPop();
2756   return false;
2757 }
2758 
2759 bool MipsAsmParser::parseSetPushDirective() {
2760   Parser.Lex();
2761   if (getLexer().isNot(AsmToken::EndOfStatement))
2762     return reportParseError("unexpected token, expected end of statement");
2763 
2764   // Create a copy of the current assembler options environment and push it.
2765   AssemblerOptions.push_back(
2766               make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
2767 
2768   getTargetStreamer().emitDirectiveSetPush();
2769   return false;
2770 }
2771 
2772 bool MipsAsmParser::parseSetAssignment() {
2773   StringRef Name;
2774   const MCExpr *Value;
2775 
2776   if (Parser.parseIdentifier(Name))
2777     reportParseError("expected identifier after .set");
2778 
2779   if (getLexer().isNot(AsmToken::Comma))
2780     return reportParseError("unexpected token, expected comma");
2781   Lex(); // Eat comma
2782 
2783   if (Parser.parseExpression(Value))
2784     return reportParseError("expected valid expression after comma");
2785 
2786   // Check if the Name already exists as a symbol.
2787   MCSymbol *Sym = getContext().LookupSymbol(Name);
2788   if (Sym)
2789     return reportParseError("symbol already defined");
2790   Sym = getContext().GetOrCreateSymbol(Name);
2791   Sym->setVariableValue(Value);
2792 
2793   return false;
2794 }
2795 
2796 bool MipsAsmParser::parseSetMips0Directive() {
2797   Parser.Lex();
2798   if (getLexer().isNot(AsmToken::EndOfStatement))
2799     return reportParseError("unexpected token, expected end of statement");
2800 
2801   // Reset assembler options to their initial values.
2802   setAvailableFeatures(AssemblerOptions.front()->getFeatures());
2803   AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
2804 
2805   getTargetStreamer().emitDirectiveSetMips0();
2806   return false;
2807 }
2808 
2809 bool MipsAsmParser::parseSetArchDirective() {
2810   Parser.Lex();
2811   if (getLexer().isNot(AsmToken::Equal))
2812     return reportParseError("unexpected token, expected equals sign");
2813 
2814   Parser.Lex();
2815   StringRef Arch;
2816   if (Parser.parseIdentifier(Arch))
2817     return reportParseError("expected arch identifier");
2818 
2819   StringRef ArchFeatureName =
2820       StringSwitch<StringRef>(Arch)
2821           .Case("mips1", "mips1")
2822           .Case("mips2", "mips2")
2823           .Case("mips3", "mips3")
2824           .Case("mips4", "mips4")
2825           .Case("mips5", "mips5")
2826           .Case("mips32", "mips32")
2827           .Case("mips32r2", "mips32r2")
2828           .Case("mips32r6", "mips32r6")
2829           .Case("mips64", "mips64")
2830           .Case("mips64r2", "mips64r2")
2831           .Case("mips64r6", "mips64r6")
2832           .Case("cnmips", "cnmips")
2833           .Case("r4000", "mips3") // This is an implementation of Mips3.
2834           .Default("");
2835 
2836   if (ArchFeatureName.empty())
2837     return reportParseError("unsupported architecture");
2838 
2839   selectArch(ArchFeatureName);
2840   getTargetStreamer().emitDirectiveSetArch(Arch);
2841   return false;
2842 }
2843 
2844 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
2845   Parser.Lex();
2846   if (getLexer().isNot(AsmToken::EndOfStatement))
2847     return reportParseError("unexpected token, expected end of statement");
2848 
2849   switch (Feature) {
2850   default:
2851     llvm_unreachable("Unimplemented feature");
2852   case Mips::FeatureDSP:
2853     setFeatureBits(Mips::FeatureDSP, "dsp");
2854     getTargetStreamer().emitDirectiveSetDsp();
2855     break;
2856   case Mips::FeatureMicroMips:
2857     getTargetStreamer().emitDirectiveSetMicroMips();
2858     break;
2859   case Mips::FeatureMips16:
2860     getTargetStreamer().emitDirectiveSetMips16();
2861     break;
2862   case Mips::FeatureMips1:
2863     selectArch("mips1");
2864     getTargetStreamer().emitDirectiveSetMips1();
2865     break;
2866   case Mips::FeatureMips2:
2867     selectArch("mips2");
2868     getTargetStreamer().emitDirectiveSetMips2();
2869     break;
2870   case Mips::FeatureMips3:
2871     selectArch("mips3");
2872     getTargetStreamer().emitDirectiveSetMips3();
2873     break;
2874   case Mips::FeatureMips4:
2875     selectArch("mips4");
2876     getTargetStreamer().emitDirectiveSetMips4();
2877     break;
2878   case Mips::FeatureMips5:
2879     selectArch("mips5");
2880     getTargetStreamer().emitDirectiveSetMips5();
2881     break;
2882   case Mips::FeatureMips32:
2883     selectArch("mips32");
2884     getTargetStreamer().emitDirectiveSetMips32();
2885     break;
2886   case Mips::FeatureMips32r2:
2887     selectArch("mips32r2");
2888     getTargetStreamer().emitDirectiveSetMips32R2();
2889     break;
2890   case Mips::FeatureMips32r6:
2891     selectArch("mips32r6");
2892     getTargetStreamer().emitDirectiveSetMips32R6();
2893     break;
2894   case Mips::FeatureMips64:
2895     selectArch("mips64");
2896     getTargetStreamer().emitDirectiveSetMips64();
2897     break;
2898   case Mips::FeatureMips64r2:
2899     selectArch("mips64r2");
2900     getTargetStreamer().emitDirectiveSetMips64R2();
2901     break;
2902   case Mips::FeatureMips64r6:
2903     selectArch("mips64r6");
2904     getTargetStreamer().emitDirectiveSetMips64R6();
2905     break;
2906   }
2907   return false;
2908 }
2909 
2910 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
2911   if (getLexer().isNot(AsmToken::Comma)) {
2912     SMLoc Loc = getLexer().getLoc();
2913     Parser.eatToEndOfStatement();
2914     return Error(Loc, ErrorStr);
2915   }
2916 
2917   Parser.Lex(); // Eat the comma.
2918   return true;
2919 }
2920 
2921 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
2922   if (AssemblerOptions.back()->isReorder())
2923     Warning(Loc, ".cpload in reorder section");
2924 
2925   // FIXME: Warn if cpload is used in Mips16 mode.
2926 
2927   SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
2928   OperandMatchResultTy ResTy = parseAnyRegister(Reg);
2929   if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
2930     reportParseError("expected register containing function address");
2931     return false;
2932   }
2933 
2934   MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
2935   if (!RegOpnd.isGPRAsmReg()) {
2936     reportParseError(RegOpnd.getStartLoc(), "invalid register");
2937     return false;
2938   }
2939 
2940   getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
2941   return false;
2942 }
2943 
2944 bool MipsAsmParser::parseDirectiveCPSetup() {
2945   unsigned FuncReg;
2946   unsigned Save;
2947   bool SaveIsReg = true;
2948 
2949   SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
2950   OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
2951   if (ResTy == MatchOperand_NoMatch) {
2952     reportParseError("expected register containing function address");
2953     Parser.eatToEndOfStatement();
2954     return false;
2955   }
2956 
2957   MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
2958   if (!FuncRegOpnd.isGPRAsmReg()) {
2959     reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
2960     Parser.eatToEndOfStatement();
2961     return false;
2962   }
2963 
2964   FuncReg = FuncRegOpnd.getGPR32Reg();
2965   TmpReg.clear();
2966 
2967   if (!eatComma("unexpected token, expected comma"))
2968     return true;
2969 
2970   ResTy = parseAnyRegister(TmpReg);
2971   if (ResTy == MatchOperand_NoMatch) {
2972     const AsmToken &Tok = Parser.getTok();
2973     if (Tok.is(AsmToken::Integer)) {
2974       Save = Tok.getIntVal();
2975       SaveIsReg = false;
2976       Parser.Lex();
2977     } else {
2978       reportParseError("expected save register or stack offset");
2979       Parser.eatToEndOfStatement();
2980       return false;
2981     }
2982   } else {
2983     MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
2984     if (!SaveOpnd.isGPRAsmReg()) {
2985       reportParseError(SaveOpnd.getStartLoc(), "invalid register");
2986       Parser.eatToEndOfStatement();
2987       return false;
2988     }
2989     Save = SaveOpnd.getGPR32Reg();
2990   }
2991 
2992   if (!eatComma("unexpected token, expected comma"))
2993     return true;
2994 
2995   StringRef Name;
2996   if (Parser.parseIdentifier(Name))
2997     reportParseError("expected identifier");
2998   MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
2999 
3000   getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, *Sym, SaveIsReg);
3001   return false;
3002 }
3003 
3004 bool MipsAsmParser::parseDirectiveNaN() {
3005   if (getLexer().isNot(AsmToken::EndOfStatement)) {
3006     const AsmToken &Tok = Parser.getTok();
3007 
3008     if (Tok.getString() == "2008") {
3009       Parser.Lex();
3010       getTargetStreamer().emitDirectiveNaN2008();
3011       return false;
3012     } else if (Tok.getString() == "legacy") {
3013       Parser.Lex();
3014       getTargetStreamer().emitDirectiveNaNLegacy();
3015       return false;
3016     }
3017   }
3018   // If we don't recognize the option passed to the .nan
3019   // directive (e.g. no option or unknown option), emit an error.
3020   reportParseError("invalid option in .nan directive");
3021   return false;
3022 }
3023 
3024 bool MipsAsmParser::parseDirectiveSet() {
3025 
3026   // Get the next token.
3027   const AsmToken &Tok = Parser.getTok();
3028 
3029   if (Tok.getString() == "noat") {
3030     return parseSetNoAtDirective();
3031   } else if (Tok.getString() == "at") {
3032     return parseSetAtDirective();
3033   } else if (Tok.getString() == "arch") {
3034     return parseSetArchDirective();
3035   } else if (Tok.getString() == "fp") {
3036     return parseSetFpDirective();
3037   } else if (Tok.getString() == "pop") {
3038     return parseSetPopDirective();
3039   } else if (Tok.getString() == "push") {
3040     return parseSetPushDirective();
3041   } else if (Tok.getString() == "reorder") {
3042     return parseSetReorderDirective();
3043   } else if (Tok.getString() == "noreorder") {
3044     return parseSetNoReorderDirective();
3045   } else if (Tok.getString() == "macro") {
3046     return parseSetMacroDirective();
3047   } else if (Tok.getString() == "nomacro") {
3048     return parseSetNoMacroDirective();
3049   } else if (Tok.getString() == "mips16") {
3050     return parseSetFeature(Mips::FeatureMips16);
3051   } else if (Tok.getString() == "nomips16") {
3052     return parseSetNoMips16Directive();
3053   } else if (Tok.getString() == "nomicromips") {
3054     getTargetStreamer().emitDirectiveSetNoMicroMips();
3055     Parser.eatToEndOfStatement();
3056     return false;
3057   } else if (Tok.getString() == "micromips") {
3058     return parseSetFeature(Mips::FeatureMicroMips);
3059   } else if (Tok.getString() == "mips0") {
3060     return parseSetMips0Directive();
3061   } else if (Tok.getString() == "mips1") {
3062     return parseSetFeature(Mips::FeatureMips1);
3063   } else if (Tok.getString() == "mips2") {
3064     return parseSetFeature(Mips::FeatureMips2);
3065   } else if (Tok.getString() == "mips3") {
3066     return parseSetFeature(Mips::FeatureMips3);
3067   } else if (Tok.getString() == "mips4") {
3068     return parseSetFeature(Mips::FeatureMips4);
3069   } else if (Tok.getString() == "mips5") {
3070     return parseSetFeature(Mips::FeatureMips5);
3071   } else if (Tok.getString() == "mips32") {
3072     return parseSetFeature(Mips::FeatureMips32);
3073   } else if (Tok.getString() == "mips32r2") {
3074     return parseSetFeature(Mips::FeatureMips32r2);
3075   } else if (Tok.getString() == "mips32r6") {
3076     return parseSetFeature(Mips::FeatureMips32r6);
3077   } else if (Tok.getString() == "mips64") {
3078     return parseSetFeature(Mips::FeatureMips64);
3079   } else if (Tok.getString() == "mips64r2") {
3080     return parseSetFeature(Mips::FeatureMips64r2);
3081   } else if (Tok.getString() == "mips64r6") {
3082     return parseSetFeature(Mips::FeatureMips64r6);
3083   } else if (Tok.getString() == "dsp") {
3084     return parseSetFeature(Mips::FeatureDSP);
3085   } else if (Tok.getString() == "nodsp") {
3086     return parseSetNoDspDirective();
3087   } else if (Tok.getString() == "msa") {
3088     return parseSetMsaDirective();
3089   } else if (Tok.getString() == "nomsa") {
3090     return parseSetNoMsaDirective();
3091   } else {
3092     // It is just an identifier, look for an assignment.
3093     parseSetAssignment();
3094     return false;
3095   }
3096 
3097   return true;
3098 }
3099 
3100 /// parseDataDirective
3101 ///  ::= .word [ expression (, expression)* ]
3102 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
3103   if (getLexer().isNot(AsmToken::EndOfStatement)) {
3104     for (;;) {
3105       const MCExpr *Value;
3106       if (getParser().parseExpression(Value))
3107         return true;
3108 
3109       getParser().getStreamer().EmitValue(Value, Size);
3110 
3111       if (getLexer().is(AsmToken::EndOfStatement))
3112         break;
3113 
3114       if (getLexer().isNot(AsmToken::Comma))
3115         return Error(L, "unexpected token, expected comma");
3116       Parser.Lex();
3117     }
3118   }
3119 
3120   Parser.Lex();
3121   return false;
3122 }
3123 
3124 /// parseDirectiveGpWord
3125 ///  ::= .gpword local_sym
3126 bool MipsAsmParser::parseDirectiveGpWord() {
3127   const MCExpr *Value;
3128   // EmitGPRel32Value requires an expression, so we are using base class
3129   // method to evaluate the expression.
3130   if (getParser().parseExpression(Value))
3131     return true;
3132   getParser().getStreamer().EmitGPRel32Value(Value);
3133 
3134   if (getLexer().isNot(AsmToken::EndOfStatement))
3135     return Error(getLexer().getLoc(),
3136                 "unexpected token, expected end of statement");
3137   Parser.Lex(); // Eat EndOfStatement token.
3138   return false;
3139 }
3140 
3141 /// parseDirectiveGpDWord
3142 ///  ::= .gpdword local_sym
3143 bool MipsAsmParser::parseDirectiveGpDWord() {
3144   const MCExpr *Value;
3145   // EmitGPRel64Value requires an expression, so we are using base class
3146   // method to evaluate the expression.
3147   if (getParser().parseExpression(Value))
3148     return true;
3149   getParser().getStreamer().EmitGPRel64Value(Value);
3150 
3151   if (getLexer().isNot(AsmToken::EndOfStatement))
3152     return Error(getLexer().getLoc(),
3153                 "unexpected token, expected end of statement");
3154   Parser.Lex(); // Eat EndOfStatement token.
3155   return false;
3156 }
3157 
3158 bool MipsAsmParser::parseDirectiveOption() {
3159   // Get the option token.
3160   AsmToken Tok = Parser.getTok();
3161   // At the moment only identifiers are supported.
3162   if (Tok.isNot(AsmToken::Identifier)) {
3163     Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
3164     Parser.eatToEndOfStatement();
3165     return false;
3166   }
3167 
3168   StringRef Option = Tok.getIdentifier();
3169 
3170   if (Option == "pic0") {
3171     getTargetStreamer().emitDirectiveOptionPic0();
3172     Parser.Lex();
3173     if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3174       Error(Parser.getTok().getLoc(),
3175             "unexpected token, expected end of statement");
3176       Parser.eatToEndOfStatement();
3177     }
3178     return false;
3179   }
3180 
3181   if (Option == "pic2") {
3182     getTargetStreamer().emitDirectiveOptionPic2();
3183     Parser.Lex();
3184     if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3185       Error(Parser.getTok().getLoc(),
3186             "unexpected token, expected end of statement");
3187       Parser.eatToEndOfStatement();
3188     }
3189     return false;
3190   }
3191 
3192   // Unknown option.
3193   Warning(Parser.getTok().getLoc(),
3194           "unknown option, expected 'pic0' or 'pic2'");
3195   Parser.eatToEndOfStatement();
3196   return false;
3197 }
3198 
3199 /// parseDirectiveModule
3200 ///  ::= .module oddspreg
3201 ///  ::= .module nooddspreg
3202 ///  ::= .module fp=value
3203 bool MipsAsmParser::parseDirectiveModule() {
3204   MCAsmLexer &Lexer = getLexer();
3205   SMLoc L = Lexer.getLoc();
3206 
3207   if (!getTargetStreamer().isModuleDirectiveAllowed()) {
3208     // TODO : get a better message.
3209     reportParseError(".module directive must appear before any code");
3210     return false;
3211   }
3212 
3213   if (Lexer.is(AsmToken::Identifier)) {
3214     StringRef Option = Parser.getTok().getString();
3215     Parser.Lex();
3216 
3217     if (Option == "oddspreg") {
3218       getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
3219       clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
3220 
3221       if (getLexer().isNot(AsmToken::EndOfStatement)) {
3222         reportParseError("unexpected token, expected end of statement");
3223         return false;
3224       }
3225 
3226       return false;
3227     } else if (Option == "nooddspreg") {
3228       if (!isABI_O32()) {
3229         Error(L, "'.module nooddspreg' requires the O32 ABI");
3230         return false;
3231       }
3232 
3233       getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
3234       setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
3235 
3236       if (getLexer().isNot(AsmToken::EndOfStatement)) {
3237         reportParseError("unexpected token, expected end of statement");
3238         return false;
3239       }
3240 
3241       return false;
3242     } else if (Option == "fp") {
3243       return parseDirectiveModuleFP();
3244     }
3245 
3246     return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
3247   }
3248 
3249   return false;
3250 }
3251 
3252 /// parseDirectiveModuleFP
3253 ///  ::= =32
3254 ///  ::= =xx
3255 ///  ::= =64
3256 bool MipsAsmParser::parseDirectiveModuleFP() {
3257   MCAsmLexer &Lexer = getLexer();
3258 
3259   if (Lexer.isNot(AsmToken::Equal)) {
3260     reportParseError("unexpected token, expected equals sign '='");
3261     return false;
3262   }
3263   Parser.Lex(); // Eat '=' token.
3264 
3265   MipsABIFlagsSection::FpABIKind FpABI;
3266   if (!parseFpABIValue(FpABI, ".module"))
3267     return false;
3268 
3269   if (getLexer().isNot(AsmToken::EndOfStatement)) {
3270     reportParseError("unexpected token, expected end of statement");
3271     return false;
3272   }
3273 
3274   // Emit appropriate flags.
3275   getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
3276   Parser.Lex(); // Consume the EndOfStatement.
3277   return false;
3278 }
3279 
3280 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
3281                                     StringRef Directive) {
3282   MCAsmLexer &Lexer = getLexer();
3283 
3284   if (Lexer.is(AsmToken::Identifier)) {
3285     StringRef Value = Parser.getTok().getString();
3286     Parser.Lex();
3287 
3288     if (Value != "xx") {
3289       reportParseError("unsupported value, expected 'xx', '32' or '64'");
3290       return false;
3291     }
3292 
3293     if (!isABI_O32()) {
3294       reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
3295       return false;
3296     }
3297 
3298     FpABI = MipsABIFlagsSection::FpABIKind::XX;
3299     return true;
3300   }
3301 
3302   if (Lexer.is(AsmToken::Integer)) {
3303     unsigned Value = Parser.getTok().getIntVal();
3304     Parser.Lex();
3305 
3306     if (Value != 32 && Value != 64) {
3307       reportParseError("unsupported value, expected 'xx', '32' or '64'");
3308       return false;
3309     }
3310 
3311     if (Value == 32) {
3312       if (!isABI_O32()) {
3313         reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
3314         return false;
3315       }
3316 
3317       FpABI = MipsABIFlagsSection::FpABIKind::S32;
3318     } else
3319       FpABI = MipsABIFlagsSection::FpABIKind::S64;
3320 
3321     return true;
3322   }
3323 
3324   return false;
3325 }
3326 
3327 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
3328   StringRef IDVal = DirectiveID.getString();
3329 
3330   if (IDVal == ".cpload")
3331     return parseDirectiveCpLoad(DirectiveID.getLoc());
3332   if (IDVal == ".dword") {
3333     parseDataDirective(8, DirectiveID.getLoc());
3334     return false;
3335   }
3336   if (IDVal == ".ent") {
3337     StringRef SymbolName;
3338 
3339     if (Parser.parseIdentifier(SymbolName)) {
3340       reportParseError("expected identifier after .ent");
3341       return false;
3342     }
3343 
3344     // There's an undocumented extension that allows an integer to
3345     // follow the name of the procedure which AFAICS is ignored by GAS.
3346     // Example: .ent foo,2
3347     if (getLexer().isNot(AsmToken::EndOfStatement)) {
3348       if (getLexer().isNot(AsmToken::Comma)) {
3349         // Even though we accept this undocumented extension for compatibility
3350         // reasons, the additional integer argument does not actually change
3351         // the behaviour of the '.ent' directive, so we would like to discourage
3352         // its use. We do this by not referring to the extended version in
3353         // error messages which are not directly related to its use.
3354         reportParseError("unexpected token, expected end of statement");
3355         return false;
3356       }
3357       Parser.Lex(); // Eat the comma.
3358       const MCExpr *DummyNumber;
3359       int64_t DummyNumberVal;
3360       // If the user was explicitly trying to use the extended version,
3361       // we still give helpful extension-related error messages.
3362       if (Parser.parseExpression(DummyNumber)) {
3363         reportParseError("expected number after comma");
3364         return false;
3365       }
3366       if (!DummyNumber->EvaluateAsAbsolute(DummyNumberVal)) {
3367         reportParseError("expected an absolute expression after comma");
3368         return false;
3369       }
3370     }
3371 
3372     // If this is not the end of the statement, report an error.
3373     if (getLexer().isNot(AsmToken::EndOfStatement)) {
3374       reportParseError("unexpected token, expected end of statement");
3375       return false;
3376     }
3377 
3378     MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName);
3379 
3380     getTargetStreamer().emitDirectiveEnt(*Sym);
3381     CurrentFn = Sym;
3382     return false;
3383   }
3384 
3385   if (IDVal == ".end") {
3386     StringRef SymbolName;
3387 
3388     if (Parser.parseIdentifier(SymbolName)) {
3389       reportParseError("expected identifier after .end");
3390       return false;
3391     }
3392 
3393     if (getLexer().isNot(AsmToken::EndOfStatement)) {
3394       reportParseError("unexpected token, expected end of statement");
3395       return false;
3396     }
3397 
3398     if (CurrentFn == nullptr) {
3399       reportParseError(".end used without .ent");
3400       return false;
3401     }
3402 
3403     if ((SymbolName != CurrentFn->getName())) {
3404       reportParseError(".end symbol does not match .ent symbol");
3405       return false;
3406     }
3407 
3408     getTargetStreamer().emitDirectiveEnd(SymbolName);
3409     CurrentFn = nullptr;
3410     return false;
3411   }
3412 
3413   if (IDVal == ".frame") {
3414     // .frame $stack_reg, frame_size_in_bytes, $return_reg
3415     SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3416     OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3417     if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3418       reportParseError("expected stack register");
3419       return false;
3420     }
3421 
3422     MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3423     if (!StackRegOpnd.isGPRAsmReg()) {
3424       reportParseError(StackRegOpnd.getStartLoc(),
3425                        "expected general purpose register");
3426       return false;
3427     }
3428     unsigned StackReg = StackRegOpnd.getGPR32Reg();
3429 
3430     if (Parser.getTok().is(AsmToken::Comma))
3431       Parser.Lex();
3432     else {
3433       reportParseError("unexpected token, expected comma");
3434       return false;
3435     }
3436 
3437     // Parse the frame size.
3438     const MCExpr *FrameSize;
3439     int64_t FrameSizeVal;
3440 
3441     if (Parser.parseExpression(FrameSize)) {
3442       reportParseError("expected frame size value");
3443       return false;
3444     }
3445 
3446     if (!FrameSize->EvaluateAsAbsolute(FrameSizeVal)) {
3447       reportParseError("frame size not an absolute expression");
3448       return false;
3449     }
3450 
3451     if (Parser.getTok().is(AsmToken::Comma))
3452       Parser.Lex();
3453     else {
3454       reportParseError("unexpected token, expected comma");
3455       return false;
3456     }
3457 
3458     // Parse the return register.
3459     TmpReg.clear();
3460     ResTy = parseAnyRegister(TmpReg);
3461     if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3462       reportParseError("expected return register");
3463       return false;
3464     }
3465 
3466     MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3467     if (!ReturnRegOpnd.isGPRAsmReg()) {
3468       reportParseError(ReturnRegOpnd.getStartLoc(),
3469                        "expected general purpose register");
3470       return false;
3471     }
3472 
3473     // If this is not the end of the statement, report an error.
3474     if (getLexer().isNot(AsmToken::EndOfStatement)) {
3475       reportParseError("unexpected token, expected end of statement");
3476       return false;
3477     }
3478 
3479     getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
3480                                   ReturnRegOpnd.getGPR32Reg());
3481     return false;
3482   }
3483 
3484   if (IDVal == ".set") {
3485     return parseDirectiveSet();
3486   }
3487 
3488   if (IDVal == ".mask" || IDVal == ".fmask") {
3489     // .mask bitmask, frame_offset
3490     // bitmask: One bit for each register used.
3491     // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
3492     //               first register is expected to be saved.
3493     // Examples:
3494     //   .mask 0x80000000, -4
3495     //   .fmask 0x80000000, -4
3496     //
3497 
3498     // Parse the bitmask
3499     const MCExpr *BitMask;
3500     int64_t BitMaskVal;
3501 
3502     if (Parser.parseExpression(BitMask)) {
3503       reportParseError("expected bitmask value");
3504       return false;
3505     }
3506 
3507     if (!BitMask->EvaluateAsAbsolute(BitMaskVal)) {
3508       reportParseError("bitmask not an absolute expression");
3509       return false;
3510     }
3511 
3512     if (Parser.getTok().is(AsmToken::Comma))
3513       Parser.Lex();
3514     else {
3515       reportParseError("unexpected token, expected comma");
3516       return false;
3517     }
3518 
3519     // Parse the frame_offset
3520     const MCExpr *FrameOffset;
3521     int64_t FrameOffsetVal;
3522 
3523     if (Parser.parseExpression(FrameOffset)) {
3524       reportParseError("expected frame offset value");
3525       return false;
3526     }
3527 
3528     if (!FrameOffset->EvaluateAsAbsolute(FrameOffsetVal)) {
3529       reportParseError("frame offset not an absolute expression");
3530       return false;
3531     }
3532 
3533     // If this is not the end of the statement, report an error.
3534     if (getLexer().isNot(AsmToken::EndOfStatement)) {
3535       reportParseError("unexpected token, expected end of statement");
3536       return false;
3537     }
3538 
3539     if (IDVal == ".mask")
3540       getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
3541     else
3542       getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
3543     return false;
3544   }
3545 
3546   if (IDVal == ".nan")
3547     return parseDirectiveNaN();
3548 
3549   if (IDVal == ".gpword") {
3550     parseDirectiveGpWord();
3551     return false;
3552   }
3553 
3554   if (IDVal == ".gpdword") {
3555     parseDirectiveGpDWord();
3556     return false;
3557   }
3558 
3559   if (IDVal == ".word") {
3560     parseDataDirective(4, DirectiveID.getLoc());
3561     return false;
3562   }
3563 
3564   if (IDVal == ".option")
3565     return parseDirectiveOption();
3566 
3567   if (IDVal == ".abicalls") {
3568     getTargetStreamer().emitDirectiveAbiCalls();
3569     if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3570       Error(Parser.getTok().getLoc(),
3571             "unexpected token, expected end of statement");
3572       // Clear line
3573       Parser.eatToEndOfStatement();
3574     }
3575     return false;
3576   }
3577 
3578   if (IDVal == ".cpsetup")
3579     return parseDirectiveCPSetup();
3580 
3581   if (IDVal == ".module")
3582     return parseDirectiveModule();
3583 
3584   return true;
3585 }
3586 
3587 extern "C" void LLVMInitializeMipsAsmParser() {
3588   RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
3589   RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
3590   RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
3591   RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
3592 }
3593 
3594 #define GET_REGISTER_MATCHER
3595 #define GET_MATCHER_IMPLEMENTATION
3596 #include "MipsGenAsmMatcher.inc"
3597