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