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