xref: /freebsd/contrib/llvm-project/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp (revision e64bea71c21eb42e97aa615188ba91f6cce0d36d)
1 //===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "MCTargetDesc/MipsABIFlagsSection.h"
10 #include "MCTargetDesc/MipsABIInfo.h"
11 #include "MCTargetDesc/MipsBaseInfo.h"
12 #include "MCTargetDesc/MipsMCAsmInfo.h"
13 #include "MCTargetDesc/MipsMCTargetDesc.h"
14 #include "MCTargetDesc/MipsTargetStreamer.h"
15 #include "TargetInfo/MipsTargetInfo.h"
16 #include "llvm/ADT/APFloat.h"
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/ADT/StringRef.h"
19 #include "llvm/ADT/StringSwitch.h"
20 #include "llvm/ADT/Twine.h"
21 #include "llvm/BinaryFormat/ELF.h"
22 #include "llvm/MC/MCContext.h"
23 #include "llvm/MC/MCExpr.h"
24 #include "llvm/MC/MCInst.h"
25 #include "llvm/MC/MCInstrDesc.h"
26 #include "llvm/MC/MCInstrInfo.h"
27 #include "llvm/MC/MCObjectFileInfo.h"
28 #include "llvm/MC/MCParser/AsmLexer.h"
29 #include "llvm/MC/MCParser/MCAsmParser.h"
30 #include "llvm/MC/MCParser/MCAsmParserExtension.h"
31 #include "llvm/MC/MCParser/MCAsmParserUtils.h"
32 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
33 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
34 #include "llvm/MC/MCSectionELF.h"
35 #include "llvm/MC/MCStreamer.h"
36 #include "llvm/MC/MCSubtargetInfo.h"
37 #include "llvm/MC/MCSymbol.h"
38 #include "llvm/MC/MCSymbolELF.h"
39 #include "llvm/MC/MCValue.h"
40 #include "llvm/MC/TargetRegistry.h"
41 #include "llvm/Support/Alignment.h"
42 #include "llvm/Support/Casting.h"
43 #include "llvm/Support/CommandLine.h"
44 #include "llvm/Support/Compiler.h"
45 #include "llvm/Support/Debug.h"
46 #include "llvm/Support/ErrorHandling.h"
47 #include "llvm/Support/MathExtras.h"
48 #include "llvm/Support/SMLoc.h"
49 #include "llvm/Support/SourceMgr.h"
50 #include "llvm/Support/raw_ostream.h"
51 #include "llvm/TargetParser/SubtargetFeature.h"
52 #include "llvm/TargetParser/Triple.h"
53 #include <algorithm>
54 #include <cassert>
55 #include <cstdint>
56 #include <memory>
57 #include <string>
58 #include <utility>
59 
60 using namespace llvm;
61 
62 #define DEBUG_TYPE "mips-asm-parser"
63 
64 namespace llvm {
65 
66 class MCInstrInfo;
67 
68 } // end namespace llvm
69 
70 extern cl::opt<bool> EmitJalrReloc;
71 
72 namespace {
73 
74 class MipsAssemblerOptions {
75 public:
MipsAssemblerOptions(const FeatureBitset & Features_)76   MipsAssemblerOptions(const FeatureBitset &Features_) : Features(Features_) {}
77 
MipsAssemblerOptions(const MipsAssemblerOptions * Opts)78   MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
79     ATReg = Opts->getATRegIndex();
80     Reorder = Opts->isReorder();
81     Macro = Opts->isMacro();
82     Features = Opts->getFeatures();
83   }
84 
getATRegIndex() const85   unsigned getATRegIndex() const { return ATReg; }
setATRegIndex(unsigned Reg)86   bool setATRegIndex(unsigned Reg) {
87     if (Reg > 31)
88       return false;
89 
90     ATReg = Reg;
91     return true;
92   }
93 
isReorder() const94   bool isReorder() const { return Reorder; }
setReorder()95   void setReorder() { Reorder = true; }
setNoReorder()96   void setNoReorder() { Reorder = false; }
97 
isMacro() const98   bool isMacro() const { return Macro; }
setMacro()99   void setMacro() { Macro = true; }
setNoMacro()100   void setNoMacro() { Macro = false; }
101 
getFeatures() const102   const FeatureBitset &getFeatures() const { return Features; }
setFeatures(const FeatureBitset & Features_)103   void setFeatures(const FeatureBitset &Features_) { Features = Features_; }
104 
105   // Set of features that are either architecture features or referenced
106   // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
107   // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
108   // The reason we need this mask is explained in the selectArch function.
109   // FIXME: Ideally we would like TableGen to generate this information.
110   static const FeatureBitset AllArchRelatedMask;
111 
112 private:
113   unsigned ATReg = 1;
114   bool Reorder = true;
115   bool Macro = true;
116   FeatureBitset Features;
117 };
118 
119 } // end anonymous namespace
120 
121 const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
122     Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
123     Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
124     Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
125     Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
126     Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
127     Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
128     Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
129     Mips::FeatureCnMipsP, Mips::FeatureFP64Bit, Mips::FeatureGP64Bit,
130     Mips::FeatureNaN2008
131 };
132 
133 namespace {
134 
135 class MipsAsmParser : public MCTargetAsmParser {
getTargetStreamer()136   MipsTargetStreamer &getTargetStreamer() {
137     assert(getParser().getStreamer().getTargetStreamer() &&
138            "do not have a target streamer");
139     MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
140     return static_cast<MipsTargetStreamer &>(TS);
141   }
142 
143   MipsABIInfo ABI;
144   SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
145   MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
146                        // nullptr, which indicates that no function is currently
147                        // selected. This usually happens after an '.end func'
148                        // directive.
149   bool IsLittleEndian;
150   bool IsPicEnabled;
151   bool IsCpRestoreSet;
152   bool CurForbiddenSlotAttr;
153   int CpRestoreOffset;
154   unsigned GPReg;
155   unsigned CpSaveLocation;
156   /// If true, then CpSaveLocation is a register, otherwise it's an offset.
157   bool     CpSaveLocationIsRegister;
158 
159   // Map of register aliases created via the .set directive.
160   StringMap<AsmToken> RegisterSets;
161 
162   // Print a warning along with its fix-it message at the given range.
163   void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
164                              SMRange Range, bool ShowColors = true);
165 
166   void ConvertXWPOperands(MCInst &Inst, const OperandVector &Operands);
167 
168 #define GET_ASSEMBLER_HEADER
169 #include "MipsGenAsmMatcher.inc"
170 
171   unsigned
172   checkEarlyTargetMatchPredicate(MCInst &Inst,
173                                  const OperandVector &Operands) override;
174   unsigned checkTargetMatchPredicate(MCInst &Inst) override;
175 
176   bool matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
177                                OperandVector &Operands, MCStreamer &Out,
178                                uint64_t &ErrorInfo,
179                                bool MatchingInlineAsm) override;
180 
181   /// Parse a register as used in CFI directives
182   bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) override;
183   ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
184                                SMLoc &EndLoc) override;
185 
186   bool parseParenSuffix(StringRef Name, OperandVector &Operands);
187 
188   bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
189 
190   bool mnemonicIsValid(StringRef Mnemonic, unsigned VariantID);
191 
192   bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
193                         SMLoc NameLoc, OperandVector &Operands) override;
194 
195   bool ParseDirective(AsmToken DirectiveID) override;
196 
197   ParseStatus parseMemOperand(OperandVector &Operands);
198   ParseStatus matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
199                                                 StringRef Identifier, SMLoc S);
200   ParseStatus matchAnyRegisterWithoutDollar(OperandVector &Operands,
201                                             const AsmToken &Token, SMLoc S);
202   ParseStatus matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
203   ParseStatus parseAnyRegister(OperandVector &Operands);
204   ParseStatus parseImm(OperandVector &Operands);
205   ParseStatus parseJumpTarget(OperandVector &Operands);
206   ParseStatus parseInvNum(OperandVector &Operands);
207   ParseStatus parseRegisterList(OperandVector &Operands);
208   const MCExpr *parseRelocExpr();
209 
210   bool searchSymbolAlias(OperandVector &Operands);
211 
212   bool parseOperand(OperandVector &, StringRef Mnemonic);
213 
214   enum MacroExpanderResultTy {
215     MER_NotAMacro,
216     MER_Success,
217     MER_Fail,
218   };
219 
220   // Expands assembly pseudo instructions.
221   MacroExpanderResultTy tryExpandInstruction(MCInst &Inst, SMLoc IDLoc,
222                                              MCStreamer &Out,
223                                              const MCSubtargetInfo *STI);
224 
225   bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
226                          const MCSubtargetInfo *STI);
227 
228   bool loadImmediate(int64_t ImmValue, MCRegister DstReg, MCRegister SrcReg,
229                      bool Is32BitImm, bool IsAddress, SMLoc IDLoc,
230                      MCStreamer &Out, const MCSubtargetInfo *STI);
231 
232   bool loadAndAddSymbolAddress(const MCExpr *SymExpr, MCRegister DstReg,
233                                MCRegister SrcReg, bool Is32BitSym, SMLoc IDLoc,
234                                MCStreamer &Out, const MCSubtargetInfo *STI);
235 
236   bool emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc, MCSymbol *Sym);
237 
238   bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
239                      MCStreamer &Out, const MCSubtargetInfo *STI);
240 
241   bool expandLoadSingleImmToGPR(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
242                                 const MCSubtargetInfo *STI);
243   bool expandLoadSingleImmToFPR(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
244                                 const MCSubtargetInfo *STI);
245   bool expandLoadDoubleImmToGPR(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
246                                 const MCSubtargetInfo *STI);
247   bool expandLoadDoubleImmToFPR(MCInst &Inst, bool Is64FPU, SMLoc IDLoc,
248                                 MCStreamer &Out, const MCSubtargetInfo *STI);
249 
250   bool expandLoadAddress(MCRegister DstReg, MCRegister BaseReg,
251                          const MCOperand &Offset, bool Is32BitAddress,
252                          SMLoc IDLoc, MCStreamer &Out,
253                          const MCSubtargetInfo *STI);
254 
255   bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
256                                   const MCSubtargetInfo *STI);
257 
258   void expandMem16Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
259                        const MCSubtargetInfo *STI, bool IsLoad);
260   void expandMem9Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
261                       const MCSubtargetInfo *STI, bool IsLoad);
262 
263   bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
264                                const MCSubtargetInfo *STI);
265 
266   bool expandAliasImmediate(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
267                             const MCSubtargetInfo *STI);
268 
269   bool expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
270                        const MCSubtargetInfo *STI);
271 
272   bool expandCondBranches(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
273                           const MCSubtargetInfo *STI);
274 
275   bool expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
276                     const MCSubtargetInfo *STI, const bool IsMips64,
277                     const bool Signed);
278 
279   bool expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU, SMLoc IDLoc,
280                    MCStreamer &Out, const MCSubtargetInfo *STI);
281 
282   bool expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc, MCStreamer &Out,
283                  const MCSubtargetInfo *STI);
284 
285   bool expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
286                  const MCSubtargetInfo *STI);
287 
288   bool expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
289                  const MCSubtargetInfo *STI);
290 
291   bool expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
292                  const MCSubtargetInfo *STI);
293 
294   bool expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
295                     const MCSubtargetInfo *STI);
296 
297   bool expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
298                     const MCSubtargetInfo *STI);
299 
300   bool expandSle(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
301                  const MCSubtargetInfo *STI);
302 
303   bool expandSleImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
304                     const MCSubtargetInfo *STI);
305 
306   bool expandRotation(MCInst &Inst, SMLoc IDLoc,
307                       MCStreamer &Out, const MCSubtargetInfo *STI);
308   bool expandRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
309                          const MCSubtargetInfo *STI);
310   bool expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
311                        const MCSubtargetInfo *STI);
312   bool expandDRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
313                           const MCSubtargetInfo *STI);
314 
315   bool expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
316                  const MCSubtargetInfo *STI);
317 
318   bool expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
319                     const MCSubtargetInfo *STI);
320 
321   bool expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
322                   const MCSubtargetInfo *STI);
323 
324   bool expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
325                    const MCSubtargetInfo *STI);
326 
327   bool expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
328                        const MCSubtargetInfo *STI);
329 
330   bool expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
331                              const MCSubtargetInfo *STI, bool IsLoad);
332 
333   bool expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
334                            const MCSubtargetInfo *STI);
335 
336   bool expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
337                  const MCSubtargetInfo *STI);
338 
339   bool expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
340                   const MCSubtargetInfo *STI);
341 
342   bool expandSne(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
343                  const MCSubtargetInfo *STI);
344 
345   bool expandSneI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
346                   const MCSubtargetInfo *STI);
347 
348   bool expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
349                        const MCSubtargetInfo *STI);
350 
351   bool expandSaaAddr(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
352                      const MCSubtargetInfo *STI);
353 
354   bool reportParseError(const Twine &ErrorMsg);
355   bool reportParseError(SMLoc Loc, const Twine &ErrorMsg);
356 
357   bool parseSetMips0Directive();
358   bool parseSetArchDirective();
359   bool parseSetFeature(uint64_t Feature);
360   bool isPicAndNotNxxAbi(); // Used by .cpload, .cprestore, and .cpsetup.
361   bool parseDirectiveCpAdd(SMLoc Loc);
362   bool parseDirectiveCpLoad(SMLoc Loc);
363   bool parseDirectiveCpLocal(SMLoc Loc);
364   bool parseDirectiveCpRestore(SMLoc Loc);
365   bool parseDirectiveCPSetup();
366   bool parseDirectiveCPReturn();
367   bool parseDirectiveNaN();
368   bool parseDirectiveSet();
369   bool parseDirectiveOption();
370   bool parseInsnDirective();
371   bool parseRSectionDirective(StringRef Section);
372   bool parseSSectionDirective(StringRef Section, unsigned Type);
373 
374   bool parseSetAtDirective();
375   bool parseSetNoAtDirective();
376   bool parseSetMacroDirective();
377   bool parseSetNoMacroDirective();
378   bool parseSetMsaDirective();
379   bool parseSetNoMsaDirective();
380   bool parseSetNoDspDirective();
381   bool parseSetNoMips3DDirective();
382   bool parseSetReorderDirective();
383   bool parseSetNoReorderDirective();
384   bool parseSetMips16Directive();
385   bool parseSetNoMips16Directive();
386   bool parseSetFpDirective();
387   bool parseSetOddSPRegDirective();
388   bool parseSetNoOddSPRegDirective();
389   bool parseSetPopDirective();
390   bool parseSetPushDirective();
391   bool parseSetSoftFloatDirective();
392   bool parseSetHardFloatDirective();
393   bool parseSetMtDirective();
394   bool parseSetNoMtDirective();
395   bool parseSetNoCRCDirective();
396   bool parseSetNoVirtDirective();
397   bool parseSetNoGINVDirective();
398 
399   bool parseSetAssignment();
400 
401   bool parseDirectiveGpWord();
402   bool parseDirectiveGpDWord();
403   bool parseDirectiveDtpRelWord();
404   bool parseDirectiveDtpRelDWord();
405   bool parseDirectiveTpRelWord();
406   bool parseDirectiveTpRelDWord();
407   bool parseDirectiveModule();
408   bool parseDirectiveModuleFP();
409   bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
410                        StringRef Directive);
411 
412   bool parseInternalDirectiveReallowModule();
413 
414   bool eatComma(StringRef ErrorStr);
415 
416   int matchCPURegisterName(StringRef Symbol);
417 
418   int matchHWRegsRegisterName(StringRef Symbol);
419 
420   int matchFPURegisterName(StringRef Name);
421 
422   int matchFCCRegisterName(StringRef Name);
423 
424   int matchACRegisterName(StringRef Name);
425 
426   int matchMSA128RegisterName(StringRef Name);
427 
428   int matchMSA128CtrlRegisterName(StringRef Name);
429 
430   MCRegister getReg(int RC, int RegNo);
431 
432   /// Returns the internal register number for the current AT. Also checks if
433   /// the current AT is unavailable (set to $0) and gives an error if it is.
434   /// This should be used in pseudo-instruction expansions which need AT.
435   MCRegister getATReg(SMLoc Loc);
436 
437   bool canUseATReg();
438 
439   bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
440                           const MCSubtargetInfo *STI);
441 
442   // Helper function that checks if the value of a vector index is within the
443   // boundaries of accepted values for each RegisterKind
444   // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
445   bool validateMSAIndex(int Val, int RegKind);
446 
447   // Selects a new architecture by updating the FeatureBits with the necessary
448   // info including implied dependencies.
449   // Internally, it clears all the feature bits related to *any* architecture
450   // and selects the new one using the ToggleFeature functionality of the
451   // MCSubtargetInfo object that handles implied dependencies. The reason we
452   // clear all the arch related bits manually is because ToggleFeature only
453   // clears the features that imply the feature being cleared and not the
454   // features implied by the feature being cleared. This is easier to see
455   // with an example:
456   //  --------------------------------------------------
457   // | Feature         | Implies                        |
458   // | -------------------------------------------------|
459   // | FeatureMips1    | None                           |
460   // | FeatureMips2    | FeatureMips1                   |
461   // | FeatureMips3    | FeatureMips2 | FeatureMipsGP64 |
462   // | FeatureMips4    | FeatureMips3                   |
463   // | ...             |                                |
464   //  --------------------------------------------------
465   //
466   // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
467   // FeatureMipsGP64 | FeatureMips1)
468   // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
selectArch(StringRef ArchFeature)469   void selectArch(StringRef ArchFeature) {
470     MCSubtargetInfo &STI = copySTI();
471     FeatureBitset FeatureBits = STI.getFeatureBits();
472     FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
473     STI.setFeatureBits(FeatureBits);
474     setAvailableFeatures(
475         ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
476     AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
477   }
478 
setFeatureBits(uint64_t Feature,StringRef FeatureString)479   void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
480     if (!(getSTI().hasFeature(Feature))) {
481       MCSubtargetInfo &STI = copySTI();
482       setAvailableFeatures(
483           ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
484       AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
485     }
486   }
487 
clearFeatureBits(uint64_t Feature,StringRef FeatureString)488   void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
489     if (getSTI().hasFeature(Feature)) {
490       MCSubtargetInfo &STI = copySTI();
491       setAvailableFeatures(
492           ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
493       AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
494     }
495   }
496 
setModuleFeatureBits(uint64_t Feature,StringRef FeatureString)497   void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
498     setFeatureBits(Feature, FeatureString);
499     AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
500   }
501 
clearModuleFeatureBits(uint64_t Feature,StringRef FeatureString)502   void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
503     clearFeatureBits(Feature, FeatureString);
504     AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
505   }
506 
507 public:
508   enum MipsMatchResultTy {
509     Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY,
510     Match_RequiresDifferentOperands,
511     Match_RequiresNoZeroRegister,
512     Match_RequiresSameSrcAndDst,
513     Match_NoFCCRegisterForCurrentISA,
514     Match_NonZeroOperandForSync,
515     Match_NonZeroOperandForMTCX,
516     Match_RequiresPosSizeRange0_32,
517     Match_RequiresPosSizeRange33_64,
518     Match_RequiresPosSizeUImm6,
519 #define GET_OPERAND_DIAGNOSTIC_TYPES
520 #include "MipsGenAsmMatcher.inc"
521 #undef GET_OPERAND_DIAGNOSTIC_TYPES
522   };
523 
MipsAsmParser(const MCSubtargetInfo & sti,MCAsmParser & parser,const MCInstrInfo & MII,const MCTargetOptions & Options)524   MipsAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
525                 const MCInstrInfo &MII, const MCTargetOptions &Options)
526       : MCTargetAsmParser(Options, sti, MII),
527         ABI(MipsABIInfo::computeTargetABI(sti.getTargetTriple(), sti.getCPU(),
528                                           Options)) {
529     MCAsmParserExtension::Initialize(parser);
530 
531     parser.addAliasForDirective(".asciiz", ".asciz");
532     parser.addAliasForDirective(".hword", ".2byte");
533     parser.addAliasForDirective(".word", ".4byte");
534     parser.addAliasForDirective(".dword", ".8byte");
535 
536     // Initialize the set of available features.
537     setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
538 
539     // Remember the initial assembler options. The user can not modify these.
540     AssemblerOptions.push_back(
541         std::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
542 
543     // Create an assembler options environment for the user to modify.
544     AssemblerOptions.push_back(
545         std::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
546 
547     getTargetStreamer().updateABIInfo(*this);
548 
549     if (!isABI_O32() && !useOddSPReg() != 0)
550       report_fatal_error("-mno-odd-spreg requires the O32 ABI");
551 
552     CurrentFn = nullptr;
553 
554     CurForbiddenSlotAttr = false;
555     IsPicEnabled = getContext().getObjectFileInfo()->isPositionIndependent();
556 
557     IsCpRestoreSet = false;
558     CpRestoreOffset = -1;
559     GPReg = ABI.GetGlobalPtr();
560 
561     const Triple &TheTriple = sti.getTargetTriple();
562     IsLittleEndian = TheTriple.isLittleEndian();
563 
564     if (getSTI().getCPU() == "mips64r6" && inMicroMipsMode())
565       report_fatal_error("microMIPS64R6 is not supported", false);
566 
567     if (!isABI_O32() && inMicroMipsMode())
568       report_fatal_error("microMIPS64 is not supported", false);
569   }
570 
571   /// True if all of $fcc0 - $fcc7 exist for the current ISA.
hasEightFccRegisters() const572   bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
573 
isGP64bit() const574   bool isGP64bit() const {
575     return getSTI().hasFeature(Mips::FeatureGP64Bit);
576   }
577 
isFP64bit() const578   bool isFP64bit() const {
579     return getSTI().hasFeature(Mips::FeatureFP64Bit);
580   }
581 
isJalrRelocAvailable(const MCExpr * JalExpr)582   bool isJalrRelocAvailable(const MCExpr *JalExpr) {
583     if (!EmitJalrReloc)
584       return false;
585     MCValue Res;
586     if (!JalExpr->evaluateAsRelocatable(Res, nullptr))
587       return false;
588     if (Res.getSubSym())
589       return false;
590     if (Res.getConstant() != 0)
591       return ABI.IsN32() || ABI.IsN64();
592     return true;
593   }
594 
getABI() const595   const MipsABIInfo &getABI() const { return ABI; }
isABI_N32() const596   bool isABI_N32() const { return ABI.IsN32(); }
isABI_N64() const597   bool isABI_N64() const { return ABI.IsN64(); }
isABI_O32() const598   bool isABI_O32() const { return ABI.IsO32(); }
isABI_FPXX() const599   bool isABI_FPXX() const {
600     return getSTI().hasFeature(Mips::FeatureFPXX);
601   }
602 
useOddSPReg() const603   bool useOddSPReg() const {
604     return !(getSTI().hasFeature(Mips::FeatureNoOddSPReg));
605   }
606 
inMicroMipsMode() const607   bool inMicroMipsMode() const {
608     return getSTI().hasFeature(Mips::FeatureMicroMips);
609   }
610 
hasMips1() const611   bool hasMips1() const {
612     return getSTI().hasFeature(Mips::FeatureMips1);
613   }
614 
hasMips2() const615   bool hasMips2() const {
616     return getSTI().hasFeature(Mips::FeatureMips2);
617   }
618 
hasMips3() const619   bool hasMips3() const {
620     return getSTI().hasFeature(Mips::FeatureMips3);
621   }
622 
hasMips4() const623   bool hasMips4() const {
624     return getSTI().hasFeature(Mips::FeatureMips4);
625   }
626 
hasMips5() const627   bool hasMips5() const {
628     return getSTI().hasFeature(Mips::FeatureMips5);
629   }
630 
hasMips32() const631   bool hasMips32() const {
632     return getSTI().hasFeature(Mips::FeatureMips32);
633   }
634 
hasMips64() const635   bool hasMips64() const {
636     return getSTI().hasFeature(Mips::FeatureMips64);
637   }
638 
hasMips32r2() const639   bool hasMips32r2() const {
640     return getSTI().hasFeature(Mips::FeatureMips32r2);
641   }
642 
hasMips64r2() const643   bool hasMips64r2() const {
644     return getSTI().hasFeature(Mips::FeatureMips64r2);
645   }
646 
hasMips32r3() const647   bool hasMips32r3() const {
648     return (getSTI().hasFeature(Mips::FeatureMips32r3));
649   }
650 
hasMips64r3() const651   bool hasMips64r3() const {
652     return (getSTI().hasFeature(Mips::FeatureMips64r3));
653   }
654 
hasMips32r5() const655   bool hasMips32r5() const {
656     return (getSTI().hasFeature(Mips::FeatureMips32r5));
657   }
658 
hasMips64r5() const659   bool hasMips64r5() const {
660     return (getSTI().hasFeature(Mips::FeatureMips64r5));
661   }
662 
hasMips32r6() const663   bool hasMips32r6() const {
664     return getSTI().hasFeature(Mips::FeatureMips32r6);
665   }
666 
hasMips64r6() const667   bool hasMips64r6() const {
668     return getSTI().hasFeature(Mips::FeatureMips64r6);
669   }
670 
hasDSP() const671   bool hasDSP() const {
672     return getSTI().hasFeature(Mips::FeatureDSP);
673   }
674 
hasDSPR2() const675   bool hasDSPR2() const {
676     return getSTI().hasFeature(Mips::FeatureDSPR2);
677   }
678 
hasDSPR3() const679   bool hasDSPR3() const {
680     return getSTI().hasFeature(Mips::FeatureDSPR3);
681   }
682 
hasMSA() const683   bool hasMSA() const {
684     return getSTI().hasFeature(Mips::FeatureMSA);
685   }
686 
hasCnMips() const687   bool hasCnMips() const {
688     return (getSTI().hasFeature(Mips::FeatureCnMips));
689   }
690 
hasCnMipsP() const691   bool hasCnMipsP() const {
692     return (getSTI().hasFeature(Mips::FeatureCnMipsP));
693   }
694 
inPicMode()695   bool inPicMode() {
696     return IsPicEnabled;
697   }
698 
inMips16Mode() const699   bool inMips16Mode() const {
700     return getSTI().hasFeature(Mips::FeatureMips16);
701   }
702 
useTraps() const703   bool useTraps() const {
704     return getSTI().hasFeature(Mips::FeatureUseTCCInDIV);
705   }
706 
useSoftFloat() const707   bool useSoftFloat() const {
708     return getSTI().hasFeature(Mips::FeatureSoftFloat);
709   }
hasMT() const710   bool hasMT() const {
711     return getSTI().hasFeature(Mips::FeatureMT);
712   }
713 
hasCRC() const714   bool hasCRC() const {
715     return getSTI().hasFeature(Mips::FeatureCRC);
716   }
717 
hasVirt() const718   bool hasVirt() const {
719     return getSTI().hasFeature(Mips::FeatureVirt);
720   }
721 
hasGINV() const722   bool hasGINV() const {
723     return getSTI().hasFeature(Mips::FeatureGINV);
724   }
725 
hasForbiddenSlot(const MCInstrDesc & MCID) const726   bool hasForbiddenSlot(const MCInstrDesc &MCID) const {
727     return !inMicroMipsMode() && (MCID.TSFlags & MipsII::HasForbiddenSlot);
728   }
729 
SafeInForbiddenSlot(const MCInstrDesc & MCID) const730   bool SafeInForbiddenSlot(const MCInstrDesc &MCID) const {
731     return !(MCID.TSFlags & MipsII::IsCTI);
732   }
733 
734   void onEndOfFile() override;
735 
736   /// Warn if RegIndex is the same as the current AT.
737   void warnIfRegIndexIsAT(MCRegister RegIndex, SMLoc Loc);
738 
739   void warnIfNoMacro(SMLoc Loc);
740 
isLittle() const741   bool isLittle() const { return IsLittleEndian; }
742 
743   bool areEqualRegs(const MCParsedAsmOperand &Op1,
744                     const MCParsedAsmOperand &Op2) const override;
745 };
746 
747 /// MipsOperand - Instances of this class represent a parsed Mips machine
748 /// instruction.
749 class MipsOperand : public MCParsedAsmOperand {
750 public:
751   /// Broad categories of register classes
752   /// The exact class is finalized by the render method.
753   enum RegKind {
754     RegKind_GPR = 1,      /// GPR32 and GPR64 (depending on isGP64bit())
755     RegKind_FGR = 2,      /// FGR32, FGR64, AFGR64 (depending on context and
756                           /// isFP64bit())
757     RegKind_FCC = 4,      /// FCC
758     RegKind_MSA128 = 8,   /// MSA128[BHWD] (makes no difference which)
759     RegKind_MSACtrl = 16, /// MSA control registers
760     RegKind_COP2 = 32,    /// COP2
761     RegKind_ACC = 64,     /// HI32DSP, LO32DSP, and ACC64DSP (depending on
762                           /// context).
763     RegKind_CCR = 128,    /// CCR
764     RegKind_HWRegs = 256, /// HWRegs
765     RegKind_COP3 = 512,   /// COP3
766     RegKind_COP0 = 1024,  /// COP0
767     /// Potentially any (e.g. $1)
768     RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
769                       RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
770                       RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
771   };
772 
773 private:
774   enum KindTy {
775     k_Immediate,     /// An immediate (possibly involving symbol references)
776     k_Memory,        /// Base + Offset Memory Address
777     k_RegisterIndex, /// A register index in one or more RegKind.
778     k_Token,         /// A simple token
779     k_RegList,       /// A physical register list
780   } Kind;
781 
782 public:
MipsOperand(KindTy K,MipsAsmParser & Parser)783   MipsOperand(KindTy K, MipsAsmParser &Parser) : Kind(K), AsmParser(Parser) {}
784 
~MipsOperand()785   ~MipsOperand() override {
786     switch (Kind) {
787     case k_Memory:
788       delete Mem.Base;
789       break;
790     case k_RegList:
791       delete RegList.List;
792       break;
793     case k_Immediate:
794     case k_RegisterIndex:
795     case k_Token:
796       break;
797     }
798   }
799 
800 private:
801   /// For diagnostics, and checking the assembler temporary
802   MipsAsmParser &AsmParser;
803 
804   struct Token {
805     const char *Data;
806     unsigned Length;
807   };
808 
809   struct RegIdxOp {
810     unsigned Index; /// Index into the register class
811     RegKind Kind;   /// Bitfield of the kinds it could possibly be
812     struct Token Tok; /// The input token this operand originated from.
813     const MCRegisterInfo *RegInfo;
814   };
815 
816   struct ImmOp {
817     const MCExpr *Val;
818   };
819 
820   struct MemOp {
821     MipsOperand *Base;
822     const MCExpr *Off;
823   };
824 
825   struct RegListOp {
826     SmallVector<unsigned, 10> *List;
827   };
828 
829   union {
830     struct Token Tok;
831     struct RegIdxOp RegIdx;
832     struct ImmOp Imm;
833     struct MemOp Mem;
834     struct RegListOp RegList;
835   };
836 
837   SMLoc StartLoc, EndLoc;
838 
839   /// Internal constructor for register kinds
CreateReg(unsigned Index,StringRef Str,RegKind RegKind,const MCRegisterInfo * RegInfo,SMLoc S,SMLoc E,MipsAsmParser & Parser)840   static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, StringRef Str,
841                                                 RegKind RegKind,
842                                                 const MCRegisterInfo *RegInfo,
843                                                 SMLoc S, SMLoc E,
844                                                 MipsAsmParser &Parser) {
845     auto Op = std::make_unique<MipsOperand>(k_RegisterIndex, Parser);
846     Op->RegIdx.Index = Index;
847     Op->RegIdx.RegInfo = RegInfo;
848     Op->RegIdx.Kind = RegKind;
849     Op->RegIdx.Tok.Data = Str.data();
850     Op->RegIdx.Tok.Length = Str.size();
851     Op->StartLoc = S;
852     Op->EndLoc = E;
853     return Op;
854   }
855 
856 public:
857   /// Coerce the register to GPR32 and return the real register for the current
858   /// target.
getGPR32Reg() const859   MCRegister getGPR32Reg() const {
860     assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
861     AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
862     unsigned ClassID = Mips::GPR32RegClassID;
863     return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
864   }
865 
866   /// Coerce the register to GPR32 and return the real register for the current
867   /// target.
getGPRMM16Reg() const868   MCRegister getGPRMM16Reg() const {
869     assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
870     unsigned ClassID = Mips::GPR32RegClassID;
871     return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
872   }
873 
874   /// Coerce the register to GPR64 and return the real register for the current
875   /// target.
getGPR64Reg() const876   MCRegister getGPR64Reg() const {
877     assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
878     unsigned ClassID = Mips::GPR64RegClassID;
879     return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
880   }
881 
882 private:
883   /// Coerce the register to AFGR64 and return the real register for the current
884   /// target.
getAFGR64Reg() const885   MCRegister getAFGR64Reg() const {
886     assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
887     if (RegIdx.Index % 2 != 0)
888       AsmParser.Warning(StartLoc, "Float register should be even.");
889     return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
890         .getRegister(RegIdx.Index / 2);
891   }
892 
893   /// Coerce the register to FGR64 and return the real register for the current
894   /// target.
getFGR64Reg() const895   MCRegister getFGR64Reg() const {
896     assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
897     return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
898         .getRegister(RegIdx.Index);
899   }
900 
901   /// Coerce the register to FGR32 and return the real register for the current
902   /// target.
getFGR32Reg() const903   MCRegister getFGR32Reg() const {
904     assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
905     return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
906         .getRegister(RegIdx.Index);
907   }
908 
909   /// Coerce the register to FCC and return the real register for the current
910   /// target.
getFCCReg() const911   MCRegister getFCCReg() const {
912     assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
913     return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
914         .getRegister(RegIdx.Index);
915   }
916 
917   /// Coerce the register to MSA128 and return the real register for the current
918   /// target.
getMSA128Reg() const919   MCRegister getMSA128Reg() const {
920     assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
921     // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
922     // identical
923     unsigned ClassID = Mips::MSA128BRegClassID;
924     return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
925   }
926 
927   /// Coerce the register to MSACtrl and return the real register for the
928   /// current target.
getMSACtrlReg() const929   MCRegister getMSACtrlReg() const {
930     assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
931     unsigned ClassID = Mips::MSACtrlRegClassID;
932     return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
933   }
934 
935   /// Coerce the register to COP0 and return the real register for the
936   /// current target.
getCOP0Reg() const937   MCRegister getCOP0Reg() const {
938     assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) && "Invalid access!");
939     unsigned ClassID = Mips::COP0RegClassID;
940     return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
941   }
942 
943   /// Coerce the register to COP2 and return the real register for the
944   /// current target.
getCOP2Reg() const945   MCRegister getCOP2Reg() const {
946     assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
947     unsigned ClassID = Mips::COP2RegClassID;
948     return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
949   }
950 
951   /// Coerce the register to COP3 and return the real register for the
952   /// current target.
getCOP3Reg() const953   MCRegister getCOP3Reg() const {
954     assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
955     unsigned ClassID = Mips::COP3RegClassID;
956     return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
957   }
958 
959   /// Coerce the register to ACC64DSP and return the real register for the
960   /// current target.
getACC64DSPReg() const961   MCRegister getACC64DSPReg() const {
962     assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
963     unsigned ClassID = Mips::ACC64DSPRegClassID;
964     return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
965   }
966 
967   /// Coerce the register to HI32DSP and return the real register for the
968   /// current target.
getHI32DSPReg() const969   MCRegister getHI32DSPReg() const {
970     assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
971     unsigned ClassID = Mips::HI32DSPRegClassID;
972     return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
973   }
974 
975   /// Coerce the register to LO32DSP and return the real register for the
976   /// current target.
getLO32DSPReg() const977   MCRegister getLO32DSPReg() const {
978     assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
979     unsigned ClassID = Mips::LO32DSPRegClassID;
980     return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
981   }
982 
983   /// Coerce the register to CCR and return the real register for the
984   /// current target.
getCCRReg() const985   MCRegister getCCRReg() const {
986     assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
987     unsigned ClassID = Mips::CCRRegClassID;
988     return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
989   }
990 
991   /// Coerce the register to HWRegs and return the real register for the
992   /// current target.
getHWRegsReg() const993   MCRegister getHWRegsReg() const {
994     assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
995     unsigned ClassID = Mips::HWRegsRegClassID;
996     return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
997   }
998 
999 public:
addExpr(MCInst & Inst,const MCExpr * Expr) const1000   void addExpr(MCInst &Inst, const MCExpr *Expr) const {
1001     // Add as immediate when possible.  Null MCExpr = 0.
1002     if (!Expr)
1003       Inst.addOperand(MCOperand::createImm(0));
1004     else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
1005       Inst.addOperand(MCOperand::createImm(CE->getValue()));
1006     else
1007       Inst.addOperand(MCOperand::createExpr(Expr));
1008   }
1009 
addRegOperands(MCInst & Inst,unsigned N) const1010   void addRegOperands(MCInst &Inst, unsigned N) const {
1011     llvm_unreachable("Use a custom parser instead");
1012   }
1013 
1014   /// Render the operand to an MCInst as a GPR32
1015   /// Asserts if the wrong number of operands are requested, or the operand
1016   /// is not a k_RegisterIndex compatible with RegKind_GPR
addGPR32ZeroAsmRegOperands(MCInst & Inst,unsigned N) const1017   void addGPR32ZeroAsmRegOperands(MCInst &Inst, unsigned N) const {
1018     assert(N == 1 && "Invalid number of operands!");
1019     Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
1020   }
1021 
addGPR32NonZeroAsmRegOperands(MCInst & Inst,unsigned N) const1022   void addGPR32NonZeroAsmRegOperands(MCInst &Inst, unsigned N) const {
1023     assert(N == 1 && "Invalid number of operands!");
1024     Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
1025   }
1026 
addGPR32AsmRegOperands(MCInst & Inst,unsigned N) const1027   void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1028     assert(N == 1 && "Invalid number of operands!");
1029     Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
1030   }
1031 
addGPRMM16AsmRegOperands(MCInst & Inst,unsigned N) const1032   void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
1033     assert(N == 1 && "Invalid number of operands!");
1034     Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1035   }
1036 
addGPRMM16AsmRegZeroOperands(MCInst & Inst,unsigned N) const1037   void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
1038     assert(N == 1 && "Invalid number of operands!");
1039     Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1040   }
1041 
addGPRMM16AsmRegMovePOperands(MCInst & Inst,unsigned N) const1042   void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
1043     assert(N == 1 && "Invalid number of operands!");
1044     Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1045   }
1046 
addGPRMM16AsmRegMovePPairFirstOperands(MCInst & Inst,unsigned N) const1047   void addGPRMM16AsmRegMovePPairFirstOperands(MCInst &Inst, unsigned N) const {
1048     assert(N == 1 && "Invalid number of operands!");
1049     Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1050   }
1051 
addGPRMM16AsmRegMovePPairSecondOperands(MCInst & Inst,unsigned N) const1052   void addGPRMM16AsmRegMovePPairSecondOperands(MCInst &Inst,
1053                                                unsigned N) const {
1054     assert(N == 1 && "Invalid number of operands!");
1055     Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1056   }
1057 
1058   /// Render the operand to an MCInst as a GPR64
1059   /// Asserts if the wrong number of operands are requested, or the operand
1060   /// is not a k_RegisterIndex compatible with RegKind_GPR
addGPR64AsmRegOperands(MCInst & Inst,unsigned N) const1061   void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1062     assert(N == 1 && "Invalid number of operands!");
1063     Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
1064   }
1065 
addAFGR64AsmRegOperands(MCInst & Inst,unsigned N) const1066   void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1067     assert(N == 1 && "Invalid number of operands!");
1068     Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
1069   }
1070 
addStrictlyAFGR64AsmRegOperands(MCInst & Inst,unsigned N) const1071   void addStrictlyAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1072     assert(N == 1 && "Invalid number of operands!");
1073     Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
1074   }
1075 
addStrictlyFGR64AsmRegOperands(MCInst & Inst,unsigned N) const1076   void addStrictlyFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1077     assert(N == 1 && "Invalid number of operands!");
1078     Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
1079   }
1080 
addFGR64AsmRegOperands(MCInst & Inst,unsigned N) const1081   void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1082     assert(N == 1 && "Invalid number of operands!");
1083     Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
1084   }
1085 
addFGR32AsmRegOperands(MCInst & Inst,unsigned N) const1086   void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1087     assert(N == 1 && "Invalid number of operands!");
1088     Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
1089     // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
1090     // FIXME: This should propagate failure up to parseStatement.
1091     if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1092       AsmParser.getParser().printError(
1093           StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
1094                     "registers");
1095   }
1096 
addStrictlyFGR32AsmRegOperands(MCInst & Inst,unsigned N) const1097   void addStrictlyFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1098     assert(N == 1 && "Invalid number of operands!");
1099     Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
1100     // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
1101     if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1102       AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
1103                                 "registers");
1104   }
1105 
addFCCAsmRegOperands(MCInst & Inst,unsigned N) const1106   void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
1107     assert(N == 1 && "Invalid number of operands!");
1108     Inst.addOperand(MCOperand::createReg(getFCCReg()));
1109   }
1110 
addMSA128AsmRegOperands(MCInst & Inst,unsigned N) const1111   void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
1112     assert(N == 1 && "Invalid number of operands!");
1113     Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
1114   }
1115 
addMSACtrlAsmRegOperands(MCInst & Inst,unsigned N) const1116   void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
1117     assert(N == 1 && "Invalid number of operands!");
1118     Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
1119   }
1120 
addCOP0AsmRegOperands(MCInst & Inst,unsigned N) const1121   void addCOP0AsmRegOperands(MCInst &Inst, unsigned N) const {
1122     assert(N == 1 && "Invalid number of operands!");
1123     Inst.addOperand(MCOperand::createReg(getCOP0Reg()));
1124   }
1125 
addCOP2AsmRegOperands(MCInst & Inst,unsigned N) const1126   void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
1127     assert(N == 1 && "Invalid number of operands!");
1128     Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
1129   }
1130 
addCOP3AsmRegOperands(MCInst & Inst,unsigned N) const1131   void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
1132     assert(N == 1 && "Invalid number of operands!");
1133     Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
1134   }
1135 
addACC64DSPAsmRegOperands(MCInst & Inst,unsigned N) const1136   void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1137     assert(N == 1 && "Invalid number of operands!");
1138     Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
1139   }
1140 
addHI32DSPAsmRegOperands(MCInst & Inst,unsigned N) const1141   void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1142     assert(N == 1 && "Invalid number of operands!");
1143     Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
1144   }
1145 
addLO32DSPAsmRegOperands(MCInst & Inst,unsigned N) const1146   void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1147     assert(N == 1 && "Invalid number of operands!");
1148     Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
1149   }
1150 
addCCRAsmRegOperands(MCInst & Inst,unsigned N) const1151   void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
1152     assert(N == 1 && "Invalid number of operands!");
1153     Inst.addOperand(MCOperand::createReg(getCCRReg()));
1154   }
1155 
addHWRegsAsmRegOperands(MCInst & Inst,unsigned N) const1156   void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
1157     assert(N == 1 && "Invalid number of operands!");
1158     Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
1159   }
1160 
1161   template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
addConstantUImmOperands(MCInst & Inst,unsigned N) const1162   void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
1163     assert(N == 1 && "Invalid number of operands!");
1164     uint64_t Imm = getConstantImm() - Offset;
1165     Imm &= (1ULL << Bits) - 1;
1166     Imm += Offset;
1167     Imm += AdjustOffset;
1168     Inst.addOperand(MCOperand::createImm(Imm));
1169   }
1170 
1171   template <unsigned Bits>
addSImmOperands(MCInst & Inst,unsigned N) const1172   void addSImmOperands(MCInst &Inst, unsigned N) const {
1173     if (isImm() && !isConstantImm()) {
1174       addExpr(Inst, getImm());
1175       return;
1176     }
1177     addConstantSImmOperands<Bits, 0, 0>(Inst, N);
1178   }
1179 
1180   template <unsigned Bits>
addUImmOperands(MCInst & Inst,unsigned N) const1181   void addUImmOperands(MCInst &Inst, unsigned N) const {
1182     if (isImm() && !isConstantImm()) {
1183       addExpr(Inst, getImm());
1184       return;
1185     }
1186     addConstantUImmOperands<Bits, 0, 0>(Inst, N);
1187   }
1188 
1189   template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
addConstantSImmOperands(MCInst & Inst,unsigned N) const1190   void addConstantSImmOperands(MCInst &Inst, unsigned N) const {
1191     assert(N == 1 && "Invalid number of operands!");
1192     int64_t Imm = getConstantImm() - Offset;
1193     Imm = SignExtend64<Bits>(Imm);
1194     Imm += Offset;
1195     Imm += AdjustOffset;
1196     Inst.addOperand(MCOperand::createImm(Imm));
1197   }
1198 
addImmOperands(MCInst & Inst,unsigned N) const1199   void addImmOperands(MCInst &Inst, unsigned N) const {
1200     assert(N == 1 && "Invalid number of operands!");
1201     const MCExpr *Expr = getImm();
1202     addExpr(Inst, Expr);
1203   }
1204 
addMemOperands(MCInst & Inst,unsigned N) const1205   void addMemOperands(MCInst &Inst, unsigned N) const {
1206     assert(N == 2 && "Invalid number of operands!");
1207 
1208     Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit()
1209                                              ? getMemBase()->getGPR64Reg()
1210                                              : getMemBase()->getGPR32Reg()));
1211 
1212     const MCExpr *Expr = getMemOff();
1213     addExpr(Inst, Expr);
1214   }
1215 
addMicroMipsMemOperands(MCInst & Inst,unsigned N) const1216   void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
1217     assert(N == 2 && "Invalid number of operands!");
1218 
1219     Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
1220 
1221     const MCExpr *Expr = getMemOff();
1222     addExpr(Inst, Expr);
1223   }
1224 
addRegListOperands(MCInst & Inst,unsigned N) const1225   void addRegListOperands(MCInst &Inst, unsigned N) const {
1226     assert(N == 1 && "Invalid number of operands!");
1227 
1228     for (auto RegNo : getRegList())
1229       Inst.addOperand(MCOperand::createReg(RegNo));
1230   }
1231 
isReg() const1232   bool isReg() const override {
1233     // As a special case until we sort out the definition of div/divu, accept
1234     // $0/$zero here so that MCK_ZERO works correctly.
1235     return isGPRAsmReg() && RegIdx.Index == 0;
1236   }
1237 
isRegIdx() const1238   bool isRegIdx() const { return Kind == k_RegisterIndex; }
isImm() const1239   bool isImm() const override { return Kind == k_Immediate; }
1240 
isConstantImm() const1241   bool isConstantImm() const {
1242     int64_t Res;
1243     return isImm() && getImm()->evaluateAsAbsolute(Res);
1244   }
1245 
isConstantImmz() const1246   bool isConstantImmz() const {
1247     return isConstantImm() && getConstantImm() == 0;
1248   }
1249 
isConstantUImm() const1250   template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
1251     return isConstantImm() && isUInt<Bits>(getConstantImm() - Offset);
1252   }
1253 
isSImm() const1254   template <unsigned Bits> bool isSImm() const {
1255     if (!isImm())
1256       return false;
1257     int64_t Res;
1258     if (getImm()->evaluateAsAbsolute(Res))
1259       return isInt<Bits>(Res);
1260     // Allow conservatively if not a parse-time constant.
1261     return true;
1262   }
1263 
isUImm() const1264   template <unsigned Bits> bool isUImm() const {
1265     if (!isImm())
1266       return false;
1267     int64_t Res;
1268     if (getImm()->evaluateAsAbsolute(Res))
1269       return isUInt<Bits>(Res);
1270     // Allow conservatively if not a parse-time constant.
1271     return true;
1272   }
1273 
isAnyImm() const1274   template <unsigned Bits> bool isAnyImm() const {
1275     return isConstantImm() ? (isInt<Bits>(getConstantImm()) ||
1276                               isUInt<Bits>(getConstantImm()))
1277                            : isImm();
1278   }
1279 
isConstantSImm() const1280   template <unsigned Bits, int Offset = 0> bool isConstantSImm() const {
1281     return isConstantImm() && isInt<Bits>(getConstantImm() - Offset);
1282   }
1283 
isConstantUImmRange() const1284   template <unsigned Bottom, unsigned Top> bool isConstantUImmRange() const {
1285     return isConstantImm() && getConstantImm() >= Bottom &&
1286            getConstantImm() <= Top;
1287   }
1288 
isToken() const1289   bool isToken() const override {
1290     // Note: It's not possible to pretend that other operand kinds are tokens.
1291     // The matcher emitter checks tokens first.
1292     return Kind == k_Token;
1293   }
1294 
isMem() const1295   bool isMem() const override { return Kind == k_Memory; }
1296 
isConstantMemOff() const1297   bool isConstantMemOff() const {
1298     return isMem() && isa<MCConstantExpr>(getMemOff());
1299   }
1300 
1301   // Allow relocation operators.
1302   template <unsigned Bits, unsigned ShiftAmount = 0>
isMemWithSimmOffset() const1303   bool isMemWithSimmOffset() const {
1304     if (!isMem())
1305       return false;
1306     if (!getMemBase()->isGPRAsmReg())
1307       return false;
1308     if (isa<MCSpecifierExpr>(getMemOff()) ||
1309         (isConstantMemOff() &&
1310          isShiftedInt<Bits, ShiftAmount>(getConstantMemOff())))
1311       return true;
1312     MCValue Res;
1313     bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr);
1314     return IsReloc && isShiftedInt<Bits, ShiftAmount>(Res.getConstant());
1315   }
1316 
isMemWithPtrSizeOffset() const1317   bool isMemWithPtrSizeOffset() const {
1318     if (!isMem())
1319       return false;
1320     if (!getMemBase()->isGPRAsmReg())
1321       return false;
1322     const unsigned PtrBits = AsmParser.getABI().ArePtrs64bit() ? 64 : 32;
1323     if (isa<MCSpecifierExpr>(getMemOff()) ||
1324         (isConstantMemOff() && isIntN(PtrBits, getConstantMemOff())))
1325       return true;
1326     MCValue Res;
1327     bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr);
1328     return IsReloc && isIntN(PtrBits, Res.getConstant());
1329   }
1330 
isMemWithGRPMM16Base() const1331   bool isMemWithGRPMM16Base() const {
1332     return isMem() && getMemBase()->isMM16AsmReg();
1333   }
1334 
isMemWithUimmOffsetSP() const1335   template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
1336     return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1337       && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
1338   }
1339 
isMemWithUimmWordAlignedOffsetSP() const1340   template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
1341     return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1342       && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1343       && (getMemBase()->getGPR32Reg() == Mips::SP);
1344   }
1345 
isMemWithSimmWordAlignedOffsetGP() const1346   template <unsigned Bits> bool isMemWithSimmWordAlignedOffsetGP() const {
1347     return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
1348       && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1349       && (getMemBase()->getGPR32Reg() == Mips::GP);
1350   }
1351 
1352   template <unsigned Bits, unsigned ShiftLeftAmount>
isScaledUImm() const1353   bool isScaledUImm() const {
1354     return isConstantImm() &&
1355            isShiftedUInt<Bits, ShiftLeftAmount>(getConstantImm());
1356   }
1357 
1358   template <unsigned Bits, unsigned ShiftLeftAmount>
isScaledSImm() const1359   bool isScaledSImm() const {
1360     if (isConstantImm() &&
1361         isShiftedInt<Bits, ShiftLeftAmount>(getConstantImm()))
1362       return true;
1363     // Operand can also be a symbol or symbol plus
1364     // offset in case of relocations.
1365     if (Kind != k_Immediate)
1366       return false;
1367     MCValue Res;
1368     bool Success = getImm()->evaluateAsRelocatable(Res, nullptr);
1369     return Success && isShiftedInt<Bits, ShiftLeftAmount>(Res.getConstant());
1370   }
1371 
isRegList16() const1372   bool isRegList16() const {
1373     if (!isRegList())
1374       return false;
1375 
1376     int Size = RegList.List->size();
1377     if (Size < 2 || Size > 5)
1378       return false;
1379 
1380     unsigned R0 = RegList.List->front();
1381     unsigned R1 = RegList.List->back();
1382     if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1383           (R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1384       return false;
1385 
1386     int PrevReg = *RegList.List->begin();
1387     for (int i = 1; i < Size - 1; i++) {
1388       int Reg = (*(RegList.List))[i];
1389       if ( Reg != PrevReg + 1)
1390         return false;
1391       PrevReg = Reg;
1392     }
1393 
1394     return true;
1395   }
1396 
isInvNum() const1397   bool isInvNum() const { return Kind == k_Immediate; }
1398 
isLSAImm() const1399   bool isLSAImm() const {
1400     if (!isConstantImm())
1401       return false;
1402     int64_t Val = getConstantImm();
1403     return 1 <= Val && Val <= 4;
1404   }
1405 
isRegList() const1406   bool isRegList() const { return Kind == k_RegList; }
1407 
getToken() const1408   StringRef getToken() const {
1409     assert(Kind == k_Token && "Invalid access!");
1410     return StringRef(Tok.Data, Tok.Length);
1411   }
1412 
getReg() const1413   MCRegister getReg() const override {
1414     // As a special case until we sort out the definition of div/divu, accept
1415     // $0/$zero here so that MCK_ZERO works correctly.
1416     if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1417         RegIdx.Kind & RegKind_GPR)
1418       return getGPR32Reg(); // FIXME: GPR64 too
1419 
1420     llvm_unreachable("Invalid access!");
1421     return 0;
1422   }
1423 
getImm() const1424   const MCExpr *getImm() const {
1425     assert((Kind == k_Immediate) && "Invalid access!");
1426     return Imm.Val;
1427   }
1428 
getConstantImm() const1429   int64_t getConstantImm() const {
1430     const MCExpr *Val = getImm();
1431     int64_t Value = 0;
1432     (void)Val->evaluateAsAbsolute(Value);
1433     return Value;
1434   }
1435 
getMemBase() const1436   MipsOperand *getMemBase() const {
1437     assert((Kind == k_Memory) && "Invalid access!");
1438     return Mem.Base;
1439   }
1440 
getMemOff() const1441   const MCExpr *getMemOff() const {
1442     assert((Kind == k_Memory) && "Invalid access!");
1443     return Mem.Off;
1444   }
1445 
getConstantMemOff() const1446   int64_t getConstantMemOff() const {
1447     return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1448   }
1449 
getRegList() const1450   const SmallVectorImpl<unsigned> &getRegList() const {
1451     assert((Kind == k_RegList) && "Invalid access!");
1452     return *(RegList.List);
1453   }
1454 
CreateToken(StringRef Str,SMLoc S,MipsAsmParser & Parser)1455   static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1456                                                   MipsAsmParser &Parser) {
1457     auto Op = std::make_unique<MipsOperand>(k_Token, Parser);
1458     Op->Tok.Data = Str.data();
1459     Op->Tok.Length = Str.size();
1460     Op->StartLoc = S;
1461     Op->EndLoc = S;
1462     return Op;
1463   }
1464 
1465   /// Create a numeric register (e.g. $1). The exact register remains
1466   /// unresolved until an instruction successfully matches
1467   static std::unique_ptr<MipsOperand>
createNumericReg(unsigned Index,StringRef Str,const MCRegisterInfo * RegInfo,SMLoc S,SMLoc E,MipsAsmParser & Parser)1468   createNumericReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1469                    SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1470     LLVM_DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1471     return CreateReg(Index, Str, RegKind_Numeric, RegInfo, S, E, Parser);
1472   }
1473 
1474   /// Create a register that is definitely a GPR.
1475   /// This is typically only used for named registers such as $gp.
1476   static std::unique_ptr<MipsOperand>
createGPRReg(unsigned Index,StringRef Str,const MCRegisterInfo * RegInfo,SMLoc S,SMLoc E,MipsAsmParser & Parser)1477   createGPRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1478                SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1479     return CreateReg(Index, Str, RegKind_GPR, RegInfo, S, E, Parser);
1480   }
1481 
1482   /// Create a register that is definitely a FGR.
1483   /// This is typically only used for named registers such as $f0.
1484   static std::unique_ptr<MipsOperand>
createFGRReg(unsigned Index,StringRef Str,const MCRegisterInfo * RegInfo,SMLoc S,SMLoc E,MipsAsmParser & Parser)1485   createFGRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1486                SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1487     return CreateReg(Index, Str, RegKind_FGR, RegInfo, S, E, Parser);
1488   }
1489 
1490   /// Create a register that is definitely a HWReg.
1491   /// This is typically only used for named registers such as $hwr_cpunum.
1492   static std::unique_ptr<MipsOperand>
createHWRegsReg(unsigned Index,StringRef Str,const MCRegisterInfo * RegInfo,SMLoc S,SMLoc E,MipsAsmParser & Parser)1493   createHWRegsReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1494                   SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1495     return CreateReg(Index, Str, RegKind_HWRegs, RegInfo, S, E, Parser);
1496   }
1497 
1498   /// Create a register that is definitely an FCC.
1499   /// This is typically only used for named registers such as $fcc0.
1500   static std::unique_ptr<MipsOperand>
createFCCReg(unsigned Index,StringRef Str,const MCRegisterInfo * RegInfo,SMLoc S,SMLoc E,MipsAsmParser & Parser)1501   createFCCReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1502                SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1503     return CreateReg(Index, Str, RegKind_FCC, RegInfo, S, E, Parser);
1504   }
1505 
1506   /// Create a register that is definitely an ACC.
1507   /// This is typically only used for named registers such as $ac0.
1508   static std::unique_ptr<MipsOperand>
createACCReg(unsigned Index,StringRef Str,const MCRegisterInfo * RegInfo,SMLoc S,SMLoc E,MipsAsmParser & Parser)1509   createACCReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1510                SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1511     return CreateReg(Index, Str, RegKind_ACC, RegInfo, S, E, Parser);
1512   }
1513 
1514   /// Create a register that is definitely an MSA128.
1515   /// This is typically only used for named registers such as $w0.
1516   static std::unique_ptr<MipsOperand>
createMSA128Reg(unsigned Index,StringRef Str,const MCRegisterInfo * RegInfo,SMLoc S,SMLoc E,MipsAsmParser & Parser)1517   createMSA128Reg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1518                   SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1519     return CreateReg(Index, Str, RegKind_MSA128, RegInfo, S, E, Parser);
1520   }
1521 
1522   /// Create a register that is definitely an MSACtrl.
1523   /// This is typically only used for named registers such as $msaaccess.
1524   static std::unique_ptr<MipsOperand>
createMSACtrlReg(unsigned Index,StringRef Str,const MCRegisterInfo * RegInfo,SMLoc S,SMLoc E,MipsAsmParser & Parser)1525   createMSACtrlReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1526                    SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1527     return CreateReg(Index, Str, RegKind_MSACtrl, RegInfo, S, E, Parser);
1528   }
1529 
1530   static std::unique_ptr<MipsOperand>
CreateImm(const MCExpr * Val,SMLoc S,SMLoc E,MipsAsmParser & Parser)1531   CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1532     auto Op = std::make_unique<MipsOperand>(k_Immediate, Parser);
1533     Op->Imm.Val = Val;
1534     Op->StartLoc = S;
1535     Op->EndLoc = E;
1536     return Op;
1537   }
1538 
1539   static std::unique_ptr<MipsOperand>
CreateMem(std::unique_ptr<MipsOperand> Base,const MCExpr * Off,SMLoc S,SMLoc E,MipsAsmParser & Parser)1540   CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1541             SMLoc E, MipsAsmParser &Parser) {
1542     auto Op = std::make_unique<MipsOperand>(k_Memory, Parser);
1543     Op->Mem.Base = Base.release();
1544     Op->Mem.Off = Off;
1545     Op->StartLoc = S;
1546     Op->EndLoc = E;
1547     return Op;
1548   }
1549 
1550   static std::unique_ptr<MipsOperand>
CreateRegList(SmallVectorImpl<unsigned> & Regs,SMLoc StartLoc,SMLoc EndLoc,MipsAsmParser & Parser)1551   CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1552                 MipsAsmParser &Parser) {
1553     assert(Regs.size() > 0 && "Empty list not allowed");
1554 
1555     auto Op = std::make_unique<MipsOperand>(k_RegList, Parser);
1556     Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1557     Op->StartLoc = StartLoc;
1558     Op->EndLoc = EndLoc;
1559     return Op;
1560   }
1561 
isGPRZeroAsmReg() const1562  bool isGPRZeroAsmReg() const {
1563     return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index == 0;
1564   }
1565 
isGPRNonZeroAsmReg() const1566  bool isGPRNonZeroAsmReg() const {
1567    return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index > 0 &&
1568           RegIdx.Index <= 31;
1569   }
1570 
isGPRAsmReg() const1571   bool isGPRAsmReg() const {
1572     return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1573   }
1574 
isMM16AsmReg() const1575   bool isMM16AsmReg() const {
1576     if (!(isRegIdx() && RegIdx.Kind))
1577       return false;
1578     return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1579             || RegIdx.Index == 16 || RegIdx.Index == 17);
1580 
1581   }
isMM16AsmRegZero() const1582   bool isMM16AsmRegZero() const {
1583     if (!(isRegIdx() && RegIdx.Kind))
1584       return false;
1585     return (RegIdx.Index == 0 ||
1586             (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1587             RegIdx.Index == 17);
1588   }
1589 
isMM16AsmRegMoveP() const1590   bool isMM16AsmRegMoveP() const {
1591     if (!(isRegIdx() && RegIdx.Kind))
1592       return false;
1593     return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1594       (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1595   }
1596 
isMM16AsmRegMovePPairFirst() const1597   bool isMM16AsmRegMovePPairFirst() const {
1598     if (!(isRegIdx() && RegIdx.Kind))
1599       return false;
1600     return RegIdx.Index >= 4 && RegIdx.Index <= 6;
1601   }
1602 
isMM16AsmRegMovePPairSecond() const1603   bool isMM16AsmRegMovePPairSecond() const {
1604     if (!(isRegIdx() && RegIdx.Kind))
1605       return false;
1606     return (RegIdx.Index == 21 || RegIdx.Index == 22 ||
1607       (RegIdx.Index >= 5 && RegIdx.Index <= 7));
1608   }
1609 
isFGRAsmReg() const1610   bool isFGRAsmReg() const {
1611     // AFGR64 is $0-$15 but we handle this in getAFGR64()
1612     return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1613   }
1614 
isStrictlyFGRAsmReg() const1615   bool isStrictlyFGRAsmReg() const {
1616     // AFGR64 is $0-$15 but we handle this in getAFGR64()
1617     return isRegIdx() && RegIdx.Kind == RegKind_FGR && RegIdx.Index <= 31;
1618   }
1619 
isHWRegsAsmReg() const1620   bool isHWRegsAsmReg() const {
1621     return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1622   }
1623 
isCCRAsmReg() const1624   bool isCCRAsmReg() const {
1625     return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1626   }
1627 
isFCCAsmReg() const1628   bool isFCCAsmReg() const {
1629     if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1630       return false;
1631     return RegIdx.Index <= 7;
1632   }
1633 
isACCAsmReg() const1634   bool isACCAsmReg() const {
1635     return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1636   }
1637 
isCOP0AsmReg() const1638   bool isCOP0AsmReg() const {
1639     return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1640   }
1641 
isCOP2AsmReg() const1642   bool isCOP2AsmReg() const {
1643     return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1644   }
1645 
isCOP3AsmReg() const1646   bool isCOP3AsmReg() const {
1647     return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1648   }
1649 
isMSA128AsmReg() const1650   bool isMSA128AsmReg() const {
1651     return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1652   }
1653 
isMSACtrlAsmReg() const1654   bool isMSACtrlAsmReg() const {
1655     return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1656   }
1657 
1658   /// getStartLoc - Get the location of the first token of this operand.
getStartLoc() const1659   SMLoc getStartLoc() const override { return StartLoc; }
1660   /// getEndLoc - Get the location of the last token of this operand.
getEndLoc() const1661   SMLoc getEndLoc() const override { return EndLoc; }
1662 
print(raw_ostream & OS,const MCAsmInfo & MAI) const1663   void print(raw_ostream &OS, const MCAsmInfo &MAI) const override {
1664     switch (Kind) {
1665     case k_Immediate:
1666       OS << "Imm<";
1667       MAI.printExpr(OS, *Imm.Val);
1668       OS << ">";
1669       break;
1670     case k_Memory:
1671       OS << "Mem<";
1672       Mem.Base->print(OS, MAI);
1673       OS << ", ";
1674       MAI.printExpr(OS, *Mem.Off);
1675       OS << ">";
1676       break;
1677     case k_RegisterIndex:
1678       OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ", "
1679          << StringRef(RegIdx.Tok.Data, RegIdx.Tok.Length) << ">";
1680       break;
1681     case k_Token:
1682       OS << getToken();
1683       break;
1684     case k_RegList:
1685       OS << "RegList< ";
1686       for (auto Reg : (*RegList.List))
1687         OS << Reg << " ";
1688       OS <<  ">";
1689       break;
1690     }
1691   }
1692 
isValidForTie(const MipsOperand & Other) const1693   bool isValidForTie(const MipsOperand &Other) const {
1694     if (Kind != Other.Kind)
1695       return false;
1696 
1697     switch (Kind) {
1698     default:
1699       llvm_unreachable("Unexpected kind");
1700       return false;
1701     case k_RegisterIndex: {
1702       StringRef Token(RegIdx.Tok.Data, RegIdx.Tok.Length);
1703       StringRef OtherToken(Other.RegIdx.Tok.Data, Other.RegIdx.Tok.Length);
1704       return Token == OtherToken;
1705     }
1706     }
1707   }
1708 }; // class MipsOperand
1709 
1710 } // end anonymous namespace
1711 
hasShortDelaySlot(MCInst & Inst)1712 static bool hasShortDelaySlot(MCInst &Inst) {
1713   switch (Inst.getOpcode()) {
1714     case Mips::BEQ_MM:
1715     case Mips::BNE_MM:
1716     case Mips::BLTZ_MM:
1717     case Mips::BGEZ_MM:
1718     case Mips::BLEZ_MM:
1719     case Mips::BGTZ_MM:
1720     case Mips::JRC16_MM:
1721     case Mips::JALS_MM:
1722     case Mips::JALRS_MM:
1723     case Mips::JALRS16_MM:
1724     case Mips::BGEZALS_MM:
1725     case Mips::BLTZALS_MM:
1726       return true;
1727     case Mips::J_MM:
1728       return !Inst.getOperand(0).isReg();
1729     default:
1730       return false;
1731   }
1732 }
1733 
getSingleMCSymbol(const MCExpr * Expr)1734 static const MCSymbol *getSingleMCSymbol(const MCExpr *Expr) {
1735   if (const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1736     return &SRExpr->getSymbol();
1737   }
1738 
1739   if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1740     const MCSymbol *LHSSym = getSingleMCSymbol(BExpr->getLHS());
1741     const MCSymbol *RHSSym = getSingleMCSymbol(BExpr->getRHS());
1742 
1743     if (LHSSym)
1744       return LHSSym;
1745 
1746     if (RHSSym)
1747       return RHSSym;
1748 
1749     return nullptr;
1750   }
1751 
1752   if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1753     return getSingleMCSymbol(UExpr->getSubExpr());
1754 
1755   return nullptr;
1756 }
1757 
countMCSymbolRefExpr(const MCExpr * Expr)1758 static unsigned countMCSymbolRefExpr(const MCExpr *Expr) {
1759   if (isa<MCSymbolRefExpr>(Expr))
1760     return 1;
1761 
1762   if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1763     return countMCSymbolRefExpr(BExpr->getLHS()) +
1764            countMCSymbolRefExpr(BExpr->getRHS());
1765 
1766   if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1767     return countMCSymbolRefExpr(UExpr->getSubExpr());
1768 
1769   return 0;
1770 }
1771 
isEvaluated(const MCExpr * Expr)1772 static bool isEvaluated(const MCExpr *Expr) {
1773   switch (Expr->getKind()) {
1774   case MCExpr::Constant:
1775     return true;
1776   case MCExpr::SymbolRef:
1777     return (cast<MCSymbolRefExpr>(Expr)->getSpecifier());
1778   case MCExpr::Binary: {
1779     const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);
1780     if (!isEvaluated(BE->getLHS()))
1781       return false;
1782     return isEvaluated(BE->getRHS());
1783   }
1784   case MCExpr::Unary:
1785     return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
1786   case MCExpr::Specifier:
1787     return true;
1788   case MCExpr::Target:
1789     llvm_unreachable("unused by this backend");
1790   }
1791   return false;
1792 }
1793 
needsExpandMemInst(MCInst & Inst,const MCInstrDesc & MCID)1794 static bool needsExpandMemInst(MCInst &Inst, const MCInstrDesc &MCID) {
1795   unsigned NumOp = MCID.getNumOperands();
1796   if (NumOp != 3 && NumOp != 4)
1797     return false;
1798 
1799   const MCOperandInfo &OpInfo = MCID.operands()[NumOp - 1];
1800   if (OpInfo.OperandType != MCOI::OPERAND_MEMORY &&
1801       OpInfo.OperandType != MCOI::OPERAND_UNKNOWN &&
1802       OpInfo.OperandType != MipsII::OPERAND_MEM_SIMM9)
1803     return false;
1804 
1805   MCOperand &Op = Inst.getOperand(NumOp - 1);
1806   if (Op.isImm()) {
1807     if (OpInfo.OperandType == MipsII::OPERAND_MEM_SIMM9)
1808       return !isInt<9>(Op.getImm());
1809     // Offset can't exceed 16bit value.
1810     return !isInt<16>(Op.getImm());
1811   }
1812 
1813   if (Op.isExpr()) {
1814     const MCExpr *Expr = Op.getExpr();
1815     if (Expr->getKind() != MCExpr::SymbolRef)
1816       return !isEvaluated(Expr);
1817 
1818     // Expand symbol.
1819     const MCSymbolRefExpr *SR = static_cast<const MCSymbolRefExpr *>(Expr);
1820     return SR->getSpecifier() == 0;
1821   }
1822 
1823   return false;
1824 }
1825 
processInstruction(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)1826 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1827                                        MCStreamer &Out,
1828                                        const MCSubtargetInfo *STI) {
1829   MipsTargetStreamer &TOut = getTargetStreamer();
1830   const unsigned Opcode = Inst.getOpcode();
1831   const MCInstrDesc &MCID = MII.get(Opcode);
1832   bool ExpandedJalSym = false;
1833 
1834   Inst.setLoc(IDLoc);
1835 
1836   if (MCID.isBranch() || MCID.isCall()) {
1837     MCOperand Offset;
1838 
1839     switch (Opcode) {
1840     default:
1841       break;
1842     case Mips::BBIT0:
1843     case Mips::BBIT032:
1844     case Mips::BBIT1:
1845     case Mips::BBIT132:
1846       assert(hasCnMips() && "instruction only valid for octeon cpus");
1847       [[fallthrough]];
1848 
1849     case Mips::BEQ:
1850     case Mips::BNE:
1851     case Mips::BEQ_MM:
1852     case Mips::BNE_MM:
1853       assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1854       Offset = Inst.getOperand(2);
1855       if (!Offset.isImm())
1856         break; // We'll deal with this situation later on when applying fixups.
1857       if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1858         return Error(IDLoc, "branch target out of range");
1859       if (offsetToAlignment(Offset.getImm(),
1860                             (inMicroMipsMode() ? Align(2) : Align(4))))
1861         return Error(IDLoc, "branch to misaligned address");
1862       break;
1863     case Mips::BGEZ:
1864     case Mips::BGTZ:
1865     case Mips::BLEZ:
1866     case Mips::BLTZ:
1867     case Mips::BGEZAL:
1868     case Mips::BLTZAL:
1869     case Mips::BC1F:
1870     case Mips::BC1T:
1871     case Mips::BGEZ_MM:
1872     case Mips::BGTZ_MM:
1873     case Mips::BLEZ_MM:
1874     case Mips::BLTZ_MM:
1875     case Mips::BGEZAL_MM:
1876     case Mips::BLTZAL_MM:
1877     case Mips::BC1F_MM:
1878     case Mips::BC1T_MM:
1879     case Mips::BC1EQZC_MMR6:
1880     case Mips::BC1NEZC_MMR6:
1881     case Mips::BC2EQZC_MMR6:
1882     case Mips::BC2NEZC_MMR6:
1883       assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1884       Offset = Inst.getOperand(1);
1885       if (!Offset.isImm())
1886         break; // We'll deal with this situation later on when applying fixups.
1887       if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1888         return Error(IDLoc, "branch target out of range");
1889       if (offsetToAlignment(Offset.getImm(),
1890                             (inMicroMipsMode() ? Align(2) : Align(4))))
1891         return Error(IDLoc, "branch to misaligned address");
1892       break;
1893     case Mips::BGEC:    case Mips::BGEC_MMR6:
1894     case Mips::BLTC:    case Mips::BLTC_MMR6:
1895     case Mips::BGEUC:   case Mips::BGEUC_MMR6:
1896     case Mips::BLTUC:   case Mips::BLTUC_MMR6:
1897     case Mips::BEQC:    case Mips::BEQC_MMR6:
1898     case Mips::BNEC:    case Mips::BNEC_MMR6:
1899       assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1900       Offset = Inst.getOperand(2);
1901       if (!Offset.isImm())
1902         break; // We'll deal with this situation later on when applying fixups.
1903       if (!isIntN(18, Offset.getImm()))
1904         return Error(IDLoc, "branch target out of range");
1905       if (offsetToAlignment(Offset.getImm(), Align(4)))
1906         return Error(IDLoc, "branch to misaligned address");
1907       break;
1908     case Mips::BLEZC:   case Mips::BLEZC_MMR6:
1909     case Mips::BGEZC:   case Mips::BGEZC_MMR6:
1910     case Mips::BGTZC:   case Mips::BGTZC_MMR6:
1911     case Mips::BLTZC:   case Mips::BLTZC_MMR6:
1912       assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1913       Offset = Inst.getOperand(1);
1914       if (!Offset.isImm())
1915         break; // We'll deal with this situation later on when applying fixups.
1916       if (!isIntN(18, Offset.getImm()))
1917         return Error(IDLoc, "branch target out of range");
1918       if (offsetToAlignment(Offset.getImm(), Align(4)))
1919         return Error(IDLoc, "branch to misaligned address");
1920       break;
1921     case Mips::BEQZC:   case Mips::BEQZC_MMR6:
1922     case Mips::BNEZC:   case Mips::BNEZC_MMR6:
1923       assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1924       Offset = Inst.getOperand(1);
1925       if (!Offset.isImm())
1926         break; // We'll deal with this situation later on when applying fixups.
1927       if (!isIntN(23, Offset.getImm()))
1928         return Error(IDLoc, "branch target out of range");
1929       if (offsetToAlignment(Offset.getImm(), Align(4)))
1930         return Error(IDLoc, "branch to misaligned address");
1931       break;
1932     case Mips::BEQZ16_MM:
1933     case Mips::BEQZC16_MMR6:
1934     case Mips::BNEZ16_MM:
1935     case Mips::BNEZC16_MMR6:
1936       assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1937       Offset = Inst.getOperand(1);
1938       if (!Offset.isImm())
1939         break; // We'll deal with this situation later on when applying fixups.
1940       if (!isInt<8>(Offset.getImm()))
1941         return Error(IDLoc, "branch target out of range");
1942       if (offsetToAlignment(Offset.getImm(), Align(2)))
1943         return Error(IDLoc, "branch to misaligned address");
1944       break;
1945     }
1946   }
1947 
1948   // SSNOP is deprecated on MIPS32r6/MIPS64r6
1949   // We still accept it but it is a normal nop.
1950   if (hasMips32r6() && Opcode == Mips::SSNOP) {
1951     std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1952     Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1953                                                       "nop instruction");
1954   }
1955 
1956   if (hasCnMips()) {
1957     MCOperand Opnd;
1958     int Imm;
1959 
1960     switch (Opcode) {
1961       default:
1962         break;
1963 
1964       case Mips::BBIT0:
1965       case Mips::BBIT032:
1966       case Mips::BBIT1:
1967       case Mips::BBIT132:
1968         assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1969         // The offset is handled above
1970         Opnd = Inst.getOperand(1);
1971         if (!Opnd.isImm())
1972           return Error(IDLoc, "expected immediate operand kind");
1973         Imm = Opnd.getImm();
1974         if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1975                               Opcode == Mips::BBIT1 ? 63 : 31))
1976           return Error(IDLoc, "immediate operand value out of range");
1977         if (Imm > 31) {
1978           Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1979                                                : Mips::BBIT132);
1980           Inst.getOperand(1).setImm(Imm - 32);
1981         }
1982         break;
1983 
1984       case Mips::SEQi:
1985       case Mips::SNEi:
1986         assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1987         Opnd = Inst.getOperand(2);
1988         if (!Opnd.isImm())
1989           return Error(IDLoc, "expected immediate operand kind");
1990         Imm = Opnd.getImm();
1991         if (!isInt<10>(Imm))
1992           return Error(IDLoc, "immediate operand value out of range");
1993         break;
1994     }
1995   }
1996 
1997   // Warn on division by zero. We're checking here as all instructions get
1998   // processed here, not just the macros that need expansion.
1999   //
2000   // The MIPS backend models most of the divison instructions and macros as
2001   // three operand instructions. The pre-R6 divide instructions however have
2002   // two operands and explicitly define HI/LO as part of the instruction,
2003   // not in the operands.
2004   unsigned FirstOp = 1;
2005   unsigned SecondOp = 2;
2006   switch (Opcode) {
2007   default:
2008     break;
2009   case Mips::SDivIMacro:
2010   case Mips::UDivIMacro:
2011   case Mips::DSDivIMacro:
2012   case Mips::DUDivIMacro:
2013     if (Inst.getOperand(2).getImm() == 0) {
2014       if (Inst.getOperand(1).getReg() == Mips::ZERO ||
2015           Inst.getOperand(1).getReg() == Mips::ZERO_64)
2016         Warning(IDLoc, "dividing zero by zero");
2017       else
2018         Warning(IDLoc, "division by zero");
2019     }
2020     break;
2021   case Mips::DSDIV:
2022   case Mips::SDIV:
2023   case Mips::UDIV:
2024   case Mips::DUDIV:
2025   case Mips::UDIV_MM:
2026   case Mips::SDIV_MM:
2027     FirstOp = 0;
2028     SecondOp = 1;
2029     [[fallthrough]];
2030   case Mips::SDivMacro:
2031   case Mips::DSDivMacro:
2032   case Mips::UDivMacro:
2033   case Mips::DUDivMacro:
2034   case Mips::DIV:
2035   case Mips::DIVU:
2036   case Mips::DDIV:
2037   case Mips::DDIVU:
2038   case Mips::DIVU_MMR6:
2039   case Mips::DIV_MMR6:
2040     if (Inst.getOperand(SecondOp).getReg() == Mips::ZERO ||
2041         Inst.getOperand(SecondOp).getReg() == Mips::ZERO_64) {
2042       if (Inst.getOperand(FirstOp).getReg() == Mips::ZERO ||
2043           Inst.getOperand(FirstOp).getReg() == Mips::ZERO_64)
2044         Warning(IDLoc, "dividing zero by zero");
2045       else
2046         Warning(IDLoc, "division by zero");
2047     }
2048     break;
2049   }
2050 
2051   // For PIC code convert unconditional jump to unconditional branch.
2052   if ((Opcode == Mips::J || Opcode == Mips::J_MM) && inPicMode()) {
2053     MCInst BInst;
2054     BInst.setOpcode(inMicroMipsMode() ? Mips::BEQ_MM : Mips::BEQ);
2055     BInst.addOperand(MCOperand::createReg(Mips::ZERO));
2056     BInst.addOperand(MCOperand::createReg(Mips::ZERO));
2057     BInst.addOperand(Inst.getOperand(0));
2058     Inst = BInst;
2059   }
2060 
2061   // This expansion is not in a function called by tryExpandInstruction()
2062   // because the pseudo-instruction doesn't have a distinct opcode.
2063   if ((Opcode == Mips::JAL || Opcode == Mips::JAL_MM) && inPicMode()) {
2064     warnIfNoMacro(IDLoc);
2065 
2066     if (!Inst.getOperand(0).isExpr()) {
2067       return Error(IDLoc, "unsupported constant in relocation");
2068     }
2069 
2070     const MCExpr *JalExpr = Inst.getOperand(0).getExpr();
2071 
2072     // We can do this expansion if there's only 1 symbol in the argument
2073     // expression.
2074     if (countMCSymbolRefExpr(JalExpr) > 1)
2075       return Error(IDLoc, "jal doesn't support multiple symbols in PIC mode");
2076 
2077     // FIXME: This is checking the expression can be handled by the later stages
2078     //        of the assembler. We ought to leave it to those later stages.
2079     const MCSymbol *JalSym = getSingleMCSymbol(JalExpr);
2080 
2081     if (expandLoadAddress(Mips::T9, MCRegister(), Inst.getOperand(0),
2082                           !isGP64bit(), IDLoc, Out, STI))
2083       return true;
2084 
2085     MCInst JalrInst;
2086     if (inMicroMipsMode())
2087       JalrInst.setOpcode(IsCpRestoreSet ? Mips::JALRS_MM : Mips::JALR_MM);
2088     else
2089       JalrInst.setOpcode(Mips::JALR);
2090     JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2091     JalrInst.addOperand(MCOperand::createReg(Mips::T9));
2092 
2093     if (isJalrRelocAvailable(JalExpr)) {
2094       // As an optimization hint for the linker, before the JALR we add:
2095       // .reloc tmplabel, R_{MICRO}MIPS_JALR, symbol
2096       // tmplabel:
2097       MCSymbol *TmpLabel = getContext().createTempSymbol();
2098       const MCExpr *TmpExpr = MCSymbolRefExpr::create(TmpLabel, getContext());
2099       const MCExpr *RelocJalrExpr =
2100           MCSymbolRefExpr::create(JalSym, getContext(), IDLoc);
2101 
2102       TOut.getStreamer().emitRelocDirective(
2103           *TmpExpr, inMicroMipsMode() ? "R_MICROMIPS_JALR" : "R_MIPS_JALR",
2104           RelocJalrExpr, IDLoc, *STI);
2105       TOut.getStreamer().emitLabel(TmpLabel);
2106     }
2107 
2108     Inst = JalrInst;
2109     ExpandedJalSym = true;
2110   }
2111 
2112   if (MCID.mayLoad() || MCID.mayStore()) {
2113     // Check the offset of memory operand, if it is a symbol
2114     // reference or immediate we may have to expand instructions.
2115     if (needsExpandMemInst(Inst, MCID)) {
2116       switch (MCID.operands()[MCID.getNumOperands() - 1].OperandType) {
2117       case MipsII::OPERAND_MEM_SIMM9:
2118         expandMem9Inst(Inst, IDLoc, Out, STI, MCID.mayLoad());
2119         break;
2120       default:
2121         expandMem16Inst(Inst, IDLoc, Out, STI, MCID.mayLoad());
2122         break;
2123       }
2124       return getParser().hasPendingError();
2125     }
2126   }
2127 
2128   if (inMicroMipsMode()) {
2129     if (MCID.mayLoad() && Opcode != Mips::LWP_MM) {
2130       // Try to create 16-bit GP relative load instruction.
2131       for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
2132         const MCOperandInfo &OpInfo = MCID.operands()[i];
2133         if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
2134             (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
2135           MCOperand &Op = Inst.getOperand(i);
2136           if (Op.isImm()) {
2137             int MemOffset = Op.getImm();
2138             MCOperand &DstReg = Inst.getOperand(0);
2139             MCOperand &BaseReg = Inst.getOperand(1);
2140             if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
2141                 getContext().getRegisterInfo()->getRegClass(
2142                   Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
2143                 (BaseReg.getReg() == Mips::GP ||
2144                 BaseReg.getReg() == Mips::GP_64)) {
2145 
2146               TOut.emitRRI(Mips::LWGP_MM, DstReg.getReg(), Mips::GP, MemOffset,
2147                            IDLoc, STI);
2148               return false;
2149             }
2150           }
2151         }
2152       } // for
2153     }   // if load
2154 
2155     // TODO: Handle this with the AsmOperandClass.PredicateMethod.
2156 
2157     MCOperand Opnd;
2158     int Imm;
2159 
2160     switch (Opcode) {
2161       default:
2162         break;
2163       case Mips::ADDIUSP_MM:
2164         Opnd = Inst.getOperand(0);
2165         if (!Opnd.isImm())
2166           return Error(IDLoc, "expected immediate operand kind");
2167         Imm = Opnd.getImm();
2168         if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
2169             Imm % 4 != 0)
2170           return Error(IDLoc, "immediate operand value out of range");
2171         break;
2172       case Mips::SLL16_MM:
2173       case Mips::SRL16_MM:
2174         Opnd = Inst.getOperand(2);
2175         if (!Opnd.isImm())
2176           return Error(IDLoc, "expected immediate operand kind");
2177         Imm = Opnd.getImm();
2178         if (Imm < 1 || Imm > 8)
2179           return Error(IDLoc, "immediate operand value out of range");
2180         break;
2181       case Mips::LI16_MM:
2182         Opnd = Inst.getOperand(1);
2183         if (!Opnd.isImm())
2184           return Error(IDLoc, "expected immediate operand kind");
2185         Imm = Opnd.getImm();
2186         if (Imm < -1 || Imm > 126)
2187           return Error(IDLoc, "immediate operand value out of range");
2188         break;
2189       case Mips::ADDIUR2_MM:
2190         Opnd = Inst.getOperand(2);
2191         if (!Opnd.isImm())
2192           return Error(IDLoc, "expected immediate operand kind");
2193         Imm = Opnd.getImm();
2194         if (!(Imm == 1 || Imm == -1 ||
2195               ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
2196           return Error(IDLoc, "immediate operand value out of range");
2197         break;
2198       case Mips::ANDI16_MM:
2199         Opnd = Inst.getOperand(2);
2200         if (!Opnd.isImm())
2201           return Error(IDLoc, "expected immediate operand kind");
2202         Imm = Opnd.getImm();
2203         if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
2204               Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
2205               Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
2206           return Error(IDLoc, "immediate operand value out of range");
2207         break;
2208       case Mips::LBU16_MM:
2209         Opnd = Inst.getOperand(2);
2210         if (!Opnd.isImm())
2211           return Error(IDLoc, "expected immediate operand kind");
2212         Imm = Opnd.getImm();
2213         if (Imm < -1 || Imm > 14)
2214           return Error(IDLoc, "immediate operand value out of range");
2215         break;
2216       case Mips::SB16_MM:
2217       case Mips::SB16_MMR6:
2218         Opnd = Inst.getOperand(2);
2219         if (!Opnd.isImm())
2220           return Error(IDLoc, "expected immediate operand kind");
2221         Imm = Opnd.getImm();
2222         if (Imm < 0 || Imm > 15)
2223           return Error(IDLoc, "immediate operand value out of range");
2224         break;
2225       case Mips::LHU16_MM:
2226       case Mips::SH16_MM:
2227       case Mips::SH16_MMR6:
2228         Opnd = Inst.getOperand(2);
2229         if (!Opnd.isImm())
2230           return Error(IDLoc, "expected immediate operand kind");
2231         Imm = Opnd.getImm();
2232         if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
2233           return Error(IDLoc, "immediate operand value out of range");
2234         break;
2235       case Mips::LW16_MM:
2236       case Mips::SW16_MM:
2237       case Mips::SW16_MMR6:
2238         Opnd = Inst.getOperand(2);
2239         if (!Opnd.isImm())
2240           return Error(IDLoc, "expected immediate operand kind");
2241         Imm = Opnd.getImm();
2242         if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
2243           return Error(IDLoc, "immediate operand value out of range");
2244         break;
2245       case Mips::ADDIUPC_MM:
2246         Opnd = Inst.getOperand(1);
2247         if (!Opnd.isImm())
2248           return Error(IDLoc, "expected immediate operand kind");
2249         Imm = Opnd.getImm();
2250         if ((Imm % 4 != 0) || !isInt<25>(Imm))
2251           return Error(IDLoc, "immediate operand value out of range");
2252         break;
2253       case Mips::LWP_MM:
2254       case Mips::SWP_MM:
2255         if (Inst.getOperand(0).getReg() == Mips::RA)
2256           return Error(IDLoc, "invalid operand for instruction");
2257         break;
2258       case Mips::MOVEP_MM:
2259       case Mips::MOVEP_MMR6: {
2260         MCRegister R0 = Inst.getOperand(0).getReg();
2261         MCRegister R1 = Inst.getOperand(1).getReg();
2262         bool RegPair = ((R0 == Mips::A1 && R1 == Mips::A2) ||
2263                         (R0 == Mips::A1 && R1 == Mips::A3) ||
2264                         (R0 == Mips::A2 && R1 == Mips::A3) ||
2265                         (R0 == Mips::A0 && R1 == Mips::S5) ||
2266                         (R0 == Mips::A0 && R1 == Mips::S6) ||
2267                         (R0 == Mips::A0 && R1 == Mips::A1) ||
2268                         (R0 == Mips::A0 && R1 == Mips::A2) ||
2269                         (R0 == Mips::A0 && R1 == Mips::A3));
2270         if (!RegPair)
2271           return Error(IDLoc, "invalid operand for instruction");
2272         break;
2273       }
2274     }
2275   }
2276 
2277   bool FillDelaySlot =
2278       MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder();
2279 
2280   // Get previous instruction`s forbidden slot attribute and
2281   // whether set reorder.
2282   bool PrevForbiddenSlotAttr = CurForbiddenSlotAttr;
2283 
2284   // Flag represents we set reorder after nop.
2285   bool SetReorderAfterNop = false;
2286 
2287   // If previous instruction has forbidden slot and .set reorder
2288   // is active and current instruction is CTI.
2289   // Then emit a NOP after it.
2290   if (PrevForbiddenSlotAttr && !SafeInForbiddenSlot(MCID)) {
2291     TOut.emitEmptyDelaySlot(false, IDLoc, STI);
2292     // When 'FillDelaySlot' is true, the existing logic will add
2293     // noreorder before instruction and reorder after it. So there
2294     // need exclude this case avoiding two '.set reorder'.
2295     // The format of the first case is:
2296     // .set noreorder
2297     // bnezc
2298     // nop
2299     // .set reorder
2300     if (AssemblerOptions.back()->isReorder() && !FillDelaySlot) {
2301       SetReorderAfterNop = true;
2302       TOut.emitDirectiveSetReorder();
2303     }
2304   }
2305 
2306   // Save current instruction`s forbidden slot and whether set reorder.
2307   // This is the judgment condition for whether to add nop.
2308   // We would add a couple of '.set noreorder' and '.set reorder' to
2309   // wrap the current instruction and the next instruction.
2310   CurForbiddenSlotAttr =
2311       hasForbiddenSlot(MCID) && AssemblerOptions.back()->isReorder();
2312 
2313   if (FillDelaySlot || CurForbiddenSlotAttr)
2314     TOut.emitDirectiveSetNoReorder();
2315 
2316   MacroExpanderResultTy ExpandResult =
2317       tryExpandInstruction(Inst, IDLoc, Out, STI);
2318   switch (ExpandResult) {
2319   case MER_NotAMacro:
2320     Out.emitInstruction(Inst, *STI);
2321     break;
2322   case MER_Success:
2323     break;
2324   case MER_Fail:
2325     return true;
2326   }
2327 
2328   // When current instruction was not CTI, recover reorder state.
2329   // The format of the second case is:
2330   // .set noreoder
2331   // bnezc
2332   // add
2333   // .set reorder
2334   if (PrevForbiddenSlotAttr && !SetReorderAfterNop && !FillDelaySlot &&
2335       AssemblerOptions.back()->isReorder()) {
2336     TOut.emitDirectiveSetReorder();
2337   }
2338 
2339   // We know we emitted an instruction on the MER_NotAMacro or MER_Success path.
2340   // If we're in microMIPS mode then we must also set EF_MIPS_MICROMIPS.
2341   if (inMicroMipsMode()) {
2342     TOut.setUsesMicroMips();
2343     TOut.updateABIInfo(*this);
2344   }
2345 
2346   // If this instruction has a delay slot and .set reorder is active,
2347   // emit a NOP after it.
2348   // The format of the third case is:
2349   // .set noreorder
2350   // bnezc
2351   // nop
2352   // .set noreorder
2353   // j
2354   // nop
2355   // .set reorder
2356   if (FillDelaySlot) {
2357     TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst), IDLoc, STI);
2358     TOut.emitDirectiveSetReorder();
2359   }
2360 
2361   if ((Opcode == Mips::JalOneReg || Opcode == Mips::JalTwoReg ||
2362        ExpandedJalSym) &&
2363       isPicAndNotNxxAbi()) {
2364     if (IsCpRestoreSet) {
2365       // We need a NOP between the JALR and the LW:
2366       // If .set reorder has been used, we've already emitted a NOP.
2367       // If .set noreorder has been used, we need to emit a NOP at this point.
2368       if (!AssemblerOptions.back()->isReorder())
2369         TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst), IDLoc,
2370                                 STI);
2371 
2372       // Load the $gp from the stack.
2373       TOut.emitGPRestore(CpRestoreOffset, IDLoc, STI);
2374     } else
2375       Warning(IDLoc, "no .cprestore used in PIC mode");
2376   }
2377 
2378   return false;
2379 }
2380 
onEndOfFile()2381 void MipsAsmParser::onEndOfFile() {
2382   MipsTargetStreamer &TOut = getTargetStreamer();
2383   SMLoc IDLoc = SMLoc();
2384   // If has pending forbidden slot, fill nop and recover reorder.
2385   if (CurForbiddenSlotAttr) {
2386     TOut.emitEmptyDelaySlot(false, IDLoc, STI);
2387     if (AssemblerOptions.back()->isReorder())
2388       TOut.emitDirectiveSetReorder();
2389   }
2390 }
2391 
2392 MipsAsmParser::MacroExpanderResultTy
tryExpandInstruction(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)2393 MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2394                                     const MCSubtargetInfo *STI) {
2395   switch (Inst.getOpcode()) {
2396   default:
2397     return MER_NotAMacro;
2398   case Mips::LoadImm32:
2399     return expandLoadImm(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2400   case Mips::LoadImm64:
2401     return expandLoadImm(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2402   case Mips::LoadAddrImm32:
2403   case Mips::LoadAddrImm64:
2404     assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2405     assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
2406            "expected immediate operand kind");
2407 
2408     return expandLoadAddress(
2409                Inst.getOperand(0).getReg(), MCRegister(), Inst.getOperand(1),
2410                Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc, Out, STI)
2411                ? MER_Fail
2412                : MER_Success;
2413   case Mips::LoadAddrReg32:
2414   case Mips::LoadAddrReg64:
2415     assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2416     assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2417     assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
2418            "expected immediate operand kind");
2419 
2420     return expandLoadAddress(Inst.getOperand(0).getReg(),
2421                              Inst.getOperand(1).getReg(), Inst.getOperand(2),
2422                              Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc,
2423                              Out, STI)
2424                ? MER_Fail
2425                : MER_Success;
2426   case Mips::B_MM_Pseudo:
2427   case Mips::B_MMR6_Pseudo:
2428     return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
2429                                                              : MER_Success;
2430   case Mips::SWM_MM:
2431   case Mips::LWM_MM:
2432     return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
2433                                                           : MER_Success;
2434   case Mips::JalOneReg:
2435   case Mips::JalTwoReg:
2436     return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2437   case Mips::BneImm:
2438   case Mips::BeqImm:
2439   case Mips::BEQLImmMacro:
2440   case Mips::BNELImmMacro:
2441     return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2442   case Mips::BLT:
2443   case Mips::BLE:
2444   case Mips::BGE:
2445   case Mips::BGT:
2446   case Mips::BLTU:
2447   case Mips::BLEU:
2448   case Mips::BGEU:
2449   case Mips::BGTU:
2450   case Mips::BLTL:
2451   case Mips::BLEL:
2452   case Mips::BGEL:
2453   case Mips::BGTL:
2454   case Mips::BLTUL:
2455   case Mips::BLEUL:
2456   case Mips::BGEUL:
2457   case Mips::BGTUL:
2458   case Mips::BLTImmMacro:
2459   case Mips::BLEImmMacro:
2460   case Mips::BGEImmMacro:
2461   case Mips::BGTImmMacro:
2462   case Mips::BLTUImmMacro:
2463   case Mips::BLEUImmMacro:
2464   case Mips::BGEUImmMacro:
2465   case Mips::BGTUImmMacro:
2466   case Mips::BLTLImmMacro:
2467   case Mips::BLELImmMacro:
2468   case Mips::BGELImmMacro:
2469   case Mips::BGTLImmMacro:
2470   case Mips::BLTULImmMacro:
2471   case Mips::BLEULImmMacro:
2472   case Mips::BGEULImmMacro:
2473   case Mips::BGTULImmMacro:
2474     return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2475   case Mips::SDivMacro:
2476   case Mips::SDivIMacro:
2477   case Mips::SRemMacro:
2478   case Mips::SRemIMacro:
2479     return expandDivRem(Inst, IDLoc, Out, STI, false, true) ? MER_Fail
2480                                                             : MER_Success;
2481   case Mips::DSDivMacro:
2482   case Mips::DSDivIMacro:
2483   case Mips::DSRemMacro:
2484   case Mips::DSRemIMacro:
2485     return expandDivRem(Inst, IDLoc, Out, STI, true, true) ? MER_Fail
2486                                                            : MER_Success;
2487   case Mips::UDivMacro:
2488   case Mips::UDivIMacro:
2489   case Mips::URemMacro:
2490   case Mips::URemIMacro:
2491     return expandDivRem(Inst, IDLoc, Out, STI, false, false) ? MER_Fail
2492                                                              : MER_Success;
2493   case Mips::DUDivMacro:
2494   case Mips::DUDivIMacro:
2495   case Mips::DURemMacro:
2496   case Mips::DURemIMacro:
2497     return expandDivRem(Inst, IDLoc, Out, STI, true, false) ? MER_Fail
2498                                                             : MER_Success;
2499   case Mips::PseudoTRUNC_W_S:
2500     return expandTrunc(Inst, false, false, IDLoc, Out, STI) ? MER_Fail
2501                                                             : MER_Success;
2502   case Mips::PseudoTRUNC_W_D32:
2503     return expandTrunc(Inst, true, false, IDLoc, Out, STI) ? MER_Fail
2504                                                            : MER_Success;
2505   case Mips::PseudoTRUNC_W_D:
2506     return expandTrunc(Inst, true, true, IDLoc, Out, STI) ? MER_Fail
2507                                                           : MER_Success;
2508 
2509   case Mips::LoadImmSingleGPR:
2510     return expandLoadSingleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2511                                                            : MER_Success;
2512   case Mips::LoadImmSingleFGR:
2513     return expandLoadSingleImmToFPR(Inst, IDLoc, Out, STI) ? MER_Fail
2514                                                            : MER_Success;
2515   case Mips::LoadImmDoubleGPR:
2516     return expandLoadDoubleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2517                                                            : MER_Success;
2518   case Mips::LoadImmDoubleFGR:
2519     return expandLoadDoubleImmToFPR(Inst, true, IDLoc, Out, STI) ? MER_Fail
2520                                                                  : MER_Success;
2521   case Mips::LoadImmDoubleFGR_32:
2522     return expandLoadDoubleImmToFPR(Inst, false, IDLoc, Out, STI) ? MER_Fail
2523                                                                   : MER_Success;
2524 
2525   case Mips::Ulh:
2526     return expandUlh(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2527   case Mips::Ulhu:
2528     return expandUlh(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2529   case Mips::Ush:
2530     return expandUsh(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2531   case Mips::Ulw:
2532   case Mips::Usw:
2533     return expandUxw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2534   case Mips::NORImm:
2535   case Mips::NORImm64:
2536     return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2537   case Mips::SGE:
2538   case Mips::SGEU:
2539     return expandSge(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2540   case Mips::SGEImm:
2541   case Mips::SGEUImm:
2542   case Mips::SGEImm64:
2543   case Mips::SGEUImm64:
2544     return expandSgeImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2545   case Mips::SGTImm:
2546   case Mips::SGTUImm:
2547   case Mips::SGTImm64:
2548   case Mips::SGTUImm64:
2549     return expandSgtImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2550   case Mips::SLE:
2551   case Mips::SLEU:
2552     return expandSle(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2553   case Mips::SLEImm:
2554   case Mips::SLEUImm:
2555   case Mips::SLEImm64:
2556   case Mips::SLEUImm64:
2557     return expandSleImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2558   case Mips::SLTImm64:
2559     if (isInt<16>(Inst.getOperand(2).getImm())) {
2560       Inst.setOpcode(Mips::SLTi64);
2561       return MER_NotAMacro;
2562     }
2563     return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2564   case Mips::SLTUImm64:
2565     if (isInt<16>(Inst.getOperand(2).getImm())) {
2566       Inst.setOpcode(Mips::SLTiu64);
2567       return MER_NotAMacro;
2568     }
2569     return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2570   case Mips::ADDi:   case Mips::ADDi_MM:
2571   case Mips::ADDiu:  case Mips::ADDiu_MM:
2572   case Mips::SLTi:   case Mips::SLTi_MM:
2573   case Mips::SLTiu:  case Mips::SLTiu_MM:
2574     if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2575         Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2576       int64_t ImmValue = Inst.getOperand(2).getImm();
2577       if (isInt<16>(ImmValue))
2578         return MER_NotAMacro;
2579       return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2580                                                          : MER_Success;
2581     }
2582     return MER_NotAMacro;
2583   case Mips::ANDi:  case Mips::ANDi_MM:  case Mips::ANDi64:
2584   case Mips::ORi:   case Mips::ORi_MM:   case Mips::ORi64:
2585   case Mips::XORi:  case Mips::XORi_MM:  case Mips::XORi64:
2586     if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2587         Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2588       int64_t ImmValue = Inst.getOperand(2).getImm();
2589       if (isUInt<16>(ImmValue))
2590         return MER_NotAMacro;
2591       return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2592                                                          : MER_Success;
2593     }
2594     return MER_NotAMacro;
2595   case Mips::ROL:
2596   case Mips::ROR:
2597     return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2598   case Mips::ROLImm:
2599   case Mips::RORImm:
2600     return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2601   case Mips::DROL:
2602   case Mips::DROR:
2603     return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2604   case Mips::DROLImm:
2605   case Mips::DRORImm:
2606     return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2607   case Mips::ABSMacro:
2608     return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2609   case Mips::MULImmMacro:
2610   case Mips::DMULImmMacro:
2611     return expandMulImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2612   case Mips::MULOMacro:
2613   case Mips::DMULOMacro:
2614     return expandMulO(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2615   case Mips::MULOUMacro:
2616   case Mips::DMULOUMacro:
2617     return expandMulOU(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2618   case Mips::DMULMacro:
2619     return expandDMULMacro(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2620   case Mips::LDMacro:
2621   case Mips::SDMacro:
2622     return expandLoadStoreDMacro(Inst, IDLoc, Out, STI,
2623                                  Inst.getOpcode() == Mips::LDMacro)
2624                ? MER_Fail
2625                : MER_Success;
2626   case Mips::SDC1_M1:
2627     return expandStoreDM1Macro(Inst, IDLoc, Out, STI)
2628                ? MER_Fail
2629                : MER_Success;
2630   case Mips::SEQMacro:
2631     return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2632   case Mips::SEQIMacro:
2633     return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2634   case Mips::SNEMacro:
2635     return expandSne(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2636   case Mips::SNEIMacro:
2637     return expandSneI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2638   case Mips::MFTC0:   case Mips::MTTC0:
2639   case Mips::MFTGPR:  case Mips::MTTGPR:
2640   case Mips::MFTLO:   case Mips::MTTLO:
2641   case Mips::MFTHI:   case Mips::MTTHI:
2642   case Mips::MFTACX:  case Mips::MTTACX:
2643   case Mips::MFTDSP:  case Mips::MTTDSP:
2644   case Mips::MFTC1:   case Mips::MTTC1:
2645   case Mips::MFTHC1:  case Mips::MTTHC1:
2646   case Mips::CFTC1:   case Mips::CTTC1:
2647     return expandMXTRAlias(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2648   case Mips::SaaAddr:
2649   case Mips::SaadAddr:
2650     return expandSaaAddr(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2651   }
2652 }
2653 
expandJalWithRegs(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)2654 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2655                                       MCStreamer &Out,
2656                                       const MCSubtargetInfo *STI) {
2657   MipsTargetStreamer &TOut = getTargetStreamer();
2658 
2659   // Create a JALR instruction which is going to replace the pseudo-JAL.
2660   MCInst JalrInst;
2661   JalrInst.setLoc(IDLoc);
2662   const MCOperand FirstRegOp = Inst.getOperand(0);
2663   const unsigned Opcode = Inst.getOpcode();
2664 
2665   if (Opcode == Mips::JalOneReg) {
2666     // jal $rs => jalr $rs
2667     if (IsCpRestoreSet && inMicroMipsMode()) {
2668       JalrInst.setOpcode(Mips::JALRS16_MM);
2669       JalrInst.addOperand(FirstRegOp);
2670     } else if (inMicroMipsMode()) {
2671       JalrInst.setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2672       JalrInst.addOperand(FirstRegOp);
2673     } else {
2674       JalrInst.setOpcode(Mips::JALR);
2675       JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2676       JalrInst.addOperand(FirstRegOp);
2677     }
2678   } else if (Opcode == Mips::JalTwoReg) {
2679     // jal $rd, $rs => jalr $rd, $rs
2680     if (IsCpRestoreSet && inMicroMipsMode())
2681       JalrInst.setOpcode(Mips::JALRS_MM);
2682     else
2683       JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2684     JalrInst.addOperand(FirstRegOp);
2685     const MCOperand SecondRegOp = Inst.getOperand(1);
2686     JalrInst.addOperand(SecondRegOp);
2687   }
2688   Out.emitInstruction(JalrInst, *STI);
2689 
2690   // If .set reorder is active and branch instruction has a delay slot,
2691   // emit a NOP after it.
2692   const MCInstrDesc &MCID = MII.get(JalrInst.getOpcode());
2693   if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2694     TOut.emitEmptyDelaySlot(hasShortDelaySlot(JalrInst), IDLoc,
2695                             STI);
2696 
2697   return false;
2698 }
2699 
2700 /// Can the value be represented by a unsigned N-bit value and a shift left?
isShiftedUIntAtAnyPosition(uint64_t x)2701 template <unsigned N> static bool isShiftedUIntAtAnyPosition(uint64_t x) {
2702   return x && isUInt<N>(x >> llvm::countr_zero(x));
2703 }
2704 
2705 /// Load (or add) an immediate into a register.
2706 ///
2707 /// @param ImmValue     The immediate to load.
2708 /// @param DstReg       The register that will hold the immediate.
2709 /// @param SrcReg       A register to add to the immediate or MCRegister()
2710 ///                     for a simple initialization.
2711 /// @param Is32BitImm   Is ImmValue 32-bit or 64-bit?
2712 /// @param IsAddress    True if the immediate represents an address. False if it
2713 ///                     is an integer.
2714 /// @param IDLoc        Location of the immediate in the source file.
loadImmediate(int64_t ImmValue,MCRegister DstReg,MCRegister SrcReg,bool Is32BitImm,bool IsAddress,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)2715 bool MipsAsmParser::loadImmediate(int64_t ImmValue, MCRegister DstReg,
2716                                   MCRegister SrcReg, bool Is32BitImm,
2717                                   bool IsAddress, SMLoc IDLoc, MCStreamer &Out,
2718                                   const MCSubtargetInfo *STI) {
2719   MipsTargetStreamer &TOut = getTargetStreamer();
2720 
2721   if (!Is32BitImm && !isGP64bit()) {
2722     Error(IDLoc, "instruction requires a 64-bit architecture");
2723     return true;
2724   }
2725 
2726   if (Is32BitImm) {
2727     if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2728       // Sign extend up to 64-bit so that the predicates match the hardware
2729       // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2730       // true.
2731       ImmValue = SignExtend64<32>(ImmValue);
2732     } else {
2733       Error(IDLoc, "instruction requires a 32-bit immediate");
2734       return true;
2735     }
2736   }
2737 
2738   MCRegister ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2739   unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2740 
2741   bool UseSrcReg = false;
2742   if (SrcReg)
2743     UseSrcReg = true;
2744 
2745   MCRegister TmpReg = DstReg;
2746   if (UseSrcReg &&
2747       getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2748     // At this point we need AT to perform the expansions and we exit if it is
2749     // not available.
2750     MCRegister ATReg = getATReg(IDLoc);
2751     if (!ATReg)
2752       return true;
2753     TmpReg = ATReg;
2754   }
2755 
2756   if (isInt<16>(ImmValue)) {
2757     if (!UseSrcReg)
2758       SrcReg = ZeroReg;
2759 
2760     // This doesn't quite follow the usual ABI expectations for N32 but matches
2761     // traditional assembler behaviour. N32 would normally use addiu for both
2762     // integers and addresses.
2763     if (IsAddress && !Is32BitImm) {
2764       TOut.emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2765       return false;
2766     }
2767 
2768     TOut.emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2769     return false;
2770   }
2771 
2772   if (isUInt<16>(ImmValue)) {
2773     MCRegister TmpReg = DstReg;
2774     if (SrcReg == DstReg) {
2775       TmpReg = getATReg(IDLoc);
2776       if (!TmpReg)
2777         return true;
2778     }
2779 
2780     TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2781     if (UseSrcReg)
2782       TOut.emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2783     return false;
2784   }
2785 
2786   if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2787     warnIfNoMacro(IDLoc);
2788 
2789     uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2790     uint16_t Bits15To0 = ImmValue & 0xffff;
2791     if (!Is32BitImm && !isInt<32>(ImmValue)) {
2792       // Traditional behaviour seems to special case this particular value. It's
2793       // not clear why other masks are handled differently.
2794       if (ImmValue == 0xffffffff) {
2795         TOut.emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2796         TOut.emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2797         if (UseSrcReg)
2798           TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2799         return false;
2800       }
2801 
2802       // Expand to an ORi instead of a LUi to avoid sign-extending into the
2803       // upper 32 bits.
2804       TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2805       TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2806       if (Bits15To0)
2807         TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2808       if (UseSrcReg)
2809         TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2810       return false;
2811     }
2812 
2813     TOut.emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2814     if (Bits15To0)
2815       TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2816     if (UseSrcReg)
2817       TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2818     return false;
2819   }
2820 
2821   if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2822     if (Is32BitImm) {
2823       Error(IDLoc, "instruction requires a 32-bit immediate");
2824       return true;
2825     }
2826 
2827     // We've processed ImmValue satisfying isUInt<16> above, so ImmValue must be
2828     // at least 17-bit wide here.
2829     unsigned BitWidth = llvm::bit_width((uint64_t)ImmValue);
2830     assert(BitWidth >= 17 && "ImmValue must be at least 17-bit wide");
2831 
2832     // Traditionally, these immediates are shifted as little as possible and as
2833     // such we align the most significant bit to bit 15 of our temporary.
2834     unsigned ShiftAmount = BitWidth - 16;
2835     uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2836     TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2837     TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2838 
2839     if (UseSrcReg)
2840       TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2841 
2842     return false;
2843   }
2844 
2845   warnIfNoMacro(IDLoc);
2846 
2847   // The remaining case is packed with a sequence of dsll and ori with zeros
2848   // being omitted and any neighbouring dsll's being coalesced.
2849   // The highest 32-bit's are equivalent to a 32-bit immediate load.
2850 
2851   // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2852   if (loadImmediate(ImmValue >> 32, TmpReg, MCRegister(), true, false, IDLoc,
2853                     Out, STI))
2854     return false;
2855 
2856   // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2857   // skip it and defer the shift to the next chunk.
2858   unsigned ShiftCarriedForwards = 16;
2859   for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2860     uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2861 
2862     if (ImmChunk != 0) {
2863       TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2864       TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2865       ShiftCarriedForwards = 0;
2866     }
2867 
2868     ShiftCarriedForwards += 16;
2869   }
2870   ShiftCarriedForwards -= 16;
2871 
2872   // Finish any remaining shifts left by trailing zeros.
2873   if (ShiftCarriedForwards)
2874     TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2875 
2876   if (UseSrcReg)
2877     TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2878 
2879   return false;
2880 }
2881 
expandLoadImm(MCInst & Inst,bool Is32BitImm,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)2882 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2883                                   MCStreamer &Out, const MCSubtargetInfo *STI) {
2884   const MCOperand &ImmOp = Inst.getOperand(1);
2885   assert(ImmOp.isImm() && "expected immediate operand kind");
2886   const MCOperand &DstRegOp = Inst.getOperand(0);
2887   assert(DstRegOp.isReg() && "expected register operand kind");
2888 
2889   if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), MCRegister(), Is32BitImm,
2890                     false, IDLoc, Out, STI))
2891     return true;
2892 
2893   return false;
2894 }
2895 
expandLoadAddress(MCRegister DstReg,MCRegister BaseReg,const MCOperand & Offset,bool Is32BitAddress,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)2896 bool MipsAsmParser::expandLoadAddress(MCRegister DstReg, MCRegister BaseReg,
2897                                       const MCOperand &Offset,
2898                                       bool Is32BitAddress, SMLoc IDLoc,
2899                                       MCStreamer &Out,
2900                                       const MCSubtargetInfo *STI) {
2901   // la can't produce a usable address when addresses are 64-bit.
2902   if (Is32BitAddress && ABI.ArePtrs64bit()) {
2903     Warning(IDLoc, "la used to load 64-bit address");
2904     // Continue as if we had 'dla' instead.
2905     Is32BitAddress = false;
2906   }
2907 
2908   // dla requires 64-bit addresses.
2909   if (!Is32BitAddress && !hasMips3()) {
2910     Error(IDLoc, "instruction requires a 64-bit architecture");
2911     return true;
2912   }
2913 
2914   if (!Offset.isImm())
2915     return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2916                                    Is32BitAddress, IDLoc, Out, STI);
2917 
2918   if (!ABI.ArePtrs64bit()) {
2919     // Continue as if we had 'la' whether we had 'la' or 'dla'.
2920     Is32BitAddress = true;
2921   }
2922 
2923   return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2924                        IDLoc, Out, STI);
2925 }
2926 
loadAndAddSymbolAddress(const MCExpr * SymExpr,MCRegister DstReg,MCRegister SrcReg,bool Is32BitSym,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)2927 bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr,
2928                                             MCRegister DstReg,
2929                                             MCRegister SrcReg, bool Is32BitSym,
2930                                             SMLoc IDLoc, MCStreamer &Out,
2931                                             const MCSubtargetInfo *STI) {
2932   MipsTargetStreamer &TOut = getTargetStreamer();
2933   bool UseSrcReg =
2934       SrcReg.isValid() && SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64;
2935   warnIfNoMacro(IDLoc);
2936 
2937   if (inPicMode()) {
2938     MCValue Res;
2939     if (!SymExpr->evaluateAsRelocatable(Res, nullptr)) {
2940       Error(IDLoc, "expected relocatable expression");
2941       return true;
2942     }
2943     if (Res.getSubSym()) {
2944       Error(IDLoc, "expected relocatable expression with only one symbol");
2945       return true;
2946     }
2947 
2948     bool IsPtr64 = ABI.ArePtrs64bit();
2949     bool IsLocalSym =
2950         Res.getAddSym()->isInSection() || Res.getAddSym()->isTemporary() ||
2951         (Res.getAddSym()->isELF() &&
2952          cast<MCSymbolELF>(Res.getAddSym())->getBinding() == ELF::STB_LOCAL);
2953     // For O32, "$"-prefixed symbols are recognized as temporary while
2954     // .L-prefixed symbols are not (PrivateGlobalPrefix is "$"). Recognize ".L"
2955     // manually.
2956     if (ABI.IsO32() && Res.getAddSym()->getName().starts_with(".L"))
2957       IsLocalSym = true;
2958     bool UseXGOT = STI->hasFeature(Mips::FeatureXGOT) && !IsLocalSym;
2959 
2960     // The case where the result register is $25 is somewhat special. If the
2961     // symbol in the final relocation is external and not modified with a
2962     // constant then we must use R_MIPS_CALL16 instead of R_MIPS_GOT16
2963     // or R_MIPS_CALL16 instead of R_MIPS_GOT_DISP in 64-bit case.
2964     if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2965         Res.getConstant() == 0 && !IsLocalSym) {
2966       if (UseXGOT) {
2967         const MCExpr *CallHiExpr =
2968             MCSpecifierExpr::create(SymExpr, Mips::S_CALL_HI16, getContext());
2969         const MCExpr *CallLoExpr =
2970             MCSpecifierExpr::create(SymExpr, Mips::S_CALL_LO16, getContext());
2971         TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(CallHiExpr), IDLoc,
2972                     STI);
2973         TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, DstReg, GPReg,
2974                      IDLoc, STI);
2975         TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, DstReg,
2976                      MCOperand::createExpr(CallLoExpr), IDLoc, STI);
2977       } else {
2978         const MCExpr *CallExpr =
2979             MCSpecifierExpr::create(SymExpr, Mips::S_GOT_CALL, getContext());
2980         TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, GPReg,
2981                      MCOperand::createExpr(CallExpr), IDLoc, STI);
2982       }
2983       return false;
2984     }
2985 
2986     MCRegister TmpReg = DstReg;
2987     if (UseSrcReg &&
2988         getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2989                                                                SrcReg)) {
2990       // If $rs is the same as $rd, we need to use AT.
2991       // If it is not available we exit.
2992       MCRegister ATReg = getATReg(IDLoc);
2993       if (!ATReg)
2994         return true;
2995       TmpReg = ATReg;
2996     }
2997 
2998     // FIXME: In case of N32 / N64 ABI and emabled XGOT, local addresses
2999     // loaded using R_MIPS_GOT_PAGE / R_MIPS_GOT_OFST pair of relocations.
3000     // FIXME: Implement XGOT for microMIPS.
3001     if (UseXGOT) {
3002       // Loading address from XGOT
3003       //   External GOT: lui $tmp, %got_hi(symbol)($gp)
3004       //                 addu $tmp, $tmp, $gp
3005       //                 lw $tmp, %got_lo(symbol)($tmp)
3006       //                >addiu $tmp, $tmp, offset
3007       //                >addiu $rd, $tmp, $rs
3008       // The addiu's marked with a '>' may be omitted if they are redundant. If
3009       // this happens then the last instruction must use $rd as the result
3010       // register.
3011       const MCExpr *CallHiExpr =
3012           MCSpecifierExpr::create(SymExpr, Mips::S_GOT_HI16, getContext());
3013       const MCExpr *CallLoExpr = MCSpecifierExpr::create(
3014           Res.getAddSym(), Mips::S_GOT_LO16, getContext());
3015 
3016       TOut.emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(CallHiExpr), IDLoc,
3017                   STI);
3018       TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg, GPReg,
3019                    IDLoc, STI);
3020       TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, TmpReg,
3021                    MCOperand::createExpr(CallLoExpr), IDLoc, STI);
3022 
3023       if (Res.getConstant() != 0)
3024         TOut.emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3025                      MCOperand::createExpr(MCConstantExpr::create(
3026                          Res.getConstant(), getContext())),
3027                      IDLoc, STI);
3028 
3029       if (UseSrcReg)
3030         TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3031                      IDLoc, STI);
3032       return false;
3033     }
3034 
3035     const MCSpecifierExpr *GotExpr = nullptr;
3036     const MCExpr *LoExpr = nullptr;
3037     if (ABI.IsN32() || ABI.IsN64()) {
3038       // The remaining cases are:
3039       //   Small offset: ld $tmp, %got_disp(symbol)($gp)
3040       //                >daddiu $tmp, $tmp, offset
3041       //                >daddu $rd, $tmp, $rs
3042       // The daddiu's marked with a '>' may be omitted if they are redundant. If
3043       // this happens then the last instruction must use $rd as the result
3044       // register.
3045       GotExpr = MCSpecifierExpr::create(Res.getAddSym(), Mips::S_GOT_DISP,
3046                                         getContext());
3047       if (Res.getConstant() != 0) {
3048         // Symbols fully resolve with just the %got_disp(symbol) but we
3049         // must still account for any offset to the symbol for
3050         // expressions like symbol+8.
3051         LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
3052 
3053         // FIXME: Offsets greater than 16 bits are not yet implemented.
3054         // FIXME: The correct range is a 32-bit sign-extended number.
3055         if (Res.getConstant() < -0x8000 || Res.getConstant() > 0x7fff) {
3056           Error(IDLoc, "macro instruction uses large offset, which is not "
3057                        "currently supported");
3058           return true;
3059         }
3060       }
3061     } else {
3062       // The remaining cases are:
3063       //   External GOT: lw $tmp, %got(symbol)($gp)
3064       //                >addiu $tmp, $tmp, offset
3065       //                >addiu $rd, $tmp, $rs
3066       //   Local GOT:    lw $tmp, %got(symbol+offset)($gp)
3067       //                 addiu $tmp, $tmp, %lo(symbol+offset)($gp)
3068       //                >addiu $rd, $tmp, $rs
3069       // The addiu's marked with a '>' may be omitted if they are redundant. If
3070       // this happens then the last instruction must use $rd as the result
3071       // register.
3072       if (IsLocalSym) {
3073         GotExpr = MCSpecifierExpr::create(SymExpr, Mips::S_GOT, getContext());
3074         LoExpr = MCSpecifierExpr::create(SymExpr, Mips::S_LO, getContext());
3075       } else {
3076         // External symbols fully resolve the symbol with just the %got(symbol)
3077         // but we must still account for any offset to the symbol for
3078         // expressions like symbol+8.
3079         GotExpr =
3080             MCSpecifierExpr::create(Res.getAddSym(), Mips::S_GOT, getContext());
3081         if (Res.getConstant() != 0)
3082           LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
3083       }
3084     }
3085 
3086     TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, GPReg,
3087                  MCOperand::createExpr(GotExpr), IDLoc, STI);
3088 
3089     if (LoExpr)
3090       TOut.emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3091                    MCOperand::createExpr(LoExpr), IDLoc, STI);
3092 
3093     if (UseSrcReg)
3094       TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3095                    IDLoc, STI);
3096 
3097     return false;
3098   }
3099 
3100   const auto *HiExpr =
3101       MCSpecifierExpr::create(SymExpr, Mips::S_HI, getContext());
3102   const auto *LoExpr =
3103       MCSpecifierExpr::create(SymExpr, Mips::S_LO, getContext());
3104 
3105   // This is the 64-bit symbol address expansion.
3106   if (ABI.ArePtrs64bit() && isGP64bit()) {
3107     // We need AT for the 64-bit expansion in the cases where the optional
3108     // source register is the destination register and for the superscalar
3109     // scheduled form.
3110     //
3111     // If it is not available we exit if the destination is the same as the
3112     // source register.
3113 
3114     const auto *HighestExpr =
3115         MCSpecifierExpr::create(SymExpr, Mips::S_HIGHEST, getContext());
3116     const auto *HigherExpr =
3117         MCSpecifierExpr::create(SymExpr, Mips::S_HIGHER, getContext());
3118 
3119     bool RdRegIsRsReg =
3120         UseSrcReg &&
3121         getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg);
3122 
3123     if (canUseATReg() && UseSrcReg && RdRegIsRsReg) {
3124       MCRegister ATReg = getATReg(IDLoc);
3125 
3126       // If $rs is the same as $rd:
3127       // (d)la $rd, sym($rd) => lui    $at, %highest(sym)
3128       //                        daddiu $at, $at, %higher(sym)
3129       //                        dsll   $at, $at, 16
3130       //                        daddiu $at, $at, %hi(sym)
3131       //                        dsll   $at, $at, 16
3132       //                        daddiu $at, $at, %lo(sym)
3133       //                        daddu  $rd, $at, $rd
3134       TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
3135                   STI);
3136       TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3137                    MCOperand::createExpr(HigherExpr), IDLoc, STI);
3138       TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3139       TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
3140                    IDLoc, STI);
3141       TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3142       TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
3143                    IDLoc, STI);
3144       TOut.emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
3145 
3146       return false;
3147     } else if (canUseATReg() && !RdRegIsRsReg && DstReg != getATReg(IDLoc)) {
3148       MCRegister ATReg = getATReg(IDLoc);
3149 
3150       // If the $rs is different from $rd or if $rs isn't specified and we
3151       // have $at available:
3152       // (d)la $rd, sym/sym($rs) => lui    $rd, %highest(sym)
3153       //                            lui    $at, %hi(sym)
3154       //                            daddiu $rd, $rd, %higher(sym)
3155       //                            daddiu $at, $at, %lo(sym)
3156       //                            dsll32 $rd, $rd, 0
3157       //                            daddu  $rd, $rd, $at
3158       //                            (daddu  $rd, $rd, $rs)
3159       //
3160       // Which is preferred for superscalar issue.
3161       TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
3162                   STI);
3163       TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3164       TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3165                    MCOperand::createExpr(HigherExpr), IDLoc, STI);
3166       TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
3167                    IDLoc, STI);
3168       TOut.emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
3169       TOut.emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
3170       if (UseSrcReg)
3171         TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3172 
3173       return false;
3174     } else if ((!canUseATReg() && !RdRegIsRsReg) ||
3175                (canUseATReg() && DstReg == getATReg(IDLoc))) {
3176       // Otherwise, synthesize the address in the destination register
3177       // serially:
3178       // (d)la $rd, sym/sym($rs) => lui    $rd, %highest(sym)
3179       //                            daddiu $rd, $rd, %higher(sym)
3180       //                            dsll   $rd, $rd, 16
3181       //                            daddiu $rd, $rd, %hi(sym)
3182       //                            dsll   $rd, $rd, 16
3183       //                            daddiu $rd, $rd, %lo(sym)
3184       TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
3185                   STI);
3186       TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3187                    MCOperand::createExpr(HigherExpr), IDLoc, STI);
3188       TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3189       TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3190                    MCOperand::createExpr(HiExpr), IDLoc, STI);
3191       TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3192       TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3193                    MCOperand::createExpr(LoExpr), IDLoc, STI);
3194       if (UseSrcReg)
3195         TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3196 
3197       return false;
3198     } else {
3199       // We have a case where SrcReg == DstReg and we don't have $at
3200       // available. We can't expand this case, so error out appropriately.
3201       assert(SrcReg == DstReg && !canUseATReg() &&
3202              "Could have expanded dla but didn't?");
3203       reportParseError(IDLoc,
3204                      "pseudo-instruction requires $at, which is not available");
3205       return true;
3206     }
3207   }
3208 
3209   // And now, the 32-bit symbol address expansion:
3210   // If $rs is the same as $rd:
3211   // (d)la $rd, sym($rd)     => lui   $at, %hi(sym)
3212   //                            ori   $at, $at, %lo(sym)
3213   //                            addu  $rd, $at, $rd
3214   // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
3215   // (d)la $rd, sym/sym($rs) => lui   $rd, %hi(sym)
3216   //                            ori   $rd, $rd, %lo(sym)
3217   //                            (addu $rd, $rd, $rs)
3218   MCRegister TmpReg = DstReg;
3219   if (UseSrcReg &&
3220       getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
3221     // If $rs is the same as $rd, we need to use AT.
3222     // If it is not available we exit.
3223     MCRegister ATReg = getATReg(IDLoc);
3224     if (!ATReg)
3225       return true;
3226     TmpReg = ATReg;
3227   }
3228 
3229   TOut.emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3230   TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
3231                IDLoc, STI);
3232 
3233   if (UseSrcReg)
3234     TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3235   else
3236     assert(
3237         getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
3238 
3239   return false;
3240 }
3241 
3242 // Each double-precision register DO-D15 overlaps with two of the single
3243 // precision registers F0-F31. As an example, all of the following hold true:
3244 // D0 + 1 == F1, F1 + 1 == D1, F1 + 1 == F2, depending on the context.
nextReg(MCRegister Reg)3245 static MCRegister nextReg(MCRegister Reg) {
3246   if (MipsMCRegisterClasses[Mips::FGR32RegClassID].contains(Reg))
3247     return Reg == (unsigned)Mips::F31 ? (unsigned)Mips::F0 : Reg + 1;
3248   switch (Reg.id()) {
3249   default: llvm_unreachable("Unknown register in assembly macro expansion!");
3250   case Mips::ZERO: return Mips::AT;
3251   case Mips::AT:   return Mips::V0;
3252   case Mips::V0:   return Mips::V1;
3253   case Mips::V1:   return Mips::A0;
3254   case Mips::A0:   return Mips::A1;
3255   case Mips::A1:   return Mips::A2;
3256   case Mips::A2:   return Mips::A3;
3257   case Mips::A3:   return Mips::T0;
3258   case Mips::T0:   return Mips::T1;
3259   case Mips::T1:   return Mips::T2;
3260   case Mips::T2:   return Mips::T3;
3261   case Mips::T3:   return Mips::T4;
3262   case Mips::T4:   return Mips::T5;
3263   case Mips::T5:   return Mips::T6;
3264   case Mips::T6:   return Mips::T7;
3265   case Mips::T7:   return Mips::S0;
3266   case Mips::S0:   return Mips::S1;
3267   case Mips::S1:   return Mips::S2;
3268   case Mips::S2:   return Mips::S3;
3269   case Mips::S3:   return Mips::S4;
3270   case Mips::S4:   return Mips::S5;
3271   case Mips::S5:   return Mips::S6;
3272   case Mips::S6:   return Mips::S7;
3273   case Mips::S7:   return Mips::T8;
3274   case Mips::T8:   return Mips::T9;
3275   case Mips::T9:   return Mips::K0;
3276   case Mips::K0:   return Mips::K1;
3277   case Mips::K1:   return Mips::GP;
3278   case Mips::GP:   return Mips::SP;
3279   case Mips::SP:   return Mips::FP;
3280   case Mips::FP:   return Mips::RA;
3281   case Mips::RA:   return Mips::ZERO;
3282   case Mips::D0:   return Mips::F1;
3283   case Mips::D1:   return Mips::F3;
3284   case Mips::D2:   return Mips::F5;
3285   case Mips::D3:   return Mips::F7;
3286   case Mips::D4:   return Mips::F9;
3287   case Mips::D5:   return Mips::F11;
3288   case Mips::D6:   return Mips::F13;
3289   case Mips::D7:   return Mips::F15;
3290   case Mips::D8:   return Mips::F17;
3291   case Mips::D9:   return Mips::F19;
3292   case Mips::D10:   return Mips::F21;
3293   case Mips::D11:   return Mips::F23;
3294   case Mips::D12:   return Mips::F25;
3295   case Mips::D13:   return Mips::F27;
3296   case Mips::D14:   return Mips::F29;
3297   case Mips::D15:   return Mips::F31;
3298   }
3299 }
3300 
3301 // FIXME: This method is too general. In principle we should compute the number
3302 // of instructions required to synthesize the immediate inline compared to
3303 // synthesizing the address inline and relying on non .text sections.
3304 // For static O32 and N32 this may yield a small benefit, for static N64 this is
3305 // likely to yield a much larger benefit as we have to synthesize a 64bit
3306 // address to load a 64 bit value.
emitPartialAddress(MipsTargetStreamer & TOut,SMLoc IDLoc,MCSymbol * Sym)3307 bool MipsAsmParser::emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc,
3308                                        MCSymbol *Sym) {
3309   MCRegister ATReg = getATReg(IDLoc);
3310   if (!ATReg)
3311     return true;
3312 
3313   if(IsPicEnabled) {
3314     const MCExpr *GotSym = MCSymbolRefExpr::create(Sym, getContext());
3315     const auto *GotExpr =
3316         MCSpecifierExpr::create(GotSym, Mips::S_GOT, getContext());
3317 
3318     if(isABI_O32() || isABI_N32()) {
3319       TOut.emitRRX(Mips::LW, ATReg, GPReg, MCOperand::createExpr(GotExpr),
3320                    IDLoc, STI);
3321     } else { //isABI_N64()
3322       TOut.emitRRX(Mips::LD, ATReg, GPReg, MCOperand::createExpr(GotExpr),
3323                    IDLoc, STI);
3324     }
3325   } else { //!IsPicEnabled
3326     const MCExpr *HiSym = MCSymbolRefExpr::create(Sym, getContext());
3327     const auto *HiExpr =
3328         MCSpecifierExpr::create(HiSym, Mips::S_HI, getContext());
3329 
3330     // FIXME: This is technically correct but gives a different result to gas,
3331     // but gas is incomplete there (it has a fixme noting it doesn't work with
3332     // 64-bit addresses).
3333     // FIXME: With -msym32 option, the address expansion for N64 should probably
3334     // use the O32 / N32 case. It's safe to use the 64 address expansion as the
3335     // symbol's value is considered sign extended.
3336     if(isABI_O32() || isABI_N32()) {
3337       TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3338     } else { //isABI_N64()
3339       const MCExpr *HighestSym = MCSymbolRefExpr::create(Sym, getContext());
3340       const auto *HighestExpr =
3341           MCSpecifierExpr::create(HighestSym, Mips::S_HIGHEST, getContext());
3342       const MCExpr *HigherSym = MCSymbolRefExpr::create(Sym, getContext());
3343       const auto *HigherExpr =
3344           MCSpecifierExpr::create(HigherSym, Mips::S_HIGHER, getContext());
3345 
3346       TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
3347                   STI);
3348       TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3349                    MCOperand::createExpr(HigherExpr), IDLoc, STI);
3350       TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3351       TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
3352                    IDLoc, STI);
3353       TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3354     }
3355   }
3356   return false;
3357 }
3358 
convertIntToDoubleImm(uint64_t ImmOp64)3359 static uint64_t convertIntToDoubleImm(uint64_t ImmOp64) {
3360   // If ImmOp64 is AsmToken::Integer type (all bits set to zero in the
3361   // exponent field), convert it to double (e.g. 1 to 1.0)
3362   if ((Hi_32(ImmOp64) & 0x7ff00000) == 0) {
3363     APFloat RealVal(APFloat::IEEEdouble(), ImmOp64);
3364     ImmOp64 = RealVal.bitcastToAPInt().getZExtValue();
3365   }
3366   return ImmOp64;
3367 }
3368 
covertDoubleImmToSingleImm(uint64_t ImmOp64)3369 static uint32_t covertDoubleImmToSingleImm(uint64_t ImmOp64) {
3370   // Conversion of a double in an uint64_t to a float in a uint32_t,
3371   // retaining the bit pattern of a float.
3372   double DoubleImm = llvm::bit_cast<double>(ImmOp64);
3373   float TmpFloat = static_cast<float>(DoubleImm);
3374   return llvm::bit_cast<uint32_t>(TmpFloat);
3375 }
3376 
expandLoadSingleImmToGPR(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)3377 bool MipsAsmParser::expandLoadSingleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3378                                              MCStreamer &Out,
3379                                              const MCSubtargetInfo *STI) {
3380   assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3381   assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3382          "Invalid instruction operand.");
3383 
3384   MCRegister FirstReg = Inst.getOperand(0).getReg();
3385   uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3386 
3387   uint32_t ImmOp32 = covertDoubleImmToSingleImm(convertIntToDoubleImm(ImmOp64));
3388 
3389   return loadImmediate(ImmOp32, FirstReg, MCRegister(), true, false, IDLoc, Out,
3390                        STI);
3391 }
3392 
expandLoadSingleImmToFPR(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)3393 bool MipsAsmParser::expandLoadSingleImmToFPR(MCInst &Inst, SMLoc IDLoc,
3394                                              MCStreamer &Out,
3395                                              const MCSubtargetInfo *STI) {
3396   MipsTargetStreamer &TOut = getTargetStreamer();
3397   assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3398   assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3399          "Invalid instruction operand.");
3400 
3401   MCRegister FirstReg = Inst.getOperand(0).getReg();
3402   uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3403 
3404   ImmOp64 = convertIntToDoubleImm(ImmOp64);
3405 
3406   uint32_t ImmOp32 = covertDoubleImmToSingleImm(ImmOp64);
3407 
3408   MCRegister TmpReg = Mips::ZERO;
3409   if (ImmOp32 != 0) {
3410     TmpReg = getATReg(IDLoc);
3411     if (!TmpReg)
3412       return true;
3413   }
3414 
3415   if (Lo_32(ImmOp64) == 0) {
3416     if (TmpReg != Mips::ZERO && loadImmediate(ImmOp32, TmpReg, MCRegister(),
3417                                               true, false, IDLoc, Out, STI))
3418       return true;
3419     TOut.emitRR(Mips::MTC1, FirstReg, TmpReg, IDLoc, STI);
3420     return false;
3421   }
3422 
3423   MCSection *CS = getStreamer().getCurrentSectionOnly();
3424   // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3425   // where appropriate.
3426   MCSection *ReadOnlySection =
3427       getContext().getELFSection(".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3428 
3429   MCSymbol *Sym = getContext().createTempSymbol();
3430   const MCExpr *LoSym = MCSymbolRefExpr::create(Sym, getContext());
3431   const auto *LoExpr = MCSpecifierExpr::create(LoSym, Mips::S_LO, getContext());
3432 
3433   getStreamer().switchSection(ReadOnlySection);
3434   getStreamer().emitLabel(Sym, IDLoc);
3435   getStreamer().emitInt32(ImmOp32);
3436   getStreamer().switchSection(CS);
3437 
3438   if (emitPartialAddress(TOut, IDLoc, Sym))
3439     return true;
3440   TOut.emitRRX(Mips::LWC1, FirstReg, TmpReg, MCOperand::createExpr(LoExpr),
3441                IDLoc, STI);
3442   return false;
3443 }
3444 
expandLoadDoubleImmToGPR(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)3445 bool MipsAsmParser::expandLoadDoubleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3446                                              MCStreamer &Out,
3447                                              const MCSubtargetInfo *STI) {
3448   MipsTargetStreamer &TOut = getTargetStreamer();
3449   assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3450   assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3451          "Invalid instruction operand.");
3452 
3453   MCRegister FirstReg = Inst.getOperand(0).getReg();
3454   uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3455 
3456   ImmOp64 = convertIntToDoubleImm(ImmOp64);
3457 
3458   if (Lo_32(ImmOp64) == 0) {
3459     if (isGP64bit()) {
3460       if (loadImmediate(ImmOp64, FirstReg, MCRegister(), false, false, IDLoc,
3461                         Out, STI))
3462         return true;
3463     } else {
3464       if (loadImmediate(Hi_32(ImmOp64), FirstReg, MCRegister(), true, false,
3465                         IDLoc, Out, STI))
3466         return true;
3467 
3468       if (loadImmediate(0, nextReg(FirstReg), MCRegister(), true, false, IDLoc,
3469                         Out, STI))
3470         return true;
3471     }
3472     return false;
3473   }
3474 
3475   MCSection *CS = getStreamer().getCurrentSectionOnly();
3476   MCSection *ReadOnlySection =
3477       getContext().getELFSection(".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3478 
3479   MCSymbol *Sym = getContext().createTempSymbol();
3480   const MCExpr *LoSym = MCSymbolRefExpr::create(Sym, getContext());
3481   const auto *LoExpr = MCSpecifierExpr::create(LoSym, Mips::S_LO, getContext());
3482 
3483   getStreamer().switchSection(ReadOnlySection);
3484   getStreamer().emitLabel(Sym, IDLoc);
3485   getStreamer().emitValueToAlignment(Align(8));
3486   getStreamer().emitIntValue(ImmOp64, 8);
3487   getStreamer().switchSection(CS);
3488 
3489   MCRegister TmpReg = getATReg(IDLoc);
3490   if (!TmpReg)
3491     return true;
3492 
3493   if (emitPartialAddress(TOut, IDLoc, Sym))
3494     return true;
3495 
3496   TOut.emitRRX(isABI_N64() ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3497                MCOperand::createExpr(LoExpr), IDLoc, STI);
3498 
3499   if (isGP64bit())
3500     TOut.emitRRI(Mips::LD, FirstReg, TmpReg, 0, IDLoc, STI);
3501   else {
3502     TOut.emitRRI(Mips::LW, FirstReg, TmpReg, 0, IDLoc, STI);
3503     TOut.emitRRI(Mips::LW, nextReg(FirstReg), TmpReg, 4, IDLoc, STI);
3504   }
3505   return false;
3506 }
3507 
expandLoadDoubleImmToFPR(MCInst & Inst,bool Is64FPU,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)3508 bool MipsAsmParser::expandLoadDoubleImmToFPR(MCInst &Inst, bool Is64FPU,
3509                                              SMLoc IDLoc, MCStreamer &Out,
3510                                              const MCSubtargetInfo *STI) {
3511   MipsTargetStreamer &TOut = getTargetStreamer();
3512   assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3513   assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3514          "Invalid instruction operand.");
3515 
3516   MCRegister FirstReg = Inst.getOperand(0).getReg();
3517   uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3518 
3519   ImmOp64 = convertIntToDoubleImm(ImmOp64);
3520 
3521   MCRegister TmpReg = Mips::ZERO;
3522   if (ImmOp64 != 0) {
3523     TmpReg = getATReg(IDLoc);
3524     if (!TmpReg)
3525       return true;
3526   }
3527 
3528   if ((Lo_32(ImmOp64) == 0) &&
3529       !((Hi_32(ImmOp64) & 0xffff0000) && (Hi_32(ImmOp64) & 0x0000ffff))) {
3530     if (isGP64bit()) {
3531       if (TmpReg != Mips::ZERO && loadImmediate(ImmOp64, TmpReg, MCRegister(),
3532                                                 false, false, IDLoc, Out, STI))
3533         return true;
3534       TOut.emitRR(Mips::DMTC1, FirstReg, TmpReg, IDLoc, STI);
3535       return false;
3536     }
3537 
3538     if (TmpReg != Mips::ZERO &&
3539         loadImmediate(Hi_32(ImmOp64), TmpReg, MCRegister(), true, false, IDLoc,
3540                       Out, STI))
3541       return true;
3542 
3543     if (hasMips32r2()) {
3544       TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3545       TOut.emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, TmpReg, IDLoc, STI);
3546     } else {
3547       TOut.emitRR(Mips::MTC1, nextReg(FirstReg), TmpReg, IDLoc, STI);
3548       TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3549     }
3550     return false;
3551   }
3552 
3553   MCSection *CS = getStreamer().getCurrentSectionOnly();
3554   // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3555   // where appropriate.
3556   MCSection *ReadOnlySection =
3557       getContext().getELFSection(".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3558 
3559   MCSymbol *Sym = getContext().createTempSymbol();
3560   const MCExpr *LoSym = MCSymbolRefExpr::create(Sym, getContext());
3561   const auto *LoExpr = MCSpecifierExpr::create(LoSym, Mips::S_LO, getContext());
3562 
3563   getStreamer().switchSection(ReadOnlySection);
3564   getStreamer().emitLabel(Sym, IDLoc);
3565   getStreamer().emitValueToAlignment(Align(8));
3566   getStreamer().emitIntValue(ImmOp64, 8);
3567   getStreamer().switchSection(CS);
3568 
3569   if (emitPartialAddress(TOut, IDLoc, Sym))
3570     return true;
3571 
3572   TOut.emitRRX(Is64FPU ? Mips::LDC164 : Mips::LDC1, FirstReg, TmpReg,
3573                MCOperand::createExpr(LoExpr), IDLoc, STI);
3574 
3575   return false;
3576 }
3577 
expandUncondBranchMMPseudo(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)3578 bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
3579                                                MCStreamer &Out,
3580                                                const MCSubtargetInfo *STI) {
3581   MipsTargetStreamer &TOut = getTargetStreamer();
3582 
3583   assert(MII.get(Inst.getOpcode()).getNumOperands() == 1 &&
3584          "unexpected number of operands");
3585 
3586   MCOperand Offset = Inst.getOperand(0);
3587   if (Offset.isExpr()) {
3588     Inst.clear();
3589     Inst.setOpcode(Mips::BEQ_MM);
3590     Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3591     Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3592     Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
3593   } else {
3594     assert(Offset.isImm() && "expected immediate operand kind");
3595     if (isInt<11>(Offset.getImm())) {
3596       // If offset fits into 11 bits then this instruction becomes microMIPS
3597       // 16-bit unconditional branch instruction.
3598       if (inMicroMipsMode())
3599         Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
3600     } else {
3601       if (!isInt<17>(Offset.getImm()))
3602         return Error(IDLoc, "branch target out of range");
3603       if (offsetToAlignment(Offset.getImm(), Align(2)))
3604         return Error(IDLoc, "branch to misaligned address");
3605       Inst.clear();
3606       Inst.setOpcode(Mips::BEQ_MM);
3607       Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3608       Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3609       Inst.addOperand(MCOperand::createImm(Offset.getImm()));
3610     }
3611   }
3612   Out.emitInstruction(Inst, *STI);
3613 
3614   // If .set reorder is active and branch instruction has a delay slot,
3615   // emit a NOP after it.
3616   const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
3617   if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
3618     TOut.emitEmptyDelaySlot(true, IDLoc, STI);
3619 
3620   return false;
3621 }
3622 
expandBranchImm(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)3623 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3624                                     const MCSubtargetInfo *STI) {
3625   MipsTargetStreamer &TOut = getTargetStreamer();
3626   const MCOperand &DstRegOp = Inst.getOperand(0);
3627   assert(DstRegOp.isReg() && "expected register operand kind");
3628 
3629   const MCOperand &ImmOp = Inst.getOperand(1);
3630   assert(ImmOp.isImm() && "expected immediate operand kind");
3631 
3632   const MCOperand &MemOffsetOp = Inst.getOperand(2);
3633   assert((MemOffsetOp.isImm() || MemOffsetOp.isExpr()) &&
3634          "expected immediate or expression operand");
3635 
3636   bool IsLikely = false;
3637 
3638   unsigned OpCode = 0;
3639   switch(Inst.getOpcode()) {
3640     case Mips::BneImm:
3641       OpCode = Mips::BNE;
3642       break;
3643     case Mips::BeqImm:
3644       OpCode = Mips::BEQ;
3645       break;
3646     case Mips::BEQLImmMacro:
3647       OpCode = Mips::BEQL;
3648       IsLikely = true;
3649       break;
3650     case Mips::BNELImmMacro:
3651       OpCode = Mips::BNEL;
3652       IsLikely = true;
3653       break;
3654     default:
3655       llvm_unreachable("Unknown immediate branch pseudo-instruction.");
3656       break;
3657   }
3658 
3659   int64_t ImmValue = ImmOp.getImm();
3660   if (ImmValue == 0) {
3661     if (IsLikely) {
3662       TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO,
3663                    MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3664       TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3665     } else
3666       TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
3667               STI);
3668   } else {
3669     warnIfNoMacro(IDLoc);
3670 
3671     MCRegister ATReg = getATReg(IDLoc);
3672     if (!ATReg)
3673       return true;
3674 
3675     if (loadImmediate(ImmValue, ATReg, MCRegister(), !isGP64bit(), true, IDLoc,
3676                       Out, STI))
3677       return true;
3678 
3679     if (IsLikely && MemOffsetOp.isExpr()) {
3680       TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg,
3681               MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3682       TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3683     } else
3684       TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, STI);
3685   }
3686   return false;
3687 }
3688 
expandMem16Inst(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI,bool IsLoad)3689 void MipsAsmParser::expandMem16Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3690                                     const MCSubtargetInfo *STI, bool IsLoad) {
3691   unsigned NumOp = Inst.getNumOperands();
3692   assert((NumOp == 3 || NumOp == 4) && "unexpected operands number");
3693   unsigned StartOp = NumOp == 3 ? 0 : 1;
3694 
3695   const MCOperand &DstRegOp = Inst.getOperand(StartOp);
3696   assert(DstRegOp.isReg() && "expected register operand kind");
3697   const MCOperand &BaseRegOp = Inst.getOperand(StartOp + 1);
3698   assert(BaseRegOp.isReg() && "expected register operand kind");
3699   const MCOperand &OffsetOp = Inst.getOperand(StartOp + 2);
3700 
3701   MipsTargetStreamer &TOut = getTargetStreamer();
3702   unsigned OpCode = Inst.getOpcode();
3703   MCRegister DstReg = DstRegOp.getReg();
3704   MCRegister BaseReg = BaseRegOp.getReg();
3705   MCRegister TmpReg = DstReg;
3706 
3707   const MCInstrDesc &Desc = MII.get(OpCode);
3708   int16_t DstRegClass = Desc.operands()[StartOp].RegClass;
3709   unsigned DstRegClassID =
3710       getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3711   bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3712                (DstRegClassID == Mips::GPR64RegClassID);
3713 
3714   if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3715     // At this point we need AT to perform the expansions
3716     // and we exit if it is not available.
3717     TmpReg = getATReg(IDLoc);
3718     if (!TmpReg)
3719       return;
3720   }
3721 
3722   auto emitInstWithOffset = [&](const MCOperand &Off) {
3723     if (NumOp == 3)
3724       TOut.emitRRX(OpCode, DstReg, TmpReg, Off, IDLoc, STI);
3725     else
3726       TOut.emitRRRX(OpCode, DstReg, DstReg, TmpReg, Off, IDLoc, STI);
3727   };
3728 
3729   if (OffsetOp.isImm()) {
3730     int64_t LoOffset = OffsetOp.getImm() & 0xffff;
3731     int64_t HiOffset = OffsetOp.getImm() & ~0xffff;
3732 
3733     // If msb of LoOffset is 1(negative number) we must increment
3734     // HiOffset to account for the sign-extension of the low part.
3735     if (LoOffset & 0x8000)
3736       HiOffset += 0x10000;
3737 
3738     bool IsLargeOffset = HiOffset != 0;
3739 
3740     if (IsLargeOffset) {
3741       bool Is32BitImm = isInt<32>(OffsetOp.getImm());
3742       if (loadImmediate(HiOffset, TmpReg, MCRegister(), Is32BitImm, true, IDLoc,
3743                         Out, STI))
3744         return;
3745     }
3746 
3747     if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3748       TOut.emitRRR(ABI.ArePtrs64bit() ? Mips::DADDu : Mips::ADDu, TmpReg,
3749                    TmpReg, BaseReg, IDLoc, STI);
3750     emitInstWithOffset(MCOperand::createImm(int16_t(LoOffset)));
3751     return;
3752   }
3753 
3754   if (OffsetOp.isExpr()) {
3755     if (inPicMode()) {
3756       // FIXME:
3757       // c) Check that immediates of R_MIPS_GOT16/R_MIPS_LO16 relocations
3758       //    do not exceed 16-bit.
3759       // d) Use R_MIPS_GOT_PAGE/R_MIPS_GOT_OFST relocations instead
3760       //    of R_MIPS_GOT_DISP in appropriate cases to reduce number
3761       //    of GOT entries.
3762       MCValue Res;
3763       if (!OffsetOp.getExpr()->evaluateAsRelocatable(Res, nullptr)) {
3764         Error(IDLoc, "expected relocatable expression");
3765         return;
3766       }
3767       if (Res.getSubSym()) {
3768         Error(IDLoc, "expected relocatable expression with only one symbol");
3769         return;
3770       }
3771 
3772       loadAndAddSymbolAddress(
3773           MCSymbolRefExpr::create(Res.getAddSym(), getContext()), TmpReg,
3774           BaseReg, !ABI.ArePtrs64bit(), IDLoc, Out, STI);
3775       emitInstWithOffset(MCOperand::createImm(int16_t(Res.getConstant())));
3776     } else {
3777       // FIXME: Implement 64-bit case.
3778       // 1) lw $8, sym => lui $8,  %hi(sym)
3779       //                  lw  $8,  %lo(sym)($8)
3780       // 2) sw $8, sym => lui $at, %hi(sym)
3781       //                  sw  $8,  %lo(sym)($at)
3782       const MCExpr *OffExpr = OffsetOp.getExpr();
3783       MCOperand LoOperand = MCOperand::createExpr(
3784           MCSpecifierExpr::create(OffExpr, Mips::S_LO, getContext()));
3785       MCOperand HiOperand = MCOperand::createExpr(
3786           MCSpecifierExpr::create(OffExpr, Mips::S_HI, getContext()));
3787 
3788       if (ABI.IsN64()) {
3789         MCOperand HighestOperand = MCOperand::createExpr(
3790             MCSpecifierExpr::create(OffExpr, Mips::S_HIGHEST, getContext()));
3791         MCOperand HigherOperand = MCOperand::createExpr(
3792             MCSpecifierExpr::create(OffExpr, Mips::S_HIGHER, getContext()));
3793 
3794         TOut.emitRX(Mips::LUi, TmpReg, HighestOperand, IDLoc, STI);
3795         TOut.emitRRX(Mips::DADDiu, TmpReg, TmpReg, HigherOperand, IDLoc, STI);
3796         TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3797         TOut.emitRRX(Mips::DADDiu, TmpReg, TmpReg, HiOperand, IDLoc, STI);
3798         TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3799         if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3800           TOut.emitRRR(Mips::DADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3801         emitInstWithOffset(LoOperand);
3802       } else {
3803         // Generate the base address in TmpReg.
3804         TOut.emitRX(Mips::LUi, TmpReg, HiOperand, IDLoc, STI);
3805         if (BaseReg != Mips::ZERO)
3806           TOut.emitRRR(Mips::ADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3807         // Emit the load or store with the adjusted base and offset.
3808         emitInstWithOffset(LoOperand);
3809       }
3810     }
3811     return;
3812   }
3813 
3814   llvm_unreachable("unexpected operand type");
3815 }
3816 
expandMem9Inst(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI,bool IsLoad)3817 void MipsAsmParser::expandMem9Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3818                                    const MCSubtargetInfo *STI, bool IsLoad) {
3819   unsigned NumOp = Inst.getNumOperands();
3820   assert((NumOp == 3 || NumOp == 4) && "unexpected operands number");
3821   unsigned StartOp = NumOp == 3 ? 0 : 1;
3822 
3823   const MCOperand &DstRegOp = Inst.getOperand(StartOp);
3824   assert(DstRegOp.isReg() && "expected register operand kind");
3825   const MCOperand &BaseRegOp = Inst.getOperand(StartOp + 1);
3826   assert(BaseRegOp.isReg() && "expected register operand kind");
3827   const MCOperand &OffsetOp = Inst.getOperand(StartOp + 2);
3828 
3829   MipsTargetStreamer &TOut = getTargetStreamer();
3830   unsigned OpCode = Inst.getOpcode();
3831   MCRegister DstReg = DstRegOp.getReg();
3832   MCRegister BaseReg = BaseRegOp.getReg();
3833   MCRegister TmpReg = DstReg;
3834 
3835   const MCInstrDesc &Desc = MII.get(OpCode);
3836   int16_t DstRegClass = Desc.operands()[StartOp].RegClass;
3837   unsigned DstRegClassID =
3838       getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3839   bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3840                (DstRegClassID == Mips::GPR64RegClassID);
3841 
3842   if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3843     // At this point we need AT to perform the expansions
3844     // and we exit if it is not available.
3845     TmpReg = getATReg(IDLoc);
3846     if (!TmpReg)
3847       return;
3848   }
3849 
3850   auto emitInst = [&]() {
3851     if (NumOp == 3)
3852       TOut.emitRRX(OpCode, DstReg, TmpReg, MCOperand::createImm(0), IDLoc, STI);
3853     else
3854       TOut.emitRRRX(OpCode, DstReg, DstReg, TmpReg, MCOperand::createImm(0),
3855                     IDLoc, STI);
3856   };
3857 
3858   if (OffsetOp.isImm()) {
3859     loadImmediate(OffsetOp.getImm(), TmpReg, BaseReg, !ABI.ArePtrs64bit(), true,
3860                   IDLoc, Out, STI);
3861     emitInst();
3862     return;
3863   }
3864 
3865   if (OffsetOp.isExpr()) {
3866     loadAndAddSymbolAddress(OffsetOp.getExpr(), TmpReg, BaseReg,
3867                             !ABI.ArePtrs64bit(), IDLoc, Out, STI);
3868     emitInst();
3869     return;
3870   }
3871 
3872   llvm_unreachable("unexpected operand type");
3873 }
3874 
expandLoadStoreMultiple(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)3875 bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
3876                                             MCStreamer &Out,
3877                                             const MCSubtargetInfo *STI) {
3878   unsigned OpNum = Inst.getNumOperands();
3879   unsigned Opcode = Inst.getOpcode();
3880   unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
3881 
3882   assert(Inst.getOperand(OpNum - 1).isImm() &&
3883          Inst.getOperand(OpNum - 2).isReg() &&
3884          Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
3885 
3886   if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
3887       Inst.getOperand(OpNum - 1).getImm() >= 0 &&
3888       (Inst.getOperand(OpNum - 2).getReg() == Mips::SP ||
3889        Inst.getOperand(OpNum - 2).getReg() == Mips::SP_64) &&
3890       (Inst.getOperand(OpNum - 3).getReg() == Mips::RA ||
3891        Inst.getOperand(OpNum - 3).getReg() == Mips::RA_64)) {
3892     // It can be implemented as SWM16 or LWM16 instruction.
3893     if (inMicroMipsMode() && hasMips32r6())
3894       NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
3895     else
3896       NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
3897   }
3898 
3899   Inst.setOpcode(NewOpcode);
3900   Out.emitInstruction(Inst, *STI);
3901   return false;
3902 }
3903 
expandCondBranches(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)3904 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
3905                                        MCStreamer &Out,
3906                                        const MCSubtargetInfo *STI) {
3907   MipsTargetStreamer &TOut = getTargetStreamer();
3908   bool EmittedNoMacroWarning = false;
3909   unsigned PseudoOpcode = Inst.getOpcode();
3910   MCRegister SrcReg = Inst.getOperand(0).getReg();
3911   const MCOperand &TrgOp = Inst.getOperand(1);
3912   const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
3913 
3914   unsigned ZeroSrcOpcode, ZeroTrgOpcode;
3915   bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
3916 
3917   MCRegister TrgReg;
3918   if (TrgOp.isReg())
3919     TrgReg = TrgOp.getReg();
3920   else if (TrgOp.isImm()) {
3921     warnIfNoMacro(IDLoc);
3922     EmittedNoMacroWarning = true;
3923 
3924     TrgReg = getATReg(IDLoc);
3925     if (!TrgReg)
3926       return true;
3927 
3928     switch(PseudoOpcode) {
3929     default:
3930       llvm_unreachable("unknown opcode for branch pseudo-instruction");
3931     case Mips::BLTImmMacro:
3932       PseudoOpcode = Mips::BLT;
3933       break;
3934     case Mips::BLEImmMacro:
3935       PseudoOpcode = Mips::BLE;
3936       break;
3937     case Mips::BGEImmMacro:
3938       PseudoOpcode = Mips::BGE;
3939       break;
3940     case Mips::BGTImmMacro:
3941       PseudoOpcode = Mips::BGT;
3942       break;
3943     case Mips::BLTUImmMacro:
3944       PseudoOpcode = Mips::BLTU;
3945       break;
3946     case Mips::BLEUImmMacro:
3947       PseudoOpcode = Mips::BLEU;
3948       break;
3949     case Mips::BGEUImmMacro:
3950       PseudoOpcode = Mips::BGEU;
3951       break;
3952     case Mips::BGTUImmMacro:
3953       PseudoOpcode = Mips::BGTU;
3954       break;
3955     case Mips::BLTLImmMacro:
3956       PseudoOpcode = Mips::BLTL;
3957       break;
3958     case Mips::BLELImmMacro:
3959       PseudoOpcode = Mips::BLEL;
3960       break;
3961     case Mips::BGELImmMacro:
3962       PseudoOpcode = Mips::BGEL;
3963       break;
3964     case Mips::BGTLImmMacro:
3965       PseudoOpcode = Mips::BGTL;
3966       break;
3967     case Mips::BLTULImmMacro:
3968       PseudoOpcode = Mips::BLTUL;
3969       break;
3970     case Mips::BLEULImmMacro:
3971       PseudoOpcode = Mips::BLEUL;
3972       break;
3973     case Mips::BGEULImmMacro:
3974       PseudoOpcode = Mips::BGEUL;
3975       break;
3976     case Mips::BGTULImmMacro:
3977       PseudoOpcode = Mips::BGTUL;
3978       break;
3979     }
3980 
3981     if (loadImmediate(TrgOp.getImm(), TrgReg, MCRegister(), !isGP64bit(), false,
3982                       IDLoc, Out, STI))
3983       return true;
3984   }
3985 
3986   switch (PseudoOpcode) {
3987   case Mips::BLT:
3988   case Mips::BLTU:
3989   case Mips::BLTL:
3990   case Mips::BLTUL:
3991     AcceptsEquality = false;
3992     ReverseOrderSLT = false;
3993     IsUnsigned =
3994         ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
3995     IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
3996     ZeroSrcOpcode = Mips::BGTZ;
3997     ZeroTrgOpcode = Mips::BLTZ;
3998     break;
3999   case Mips::BLE:
4000   case Mips::BLEU:
4001   case Mips::BLEL:
4002   case Mips::BLEUL:
4003     AcceptsEquality = true;
4004     ReverseOrderSLT = true;
4005     IsUnsigned =
4006         ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
4007     IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
4008     ZeroSrcOpcode = Mips::BGEZ;
4009     ZeroTrgOpcode = Mips::BLEZ;
4010     break;
4011   case Mips::BGE:
4012   case Mips::BGEU:
4013   case Mips::BGEL:
4014   case Mips::BGEUL:
4015     AcceptsEquality = true;
4016     ReverseOrderSLT = false;
4017     IsUnsigned =
4018         ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
4019     IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
4020     ZeroSrcOpcode = Mips::BLEZ;
4021     ZeroTrgOpcode = Mips::BGEZ;
4022     break;
4023   case Mips::BGT:
4024   case Mips::BGTU:
4025   case Mips::BGTL:
4026   case Mips::BGTUL:
4027     AcceptsEquality = false;
4028     ReverseOrderSLT = true;
4029     IsUnsigned =
4030         ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
4031     IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
4032     ZeroSrcOpcode = Mips::BLTZ;
4033     ZeroTrgOpcode = Mips::BGTZ;
4034     break;
4035   default:
4036     llvm_unreachable("unknown opcode for branch pseudo-instruction");
4037   }
4038 
4039   bool IsTrgRegZero = (TrgReg == Mips::ZERO);
4040   bool IsSrcRegZero = (SrcReg == Mips::ZERO);
4041   if (IsSrcRegZero && IsTrgRegZero) {
4042     // FIXME: All of these Opcode-specific if's are needed for compatibility
4043     // with GAS' behaviour. However, they may not generate the most efficient
4044     // code in some circumstances.
4045     if (PseudoOpcode == Mips::BLT) {
4046       TOut.emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
4047                   IDLoc, STI);
4048       return false;
4049     }
4050     if (PseudoOpcode == Mips::BLE) {
4051       TOut.emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
4052                   IDLoc, STI);
4053       Warning(IDLoc, "branch is always taken");
4054       return false;
4055     }
4056     if (PseudoOpcode == Mips::BGE) {
4057       TOut.emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
4058                   IDLoc, STI);
4059       Warning(IDLoc, "branch is always taken");
4060       return false;
4061     }
4062     if (PseudoOpcode == Mips::BGT) {
4063       TOut.emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
4064                   IDLoc, STI);
4065       return false;
4066     }
4067     if (PseudoOpcode == Mips::BGTU) {
4068       TOut.emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
4069                    MCOperand::createExpr(OffsetExpr), IDLoc, STI);
4070       return false;
4071     }
4072     if (AcceptsEquality) {
4073       // If both registers are $0 and the pseudo-branch accepts equality, it
4074       // will always be taken, so we emit an unconditional branch.
4075       TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4076                    MCOperand::createExpr(OffsetExpr), IDLoc, STI);
4077       Warning(IDLoc, "branch is always taken");
4078       return false;
4079     }
4080     // If both registers are $0 and the pseudo-branch does not accept
4081     // equality, it will never be taken, so we don't have to emit anything.
4082     return false;
4083   }
4084   if (IsSrcRegZero || IsTrgRegZero) {
4085     if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
4086         (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
4087       // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
4088       // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
4089       // the pseudo-branch will never be taken, so we don't emit anything.
4090       // This only applies to unsigned pseudo-branches.
4091       return false;
4092     }
4093     if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
4094         (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
4095       // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
4096       // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
4097       // the pseudo-branch will always be taken, so we emit an unconditional
4098       // branch.
4099       // This only applies to unsigned pseudo-branches.
4100       TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4101                    MCOperand::createExpr(OffsetExpr), IDLoc, STI);
4102       Warning(IDLoc, "branch is always taken");
4103       return false;
4104     }
4105     if (IsUnsigned) {
4106       // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
4107       // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
4108       // the pseudo-branch will be taken only when the non-zero register is
4109       // different from 0, so we emit a BNEZ.
4110       //
4111       // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
4112       // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
4113       // the pseudo-branch will be taken only when the non-zero register is
4114       // equal to 0, so we emit a BEQZ.
4115       //
4116       // Because only BLEU and BGEU branch on equality, we can use the
4117       // AcceptsEquality variable to decide when to emit the BEQZ.
4118       TOut.emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
4119                    IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
4120                    MCOperand::createExpr(OffsetExpr), IDLoc, STI);
4121       return false;
4122     }
4123     // If we have a signed pseudo-branch and one of the registers is $0,
4124     // we can use an appropriate compare-to-zero branch. We select which one
4125     // to use in the switch statement above.
4126     TOut.emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
4127                 IsSrcRegZero ? TrgReg : SrcReg,
4128                 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
4129     return false;
4130   }
4131 
4132   // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
4133   // expansions. If it is not available, we return.
4134   MCRegister ATRegNum = getATReg(IDLoc);
4135   if (!ATRegNum)
4136     return true;
4137 
4138   if (!EmittedNoMacroWarning)
4139     warnIfNoMacro(IDLoc);
4140 
4141   // SLT fits well with 2 of our 4 pseudo-branches:
4142   //   BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
4143   //   BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
4144   // If the result of the SLT is 1, we branch, and if it's 0, we don't.
4145   // This is accomplished by using a BNEZ with the result of the SLT.
4146   //
4147   // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
4148   // and BLE with BGT), so we change the BNEZ into a BEQZ.
4149   // Because only BGE and BLE branch on equality, we can use the
4150   // AcceptsEquality variable to decide when to emit the BEQZ.
4151   // Note that the order of the SLT arguments doesn't change between
4152   // opposites.
4153   //
4154   // The same applies to the unsigned variants, except that SLTu is used
4155   // instead of SLT.
4156   TOut.emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
4157                ReverseOrderSLT ? TrgReg : SrcReg,
4158                ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
4159 
4160   TOut.emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
4161                         : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
4162                ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
4163                STI);
4164   return false;
4165 }
4166 
4167 // Expand a integer division macro.
4168 //
4169 // Notably we don't have to emit a warning when encountering $rt as the $zero
4170 // register, or 0 as an immediate. processInstruction() has already done that.
4171 //
4172 // The destination register can only be $zero when expanding (S)DivIMacro or
4173 // D(S)DivMacro.
4174 
expandDivRem(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI,const bool IsMips64,const bool Signed)4175 bool MipsAsmParser::expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4176                                  const MCSubtargetInfo *STI,
4177                                  const bool IsMips64, const bool Signed) {
4178   MipsTargetStreamer &TOut = getTargetStreamer();
4179 
4180   warnIfNoMacro(IDLoc);
4181 
4182   const MCOperand &RdRegOp = Inst.getOperand(0);
4183   assert(RdRegOp.isReg() && "expected register operand kind");
4184   MCRegister RdReg = RdRegOp.getReg();
4185 
4186   const MCOperand &RsRegOp = Inst.getOperand(1);
4187   assert(RsRegOp.isReg() && "expected register operand kind");
4188   MCRegister RsReg = RsRegOp.getReg();
4189 
4190   MCRegister RtReg;
4191   int64_t ImmValue;
4192 
4193   const MCOperand &RtOp = Inst.getOperand(2);
4194   assert((RtOp.isReg() || RtOp.isImm()) &&
4195          "expected register or immediate operand kind");
4196   if (RtOp.isReg())
4197     RtReg = RtOp.getReg();
4198   else
4199     ImmValue = RtOp.getImm();
4200 
4201   unsigned DivOp;
4202   unsigned ZeroReg;
4203   unsigned SubOp;
4204 
4205   if (IsMips64) {
4206     DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
4207     ZeroReg = Mips::ZERO_64;
4208     SubOp = Mips::DSUB;
4209   } else {
4210     DivOp = Signed ? Mips::SDIV : Mips::UDIV;
4211     ZeroReg = Mips::ZERO;
4212     SubOp = Mips::SUB;
4213   }
4214 
4215   bool UseTraps = useTraps();
4216 
4217   unsigned Opcode = Inst.getOpcode();
4218   bool isDiv = Opcode == Mips::SDivMacro || Opcode == Mips::SDivIMacro ||
4219                Opcode == Mips::UDivMacro || Opcode == Mips::UDivIMacro ||
4220                Opcode == Mips::DSDivMacro || Opcode == Mips::DSDivIMacro ||
4221                Opcode == Mips::DUDivMacro || Opcode == Mips::DUDivIMacro;
4222 
4223   bool isRem = Opcode == Mips::SRemMacro || Opcode == Mips::SRemIMacro ||
4224                Opcode == Mips::URemMacro || Opcode == Mips::URemIMacro ||
4225                Opcode == Mips::DSRemMacro || Opcode == Mips::DSRemIMacro ||
4226                Opcode == Mips::DURemMacro || Opcode == Mips::DURemIMacro;
4227 
4228   if (RtOp.isImm()) {
4229     MCRegister ATReg = getATReg(IDLoc);
4230     if (!ATReg)
4231       return true;
4232 
4233     if (ImmValue == 0) {
4234       if (UseTraps)
4235         TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4236       else
4237         TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4238       return false;
4239     }
4240 
4241     if (isRem && (ImmValue == 1 || (Signed && (ImmValue == -1)))) {
4242       TOut.emitRRR(Mips::OR, RdReg, ZeroReg, ZeroReg, IDLoc, STI);
4243       return false;
4244     } else if (isDiv && ImmValue == 1) {
4245       TOut.emitRRR(Mips::OR, RdReg, RsReg, Mips::ZERO, IDLoc, STI);
4246       return false;
4247     } else if (isDiv && Signed && ImmValue == -1) {
4248       TOut.emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI);
4249       return false;
4250     } else {
4251       if (loadImmediate(ImmValue, ATReg, MCRegister(), isInt<32>(ImmValue),
4252                         false, Inst.getLoc(), Out, STI))
4253         return true;
4254       TOut.emitRR(DivOp, RsReg, ATReg, IDLoc, STI);
4255       TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4256       return false;
4257     }
4258     return true;
4259   }
4260 
4261   // If the macro expansion of (d)div(u) or (d)rem(u) would always trap or
4262   // break, insert the trap/break and exit. This gives a different result to
4263   // GAS. GAS has an inconsistency/missed optimization in that not all cases
4264   // are handled equivalently. As the observed behaviour is the same, we're ok.
4265   if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
4266     if (UseTraps) {
4267       TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4268       return false;
4269     }
4270     TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4271     return false;
4272   }
4273 
4274   // (d)rem(u) $0, $X, $Y is a special case. Like div $zero, $X, $Y, it does
4275   // not expand to macro sequence.
4276   if (isRem && (RdReg == Mips::ZERO || RdReg == Mips::ZERO_64)) {
4277     TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4278     return false;
4279   }
4280 
4281   // Temporary label for first branch traget
4282   MCContext &Context = TOut.getContext();
4283   MCSymbol *BrTarget;
4284   MCOperand LabelOp;
4285 
4286   if (UseTraps) {
4287     TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
4288   } else {
4289     // Branch to the li instruction.
4290     BrTarget = Context.createTempSymbol();
4291     LabelOp = MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
4292     TOut.emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
4293   }
4294 
4295   TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4296 
4297   if (!UseTraps)
4298     TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4299 
4300   if (!Signed) {
4301     if (!UseTraps)
4302       TOut.getStreamer().emitLabel(BrTarget);
4303 
4304     TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4305     return false;
4306   }
4307 
4308   MCRegister ATReg = getATReg(IDLoc);
4309   if (!ATReg)
4310     return true;
4311 
4312   if (!UseTraps)
4313     TOut.getStreamer().emitLabel(BrTarget);
4314 
4315   TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, STI);
4316 
4317   // Temporary label for the second branch target.
4318   MCSymbol *BrTargetEnd = Context.createTempSymbol();
4319   MCOperand LabelOpEnd =
4320       MCOperand::createExpr(MCSymbolRefExpr::create(BrTargetEnd, Context));
4321 
4322   // Branch to the mflo instruction.
4323   TOut.emitRRX(Mips::BNE, RtReg, ATReg, LabelOpEnd, IDLoc, STI);
4324 
4325   if (IsMips64) {
4326     TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, STI);
4327     TOut.emitDSLL(ATReg, ATReg, 63, IDLoc, STI);
4328   } else {
4329     TOut.emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, STI);
4330   }
4331 
4332   if (UseTraps)
4333     TOut.emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, STI);
4334   else {
4335     // Branch to the mflo instruction.
4336     TOut.emitRRX(Mips::BNE, RsReg, ATReg, LabelOpEnd, IDLoc, STI);
4337     TOut.emitNop(IDLoc, STI);
4338     TOut.emitII(Mips::BREAK, 0x6, 0, IDLoc, STI);
4339   }
4340 
4341   TOut.getStreamer().emitLabel(BrTargetEnd);
4342   TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4343   return false;
4344 }
4345 
expandTrunc(MCInst & Inst,bool IsDouble,bool Is64FPU,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)4346 bool MipsAsmParser::expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU,
4347                                 SMLoc IDLoc, MCStreamer &Out,
4348                                 const MCSubtargetInfo *STI) {
4349   MipsTargetStreamer &TOut = getTargetStreamer();
4350 
4351   assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4352   assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() &&
4353          Inst.getOperand(2).isReg() && "Invalid instruction operand.");
4354 
4355   MCRegister FirstReg = Inst.getOperand(0).getReg();
4356   MCRegister SecondReg = Inst.getOperand(1).getReg();
4357   MCRegister ThirdReg = Inst.getOperand(2).getReg();
4358 
4359   if (hasMips1() && !hasMips2()) {
4360     MCRegister ATReg = getATReg(IDLoc);
4361     if (!ATReg)
4362       return true;
4363     TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4364     TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4365     TOut.emitNop(IDLoc, STI);
4366     TOut.emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
4367     TOut.emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
4368     TOut.emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
4369     TOut.emitNop(IDLoc, STI);
4370     TOut.emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
4371                          : Mips::CVT_W_S,
4372                 FirstReg, SecondReg, IDLoc, STI);
4373     TOut.emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
4374     TOut.emitNop(IDLoc, STI);
4375     return false;
4376   }
4377 
4378   TOut.emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
4379                        : Mips::TRUNC_W_S,
4380               FirstReg, SecondReg, IDLoc, STI);
4381 
4382   return false;
4383 }
4384 
expandUlh(MCInst & Inst,bool Signed,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)4385 bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
4386                               MCStreamer &Out, const MCSubtargetInfo *STI) {
4387   if (hasMips32r6() || hasMips64r6()) {
4388     return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4389   }
4390 
4391   const MCOperand &DstRegOp = Inst.getOperand(0);
4392   assert(DstRegOp.isReg() && "expected register operand kind");
4393   const MCOperand &SrcRegOp = Inst.getOperand(1);
4394   assert(SrcRegOp.isReg() && "expected register operand kind");
4395   const MCOperand &OffsetImmOp = Inst.getOperand(2);
4396   assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4397 
4398   MipsTargetStreamer &TOut = getTargetStreamer();
4399   MCRegister DstReg = DstRegOp.getReg();
4400   MCRegister SrcReg = SrcRegOp.getReg();
4401   int64_t OffsetValue = OffsetImmOp.getImm();
4402 
4403   // NOTE: We always need AT for ULHU, as it is always used as the source
4404   // register for one of the LBu's.
4405   warnIfNoMacro(IDLoc);
4406   MCRegister ATReg = getATReg(IDLoc);
4407   if (!ATReg)
4408     return true;
4409 
4410   bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4411   if (IsLargeOffset) {
4412     if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4413                       IDLoc, Out, STI))
4414       return true;
4415   }
4416 
4417   int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
4418   int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4419   if (isLittle())
4420     std::swap(FirstOffset, SecondOffset);
4421 
4422   MCRegister FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
4423   MCRegister SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
4424 
4425   MCRegister LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
4426   MCRegister SllReg = IsLargeOffset ? DstReg : ATReg;
4427 
4428   TOut.emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
4429                FirstOffset, IDLoc, STI);
4430   TOut.emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4431   TOut.emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4432   TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4433 
4434   return false;
4435 }
4436 
expandUsh(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)4437 bool MipsAsmParser::expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4438                               const MCSubtargetInfo *STI) {
4439   if (hasMips32r6() || hasMips64r6()) {
4440     return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4441   }
4442 
4443   const MCOperand &DstRegOp = Inst.getOperand(0);
4444   assert(DstRegOp.isReg() && "expected register operand kind");
4445   const MCOperand &SrcRegOp = Inst.getOperand(1);
4446   assert(SrcRegOp.isReg() && "expected register operand kind");
4447   const MCOperand &OffsetImmOp = Inst.getOperand(2);
4448   assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4449 
4450   MipsTargetStreamer &TOut = getTargetStreamer();
4451   MCRegister DstReg = DstRegOp.getReg();
4452   MCRegister SrcReg = SrcRegOp.getReg();
4453   int64_t OffsetValue = OffsetImmOp.getImm();
4454 
4455   warnIfNoMacro(IDLoc);
4456   MCRegister ATReg = getATReg(IDLoc);
4457   if (!ATReg)
4458     return true;
4459 
4460   bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4461   if (IsLargeOffset) {
4462     if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4463                       IDLoc, Out, STI))
4464       return true;
4465   }
4466 
4467   int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4468   int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
4469   if (isLittle())
4470     std::swap(FirstOffset, SecondOffset);
4471 
4472   if (IsLargeOffset) {
4473     TOut.emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4474     TOut.emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
4475     TOut.emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4476     TOut.emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4477     TOut.emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4478     TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4479   } else {
4480     TOut.emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4481     TOut.emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
4482     TOut.emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4483   }
4484 
4485   return false;
4486 }
4487 
expandUxw(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)4488 bool MipsAsmParser::expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4489                               const MCSubtargetInfo *STI) {
4490   if (hasMips32r6() || hasMips64r6()) {
4491     return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4492   }
4493 
4494   const MCOperand &DstRegOp = Inst.getOperand(0);
4495   assert(DstRegOp.isReg() && "expected register operand kind");
4496   const MCOperand &SrcRegOp = Inst.getOperand(1);
4497   assert(SrcRegOp.isReg() && "expected register operand kind");
4498   const MCOperand &OffsetImmOp = Inst.getOperand(2);
4499   assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4500 
4501   MipsTargetStreamer &TOut = getTargetStreamer();
4502   MCRegister DstReg = DstRegOp.getReg();
4503   MCRegister SrcReg = SrcRegOp.getReg();
4504   int64_t OffsetValue = OffsetImmOp.getImm();
4505 
4506   // Compute left/right load/store offsets.
4507   bool IsLargeOffset = !(isInt<16>(OffsetValue + 3) && isInt<16>(OffsetValue));
4508   int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
4509   int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
4510   if (isLittle())
4511     std::swap(LxlOffset, LxrOffset);
4512 
4513   bool IsLoadInst = (Inst.getOpcode() == Mips::Ulw);
4514   bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
4515   MCRegister TmpReg = SrcReg;
4516   if (IsLargeOffset || DoMove) {
4517     warnIfNoMacro(IDLoc);
4518     TmpReg = getATReg(IDLoc);
4519     if (!TmpReg)
4520       return true;
4521   }
4522 
4523   if (IsLargeOffset) {
4524     if (loadImmediate(OffsetValue, TmpReg, SrcReg, !ABI.ArePtrs64bit(), true,
4525                       IDLoc, Out, STI))
4526       return true;
4527   }
4528 
4529   if (DoMove)
4530     std::swap(DstReg, TmpReg);
4531 
4532   unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
4533   unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
4534   TOut.emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4535   TOut.emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4536 
4537   if (DoMove)
4538     TOut.emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
4539 
4540   return false;
4541 }
4542 
expandSge(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)4543 bool MipsAsmParser::expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4544                               const MCSubtargetInfo *STI) {
4545   MipsTargetStreamer &TOut = getTargetStreamer();
4546 
4547   assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4548   assert(Inst.getOperand(0).isReg() &&
4549          Inst.getOperand(1).isReg() &&
4550          Inst.getOperand(2).isReg() && "Invalid instruction operand.");
4551 
4552   MCRegister DstReg = Inst.getOperand(0).getReg();
4553   MCRegister SrcReg = Inst.getOperand(1).getReg();
4554   MCRegister OpReg = Inst.getOperand(2).getReg();
4555   unsigned OpCode;
4556 
4557   warnIfNoMacro(IDLoc);
4558 
4559   switch (Inst.getOpcode()) {
4560   case Mips::SGE:
4561     OpCode = Mips::SLT;
4562     break;
4563   case Mips::SGEU:
4564     OpCode = Mips::SLTu;
4565     break;
4566   default:
4567     llvm_unreachable("unexpected 'sge' opcode");
4568   }
4569 
4570   // $SrcReg >= $OpReg is equal to (not ($SrcReg < $OpReg))
4571   TOut.emitRRR(OpCode, DstReg, SrcReg, OpReg, IDLoc, STI);
4572   TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4573 
4574   return false;
4575 }
4576 
expandSgeImm(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)4577 bool MipsAsmParser::expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4578                                  const MCSubtargetInfo *STI) {
4579   MipsTargetStreamer &TOut = getTargetStreamer();
4580 
4581   assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4582   assert(Inst.getOperand(0).isReg() &&
4583          Inst.getOperand(1).isReg() &&
4584          Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4585 
4586   MCRegister DstReg = Inst.getOperand(0).getReg();
4587   MCRegister SrcReg = Inst.getOperand(1).getReg();
4588   int64_t ImmValue = Inst.getOperand(2).getImm();
4589   unsigned OpRegCode, OpImmCode;
4590 
4591   warnIfNoMacro(IDLoc);
4592 
4593   switch (Inst.getOpcode()) {
4594   case Mips::SGEImm:
4595   case Mips::SGEImm64:
4596     OpRegCode = Mips::SLT;
4597     OpImmCode = Mips::SLTi;
4598     break;
4599   case Mips::SGEUImm:
4600   case Mips::SGEUImm64:
4601     OpRegCode = Mips::SLTu;
4602     OpImmCode = Mips::SLTiu;
4603     break;
4604   default:
4605     llvm_unreachable("unexpected 'sge' opcode with immediate");
4606   }
4607 
4608   // $SrcReg >= Imm is equal to (not ($SrcReg < Imm))
4609   if (isInt<16>(ImmValue)) {
4610     // Use immediate version of STL.
4611     TOut.emitRRI(OpImmCode, DstReg, SrcReg, ImmValue, IDLoc, STI);
4612     TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4613   } else {
4614     MCRegister ImmReg = DstReg;
4615     if (DstReg == SrcReg) {
4616       MCRegister ATReg = getATReg(Inst.getLoc());
4617       if (!ATReg)
4618         return true;
4619       ImmReg = ATReg;
4620     }
4621 
4622     if (loadImmediate(ImmValue, ImmReg, MCRegister(), isInt<32>(ImmValue),
4623                       false, IDLoc, Out, STI))
4624       return true;
4625 
4626     TOut.emitRRR(OpRegCode, DstReg, SrcReg, ImmReg, IDLoc, STI);
4627     TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4628   }
4629 
4630   return false;
4631 }
4632 
expandSgtImm(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)4633 bool MipsAsmParser::expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4634                                  const MCSubtargetInfo *STI) {
4635   MipsTargetStreamer &TOut = getTargetStreamer();
4636 
4637   assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4638   assert(Inst.getOperand(0).isReg() &&
4639          Inst.getOperand(1).isReg() &&
4640          Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4641 
4642   MCRegister DstReg = Inst.getOperand(0).getReg();
4643   MCRegister SrcReg = Inst.getOperand(1).getReg();
4644   MCRegister ImmReg = DstReg;
4645   int64_t ImmValue = Inst.getOperand(2).getImm();
4646   unsigned OpCode;
4647 
4648   warnIfNoMacro(IDLoc);
4649 
4650   switch (Inst.getOpcode()) {
4651   case Mips::SGTImm:
4652   case Mips::SGTImm64:
4653     OpCode = Mips::SLT;
4654     break;
4655   case Mips::SGTUImm:
4656   case Mips::SGTUImm64:
4657     OpCode = Mips::SLTu;
4658     break;
4659   default:
4660     llvm_unreachable("unexpected 'sgt' opcode with immediate");
4661   }
4662 
4663   if (DstReg == SrcReg) {
4664     MCRegister ATReg = getATReg(Inst.getLoc());
4665     if (!ATReg)
4666       return true;
4667     ImmReg = ATReg;
4668   }
4669 
4670   if (loadImmediate(ImmValue, ImmReg, MCRegister(), isInt<32>(ImmValue), false,
4671                     IDLoc, Out, STI))
4672     return true;
4673 
4674   // $SrcReg > $ImmReg is equal to $ImmReg < $SrcReg
4675   TOut.emitRRR(OpCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4676 
4677   return false;
4678 }
4679 
expandSle(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)4680 bool MipsAsmParser::expandSle(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4681                               const MCSubtargetInfo *STI) {
4682   MipsTargetStreamer &TOut = getTargetStreamer();
4683 
4684   assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4685   assert(Inst.getOperand(0).isReg() &&
4686          Inst.getOperand(1).isReg() &&
4687          Inst.getOperand(2).isReg() && "Invalid instruction operand.");
4688 
4689   MCRegister DstReg = Inst.getOperand(0).getReg();
4690   MCRegister SrcReg = Inst.getOperand(1).getReg();
4691   MCRegister OpReg = Inst.getOperand(2).getReg();
4692   unsigned OpCode;
4693 
4694   warnIfNoMacro(IDLoc);
4695 
4696   switch (Inst.getOpcode()) {
4697   case Mips::SLE:
4698     OpCode = Mips::SLT;
4699     break;
4700   case Mips::SLEU:
4701     OpCode = Mips::SLTu;
4702     break;
4703   default:
4704     llvm_unreachable("unexpected 'sge' opcode");
4705   }
4706 
4707   // $SrcReg <= $OpReg is equal to (not ($OpReg < $SrcReg))
4708   TOut.emitRRR(OpCode, DstReg, OpReg, SrcReg, IDLoc, STI);
4709   TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4710 
4711   return false;
4712 }
4713 
expandSleImm(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)4714 bool MipsAsmParser::expandSleImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4715                                  const MCSubtargetInfo *STI) {
4716   MipsTargetStreamer &TOut = getTargetStreamer();
4717 
4718   assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4719   assert(Inst.getOperand(0).isReg() &&
4720          Inst.getOperand(1).isReg() &&
4721          Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4722 
4723   MCRegister DstReg = Inst.getOperand(0).getReg();
4724   MCRegister SrcReg = Inst.getOperand(1).getReg();
4725   int64_t ImmValue = Inst.getOperand(2).getImm();
4726   unsigned OpRegCode;
4727 
4728   warnIfNoMacro(IDLoc);
4729 
4730   switch (Inst.getOpcode()) {
4731   case Mips::SLEImm:
4732   case Mips::SLEImm64:
4733     OpRegCode = Mips::SLT;
4734     break;
4735   case Mips::SLEUImm:
4736   case Mips::SLEUImm64:
4737     OpRegCode = Mips::SLTu;
4738     break;
4739   default:
4740     llvm_unreachable("unexpected 'sge' opcode with immediate");
4741   }
4742 
4743   // $SrcReg <= Imm is equal to (not (Imm < $SrcReg))
4744   MCRegister ImmReg = DstReg;
4745   if (DstReg == SrcReg) {
4746     MCRegister ATReg = getATReg(Inst.getLoc());
4747     if (!ATReg)
4748       return true;
4749     ImmReg = ATReg;
4750   }
4751 
4752   if (loadImmediate(ImmValue, ImmReg, MCRegister(), isInt<32>(ImmValue), false,
4753                     IDLoc, Out, STI))
4754     return true;
4755 
4756   TOut.emitRRR(OpRegCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4757   TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4758 
4759   return false;
4760 }
4761 
expandAliasImmediate(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)4762 bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
4763                                          MCStreamer &Out,
4764                                          const MCSubtargetInfo *STI) {
4765   MipsTargetStreamer &TOut = getTargetStreamer();
4766 
4767   assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4768   assert(Inst.getOperand(0).isReg() &&
4769          Inst.getOperand(1).isReg() &&
4770          Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4771 
4772   MCRegister ATReg;
4773   MCRegister FinalDstReg;
4774   MCRegister DstReg = Inst.getOperand(0).getReg();
4775   MCRegister SrcReg = Inst.getOperand(1).getReg();
4776   int64_t ImmValue = Inst.getOperand(2).getImm();
4777 
4778   bool Is32Bit = isInt<32>(ImmValue) || (!isGP64bit() && isUInt<32>(ImmValue));
4779 
4780   unsigned FinalOpcode = Inst.getOpcode();
4781 
4782   if (DstReg == SrcReg) {
4783     ATReg = getATReg(Inst.getLoc());
4784     if (!ATReg)
4785       return true;
4786     FinalDstReg = DstReg;
4787     DstReg = ATReg;
4788   }
4789 
4790   if (!loadImmediate(ImmValue, DstReg, MCRegister(), Is32Bit, false,
4791                      Inst.getLoc(), Out, STI)) {
4792     switch (FinalOpcode) {
4793     default:
4794       llvm_unreachable("unimplemented expansion");
4795     case Mips::ADDi:
4796       FinalOpcode = Mips::ADD;
4797       break;
4798     case Mips::ADDiu:
4799       FinalOpcode = Mips::ADDu;
4800       break;
4801     case Mips::ANDi:
4802       FinalOpcode = Mips::AND;
4803       break;
4804     case Mips::NORImm:
4805       FinalOpcode = Mips::NOR;
4806       break;
4807     case Mips::ORi:
4808       FinalOpcode = Mips::OR;
4809       break;
4810     case Mips::SLTi:
4811       FinalOpcode = Mips::SLT;
4812       break;
4813     case Mips::SLTiu:
4814       FinalOpcode = Mips::SLTu;
4815       break;
4816     case Mips::XORi:
4817       FinalOpcode = Mips::XOR;
4818       break;
4819     case Mips::ADDi_MM:
4820       FinalOpcode = Mips::ADD_MM;
4821       break;
4822     case Mips::ADDiu_MM:
4823       FinalOpcode = Mips::ADDu_MM;
4824       break;
4825     case Mips::ANDi_MM:
4826       FinalOpcode = Mips::AND_MM;
4827       break;
4828     case Mips::ORi_MM:
4829       FinalOpcode = Mips::OR_MM;
4830       break;
4831     case Mips::SLTi_MM:
4832       FinalOpcode = Mips::SLT_MM;
4833       break;
4834     case Mips::SLTiu_MM:
4835       FinalOpcode = Mips::SLTu_MM;
4836       break;
4837     case Mips::XORi_MM:
4838       FinalOpcode = Mips::XOR_MM;
4839       break;
4840     case Mips::ANDi64:
4841       FinalOpcode = Mips::AND64;
4842       break;
4843     case Mips::NORImm64:
4844       FinalOpcode = Mips::NOR64;
4845       break;
4846     case Mips::ORi64:
4847       FinalOpcode = Mips::OR64;
4848       break;
4849     case Mips::SLTImm64:
4850       FinalOpcode = Mips::SLT64;
4851       break;
4852     case Mips::SLTUImm64:
4853       FinalOpcode = Mips::SLTu64;
4854       break;
4855     case Mips::XORi64:
4856       FinalOpcode = Mips::XOR64;
4857       break;
4858     }
4859 
4860     if (!FinalDstReg)
4861       TOut.emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4862     else
4863       TOut.emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4864     return false;
4865   }
4866   return true;
4867 }
4868 
expandRotation(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)4869 bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4870                                    const MCSubtargetInfo *STI) {
4871   MipsTargetStreamer &TOut = getTargetStreamer();
4872   MCRegister ATReg;
4873   MCRegister DReg = Inst.getOperand(0).getReg();
4874   MCRegister SReg = Inst.getOperand(1).getReg();
4875   MCRegister TReg = Inst.getOperand(2).getReg();
4876   MCRegister TmpReg = DReg;
4877 
4878   unsigned FirstShift = Mips::NOP;
4879   unsigned SecondShift = Mips::NOP;
4880 
4881   if (hasMips32r2()) {
4882     if (DReg == SReg) {
4883       TmpReg = getATReg(Inst.getLoc());
4884       if (!TmpReg)
4885         return true;
4886     }
4887 
4888     if (Inst.getOpcode() == Mips::ROL) {
4889       TOut.emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4890       TOut.emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
4891       return false;
4892     }
4893 
4894     if (Inst.getOpcode() == Mips::ROR) {
4895       TOut.emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
4896       return false;
4897     }
4898 
4899     return true;
4900   }
4901 
4902   if (hasMips32()) {
4903     switch (Inst.getOpcode()) {
4904     default:
4905       llvm_unreachable("unexpected instruction opcode");
4906     case Mips::ROL:
4907       FirstShift = Mips::SRLV;
4908       SecondShift = Mips::SLLV;
4909       break;
4910     case Mips::ROR:
4911       FirstShift = Mips::SLLV;
4912       SecondShift = Mips::SRLV;
4913       break;
4914     }
4915 
4916     ATReg = getATReg(Inst.getLoc());
4917     if (!ATReg)
4918       return true;
4919 
4920     TOut.emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4921     TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
4922     TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
4923     TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4924 
4925     return false;
4926   }
4927 
4928   return true;
4929 }
4930 
expandRotationImm(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)4931 bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
4932                                       MCStreamer &Out,
4933                                       const MCSubtargetInfo *STI) {
4934   MipsTargetStreamer &TOut = getTargetStreamer();
4935   MCRegister ATReg;
4936   MCRegister DReg = Inst.getOperand(0).getReg();
4937   MCRegister SReg = Inst.getOperand(1).getReg();
4938   int64_t ImmValue = Inst.getOperand(2).getImm();
4939 
4940   unsigned FirstShift = Mips::NOP;
4941   unsigned SecondShift = Mips::NOP;
4942 
4943   if (hasMips32r2()) {
4944     if (Inst.getOpcode() == Mips::ROLImm) {
4945       uint64_t MaxShift = 32;
4946       uint64_t ShiftValue = ImmValue;
4947       if (ImmValue != 0)
4948         ShiftValue = MaxShift - ImmValue;
4949       TOut.emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
4950       return false;
4951     }
4952 
4953     if (Inst.getOpcode() == Mips::RORImm) {
4954       TOut.emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.getLoc(), STI);
4955       return false;
4956     }
4957 
4958     return true;
4959   }
4960 
4961   if (hasMips32()) {
4962     if (ImmValue == 0) {
4963       TOut.emitRRI(Mips::SRL, DReg, SReg, 0, Inst.getLoc(), STI);
4964       return false;
4965     }
4966 
4967     switch (Inst.getOpcode()) {
4968     default:
4969       llvm_unreachable("unexpected instruction opcode");
4970     case Mips::ROLImm:
4971       FirstShift = Mips::SLL;
4972       SecondShift = Mips::SRL;
4973       break;
4974     case Mips::RORImm:
4975       FirstShift = Mips::SRL;
4976       SecondShift = Mips::SLL;
4977       break;
4978     }
4979 
4980     ATReg = getATReg(Inst.getLoc());
4981     if (!ATReg)
4982       return true;
4983 
4984     TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.getLoc(), STI);
4985     TOut.emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.getLoc(), STI);
4986     TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4987 
4988     return false;
4989   }
4990 
4991   return true;
4992 }
4993 
expandDRotation(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)4994 bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4995                                     const MCSubtargetInfo *STI) {
4996   MipsTargetStreamer &TOut = getTargetStreamer();
4997   MCRegister ATReg;
4998   MCRegister DReg = Inst.getOperand(0).getReg();
4999   MCRegister SReg = Inst.getOperand(1).getReg();
5000   MCRegister TReg = Inst.getOperand(2).getReg();
5001   MCRegister TmpReg = DReg;
5002 
5003   unsigned FirstShift = Mips::NOP;
5004   unsigned SecondShift = Mips::NOP;
5005 
5006   if (hasMips64r2()) {
5007     if (TmpReg == SReg) {
5008       TmpReg = getATReg(Inst.getLoc());
5009       if (!TmpReg)
5010         return true;
5011     }
5012 
5013     if (Inst.getOpcode() == Mips::DROL) {
5014       TOut.emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
5015       TOut.emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
5016       return false;
5017     }
5018 
5019     if (Inst.getOpcode() == Mips::DROR) {
5020       TOut.emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
5021       return false;
5022     }
5023 
5024     return true;
5025   }
5026 
5027   if (hasMips64()) {
5028     switch (Inst.getOpcode()) {
5029     default:
5030       llvm_unreachable("unexpected instruction opcode");
5031     case Mips::DROL:
5032       FirstShift = Mips::DSRLV;
5033       SecondShift = Mips::DSLLV;
5034       break;
5035     case Mips::DROR:
5036       FirstShift = Mips::DSLLV;
5037       SecondShift = Mips::DSRLV;
5038       break;
5039     }
5040 
5041     ATReg = getATReg(Inst.getLoc());
5042     if (!ATReg)
5043       return true;
5044 
5045     TOut.emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
5046     TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
5047     TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
5048     TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
5049 
5050     return false;
5051   }
5052 
5053   return true;
5054 }
5055 
expandDRotationImm(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)5056 bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
5057                                        MCStreamer &Out,
5058                                        const MCSubtargetInfo *STI) {
5059   MipsTargetStreamer &TOut = getTargetStreamer();
5060   MCRegister ATReg;
5061   MCRegister DReg = Inst.getOperand(0).getReg();
5062   MCRegister SReg = Inst.getOperand(1).getReg();
5063   int64_t ImmValue = Inst.getOperand(2).getImm() % 64;
5064 
5065   unsigned FirstShift = Mips::NOP;
5066   unsigned SecondShift = Mips::NOP;
5067 
5068   MCInst TmpInst;
5069 
5070   if (hasMips64r2()) {
5071     unsigned FinalOpcode = Mips::NOP;
5072     if (ImmValue == 0)
5073       FinalOpcode = Mips::DROTR;
5074     else if (ImmValue % 32 == 0)
5075       FinalOpcode = Mips::DROTR32;
5076     else if ((ImmValue >= 1) && (ImmValue <= 32)) {
5077       if (Inst.getOpcode() == Mips::DROLImm)
5078         FinalOpcode = Mips::DROTR32;
5079       else
5080         FinalOpcode = Mips::DROTR;
5081     } else if (ImmValue >= 33) {
5082       if (Inst.getOpcode() == Mips::DROLImm)
5083         FinalOpcode = Mips::DROTR;
5084       else
5085         FinalOpcode = Mips::DROTR32;
5086     }
5087 
5088     uint64_t ShiftValue = ImmValue % 32;
5089     if (Inst.getOpcode() == Mips::DROLImm)
5090       ShiftValue = (32 - ImmValue % 32) % 32;
5091 
5092     TOut.emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
5093 
5094     return false;
5095   }
5096 
5097   if (hasMips64()) {
5098     if (ImmValue == 0) {
5099       TOut.emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.getLoc(), STI);
5100       return false;
5101     }
5102 
5103     switch (Inst.getOpcode()) {
5104     default:
5105       llvm_unreachable("unexpected instruction opcode");
5106     case Mips::DROLImm:
5107       if ((ImmValue >= 1) && (ImmValue <= 31)) {
5108         FirstShift = Mips::DSLL;
5109         SecondShift = Mips::DSRL32;
5110       }
5111       if (ImmValue == 32) {
5112         FirstShift = Mips::DSLL32;
5113         SecondShift = Mips::DSRL32;
5114       }
5115       if ((ImmValue >= 33) && (ImmValue <= 63)) {
5116         FirstShift = Mips::DSLL32;
5117         SecondShift = Mips::DSRL;
5118       }
5119       break;
5120     case Mips::DRORImm:
5121       if ((ImmValue >= 1) && (ImmValue <= 31)) {
5122         FirstShift = Mips::DSRL;
5123         SecondShift = Mips::DSLL32;
5124       }
5125       if (ImmValue == 32) {
5126         FirstShift = Mips::DSRL32;
5127         SecondShift = Mips::DSLL32;
5128       }
5129       if ((ImmValue >= 33) && (ImmValue <= 63)) {
5130         FirstShift = Mips::DSRL32;
5131         SecondShift = Mips::DSLL;
5132       }
5133       break;
5134     }
5135 
5136     ATReg = getATReg(Inst.getLoc());
5137     if (!ATReg)
5138       return true;
5139 
5140     TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.getLoc(), STI);
5141     TOut.emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
5142                  Inst.getLoc(), STI);
5143     TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
5144 
5145     return false;
5146   }
5147 
5148   return true;
5149 }
5150 
expandAbs(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)5151 bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5152                               const MCSubtargetInfo *STI) {
5153   MipsTargetStreamer &TOut = getTargetStreamer();
5154   MCRegister FirstRegOp = Inst.getOperand(0).getReg();
5155   MCRegister SecondRegOp = Inst.getOperand(1).getReg();
5156 
5157   TOut.emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
5158   if (FirstRegOp != SecondRegOp)
5159     TOut.emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
5160   else
5161     TOut.emitEmptyDelaySlot(false, IDLoc, STI);
5162   TOut.emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
5163 
5164   return false;
5165 }
5166 
expandMulImm(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)5167 bool MipsAsmParser::expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5168                                  const MCSubtargetInfo *STI) {
5169   MipsTargetStreamer &TOut = getTargetStreamer();
5170   MCRegister ATReg;
5171   MCRegister DstReg = Inst.getOperand(0).getReg();
5172   MCRegister SrcReg = Inst.getOperand(1).getReg();
5173   int32_t ImmValue = Inst.getOperand(2).getImm();
5174 
5175   ATReg = getATReg(IDLoc);
5176   if (!ATReg)
5177     return true;
5178 
5179   loadImmediate(ImmValue, ATReg, MCRegister(), true, false, IDLoc, Out, STI);
5180 
5181   TOut.emitRR(Inst.getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
5182               SrcReg, ATReg, IDLoc, STI);
5183 
5184   TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5185 
5186   return false;
5187 }
5188 
expandMulO(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)5189 bool MipsAsmParser::expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5190                                const MCSubtargetInfo *STI) {
5191   MipsTargetStreamer &TOut = getTargetStreamer();
5192   MCRegister ATReg;
5193   MCRegister DstReg = Inst.getOperand(0).getReg();
5194   MCRegister SrcReg = Inst.getOperand(1).getReg();
5195   MCRegister TmpReg = Inst.getOperand(2).getReg();
5196 
5197   ATReg = getATReg(Inst.getLoc());
5198   if (!ATReg)
5199     return true;
5200 
5201   TOut.emitRR(Inst.getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT,
5202               SrcReg, TmpReg, IDLoc, STI);
5203 
5204   TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5205 
5206   TOut.emitRRI(Inst.getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32,
5207                DstReg, DstReg, 0x1F, IDLoc, STI);
5208 
5209   TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
5210 
5211   if (useTraps()) {
5212     TOut.emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
5213   } else {
5214     MCContext &Context = TOut.getContext();
5215     MCSymbol * BrTarget = Context.createTempSymbol();
5216     MCOperand LabelOp =
5217         MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
5218 
5219     TOut.emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
5220     if (AssemblerOptions.back()->isReorder())
5221       TOut.emitNop(IDLoc, STI);
5222     TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5223 
5224     TOut.getStreamer().emitLabel(BrTarget);
5225   }
5226   TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5227 
5228   return false;
5229 }
5230 
expandMulOU(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)5231 bool MipsAsmParser::expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5232                                 const MCSubtargetInfo *STI) {
5233   MipsTargetStreamer &TOut = getTargetStreamer();
5234   MCRegister ATReg;
5235   MCRegister DstReg = Inst.getOperand(0).getReg();
5236   MCRegister SrcReg = Inst.getOperand(1).getReg();
5237   MCRegister TmpReg = Inst.getOperand(2).getReg();
5238 
5239   ATReg = getATReg(IDLoc);
5240   if (!ATReg)
5241     return true;
5242 
5243   TOut.emitRR(Inst.getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
5244               SrcReg, TmpReg, IDLoc, STI);
5245 
5246   TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
5247   TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5248   if (useTraps()) {
5249     TOut.emitRRI(Mips::TNE, ATReg, Mips::ZERO, 6, IDLoc, STI);
5250   } else {
5251     MCContext &Context = TOut.getContext();
5252     MCSymbol * BrTarget = Context.createTempSymbol();
5253     MCOperand LabelOp =
5254         MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context));
5255 
5256     TOut.emitRRX(Mips::BEQ, ATReg, Mips::ZERO, LabelOp, IDLoc, STI);
5257     if (AssemblerOptions.back()->isReorder())
5258       TOut.emitNop(IDLoc, STI);
5259     TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5260 
5261     TOut.getStreamer().emitLabel(BrTarget);
5262   }
5263 
5264   return false;
5265 }
5266 
expandDMULMacro(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)5267 bool MipsAsmParser::expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5268                                     const MCSubtargetInfo *STI) {
5269   MipsTargetStreamer &TOut = getTargetStreamer();
5270   MCRegister DstReg = Inst.getOperand(0).getReg();
5271   MCRegister SrcReg = Inst.getOperand(1).getReg();
5272   MCRegister TmpReg = Inst.getOperand(2).getReg();
5273 
5274   TOut.emitRR(Mips::DMULTu, SrcReg, TmpReg, IDLoc, STI);
5275   TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5276 
5277   return false;
5278 }
5279 
5280 // Expand 'ld $<reg> offset($reg2)' to 'lw $<reg>, offset($reg2);
5281 //                                      lw $<reg+1>>, offset+4($reg2)'
5282 // or expand 'sd $<reg> offset($reg2)' to 'sw $<reg>, offset($reg2);
5283 //                                         sw $<reg+1>>, offset+4($reg2)'
5284 // for O32.
expandLoadStoreDMacro(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI,bool IsLoad)5285 bool MipsAsmParser::expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc,
5286                                           MCStreamer &Out,
5287                                           const MCSubtargetInfo *STI,
5288                                           bool IsLoad) {
5289   if (!isABI_O32())
5290     return true;
5291 
5292   warnIfNoMacro(IDLoc);
5293 
5294   MipsTargetStreamer &TOut = getTargetStreamer();
5295   unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
5296   MCRegister FirstReg = Inst.getOperand(0).getReg();
5297   MCRegister SecondReg = nextReg(FirstReg);
5298   MCRegister BaseReg = Inst.getOperand(1).getReg();
5299   if (!SecondReg)
5300     return true;
5301 
5302   warnIfRegIndexIsAT(FirstReg, IDLoc);
5303 
5304   assert(Inst.getOperand(2).isImm() &&
5305          "Offset for load macro is not immediate!");
5306 
5307   MCOperand &FirstOffset = Inst.getOperand(2);
5308   signed NextOffset = FirstOffset.getImm() + 4;
5309   MCOperand SecondOffset = MCOperand::createImm(NextOffset);
5310 
5311   if (!isInt<16>(FirstOffset.getImm()) || !isInt<16>(NextOffset))
5312     return true;
5313 
5314   // For loads, clobber the base register with the second load instead of the
5315   // first if the BaseReg == FirstReg.
5316   if (FirstReg != BaseReg || !IsLoad) {
5317     TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5318     TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5319   } else {
5320     TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5321     TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5322   }
5323 
5324   return false;
5325 }
5326 
5327 
5328 // Expand 's.d $<reg> offset($reg2)' to 'swc1 $<reg+1>, offset($reg2);
5329 //                                       swc1 $<reg>, offset+4($reg2)'
5330 // or if little endian to 'swc1 $<reg>, offset($reg2);
5331 //                         swc1 $<reg+1>, offset+4($reg2)'
5332 // for Mips1.
expandStoreDM1Macro(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)5333 bool MipsAsmParser::expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc,
5334                                         MCStreamer &Out,
5335                                         const MCSubtargetInfo *STI) {
5336   if (!isABI_O32())
5337     return true;
5338 
5339   warnIfNoMacro(IDLoc);
5340 
5341   MipsTargetStreamer &TOut = getTargetStreamer();
5342   unsigned Opcode = Mips::SWC1;
5343   MCRegister FirstReg = Inst.getOperand(0).getReg();
5344   MCRegister SecondReg = nextReg(FirstReg);
5345   MCRegister BaseReg = Inst.getOperand(1).getReg();
5346   if (!SecondReg)
5347     return true;
5348 
5349   warnIfRegIndexIsAT(FirstReg, IDLoc);
5350 
5351   assert(Inst.getOperand(2).isImm() &&
5352          "Offset for macro is not immediate!");
5353 
5354   MCOperand &FirstOffset = Inst.getOperand(2);
5355   signed NextOffset = FirstOffset.getImm() + 4;
5356   MCOperand SecondOffset = MCOperand::createImm(NextOffset);
5357 
5358   if (!isInt<16>(FirstOffset.getImm()) || !isInt<16>(NextOffset))
5359     return true;
5360 
5361   if (!IsLittleEndian)
5362     std::swap(FirstReg, SecondReg);
5363 
5364   TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5365   TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5366 
5367   return false;
5368 }
5369 
expandSeq(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)5370 bool MipsAsmParser::expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5371                               const MCSubtargetInfo *STI) {
5372   MipsTargetStreamer &TOut = getTargetStreamer();
5373 
5374   assert(Inst.getNumOperands() == 3 && "Invalid operand count");
5375   assert(Inst.getOperand(0).isReg() &&
5376          Inst.getOperand(1).isReg() &&
5377          Inst.getOperand(2).isReg() && "Invalid instruction operand.");
5378 
5379   MCRegister DstReg = Inst.getOperand(0).getReg();
5380   MCRegister SrcReg = Inst.getOperand(1).getReg();
5381   MCRegister OpReg = Inst.getOperand(2).getReg();
5382 
5383   warnIfNoMacro(IDLoc);
5384 
5385   if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5386     TOut.emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5387     TOut.emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5388     return false;
5389   }
5390 
5391   MCRegister Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5392   TOut.emitRRI(Mips::SLTiu, DstReg, Reg, 1, IDLoc, STI);
5393   return false;
5394 }
5395 
expandSeqI(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)5396 bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5397                                const MCSubtargetInfo *STI) {
5398   MipsTargetStreamer &TOut = getTargetStreamer();
5399 
5400   assert(Inst.getNumOperands() == 3 && "Invalid operand count");
5401   assert(Inst.getOperand(0).isReg() &&
5402          Inst.getOperand(1).isReg() &&
5403          Inst.getOperand(2).isImm() && "Invalid instruction operand.");
5404 
5405   MCRegister DstReg = Inst.getOperand(0).getReg();
5406   MCRegister SrcReg = Inst.getOperand(1).getReg();
5407   int64_t Imm = Inst.getOperand(2).getImm();
5408 
5409   warnIfNoMacro(IDLoc);
5410 
5411   if (Imm == 0) {
5412     TOut.emitRRI(Mips::SLTiu, DstReg, SrcReg, 1, IDLoc, STI);
5413     return false;
5414   }
5415 
5416   if (SrcReg == Mips::ZERO) {
5417     Warning(IDLoc, "comparison is always false");
5418     TOut.emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
5419                  DstReg, SrcReg, SrcReg, IDLoc, STI);
5420     return false;
5421   }
5422 
5423   unsigned Opc;
5424   if (Imm > -0x8000 && Imm < 0) {
5425     Imm = -Imm;
5426     Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5427   } else {
5428     Opc = Mips::XORi;
5429   }
5430 
5431   if (!isUInt<16>(Imm)) {
5432     MCRegister ATReg = getATReg(IDLoc);
5433     if (!ATReg)
5434       return true;
5435 
5436     if (loadImmediate(Imm, ATReg, MCRegister(), true, isGP64bit(), IDLoc, Out,
5437                       STI))
5438       return true;
5439 
5440     TOut.emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5441     TOut.emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5442     return false;
5443   }
5444 
5445   TOut.emitRRI(Opc, DstReg, SrcReg, Imm, IDLoc, STI);
5446   TOut.emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5447   return false;
5448 }
5449 
expandSne(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)5450 bool MipsAsmParser::expandSne(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5451                               const MCSubtargetInfo *STI) {
5452 
5453   MipsTargetStreamer &TOut = getTargetStreamer();
5454 
5455   assert(Inst.getNumOperands() == 3 && "Invalid operand count");
5456   assert(Inst.getOperand(0).isReg() &&
5457          Inst.getOperand(1).isReg() &&
5458          Inst.getOperand(2).isReg() && "Invalid instruction operand.");
5459 
5460   MCRegister DstReg = Inst.getOperand(0).getReg();
5461   MCRegister SrcReg = Inst.getOperand(1).getReg();
5462   MCRegister OpReg = Inst.getOperand(2).getReg();
5463 
5464   warnIfNoMacro(IDLoc);
5465 
5466   if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5467     TOut.emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5468     TOut.emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5469     return false;
5470   }
5471 
5472   MCRegister Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5473   TOut.emitRRR(Mips::SLTu, DstReg, Mips::ZERO, Reg, IDLoc, STI);
5474   return false;
5475 }
5476 
expandSneI(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)5477 bool MipsAsmParser::expandSneI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5478                                const MCSubtargetInfo *STI) {
5479   MipsTargetStreamer &TOut = getTargetStreamer();
5480 
5481   assert(Inst.getNumOperands() == 3 && "Invalid operand count");
5482   assert(Inst.getOperand(0).isReg() &&
5483          Inst.getOperand(1).isReg() &&
5484          Inst.getOperand(2).isImm() && "Invalid instruction operand.");
5485 
5486   MCRegister DstReg = Inst.getOperand(0).getReg();
5487   MCRegister SrcReg = Inst.getOperand(1).getReg();
5488   int64_t ImmValue = Inst.getOperand(2).getImm();
5489 
5490   warnIfNoMacro(IDLoc);
5491 
5492   if (ImmValue == 0) {
5493     TOut.emitRRR(Mips::SLTu, DstReg, Mips::ZERO, SrcReg, IDLoc, STI);
5494     return false;
5495   }
5496 
5497   if (SrcReg == Mips::ZERO) {
5498     Warning(IDLoc, "comparison is always true");
5499     if (loadImmediate(1, DstReg, MCRegister(), true, false, IDLoc, Out, STI))
5500       return true;
5501     return false;
5502   }
5503 
5504   unsigned Opc;
5505   if (ImmValue > -0x8000 && ImmValue < 0) {
5506     ImmValue = -ImmValue;
5507     Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5508   } else {
5509     Opc = Mips::XORi;
5510   }
5511 
5512   if (isUInt<16>(ImmValue)) {
5513     TOut.emitRRI(Opc, DstReg, SrcReg, ImmValue, IDLoc, STI);
5514     TOut.emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5515     return false;
5516   }
5517 
5518   MCRegister ATReg = getATReg(IDLoc);
5519   if (!ATReg)
5520     return true;
5521 
5522   if (loadImmediate(ImmValue, ATReg, MCRegister(), isInt<32>(ImmValue), false,
5523                     IDLoc, Out, STI))
5524     return true;
5525 
5526   TOut.emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5527   TOut.emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5528   return false;
5529 }
5530 
5531 // Map the DSP accumulator and control register to the corresponding gpr
5532 // operand. Unlike the other alias, the m(f|t)t(lo|hi|acx) instructions
5533 // do not map the DSP registers contigously to gpr registers.
getRegisterForMxtrDSP(MCInst & Inst,bool IsMFDSP)5534 static unsigned getRegisterForMxtrDSP(MCInst &Inst, bool IsMFDSP) {
5535   switch (Inst.getOpcode()) {
5536     case Mips::MFTLO:
5537     case Mips::MTTLO:
5538       switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg().id()) {
5539         case Mips::AC0:
5540           return Mips::ZERO;
5541         case Mips::AC1:
5542           return Mips::A0;
5543         case Mips::AC2:
5544           return Mips::T0;
5545         case Mips::AC3:
5546           return Mips::T4;
5547         default:
5548           llvm_unreachable("Unknown register for 'mttr' alias!");
5549     }
5550     case Mips::MFTHI:
5551     case Mips::MTTHI:
5552       switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg().id()) {
5553         case Mips::AC0:
5554           return Mips::AT;
5555         case Mips::AC1:
5556           return Mips::A1;
5557         case Mips::AC2:
5558           return Mips::T1;
5559         case Mips::AC3:
5560           return Mips::T5;
5561         default:
5562           llvm_unreachable("Unknown register for 'mttr' alias!");
5563     }
5564     case Mips::MFTACX:
5565     case Mips::MTTACX:
5566       switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg().id()) {
5567         case Mips::AC0:
5568           return Mips::V0;
5569         case Mips::AC1:
5570           return Mips::A2;
5571         case Mips::AC2:
5572           return Mips::T2;
5573         case Mips::AC3:
5574           return Mips::T6;
5575         default:
5576           llvm_unreachable("Unknown register for 'mttr' alias!");
5577     }
5578     case Mips::MFTDSP:
5579     case Mips::MTTDSP:
5580       return Mips::S0;
5581     default:
5582       llvm_unreachable("Unknown instruction for 'mttr' dsp alias!");
5583   }
5584 }
5585 
5586 // Map the floating point register operand to the corresponding register
5587 // operand.
getRegisterForMxtrFP(MCInst & Inst,bool IsMFTC1)5588 static unsigned getRegisterForMxtrFP(MCInst &Inst, bool IsMFTC1) {
5589   switch (Inst.getOperand(IsMFTC1 ? 1 : 0).getReg().id()) {
5590     case Mips::F0:  return Mips::ZERO;
5591     case Mips::F1:  return Mips::AT;
5592     case Mips::F2:  return Mips::V0;
5593     case Mips::F3:  return Mips::V1;
5594     case Mips::F4:  return Mips::A0;
5595     case Mips::F5:  return Mips::A1;
5596     case Mips::F6:  return Mips::A2;
5597     case Mips::F7:  return Mips::A3;
5598     case Mips::F8:  return Mips::T0;
5599     case Mips::F9:  return Mips::T1;
5600     case Mips::F10: return Mips::T2;
5601     case Mips::F11: return Mips::T3;
5602     case Mips::F12: return Mips::T4;
5603     case Mips::F13: return Mips::T5;
5604     case Mips::F14: return Mips::T6;
5605     case Mips::F15: return Mips::T7;
5606     case Mips::F16: return Mips::S0;
5607     case Mips::F17: return Mips::S1;
5608     case Mips::F18: return Mips::S2;
5609     case Mips::F19: return Mips::S3;
5610     case Mips::F20: return Mips::S4;
5611     case Mips::F21: return Mips::S5;
5612     case Mips::F22: return Mips::S6;
5613     case Mips::F23: return Mips::S7;
5614     case Mips::F24: return Mips::T8;
5615     case Mips::F25: return Mips::T9;
5616     case Mips::F26: return Mips::K0;
5617     case Mips::F27: return Mips::K1;
5618     case Mips::F28: return Mips::GP;
5619     case Mips::F29: return Mips::SP;
5620     case Mips::F30: return Mips::FP;
5621     case Mips::F31: return Mips::RA;
5622     default: llvm_unreachable("Unknown register for mttc1 alias!");
5623   }
5624 }
5625 
5626 // Map the coprocessor operand the corresponding gpr register operand.
getRegisterForMxtrC0(MCInst & Inst,bool IsMFTC0)5627 static unsigned getRegisterForMxtrC0(MCInst &Inst, bool IsMFTC0) {
5628   switch (Inst.getOperand(IsMFTC0 ? 1 : 0).getReg().id()) {
5629     case Mips::COP00:  return Mips::ZERO;
5630     case Mips::COP01:  return Mips::AT;
5631     case Mips::COP02:  return Mips::V0;
5632     case Mips::COP03:  return Mips::V1;
5633     case Mips::COP04:  return Mips::A0;
5634     case Mips::COP05:  return Mips::A1;
5635     case Mips::COP06:  return Mips::A2;
5636     case Mips::COP07:  return Mips::A3;
5637     case Mips::COP08:  return Mips::T0;
5638     case Mips::COP09:  return Mips::T1;
5639     case Mips::COP010: return Mips::T2;
5640     case Mips::COP011: return Mips::T3;
5641     case Mips::COP012: return Mips::T4;
5642     case Mips::COP013: return Mips::T5;
5643     case Mips::COP014: return Mips::T6;
5644     case Mips::COP015: return Mips::T7;
5645     case Mips::COP016: return Mips::S0;
5646     case Mips::COP017: return Mips::S1;
5647     case Mips::COP018: return Mips::S2;
5648     case Mips::COP019: return Mips::S3;
5649     case Mips::COP020: return Mips::S4;
5650     case Mips::COP021: return Mips::S5;
5651     case Mips::COP022: return Mips::S6;
5652     case Mips::COP023: return Mips::S7;
5653     case Mips::COP024: return Mips::T8;
5654     case Mips::COP025: return Mips::T9;
5655     case Mips::COP026: return Mips::K0;
5656     case Mips::COP027: return Mips::K1;
5657     case Mips::COP028: return Mips::GP;
5658     case Mips::COP029: return Mips::SP;
5659     case Mips::COP030: return Mips::FP;
5660     case Mips::COP031: return Mips::RA;
5661     default: llvm_unreachable("Unknown register for mttc0 alias!");
5662   }
5663 }
5664 
5665 /// Expand an alias of 'mftr' or 'mttr' into the full instruction, by producing
5666 /// an mftr or mttr with the correctly mapped gpr register, u, sel and h bits.
expandMXTRAlias(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)5667 bool MipsAsmParser::expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5668                                     const MCSubtargetInfo *STI) {
5669   MipsTargetStreamer &TOut = getTargetStreamer();
5670   MCRegister rd;
5671   unsigned u = 1;
5672   unsigned sel = 0;
5673   unsigned h = 0;
5674   bool IsMFTR = false;
5675   switch (Inst.getOpcode()) {
5676     case Mips::MFTC0:
5677       IsMFTR = true;
5678       [[fallthrough]];
5679     case Mips::MTTC0:
5680       u = 0;
5681       rd = getRegisterForMxtrC0(Inst, IsMFTR);
5682       sel = Inst.getOperand(2).getImm();
5683       break;
5684     case Mips::MFTGPR:
5685       IsMFTR = true;
5686       [[fallthrough]];
5687     case Mips::MTTGPR:
5688       rd = Inst.getOperand(IsMFTR ? 1 : 0).getReg();
5689       break;
5690     case Mips::MFTLO:
5691     case Mips::MFTHI:
5692     case Mips::MFTACX:
5693     case Mips::MFTDSP:
5694       IsMFTR = true;
5695       [[fallthrough]];
5696     case Mips::MTTLO:
5697     case Mips::MTTHI:
5698     case Mips::MTTACX:
5699     case Mips::MTTDSP:
5700       rd = getRegisterForMxtrDSP(Inst, IsMFTR);
5701       sel = 1;
5702       break;
5703     case Mips::MFTHC1:
5704       h = 1;
5705       [[fallthrough]];
5706     case Mips::MFTC1:
5707       IsMFTR = true;
5708       rd = getRegisterForMxtrFP(Inst, IsMFTR);
5709       sel = 2;
5710       break;
5711     case Mips::MTTHC1:
5712       h = 1;
5713       [[fallthrough]];
5714     case Mips::MTTC1:
5715       rd = getRegisterForMxtrFP(Inst, IsMFTR);
5716       sel = 2;
5717       break;
5718     case Mips::CFTC1:
5719       IsMFTR = true;
5720       [[fallthrough]];
5721     case Mips::CTTC1:
5722       rd = getRegisterForMxtrFP(Inst, IsMFTR);
5723       sel = 3;
5724       break;
5725   }
5726   MCRegister Op0 = IsMFTR ? Inst.getOperand(0).getReg() : MCRegister(rd);
5727   MCRegister Op1 =
5728       IsMFTR ? MCRegister(rd)
5729              : (Inst.getOpcode() != Mips::MTTDSP ? Inst.getOperand(1).getReg()
5730                                                  : Inst.getOperand(0).getReg());
5731 
5732   TOut.emitRRIII(IsMFTR ? Mips::MFTR : Mips::MTTR, Op0, Op1, u, sel, h, IDLoc,
5733                  STI);
5734   return false;
5735 }
5736 
expandSaaAddr(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out,const MCSubtargetInfo * STI)5737 bool MipsAsmParser::expandSaaAddr(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5738                                   const MCSubtargetInfo *STI) {
5739   assert(Inst.getNumOperands() == 3 && "expected three operands");
5740   assert(Inst.getOperand(0).isReg() && "expected register operand kind");
5741   assert(Inst.getOperand(1).isReg() && "expected register operand kind");
5742 
5743   warnIfNoMacro(IDLoc);
5744 
5745   MipsTargetStreamer &TOut = getTargetStreamer();
5746   unsigned Opcode = Inst.getOpcode() == Mips::SaaAddr ? Mips::SAA : Mips::SAAD;
5747   MCRegister RtReg = Inst.getOperand(0).getReg();
5748   MCRegister BaseReg = Inst.getOperand(1).getReg();
5749   const MCOperand &BaseOp = Inst.getOperand(2);
5750 
5751   if (BaseOp.isImm()) {
5752     int64_t ImmValue = BaseOp.getImm();
5753     if (ImmValue == 0) {
5754       TOut.emitRR(Opcode, RtReg, BaseReg, IDLoc, STI);
5755       return false;
5756     }
5757   }
5758 
5759   MCRegister ATReg = getATReg(IDLoc);
5760   if (!ATReg)
5761     return true;
5762 
5763   if (expandLoadAddress(ATReg, BaseReg, BaseOp, !isGP64bit(), IDLoc, Out, STI))
5764     return true;
5765 
5766   TOut.emitRR(Opcode, RtReg, ATReg, IDLoc, STI);
5767   return false;
5768 }
5769 
5770 unsigned
checkEarlyTargetMatchPredicate(MCInst & Inst,const OperandVector & Operands)5771 MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
5772                                               const OperandVector &Operands) {
5773   switch (Inst.getOpcode()) {
5774   default:
5775     return Match_Success;
5776   case Mips::DATI:
5777   case Mips::DAHI:
5778     if (static_cast<MipsOperand &>(*Operands[1])
5779             .isValidForTie(static_cast<MipsOperand &>(*Operands[2])))
5780       return Match_Success;
5781     return Match_RequiresSameSrcAndDst;
5782   }
5783 }
5784 
checkTargetMatchPredicate(MCInst & Inst)5785 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
5786   switch (Inst.getOpcode()) {
5787   // As described by the MIPSR6 spec, daui must not use the zero operand for
5788   // its source operand.
5789   case Mips::DAUI:
5790     if (Inst.getOperand(1).getReg() == Mips::ZERO ||
5791         Inst.getOperand(1).getReg() == Mips::ZERO_64)
5792       return Match_RequiresNoZeroRegister;
5793     return Match_Success;
5794   // As described by the Mips32r2 spec, the registers Rd and Rs for
5795   // jalr.hb must be different.
5796   // It also applies for registers Rt and Rs of microMIPSr6 jalrc.hb instruction
5797   // and registers Rd and Base for microMIPS lwp instruction
5798   case Mips::JALR_HB:
5799   case Mips::JALR_HB64:
5800   case Mips::JALRC_HB_MMR6:
5801   case Mips::JALRC_MMR6:
5802     if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
5803       return Match_RequiresDifferentSrcAndDst;
5804     return Match_Success;
5805   case Mips::LWP_MM:
5806     if (Inst.getOperand(0).getReg() == Inst.getOperand(2).getReg())
5807       return Match_RequiresDifferentSrcAndDst;
5808     return Match_Success;
5809   case Mips::SYNC:
5810     if (Inst.getOperand(0).getImm() != 0 && !hasMips32())
5811       return Match_NonZeroOperandForSync;
5812     return Match_Success;
5813   case Mips::MFC0:
5814   case Mips::MTC0:
5815   case Mips::MTC2:
5816   case Mips::MFC2:
5817     if (Inst.getOperand(2).getImm() != 0 && !hasMips32())
5818       return Match_NonZeroOperandForMTCX;
5819     return Match_Success;
5820   // As described the MIPSR6 spec, the compact branches that compare registers
5821   // must:
5822   // a) Not use the zero register.
5823   // b) Not use the same register twice.
5824   // c) rs < rt for bnec, beqc.
5825   //    NB: For this case, the encoding will swap the operands as their
5826   //    ordering doesn't matter. GAS performs this transformation  too.
5827   //    Hence, that constraint does not have to be enforced.
5828   //
5829   // The compact branches that branch iff the signed addition of two registers
5830   // would overflow must have rs >= rt. That can be handled like beqc/bnec with
5831   // operand swapping. They do not have restriction of using the zero register.
5832   case Mips::BLEZC:   case Mips::BLEZC_MMR6:
5833   case Mips::BGEZC:   case Mips::BGEZC_MMR6:
5834   case Mips::BGTZC:   case Mips::BGTZC_MMR6:
5835   case Mips::BLTZC:   case Mips::BLTZC_MMR6:
5836   case Mips::BEQZC:   case Mips::BEQZC_MMR6:
5837   case Mips::BNEZC:   case Mips::BNEZC_MMR6:
5838   case Mips::BLEZC64:
5839   case Mips::BGEZC64:
5840   case Mips::BGTZC64:
5841   case Mips::BLTZC64:
5842   case Mips::BEQZC64:
5843   case Mips::BNEZC64:
5844     if (Inst.getOperand(0).getReg() == Mips::ZERO ||
5845         Inst.getOperand(0).getReg() == Mips::ZERO_64)
5846       return Match_RequiresNoZeroRegister;
5847     return Match_Success;
5848   case Mips::BGEC:    case Mips::BGEC_MMR6:
5849   case Mips::BLTC:    case Mips::BLTC_MMR6:
5850   case Mips::BGEUC:   case Mips::BGEUC_MMR6:
5851   case Mips::BLTUC:   case Mips::BLTUC_MMR6:
5852   case Mips::BEQC:    case Mips::BEQC_MMR6:
5853   case Mips::BNEC:    case Mips::BNEC_MMR6:
5854   case Mips::BGEC64:
5855   case Mips::BLTC64:
5856   case Mips::BGEUC64:
5857   case Mips::BLTUC64:
5858   case Mips::BEQC64:
5859   case Mips::BNEC64:
5860     if (Inst.getOperand(0).getReg() == Mips::ZERO ||
5861         Inst.getOperand(0).getReg() == Mips::ZERO_64)
5862       return Match_RequiresNoZeroRegister;
5863     if (Inst.getOperand(1).getReg() == Mips::ZERO ||
5864         Inst.getOperand(1).getReg() == Mips::ZERO_64)
5865       return Match_RequiresNoZeroRegister;
5866     if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
5867       return Match_RequiresDifferentOperands;
5868     return Match_Success;
5869   case Mips::DINS: {
5870     assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5871            "Operands must be immediates for dins!");
5872     const signed Pos = Inst.getOperand(2).getImm();
5873     const signed Size = Inst.getOperand(3).getImm();
5874     if ((0 > (Pos + Size)) || ((Pos + Size) > 32))
5875       return Match_RequiresPosSizeRange0_32;
5876     return Match_Success;
5877   }
5878   case Mips::DINSM:
5879   case Mips::DINSU: {
5880     assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5881            "Operands must be immediates for dinsm/dinsu!");
5882     const signed Pos = Inst.getOperand(2).getImm();
5883     const signed Size = Inst.getOperand(3).getImm();
5884     if ((32 >= (Pos + Size)) || ((Pos + Size) > 64))
5885       return Match_RequiresPosSizeRange33_64;
5886     return Match_Success;
5887   }
5888   case Mips::DEXT: {
5889     assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5890            "Operands must be immediates for DEXTM!");
5891     const signed Pos = Inst.getOperand(2).getImm();
5892     const signed Size = Inst.getOperand(3).getImm();
5893     if ((1 > (Pos + Size)) || ((Pos + Size) > 63))
5894       return Match_RequiresPosSizeUImm6;
5895     return Match_Success;
5896   }
5897   case Mips::DEXTM:
5898   case Mips::DEXTU: {
5899     assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() &&
5900            "Operands must be immediates for dextm/dextu!");
5901     const signed Pos = Inst.getOperand(2).getImm();
5902     const signed Size = Inst.getOperand(3).getImm();
5903     if ((32 > (Pos + Size)) || ((Pos + Size) > 64))
5904       return Match_RequiresPosSizeRange33_64;
5905     return Match_Success;
5906   }
5907   case Mips::CRC32B: case Mips::CRC32CB:
5908   case Mips::CRC32H: case Mips::CRC32CH:
5909   case Mips::CRC32W: case Mips::CRC32CW:
5910   case Mips::CRC32D: case Mips::CRC32CD:
5911     if (Inst.getOperand(0).getReg() != Inst.getOperand(2).getReg())
5912       return Match_RequiresSameSrcAndDst;
5913     return Match_Success;
5914   }
5915 
5916   uint64_t TSFlags = MII.get(Inst.getOpcode()).TSFlags;
5917   if ((TSFlags & MipsII::HasFCCRegOperand) &&
5918       (Inst.getOperand(0).getReg() != Mips::FCC0) && !hasEightFccRegisters())
5919     return Match_NoFCCRegisterForCurrentISA;
5920 
5921   return Match_Success;
5922 
5923 }
5924 
RefineErrorLoc(const SMLoc Loc,const OperandVector & Operands,uint64_t ErrorInfo)5925 static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands,
5926                             uint64_t ErrorInfo) {
5927   if (ErrorInfo != ~0ULL && ErrorInfo < Operands.size()) {
5928     SMLoc ErrorLoc = Operands[ErrorInfo]->getStartLoc();
5929     if (ErrorLoc == SMLoc())
5930       return Loc;
5931     return ErrorLoc;
5932   }
5933   return Loc;
5934 }
5935 
matchAndEmitInstruction(SMLoc IDLoc,unsigned & Opcode,OperandVector & Operands,MCStreamer & Out,uint64_t & ErrorInfo,bool MatchingInlineAsm)5936 bool MipsAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
5937                                             OperandVector &Operands,
5938                                             MCStreamer &Out,
5939                                             uint64_t &ErrorInfo,
5940                                             bool MatchingInlineAsm) {
5941   MCInst Inst;
5942   unsigned MatchResult =
5943       MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
5944 
5945   switch (MatchResult) {
5946   case Match_Success:
5947     if (processInstruction(Inst, IDLoc, Out, STI))
5948       return true;
5949     return false;
5950   case Match_MissingFeature:
5951     Error(IDLoc, "instruction requires a CPU feature not currently enabled");
5952     return true;
5953   case Match_InvalidTiedOperand:
5954     Error(IDLoc, "operand must match destination register");
5955     return true;
5956   case Match_InvalidOperand: {
5957     SMLoc ErrorLoc = IDLoc;
5958     if (ErrorInfo != ~0ULL) {
5959       if (ErrorInfo >= Operands.size())
5960         return Error(IDLoc, "too few operands for instruction");
5961 
5962       ErrorLoc = Operands[ErrorInfo]->getStartLoc();
5963       if (ErrorLoc == SMLoc())
5964         ErrorLoc = IDLoc;
5965     }
5966 
5967     return Error(ErrorLoc, "invalid operand for instruction");
5968   }
5969   case Match_NonZeroOperandForSync:
5970     return Error(IDLoc,
5971                  "s-type must be zero or unspecified for pre-MIPS32 ISAs");
5972   case Match_NonZeroOperandForMTCX:
5973     return Error(IDLoc, "selector must be zero for pre-MIPS32 ISAs");
5974   case Match_MnemonicFail:
5975     return Error(IDLoc, "invalid instruction");
5976   case Match_RequiresDifferentSrcAndDst:
5977     return Error(IDLoc, "source and destination must be different");
5978   case Match_RequiresDifferentOperands:
5979     return Error(IDLoc, "registers must be different");
5980   case Match_RequiresNoZeroRegister:
5981     return Error(IDLoc, "invalid operand ($zero) for instruction");
5982   case Match_RequiresSameSrcAndDst:
5983     return Error(IDLoc, "source and destination must match");
5984   case Match_NoFCCRegisterForCurrentISA:
5985     return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5986                  "non-zero fcc register doesn't exist in current ISA level");
5987   case Match_Immz:
5988     return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected '0'");
5989   case Match_UImm1_0:
5990     return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5991                  "expected 1-bit unsigned immediate");
5992   case Match_UImm2_0:
5993     return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5994                  "expected 2-bit unsigned immediate");
5995   case Match_UImm2_1:
5996     return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
5997                  "expected immediate in range 1 .. 4");
5998   case Match_UImm3_0:
5999     return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6000                  "expected 3-bit unsigned immediate");
6001   case Match_UImm4_0:
6002     return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6003                  "expected 4-bit unsigned immediate");
6004   case Match_SImm4_0:
6005     return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6006                  "expected 4-bit signed immediate");
6007   case Match_UImm5_0:
6008     return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6009                  "expected 5-bit unsigned immediate");
6010   case Match_SImm5_0:
6011     return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6012                  "expected 5-bit signed immediate");
6013   case Match_UImm5_1:
6014     return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6015                  "expected immediate in range 1 .. 32");
6016   case Match_UImm5_32:
6017     return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6018                  "expected immediate in range 32 .. 63");
6019   case Match_UImm5_33:
6020     return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6021                  "expected immediate in range 33 .. 64");
6022   case Match_UImm5_0_Report_UImm6:
6023     // This is used on UImm5 operands that have a corresponding UImm5_32
6024     // operand to avoid confusing the user.
6025     return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6026                  "expected 6-bit unsigned immediate");
6027   case Match_UImm5_Lsl2:
6028     return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6029                  "expected both 7-bit unsigned immediate and multiple of 4");
6030   case Match_UImmRange2_64:
6031     return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6032                  "expected immediate in range 2 .. 64");
6033   case Match_UImm6_0:
6034     return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6035                  "expected 6-bit unsigned immediate");
6036   case Match_UImm6_Lsl2:
6037     return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6038                  "expected both 8-bit unsigned immediate and multiple of 4");
6039   case Match_SImm6_0:
6040     return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6041                  "expected 6-bit signed immediate");
6042   case Match_UImm7_0:
6043     return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6044                  "expected 7-bit unsigned immediate");
6045   case Match_UImm7_N1:
6046     return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6047                  "expected immediate in range -1 .. 126");
6048   case Match_SImm7_Lsl2:
6049     return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6050                  "expected both 9-bit signed immediate and multiple of 4");
6051   case Match_UImm8_0:
6052     return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6053                  "expected 8-bit unsigned immediate");
6054   case Match_UImm10_0:
6055     return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6056                  "expected 10-bit unsigned immediate");
6057   case Match_SImm10_0:
6058     return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6059                  "expected 10-bit signed immediate");
6060   case Match_SImm11_0:
6061     return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6062                  "expected 11-bit signed immediate");
6063   case Match_UImm16:
6064   case Match_UImm16_Relaxed:
6065   case Match_UImm16_AltRelaxed:
6066     return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6067                  "expected 16-bit unsigned immediate");
6068   case Match_SImm16:
6069   case Match_SImm16_Relaxed:
6070     return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6071                  "expected 16-bit signed immediate");
6072   case Match_SImm19_Lsl2:
6073     return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6074                  "expected both 19-bit signed immediate and multiple of 4");
6075   case Match_UImm20_0:
6076     return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6077                  "expected 20-bit unsigned immediate");
6078   case Match_UImm26_0:
6079     return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6080                  "expected 26-bit unsigned immediate");
6081   case Match_SImm32:
6082   case Match_SImm32_Relaxed:
6083     return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6084                  "expected 32-bit signed immediate");
6085   case Match_UImm32_Coerced:
6086     return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6087                  "expected 32-bit immediate");
6088   case Match_MemSImm9:
6089     return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6090                  "expected memory with 9-bit signed offset");
6091   case Match_MemSImm10:
6092     return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6093                  "expected memory with 10-bit signed offset");
6094   case Match_MemSImm10Lsl1:
6095     return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6096                  "expected memory with 11-bit signed offset and multiple of 2");
6097   case Match_MemSImm10Lsl2:
6098     return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6099                  "expected memory with 12-bit signed offset and multiple of 4");
6100   case Match_MemSImm10Lsl3:
6101     return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6102                  "expected memory with 13-bit signed offset and multiple of 8");
6103   case Match_MemSImm11:
6104     return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6105                  "expected memory with 11-bit signed offset");
6106   case Match_MemSImm12:
6107     return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6108                  "expected memory with 12-bit signed offset");
6109   case Match_MemSImm16:
6110     return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6111                  "expected memory with 16-bit signed offset");
6112   case Match_MemSImmPtr:
6113     return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
6114                  "expected memory with 32-bit signed offset");
6115   case Match_RequiresPosSizeRange0_32: {
6116     SMLoc ErrorStart = Operands[3]->getStartLoc();
6117     SMLoc ErrorEnd = Operands[4]->getEndLoc();
6118     return Error(ErrorStart, "size plus position are not in the range 0 .. 32",
6119                  SMRange(ErrorStart, ErrorEnd));
6120     }
6121   case Match_RequiresPosSizeUImm6: {
6122     SMLoc ErrorStart = Operands[3]->getStartLoc();
6123     SMLoc ErrorEnd = Operands[4]->getEndLoc();
6124     return Error(ErrorStart, "size plus position are not in the range 1 .. 63",
6125                  SMRange(ErrorStart, ErrorEnd));
6126     }
6127   case Match_RequiresPosSizeRange33_64: {
6128     SMLoc ErrorStart = Operands[3]->getStartLoc();
6129     SMLoc ErrorEnd = Operands[4]->getEndLoc();
6130     return Error(ErrorStart, "size plus position are not in the range 33 .. 64",
6131                  SMRange(ErrorStart, ErrorEnd));
6132     }
6133   }
6134 
6135   llvm_unreachable("Implement any new match types added!");
6136 }
6137 
warnIfRegIndexIsAT(MCRegister RegIndex,SMLoc Loc)6138 void MipsAsmParser::warnIfRegIndexIsAT(MCRegister RegIndex, SMLoc Loc) {
6139   if (RegIndex && AssemblerOptions.back()->getATRegIndex() == RegIndex)
6140     Warning(Loc, "used $at (currently $" + Twine(RegIndex.id()) +
6141                      ") without \".set noat\"");
6142 }
6143 
warnIfNoMacro(SMLoc Loc)6144 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
6145   if (!AssemblerOptions.back()->isMacro())
6146     Warning(Loc, "macro instruction expanded into multiple instructions");
6147 }
6148 
ConvertXWPOperands(MCInst & Inst,const OperandVector & Operands)6149 void MipsAsmParser::ConvertXWPOperands(MCInst &Inst,
6150                                        const OperandVector &Operands) {
6151   assert(
6152       (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM) &&
6153       "Unexpected instruction!");
6154   ((MipsOperand &)*Operands[1]).addGPR32ZeroAsmRegOperands(Inst, 1);
6155   MCRegister NextReg = nextReg(((MipsOperand &)*Operands[1]).getGPR32Reg());
6156   Inst.addOperand(MCOperand::createReg(NextReg));
6157   ((MipsOperand &)*Operands[2]).addMemOperands(Inst, 2);
6158 }
6159 
6160 void
printWarningWithFixIt(const Twine & Msg,const Twine & FixMsg,SMRange Range,bool ShowColors)6161 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
6162                                      SMRange Range, bool ShowColors) {
6163   getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
6164                                   Range, SMFixIt(Range, FixMsg),
6165                                   ShowColors);
6166 }
6167 
matchCPURegisterName(StringRef Name)6168 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
6169   int CC;
6170 
6171   CC = StringSwitch<unsigned>(Name)
6172            .Case("zero", 0)
6173            .Cases("at", "AT", 1)
6174            .Case("a0", 4)
6175            .Case("a1", 5)
6176            .Case("a2", 6)
6177            .Case("a3", 7)
6178            .Case("v0", 2)
6179            .Case("v1", 3)
6180            .Case("s0", 16)
6181            .Case("s1", 17)
6182            .Case("s2", 18)
6183            .Case("s3", 19)
6184            .Case("s4", 20)
6185            .Case("s5", 21)
6186            .Case("s6", 22)
6187            .Case("s7", 23)
6188            .Case("k0", 26)
6189            .Case("k1", 27)
6190            .Case("gp", 28)
6191            .Case("sp", 29)
6192            .Case("fp", 30)
6193            .Case("s8", 30)
6194            .Case("ra", 31)
6195            .Case("t0", 8)
6196            .Case("t1", 9)
6197            .Case("t2", 10)
6198            .Case("t3", 11)
6199            .Case("t4", 12)
6200            .Case("t5", 13)
6201            .Case("t6", 14)
6202            .Case("t7", 15)
6203            .Case("t8", 24)
6204            .Case("t9", 25)
6205            .Default(-1);
6206 
6207   if (!(isABI_N32() || isABI_N64()))
6208     return CC;
6209 
6210   if (12 <= CC && CC <= 15) {
6211     // Name is one of t4-t7
6212     AsmToken RegTok = getLexer().peekTok();
6213     SMRange RegRange = RegTok.getLocRange();
6214 
6215     StringRef FixedName = StringSwitch<StringRef>(Name)
6216                               .Case("t4", "t0")
6217                               .Case("t5", "t1")
6218                               .Case("t6", "t2")
6219                               .Case("t7", "t3")
6220                               .Default("");
6221     assert(FixedName != "" &&  "Register name is not one of t4-t7.");
6222 
6223     printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
6224                           "Did you mean $" + FixedName + "?", RegRange);
6225   }
6226 
6227   // Although SGI documentation just cuts out t0-t3 for n32/n64,
6228   // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
6229   // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
6230   if (8 <= CC && CC <= 11)
6231     CC += 4;
6232 
6233   if (CC == -1)
6234     CC = StringSwitch<unsigned>(Name)
6235              .Case("a4", 8)
6236              .Case("a5", 9)
6237              .Case("a6", 10)
6238              .Case("a7", 11)
6239              .Case("kt0", 26)
6240              .Case("kt1", 27)
6241              .Default(-1);
6242 
6243   return CC;
6244 }
6245 
matchHWRegsRegisterName(StringRef Name)6246 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
6247   int CC;
6248 
6249   CC = StringSwitch<unsigned>(Name)
6250             .Case("hwr_cpunum", 0)
6251             .Case("hwr_synci_step", 1)
6252             .Case("hwr_cc", 2)
6253             .Case("hwr_ccres", 3)
6254             .Case("hwr_ulr", 29)
6255             .Default(-1);
6256 
6257   return CC;
6258 }
6259 
matchFPURegisterName(StringRef Name)6260 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
6261   if (Name[0] == 'f') {
6262     StringRef NumString = Name.substr(1);
6263     unsigned IntVal;
6264     if (NumString.getAsInteger(10, IntVal))
6265       return -1;     // This is not an integer.
6266     if (IntVal > 31) // Maximum index for fpu register.
6267       return -1;
6268     return IntVal;
6269   }
6270   return -1;
6271 }
6272 
matchFCCRegisterName(StringRef Name)6273 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
6274   if (Name.starts_with("fcc")) {
6275     StringRef NumString = Name.substr(3);
6276     unsigned IntVal;
6277     if (NumString.getAsInteger(10, IntVal))
6278       return -1;    // This is not an integer.
6279     if (IntVal > 7) // There are only 8 fcc registers.
6280       return -1;
6281     return IntVal;
6282   }
6283   return -1;
6284 }
6285 
matchACRegisterName(StringRef Name)6286 int MipsAsmParser::matchACRegisterName(StringRef Name) {
6287   if (Name.starts_with("ac")) {
6288     StringRef NumString = Name.substr(2);
6289     unsigned IntVal;
6290     if (NumString.getAsInteger(10, IntVal))
6291       return -1;    // This is not an integer.
6292     if (IntVal > 3) // There are only 3 acc registers.
6293       return -1;
6294     return IntVal;
6295   }
6296   return -1;
6297 }
6298 
matchMSA128RegisterName(StringRef Name)6299 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
6300   unsigned IntVal;
6301 
6302   if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
6303     return -1;
6304 
6305   if (IntVal > 31)
6306     return -1;
6307 
6308   return IntVal;
6309 }
6310 
matchMSA128CtrlRegisterName(StringRef Name)6311 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
6312   int CC;
6313 
6314   CC = StringSwitch<unsigned>(Name)
6315            .Case("msair", 0)
6316            .Case("msacsr", 1)
6317            .Case("msaaccess", 2)
6318            .Case("msasave", 3)
6319            .Case("msamodify", 4)
6320            .Case("msarequest", 5)
6321            .Case("msamap", 6)
6322            .Case("msaunmap", 7)
6323            .Default(-1);
6324 
6325   return CC;
6326 }
6327 
canUseATReg()6328 bool MipsAsmParser::canUseATReg() {
6329   return AssemblerOptions.back()->getATRegIndex() != 0;
6330 }
6331 
getATReg(SMLoc Loc)6332 MCRegister MipsAsmParser::getATReg(SMLoc Loc) {
6333   unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
6334   if (ATIndex == 0) {
6335     reportParseError(Loc,
6336                      "pseudo-instruction requires $at, which is not available");
6337     return 0;
6338   }
6339   MCRegister AT = getReg(
6340       (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
6341   return AT;
6342 }
6343 
getReg(int RC,int RegNo)6344 MCRegister MipsAsmParser::getReg(int RC, int RegNo) {
6345   return getContext().getRegisterInfo()->getRegClass(RC).getRegister(RegNo);
6346 }
6347 
6348 // Parse an expression with optional relocation operator prefixes (e.g. %lo).
6349 // Some weird expressions allowed by gas are not supported for simplicity,
6350 // e.g. "%lo foo", "(%lo(foo))", "%lo(foo)+1".
parseRelocExpr()6351 const MCExpr *MipsAsmParser::parseRelocExpr() {
6352   auto getOp = [](StringRef Op) {
6353     return StringSwitch<Mips::Specifier>(Op)
6354         .Case("call16", Mips::S_GOT_CALL)
6355         .Case("call_hi", Mips::S_CALL_HI16)
6356         .Case("call_lo", Mips::S_CALL_LO16)
6357         .Case("dtprel_hi", Mips::S_DTPREL_HI)
6358         .Case("dtprel_lo", Mips::S_DTPREL_LO)
6359         .Case("got", Mips::S_GOT)
6360         .Case("got_disp", Mips::S_GOT_DISP)
6361         .Case("got_hi", Mips::S_GOT_HI16)
6362         .Case("got_lo", Mips::S_GOT_LO16)
6363         .Case("got_ofst", Mips::S_GOT_OFST)
6364         .Case("got_page", Mips::S_GOT_PAGE)
6365         .Case("gottprel", Mips::S_GOTTPREL)
6366         .Case("gp_rel", Mips::S_GPREL)
6367         .Case("hi", Mips::S_HI)
6368         .Case("higher", Mips::S_HIGHER)
6369         .Case("highest", Mips::S_HIGHEST)
6370         .Case("lo", Mips::S_LO)
6371         .Case("neg", Mips::S_NEG)
6372         .Case("pcrel_hi", Mips::S_PCREL_HI16)
6373         .Case("pcrel_lo", Mips::S_PCREL_LO16)
6374         .Case("tlsgd", Mips::S_TLSGD)
6375         .Case("tlsldm", Mips::S_TLSLDM)
6376         .Case("tprel_hi", Mips::S_TPREL_HI)
6377         .Case("tprel_lo", Mips::S_TPREL_LO)
6378         .Default(Mips::S_None);
6379   };
6380 
6381   MCAsmParser &Parser = getParser();
6382   StringRef Name;
6383   const MCExpr *Res = nullptr;
6384   SmallVector<Mips::Specifier, 0> Ops;
6385   while (parseOptionalToken(AsmToken::Percent)) {
6386     if (Parser.parseIdentifier(Name) ||
6387         Parser.parseToken(AsmToken::LParen, "expected '('"))
6388       return nullptr;
6389     auto Op = getOp(Name);
6390     if (Op == Mips::S_None) {
6391       Error(Parser.getTok().getLoc(), "invalid relocation operator");
6392       return nullptr;
6393     }
6394     Ops.push_back(Op);
6395   }
6396   if (Parser.parseExpression(Res))
6397     return nullptr;
6398   while (Ops.size()) {
6399     if (Parser.parseToken(AsmToken::RParen, "expected ')'"))
6400       return nullptr;
6401     Res = MCSpecifierExpr::create(Res, Ops.pop_back_val(), getContext());
6402   }
6403   return Res;
6404 }
6405 
parseOperand(OperandVector & Operands,StringRef Mnemonic)6406 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
6407   MCAsmParser &Parser = getParser();
6408   LLVM_DEBUG(dbgs() << "parseOperand\n");
6409 
6410   // Check if the current operand has a custom associated parser, if so, try to
6411   // custom parse the operand, or fallback to the general approach.
6412   // Setting the third parameter to true tells the parser to keep parsing even
6413   // if the operands are not supported with the current feature set. In this
6414   // case, the instruction matcher will output a "instruction requires a CPU
6415   // feature not currently enabled" error. If this were false, the parser would
6416   // stop here and output a less useful "invalid operand" error.
6417   ParseStatus Res = MatchOperandParserImpl(Operands, Mnemonic, true);
6418   if (Res.isSuccess())
6419     return false;
6420   // If there wasn't a custom match, try the generic matcher below. Otherwise,
6421   // there was a match, but an error occurred, in which case, just return that
6422   // the operand parsing failed.
6423   if (Res.isFailure())
6424     return true;
6425 
6426   LLVM_DEBUG(dbgs() << ".. Generic Parser\n");
6427 
6428   switch (getLexer().getKind()) {
6429   case AsmToken::Dollar: {
6430     // Parse the register.
6431     SMLoc S = Parser.getTok().getLoc();
6432 
6433     // Almost all registers have been parsed by custom parsers. There is only
6434     // one exception to this. $zero (and it's alias $0) will reach this point
6435     // for div, divu, and similar instructions because it is not an operand
6436     // to the instruction definition but an explicit register. Special case
6437     // this situation for now.
6438     if (!parseAnyRegister(Operands).isNoMatch())
6439       return false;
6440 
6441     // Maybe it is a symbol reference.
6442     StringRef Identifier;
6443     if (Parser.parseIdentifier(Identifier))
6444       return true;
6445 
6446     SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6447     MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
6448     // Otherwise create a symbol reference.
6449     const MCExpr *SymRef = MCSymbolRefExpr::create(Sym, getContext());
6450 
6451     Operands.push_back(MipsOperand::CreateImm(SymRef, S, E, *this));
6452     return false;
6453   }
6454   default: {
6455     SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
6456     const MCExpr *Expr = parseRelocExpr();
6457     if (!Expr)
6458       return true;
6459     SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6460     Operands.push_back(MipsOperand::CreateImm(Expr, S, E, *this));
6461     return false;
6462   }
6463   } // switch(getLexer().getKind())
6464   return true;
6465 }
6466 
parseRegister(MCRegister & Reg,SMLoc & StartLoc,SMLoc & EndLoc)6467 bool MipsAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,
6468                                   SMLoc &EndLoc) {
6469   return !tryParseRegister(Reg, StartLoc, EndLoc).isSuccess();
6470 }
6471 
tryParseRegister(MCRegister & Reg,SMLoc & StartLoc,SMLoc & EndLoc)6472 ParseStatus MipsAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
6473                                             SMLoc &EndLoc) {
6474   SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
6475   ParseStatus Res = parseAnyRegister(Operands);
6476   if (Res.isSuccess()) {
6477     assert(Operands.size() == 1);
6478     MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
6479     StartLoc = Operand.getStartLoc();
6480     EndLoc = Operand.getEndLoc();
6481 
6482     // AFAIK, we only support numeric registers and named GPR's in CFI
6483     // directives.
6484     // Don't worry about eating tokens before failing. Using an unrecognised
6485     // register is a parse error.
6486     if (Operand.isGPRAsmReg()) {
6487       // Resolve to GPR32 or GPR64 appropriately.
6488       Reg = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
6489     }
6490 
6491     return (Reg == (unsigned)-1) ? ParseStatus::NoMatch : ParseStatus::Success;
6492   }
6493 
6494   assert(Operands.size() == 0);
6495   return (Reg == (unsigned)-1) ? ParseStatus::NoMatch : ParseStatus::Success;
6496 }
6497 
parseMemOperand(OperandVector & Operands)6498 ParseStatus MipsAsmParser::parseMemOperand(OperandVector &Operands) {
6499   MCAsmParser &Parser = getParser();
6500   LLVM_DEBUG(dbgs() << "parseMemOperand\n");
6501   const MCExpr *IdVal = nullptr;
6502   SMLoc S;
6503   bool isParenExpr = false;
6504   ParseStatus Res = ParseStatus::NoMatch;
6505   // First operand is the offset.
6506   S = Parser.getTok().getLoc();
6507 
6508   if (getLexer().getKind() == AsmToken::LParen) {
6509     Parser.Lex();
6510     isParenExpr = true;
6511   }
6512 
6513   if (getLexer().getKind() != AsmToken::Dollar) {
6514     IdVal = parseRelocExpr();
6515     if (!IdVal)
6516       return ParseStatus::Failure;
6517     if (isParenExpr && Parser.parseRParen())
6518       return ParseStatus::Failure;
6519 
6520     const AsmToken &Tok = Parser.getTok(); // Get the next token.
6521     if (Tok.isNot(AsmToken::LParen)) {
6522       MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
6523       if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
6524         SMLoc E =
6525             SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6526         Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
6527         return ParseStatus::Success;
6528       }
6529       if (Tok.is(AsmToken::EndOfStatement)) {
6530         SMLoc E =
6531             SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6532 
6533         // Zero register assumed, add a memory operand with ZERO as its base.
6534         // "Base" will be managed by k_Memory.
6535         auto Base = MipsOperand::createGPRReg(
6536             0, "0", getContext().getRegisterInfo(), S, E, *this);
6537         Operands.push_back(
6538             MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
6539         return ParseStatus::Success;
6540       }
6541       MCBinaryExpr::Opcode Opcode;
6542       // GAS and LLVM treat comparison operators different. GAS will generate -1
6543       // or 0, while LLVM will generate 0 or 1. Since a comparsion operator is
6544       // highly unlikely to be found in a memory offset expression, we don't
6545       // handle them.
6546       switch (Tok.getKind()) {
6547       case AsmToken::Plus:
6548         Opcode = MCBinaryExpr::Add;
6549         Parser.Lex();
6550         break;
6551       case AsmToken::Minus:
6552         Opcode = MCBinaryExpr::Sub;
6553         Parser.Lex();
6554         break;
6555       case AsmToken::Star:
6556         Opcode = MCBinaryExpr::Mul;
6557         Parser.Lex();
6558         break;
6559       case AsmToken::Pipe:
6560         Opcode = MCBinaryExpr::Or;
6561         Parser.Lex();
6562         break;
6563       case AsmToken::Amp:
6564         Opcode = MCBinaryExpr::And;
6565         Parser.Lex();
6566         break;
6567       case AsmToken::LessLess:
6568         Opcode = MCBinaryExpr::Shl;
6569         Parser.Lex();
6570         break;
6571       case AsmToken::GreaterGreater:
6572         Opcode = MCBinaryExpr::LShr;
6573         Parser.Lex();
6574         break;
6575       case AsmToken::Caret:
6576         Opcode = MCBinaryExpr::Xor;
6577         Parser.Lex();
6578         break;
6579       case AsmToken::Slash:
6580         Opcode = MCBinaryExpr::Div;
6581         Parser.Lex();
6582         break;
6583       case AsmToken::Percent:
6584         Opcode = MCBinaryExpr::Mod;
6585         Parser.Lex();
6586         break;
6587       default:
6588         return Error(Parser.getTok().getLoc(), "'(' or expression expected");
6589       }
6590       const MCExpr * NextExpr;
6591       if (getParser().parseExpression(NextExpr))
6592         return ParseStatus::Failure;
6593       IdVal = MCBinaryExpr::create(Opcode, IdVal, NextExpr, getContext());
6594     }
6595 
6596     Parser.Lex(); // Eat the '(' token.
6597   }
6598 
6599   Res = parseAnyRegister(Operands);
6600   if (!Res.isSuccess())
6601     return Res;
6602 
6603   if (Parser.getTok().isNot(AsmToken::RParen))
6604     return Error(Parser.getTok().getLoc(), "')' expected");
6605 
6606   SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6607 
6608   Parser.Lex(); // Eat the ')' token.
6609 
6610   if (!IdVal)
6611     IdVal = MCConstantExpr::create(0, getContext());
6612 
6613   // Replace the register operand with the memory operand.
6614   std::unique_ptr<MipsOperand> op(
6615       static_cast<MipsOperand *>(Operands.back().release()));
6616   // Remove the register from the operands.
6617   // "op" will be managed by k_Memory.
6618   Operands.pop_back();
6619   // Add the memory operand.
6620   if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
6621     int64_t Imm;
6622     if (IdVal->evaluateAsAbsolute(Imm))
6623       IdVal = MCConstantExpr::create(Imm, getContext());
6624     else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
6625       IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
6626                                    getContext());
6627   }
6628 
6629   Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
6630   return ParseStatus::Success;
6631 }
6632 
searchSymbolAlias(OperandVector & Operands)6633 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
6634   MCAsmParser &Parser = getParser();
6635   MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
6636   if (!Sym)
6637     return false;
6638 
6639   SMLoc S = Parser.getTok().getLoc();
6640   if (Sym->isVariable()) {
6641     const MCExpr *Expr = Sym->getVariableValue();
6642     if (Expr->getKind() == MCExpr::SymbolRef) {
6643       const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
6644       StringRef DefSymbol = Ref->getSymbol().getName();
6645       if (DefSymbol.starts_with("$")) {
6646         ParseStatus Res =
6647             matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
6648         if (Res.isSuccess()) {
6649           Parser.Lex();
6650           return true;
6651         }
6652         if (Res.isFailure())
6653           llvm_unreachable("Should never fail");
6654       }
6655     }
6656   } else if (Sym->isUnset()) {
6657     // If symbol is unset, it might be created in the `parseSetAssignment`
6658     // routine as an alias for a numeric register name.
6659     // Lookup in the aliases list.
6660     auto Entry = RegisterSets.find(Sym->getName());
6661     if (Entry != RegisterSets.end()) {
6662       ParseStatus Res =
6663           matchAnyRegisterWithoutDollar(Operands, Entry->getValue(), S);
6664       if (Res.isSuccess()) {
6665         Parser.Lex();
6666         return true;
6667       }
6668     }
6669   }
6670 
6671   return false;
6672 }
6673 
matchAnyRegisterNameWithoutDollar(OperandVector & Operands,StringRef Identifier,SMLoc S)6674 ParseStatus MipsAsmParser::matchAnyRegisterNameWithoutDollar(
6675     OperandVector &Operands, StringRef Identifier, SMLoc S) {
6676   int Index = matchCPURegisterName(Identifier);
6677   if (Index != -1) {
6678     Operands.push_back(MipsOperand::createGPRReg(
6679         Index, Identifier, getContext().getRegisterInfo(), S,
6680         getLexer().getLoc(), *this));
6681     return ParseStatus::Success;
6682   }
6683 
6684   Index = matchHWRegsRegisterName(Identifier);
6685   if (Index != -1) {
6686     Operands.push_back(MipsOperand::createHWRegsReg(
6687         Index, Identifier, getContext().getRegisterInfo(), S,
6688         getLexer().getLoc(), *this));
6689     return ParseStatus::Success;
6690   }
6691 
6692   Index = matchFPURegisterName(Identifier);
6693   if (Index != -1) {
6694     Operands.push_back(MipsOperand::createFGRReg(
6695         Index, Identifier, getContext().getRegisterInfo(), S,
6696         getLexer().getLoc(), *this));
6697     return ParseStatus::Success;
6698   }
6699 
6700   Index = matchFCCRegisterName(Identifier);
6701   if (Index != -1) {
6702     Operands.push_back(MipsOperand::createFCCReg(
6703         Index, Identifier, getContext().getRegisterInfo(), S,
6704         getLexer().getLoc(), *this));
6705     return ParseStatus::Success;
6706   }
6707 
6708   Index = matchACRegisterName(Identifier);
6709   if (Index != -1) {
6710     Operands.push_back(MipsOperand::createACCReg(
6711         Index, Identifier, getContext().getRegisterInfo(), S,
6712         getLexer().getLoc(), *this));
6713     return ParseStatus::Success;
6714   }
6715 
6716   Index = matchMSA128RegisterName(Identifier);
6717   if (Index != -1) {
6718     Operands.push_back(MipsOperand::createMSA128Reg(
6719         Index, Identifier, getContext().getRegisterInfo(), S,
6720         getLexer().getLoc(), *this));
6721     return ParseStatus::Success;
6722   }
6723 
6724   Index = matchMSA128CtrlRegisterName(Identifier);
6725   if (Index != -1) {
6726     Operands.push_back(MipsOperand::createMSACtrlReg(
6727         Index, Identifier, getContext().getRegisterInfo(), S,
6728         getLexer().getLoc(), *this));
6729     return ParseStatus::Success;
6730   }
6731 
6732   return ParseStatus::NoMatch;
6733 }
6734 
6735 ParseStatus
matchAnyRegisterWithoutDollar(OperandVector & Operands,const AsmToken & Token,SMLoc S)6736 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands,
6737                                              const AsmToken &Token, SMLoc S) {
6738   if (Token.is(AsmToken::Identifier)) {
6739     LLVM_DEBUG(dbgs() << ".. identifier\n");
6740     StringRef Identifier = Token.getIdentifier();
6741     return matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
6742   }
6743   if (Token.is(AsmToken::Integer)) {
6744     LLVM_DEBUG(dbgs() << ".. integer\n");
6745     int64_t RegNum = Token.getIntVal();
6746     if (RegNum < 0 || RegNum > 31) {
6747       // Show the error, but treat invalid register
6748       // number as a normal one to continue parsing
6749       // and catch other possible errors.
6750       Error(getLexer().getLoc(), "invalid register number");
6751     }
6752     Operands.push_back(MipsOperand::createNumericReg(
6753         RegNum, Token.getString(), getContext().getRegisterInfo(), S,
6754         Token.getLoc(), *this));
6755     return ParseStatus::Success;
6756   }
6757 
6758   LLVM_DEBUG(dbgs() << Token.getKind() << "\n");
6759 
6760   return ParseStatus::NoMatch;
6761 }
6762 
6763 ParseStatus
matchAnyRegisterWithoutDollar(OperandVector & Operands,SMLoc S)6764 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
6765   auto Token = getLexer().peekTok(false);
6766   return matchAnyRegisterWithoutDollar(Operands, Token, S);
6767 }
6768 
parseAnyRegister(OperandVector & Operands)6769 ParseStatus MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
6770   MCAsmParser &Parser = getParser();
6771   LLVM_DEBUG(dbgs() << "parseAnyRegister\n");
6772 
6773   auto Token = Parser.getTok();
6774 
6775   SMLoc S = Token.getLoc();
6776 
6777   if (Token.isNot(AsmToken::Dollar)) {
6778     LLVM_DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
6779     if (Token.is(AsmToken::Identifier)) {
6780       if (searchSymbolAlias(Operands))
6781         return ParseStatus::Success;
6782     }
6783     LLVM_DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
6784     return ParseStatus::NoMatch;
6785   }
6786   LLVM_DEBUG(dbgs() << ".. $\n");
6787 
6788   ParseStatus Res = matchAnyRegisterWithoutDollar(Operands, S);
6789   if (Res.isSuccess()) {
6790     Parser.Lex(); // $
6791     Parser.Lex(); // identifier
6792   }
6793   return Res;
6794 }
6795 
parseJumpTarget(OperandVector & Operands)6796 ParseStatus MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
6797   MCAsmParser &Parser = getParser();
6798   LLVM_DEBUG(dbgs() << "parseJumpTarget\n");
6799 
6800   SMLoc S = getLexer().getLoc();
6801 
6802   // Registers are a valid target and have priority over symbols.
6803   ParseStatus Res = parseAnyRegister(Operands);
6804   if (!Res.isNoMatch())
6805     return Res;
6806 
6807   // Integers and expressions are acceptable
6808   const MCExpr *Expr = nullptr;
6809   if (Parser.parseExpression(Expr)) {
6810     // We have no way of knowing if a symbol was consumed so we must ParseFail
6811     return ParseStatus::Failure;
6812   }
6813   Operands.push_back(
6814       MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
6815   return ParseStatus::Success;
6816 }
6817 
parseInvNum(OperandVector & Operands)6818 ParseStatus MipsAsmParser::parseInvNum(OperandVector &Operands) {
6819   MCAsmParser &Parser = getParser();
6820   const MCExpr *IdVal;
6821   // If the first token is '$' we may have register operand. We have to reject
6822   // cases where it is not a register. Complicating the matter is that
6823   // register names are not reserved across all ABIs.
6824   // Peek past the dollar to see if it's a register name for this ABI.
6825   SMLoc S = Parser.getTok().getLoc();
6826   if (Parser.getTok().is(AsmToken::Dollar)) {
6827     return matchCPURegisterName(Parser.getLexer().peekTok().getString()) == -1
6828                ? ParseStatus::Failure
6829                : ParseStatus::NoMatch;
6830   }
6831   if (getParser().parseExpression(IdVal))
6832     return ParseStatus::Failure;
6833   const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
6834   if (!MCE)
6835     return ParseStatus::NoMatch;
6836   int64_t Val = MCE->getValue();
6837   SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6838   Operands.push_back(MipsOperand::CreateImm(
6839       MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
6840   return ParseStatus::Success;
6841 }
6842 
parseRegisterList(OperandVector & Operands)6843 ParseStatus MipsAsmParser::parseRegisterList(OperandVector &Operands) {
6844   MCAsmParser &Parser = getParser();
6845   SmallVector<unsigned, 10> Regs;
6846   unsigned RegNo;
6847   unsigned PrevReg = Mips::NoRegister;
6848   bool RegRange = false;
6849   SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
6850 
6851   if (Parser.getTok().isNot(AsmToken::Dollar))
6852     return ParseStatus::Failure;
6853 
6854   SMLoc S = Parser.getTok().getLoc();
6855   while (parseAnyRegister(TmpOperands).isSuccess()) {
6856     SMLoc E = getLexer().getLoc();
6857     MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
6858     RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
6859     if (RegRange) {
6860       // Remove last register operand because registers from register range
6861       // should be inserted first.
6862       if ((isGP64bit() && RegNo == Mips::RA_64) ||
6863           (!isGP64bit() && RegNo == Mips::RA)) {
6864         Regs.push_back(RegNo);
6865       } else {
6866         unsigned TmpReg = PrevReg + 1;
6867         while (TmpReg <= RegNo) {
6868           if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
6869               (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
6870                isGP64bit()))
6871             return Error(E, "invalid register operand");
6872 
6873           PrevReg = TmpReg;
6874           Regs.push_back(TmpReg++);
6875         }
6876       }
6877 
6878       RegRange = false;
6879     } else {
6880       if ((PrevReg == Mips::NoRegister) &&
6881           ((isGP64bit() && (RegNo != Mips::S0_64) && (RegNo != Mips::RA_64)) ||
6882            (!isGP64bit() && (RegNo != Mips::S0) && (RegNo != Mips::RA))))
6883         return Error(E, "$16 or $31 expected");
6884       if (!(((RegNo == Mips::FP || RegNo == Mips::RA ||
6885               (RegNo >= Mips::S0 && RegNo <= Mips::S7)) &&
6886              !isGP64bit()) ||
6887             ((RegNo == Mips::FP_64 || RegNo == Mips::RA_64 ||
6888               (RegNo >= Mips::S0_64 && RegNo <= Mips::S7_64)) &&
6889              isGP64bit())))
6890         return Error(E, "invalid register operand");
6891       if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
6892           ((RegNo != Mips::FP && RegNo != Mips::RA && !isGP64bit()) ||
6893            (RegNo != Mips::FP_64 && RegNo != Mips::RA_64 && isGP64bit())))
6894         return Error(E, "consecutive register numbers expected");
6895 
6896       Regs.push_back(RegNo);
6897     }
6898 
6899     if (Parser.getTok().is(AsmToken::Minus))
6900       RegRange = true;
6901 
6902     if (!Parser.getTok().isNot(AsmToken::Minus) &&
6903         !Parser.getTok().isNot(AsmToken::Comma))
6904       return Error(E, "',' or '-' expected");
6905 
6906     Lex(); // Consume comma or minus
6907     if (Parser.getTok().isNot(AsmToken::Dollar))
6908       break;
6909 
6910     PrevReg = RegNo;
6911   }
6912 
6913   SMLoc E = Parser.getTok().getLoc();
6914   Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
6915   parseMemOperand(Operands);
6916   return ParseStatus::Success;
6917 }
6918 
6919 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
6920 /// either this.
6921 /// ::= '(', register, ')'
6922 /// handle it before we iterate so we don't get tripped up by the lack of
6923 /// a comma.
parseParenSuffix(StringRef Name,OperandVector & Operands)6924 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
6925   MCAsmParser &Parser = getParser();
6926   if (getLexer().is(AsmToken::LParen)) {
6927     Operands.push_back(
6928         MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
6929     Parser.Lex();
6930     if (parseOperand(Operands, Name)) {
6931       SMLoc Loc = getLexer().getLoc();
6932       return Error(Loc, "unexpected token in argument list");
6933     }
6934     if (Parser.getTok().isNot(AsmToken::RParen)) {
6935       SMLoc Loc = getLexer().getLoc();
6936       return Error(Loc, "unexpected token, expected ')'");
6937     }
6938     Operands.push_back(
6939         MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
6940     Parser.Lex();
6941   }
6942   return false;
6943 }
6944 
6945 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
6946 /// either one of these.
6947 /// ::= '[', register, ']'
6948 /// ::= '[', integer, ']'
6949 /// handle it before we iterate so we don't get tripped up by the lack of
6950 /// a comma.
parseBracketSuffix(StringRef Name,OperandVector & Operands)6951 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
6952                                        OperandVector &Operands) {
6953   MCAsmParser &Parser = getParser();
6954   if (getLexer().is(AsmToken::LBrac)) {
6955     Operands.push_back(
6956         MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
6957     Parser.Lex();
6958     if (parseOperand(Operands, Name)) {
6959       SMLoc Loc = getLexer().getLoc();
6960       return Error(Loc, "unexpected token in argument list");
6961     }
6962     if (Parser.getTok().isNot(AsmToken::RBrac)) {
6963       SMLoc Loc = getLexer().getLoc();
6964       return Error(Loc, "unexpected token, expected ']'");
6965     }
6966     Operands.push_back(
6967         MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
6968     Parser.Lex();
6969   }
6970   return false;
6971 }
6972 
6973 static std::string MipsMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS,
6974                                           unsigned VariantID = 0);
6975 
areEqualRegs(const MCParsedAsmOperand & Op1,const MCParsedAsmOperand & Op2) const6976 bool MipsAsmParser::areEqualRegs(const MCParsedAsmOperand &Op1,
6977                                  const MCParsedAsmOperand &Op2) const {
6978   // This target-overriden function exists to maintain current behaviour for
6979   // e.g.
6980   //   dahi    $3, $3, 0x5678
6981   // as tested in test/MC/Mips/mips64r6/valid.s.
6982   // FIXME: Should this test actually fail with an error? If so, then remove
6983   // this overloaded method.
6984   if (!Op1.isReg() || !Op2.isReg())
6985     return true;
6986   return Op1.getReg() == Op2.getReg();
6987 }
6988 
parseInstruction(ParseInstructionInfo & Info,StringRef Name,SMLoc NameLoc,OperandVector & Operands)6989 bool MipsAsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,
6990                                      SMLoc NameLoc, OperandVector &Operands) {
6991   MCAsmParser &Parser = getParser();
6992   LLVM_DEBUG(dbgs() << "parseInstruction\n");
6993 
6994   // We have reached first instruction, module directive are now forbidden.
6995   getTargetStreamer().forbidModuleDirective();
6996 
6997   // Check if we have valid mnemonic
6998   if (!mnemonicIsValid(Name, 0)) {
6999     FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
7000     std::string Suggestion = MipsMnemonicSpellCheck(Name, FBS);
7001     return Error(NameLoc, "unknown instruction" + Suggestion);
7002   }
7003   // First operand in MCInst is instruction mnemonic.
7004   Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
7005 
7006   // Read the remaining operands.
7007   if (getLexer().isNot(AsmToken::EndOfStatement)) {
7008     // Read the first operand.
7009     if (parseOperand(Operands, Name)) {
7010       SMLoc Loc = getLexer().getLoc();
7011       return Error(Loc, "unexpected token in argument list");
7012     }
7013     if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
7014       return true;
7015     // AFAIK, parenthesis suffixes are never on the first operand
7016 
7017     while (getLexer().is(AsmToken::Comma)) {
7018       Parser.Lex(); // Eat the comma.
7019       // Parse and remember the operand.
7020       if (parseOperand(Operands, Name)) {
7021         SMLoc Loc = getLexer().getLoc();
7022         return Error(Loc, "unexpected token in argument list");
7023       }
7024       // Parse bracket and parenthesis suffixes before we iterate
7025       if (getLexer().is(AsmToken::LBrac)) {
7026         if (parseBracketSuffix(Name, Operands))
7027           return true;
7028       } else if (getLexer().is(AsmToken::LParen) &&
7029                  parseParenSuffix(Name, Operands))
7030         return true;
7031     }
7032   }
7033   if (getLexer().isNot(AsmToken::EndOfStatement)) {
7034     SMLoc Loc = getLexer().getLoc();
7035     return Error(Loc, "unexpected token in argument list");
7036   }
7037   Parser.Lex(); // Consume the EndOfStatement.
7038   return false;
7039 }
7040 
7041 // FIXME: Given that these have the same name, these should both be
7042 // consistent on affecting the Parser.
reportParseError(const Twine & ErrorMsg)7043 bool MipsAsmParser::reportParseError(const Twine &ErrorMsg) {
7044   SMLoc Loc = getLexer().getLoc();
7045   return Error(Loc, ErrorMsg);
7046 }
7047 
reportParseError(SMLoc Loc,const Twine & ErrorMsg)7048 bool MipsAsmParser::reportParseError(SMLoc Loc, const Twine &ErrorMsg) {
7049   return Error(Loc, ErrorMsg);
7050 }
7051 
parseSetNoAtDirective()7052 bool MipsAsmParser::parseSetNoAtDirective() {
7053   MCAsmParser &Parser = getParser();
7054   // Line should look like: ".set noat".
7055 
7056   // Set the $at register to $0.
7057   AssemblerOptions.back()->setATRegIndex(0);
7058 
7059   Parser.Lex(); // Eat "noat".
7060 
7061   // If this is not the end of the statement, report an error.
7062   if (getLexer().isNot(AsmToken::EndOfStatement)) {
7063     reportParseError("unexpected token, expected end of statement");
7064     return false;
7065   }
7066 
7067   getTargetStreamer().emitDirectiveSetNoAt();
7068   Parser.Lex(); // Consume the EndOfStatement.
7069   return false;
7070 }
7071 
parseSetAtDirective()7072 bool MipsAsmParser::parseSetAtDirective() {
7073   // Line can be: ".set at", which sets $at to $1
7074   //          or  ".set at=$reg", which sets $at to $reg.
7075   MCAsmParser &Parser = getParser();
7076   Parser.Lex(); // Eat "at".
7077 
7078   if (getLexer().is(AsmToken::EndOfStatement)) {
7079     // No register was specified, so we set $at to $1.
7080     AssemblerOptions.back()->setATRegIndex(1);
7081 
7082     getTargetStreamer().emitDirectiveSetAt();
7083     Parser.Lex(); // Consume the EndOfStatement.
7084     return false;
7085   }
7086 
7087   if (getLexer().isNot(AsmToken::Equal)) {
7088     reportParseError("unexpected token, expected equals sign");
7089     return false;
7090   }
7091   Parser.Lex(); // Eat "=".
7092 
7093   if (getLexer().isNot(AsmToken::Dollar)) {
7094     if (getLexer().is(AsmToken::EndOfStatement)) {
7095       reportParseError("no register specified");
7096       return false;
7097     } else {
7098       reportParseError("unexpected token, expected dollar sign '$'");
7099       return false;
7100     }
7101   }
7102   Parser.Lex(); // Eat "$".
7103 
7104   // Find out what "reg" is.
7105   unsigned AtRegNo;
7106   const AsmToken &Reg = Parser.getTok();
7107   if (Reg.is(AsmToken::Identifier)) {
7108     AtRegNo = matchCPURegisterName(Reg.getIdentifier());
7109   } else if (Reg.is(AsmToken::Integer)) {
7110     AtRegNo = Reg.getIntVal();
7111   } else {
7112     reportParseError("unexpected token, expected identifier or integer");
7113     return false;
7114   }
7115 
7116   // Check if $reg is a valid register. If it is, set $at to $reg.
7117   if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
7118     reportParseError("invalid register");
7119     return false;
7120   }
7121   Parser.Lex(); // Eat "reg".
7122 
7123   // If this is not the end of the statement, report an error.
7124   if (getLexer().isNot(AsmToken::EndOfStatement)) {
7125     reportParseError("unexpected token, expected end of statement");
7126     return false;
7127   }
7128 
7129   getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
7130 
7131   Parser.Lex(); // Consume the EndOfStatement.
7132   return false;
7133 }
7134 
parseSetReorderDirective()7135 bool MipsAsmParser::parseSetReorderDirective() {
7136   MCAsmParser &Parser = getParser();
7137   Parser.Lex();
7138   // If this is not the end of the statement, report an error.
7139   if (getLexer().isNot(AsmToken::EndOfStatement)) {
7140     reportParseError("unexpected token, expected end of statement");
7141     return false;
7142   }
7143   AssemblerOptions.back()->setReorder();
7144   getTargetStreamer().emitDirectiveSetReorder();
7145   Parser.Lex(); // Consume the EndOfStatement.
7146   return false;
7147 }
7148 
parseSetNoReorderDirective()7149 bool MipsAsmParser::parseSetNoReorderDirective() {
7150   MCAsmParser &Parser = getParser();
7151   Parser.Lex();
7152   // If this is not the end of the statement, report an error.
7153   if (getLexer().isNot(AsmToken::EndOfStatement)) {
7154     reportParseError("unexpected token, expected end of statement");
7155     return false;
7156   }
7157   AssemblerOptions.back()->setNoReorder();
7158   getTargetStreamer().emitDirectiveSetNoReorder();
7159   Parser.Lex(); // Consume the EndOfStatement.
7160   return false;
7161 }
7162 
parseSetMacroDirective()7163 bool MipsAsmParser::parseSetMacroDirective() {
7164   MCAsmParser &Parser = getParser();
7165   Parser.Lex();
7166   // If this is not the end of the statement, report an error.
7167   if (getLexer().isNot(AsmToken::EndOfStatement)) {
7168     reportParseError("unexpected token, expected end of statement");
7169     return false;
7170   }
7171   AssemblerOptions.back()->setMacro();
7172   getTargetStreamer().emitDirectiveSetMacro();
7173   Parser.Lex(); // Consume the EndOfStatement.
7174   return false;
7175 }
7176 
parseSetNoMacroDirective()7177 bool MipsAsmParser::parseSetNoMacroDirective() {
7178   MCAsmParser &Parser = getParser();
7179   Parser.Lex();
7180   // If this is not the end of the statement, report an error.
7181   if (getLexer().isNot(AsmToken::EndOfStatement)) {
7182     reportParseError("unexpected token, expected end of statement");
7183     return false;
7184   }
7185   if (AssemblerOptions.back()->isReorder()) {
7186     reportParseError("`noreorder' must be set before `nomacro'");
7187     return false;
7188   }
7189   AssemblerOptions.back()->setNoMacro();
7190   getTargetStreamer().emitDirectiveSetNoMacro();
7191   Parser.Lex(); // Consume the EndOfStatement.
7192   return false;
7193 }
7194 
parseSetMsaDirective()7195 bool MipsAsmParser::parseSetMsaDirective() {
7196   MCAsmParser &Parser = getParser();
7197   Parser.Lex();
7198 
7199   // If this is not the end of the statement, report an error.
7200   if (getLexer().isNot(AsmToken::EndOfStatement))
7201     return reportParseError("unexpected token, expected end of statement");
7202 
7203   setFeatureBits(Mips::FeatureMSA, "msa");
7204   getTargetStreamer().emitDirectiveSetMsa();
7205   return false;
7206 }
7207 
parseSetNoMsaDirective()7208 bool MipsAsmParser::parseSetNoMsaDirective() {
7209   MCAsmParser &Parser = getParser();
7210   Parser.Lex();
7211 
7212   // If this is not the end of the statement, report an error.
7213   if (getLexer().isNot(AsmToken::EndOfStatement))
7214     return reportParseError("unexpected token, expected end of statement");
7215 
7216   clearFeatureBits(Mips::FeatureMSA, "msa");
7217   getTargetStreamer().emitDirectiveSetNoMsa();
7218   return false;
7219 }
7220 
parseSetNoDspDirective()7221 bool MipsAsmParser::parseSetNoDspDirective() {
7222   MCAsmParser &Parser = getParser();
7223   Parser.Lex(); // Eat "nodsp".
7224 
7225   // If this is not the end of the statement, report an error.
7226   if (getLexer().isNot(AsmToken::EndOfStatement)) {
7227     reportParseError("unexpected token, expected end of statement");
7228     return false;
7229   }
7230 
7231   clearFeatureBits(Mips::FeatureDSP, "dsp");
7232   getTargetStreamer().emitDirectiveSetNoDsp();
7233   return false;
7234 }
7235 
parseSetNoMips3DDirective()7236 bool MipsAsmParser::parseSetNoMips3DDirective() {
7237   MCAsmParser &Parser = getParser();
7238   Parser.Lex(); // Eat "nomips3d".
7239 
7240   // If this is not the end of the statement, report an error.
7241   if (getLexer().isNot(AsmToken::EndOfStatement)) {
7242     reportParseError("unexpected token, expected end of statement");
7243     return false;
7244   }
7245 
7246   clearFeatureBits(Mips::FeatureMips3D, "mips3d");
7247   getTargetStreamer().emitDirectiveSetNoMips3D();
7248   return false;
7249 }
7250 
parseSetMips16Directive()7251 bool MipsAsmParser::parseSetMips16Directive() {
7252   MCAsmParser &Parser = getParser();
7253   Parser.Lex(); // Eat "mips16".
7254 
7255   // If this is not the end of the statement, report an error.
7256   if (getLexer().isNot(AsmToken::EndOfStatement)) {
7257     reportParseError("unexpected token, expected end of statement");
7258     return false;
7259   }
7260 
7261   setFeatureBits(Mips::FeatureMips16, "mips16");
7262   getTargetStreamer().emitDirectiveSetMips16();
7263   Parser.Lex(); // Consume the EndOfStatement.
7264   return false;
7265 }
7266 
parseSetNoMips16Directive()7267 bool MipsAsmParser::parseSetNoMips16Directive() {
7268   MCAsmParser &Parser = getParser();
7269   Parser.Lex(); // Eat "nomips16".
7270 
7271   // If this is not the end of the statement, report an error.
7272   if (getLexer().isNot(AsmToken::EndOfStatement)) {
7273     reportParseError("unexpected token, expected end of statement");
7274     return false;
7275   }
7276 
7277   clearFeatureBits(Mips::FeatureMips16, "mips16");
7278   getTargetStreamer().emitDirectiveSetNoMips16();
7279   Parser.Lex(); // Consume the EndOfStatement.
7280   return false;
7281 }
7282 
parseSetFpDirective()7283 bool MipsAsmParser::parseSetFpDirective() {
7284   MCAsmParser &Parser = getParser();
7285   MipsABIFlagsSection::FpABIKind FpAbiVal;
7286   // Line can be: .set fp=32
7287   //              .set fp=xx
7288   //              .set fp=64
7289   Parser.Lex(); // Eat fp token
7290   AsmToken Tok = Parser.getTok();
7291   if (Tok.isNot(AsmToken::Equal)) {
7292     reportParseError("unexpected token, expected equals sign '='");
7293     return false;
7294   }
7295   Parser.Lex(); // Eat '=' token.
7296   Tok = Parser.getTok();
7297 
7298   if (!parseFpABIValue(FpAbiVal, ".set"))
7299     return false;
7300 
7301   if (getLexer().isNot(AsmToken::EndOfStatement)) {
7302     reportParseError("unexpected token, expected end of statement");
7303     return false;
7304   }
7305   getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
7306   Parser.Lex(); // Consume the EndOfStatement.
7307   return false;
7308 }
7309 
parseSetOddSPRegDirective()7310 bool MipsAsmParser::parseSetOddSPRegDirective() {
7311   MCAsmParser &Parser = getParser();
7312 
7313   Parser.Lex(); // Eat "oddspreg".
7314   if (getLexer().isNot(AsmToken::EndOfStatement)) {
7315     reportParseError("unexpected token, expected end of statement");
7316     return false;
7317   }
7318 
7319   clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
7320   getTargetStreamer().emitDirectiveSetOddSPReg();
7321   return false;
7322 }
7323 
parseSetNoOddSPRegDirective()7324 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
7325   MCAsmParser &Parser = getParser();
7326 
7327   Parser.Lex(); // Eat "nooddspreg".
7328   if (getLexer().isNot(AsmToken::EndOfStatement)) {
7329     reportParseError("unexpected token, expected end of statement");
7330     return false;
7331   }
7332 
7333   setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
7334   getTargetStreamer().emitDirectiveSetNoOddSPReg();
7335   return false;
7336 }
7337 
parseSetMtDirective()7338 bool MipsAsmParser::parseSetMtDirective() {
7339   MCAsmParser &Parser = getParser();
7340   Parser.Lex(); // Eat "mt".
7341 
7342   // If this is not the end of the statement, report an error.
7343   if (getLexer().isNot(AsmToken::EndOfStatement)) {
7344     reportParseError("unexpected token, expected end of statement");
7345     return false;
7346   }
7347 
7348   setFeatureBits(Mips::FeatureMT, "mt");
7349   getTargetStreamer().emitDirectiveSetMt();
7350   Parser.Lex(); // Consume the EndOfStatement.
7351   return false;
7352 }
7353 
parseSetNoMtDirective()7354 bool MipsAsmParser::parseSetNoMtDirective() {
7355   MCAsmParser &Parser = getParser();
7356   Parser.Lex(); // Eat "nomt".
7357 
7358   // If this is not the end of the statement, report an error.
7359   if (getLexer().isNot(AsmToken::EndOfStatement)) {
7360     reportParseError("unexpected token, expected end of statement");
7361     return false;
7362   }
7363 
7364   clearFeatureBits(Mips::FeatureMT, "mt");
7365 
7366   getTargetStreamer().emitDirectiveSetNoMt();
7367   Parser.Lex(); // Consume the EndOfStatement.
7368   return false;
7369 }
7370 
parseSetNoCRCDirective()7371 bool MipsAsmParser::parseSetNoCRCDirective() {
7372   MCAsmParser &Parser = getParser();
7373   Parser.Lex(); // Eat "nocrc".
7374 
7375   // If this is not the end of the statement, report an error.
7376   if (getLexer().isNot(AsmToken::EndOfStatement)) {
7377     reportParseError("unexpected token, expected end of statement");
7378     return false;
7379   }
7380 
7381   clearFeatureBits(Mips::FeatureCRC, "crc");
7382 
7383   getTargetStreamer().emitDirectiveSetNoCRC();
7384   Parser.Lex(); // Consume the EndOfStatement.
7385   return false;
7386 }
7387 
parseSetNoVirtDirective()7388 bool MipsAsmParser::parseSetNoVirtDirective() {
7389   MCAsmParser &Parser = getParser();
7390   Parser.Lex(); // Eat "novirt".
7391 
7392   // If this is not the end of the statement, report an error.
7393   if (getLexer().isNot(AsmToken::EndOfStatement)) {
7394     reportParseError("unexpected token, expected end of statement");
7395     return false;
7396   }
7397 
7398   clearFeatureBits(Mips::FeatureVirt, "virt");
7399 
7400   getTargetStreamer().emitDirectiveSetNoVirt();
7401   Parser.Lex(); // Consume the EndOfStatement.
7402   return false;
7403 }
7404 
parseSetNoGINVDirective()7405 bool MipsAsmParser::parseSetNoGINVDirective() {
7406   MCAsmParser &Parser = getParser();
7407   Parser.Lex(); // Eat "noginv".
7408 
7409   // If this is not the end of the statement, report an error.
7410   if (getLexer().isNot(AsmToken::EndOfStatement)) {
7411     reportParseError("unexpected token, expected end of statement");
7412     return false;
7413   }
7414 
7415   clearFeatureBits(Mips::FeatureGINV, "ginv");
7416 
7417   getTargetStreamer().emitDirectiveSetNoGINV();
7418   Parser.Lex(); // Consume the EndOfStatement.
7419   return false;
7420 }
7421 
parseSetPopDirective()7422 bool MipsAsmParser::parseSetPopDirective() {
7423   MCAsmParser &Parser = getParser();
7424   SMLoc Loc = getLexer().getLoc();
7425 
7426   Parser.Lex();
7427   if (getLexer().isNot(AsmToken::EndOfStatement))
7428     return reportParseError("unexpected token, expected end of statement");
7429 
7430   // Always keep an element on the options "stack" to prevent the user
7431   // from changing the initial options. This is how we remember them.
7432   if (AssemblerOptions.size() == 2)
7433     return reportParseError(Loc, ".set pop with no .set push");
7434 
7435   MCSubtargetInfo &STI = copySTI();
7436   AssemblerOptions.pop_back();
7437   setAvailableFeatures(
7438       ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
7439   STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
7440 
7441   getTargetStreamer().emitDirectiveSetPop();
7442   return false;
7443 }
7444 
parseSetPushDirective()7445 bool MipsAsmParser::parseSetPushDirective() {
7446   MCAsmParser &Parser = getParser();
7447   Parser.Lex();
7448   if (getLexer().isNot(AsmToken::EndOfStatement))
7449     return reportParseError("unexpected token, expected end of statement");
7450 
7451   // Create a copy of the current assembler options environment and push it.
7452   AssemblerOptions.push_back(
7453         std::make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
7454 
7455   getTargetStreamer().emitDirectiveSetPush();
7456   return false;
7457 }
7458 
parseSetSoftFloatDirective()7459 bool MipsAsmParser::parseSetSoftFloatDirective() {
7460   MCAsmParser &Parser = getParser();
7461   Parser.Lex();
7462   if (getLexer().isNot(AsmToken::EndOfStatement))
7463     return reportParseError("unexpected token, expected end of statement");
7464 
7465   setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
7466   getTargetStreamer().emitDirectiveSetSoftFloat();
7467   return false;
7468 }
7469 
parseSetHardFloatDirective()7470 bool MipsAsmParser::parseSetHardFloatDirective() {
7471   MCAsmParser &Parser = getParser();
7472   Parser.Lex();
7473   if (getLexer().isNot(AsmToken::EndOfStatement))
7474     return reportParseError("unexpected token, expected end of statement");
7475 
7476   clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
7477   getTargetStreamer().emitDirectiveSetHardFloat();
7478   return false;
7479 }
7480 
parseSetAssignment()7481 bool MipsAsmParser::parseSetAssignment() {
7482   StringRef Name;
7483   MCAsmParser &Parser = getParser();
7484 
7485   if (Parser.parseIdentifier(Name))
7486     return reportParseError("expected identifier after .set");
7487 
7488   if (getLexer().isNot(AsmToken::Comma))
7489     return reportParseError("unexpected token, expected comma");
7490   Lex(); // Eat comma
7491 
7492   if (getLexer().is(AsmToken::Dollar) &&
7493       getLexer().peekTok().is(AsmToken::Integer)) {
7494     // Parse assignment of a numeric register:
7495     //   .set r1,$1
7496     Parser.Lex(); // Eat $.
7497     RegisterSets[Name] = Parser.getTok();
7498     Parser.Lex(); // Eat identifier.
7499     getContext().getOrCreateSymbol(Name);
7500     return false;
7501   }
7502 
7503   MCSymbol *Sym;
7504   const MCExpr *Value;
7505   if (MCParserUtils::parseAssignmentExpression(Name, /* allow_redef */ true,
7506                                                Parser, Sym, Value))
7507     return true;
7508   getStreamer().emitAssignment(Sym, Value);
7509 
7510   return false;
7511 }
7512 
parseSetMips0Directive()7513 bool MipsAsmParser::parseSetMips0Directive() {
7514   MCAsmParser &Parser = getParser();
7515   Parser.Lex();
7516   if (getLexer().isNot(AsmToken::EndOfStatement))
7517     return reportParseError("unexpected token, expected end of statement");
7518 
7519   // Reset assembler options to their initial values.
7520   MCSubtargetInfo &STI = copySTI();
7521   setAvailableFeatures(
7522       ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
7523   STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
7524   AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
7525 
7526   getTargetStreamer().emitDirectiveSetMips0();
7527   return false;
7528 }
7529 
parseSetArchDirective()7530 bool MipsAsmParser::parseSetArchDirective() {
7531   MCAsmParser &Parser = getParser();
7532   Parser.Lex();
7533   if (getLexer().isNot(AsmToken::Equal))
7534     return reportParseError("unexpected token, expected equals sign");
7535 
7536   Parser.Lex();
7537   StringRef Arch = getParser().parseStringToEndOfStatement().trim();
7538   if (Arch.empty())
7539     return reportParseError("expected arch identifier");
7540 
7541   StringRef ArchFeatureName =
7542       StringSwitch<StringRef>(Arch)
7543           .Case("mips1", "mips1")
7544           .Case("mips2", "mips2")
7545           .Case("mips3", "mips3")
7546           .Case("mips4", "mips4")
7547           .Case("mips5", "mips5")
7548           .Case("mips32", "mips32")
7549           .Case("mips32r2", "mips32r2")
7550           .Case("mips32r3", "mips32r3")
7551           .Case("mips32r5", "mips32r5")
7552           .Case("mips32r6", "mips32r6")
7553           .Case("mips64", "mips64")
7554           .Case("mips64r2", "mips64r2")
7555           .Case("mips64r3", "mips64r3")
7556           .Case("mips64r5", "mips64r5")
7557           .Case("mips64r6", "mips64r6")
7558           .Case("octeon", "cnmips")
7559           .Case("octeon+", "cnmipsp")
7560           .Case("r4000", "mips3") // This is an implementation of Mips3.
7561           .Default("");
7562 
7563   if (ArchFeatureName.empty())
7564     return reportParseError("unsupported architecture");
7565 
7566   if (ArchFeatureName == "mips64r6" && inMicroMipsMode())
7567     return reportParseError("mips64r6 does not support microMIPS");
7568 
7569   selectArch(ArchFeatureName);
7570   getTargetStreamer().emitDirectiveSetArch(Arch);
7571   return false;
7572 }
7573 
parseSetFeature(uint64_t Feature)7574 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
7575   MCAsmParser &Parser = getParser();
7576   Parser.Lex();
7577   if (getLexer().isNot(AsmToken::EndOfStatement))
7578     return reportParseError("unexpected token, expected end of statement");
7579 
7580   switch (Feature) {
7581   default:
7582     llvm_unreachable("Unimplemented feature");
7583   case Mips::FeatureMips3D:
7584     setFeatureBits(Mips::FeatureMips3D, "mips3d");
7585     getTargetStreamer().emitDirectiveSetMips3D();
7586     break;
7587   case Mips::FeatureDSP:
7588     setFeatureBits(Mips::FeatureDSP, "dsp");
7589     getTargetStreamer().emitDirectiveSetDsp();
7590     break;
7591   case Mips::FeatureDSPR2:
7592     setFeatureBits(Mips::FeatureDSPR2, "dspr2");
7593     getTargetStreamer().emitDirectiveSetDspr2();
7594     break;
7595   case Mips::FeatureMicroMips:
7596     setFeatureBits(Mips::FeatureMicroMips, "micromips");
7597     getTargetStreamer().emitDirectiveSetMicroMips();
7598     break;
7599   case Mips::FeatureMips1:
7600     selectArch("mips1");
7601     getTargetStreamer().emitDirectiveSetMips1();
7602     break;
7603   case Mips::FeatureMips2:
7604     selectArch("mips2");
7605     getTargetStreamer().emitDirectiveSetMips2();
7606     break;
7607   case Mips::FeatureMips3:
7608     selectArch("mips3");
7609     getTargetStreamer().emitDirectiveSetMips3();
7610     break;
7611   case Mips::FeatureMips4:
7612     selectArch("mips4");
7613     getTargetStreamer().emitDirectiveSetMips4();
7614     break;
7615   case Mips::FeatureMips5:
7616     selectArch("mips5");
7617     getTargetStreamer().emitDirectiveSetMips5();
7618     break;
7619   case Mips::FeatureMips32:
7620     selectArch("mips32");
7621     getTargetStreamer().emitDirectiveSetMips32();
7622     break;
7623   case Mips::FeatureMips32r2:
7624     selectArch("mips32r2");
7625     getTargetStreamer().emitDirectiveSetMips32R2();
7626     break;
7627   case Mips::FeatureMips32r3:
7628     selectArch("mips32r3");
7629     getTargetStreamer().emitDirectiveSetMips32R3();
7630     break;
7631   case Mips::FeatureMips32r5:
7632     selectArch("mips32r5");
7633     getTargetStreamer().emitDirectiveSetMips32R5();
7634     break;
7635   case Mips::FeatureMips32r6:
7636     selectArch("mips32r6");
7637     getTargetStreamer().emitDirectiveSetMips32R6();
7638     break;
7639   case Mips::FeatureMips64:
7640     selectArch("mips64");
7641     getTargetStreamer().emitDirectiveSetMips64();
7642     break;
7643   case Mips::FeatureMips64r2:
7644     selectArch("mips64r2");
7645     getTargetStreamer().emitDirectiveSetMips64R2();
7646     break;
7647   case Mips::FeatureMips64r3:
7648     selectArch("mips64r3");
7649     getTargetStreamer().emitDirectiveSetMips64R3();
7650     break;
7651   case Mips::FeatureMips64r5:
7652     selectArch("mips64r5");
7653     getTargetStreamer().emitDirectiveSetMips64R5();
7654     break;
7655   case Mips::FeatureMips64r6:
7656     selectArch("mips64r6");
7657     getTargetStreamer().emitDirectiveSetMips64R6();
7658     break;
7659   case Mips::FeatureCRC:
7660     setFeatureBits(Mips::FeatureCRC, "crc");
7661     getTargetStreamer().emitDirectiveSetCRC();
7662     break;
7663   case Mips::FeatureVirt:
7664     setFeatureBits(Mips::FeatureVirt, "virt");
7665     getTargetStreamer().emitDirectiveSetVirt();
7666     break;
7667   case Mips::FeatureGINV:
7668     setFeatureBits(Mips::FeatureGINV, "ginv");
7669     getTargetStreamer().emitDirectiveSetGINV();
7670     break;
7671   }
7672   return false;
7673 }
7674 
eatComma(StringRef ErrorStr)7675 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
7676   MCAsmParser &Parser = getParser();
7677   if (getLexer().isNot(AsmToken::Comma)) {
7678     SMLoc Loc = getLexer().getLoc();
7679     return Error(Loc, ErrorStr);
7680   }
7681 
7682   Parser.Lex(); // Eat the comma.
7683   return true;
7684 }
7685 
7686 // Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
7687 // In this class, it is only used for .cprestore.
7688 // FIXME: Only keep track of IsPicEnabled in one place, instead of in both
7689 // MipsTargetELFStreamer and MipsAsmParser.
isPicAndNotNxxAbi()7690 bool MipsAsmParser::isPicAndNotNxxAbi() {
7691   return inPicMode() && !(isABI_N32() || isABI_N64());
7692 }
7693 
parseDirectiveCpAdd(SMLoc Loc)7694 bool MipsAsmParser::parseDirectiveCpAdd(SMLoc Loc) {
7695   SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
7696   ParseStatus Res = parseAnyRegister(Reg);
7697   if (Res.isNoMatch() || Res.isFailure()) {
7698     reportParseError("expected register");
7699     return false;
7700   }
7701 
7702   MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
7703   if (!RegOpnd.isGPRAsmReg()) {
7704     reportParseError(RegOpnd.getStartLoc(), "invalid register");
7705     return false;
7706   }
7707 
7708   // If this is not the end of the statement, report an error.
7709   if (getLexer().isNot(AsmToken::EndOfStatement)) {
7710     reportParseError("unexpected token, expected end of statement");
7711     return false;
7712   }
7713   getParser().Lex(); // Consume the EndOfStatement.
7714 
7715   getTargetStreamer().emitDirectiveCpAdd(RegOpnd.getGPR32Reg());
7716   return false;
7717 }
7718 
parseDirectiveCpLoad(SMLoc Loc)7719 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
7720   if (AssemblerOptions.back()->isReorder())
7721     Warning(Loc, ".cpload should be inside a noreorder section");
7722 
7723   if (inMips16Mode()) {
7724     reportParseError(".cpload is not supported in Mips16 mode");
7725     return false;
7726   }
7727 
7728   SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
7729   ParseStatus Res = parseAnyRegister(Reg);
7730   if (Res.isNoMatch() || Res.isFailure()) {
7731     reportParseError("expected register containing function address");
7732     return false;
7733   }
7734 
7735   MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
7736   if (!RegOpnd.isGPRAsmReg()) {
7737     reportParseError(RegOpnd.getStartLoc(), "invalid register");
7738     return false;
7739   }
7740 
7741   // If this is not the end of the statement, report an error.
7742   if (getLexer().isNot(AsmToken::EndOfStatement)) {
7743     reportParseError("unexpected token, expected end of statement");
7744     return false;
7745   }
7746 
7747   getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
7748   return false;
7749 }
7750 
parseDirectiveCpLocal(SMLoc Loc)7751 bool MipsAsmParser::parseDirectiveCpLocal(SMLoc Loc) {
7752   if (!isABI_N32() && !isABI_N64()) {
7753     reportParseError(".cplocal is allowed only in N32 or N64 mode");
7754     return false;
7755   }
7756 
7757   SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
7758   ParseStatus Res = parseAnyRegister(Reg);
7759   if (Res.isNoMatch() || Res.isFailure()) {
7760     reportParseError("expected register containing global pointer");
7761     return false;
7762   }
7763 
7764   MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
7765   if (!RegOpnd.isGPRAsmReg()) {
7766     reportParseError(RegOpnd.getStartLoc(), "invalid register");
7767     return false;
7768   }
7769 
7770   // If this is not the end of the statement, report an error.
7771   if (getLexer().isNot(AsmToken::EndOfStatement)) {
7772     reportParseError("unexpected token, expected end of statement");
7773     return false;
7774   }
7775   getParser().Lex(); // Consume the EndOfStatement.
7776 
7777   unsigned NewReg = RegOpnd.getGPR32Reg();
7778   if (IsPicEnabled)
7779     GPReg = NewReg;
7780 
7781   getTargetStreamer().emitDirectiveCpLocal(NewReg);
7782   return false;
7783 }
7784 
parseDirectiveCpRestore(SMLoc Loc)7785 bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
7786   MCAsmParser &Parser = getParser();
7787 
7788   // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
7789   // is used in non-PIC mode.
7790 
7791   if (inMips16Mode()) {
7792     reportParseError(".cprestore is not supported in Mips16 mode");
7793     return false;
7794   }
7795 
7796   // Get the stack offset value.
7797   const MCExpr *StackOffset;
7798   int64_t StackOffsetVal;
7799   if (Parser.parseExpression(StackOffset)) {
7800     reportParseError("expected stack offset value");
7801     return false;
7802   }
7803 
7804   if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
7805     reportParseError("stack offset is not an absolute expression");
7806     return false;
7807   }
7808 
7809   if (StackOffsetVal < 0) {
7810     Warning(Loc, ".cprestore with negative stack offset has no effect");
7811     IsCpRestoreSet = false;
7812   } else {
7813     IsCpRestoreSet = true;
7814     CpRestoreOffset = StackOffsetVal;
7815   }
7816 
7817   // If this is not the end of the statement, report an error.
7818   if (getLexer().isNot(AsmToken::EndOfStatement)) {
7819     reportParseError("unexpected token, expected end of statement");
7820     return false;
7821   }
7822 
7823   if (!getTargetStreamer().emitDirectiveCpRestore(
7824           CpRestoreOffset, [&]() { return getATReg(Loc); }, Loc, STI))
7825     return true;
7826   Parser.Lex(); // Consume the EndOfStatement.
7827   return false;
7828 }
7829 
parseDirectiveCPSetup()7830 bool MipsAsmParser::parseDirectiveCPSetup() {
7831   MCAsmParser &Parser = getParser();
7832   unsigned FuncReg;
7833   unsigned Save;
7834   bool SaveIsReg = true;
7835 
7836   SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
7837   ParseStatus Res = parseAnyRegister(TmpReg);
7838   if (Res.isNoMatch()) {
7839     reportParseError("expected register containing function address");
7840     return false;
7841   }
7842 
7843   MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
7844   if (!FuncRegOpnd.isGPRAsmReg()) {
7845     reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
7846     return false;
7847   }
7848 
7849   FuncReg = FuncRegOpnd.getGPR32Reg();
7850   TmpReg.clear();
7851 
7852   if (!eatComma("unexpected token, expected comma"))
7853     return true;
7854 
7855   Res = parseAnyRegister(TmpReg);
7856   if (Res.isNoMatch()) {
7857     const MCExpr *OffsetExpr;
7858     int64_t OffsetVal;
7859     SMLoc ExprLoc = getLexer().getLoc();
7860 
7861     if (Parser.parseExpression(OffsetExpr) ||
7862         !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
7863       reportParseError(ExprLoc, "expected save register or stack offset");
7864       return false;
7865     }
7866 
7867     Save = OffsetVal;
7868     SaveIsReg = false;
7869   } else {
7870     MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
7871     if (!SaveOpnd.isGPRAsmReg()) {
7872       reportParseError(SaveOpnd.getStartLoc(), "invalid register");
7873       return false;
7874     }
7875     Save = SaveOpnd.getGPR32Reg();
7876   }
7877 
7878   if (!eatComma("unexpected token, expected comma"))
7879     return true;
7880 
7881   const MCExpr *Expr;
7882   if (Parser.parseExpression(Expr)) {
7883     reportParseError("expected expression");
7884     return false;
7885   }
7886 
7887   if (Expr->getKind() != MCExpr::SymbolRef) {
7888     reportParseError("expected symbol");
7889     return false;
7890   }
7891   const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
7892 
7893   CpSaveLocation = Save;
7894   CpSaveLocationIsRegister = SaveIsReg;
7895 
7896   getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
7897                                            SaveIsReg);
7898   return false;
7899 }
7900 
parseDirectiveCPReturn()7901 bool MipsAsmParser::parseDirectiveCPReturn() {
7902   getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
7903                                             CpSaveLocationIsRegister);
7904   return false;
7905 }
7906 
parseDirectiveNaN()7907 bool MipsAsmParser::parseDirectiveNaN() {
7908   MCAsmParser &Parser = getParser();
7909   if (getLexer().isNot(AsmToken::EndOfStatement)) {
7910     const AsmToken &Tok = Parser.getTok();
7911 
7912     if (Tok.getString() == "2008") {
7913       Parser.Lex();
7914       getTargetStreamer().emitDirectiveNaN2008();
7915       return false;
7916     } else if (Tok.getString() == "legacy") {
7917       Parser.Lex();
7918       getTargetStreamer().emitDirectiveNaNLegacy();
7919       return false;
7920     }
7921   }
7922   // If we don't recognize the option passed to the .nan
7923   // directive (e.g. no option or unknown option), emit an error.
7924   reportParseError("invalid option in .nan directive");
7925   return false;
7926 }
7927 
parseDirectiveSet()7928 bool MipsAsmParser::parseDirectiveSet() {
7929   const AsmToken &Tok = getParser().getTok();
7930   StringRef IdVal = Tok.getString();
7931   SMLoc Loc = Tok.getLoc();
7932 
7933   if (IdVal == "noat")
7934     return parseSetNoAtDirective();
7935   if (IdVal == "at")
7936     return parseSetAtDirective();
7937   if (IdVal == "arch")
7938     return parseSetArchDirective();
7939   if (IdVal == "bopt") {
7940     Warning(Loc, "'bopt' feature is unsupported");
7941     getParser().Lex();
7942     return false;
7943   }
7944   if (IdVal == "nobopt") {
7945     // We're already running in nobopt mode, so nothing to do.
7946     getParser().Lex();
7947     return false;
7948   }
7949   if (IdVal == "fp")
7950     return parseSetFpDirective();
7951   if (IdVal == "oddspreg")
7952     return parseSetOddSPRegDirective();
7953   if (IdVal == "nooddspreg")
7954     return parseSetNoOddSPRegDirective();
7955   if (IdVal == "pop")
7956     return parseSetPopDirective();
7957   if (IdVal == "push")
7958     return parseSetPushDirective();
7959   if (IdVal == "reorder")
7960     return parseSetReorderDirective();
7961   if (IdVal == "noreorder")
7962     return parseSetNoReorderDirective();
7963   if (IdVal == "macro")
7964     return parseSetMacroDirective();
7965   if (IdVal == "nomacro")
7966     return parseSetNoMacroDirective();
7967   if (IdVal == "mips16")
7968     return parseSetMips16Directive();
7969   if (IdVal == "nomips16")
7970     return parseSetNoMips16Directive();
7971   if (IdVal == "nomicromips") {
7972     clearFeatureBits(Mips::FeatureMicroMips, "micromips");
7973     getTargetStreamer().emitDirectiveSetNoMicroMips();
7974     getParser().eatToEndOfStatement();
7975     return false;
7976   }
7977   if (IdVal == "micromips") {
7978     if (hasMips64r6()) {
7979       Error(Loc, ".set micromips directive is not supported with MIPS64R6");
7980       return false;
7981     }
7982     return parseSetFeature(Mips::FeatureMicroMips);
7983   }
7984   if (IdVal == "mips0")
7985     return parseSetMips0Directive();
7986   if (IdVal == "mips1")
7987     return parseSetFeature(Mips::FeatureMips1);
7988   if (IdVal == "mips2")
7989     return parseSetFeature(Mips::FeatureMips2);
7990   if (IdVal == "mips3")
7991     return parseSetFeature(Mips::FeatureMips3);
7992   if (IdVal == "mips4")
7993     return parseSetFeature(Mips::FeatureMips4);
7994   if (IdVal == "mips5")
7995     return parseSetFeature(Mips::FeatureMips5);
7996   if (IdVal == "mips32")
7997     return parseSetFeature(Mips::FeatureMips32);
7998   if (IdVal == "mips32r2")
7999     return parseSetFeature(Mips::FeatureMips32r2);
8000   if (IdVal == "mips32r3")
8001     return parseSetFeature(Mips::FeatureMips32r3);
8002   if (IdVal == "mips32r5")
8003     return parseSetFeature(Mips::FeatureMips32r5);
8004   if (IdVal == "mips32r6")
8005     return parseSetFeature(Mips::FeatureMips32r6);
8006   if (IdVal == "mips64")
8007     return parseSetFeature(Mips::FeatureMips64);
8008   if (IdVal == "mips64r2")
8009     return parseSetFeature(Mips::FeatureMips64r2);
8010   if (IdVal == "mips64r3")
8011     return parseSetFeature(Mips::FeatureMips64r3);
8012   if (IdVal == "mips64r5")
8013     return parseSetFeature(Mips::FeatureMips64r5);
8014   if (IdVal == "mips64r6") {
8015     if (inMicroMipsMode()) {
8016       Error(Loc, "MIPS64R6 is not supported with microMIPS");
8017       return false;
8018     }
8019     return parseSetFeature(Mips::FeatureMips64r6);
8020   }
8021   if (IdVal == "dsp")
8022     return parseSetFeature(Mips::FeatureDSP);
8023   if (IdVal == "dspr2")
8024     return parseSetFeature(Mips::FeatureDSPR2);
8025   if (IdVal == "nodsp")
8026     return parseSetNoDspDirective();
8027   if (IdVal == "mips3d")
8028     return parseSetFeature(Mips::FeatureMips3D);
8029   if (IdVal == "nomips3d")
8030     return parseSetNoMips3DDirective();
8031   if (IdVal == "msa")
8032     return parseSetMsaDirective();
8033   if (IdVal == "nomsa")
8034     return parseSetNoMsaDirective();
8035   if (IdVal == "mt")
8036     return parseSetMtDirective();
8037   if (IdVal == "nomt")
8038     return parseSetNoMtDirective();
8039   if (IdVal == "softfloat")
8040     return parseSetSoftFloatDirective();
8041   if (IdVal == "hardfloat")
8042     return parseSetHardFloatDirective();
8043   if (IdVal == "crc")
8044     return parseSetFeature(Mips::FeatureCRC);
8045   if (IdVal == "nocrc")
8046     return parseSetNoCRCDirective();
8047   if (IdVal == "virt")
8048     return parseSetFeature(Mips::FeatureVirt);
8049   if (IdVal == "novirt")
8050     return parseSetNoVirtDirective();
8051   if (IdVal == "ginv")
8052     return parseSetFeature(Mips::FeatureGINV);
8053   if (IdVal == "noginv")
8054     return parseSetNoGINVDirective();
8055 
8056   // It is just an identifier, look for an assignment.
8057   return parseSetAssignment();
8058 }
8059 
8060 /// parseDirectiveGpWord
8061 ///  ::= .gpword local_sym
parseDirectiveGpWord()8062 bool MipsAsmParser::parseDirectiveGpWord() {
8063   const MCExpr *Value;
8064   if (getParser().parseExpression(Value))
8065     return true;
8066   getTargetStreamer().emitGPRel32Value(Value);
8067   return parseEOL();
8068 }
8069 
8070 /// parseDirectiveGpDWord
8071 ///  ::= .gpdword local_sym
parseDirectiveGpDWord()8072 bool MipsAsmParser::parseDirectiveGpDWord() {
8073   const MCExpr *Value;
8074   if (getParser().parseExpression(Value))
8075     return true;
8076   getTargetStreamer().emitGPRel64Value(Value);
8077   return parseEOL();
8078 }
8079 
8080 /// parseDirectiveDtpRelWord
8081 ///  ::= .dtprelword tls_sym
parseDirectiveDtpRelWord()8082 bool MipsAsmParser::parseDirectiveDtpRelWord() {
8083   const MCExpr *Value;
8084   if (getParser().parseExpression(Value))
8085     return true;
8086   getTargetStreamer().emitDTPRel32Value(Value);
8087   return parseEOL();
8088 }
8089 
8090 /// parseDirectiveDtpRelDWord
8091 ///  ::= .dtpreldword tls_sym
parseDirectiveDtpRelDWord()8092 bool MipsAsmParser::parseDirectiveDtpRelDWord() {
8093   const MCExpr *Value;
8094   if (getParser().parseExpression(Value))
8095     return true;
8096   getTargetStreamer().emitDTPRel64Value(Value);
8097   return parseEOL();
8098 }
8099 
8100 /// parseDirectiveTpRelWord
8101 ///  ::= .tprelword tls_sym
parseDirectiveTpRelWord()8102 bool MipsAsmParser::parseDirectiveTpRelWord() {
8103   const MCExpr *Value;
8104   if (getParser().parseExpression(Value))
8105     return true;
8106   getTargetStreamer().emitTPRel32Value(Value);
8107   return parseEOL();
8108 }
8109 
8110 /// parseDirectiveTpRelDWord
8111 ///  ::= .tpreldword tls_sym
parseDirectiveTpRelDWord()8112 bool MipsAsmParser::parseDirectiveTpRelDWord() {
8113   const MCExpr *Value;
8114   if (getParser().parseExpression(Value))
8115     return true;
8116   getTargetStreamer().emitTPRel64Value(Value);
8117   return parseEOL();
8118 }
8119 
parseDirectiveOption()8120 bool MipsAsmParser::parseDirectiveOption() {
8121   MCAsmParser &Parser = getParser();
8122   // Get the option token.
8123   AsmToken Tok = Parser.getTok();
8124   // At the moment only identifiers are supported.
8125   if (Tok.isNot(AsmToken::Identifier)) {
8126     return Error(Parser.getTok().getLoc(),
8127                  "unexpected token, expected identifier");
8128   }
8129 
8130   StringRef Option = Tok.getIdentifier();
8131 
8132   if (Option == "pic0") {
8133     // MipsAsmParser needs to know if the current PIC mode changes.
8134     IsPicEnabled = false;
8135 
8136     getTargetStreamer().emitDirectiveOptionPic0();
8137     Parser.Lex();
8138     if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
8139       return Error(Parser.getTok().getLoc(),
8140                    "unexpected token, expected end of statement");
8141     }
8142     return false;
8143   }
8144 
8145   if (Option == "pic2") {
8146     // MipsAsmParser needs to know if the current PIC mode changes.
8147     IsPicEnabled = true;
8148 
8149     getTargetStreamer().emitDirectiveOptionPic2();
8150     Parser.Lex();
8151     if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
8152       return Error(Parser.getTok().getLoc(),
8153                    "unexpected token, expected end of statement");
8154     }
8155     return false;
8156   }
8157 
8158   // Unknown option.
8159   Warning(Parser.getTok().getLoc(),
8160           "unknown option, expected 'pic0' or 'pic2'");
8161   Parser.eatToEndOfStatement();
8162   return false;
8163 }
8164 
8165 /// parseInsnDirective
8166 ///  ::= .insn
parseInsnDirective()8167 bool MipsAsmParser::parseInsnDirective() {
8168   // If this is not the end of the statement, report an error.
8169   if (getLexer().isNot(AsmToken::EndOfStatement)) {
8170     reportParseError("unexpected token, expected end of statement");
8171     return false;
8172   }
8173 
8174   // The actual label marking happens in
8175   // MipsELFStreamer::createPendingLabelRelocs().
8176   getTargetStreamer().emitDirectiveInsn();
8177 
8178   getParser().Lex(); // Eat EndOfStatement token.
8179   return false;
8180 }
8181 
8182 /// parseRSectionDirective
8183 ///  ::= .rdata
parseRSectionDirective(StringRef Section)8184 bool MipsAsmParser::parseRSectionDirective(StringRef Section) {
8185   // If this is not the end of the statement, report an error.
8186   if (getLexer().isNot(AsmToken::EndOfStatement)) {
8187     reportParseError("unexpected token, expected end of statement");
8188     return false;
8189   }
8190 
8191   MCSection *ELFSection = getContext().getELFSection(
8192       Section, ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
8193   getParser().getStreamer().switchSection(ELFSection);
8194 
8195   getParser().Lex(); // Eat EndOfStatement token.
8196   return false;
8197 }
8198 
8199 /// parseSSectionDirective
8200 ///  ::= .sbss
8201 ///  ::= .sdata
parseSSectionDirective(StringRef Section,unsigned Type)8202 bool MipsAsmParser::parseSSectionDirective(StringRef Section, unsigned Type) {
8203   // If this is not the end of the statement, report an error.
8204   if (getLexer().isNot(AsmToken::EndOfStatement)) {
8205     reportParseError("unexpected token, expected end of statement");
8206     return false;
8207   }
8208 
8209   MCSection *ELFSection = getContext().getELFSection(
8210       Section, Type, ELF::SHF_WRITE | ELF::SHF_ALLOC | ELF::SHF_MIPS_GPREL);
8211   getParser().getStreamer().switchSection(ELFSection);
8212 
8213   getParser().Lex(); // Eat EndOfStatement token.
8214   return false;
8215 }
8216 
8217 /// parseDirectiveModule
8218 ///  ::= .module oddspreg
8219 ///  ::= .module nooddspreg
8220 ///  ::= .module fp=value
8221 ///  ::= .module softfloat
8222 ///  ::= .module hardfloat
8223 ///  ::= .module mt
8224 ///  ::= .module crc
8225 ///  ::= .module nocrc
8226 ///  ::= .module virt
8227 ///  ::= .module novirt
8228 ///  ::= .module ginv
8229 ///  ::= .module noginv
parseDirectiveModule()8230 bool MipsAsmParser::parseDirectiveModule() {
8231   MCAsmParser &Parser = getParser();
8232   AsmLexer &Lexer = getLexer();
8233   SMLoc L = Lexer.getLoc();
8234 
8235   if (!getTargetStreamer().isModuleDirectiveAllowed()) {
8236     // TODO : get a better message.
8237     reportParseError(".module directive must appear before any code");
8238     return false;
8239   }
8240 
8241   StringRef Option;
8242   if (Parser.parseIdentifier(Option)) {
8243     reportParseError("expected .module option identifier");
8244     return false;
8245   }
8246 
8247   if (Option == "oddspreg") {
8248     clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
8249 
8250     // Synchronize the abiflags information with the FeatureBits information we
8251     // changed above.
8252     getTargetStreamer().updateABIInfo(*this);
8253 
8254     // If printing assembly, use the recently updated abiflags information.
8255     // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8256     // emitted at the end).
8257     getTargetStreamer().emitDirectiveModuleOddSPReg();
8258 
8259     // If this is not the end of the statement, report an error.
8260     if (getLexer().isNot(AsmToken::EndOfStatement)) {
8261       reportParseError("unexpected token, expected end of statement");
8262       return false;
8263     }
8264 
8265     return false; // parseDirectiveModule has finished successfully.
8266   } else if (Option == "nooddspreg") {
8267     if (!isABI_O32()) {
8268       return Error(L, "'.module nooddspreg' requires the O32 ABI");
8269     }
8270 
8271     setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
8272 
8273     // Synchronize the abiflags information with the FeatureBits information we
8274     // changed above.
8275     getTargetStreamer().updateABIInfo(*this);
8276 
8277     // If printing assembly, use the recently updated abiflags information.
8278     // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8279     // emitted at the end).
8280     getTargetStreamer().emitDirectiveModuleOddSPReg();
8281 
8282     // If this is not the end of the statement, report an error.
8283     if (getLexer().isNot(AsmToken::EndOfStatement)) {
8284       reportParseError("unexpected token, expected end of statement");
8285       return false;
8286     }
8287 
8288     return false; // parseDirectiveModule has finished successfully.
8289   } else if (Option == "fp") {
8290     return parseDirectiveModuleFP();
8291   } else if (Option == "softfloat") {
8292     setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
8293 
8294     // Synchronize the ABI Flags information with the FeatureBits information we
8295     // updated above.
8296     getTargetStreamer().updateABIInfo(*this);
8297 
8298     // If printing assembly, use the recently updated ABI Flags information.
8299     // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8300     // emitted later).
8301     getTargetStreamer().emitDirectiveModuleSoftFloat();
8302 
8303     // If this is not the end of the statement, report an error.
8304     if (getLexer().isNot(AsmToken::EndOfStatement)) {
8305       reportParseError("unexpected token, expected end of statement");
8306       return false;
8307     }
8308 
8309     return false; // parseDirectiveModule has finished successfully.
8310   } else if (Option == "hardfloat") {
8311     clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
8312 
8313     // Synchronize the ABI Flags information with the FeatureBits information we
8314     // updated above.
8315     getTargetStreamer().updateABIInfo(*this);
8316 
8317     // If printing assembly, use the recently updated ABI Flags information.
8318     // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8319     // emitted later).
8320     getTargetStreamer().emitDirectiveModuleHardFloat();
8321 
8322     // If this is not the end of the statement, report an error.
8323     if (getLexer().isNot(AsmToken::EndOfStatement)) {
8324       reportParseError("unexpected token, expected end of statement");
8325       return false;
8326     }
8327 
8328     return false; // parseDirectiveModule has finished successfully.
8329   } else if (Option == "mt") {
8330     setModuleFeatureBits(Mips::FeatureMT, "mt");
8331 
8332     // Synchronize the ABI Flags information with the FeatureBits information we
8333     // updated above.
8334     getTargetStreamer().updateABIInfo(*this);
8335 
8336     // If printing assembly, use the recently updated ABI Flags information.
8337     // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8338     // emitted later).
8339     getTargetStreamer().emitDirectiveModuleMT();
8340 
8341     // If this is not the end of the statement, report an error.
8342     if (getLexer().isNot(AsmToken::EndOfStatement)) {
8343       reportParseError("unexpected token, expected end of statement");
8344       return false;
8345     }
8346 
8347     return false; // parseDirectiveModule has finished successfully.
8348   } else if (Option == "crc") {
8349     setModuleFeatureBits(Mips::FeatureCRC, "crc");
8350 
8351     // Synchronize the ABI Flags information with the FeatureBits information we
8352     // updated above.
8353     getTargetStreamer().updateABIInfo(*this);
8354 
8355     // If printing assembly, use the recently updated ABI Flags information.
8356     // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8357     // emitted later).
8358     getTargetStreamer().emitDirectiveModuleCRC();
8359 
8360     // If this is not the end of the statement, report an error.
8361     if (getLexer().isNot(AsmToken::EndOfStatement)) {
8362       reportParseError("unexpected token, expected end of statement");
8363       return false;
8364     }
8365 
8366     return false; // parseDirectiveModule has finished successfully.
8367   } else if (Option == "nocrc") {
8368     clearModuleFeatureBits(Mips::FeatureCRC, "crc");
8369 
8370     // Synchronize the ABI Flags information with the FeatureBits information we
8371     // updated above.
8372     getTargetStreamer().updateABIInfo(*this);
8373 
8374     // If printing assembly, use the recently updated ABI Flags information.
8375     // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8376     // emitted later).
8377     getTargetStreamer().emitDirectiveModuleNoCRC();
8378 
8379     // If this is not the end of the statement, report an error.
8380     if (getLexer().isNot(AsmToken::EndOfStatement)) {
8381       reportParseError("unexpected token, expected end of statement");
8382       return false;
8383     }
8384 
8385     return false; // parseDirectiveModule has finished successfully.
8386   } else if (Option == "virt") {
8387     setModuleFeatureBits(Mips::FeatureVirt, "virt");
8388 
8389     // Synchronize the ABI Flags information with the FeatureBits information we
8390     // updated above.
8391     getTargetStreamer().updateABIInfo(*this);
8392 
8393     // If printing assembly, use the recently updated ABI Flags information.
8394     // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8395     // emitted later).
8396     getTargetStreamer().emitDirectiveModuleVirt();
8397 
8398     // If this is not the end of the statement, report an error.
8399     if (getLexer().isNot(AsmToken::EndOfStatement)) {
8400       reportParseError("unexpected token, expected end of statement");
8401       return false;
8402     }
8403 
8404     return false; // parseDirectiveModule has finished successfully.
8405   } else if (Option == "novirt") {
8406     clearModuleFeatureBits(Mips::FeatureVirt, "virt");
8407 
8408     // Synchronize the ABI Flags information with the FeatureBits information we
8409     // updated above.
8410     getTargetStreamer().updateABIInfo(*this);
8411 
8412     // If printing assembly, use the recently updated ABI Flags information.
8413     // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8414     // emitted later).
8415     getTargetStreamer().emitDirectiveModuleNoVirt();
8416 
8417     // If this is not the end of the statement, report an error.
8418     if (getLexer().isNot(AsmToken::EndOfStatement)) {
8419       reportParseError("unexpected token, expected end of statement");
8420       return false;
8421     }
8422 
8423     return false; // parseDirectiveModule has finished successfully.
8424   } else if (Option == "ginv") {
8425     setModuleFeatureBits(Mips::FeatureGINV, "ginv");
8426 
8427     // Synchronize the ABI Flags information with the FeatureBits information we
8428     // updated above.
8429     getTargetStreamer().updateABIInfo(*this);
8430 
8431     // If printing assembly, use the recently updated ABI Flags information.
8432     // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8433     // emitted later).
8434     getTargetStreamer().emitDirectiveModuleGINV();
8435 
8436     // If this is not the end of the statement, report an error.
8437     if (getLexer().isNot(AsmToken::EndOfStatement)) {
8438       reportParseError("unexpected token, expected end of statement");
8439       return false;
8440     }
8441 
8442     return false; // parseDirectiveModule has finished successfully.
8443   } else if (Option == "noginv") {
8444     clearModuleFeatureBits(Mips::FeatureGINV, "ginv");
8445 
8446     // Synchronize the ABI Flags information with the FeatureBits information we
8447     // updated above.
8448     getTargetStreamer().updateABIInfo(*this);
8449 
8450     // If printing assembly, use the recently updated ABI Flags information.
8451     // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8452     // emitted later).
8453     getTargetStreamer().emitDirectiveModuleNoGINV();
8454 
8455     // If this is not the end of the statement, report an error.
8456     if (getLexer().isNot(AsmToken::EndOfStatement)) {
8457       reportParseError("unexpected token, expected end of statement");
8458       return false;
8459     }
8460 
8461     return false; // parseDirectiveModule has finished successfully.
8462   } else {
8463     return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
8464   }
8465 }
8466 
8467 /// parseDirectiveModuleFP
8468 ///  ::= =32
8469 ///  ::= =xx
8470 ///  ::= =64
parseDirectiveModuleFP()8471 bool MipsAsmParser::parseDirectiveModuleFP() {
8472   MCAsmParser &Parser = getParser();
8473   AsmLexer &Lexer = getLexer();
8474 
8475   if (Lexer.isNot(AsmToken::Equal)) {
8476     reportParseError("unexpected token, expected equals sign '='");
8477     return false;
8478   }
8479   Parser.Lex(); // Eat '=' token.
8480 
8481   MipsABIFlagsSection::FpABIKind FpABI;
8482   if (!parseFpABIValue(FpABI, ".module"))
8483     return false;
8484 
8485   if (getLexer().isNot(AsmToken::EndOfStatement)) {
8486     reportParseError("unexpected token, expected end of statement");
8487     return false;
8488   }
8489 
8490   // Synchronize the abiflags information with the FeatureBits information we
8491   // changed above.
8492   getTargetStreamer().updateABIInfo(*this);
8493 
8494   // If printing assembly, use the recently updated abiflags information.
8495   // If generating ELF, don't do anything (the .MIPS.abiflags section gets
8496   // emitted at the end).
8497   getTargetStreamer().emitDirectiveModuleFP();
8498 
8499   Parser.Lex(); // Consume the EndOfStatement.
8500   return false;
8501 }
8502 
parseFpABIValue(MipsABIFlagsSection::FpABIKind & FpABI,StringRef Directive)8503 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
8504                                     StringRef Directive) {
8505   MCAsmParser &Parser = getParser();
8506   AsmLexer &Lexer = getLexer();
8507   bool ModuleLevelOptions = Directive == ".module";
8508 
8509   if (Lexer.is(AsmToken::Identifier)) {
8510     StringRef Value = Parser.getTok().getString();
8511     Parser.Lex();
8512 
8513     if (Value != "xx") {
8514       reportParseError("unsupported value, expected 'xx', '32' or '64'");
8515       return false;
8516     }
8517 
8518     if (!isABI_O32()) {
8519       reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
8520       return false;
8521     }
8522 
8523     FpABI = MipsABIFlagsSection::FpABIKind::XX;
8524     if (ModuleLevelOptions) {
8525       setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
8526       clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
8527     } else {
8528       setFeatureBits(Mips::FeatureFPXX, "fpxx");
8529       clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
8530     }
8531     return true;
8532   }
8533 
8534   if (Lexer.is(AsmToken::Integer)) {
8535     unsigned Value = Parser.getTok().getIntVal();
8536     Parser.Lex();
8537 
8538     if (Value != 32 && Value != 64) {
8539       reportParseError("unsupported value, expected 'xx', '32' or '64'");
8540       return false;
8541     }
8542 
8543     if (Value == 32) {
8544       if (!isABI_O32()) {
8545         reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
8546         return false;
8547       }
8548 
8549       FpABI = MipsABIFlagsSection::FpABIKind::S32;
8550       if (ModuleLevelOptions) {
8551         clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
8552         clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
8553       } else {
8554         clearFeatureBits(Mips::FeatureFPXX, "fpxx");
8555         clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
8556       }
8557     } else {
8558       FpABI = MipsABIFlagsSection::FpABIKind::S64;
8559       if (ModuleLevelOptions) {
8560         clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
8561         setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
8562       } else {
8563         clearFeatureBits(Mips::FeatureFPXX, "fpxx");
8564         setFeatureBits(Mips::FeatureFP64Bit, "fp64");
8565       }
8566     }
8567 
8568     return true;
8569   }
8570 
8571   return false;
8572 }
8573 
ParseDirective(AsmToken DirectiveID)8574 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
8575   // This returns false if this function recognizes the directive
8576   // regardless of whether it is successfully handles or reports an
8577   // error. Otherwise it returns true to give the generic parser a
8578   // chance at recognizing it.
8579 
8580   MCAsmParser &Parser = getParser();
8581   StringRef IDVal = DirectiveID.getString();
8582 
8583   if (IDVal == ".cpadd") {
8584     parseDirectiveCpAdd(DirectiveID.getLoc());
8585     return false;
8586   }
8587   if (IDVal == ".cpload") {
8588     parseDirectiveCpLoad(DirectiveID.getLoc());
8589     return false;
8590   }
8591   if (IDVal == ".cprestore") {
8592     parseDirectiveCpRestore(DirectiveID.getLoc());
8593     return false;
8594   }
8595   if (IDVal == ".cplocal") {
8596     parseDirectiveCpLocal(DirectiveID.getLoc());
8597     return false;
8598   }
8599   if (IDVal == ".ent") {
8600     StringRef SymbolName;
8601 
8602     if (Parser.parseIdentifier(SymbolName)) {
8603       reportParseError("expected identifier after .ent");
8604       return false;
8605     }
8606 
8607     // There's an undocumented extension that allows an integer to
8608     // follow the name of the procedure which AFAICS is ignored by GAS.
8609     // Example: .ent foo,2
8610     if (getLexer().isNot(AsmToken::EndOfStatement)) {
8611       if (getLexer().isNot(AsmToken::Comma)) {
8612         // Even though we accept this undocumented extension for compatibility
8613         // reasons, the additional integer argument does not actually change
8614         // the behaviour of the '.ent' directive, so we would like to discourage
8615         // its use. We do this by not referring to the extended version in
8616         // error messages which are not directly related to its use.
8617         reportParseError("unexpected token, expected end of statement");
8618         return false;
8619       }
8620       Parser.Lex(); // Eat the comma.
8621       const MCExpr *DummyNumber;
8622       int64_t DummyNumberVal;
8623       // If the user was explicitly trying to use the extended version,
8624       // we still give helpful extension-related error messages.
8625       if (Parser.parseExpression(DummyNumber)) {
8626         reportParseError("expected number after comma");
8627         return false;
8628       }
8629       if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
8630         reportParseError("expected an absolute expression after comma");
8631         return false;
8632       }
8633     }
8634 
8635     // If this is not the end of the statement, report an error.
8636     if (getLexer().isNot(AsmToken::EndOfStatement)) {
8637       reportParseError("unexpected token, expected end of statement");
8638       return false;
8639     }
8640 
8641     MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
8642 
8643     getTargetStreamer().emitDirectiveEnt(*Sym);
8644     CurrentFn = Sym;
8645     IsCpRestoreSet = false;
8646     return false;
8647   }
8648 
8649   if (IDVal == ".end") {
8650     StringRef SymbolName;
8651 
8652     if (Parser.parseIdentifier(SymbolName)) {
8653       reportParseError("expected identifier after .end");
8654       return false;
8655     }
8656 
8657     if (getLexer().isNot(AsmToken::EndOfStatement)) {
8658       reportParseError("unexpected token, expected end of statement");
8659       return false;
8660     }
8661 
8662     if (CurrentFn == nullptr) {
8663       reportParseError(".end used without .ent");
8664       return false;
8665     }
8666 
8667     if ((SymbolName != CurrentFn->getName())) {
8668       reportParseError(".end symbol does not match .ent symbol");
8669       return false;
8670     }
8671 
8672     getTargetStreamer().emitDirectiveEnd(SymbolName);
8673     CurrentFn = nullptr;
8674     IsCpRestoreSet = false;
8675     return false;
8676   }
8677 
8678   if (IDVal == ".frame") {
8679     // .frame $stack_reg, frame_size_in_bytes, $return_reg
8680     SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
8681     ParseStatus Res = parseAnyRegister(TmpReg);
8682     if (Res.isNoMatch() || Res.isFailure()) {
8683       reportParseError("expected stack register");
8684       return false;
8685     }
8686 
8687     MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
8688     if (!StackRegOpnd.isGPRAsmReg()) {
8689       reportParseError(StackRegOpnd.getStartLoc(),
8690                        "expected general purpose register");
8691       return false;
8692     }
8693     unsigned StackReg = StackRegOpnd.getGPR32Reg();
8694 
8695     if (Parser.getTok().is(AsmToken::Comma))
8696       Parser.Lex();
8697     else {
8698       reportParseError("unexpected token, expected comma");
8699       return false;
8700     }
8701 
8702     // Parse the frame size.
8703     const MCExpr *FrameSize;
8704     int64_t FrameSizeVal;
8705 
8706     if (Parser.parseExpression(FrameSize)) {
8707       reportParseError("expected frame size value");
8708       return false;
8709     }
8710 
8711     if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
8712       reportParseError("frame size not an absolute expression");
8713       return false;
8714     }
8715 
8716     if (Parser.getTok().is(AsmToken::Comma))
8717       Parser.Lex();
8718     else {
8719       reportParseError("unexpected token, expected comma");
8720       return false;
8721     }
8722 
8723     // Parse the return register.
8724     TmpReg.clear();
8725     Res = parseAnyRegister(TmpReg);
8726     if (Res.isNoMatch() || Res.isFailure()) {
8727       reportParseError("expected return register");
8728       return false;
8729     }
8730 
8731     MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
8732     if (!ReturnRegOpnd.isGPRAsmReg()) {
8733       reportParseError(ReturnRegOpnd.getStartLoc(),
8734                        "expected general purpose register");
8735       return false;
8736     }
8737 
8738     // If this is not the end of the statement, report an error.
8739     if (getLexer().isNot(AsmToken::EndOfStatement)) {
8740       reportParseError("unexpected token, expected end of statement");
8741       return false;
8742     }
8743 
8744     getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
8745                                   ReturnRegOpnd.getGPR32Reg());
8746     IsCpRestoreSet = false;
8747     return false;
8748   }
8749 
8750   if (IDVal == ".set") {
8751     parseDirectiveSet();
8752     return false;
8753   }
8754 
8755   if (IDVal == ".mask" || IDVal == ".fmask") {
8756     // .mask bitmask, frame_offset
8757     // bitmask: One bit for each register used.
8758     // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
8759     //               first register is expected to be saved.
8760     // Examples:
8761     //   .mask 0x80000000, -4
8762     //   .fmask 0x80000000, -4
8763     //
8764 
8765     // Parse the bitmask
8766     const MCExpr *BitMask;
8767     int64_t BitMaskVal;
8768 
8769     if (Parser.parseExpression(BitMask)) {
8770       reportParseError("expected bitmask value");
8771       return false;
8772     }
8773 
8774     if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
8775       reportParseError("bitmask not an absolute expression");
8776       return false;
8777     }
8778 
8779     if (Parser.getTok().is(AsmToken::Comma))
8780       Parser.Lex();
8781     else {
8782       reportParseError("unexpected token, expected comma");
8783       return false;
8784     }
8785 
8786     // Parse the frame_offset
8787     const MCExpr *FrameOffset;
8788     int64_t FrameOffsetVal;
8789 
8790     if (Parser.parseExpression(FrameOffset)) {
8791       reportParseError("expected frame offset value");
8792       return false;
8793     }
8794 
8795     if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
8796       reportParseError("frame offset not an absolute expression");
8797       return false;
8798     }
8799 
8800     // If this is not the end of the statement, report an error.
8801     if (getLexer().isNot(AsmToken::EndOfStatement)) {
8802       reportParseError("unexpected token, expected end of statement");
8803       return false;
8804     }
8805 
8806     if (IDVal == ".mask")
8807       getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
8808     else
8809       getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
8810     return false;
8811   }
8812 
8813   if (IDVal == ".nan")
8814     return parseDirectiveNaN();
8815 
8816   if (IDVal == ".gpword") {
8817     parseDirectiveGpWord();
8818     return false;
8819   }
8820 
8821   if (IDVal == ".gpdword") {
8822     parseDirectiveGpDWord();
8823     return false;
8824   }
8825 
8826   if (IDVal == ".dtprelword") {
8827     parseDirectiveDtpRelWord();
8828     return false;
8829   }
8830 
8831   if (IDVal == ".dtpreldword") {
8832     parseDirectiveDtpRelDWord();
8833     return false;
8834   }
8835 
8836   if (IDVal == ".tprelword") {
8837     parseDirectiveTpRelWord();
8838     return false;
8839   }
8840 
8841   if (IDVal == ".tpreldword") {
8842     parseDirectiveTpRelDWord();
8843     return false;
8844   }
8845 
8846   if (IDVal == ".option") {
8847     parseDirectiveOption();
8848     return false;
8849   }
8850 
8851   if (IDVal == ".abicalls") {
8852     getTargetStreamer().emitDirectiveAbiCalls();
8853     if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
8854       Error(Parser.getTok().getLoc(),
8855             "unexpected token, expected end of statement");
8856     }
8857     return false;
8858   }
8859 
8860   if (IDVal == ".cpsetup") {
8861     parseDirectiveCPSetup();
8862     return false;
8863   }
8864   if (IDVal == ".cpreturn") {
8865     parseDirectiveCPReturn();
8866     return false;
8867   }
8868   if (IDVal == ".module") {
8869     parseDirectiveModule();
8870     return false;
8871   }
8872   if (IDVal == ".llvm_internal_mips_reallow_module_directive") {
8873     parseInternalDirectiveReallowModule();
8874     return false;
8875   }
8876   if (IDVal == ".insn") {
8877     parseInsnDirective();
8878     return false;
8879   }
8880   if (IDVal == ".rdata") {
8881     parseRSectionDirective(".rodata");
8882     return false;
8883   }
8884   if (IDVal == ".sbss") {
8885     parseSSectionDirective(IDVal, ELF::SHT_NOBITS);
8886     return false;
8887   }
8888   if (IDVal == ".sdata") {
8889     parseSSectionDirective(IDVal, ELF::SHT_PROGBITS);
8890     return false;
8891   }
8892 
8893   return true;
8894 }
8895 
parseInternalDirectiveReallowModule()8896 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
8897   // If this is not the end of the statement, report an error.
8898   if (getLexer().isNot(AsmToken::EndOfStatement)) {
8899     reportParseError("unexpected token, expected end of statement");
8900     return false;
8901   }
8902 
8903   getTargetStreamer().reallowModuleDirective();
8904 
8905   getParser().Lex(); // Eat EndOfStatement token.
8906   return false;
8907 }
8908 
8909 extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void
LLVMInitializeMipsAsmParser()8910 LLVMInitializeMipsAsmParser() {
8911   RegisterMCAsmParser<MipsAsmParser> X(getTheMipsTarget());
8912   RegisterMCAsmParser<MipsAsmParser> Y(getTheMipselTarget());
8913   RegisterMCAsmParser<MipsAsmParser> A(getTheMips64Target());
8914   RegisterMCAsmParser<MipsAsmParser> B(getTheMips64elTarget());
8915 }
8916 
8917 #define GET_REGISTER_MATCHER
8918 #define GET_MATCHER_IMPLEMENTATION
8919 #define GET_MNEMONIC_SPELL_CHECKER
8920 #include "MipsGenAsmMatcher.inc"
8921 
mnemonicIsValid(StringRef Mnemonic,unsigned VariantID)8922 bool MipsAsmParser::mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) {
8923   // Find the appropriate table for this asm variant.
8924   const MatchEntry *Start, *End;
8925   switch (VariantID) {
8926   default: llvm_unreachable("invalid variant!");
8927   case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0); break;
8928   }
8929   // Search the table.
8930   auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode());
8931   return MnemonicRange.first != MnemonicRange.second;
8932 }
8933