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