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