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