LLVM  4.0.0
MipsAsmParser.cpp
Go to the documentation of this file.
1 //===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
13 #include "MipsRegisterInfo.h"
14 #include "MipsTargetObjectFile.h"
15 #include "MipsTargetStreamer.h"
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/ADT/StringSwitch.h"
19 #include "llvm/MC/MCContext.h"
20 #include "llvm/MC/MCExpr.h"
21 #include "llvm/MC/MCInst.h"
22 #include "llvm/MC/MCInstBuilder.h"
26 #include "llvm/MC/MCSectionELF.h"
27 #include "llvm/MC/MCStreamer.h"
29 #include "llvm/MC/MCSymbol.h"
30 #include "llvm/Support/Debug.h"
31 #include "llvm/Support/ELF.h"
33 #include "llvm/Support/SourceMgr.h"
36 #include <memory>
37 
38 using namespace llvm;
39 
40 #define DEBUG_TYPE "mips-asm-parser"
41 
42 namespace llvm {
43 class MCInstrInfo;
44 }
45 
46 namespace {
47 class MipsAssemblerOptions {
48 public:
49  MipsAssemblerOptions(const FeatureBitset &Features_) :
50  ATReg(1), Reorder(true), Macro(true), Features(Features_) {}
51 
52  MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
53  ATReg = Opts->getATRegIndex();
54  Reorder = Opts->isReorder();
55  Macro = Opts->isMacro();
56  Features = Opts->getFeatures();
57  }
58 
59  unsigned getATRegIndex() const { return ATReg; }
60  bool setATRegIndex(unsigned Reg) {
61  if (Reg > 31)
62  return false;
63 
64  ATReg = Reg;
65  return true;
66  }
67 
68  bool isReorder() const { return Reorder; }
69  void setReorder() { Reorder = true; }
70  void setNoReorder() { Reorder = false; }
71 
72  bool isMacro() const { return Macro; }
73  void setMacro() { Macro = true; }
74  void setNoMacro() { Macro = false; }
75 
76  const FeatureBitset &getFeatures() const { return Features; }
77  void setFeatures(const FeatureBitset &Features_) { Features = Features_; }
78 
79  // Set of features that are either architecture features or referenced
80  // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
81  // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
82  // The reason we need this mask is explained in the selectArch function.
83  // FIXME: Ideally we would like TableGen to generate this information.
84  static const FeatureBitset AllArchRelatedMask;
85 
86 private:
87  unsigned ATReg;
88  bool Reorder;
89  bool Macro;
91 };
92 }
93 
94 const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
95  Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
96  Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
97  Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
98  Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
99  Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
100  Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
101  Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
102  Mips::FeatureFP64Bit, Mips::FeatureGP64Bit, Mips::FeatureNaN2008
103 };
104 
105 namespace {
106 class MipsAsmParser : public MCTargetAsmParser {
107  MipsTargetStreamer &getTargetStreamer() {
108  MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
109  return static_cast<MipsTargetStreamer &>(TS);
110  }
111 
112  MipsABIInfo ABI;
114  MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
115  // nullptr, which indicates that no function is currently
116  // selected. This usually happens after an '.end func'
117  // directive.
118  bool IsLittleEndian;
119  bool IsPicEnabled;
120  bool IsCpRestoreSet;
121  int CpRestoreOffset;
122  unsigned CpSaveLocation;
123  /// If true, then CpSaveLocation is a register, otherwise it's an offset.
124  bool CpSaveLocationIsRegister;
125 
126  // Print a warning along with its fix-it message at the given range.
127  void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
128  SMRange Range, bool ShowColors = true);
129 
130 #define GET_ASSEMBLER_HEADER
131 #include "MipsGenAsmMatcher.inc"
132 
133  unsigned
134  checkEarlyTargetMatchPredicate(MCInst &Inst,
135  const OperandVector &Operands) override;
136  unsigned checkTargetMatchPredicate(MCInst &Inst) override;
137 
138  bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
139  OperandVector &Operands, MCStreamer &Out,
140  uint64_t &ErrorInfo,
141  bool MatchingInlineAsm) override;
142 
143  /// Parse a register as used in CFI directives
144  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
145 
146  bool parseParenSuffix(StringRef Name, OperandVector &Operands);
147 
148  bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
149 
150  bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
151  SMLoc NameLoc, OperandVector &Operands) override;
152 
153  bool ParseDirective(AsmToken DirectiveID) override;
154 
155  OperandMatchResultTy parseMemOperand(OperandVector &Operands);
157  matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
158  StringRef Identifier, SMLoc S);
159  OperandMatchResultTy matchAnyRegisterWithoutDollar(OperandVector &Operands,
160  SMLoc S);
161  OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
162  OperandMatchResultTy parseImm(OperandVector &Operands);
163  OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
164  OperandMatchResultTy parseInvNum(OperandVector &Operands);
165  OperandMatchResultTy parseRegisterPair(OperandVector &Operands);
166  OperandMatchResultTy parseMovePRegPair(OperandVector &Operands);
167  OperandMatchResultTy parseRegisterList(OperandVector &Operands);
168 
169  bool searchSymbolAlias(OperandVector &Operands);
170 
171  bool parseOperand(OperandVector &, StringRef Mnemonic);
172 
173  enum MacroExpanderResultTy {
174  MER_NotAMacro,
175  MER_Success,
176  MER_Fail,
177  };
178 
179  // Expands assembly pseudo instructions.
180  MacroExpanderResultTy tryExpandInstruction(MCInst &Inst, SMLoc IDLoc,
181  MCStreamer &Out,
182  const MCSubtargetInfo *STI);
183 
184  bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
185  const MCSubtargetInfo *STI);
186 
187  bool loadImmediate(int64_t ImmValue, unsigned DstReg, unsigned SrcReg,
188  bool Is32BitImm, bool IsAddress, SMLoc IDLoc,
189  MCStreamer &Out, const MCSubtargetInfo *STI);
190 
191  bool loadAndAddSymbolAddress(const MCExpr *SymExpr, unsigned DstReg,
192  unsigned SrcReg, bool Is32BitSym, SMLoc IDLoc,
193  MCStreamer &Out, const MCSubtargetInfo *STI);
194 
195  bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
196  MCStreamer &Out, const MCSubtargetInfo *STI);
197 
198  bool expandLoadAddress(unsigned DstReg, unsigned BaseReg,
199  const MCOperand &Offset, bool Is32BitAddress,
200  SMLoc IDLoc, MCStreamer &Out,
201  const MCSubtargetInfo *STI);
202 
203  bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
204  const MCSubtargetInfo *STI);
205 
206  void expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
207  const MCSubtargetInfo *STI, bool IsLoad, bool IsImmOpnd);
208 
209  void expandLoadInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
210  const MCSubtargetInfo *STI, bool IsImmOpnd);
211 
212  void expandStoreInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
213  const MCSubtargetInfo *STI, bool IsImmOpnd);
214 
215  bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
216  const MCSubtargetInfo *STI);
217 
218  bool expandAliasImmediate(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
219  const MCSubtargetInfo *STI);
220 
221  bool expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
222  const MCSubtargetInfo *STI);
223 
224  bool expandCondBranches(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
225  const MCSubtargetInfo *STI);
226 
227  bool expandDiv(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
228  const MCSubtargetInfo *STI, const bool IsMips64,
229  const bool Signed);
230 
231  bool expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU, SMLoc IDLoc,
232  MCStreamer &Out, const MCSubtargetInfo *STI);
233 
234  bool expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc, MCStreamer &Out,
235  const MCSubtargetInfo *STI);
236 
237  bool expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
238  const MCSubtargetInfo *STI);
239 
240  bool expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
241  const MCSubtargetInfo *STI);
242 
243  bool expandRotation(MCInst &Inst, SMLoc IDLoc,
244  MCStreamer &Out, const MCSubtargetInfo *STI);
245  bool expandRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
246  const MCSubtargetInfo *STI);
247  bool expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
248  const MCSubtargetInfo *STI);
249  bool expandDRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
250  const MCSubtargetInfo *STI);
251 
252  bool expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
253  const MCSubtargetInfo *STI);
254 
255  bool expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
256  const MCSubtargetInfo *STI, bool IsLoad);
257 
258  bool expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
259  const MCSubtargetInfo *STI);
260 
261  bool expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
262  const MCSubtargetInfo *STI);
263 
264  bool reportParseError(Twine ErrorMsg);
265  bool reportParseError(SMLoc Loc, Twine ErrorMsg);
266 
267  bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
268 
269  bool isEvaluated(const MCExpr *Expr);
270  bool parseSetMips0Directive();
271  bool parseSetArchDirective();
272  bool parseSetFeature(uint64_t Feature);
273  bool isPicAndNotNxxAbi(); // Used by .cpload, .cprestore, and .cpsetup.
274  bool parseDirectiveCpLoad(SMLoc Loc);
275  bool parseDirectiveCpRestore(SMLoc Loc);
276  bool parseDirectiveCPSetup();
277  bool parseDirectiveCPReturn();
278  bool parseDirectiveNaN();
279  bool parseDirectiveSet();
280  bool parseDirectiveOption();
281  bool parseInsnDirective();
282  bool parseSSectionDirective(StringRef Section, unsigned Type);
283 
284  bool parseSetAtDirective();
285  bool parseSetNoAtDirective();
286  bool parseSetMacroDirective();
287  bool parseSetNoMacroDirective();
288  bool parseSetMsaDirective();
289  bool parseSetNoMsaDirective();
290  bool parseSetNoDspDirective();
291  bool parseSetReorderDirective();
292  bool parseSetNoReorderDirective();
293  bool parseSetMips16Directive();
294  bool parseSetNoMips16Directive();
295  bool parseSetFpDirective();
296  bool parseSetOddSPRegDirective();
297  bool parseSetNoOddSPRegDirective();
298  bool parseSetPopDirective();
299  bool parseSetPushDirective();
300  bool parseSetSoftFloatDirective();
301  bool parseSetHardFloatDirective();
302 
303  bool parseSetAssignment();
304 
305  bool parseDataDirective(unsigned Size, SMLoc L);
306  bool parseDirectiveGpWord();
307  bool parseDirectiveGpDWord();
308  bool parseDirectiveDtpRelWord();
309  bool parseDirectiveDtpRelDWord();
310  bool parseDirectiveTpRelWord();
311  bool parseDirectiveTpRelDWord();
312  bool parseDirectiveModule();
313  bool parseDirectiveModuleFP();
314  bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
315  StringRef Directive);
316 
317  bool parseInternalDirectiveReallowModule();
318 
319  bool eatComma(StringRef ErrorStr);
320 
321  int matchCPURegisterName(StringRef Symbol);
322 
323  int matchHWRegsRegisterName(StringRef Symbol);
324 
325  int matchFPURegisterName(StringRef Name);
326 
327  int matchFCCRegisterName(StringRef Name);
328 
329  int matchACRegisterName(StringRef Name);
330 
331  int matchMSA128RegisterName(StringRef Name);
332 
333  int matchMSA128CtrlRegisterName(StringRef Name);
334 
335  unsigned getReg(int RC, int RegNo);
336 
337  /// Returns the internal register number for the current AT. Also checks if
338  /// the current AT is unavailable (set to $0) and gives an error if it is.
339  /// This should be used in pseudo-instruction expansions which need AT.
340  unsigned getATReg(SMLoc Loc);
341 
342  bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
343  const MCSubtargetInfo *STI);
344 
345  // Helper function that checks if the value of a vector index is within the
346  // boundaries of accepted values for each RegisterKind
347  // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
348  bool validateMSAIndex(int Val, int RegKind);
349 
350  // Selects a new architecture by updating the FeatureBits with the necessary
351  // info including implied dependencies.
352  // Internally, it clears all the feature bits related to *any* architecture
353  // and selects the new one using the ToggleFeature functionality of the
354  // MCSubtargetInfo object that handles implied dependencies. The reason we
355  // clear all the arch related bits manually is because ToggleFeature only
356  // clears the features that imply the feature being cleared and not the
357  // features implied by the feature being cleared. This is easier to see
358  // with an example:
359  // --------------------------------------------------
360  // | Feature | Implies |
361  // | -------------------------------------------------|
362  // | FeatureMips1 | None |
363  // | FeatureMips2 | FeatureMips1 |
364  // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
365  // | FeatureMips4 | FeatureMips3 |
366  // | ... | |
367  // --------------------------------------------------
368  //
369  // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
370  // FeatureMipsGP64 | FeatureMips1)
371  // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
372  void selectArch(StringRef ArchFeature) {
373  MCSubtargetInfo &STI = copySTI();
374  FeatureBitset FeatureBits = STI.getFeatureBits();
375  FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
376  STI.setFeatureBits(FeatureBits);
377  setAvailableFeatures(
378  ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
379  AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
380  }
381 
382  void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
383  if (!(getSTI().getFeatureBits()[Feature])) {
384  MCSubtargetInfo &STI = copySTI();
385  setAvailableFeatures(
386  ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
387  AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
388  }
389  }
390 
391  void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
392  if (getSTI().getFeatureBits()[Feature]) {
393  MCSubtargetInfo &STI = copySTI();
394  setAvailableFeatures(
395  ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
396  AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
397  }
398  }
399 
400  void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
401  setFeatureBits(Feature, FeatureString);
402  AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
403  }
404 
405  void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
406  clearFeatureBits(Feature, FeatureString);
407  AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
408  }
409 
410 public:
411  enum MipsMatchResultTy {
412  Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY,
413  Match_RequiresDifferentOperands,
414  Match_RequiresNoZeroRegister,
415  Match_RequiresSameSrcAndDst,
416  Match_NoFCCRegisterForCurrentISA,
417  Match_NonZeroOperandForSync,
418 #define GET_OPERAND_DIAGNOSTIC_TYPES
419 #include "MipsGenAsmMatcher.inc"
420 #undef GET_OPERAND_DIAGNOSTIC_TYPES
421  };
422 
423  MipsAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
424  const MCInstrInfo &MII, const MCTargetOptions &Options)
425  : MCTargetAsmParser(Options, sti),
426  ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
427  sti.getCPU(), Options)) {
429 
430  parser.addAliasForDirective(".asciiz", ".asciz");
431 
432  // Initialize the set of available features.
433  setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
434 
435  // Remember the initial assembler options. The user can not modify these.
436  AssemblerOptions.push_back(
437  llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
438 
439  // Create an assembler options environment for the user to modify.
440  AssemblerOptions.push_back(
441  llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
442 
443  getTargetStreamer().updateABIInfo(*this);
444 
445  if (!isABI_O32() && !useOddSPReg() != 0)
446  report_fatal_error("-mno-odd-spreg requires the O32 ABI");
447 
448  CurrentFn = nullptr;
449 
450  IsPicEnabled = getContext().getObjectFileInfo()->isPositionIndependent();
451 
452  IsCpRestoreSet = false;
453  CpRestoreOffset = -1;
454 
455  const Triple &TheTriple = sti.getTargetTriple();
456  if ((TheTriple.getArch() == Triple::mips) ||
457  (TheTriple.getArch() == Triple::mips64))
458  IsLittleEndian = false;
459  else
460  IsLittleEndian = true;
461  }
462 
463  /// True if all of $fcc0 - $fcc7 exist for the current ISA.
464  bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
465 
466  bool isGP64bit() const {
467  return getSTI().getFeatureBits()[Mips::FeatureGP64Bit];
468  }
469  bool isFP64bit() const {
470  return getSTI().getFeatureBits()[Mips::FeatureFP64Bit];
471  }
472  const MipsABIInfo &getABI() const { return ABI; }
473  bool isABI_N32() const { return ABI.IsN32(); }
474  bool isABI_N64() const { return ABI.IsN64(); }
475  bool isABI_O32() const { return ABI.IsO32(); }
476  bool isABI_FPXX() const {
477  return getSTI().getFeatureBits()[Mips::FeatureFPXX];
478  }
479 
480  bool useOddSPReg() const {
481  return !(getSTI().getFeatureBits()[Mips::FeatureNoOddSPReg]);
482  }
483 
484  bool inMicroMipsMode() const {
485  return getSTI().getFeatureBits()[Mips::FeatureMicroMips];
486  }
487  bool hasMips1() const {
488  return getSTI().getFeatureBits()[Mips::FeatureMips1];
489  }
490  bool hasMips2() const {
491  return getSTI().getFeatureBits()[Mips::FeatureMips2];
492  }
493  bool hasMips3() const {
494  return getSTI().getFeatureBits()[Mips::FeatureMips3];
495  }
496  bool hasMips4() const {
497  return getSTI().getFeatureBits()[Mips::FeatureMips4];
498  }
499  bool hasMips5() const {
500  return getSTI().getFeatureBits()[Mips::FeatureMips5];
501  }
502  bool hasMips32() const {
503  return getSTI().getFeatureBits()[Mips::FeatureMips32];
504  }
505  bool hasMips64() const {
506  return getSTI().getFeatureBits()[Mips::FeatureMips64];
507  }
508  bool hasMips32r2() const {
509  return getSTI().getFeatureBits()[Mips::FeatureMips32r2];
510  }
511  bool hasMips64r2() const {
512  return getSTI().getFeatureBits()[Mips::FeatureMips64r2];
513  }
514  bool hasMips32r3() const {
515  return (getSTI().getFeatureBits()[Mips::FeatureMips32r3]);
516  }
517  bool hasMips64r3() const {
518  return (getSTI().getFeatureBits()[Mips::FeatureMips64r3]);
519  }
520  bool hasMips32r5() const {
521  return (getSTI().getFeatureBits()[Mips::FeatureMips32r5]);
522  }
523  bool hasMips64r5() const {
524  return (getSTI().getFeatureBits()[Mips::FeatureMips64r5]);
525  }
526  bool hasMips32r6() const {
527  return getSTI().getFeatureBits()[Mips::FeatureMips32r6];
528  }
529  bool hasMips64r6() const {
530  return getSTI().getFeatureBits()[Mips::FeatureMips64r6];
531  }
532 
533  bool hasDSP() const {
534  return getSTI().getFeatureBits()[Mips::FeatureDSP];
535  }
536  bool hasDSPR2() const {
537  return getSTI().getFeatureBits()[Mips::FeatureDSPR2];
538  }
539  bool hasDSPR3() const {
540  return getSTI().getFeatureBits()[Mips::FeatureDSPR3];
541  }
542  bool hasMSA() const {
543  return getSTI().getFeatureBits()[Mips::FeatureMSA];
544  }
545  bool hasCnMips() const {
546  return (getSTI().getFeatureBits()[Mips::FeatureCnMips]);
547  }
548 
549  bool inPicMode() {
550  return IsPicEnabled;
551  }
552 
553  bool inMips16Mode() const {
554  return getSTI().getFeatureBits()[Mips::FeatureMips16];
555  }
556 
557  bool useTraps() const {
558  return getSTI().getFeatureBits()[Mips::FeatureUseTCCInDIV];
559  }
560 
561  bool useSoftFloat() const {
562  return getSTI().getFeatureBits()[Mips::FeatureSoftFloat];
563  }
564 
565  /// Warn if RegIndex is the same as the current AT.
566  void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
567 
568  void warnIfNoMacro(SMLoc Loc);
569 
570  bool isLittle() const { return IsLittleEndian; }
571 
572  const MCExpr *createTargetUnaryExpr(const MCExpr *E,
573  AsmToken::TokenKind OperatorToken,
574  MCContext &Ctx) override {
575  switch(OperatorToken) {
576  default:
577  llvm_unreachable("Unknown token");
578  return nullptr;
590  return MipsMCExpr::create(MipsMCExpr::MEK_GOT, E, Ctx);
605  case AsmToken::PercentHi:
606  return MipsMCExpr::create(MipsMCExpr::MEK_HI, E, Ctx);
611  case AsmToken::PercentLo:
612  return MipsMCExpr::create(MipsMCExpr::MEK_LO, E, Ctx);
614  return MipsMCExpr::create(MipsMCExpr::MEK_NEG, E, Ctx);
627  }
628  }
629 };
630 }
631 
632 namespace {
633 
634 /// MipsOperand - Instances of this class represent a parsed Mips machine
635 /// instruction.
636 class MipsOperand : public MCParsedAsmOperand {
637 public:
638  /// Broad categories of register classes
639  /// The exact class is finalized by the render method.
640  enum RegKind {
641  RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
642  RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
643  /// isFP64bit())
644  RegKind_FCC = 4, /// FCC
645  RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
646  RegKind_MSACtrl = 16, /// MSA control registers
647  RegKind_COP2 = 32, /// COP2
648  RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
649  /// context).
650  RegKind_CCR = 128, /// CCR
651  RegKind_HWRegs = 256, /// HWRegs
652  RegKind_COP3 = 512, /// COP3
653  RegKind_COP0 = 1024, /// COP0
654  /// Potentially any (e.g. $1)
655  RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
656  RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
657  RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
658  };
659 
660 private:
661  enum KindTy {
662  k_Immediate, /// An immediate (possibly involving symbol references)
663  k_Memory, /// Base + Offset Memory Address
664  k_RegisterIndex, /// A register index in one or more RegKind.
665  k_Token, /// A simple token
666  k_RegList, /// A physical register list
667  k_RegPair /// A pair of physical register
668  } Kind;
669 
670 public:
671  MipsOperand(KindTy K, MipsAsmParser &Parser)
672  : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
673 
674 private:
675  /// For diagnostics, and checking the assembler temporary
676  MipsAsmParser &AsmParser;
677 
678  struct Token {
679  const char *Data;
680  unsigned Length;
681  };
682 
683  struct RegIdxOp {
684  unsigned Index; /// Index into the register class
685  RegKind Kind; /// Bitfield of the kinds it could possibly be
686  struct Token Tok; /// The input token this operand originated from.
687  const MCRegisterInfo *RegInfo;
688  };
689 
690  struct ImmOp {
691  const MCExpr *Val;
692  };
693 
694  struct MemOp {
695  MipsOperand *Base;
696  const MCExpr *Off;
697  };
698 
699  struct RegListOp {
701  };
702 
703  union {
704  struct Token Tok;
705  struct RegIdxOp RegIdx;
706  struct ImmOp Imm;
707  struct MemOp Mem;
708  struct RegListOp RegList;
709  };
710 
711  SMLoc StartLoc, EndLoc;
712 
713  /// Internal constructor for register kinds
714  static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, StringRef Str,
715  RegKind RegKind,
716  const MCRegisterInfo *RegInfo,
717  SMLoc S, SMLoc E,
718  MipsAsmParser &Parser) {
719  auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
720  Op->RegIdx.Index = Index;
721  Op->RegIdx.RegInfo = RegInfo;
722  Op->RegIdx.Kind = RegKind;
723  Op->RegIdx.Tok.Data = Str.data();
724  Op->RegIdx.Tok.Length = Str.size();
725  Op->StartLoc = S;
726  Op->EndLoc = E;
727  return Op;
728  }
729 
730 public:
731  /// Coerce the register to GPR32 and return the real register for the current
732  /// target.
733  unsigned getGPR32Reg() const {
734  assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
735  AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
736  unsigned ClassID = Mips::GPR32RegClassID;
737  return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
738  }
739 
740  /// Coerce the register to GPR32 and return the real register for the current
741  /// target.
742  unsigned getGPRMM16Reg() const {
743  assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
744  unsigned ClassID = Mips::GPR32RegClassID;
745  return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
746  }
747 
748  /// Coerce the register to GPR64 and return the real register for the current
749  /// target.
750  unsigned getGPR64Reg() const {
751  assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
752  unsigned ClassID = Mips::GPR64RegClassID;
753  return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
754  }
755 
756 private:
757  /// Coerce the register to AFGR64 and return the real register for the current
758  /// target.
759  unsigned getAFGR64Reg() const {
760  assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
761  if (RegIdx.Index % 2 != 0)
762  AsmParser.Warning(StartLoc, "Float register should be even.");
763  return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
764  .getRegister(RegIdx.Index / 2);
765  }
766 
767  /// Coerce the register to FGR64 and return the real register for the current
768  /// target.
769  unsigned getFGR64Reg() const {
770  assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
771  return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
772  .getRegister(RegIdx.Index);
773  }
774 
775  /// Coerce the register to FGR32 and return the real register for the current
776  /// target.
777  unsigned getFGR32Reg() const {
778  assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
779  return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
780  .getRegister(RegIdx.Index);
781  }
782 
783  /// Coerce the register to FGRH32 and return the real register for the current
784  /// target.
785  unsigned getFGRH32Reg() const {
786  assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
787  return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
788  .getRegister(RegIdx.Index);
789  }
790 
791  /// Coerce the register to FCC and return the real register for the current
792  /// target.
793  unsigned getFCCReg() const {
794  assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
795  return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
796  .getRegister(RegIdx.Index);
797  }
798 
799  /// Coerce the register to MSA128 and return the real register for the current
800  /// target.
801  unsigned getMSA128Reg() const {
802  assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
803  // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
804  // identical
805  unsigned ClassID = Mips::MSA128BRegClassID;
806  return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
807  }
808 
809  /// Coerce the register to MSACtrl and return the real register for the
810  /// current target.
811  unsigned getMSACtrlReg() const {
812  assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
813  unsigned ClassID = Mips::MSACtrlRegClassID;
814  return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
815  }
816 
817  /// Coerce the register to COP0 and return the real register for the
818  /// current target.
819  unsigned getCOP0Reg() const {
820  assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) && "Invalid access!");
821  unsigned ClassID = Mips::COP0RegClassID;
822  return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
823  }
824 
825  /// Coerce the register to COP2 and return the real register for the
826  /// current target.
827  unsigned getCOP2Reg() const {
828  assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
829  unsigned ClassID = Mips::COP2RegClassID;
830  return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
831  }
832 
833  /// Coerce the register to COP3 and return the real register for the
834  /// current target.
835  unsigned getCOP3Reg() const {
836  assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
837  unsigned ClassID = Mips::COP3RegClassID;
838  return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
839  }
840 
841  /// Coerce the register to ACC64DSP and return the real register for the
842  /// current target.
843  unsigned getACC64DSPReg() const {
844  assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
845  unsigned ClassID = Mips::ACC64DSPRegClassID;
846  return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
847  }
848 
849  /// Coerce the register to HI32DSP and return the real register for the
850  /// current target.
851  unsigned getHI32DSPReg() const {
852  assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
853  unsigned ClassID = Mips::HI32DSPRegClassID;
854  return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
855  }
856 
857  /// Coerce the register to LO32DSP and return the real register for the
858  /// current target.
859  unsigned getLO32DSPReg() const {
860  assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
861  unsigned ClassID = Mips::LO32DSPRegClassID;
862  return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
863  }
864 
865  /// Coerce the register to CCR and return the real register for the
866  /// current target.
867  unsigned getCCRReg() const {
868  assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
869  unsigned ClassID = Mips::CCRRegClassID;
870  return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
871  }
872 
873  /// Coerce the register to HWRegs and return the real register for the
874  /// current target.
875  unsigned getHWRegsReg() const {
876  assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
877  unsigned ClassID = Mips::HWRegsRegClassID;
878  return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
879  }
880 
881 public:
882  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
883  // Add as immediate when possible. Null MCExpr = 0.
884  if (!Expr)
886  else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
887  Inst.addOperand(MCOperand::createImm(CE->getValue()));
888  else
889  Inst.addOperand(MCOperand::createExpr(Expr));
890  }
891 
892  void addRegOperands(MCInst &Inst, unsigned N) const {
893  llvm_unreachable("Use a custom parser instead");
894  }
895 
896  /// Render the operand to an MCInst as a GPR32
897  /// Asserts if the wrong number of operands are requested, or the operand
898  /// is not a k_RegisterIndex compatible with RegKind_GPR
899  void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
900  assert(N == 1 && "Invalid number of operands!");
901  Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
902  }
903 
904  void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
905  assert(N == 1 && "Invalid number of operands!");
906  Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
907  }
908 
909  void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
910  assert(N == 1 && "Invalid number of operands!");
911  Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
912  }
913 
914  void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
915  assert(N == 1 && "Invalid number of operands!");
916  Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
917  }
918 
919  /// Render the operand to an MCInst as a GPR64
920  /// Asserts if the wrong number of operands are requested, or the operand
921  /// is not a k_RegisterIndex compatible with RegKind_GPR
922  void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
923  assert(N == 1 && "Invalid number of operands!");
924  Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
925  }
926 
927  void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
928  assert(N == 1 && "Invalid number of operands!");
929  Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
930  }
931 
932  void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
933  assert(N == 1 && "Invalid number of operands!");
934  Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
935  }
936 
937  void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
938  assert(N == 1 && "Invalid number of operands!");
939  Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
940  // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
941  // FIXME: This should propagate failure up to parseStatement.
942  if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
943  AsmParser.getParser().printError(
944  StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
945  "registers");
946  }
947 
948  void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
949  assert(N == 1 && "Invalid number of operands!");
950  Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
951  }
952 
953  void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
954  assert(N == 1 && "Invalid number of operands!");
955  Inst.addOperand(MCOperand::createReg(getFCCReg()));
956  }
957 
958  void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
959  assert(N == 1 && "Invalid number of operands!");
960  Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
961  }
962 
963  void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
964  assert(N == 1 && "Invalid number of operands!");
965  Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
966  }
967 
968  void addCOP0AsmRegOperands(MCInst &Inst, unsigned N) const {
969  assert(N == 1 && "Invalid number of operands!");
970  Inst.addOperand(MCOperand::createReg(getCOP0Reg()));
971  }
972 
973  void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
974  assert(N == 1 && "Invalid number of operands!");
975  Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
976  }
977 
978  void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
979  assert(N == 1 && "Invalid number of operands!");
980  Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
981  }
982 
983  void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
984  assert(N == 1 && "Invalid number of operands!");
985  Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
986  }
987 
988  void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
989  assert(N == 1 && "Invalid number of operands!");
990  Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
991  }
992 
993  void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
994  assert(N == 1 && "Invalid number of operands!");
995  Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
996  }
997 
998  void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
999  assert(N == 1 && "Invalid number of operands!");
1000  Inst.addOperand(MCOperand::createReg(getCCRReg()));
1001  }
1002 
1003  void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
1004  assert(N == 1 && "Invalid number of operands!");
1005  Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
1006  }
1007 
1008  template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
1009  void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
1010  assert(N == 1 && "Invalid number of operands!");
1011  uint64_t Imm = getConstantImm() - Offset;
1012  Imm &= (1ULL << Bits) - 1;
1013  Imm += Offset;
1014  Imm += AdjustOffset;
1015  Inst.addOperand(MCOperand::createImm(Imm));
1016  }
1017 
1018  template <unsigned Bits>
1019  void addSImmOperands(MCInst &Inst, unsigned N) const {
1020  if (isImm() && !isConstantImm()) {
1021  addExpr(Inst, getImm());
1022  return;
1023  }
1024  addConstantSImmOperands<Bits, 0, 0>(Inst, N);
1025  }
1026 
1027  template <unsigned Bits>
1028  void addUImmOperands(MCInst &Inst, unsigned N) const {
1029  if (isImm() && !isConstantImm()) {
1030  addExpr(Inst, getImm());
1031  return;
1032  }
1033  addConstantUImmOperands<Bits, 0, 0>(Inst, N);
1034  }
1035 
1036  template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
1037  void addConstantSImmOperands(MCInst &Inst, unsigned N) const {
1038  assert(N == 1 && "Invalid number of operands!");
1039  int64_t Imm = getConstantImm() - Offset;
1040  Imm = SignExtend64<Bits>(Imm);
1041  Imm += Offset;
1042  Imm += AdjustOffset;
1043  Inst.addOperand(MCOperand::createImm(Imm));
1044  }
1045 
1046  void addImmOperands(MCInst &Inst, unsigned N) const {
1047  assert(N == 1 && "Invalid number of operands!");
1048  const MCExpr *Expr = getImm();
1049  addExpr(Inst, Expr);
1050  }
1051 
1052  void addMemOperands(MCInst &Inst, unsigned N) const {
1053  assert(N == 2 && "Invalid number of operands!");
1054 
1055  Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit()
1056  ? getMemBase()->getGPR64Reg()
1057  : getMemBase()->getGPR32Reg()));
1058 
1059  const MCExpr *Expr = getMemOff();
1060  addExpr(Inst, Expr);
1061  }
1062 
1063  void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
1064  assert(N == 2 && "Invalid number of operands!");
1065 
1066  Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
1067 
1068  const MCExpr *Expr = getMemOff();
1069  addExpr(Inst, Expr);
1070  }
1071 
1072  void addRegListOperands(MCInst &Inst, unsigned N) const {
1073  assert(N == 1 && "Invalid number of operands!");
1074 
1075  for (auto RegNo : getRegList())
1076  Inst.addOperand(MCOperand::createReg(RegNo));
1077  }
1078 
1079  void addRegPairOperands(MCInst &Inst, unsigned N) const {
1080  assert(N == 2 && "Invalid number of operands!");
1081  assert((RegIdx.Kind & RegKind_GPR) && "Invalid access!");
1082  unsigned RegNo = getRegPair();
1083  AsmParser.warnIfRegIndexIsAT(RegNo, StartLoc);
1085  RegIdx.RegInfo->getRegClass(
1086  AsmParser.getABI().AreGprs64bit()
1087  ? Mips::GPR64RegClassID
1088  : Mips::GPR32RegClassID).getRegister(RegNo++)));
1090  RegIdx.RegInfo->getRegClass(
1091  AsmParser.getABI().AreGprs64bit()
1092  ? Mips::GPR64RegClassID
1093  : Mips::GPR32RegClassID).getRegister(RegNo)));
1094  }
1095 
1096  void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
1097  assert(N == 2 && "Invalid number of operands!");
1098  for (auto RegNo : getRegList())
1099  Inst.addOperand(MCOperand::createReg(RegNo));
1100  }
1101 
1102  bool isReg() const override {
1103  // As a special case until we sort out the definition of div/divu, accept
1104  // $0/$zero here so that MCK_ZERO works correctly.
1105  return isGPRAsmReg() && RegIdx.Index == 0;
1106  }
1107  bool isRegIdx() const { return Kind == k_RegisterIndex; }
1108  bool isImm() const override { return Kind == k_Immediate; }
1109  bool isConstantImm() const {
1110  int64_t Res;
1111  return isImm() && getImm()->evaluateAsAbsolute(Res);
1112  }
1113  bool isConstantImmz() const {
1114  return isConstantImm() && getConstantImm() == 0;
1115  }
1116  template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
1117  return isConstantImm() && isUInt<Bits>(getConstantImm() - Offset);
1118  }
1119  template <unsigned Bits> bool isSImm() const {
1120  return isConstantImm() ? isInt<Bits>(getConstantImm()) : isImm();
1121  }
1122  template <unsigned Bits> bool isUImm() const {
1123  return isConstantImm() ? isUInt<Bits>(getConstantImm()) : isImm();
1124  }
1125  template <unsigned Bits> bool isAnyImm() const {
1126  return isConstantImm() ? (isInt<Bits>(getConstantImm()) ||
1127  isUInt<Bits>(getConstantImm()))
1128  : isImm();
1129  }
1130  template <unsigned Bits, int Offset = 0> bool isConstantSImm() const {
1131  return isConstantImm() && isInt<Bits>(getConstantImm() - Offset);
1132  }
1133  template <unsigned Bottom, unsigned Top> bool isConstantUImmRange() const {
1134  return isConstantImm() && getConstantImm() >= Bottom &&
1135  getConstantImm() <= Top;
1136  }
1137  bool isToken() const override {
1138  // Note: It's not possible to pretend that other operand kinds are tokens.
1139  // The matcher emitter checks tokens first.
1140  return Kind == k_Token;
1141  }
1142  bool isMem() const override { return Kind == k_Memory; }
1143  bool isConstantMemOff() const {
1144  return isMem() && isa<MCConstantExpr>(getMemOff());
1145  }
1146  // Allow relocation operators.
1147  // FIXME: This predicate and others need to look through binary expressions
1148  // and determine whether a Value is a constant or not.
1149  template <unsigned Bits, unsigned ShiftAmount = 0>
1150  bool isMemWithSimmOffset() const {
1151  if (!isMem())
1152  return false;
1153  if (!getMemBase()->isGPRAsmReg())
1154  return false;
1155  if (isa<MCTargetExpr>(getMemOff()) ||
1156  (isConstantMemOff() &&
1157  isShiftedInt<Bits, ShiftAmount>(getConstantMemOff())))
1158  return true;
1159  MCValue Res;
1160  bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr);
1161  return IsReloc && isShiftedInt<Bits, ShiftAmount>(Res.getConstant());
1162  }
1163  bool isMemWithGRPMM16Base() const {
1164  return isMem() && getMemBase()->isMM16AsmReg();
1165  }
1166  template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
1167  return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1168  && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
1169  }
1170  template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
1171  return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1172  && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1173  && (getMemBase()->getGPR32Reg() == Mips::SP);
1174  }
1175  template <unsigned Bits> bool isMemWithSimmWordAlignedOffsetGP() const {
1176  return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
1177  && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1178  && (getMemBase()->getGPR32Reg() == Mips::GP);
1179  }
1180  template <unsigned Bits, unsigned ShiftLeftAmount>
1181  bool isScaledUImm() const {
1182  return isConstantImm() &&
1183  isShiftedUInt<Bits, ShiftLeftAmount>(getConstantImm());
1184  }
1185  template <unsigned Bits, unsigned ShiftLeftAmount>
1186  bool isScaledSImm() const {
1187  if (isConstantImm() && isShiftedInt<Bits, ShiftLeftAmount>(getConstantImm()))
1188  return true;
1189  // Operand can also be a symbol or symbol plus offset in case of relocations.
1190  if (Kind != k_Immediate)
1191  return false;
1192  MCValue Res;
1193  bool Success = getImm()->evaluateAsRelocatable(Res, nullptr, nullptr);
1194  return Success && isShiftedInt<Bits, ShiftLeftAmount>(Res.getConstant());
1195  }
1196  bool isRegList16() const {
1197  if (!isRegList())
1198  return false;
1199 
1200  int Size = RegList.List->size();
1201  if (Size < 2 || Size > 5)
1202  return false;
1203 
1204  unsigned R0 = RegList.List->front();
1205  unsigned R1 = RegList.List->back();
1206  if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1207  (R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1208  return false;
1209 
1210  int PrevReg = *RegList.List->begin();
1211  for (int i = 1; i < Size - 1; i++) {
1212  int Reg = (*(RegList.List))[i];
1213  if ( Reg != PrevReg + 1)
1214  return false;
1215  PrevReg = Reg;
1216  }
1217 
1218  return true;
1219  }
1220  bool isInvNum() const { return Kind == k_Immediate; }
1221  bool isLSAImm() const {
1222  if (!isConstantImm())
1223  return false;
1224  int64_t Val = getConstantImm();
1225  return 1 <= Val && Val <= 4;
1226  }
1227  bool isRegList() const { return Kind == k_RegList; }
1228  bool isMovePRegPair() const {
1229  if (Kind != k_RegList || RegList.List->size() != 2)
1230  return false;
1231 
1232  unsigned R0 = RegList.List->front();
1233  unsigned R1 = RegList.List->back();
1234 
1235  if ((R0 == Mips::A1 && R1 == Mips::A2) ||
1236  (R0 == Mips::A1 && R1 == Mips::A3) ||
1237  (R0 == Mips::A2 && R1 == Mips::A3) ||
1238  (R0 == Mips::A0 && R1 == Mips::S5) ||
1239  (R0 == Mips::A0 && R1 == Mips::S6) ||
1240  (R0 == Mips::A0 && R1 == Mips::A1) ||
1241  (R0 == Mips::A0 && R1 == Mips::A2) ||
1242  (R0 == Mips::A0 && R1 == Mips::A3) ||
1243  (R0 == Mips::A1_64 && R1 == Mips::A2_64) ||
1244  (R0 == Mips::A1_64 && R1 == Mips::A3_64) ||
1245  (R0 == Mips::A2_64 && R1 == Mips::A3_64) ||
1246  (R0 == Mips::A0_64 && R1 == Mips::S5_64) ||
1247  (R0 == Mips::A0_64 && R1 == Mips::S6_64) ||
1248  (R0 == Mips::A0_64 && R1 == Mips::A1_64) ||
1249  (R0 == Mips::A0_64 && R1 == Mips::A2_64) ||
1250  (R0 == Mips::A0_64 && R1 == Mips::A3_64))
1251  return true;
1252 
1253  return false;
1254  }
1255 
1256  StringRef getToken() const {
1257  assert(Kind == k_Token && "Invalid access!");
1258  return StringRef(Tok.Data, Tok.Length);
1259  }
1260  bool isRegPair() const {
1261  return Kind == k_RegPair && RegIdx.Index <= 30;
1262  }
1263 
1264  unsigned getReg() const override {
1265  // As a special case until we sort out the definition of div/divu, accept
1266  // $0/$zero here so that MCK_ZERO works correctly.
1267  if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1268  RegIdx.Kind & RegKind_GPR)
1269  return getGPR32Reg(); // FIXME: GPR64 too
1270 
1271  llvm_unreachable("Invalid access!");
1272  return 0;
1273  }
1274 
1275  const MCExpr *getImm() const {
1276  assert((Kind == k_Immediate) && "Invalid access!");
1277  return Imm.Val;
1278  }
1279 
1280  int64_t getConstantImm() const {
1281  const MCExpr *Val = getImm();
1282  int64_t Value = 0;
1283  (void)Val->evaluateAsAbsolute(Value);
1284  return Value;
1285  }
1286 
1287  MipsOperand *getMemBase() const {
1288  assert((Kind == k_Memory) && "Invalid access!");
1289  return Mem.Base;
1290  }
1291 
1292  const MCExpr *getMemOff() const {
1293  assert((Kind == k_Memory) && "Invalid access!");
1294  return Mem.Off;
1295  }
1296 
1297  int64_t getConstantMemOff() const {
1298  return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1299  }
1300 
1301  const SmallVectorImpl<unsigned> &getRegList() const {
1302  assert((Kind == k_RegList) && "Invalid access!");
1303  return *(RegList.List);
1304  }
1305 
1306  unsigned getRegPair() const {
1307  assert((Kind == k_RegPair) && "Invalid access!");
1308  return RegIdx.Index;
1309  }
1310 
1311  static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1312  MipsAsmParser &Parser) {
1313  auto Op = make_unique<MipsOperand>(k_Token, Parser);
1314  Op->Tok.Data = Str.data();
1315  Op->Tok.Length = Str.size();
1316  Op->StartLoc = S;
1317  Op->EndLoc = S;
1318  return Op;
1319  }
1320 
1321  /// Create a numeric register (e.g. $1). The exact register remains
1322  /// unresolved until an instruction successfully matches
1323  static std::unique_ptr<MipsOperand>
1324  createNumericReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1325  SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1326  DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1327  return CreateReg(Index, Str, RegKind_Numeric, RegInfo, S, E, Parser);
1328  }
1329 
1330  /// Create a register that is definitely a GPR.
1331  /// This is typically only used for named registers such as $gp.
1332  static std::unique_ptr<MipsOperand>
1333  createGPRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1334  SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1335  return CreateReg(Index, Str, RegKind_GPR, RegInfo, S, E, Parser);
1336  }
1337 
1338  /// Create a register that is definitely a FGR.
1339  /// This is typically only used for named registers such as $f0.
1340  static std::unique_ptr<MipsOperand>
1341  createFGRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1342  SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1343  return CreateReg(Index, Str, RegKind_FGR, RegInfo, S, E, Parser);
1344  }
1345 
1346  /// Create a register that is definitely a HWReg.
1347  /// This is typically only used for named registers such as $hwr_cpunum.
1348  static std::unique_ptr<MipsOperand>
1349  createHWRegsReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1350  SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1351  return CreateReg(Index, Str, RegKind_HWRegs, RegInfo, S, E, Parser);
1352  }
1353 
1354  /// Create a register that is definitely an FCC.
1355  /// This is typically only used for named registers such as $fcc0.
1356  static std::unique_ptr<MipsOperand>
1357  createFCCReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1358  SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1359  return CreateReg(Index, Str, RegKind_FCC, RegInfo, S, E, Parser);
1360  }
1361 
1362  /// Create a register that is definitely an ACC.
1363  /// This is typically only used for named registers such as $ac0.
1364  static std::unique_ptr<MipsOperand>
1365  createACCReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1366  SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1367  return CreateReg(Index, Str, RegKind_ACC, RegInfo, S, E, Parser);
1368  }
1369 
1370  /// Create a register that is definitely an MSA128.
1371  /// This is typically only used for named registers such as $w0.
1372  static std::unique_ptr<MipsOperand>
1373  createMSA128Reg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1374  SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1375  return CreateReg(Index, Str, RegKind_MSA128, RegInfo, S, E, Parser);
1376  }
1377 
1378  /// Create a register that is definitely an MSACtrl.
1379  /// This is typically only used for named registers such as $msaaccess.
1380  static std::unique_ptr<MipsOperand>
1381  createMSACtrlReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1382  SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1383  return CreateReg(Index, Str, RegKind_MSACtrl, RegInfo, S, E, Parser);
1384  }
1385 
1386  static std::unique_ptr<MipsOperand>
1387  CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1388  auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1389  Op->Imm.Val = Val;
1390  Op->StartLoc = S;
1391  Op->EndLoc = E;
1392  return Op;
1393  }
1394 
1395  static std::unique_ptr<MipsOperand>
1396  CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1397  SMLoc E, MipsAsmParser &Parser) {
1398  auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1399  Op->Mem.Base = Base.release();
1400  Op->Mem.Off = Off;
1401  Op->StartLoc = S;
1402  Op->EndLoc = E;
1403  return Op;
1404  }
1405 
1406  static std::unique_ptr<MipsOperand>
1407  CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1408  MipsAsmParser &Parser) {
1409  assert (Regs.size() > 0 && "Empty list not allowed");
1410 
1411  auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1412  Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1413  Op->StartLoc = StartLoc;
1414  Op->EndLoc = EndLoc;
1415  return Op;
1416  }
1417 
1418  static std::unique_ptr<MipsOperand> CreateRegPair(const MipsOperand &MOP,
1419  SMLoc S, SMLoc E,
1420  MipsAsmParser &Parser) {
1421  auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1422  Op->RegIdx.Index = MOP.RegIdx.Index;
1423  Op->RegIdx.RegInfo = MOP.RegIdx.RegInfo;
1424  Op->RegIdx.Kind = MOP.RegIdx.Kind;
1425  Op->StartLoc = S;
1426  Op->EndLoc = E;
1427  return Op;
1428  }
1429 
1430  bool isGPRAsmReg() const {
1431  return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1432  }
1433  bool isMM16AsmReg() const {
1434  if (!(isRegIdx() && RegIdx.Kind))
1435  return false;
1436  return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1437  || RegIdx.Index == 16 || RegIdx.Index == 17);
1438  }
1439  bool isMM16AsmRegZero() const {
1440  if (!(isRegIdx() && RegIdx.Kind))
1441  return false;
1442  return (RegIdx.Index == 0 ||
1443  (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1444  RegIdx.Index == 17);
1445  }
1446  bool isMM16AsmRegMoveP() const {
1447  if (!(isRegIdx() && RegIdx.Kind))
1448  return false;
1449  return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1450  (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1451  }
1452  bool isFGRAsmReg() const {
1453  // AFGR64 is $0-$15 but we handle this in getAFGR64()
1454  return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1455  }
1456  bool isHWRegsAsmReg() const {
1457  return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1458  }
1459  bool isCCRAsmReg() const {
1460  return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1461  }
1462  bool isFCCAsmReg() const {
1463  if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1464  return false;
1465  return RegIdx.Index <= 7;
1466  }
1467  bool isACCAsmReg() const {
1468  return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1469  }
1470  bool isCOP0AsmReg() const {
1471  return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1472  }
1473  bool isCOP2AsmReg() const {
1474  return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1475  }
1476  bool isCOP3AsmReg() const {
1477  return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1478  }
1479  bool isMSA128AsmReg() const {
1480  return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1481  }
1482  bool isMSACtrlAsmReg() const {
1483  return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1484  }
1485 
1486  /// getStartLoc - Get the location of the first token of this operand.
1487  SMLoc getStartLoc() const override { return StartLoc; }
1488  /// getEndLoc - Get the location of the last token of this operand.
1489  SMLoc getEndLoc() const override { return EndLoc; }
1490 
1491  virtual ~MipsOperand() {
1492  switch (Kind) {
1493  case k_Immediate:
1494  break;
1495  case k_Memory:
1496  delete Mem.Base;
1497  break;
1498  case k_RegList:
1499  delete RegList.List;
1500  case k_RegisterIndex:
1501  case k_Token:
1502  case k_RegPair:
1503  break;
1504  }
1505  }
1506 
1507  void print(raw_ostream &OS) const override {
1508  switch (Kind) {
1509  case k_Immediate:
1510  OS << "Imm<";
1511  OS << *Imm.Val;
1512  OS << ">";
1513  break;
1514  case k_Memory:
1515  OS << "Mem<";
1516  Mem.Base->print(OS);
1517  OS << ", ";
1518  OS << *Mem.Off;
1519  OS << ">";
1520  break;
1521  case k_RegisterIndex:
1522  OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ", "
1523  << StringRef(RegIdx.Tok.Data, RegIdx.Tok.Length) << ">";
1524  break;
1525  case k_Token:
1526  OS << getToken();
1527  break;
1528  case k_RegList:
1529  OS << "RegList< ";
1530  for (auto Reg : (*RegList.List))
1531  OS << Reg << " ";
1532  OS << ">";
1533  break;
1534  case k_RegPair:
1535  OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1536  break;
1537  }
1538  }
1539 
1540  bool isValidForTie(const MipsOperand &Other) const {
1541  if (Kind != Other.Kind)
1542  return false;
1543 
1544  switch (Kind) {
1545  default:
1546  llvm_unreachable("Unexpected kind");
1547  return false;
1548  case k_RegisterIndex: {
1549  StringRef Token(RegIdx.Tok.Data, RegIdx.Tok.Length);
1550  StringRef OtherToken(Other.RegIdx.Tok.Data, Other.RegIdx.Tok.Length);
1551  return Token == OtherToken;
1552  }
1553  }
1554  }
1555 }; // class MipsOperand
1556 } // namespace
1557 
1558 namespace llvm {
1559 extern const MCInstrDesc MipsInsts[];
1560 }
1561 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1562  return MipsInsts[Opcode];
1563 }
1564 
1565 static bool hasShortDelaySlot(unsigned Opcode) {
1566  switch (Opcode) {
1567  case Mips::JALS_MM:
1568  case Mips::JALRS_MM:
1569  case Mips::JALRS16_MM:
1570  case Mips::BGEZALS_MM:
1571  case Mips::BLTZALS_MM:
1572  return true;
1573  default:
1574  return false;
1575  }
1576 }
1577 
1578 static const MCSymbol *getSingleMCSymbol(const MCExpr *Expr) {
1579  if (const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1580  return &SRExpr->getSymbol();
1581  }
1582 
1583  if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1584  const MCSymbol *LHSSym = getSingleMCSymbol(BExpr->getLHS());
1585  const MCSymbol *RHSSym = getSingleMCSymbol(BExpr->getRHS());
1586 
1587  if (LHSSym)
1588  return LHSSym;
1589 
1590  if (RHSSym)
1591  return RHSSym;
1592 
1593  return nullptr;
1594  }
1595 
1596  if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1597  return getSingleMCSymbol(UExpr->getSubExpr());
1598 
1599  return nullptr;
1600 }
1601 
1602 static unsigned countMCSymbolRefExpr(const MCExpr *Expr) {
1603  if (isa<MCSymbolRefExpr>(Expr))
1604  return 1;
1605 
1606  if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1607  return countMCSymbolRefExpr(BExpr->getLHS()) +
1608  countMCSymbolRefExpr(BExpr->getRHS());
1609 
1610  if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1611  return countMCSymbolRefExpr(UExpr->getSubExpr());
1612 
1613  return 0;
1614 }
1615 
1616 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1617  MCStreamer &Out,
1618  const MCSubtargetInfo *STI) {
1619  MipsTargetStreamer &TOut = getTargetStreamer();
1620  const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1621  bool ExpandedJalSym = false;
1622 
1623  Inst.setLoc(IDLoc);
1624 
1625  if (MCID.isBranch() || MCID.isCall()) {
1626  const unsigned Opcode = Inst.getOpcode();
1627  MCOperand Offset;
1628 
1629  switch (Opcode) {
1630  default:
1631  break;
1632  case Mips::BBIT0:
1633  case Mips::BBIT032:
1634  case Mips::BBIT1:
1635  case Mips::BBIT132:
1636  assert(hasCnMips() && "instruction only valid for octeon cpus");
1638 
1639  case Mips::BEQ:
1640  case Mips::BNE:
1641  case Mips::BEQ_MM:
1642  case Mips::BNE_MM:
1643  assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1644  Offset = Inst.getOperand(2);
1645  if (!Offset.isImm())
1646  break; // We'll deal with this situation later on when applying fixups.
1647  if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1648  return Error(IDLoc, "branch target out of range");
1649  if (OffsetToAlignment(Offset.getImm(),
1650  1LL << (inMicroMipsMode() ? 1 : 2)))
1651  return Error(IDLoc, "branch to misaligned address");
1652  break;
1653  case Mips::BGEZ:
1654  case Mips::BGTZ:
1655  case Mips::BLEZ:
1656  case Mips::BLTZ:
1657  case Mips::BGEZAL:
1658  case Mips::BLTZAL:
1659  case Mips::BC1F:
1660  case Mips::BC1T:
1661  case Mips::BGEZ_MM:
1662  case Mips::BGTZ_MM:
1663  case Mips::BLEZ_MM:
1664  case Mips::BLTZ_MM:
1665  case Mips::BGEZAL_MM:
1666  case Mips::BLTZAL_MM:
1667  case Mips::BC1F_MM:
1668  case Mips::BC1T_MM:
1669  case Mips::BC1EQZC_MMR6:
1670  case Mips::BC1NEZC_MMR6:
1671  case Mips::BC2EQZC_MMR6:
1672  case Mips::BC2NEZC_MMR6:
1673  assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1674  Offset = Inst.getOperand(1);
1675  if (!Offset.isImm())
1676  break; // We'll deal with this situation later on when applying fixups.
1677  if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1678  return Error(IDLoc, "branch target out of range");
1679  if (OffsetToAlignment(Offset.getImm(),
1680  1LL << (inMicroMipsMode() ? 1 : 2)))
1681  return Error(IDLoc, "branch to misaligned address");
1682  break;
1683  case Mips::BGEC: case Mips::BGEC_MMR6:
1684  case Mips::BLTC: case Mips::BLTC_MMR6:
1685  case Mips::BGEUC: case Mips::BGEUC_MMR6:
1686  case Mips::BLTUC: case Mips::BLTUC_MMR6:
1687  case Mips::BEQC: case Mips::BEQC_MMR6:
1688  case Mips::BNEC: case Mips::BNEC_MMR6:
1689  assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1690  Offset = Inst.getOperand(2);
1691  if (!Offset.isImm())
1692  break; // We'll deal with this situation later on when applying fixups.
1693  if (!isIntN(18, Offset.getImm()))
1694  return Error(IDLoc, "branch target out of range");
1695  if (OffsetToAlignment(Offset.getImm(), 1LL << 2))
1696  return Error(IDLoc, "branch to misaligned address");
1697  break;
1698  case Mips::BLEZC: case Mips::BLEZC_MMR6:
1699  case Mips::BGEZC: case Mips::BGEZC_MMR6:
1700  case Mips::BGTZC: case Mips::BGTZC_MMR6:
1701  case Mips::BLTZC: case Mips::BLTZC_MMR6:
1702  assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1703  Offset = Inst.getOperand(1);
1704  if (!Offset.isImm())
1705  break; // We'll deal with this situation later on when applying fixups.
1706  if (!isIntN(18, Offset.getImm()))
1707  return Error(IDLoc, "branch target out of range");
1708  if (OffsetToAlignment(Offset.getImm(), 1LL << 2))
1709  return Error(IDLoc, "branch to misaligned address");
1710  break;
1711  case Mips::BEQZC: case Mips::BEQZC_MMR6:
1712  case Mips::BNEZC: case Mips::BNEZC_MMR6:
1713  assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1714  Offset = Inst.getOperand(1);
1715  if (!Offset.isImm())
1716  break; // We'll deal with this situation later on when applying fixups.
1717  if (!isIntN(23, Offset.getImm()))
1718  return Error(IDLoc, "branch target out of range");
1719  if (OffsetToAlignment(Offset.getImm(), 1LL << 2))
1720  return Error(IDLoc, "branch to misaligned address");
1721  break;
1722  case Mips::BEQZ16_MM:
1723  case Mips::BEQZC16_MMR6:
1724  case Mips::BNEZ16_MM:
1725  case Mips::BNEZC16_MMR6:
1726  assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1727  Offset = Inst.getOperand(1);
1728  if (!Offset.isImm())
1729  break; // We'll deal with this situation later on when applying fixups.
1730  if (!isInt<8>(Offset.getImm()))
1731  return Error(IDLoc, "branch target out of range");
1732  if (OffsetToAlignment(Offset.getImm(), 2LL))
1733  return Error(IDLoc, "branch to misaligned address");
1734  break;
1735  }
1736  }
1737 
1738  // SSNOP is deprecated on MIPS32r6/MIPS64r6
1739  // We still accept it but it is a normal nop.
1740  if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1741  std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1742  Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1743  "nop instruction");
1744  }
1745 
1746  if (hasCnMips()) {
1747  const unsigned Opcode = Inst.getOpcode();
1748  MCOperand Opnd;
1749  int Imm;
1750 
1751  switch (Opcode) {
1752  default:
1753  break;
1754 
1755  case Mips::BBIT0:
1756  case Mips::BBIT032:
1757  case Mips::BBIT1:
1758  case Mips::BBIT132:
1759  assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1760  // The offset is handled above
1761  Opnd = Inst.getOperand(1);
1762  if (!Opnd.isImm())
1763  return Error(IDLoc, "expected immediate operand kind");
1764  Imm = Opnd.getImm();
1765  if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1766  Opcode == Mips::BBIT1 ? 63 : 31))
1767  return Error(IDLoc, "immediate operand value out of range");
1768  if (Imm > 31) {
1769  Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1770  : Mips::BBIT132);
1771  Inst.getOperand(1).setImm(Imm - 32);
1772  }
1773  break;
1774 
1775  case Mips::SEQi:
1776  case Mips::SNEi:
1777  assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1778  Opnd = Inst.getOperand(2);
1779  if (!Opnd.isImm())
1780  return Error(IDLoc, "expected immediate operand kind");
1781  Imm = Opnd.getImm();
1782  if (!isInt<10>(Imm))
1783  return Error(IDLoc, "immediate operand value out of range");
1784  break;
1785  }
1786  }
1787 
1788  // For PIC code convert unconditional jump to unconditional branch.
1789  if ((Inst.getOpcode() == Mips::J || Inst.getOpcode() == Mips::J_MM) &&
1790  inPicMode()) {
1791  MCInst BInst;
1792  BInst.setOpcode(inMicroMipsMode() ? Mips::BEQ_MM : Mips::BEQ);
1793  BInst.addOperand(MCOperand::createReg(Mips::ZERO));
1794  BInst.addOperand(MCOperand::createReg(Mips::ZERO));
1795  BInst.addOperand(Inst.getOperand(0));
1796  Inst = BInst;
1797  }
1798 
1799  // This expansion is not in a function called by tryExpandInstruction()
1800  // because the pseudo-instruction doesn't have a distinct opcode.
1801  if ((Inst.getOpcode() == Mips::JAL || Inst.getOpcode() == Mips::JAL_MM) &&
1802  inPicMode()) {
1803  warnIfNoMacro(IDLoc);
1804 
1805  const MCExpr *JalExpr = Inst.getOperand(0).getExpr();
1806 
1807  // We can do this expansion if there's only 1 symbol in the argument
1808  // expression.
1809  if (countMCSymbolRefExpr(JalExpr) > 1)
1810  return Error(IDLoc, "jal doesn't support multiple symbols in PIC mode");
1811 
1812  // FIXME: This is checking the expression can be handled by the later stages
1813  // of the assembler. We ought to leave it to those later stages.
1814  const MCSymbol *JalSym = getSingleMCSymbol(JalExpr);
1815 
1816  // FIXME: Add support for label+offset operands (currently causes an error).
1817  // FIXME: Add support for forward-declared local symbols.
1818  // FIXME: Add expansion for when the LargeGOT option is enabled.
1819  if (JalSym->isInSection() || JalSym->isTemporary() ||
1820  (JalSym->isELF() && cast<MCSymbolELF>(JalSym)->getBinding() == ELF::STB_LOCAL)) {
1821  if (isABI_O32()) {
1822  // If it's a local symbol and the O32 ABI is being used, we expand to:
1823  // lw $25, 0($gp)
1824  // R_(MICRO)MIPS_GOT16 label
1825  // addiu $25, $25, 0
1826  // R_(MICRO)MIPS_LO16 label
1827  // jalr $25
1828  const MCExpr *Got16RelocExpr =
1829  MipsMCExpr::create(MipsMCExpr::MEK_GOT, JalExpr, getContext());
1830  const MCExpr *Lo16RelocExpr =
1831  MipsMCExpr::create(MipsMCExpr::MEK_LO, JalExpr, getContext());
1832 
1833  TOut.emitRRX(Mips::LW, Mips::T9, Mips::GP,
1834  MCOperand::createExpr(Got16RelocExpr), IDLoc, STI);
1835  TOut.emitRRX(Mips::ADDiu, Mips::T9, Mips::T9,
1836  MCOperand::createExpr(Lo16RelocExpr), IDLoc, STI);
1837  } else if (isABI_N32() || isABI_N64()) {
1838  // If it's a local symbol and the N32/N64 ABIs are being used,
1839  // we expand to:
1840  // lw/ld $25, 0($gp)
1841  // R_(MICRO)MIPS_GOT_DISP label
1842  // jalr $25
1843  const MCExpr *GotDispRelocExpr =
1844  MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP, JalExpr, getContext());
1845 
1846  TOut.emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9,
1847  Mips::GP, MCOperand::createExpr(GotDispRelocExpr), IDLoc,
1848  STI);
1849  }
1850  } else {
1851  // If it's an external/weak symbol, we expand to:
1852  // lw/ld $25, 0($gp)
1853  // R_(MICRO)MIPS_CALL16 label
1854  // jalr $25
1855  const MCExpr *Call16RelocExpr =
1856  MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, JalExpr, getContext());
1857 
1858  TOut.emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, Mips::GP,
1859  MCOperand::createExpr(Call16RelocExpr), IDLoc, STI);
1860  }
1861 
1862  MCInst JalrInst;
1863  if (IsCpRestoreSet && inMicroMipsMode())
1864  JalrInst.setOpcode(Mips::JALRS_MM);
1865  else
1866  JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1867  JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1868  JalrInst.addOperand(MCOperand::createReg(Mips::T9));
1869 
1870  // FIXME: Add an R_(MICRO)MIPS_JALR relocation after the JALR.
1871  // This relocation is supposed to be an optimization hint for the linker
1872  // and is not necessary for correctness.
1873 
1874  Inst = JalrInst;
1875  ExpandedJalSym = true;
1876  }
1877 
1878  bool IsPCRelativeLoad = (MCID.TSFlags & MipsII::IsPCRelativeLoad) != 0;
1879  if ((MCID.mayLoad() || MCID.mayStore()) && !IsPCRelativeLoad) {
1880  // Check the offset of memory operand, if it is a symbol
1881  // reference or immediate we may have to expand instructions.
1882  for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1883  const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1884  if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1885  (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1886  MCOperand &Op = Inst.getOperand(i);
1887  if (Op.isImm()) {
1888  int MemOffset = Op.getImm();
1889  if (MemOffset < -32768 || MemOffset > 32767) {
1890  // Offset can't exceed 16bit value.
1891  expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad(), true);
1892  return getParser().hasPendingError();
1893  }
1894  } else if (Op.isExpr()) {
1895  const MCExpr *Expr = Op.getExpr();
1896  if (Expr->getKind() == MCExpr::SymbolRef) {
1897  const MCSymbolRefExpr *SR =
1898  static_cast<const MCSymbolRefExpr *>(Expr);
1899  if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1900  // Expand symbol.
1901  expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad(), false);
1902  return getParser().hasPendingError();
1903  }
1904  } else if (!isEvaluated(Expr)) {
1905  expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad(), false);
1906  return getParser().hasPendingError();
1907  }
1908  }
1909  }
1910  } // for
1911  } // if load/store
1912 
1913  if (inMicroMipsMode()) {
1914  if (MCID.mayLoad()) {
1915  // Try to create 16-bit GP relative load instruction.
1916  for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1917  const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1918  if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1919  (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1920  MCOperand &Op = Inst.getOperand(i);
1921  if (Op.isImm()) {
1922  int MemOffset = Op.getImm();
1923  MCOperand &DstReg = Inst.getOperand(0);
1924  MCOperand &BaseReg = Inst.getOperand(1);
1925  if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
1926  getContext().getRegisterInfo()->getRegClass(
1927  Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1928  (BaseReg.getReg() == Mips::GP ||
1929  BaseReg.getReg() == Mips::GP_64)) {
1930 
1931  TOut.emitRRI(Mips::LWGP_MM, DstReg.getReg(), Mips::GP, MemOffset,
1932  IDLoc, STI);
1933  return false;
1934  }
1935  }
1936  }
1937  } // for
1938  } // if load
1939 
1940  // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1941 
1942  MCOperand Opnd;
1943  int Imm;
1944 
1945  switch (Inst.getOpcode()) {
1946  default:
1947  break;
1948  case Mips::ADDIUSP_MM:
1949  Opnd = Inst.getOperand(0);
1950  if (!Opnd.isImm())
1951  return Error(IDLoc, "expected immediate operand kind");
1952  Imm = Opnd.getImm();
1953  if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1954  Imm % 4 != 0)
1955  return Error(IDLoc, "immediate operand value out of range");
1956  break;
1957  case Mips::SLL16_MM:
1958  case Mips::SRL16_MM:
1959  Opnd = Inst.getOperand(2);
1960  if (!Opnd.isImm())
1961  return Error(IDLoc, "expected immediate operand kind");
1962  Imm = Opnd.getImm();
1963  if (Imm < 1 || Imm > 8)
1964  return Error(IDLoc, "immediate operand value out of range");
1965  break;
1966  case Mips::LI16_MM:
1967  Opnd = Inst.getOperand(1);
1968  if (!Opnd.isImm())
1969  return Error(IDLoc, "expected immediate operand kind");
1970  Imm = Opnd.getImm();
1971  if (Imm < -1 || Imm > 126)
1972  return Error(IDLoc, "immediate operand value out of range");
1973  break;
1974  case Mips::ADDIUR2_MM:
1975  Opnd = Inst.getOperand(2);
1976  if (!Opnd.isImm())
1977  return Error(IDLoc, "expected immediate operand kind");
1978  Imm = Opnd.getImm();
1979  if (!(Imm == 1 || Imm == -1 ||
1980  ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1981  return Error(IDLoc, "immediate operand value out of range");
1982  break;
1983  case Mips::ANDI16_MM:
1984  Opnd = Inst.getOperand(2);
1985  if (!Opnd.isImm())
1986  return Error(IDLoc, "expected immediate operand kind");
1987  Imm = Opnd.getImm();
1988  if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1989  Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1990  Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1991  return Error(IDLoc, "immediate operand value out of range");
1992  break;
1993  case Mips::LBU16_MM:
1994  Opnd = Inst.getOperand(2);
1995  if (!Opnd.isImm())
1996  return Error(IDLoc, "expected immediate operand kind");
1997  Imm = Opnd.getImm();
1998  if (Imm < -1 || Imm > 14)
1999  return Error(IDLoc, "immediate operand value out of range");
2000  break;
2001  case Mips::SB16_MM:
2002  case Mips::SB16_MMR6:
2003  Opnd = Inst.getOperand(2);
2004  if (!Opnd.isImm())
2005  return Error(IDLoc, "expected immediate operand kind");
2006  Imm = Opnd.getImm();
2007  if (Imm < 0 || Imm > 15)
2008  return Error(IDLoc, "immediate operand value out of range");
2009  break;
2010  case Mips::LHU16_MM:
2011  case Mips::SH16_MM:
2012  case Mips::SH16_MMR6:
2013  Opnd = Inst.getOperand(2);
2014  if (!Opnd.isImm())
2015  return Error(IDLoc, "expected immediate operand kind");
2016  Imm = Opnd.getImm();
2017  if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
2018  return Error(IDLoc, "immediate operand value out of range");
2019  break;
2020  case Mips::LW16_MM:
2021  case Mips::SW16_MM:
2022  case Mips::SW16_MMR6:
2023  Opnd = Inst.getOperand(2);
2024  if (!Opnd.isImm())
2025  return Error(IDLoc, "expected immediate operand kind");
2026  Imm = Opnd.getImm();
2027  if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
2028  return Error(IDLoc, "immediate operand value out of range");
2029  break;
2030  case Mips::ADDIUPC_MM:
2031  MCOperand Opnd = Inst.getOperand(1);
2032  if (!Opnd.isImm())
2033  return Error(IDLoc, "expected immediate operand kind");
2034  int Imm = Opnd.getImm();
2035  if ((Imm % 4 != 0) || !isInt<25>(Imm))
2036  return Error(IDLoc, "immediate operand value out of range");
2037  break;
2038  }
2039  }
2040 
2041  bool FillDelaySlot =
2042  MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder();
2043  if (FillDelaySlot)
2045 
2046  MacroExpanderResultTy ExpandResult =
2047  tryExpandInstruction(Inst, IDLoc, Out, STI);
2048  switch (ExpandResult) {
2049  case MER_NotAMacro:
2050  Out.EmitInstruction(Inst, *STI);
2051  break;
2052  case MER_Success:
2053  break;
2054  case MER_Fail:
2055  return true;
2056  }
2057 
2058  // We know we emitted an instruction on the MER_NotAMacro or MER_Success path.
2059  // If we're in microMIPS mode then we must also set EF_MIPS_MICROMIPS.
2060  if (inMicroMipsMode())
2061  TOut.setUsesMicroMips();
2062 
2063  // If this instruction has a delay slot and .set reorder is active,
2064  // emit a NOP after it.
2065  if (FillDelaySlot) {
2066  TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst.getOpcode()), IDLoc, STI);
2067  TOut.emitDirectiveSetReorder();
2068  }
2069 
2070  if ((Inst.getOpcode() == Mips::JalOneReg ||
2071  Inst.getOpcode() == Mips::JalTwoReg || ExpandedJalSym) &&
2072  isPicAndNotNxxAbi()) {
2073  if (IsCpRestoreSet) {
2074  // We need a NOP between the JALR and the LW:
2075  // If .set reorder has been used, we've already emitted a NOP.
2076  // If .set noreorder has been used, we need to emit a NOP at this point.
2077  if (!AssemblerOptions.back()->isReorder())
2078  TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst.getOpcode()), IDLoc,
2079  STI);
2080 
2081  // Load the $gp from the stack.
2082  TOut.emitGPRestore(CpRestoreOffset, IDLoc, STI);
2083  } else
2084  Warning(IDLoc, "no .cprestore used in PIC mode");
2085  }
2086 
2087  return false;
2088 }
2089 
2090 MipsAsmParser::MacroExpanderResultTy
2091 MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2092  const MCSubtargetInfo *STI) {
2093  switch (Inst.getOpcode()) {
2094  default:
2095  return MER_NotAMacro;
2096  case Mips::LoadImm32:
2097  return expandLoadImm(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2098  case Mips::LoadImm64:
2099  return expandLoadImm(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2100  case Mips::LoadAddrImm32:
2101  case Mips::LoadAddrImm64:
2102  assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2103  assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
2104  "expected immediate operand kind");
2105 
2106  return expandLoadAddress(Inst.getOperand(0).getReg(), Mips::NoRegister,
2107  Inst.getOperand(1),
2108  Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc,
2109  Out, STI)
2110  ? MER_Fail
2111  : MER_Success;
2112  case Mips::LoadAddrReg32:
2113  case Mips::LoadAddrReg64:
2114  assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2115  assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2116  assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
2117  "expected immediate operand kind");
2118 
2119  return expandLoadAddress(Inst.getOperand(0).getReg(),
2120  Inst.getOperand(1).getReg(), Inst.getOperand(2),
2121  Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc,
2122  Out, STI)
2123  ? MER_Fail
2124  : MER_Success;
2125  case Mips::B_MM_Pseudo:
2126  case Mips::B_MMR6_Pseudo:
2127  return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
2128  : MER_Success;
2129  case Mips::SWM_MM:
2130  case Mips::LWM_MM:
2131  return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
2132  : MER_Success;
2133  case Mips::JalOneReg:
2134  case Mips::JalTwoReg:
2135  return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2136  case Mips::BneImm:
2137  case Mips::BeqImm:
2138  return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2139  case Mips::BLT:
2140  case Mips::BLE:
2141  case Mips::BGE:
2142  case Mips::BGT:
2143  case Mips::BLTU:
2144  case Mips::BLEU:
2145  case Mips::BGEU:
2146  case Mips::BGTU:
2147  case Mips::BLTL:
2148  case Mips::BLEL:
2149  case Mips::BGEL:
2150  case Mips::BGTL:
2151  case Mips::BLTUL:
2152  case Mips::BLEUL:
2153  case Mips::BGEUL:
2154  case Mips::BGTUL:
2155  case Mips::BLTImmMacro:
2156  case Mips::BLEImmMacro:
2157  case Mips::BGEImmMacro:
2158  case Mips::BGTImmMacro:
2159  case Mips::BLTUImmMacro:
2160  case Mips::BLEUImmMacro:
2161  case Mips::BGEUImmMacro:
2162  case Mips::BGTUImmMacro:
2163  case Mips::BLTLImmMacro:
2164  case Mips::BLELImmMacro:
2165  case Mips::BGELImmMacro:
2166  case Mips::BGTLImmMacro:
2167  case Mips::BLTULImmMacro:
2168  case Mips::BLEULImmMacro:
2169  case Mips::BGEULImmMacro:
2170  case Mips::BGTULImmMacro:
2171  return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2172  case Mips::SDivMacro:
2173  return expandDiv(Inst, IDLoc, Out, STI, false, true) ? MER_Fail
2174  : MER_Success;
2175  case Mips::DSDivMacro:
2176  return expandDiv(Inst, IDLoc, Out, STI, true, true) ? MER_Fail
2177  : MER_Success;
2178  case Mips::UDivMacro:
2179  return expandDiv(Inst, IDLoc, Out, STI, false, false) ? MER_Fail
2180  : MER_Success;
2181  case Mips::DUDivMacro:
2182  return expandDiv(Inst, IDLoc, Out, STI, true, false) ? MER_Fail
2183  : MER_Success;
2184  case Mips::PseudoTRUNC_W_S:
2185  return expandTrunc(Inst, false, false, IDLoc, Out, STI) ? MER_Fail
2186  : MER_Success;
2187  case Mips::PseudoTRUNC_W_D32:
2188  return expandTrunc(Inst, true, false, IDLoc, Out, STI) ? MER_Fail
2189  : MER_Success;
2190  case Mips::PseudoTRUNC_W_D:
2191  return expandTrunc(Inst, true, true, IDLoc, Out, STI) ? MER_Fail
2192  : MER_Success;
2193  case Mips::Ulh:
2194  return expandUlh(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2195  case Mips::Ulhu:
2196  return expandUlh(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2197  case Mips::Ush:
2198  return expandUsh(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2199  case Mips::Ulw:
2200  case Mips::Usw:
2201  return expandUxw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2202  case Mips::NORImm:
2203  return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2204  case Mips::ADDi:
2205  case Mips::ADDiu:
2206  case Mips::SLTi:
2207  case Mips::SLTiu:
2208  if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2209  Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2210  int64_t ImmValue = Inst.getOperand(2).getImm();
2211  if (isInt<16>(ImmValue))
2212  return MER_NotAMacro;
2213  return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2214  : MER_Success;
2215  }
2216  return MER_NotAMacro;
2217  case Mips::ANDi:
2218  case Mips::ORi:
2219  case Mips::XORi:
2220  if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2221  Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2222  int64_t ImmValue = Inst.getOperand(2).getImm();
2223  if (isUInt<16>(ImmValue))
2224  return MER_NotAMacro;
2225  return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2226  : MER_Success;
2227  }
2228  return MER_NotAMacro;
2229  case Mips::ROL:
2230  case Mips::ROR:
2231  return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2232  case Mips::ROLImm:
2233  case Mips::RORImm:
2234  return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2235  case Mips::DROL:
2236  case Mips::DROR:
2237  return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2238  case Mips::DROLImm:
2239  case Mips::DRORImm:
2240  return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2241  case Mips::ABSMacro:
2242  return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2243  case Mips::LDMacro:
2244  case Mips::SDMacro:
2245  return expandLoadStoreDMacro(Inst, IDLoc, Out, STI,
2246  Inst.getOpcode() == Mips::LDMacro)
2247  ? MER_Fail
2248  : MER_Success;
2249  case Mips::SEQMacro:
2250  return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2251  case Mips::SEQIMacro:
2252  return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2253  }
2254 }
2255 
2256 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2257  MCStreamer &Out,
2258  const MCSubtargetInfo *STI) {
2259  MipsTargetStreamer &TOut = getTargetStreamer();
2260 
2261  // Create a JALR instruction which is going to replace the pseudo-JAL.
2262  MCInst JalrInst;
2263  JalrInst.setLoc(IDLoc);
2264  const MCOperand FirstRegOp = Inst.getOperand(0);
2265  const unsigned Opcode = Inst.getOpcode();
2266 
2267  if (Opcode == Mips::JalOneReg) {
2268  // jal $rs => jalr $rs
2269  if (IsCpRestoreSet && inMicroMipsMode()) {
2270  JalrInst.setOpcode(Mips::JALRS16_MM);
2271  JalrInst.addOperand(FirstRegOp);
2272  } else if (inMicroMipsMode()) {
2273  JalrInst.setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2274  JalrInst.addOperand(FirstRegOp);
2275  } else {
2276  JalrInst.setOpcode(Mips::JALR);
2277  JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2278  JalrInst.addOperand(FirstRegOp);
2279  }
2280  } else if (Opcode == Mips::JalTwoReg) {
2281  // jal $rd, $rs => jalr $rd, $rs
2282  if (IsCpRestoreSet && inMicroMipsMode())
2283  JalrInst.setOpcode(Mips::JALRS_MM);
2284  else
2285  JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2286  JalrInst.addOperand(FirstRegOp);
2287  const MCOperand SecondRegOp = Inst.getOperand(1);
2288  JalrInst.addOperand(SecondRegOp);
2289  }
2290  Out.EmitInstruction(JalrInst, *STI);
2291 
2292  // If .set reorder is active and branch instruction has a delay slot,
2293  // emit a NOP after it.
2294  const MCInstrDesc &MCID = getInstDesc(JalrInst.getOpcode());
2295  if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2296  TOut.emitEmptyDelaySlot(hasShortDelaySlot(JalrInst.getOpcode()), IDLoc,
2297  STI);
2298 
2299  return false;
2300 }
2301 
2302 /// Can the value be represented by a unsigned N-bit value and a shift left?
2303 template <unsigned N> static bool isShiftedUIntAtAnyPosition(uint64_t x) {
2304  unsigned BitNum = findFirstSet(x);
2305 
2306  return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
2307 }
2308 
2309 /// Load (or add) an immediate into a register.
2310 ///
2311 /// @param ImmValue The immediate to load.
2312 /// @param DstReg The register that will hold the immediate.
2313 /// @param SrcReg A register to add to the immediate or Mips::NoRegister
2314 /// for a simple initialization.
2315 /// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2316 /// @param IsAddress True if the immediate represents an address. False if it
2317 /// is an integer.
2318 /// @param IDLoc Location of the immediate in the source file.
2319 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2320  unsigned SrcReg, bool Is32BitImm,
2321  bool IsAddress, SMLoc IDLoc, MCStreamer &Out,
2322  const MCSubtargetInfo *STI) {
2323  MipsTargetStreamer &TOut = getTargetStreamer();
2324 
2325  if (!Is32BitImm && !isGP64bit()) {
2326  Error(IDLoc, "instruction requires a 64-bit architecture");
2327  return true;
2328  }
2329 
2330  if (Is32BitImm) {
2331  if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2332  // Sign extend up to 64-bit so that the predicates match the hardware
2333  // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2334  // true.
2335  ImmValue = SignExtend64<32>(ImmValue);
2336  } else {
2337  Error(IDLoc, "instruction requires a 32-bit immediate");
2338  return true;
2339  }
2340  }
2341 
2342  unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2343  unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2344 
2345  bool UseSrcReg = false;
2346  if (SrcReg != Mips::NoRegister)
2347  UseSrcReg = true;
2348 
2349  unsigned TmpReg = DstReg;
2350  if (UseSrcReg &&
2351  getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2352  // At this point we need AT to perform the expansions and we exit if it is
2353  // not available.
2354  unsigned ATReg = getATReg(IDLoc);
2355  if (!ATReg)
2356  return true;
2357  TmpReg = ATReg;
2358  }
2359 
2360  if (isInt<16>(ImmValue)) {
2361  if (!UseSrcReg)
2362  SrcReg = ZeroReg;
2363 
2364  // This doesn't quite follow the usual ABI expectations for N32 but matches
2365  // traditional assembler behaviour. N32 would normally use addiu for both
2366  // integers and addresses.
2367  if (IsAddress && !Is32BitImm) {
2368  TOut.emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2369  return false;
2370  }
2371 
2372  TOut.emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2373  return false;
2374  }
2375 
2376  if (isUInt<16>(ImmValue)) {
2377  unsigned TmpReg = DstReg;
2378  if (SrcReg == DstReg) {
2379  TmpReg = getATReg(IDLoc);
2380  if (!TmpReg)
2381  return true;
2382  }
2383 
2384  TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2385  if (UseSrcReg)
2386  TOut.emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2387  return false;
2388  }
2389 
2390  if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2391  warnIfNoMacro(IDLoc);
2392 
2393  uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2394  uint16_t Bits15To0 = ImmValue & 0xffff;
2395 
2396  if (!Is32BitImm && !isInt<32>(ImmValue)) {
2397  // Traditional behaviour seems to special case this particular value. It's
2398  // not clear why other masks are handled differently.
2399  if (ImmValue == 0xffffffff) {
2400  TOut.emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2401  TOut.emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2402  if (UseSrcReg)
2403  TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2404  return false;
2405  }
2406 
2407  // Expand to an ORi instead of a LUi to avoid sign-extending into the
2408  // upper 32 bits.
2409  TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2410  TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2411  if (Bits15To0)
2412  TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2413  if (UseSrcReg)
2414  TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2415  return false;
2416  }
2417 
2418  TOut.emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2419  if (Bits15To0)
2420  TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2421  if (UseSrcReg)
2422  TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2423  return false;
2424  }
2425 
2426  if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2427  if (Is32BitImm) {
2428  Error(IDLoc, "instruction requires a 32-bit immediate");
2429  return true;
2430  }
2431 
2432  // Traditionally, these immediates are shifted as little as possible and as
2433  // such we align the most significant bit to bit 15 of our temporary.
2434  unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
2435  unsigned LastSet = findLastSet((uint64_t)ImmValue);
2436  unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2437  uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2438  TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2439  TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2440 
2441  if (UseSrcReg)
2442  TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2443 
2444  return false;
2445  }
2446 
2447  warnIfNoMacro(IDLoc);
2448 
2449  // The remaining case is packed with a sequence of dsll and ori with zeros
2450  // being omitted and any neighbouring dsll's being coalesced.
2451  // The highest 32-bit's are equivalent to a 32-bit immediate load.
2452 
2453  // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2454  if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2455  IDLoc, Out, STI))
2456  return false;
2457 
2458  // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2459  // skip it and defer the shift to the next chunk.
2460  unsigned ShiftCarriedForwards = 16;
2461  for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2462  uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2463 
2464  if (ImmChunk != 0) {
2465  TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2466  TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2467  ShiftCarriedForwards = 0;
2468  }
2469 
2470  ShiftCarriedForwards += 16;
2471  }
2472  ShiftCarriedForwards -= 16;
2473 
2474  // Finish any remaining shifts left by trailing zeros.
2475  if (ShiftCarriedForwards)
2476  TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2477 
2478  if (UseSrcReg)
2479  TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2480 
2481  return false;
2482 }
2483 
2484 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2485  MCStreamer &Out, const MCSubtargetInfo *STI) {
2486  const MCOperand &ImmOp = Inst.getOperand(1);
2487  assert(ImmOp.isImm() && "expected immediate operand kind");
2488  const MCOperand &DstRegOp = Inst.getOperand(0);
2489  assert(DstRegOp.isReg() && "expected register operand kind");
2490 
2491  if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2492  Is32BitImm, false, IDLoc, Out, STI))
2493  return true;
2494 
2495  return false;
2496 }
2497 
2498 bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2499  const MCOperand &Offset,
2500  bool Is32BitAddress, SMLoc IDLoc,
2501  MCStreamer &Out,
2502  const MCSubtargetInfo *STI) {
2503  // la can't produce a usable address when addresses are 64-bit.
2504  if (Is32BitAddress && ABI.ArePtrs64bit()) {
2505  // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
2506  // We currently can't do this because we depend on the equality
2507  // operator and N64 can end up with a GPR32/GPR64 mismatch.
2508  Error(IDLoc, "la used to load 64-bit address");
2509  // Continue as if we had 'dla' instead.
2510  Is32BitAddress = false;
2511  return true;
2512  }
2513 
2514  // dla requires 64-bit addresses.
2515  if (!Is32BitAddress && !hasMips3()) {
2516  Error(IDLoc, "instruction requires a 64-bit architecture");
2517  return true;
2518  }
2519 
2520  if (!Offset.isImm())
2521  return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2522  Is32BitAddress, IDLoc, Out, STI);
2523 
2524  if (!ABI.ArePtrs64bit()) {
2525  // Continue as if we had 'la' whether we had 'la' or 'dla'.
2526  Is32BitAddress = true;
2527  }
2528 
2529  return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2530  IDLoc, Out, STI);
2531 }
2532 
2533 bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr,
2534  unsigned DstReg, unsigned SrcReg,
2535  bool Is32BitSym, SMLoc IDLoc,
2536  MCStreamer &Out,
2537  const MCSubtargetInfo *STI) {
2538  MipsTargetStreamer &TOut = getTargetStreamer();
2539  bool UseSrcReg = SrcReg != Mips::NoRegister;
2540  warnIfNoMacro(IDLoc);
2541 
2542  if (inPicMode() && ABI.IsO32()) {
2543  MCValue Res;
2544  if (!SymExpr->evaluateAsRelocatable(Res, nullptr, nullptr)) {
2545  Error(IDLoc, "expected relocatable expression");
2546  return true;
2547  }
2548  if (Res.getSymB() != nullptr) {
2549  Error(IDLoc, "expected relocatable expression with only one symbol");
2550  return true;
2551  }
2552 
2553  // The case where the result register is $25 is somewhat special. If the
2554  // symbol in the final relocation is external and not modified with a
2555  // constant then we must use R_MIPS_CALL16 instead of R_MIPS_GOT16.
2556  if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2557  Res.getConstant() == 0 && !Res.getSymA()->getSymbol().isInSection() &&
2558  !Res.getSymA()->getSymbol().isTemporary()) {
2559  const MCExpr *CallExpr =
2560  MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, SymExpr, getContext());
2561  TOut.emitRRX(Mips::LW, DstReg, ABI.GetGlobalPtr(),
2562  MCOperand::createExpr(CallExpr), IDLoc, STI);
2563  return false;
2564  }
2565 
2566  // The remaining cases are:
2567  // External GOT: lw $tmp, %got(symbol+offset)($gp)
2568  // >addiu $tmp, $tmp, %lo(offset)
2569  // >addiu $rd, $tmp, $rs
2570  // Local GOT: lw $tmp, %got(symbol+offset)($gp)
2571  // addiu $tmp, $tmp, %lo(symbol+offset)($gp)
2572  // >addiu $rd, $tmp, $rs
2573  // The addiu's marked with a '>' may be omitted if they are redundant. If
2574  // this happens then the last instruction must use $rd as the result
2575  // register.
2576  const MipsMCExpr *GotExpr =
2577  MipsMCExpr::create(MipsMCExpr::MEK_GOT, SymExpr, getContext());
2578  const MCExpr *LoExpr = nullptr;
2579  if (Res.getSymA()->getSymbol().isInSection() ||
2580  Res.getSymA()->getSymbol().isTemporary())
2581  LoExpr = MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
2582  else if (Res.getConstant() != 0) {
2583  // External symbols fully resolve the symbol with just the %got(symbol)
2584  // but we must still account for any offset to the symbol for expressions
2585  // like symbol+8.
2586  LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
2587  }
2588 
2589  unsigned TmpReg = DstReg;
2590  if (UseSrcReg &&
2591  getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2592  SrcReg)) {
2593  // If $rs is the same as $rd, we need to use AT.
2594  // If it is not available we exit.
2595  unsigned ATReg = getATReg(IDLoc);
2596  if (!ATReg)
2597  return true;
2598  TmpReg = ATReg;
2599  }
2600 
2601  TOut.emitRRX(Mips::LW, TmpReg, ABI.GetGlobalPtr(),
2602  MCOperand::createExpr(GotExpr), IDLoc, STI);
2603 
2604  if (LoExpr)
2605  TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
2606  IDLoc, STI);
2607 
2608  if (UseSrcReg)
2609  TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
2610 
2611  return false;
2612  }
2613 
2614  const MipsMCExpr *HiExpr =
2615  MipsMCExpr::create(MipsMCExpr::MEK_HI, SymExpr, getContext());
2616  const MipsMCExpr *LoExpr =
2617  MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
2618 
2619  // This is the 64-bit symbol address expansion.
2620  if (ABI.ArePtrs64bit() && isGP64bit()) {
2621  // We always need AT for the 64-bit expansion.
2622  // If it is not available we exit.
2623  unsigned ATReg = getATReg(IDLoc);
2624  if (!ATReg)
2625  return true;
2626 
2627  const MipsMCExpr *HighestExpr =
2628  MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, SymExpr, getContext());
2629  const MipsMCExpr *HigherExpr =
2630  MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, SymExpr, getContext());
2631 
2632  if (UseSrcReg &&
2633  getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2634  SrcReg)) {
2635  // If $rs is the same as $rd:
2636  // (d)la $rd, sym($rd) => lui $at, %highest(sym)
2637  // daddiu $at, $at, %higher(sym)
2638  // dsll $at, $at, 16
2639  // daddiu $at, $at, %hi(sym)
2640  // dsll $at, $at, 16
2641  // daddiu $at, $at, %lo(sym)
2642  // daddu $rd, $at, $rd
2643  TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
2644  STI);
2645  TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
2646  MCOperand::createExpr(HigherExpr), IDLoc, STI);
2647  TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
2648  TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
2649  IDLoc, STI);
2650  TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
2651  TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
2652  IDLoc, STI);
2653  TOut.emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
2654 
2655  return false;
2656  }
2657 
2658  // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2659  // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
2660  // lui $at, %hi(sym)
2661  // daddiu $rd, $rd, %higher(sym)
2662  // daddiu $at, $at, %lo(sym)
2663  // dsll32 $rd, $rd, 0
2664  // daddu $rd, $rd, $at
2665  // (daddu $rd, $rd, $rs)
2666  TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
2667  STI);
2668  TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
2669  TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
2670  MCOperand::createExpr(HigherExpr), IDLoc, STI);
2671  TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
2672  IDLoc, STI);
2673  TOut.emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
2674  TOut.emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
2675  if (UseSrcReg)
2676  TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
2677 
2678  return false;
2679  }
2680 
2681  // And now, the 32-bit symbol address expansion:
2682  // If $rs is the same as $rd:
2683  // (d)la $rd, sym($rd) => lui $at, %hi(sym)
2684  // ori $at, $at, %lo(sym)
2685  // addu $rd, $at, $rd
2686  // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2687  // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
2688  // ori $rd, $rd, %lo(sym)
2689  // (addu $rd, $rd, $rs)
2690  unsigned TmpReg = DstReg;
2691  if (UseSrcReg &&
2692  getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2693  // If $rs is the same as $rd, we need to use AT.
2694  // If it is not available we exit.
2695  unsigned ATReg = getATReg(IDLoc);
2696  if (!ATReg)
2697  return true;
2698  TmpReg = ATReg;
2699  }
2700 
2701  TOut.emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
2702  TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
2703  IDLoc, STI);
2704 
2705  if (UseSrcReg)
2706  TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
2707  else
2708  assert(
2709  getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
2710 
2711  return false;
2712 }
2713 
2714 bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
2715  MCStreamer &Out,
2716  const MCSubtargetInfo *STI) {
2717  MipsTargetStreamer &TOut = getTargetStreamer();
2718 
2719  assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
2720  "unexpected number of operands");
2721 
2722  MCOperand Offset = Inst.getOperand(0);
2723  if (Offset.isExpr()) {
2724  Inst.clear();
2725  Inst.setOpcode(Mips::BEQ_MM);
2726  Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2727  Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2728  Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2729  } else {
2730  assert(Offset.isImm() && "expected immediate operand kind");
2731  if (isInt<11>(Offset.getImm())) {
2732  // If offset fits into 11 bits then this instruction becomes microMIPS
2733  // 16-bit unconditional branch instruction.
2734  if (inMicroMipsMode())
2735  Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
2736  } else {
2737  if (!isInt<17>(Offset.getImm()))
2738  return Error(IDLoc, "branch target out of range");
2739  if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2740  return Error(IDLoc, "branch to misaligned address");
2741  Inst.clear();
2742  Inst.setOpcode(Mips::BEQ_MM);
2743  Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2744  Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2745  Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2746  }
2747  }
2748  Out.EmitInstruction(Inst, *STI);
2749 
2750  // If .set reorder is active and branch instruction has a delay slot,
2751  // emit a NOP after it.
2752  const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
2753  if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2754  TOut.emitEmptyDelaySlot(true, IDLoc, STI);
2755 
2756  return false;
2757 }
2758 
2759 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2760  const MCSubtargetInfo *STI) {
2761  MipsTargetStreamer &TOut = getTargetStreamer();
2762  const MCOperand &DstRegOp = Inst.getOperand(0);
2763  assert(DstRegOp.isReg() && "expected register operand kind");
2764 
2765  const MCOperand &ImmOp = Inst.getOperand(1);
2766  assert(ImmOp.isImm() && "expected immediate operand kind");
2767 
2768  const MCOperand &MemOffsetOp = Inst.getOperand(2);
2769  assert((MemOffsetOp.isImm() || MemOffsetOp.isExpr()) &&
2770  "expected immediate or expression operand");
2771 
2772  unsigned OpCode = 0;
2773  switch(Inst.getOpcode()) {
2774  case Mips::BneImm:
2775  OpCode = Mips::BNE;
2776  break;
2777  case Mips::BeqImm:
2778  OpCode = Mips::BEQ;
2779  break;
2780  default:
2781  llvm_unreachable("Unknown immediate branch pseudo-instruction.");
2782  break;
2783  }
2784 
2785  int64_t ImmValue = ImmOp.getImm();
2786  if (ImmValue == 0)
2787  TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
2788  STI);
2789  else {
2790  warnIfNoMacro(IDLoc);
2791 
2792  unsigned ATReg = getATReg(IDLoc);
2793  if (!ATReg)
2794  return true;
2795 
2796  if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
2797  IDLoc, Out, STI))
2798  return true;
2799 
2800  TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, STI);
2801  }
2802  return false;
2803 }
2804 
2805 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2806  const MCSubtargetInfo *STI, bool IsLoad,
2807  bool IsImmOpnd) {
2808  if (IsLoad) {
2809  expandLoadInst(Inst, IDLoc, Out, STI, IsImmOpnd);
2810  return;
2811  }
2812  expandStoreInst(Inst, IDLoc, Out, STI, IsImmOpnd);
2813 }
2814 
2815 void MipsAsmParser::expandLoadInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2816  const MCSubtargetInfo *STI, bool IsImmOpnd) {
2817  MipsTargetStreamer &TOut = getTargetStreamer();
2818 
2819  unsigned DstReg = Inst.getOperand(0).getReg();
2820  unsigned BaseReg = Inst.getOperand(1).getReg();
2821 
2822  const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2823  int16_t DstRegClass = Desc.OpInfo[0].RegClass;
2824  unsigned DstRegClassID =
2825  getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
2826  bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
2827  (DstRegClassID == Mips::GPR64RegClassID);
2828 
2829  if (IsImmOpnd) {
2830  // Try to use DstReg as the temporary.
2831  if (IsGPR && (BaseReg != DstReg)) {
2832  TOut.emitLoadWithImmOffset(Inst.getOpcode(), DstReg, BaseReg,
2833  Inst.getOperand(2).getImm(), DstReg, IDLoc,
2834  STI);
2835  return;
2836  }
2837 
2838  // At this point we need AT to perform the expansions and we exit if it is
2839  // not available.
2840  unsigned ATReg = getATReg(IDLoc);
2841  if (!ATReg)
2842  return;
2843 
2844  TOut.emitLoadWithImmOffset(Inst.getOpcode(), DstReg, BaseReg,
2845  Inst.getOperand(2).getImm(), ATReg, IDLoc, STI);
2846  return;
2847  }
2848 
2849  const MCExpr *ExprOffset = Inst.getOperand(2).getExpr();
2850  MCOperand LoOperand = MCOperand::createExpr(
2851  MipsMCExpr::create(MipsMCExpr::MEK_LO, ExprOffset, getContext()));
2852  MCOperand HiOperand = MCOperand::createExpr(
2853  MipsMCExpr::create(MipsMCExpr::MEK_HI, ExprOffset, getContext()));
2854 
2855  // Try to use DstReg as the temporary.
2856  if (IsGPR && (BaseReg != DstReg)) {
2857  TOut.emitLoadWithSymOffset(Inst.getOpcode(), DstReg, BaseReg, HiOperand,
2858  LoOperand, DstReg, IDLoc, STI);
2859  return;
2860  }
2861 
2862  // At this point we need AT to perform the expansions and we exit if it is
2863  // not available.
2864  unsigned ATReg = getATReg(IDLoc);
2865  if (!ATReg)
2866  return;
2867 
2868  TOut.emitLoadWithSymOffset(Inst.getOpcode(), DstReg, BaseReg, HiOperand,
2869  LoOperand, ATReg, IDLoc, STI);
2870 }
2871 
2872 void MipsAsmParser::expandStoreInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2873  const MCSubtargetInfo *STI,
2874  bool IsImmOpnd) {
2875  MipsTargetStreamer &TOut = getTargetStreamer();
2876 
2877  unsigned SrcReg = Inst.getOperand(0).getReg();
2878  unsigned BaseReg = Inst.getOperand(1).getReg();
2879 
2880  if (IsImmOpnd) {
2881  TOut.emitStoreWithImmOffset(Inst.getOpcode(), SrcReg, BaseReg,
2882  Inst.getOperand(2).getImm(),
2883  [&]() { return getATReg(IDLoc); }, IDLoc, STI);
2884  return;
2885  }
2886 
2887  unsigned ATReg = getATReg(IDLoc);
2888  if (!ATReg)
2889  return;
2890 
2891  const MCExpr *ExprOffset = Inst.getOperand(2).getExpr();
2892  MCOperand LoOperand = MCOperand::createExpr(
2893  MipsMCExpr::create(MipsMCExpr::MEK_LO, ExprOffset, getContext()));
2894  MCOperand HiOperand = MCOperand::createExpr(
2895  MipsMCExpr::create(MipsMCExpr::MEK_HI, ExprOffset, getContext()));
2896  TOut.emitStoreWithSymOffset(Inst.getOpcode(), SrcReg, BaseReg, HiOperand,
2897  LoOperand, ATReg, IDLoc, STI);
2898 }
2899 
2900 bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2901  MCStreamer &Out,
2902  const MCSubtargetInfo *STI) {
2903  unsigned OpNum = Inst.getNumOperands();
2904  unsigned Opcode = Inst.getOpcode();
2905  unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2906 
2907  assert (Inst.getOperand(OpNum - 1).isImm() &&
2908  Inst.getOperand(OpNum - 2).isReg() &&
2909  Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2910 
2911  if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2912  Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2913  (Inst.getOperand(OpNum - 2).getReg() == Mips::SP ||
2914  Inst.getOperand(OpNum - 2).getReg() == Mips::SP_64) &&
2915  (Inst.getOperand(OpNum - 3).getReg() == Mips::RA ||
2916  Inst.getOperand(OpNum - 3).getReg() == Mips::RA_64)) {
2917  // It can be implemented as SWM16 or LWM16 instruction.
2918  if (inMicroMipsMode() && hasMips32r6())
2919  NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
2920  else
2921  NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2922  }
2923 
2924  Inst.setOpcode(NewOpcode);
2925  Out.EmitInstruction(Inst, *STI);
2926  return false;
2927 }
2928 
2929 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
2930  MCStreamer &Out,
2931  const MCSubtargetInfo *STI) {
2932  MipsTargetStreamer &TOut = getTargetStreamer();
2933  bool EmittedNoMacroWarning = false;
2934  unsigned PseudoOpcode = Inst.getOpcode();
2935  unsigned SrcReg = Inst.getOperand(0).getReg();
2936  const MCOperand &TrgOp = Inst.getOperand(1);
2937  const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
2938 
2939  unsigned ZeroSrcOpcode, ZeroTrgOpcode;
2940  bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
2941 
2942  unsigned TrgReg;
2943  if (TrgOp.isReg())
2944  TrgReg = TrgOp.getReg();
2945  else if (TrgOp.isImm()) {
2946  warnIfNoMacro(IDLoc);
2947  EmittedNoMacroWarning = true;
2948 
2949  TrgReg = getATReg(IDLoc);
2950  if (!TrgReg)
2951  return true;
2952 
2953  switch(PseudoOpcode) {
2954  default:
2955  llvm_unreachable("unknown opcode for branch pseudo-instruction");
2956  case Mips::BLTImmMacro:
2957  PseudoOpcode = Mips::BLT;
2958  break;
2959  case Mips::BLEImmMacro:
2960  PseudoOpcode = Mips::BLE;
2961  break;
2962  case Mips::BGEImmMacro:
2963  PseudoOpcode = Mips::BGE;
2964  break;
2965  case Mips::BGTImmMacro:
2966  PseudoOpcode = Mips::BGT;
2967  break;
2968  case Mips::BLTUImmMacro:
2969  PseudoOpcode = Mips::BLTU;
2970  break;
2971  case Mips::BLEUImmMacro:
2972  PseudoOpcode = Mips::BLEU;
2973  break;
2974  case Mips::BGEUImmMacro:
2975  PseudoOpcode = Mips::BGEU;
2976  break;
2977  case Mips::BGTUImmMacro:
2978  PseudoOpcode = Mips::BGTU;
2979  break;
2980  case Mips::BLTLImmMacro:
2981  PseudoOpcode = Mips::BLTL;
2982  break;
2983  case Mips::BLELImmMacro:
2984  PseudoOpcode = Mips::BLEL;
2985  break;
2986  case Mips::BGELImmMacro:
2987  PseudoOpcode = Mips::BGEL;
2988  break;
2989  case Mips::BGTLImmMacro:
2990  PseudoOpcode = Mips::BGTL;
2991  break;
2992  case Mips::BLTULImmMacro:
2993  PseudoOpcode = Mips::BLTUL;
2994  break;
2995  case Mips::BLEULImmMacro:
2996  PseudoOpcode = Mips::BLEUL;
2997  break;
2998  case Mips::BGEULImmMacro:
2999  PseudoOpcode = Mips::BGEUL;
3000  break;
3001  case Mips::BGTULImmMacro:
3002  PseudoOpcode = Mips::BGTUL;
3003  break;
3004  }
3005 
3006  if (loadImmediate(TrgOp.getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
3007  false, IDLoc, Out, STI))
3008  return true;
3009  }
3010 
3011  switch (PseudoOpcode) {
3012  case Mips::BLT:
3013  case Mips::BLTU:
3014  case Mips::BLTL:
3015  case Mips::BLTUL:
3016  AcceptsEquality = false;
3017  ReverseOrderSLT = false;
3018  IsUnsigned = ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
3019  IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
3020  ZeroSrcOpcode = Mips::BGTZ;
3021  ZeroTrgOpcode = Mips::BLTZ;
3022  break;
3023  case Mips::BLE:
3024  case Mips::BLEU:
3025  case Mips::BLEL:
3026  case Mips::BLEUL:
3027  AcceptsEquality = true;
3028  ReverseOrderSLT = true;
3029  IsUnsigned = ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
3030  IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
3031  ZeroSrcOpcode = Mips::BGEZ;
3032  ZeroTrgOpcode = Mips::BLEZ;
3033  break;
3034  case Mips::BGE:
3035  case Mips::BGEU:
3036  case Mips::BGEL:
3037  case Mips::BGEUL:
3038  AcceptsEquality = true;
3039  ReverseOrderSLT = false;
3040  IsUnsigned = ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
3041  IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
3042  ZeroSrcOpcode = Mips::BLEZ;
3043  ZeroTrgOpcode = Mips::BGEZ;
3044  break;
3045  case Mips::BGT:
3046  case Mips::BGTU:
3047  case Mips::BGTL:
3048  case Mips::BGTUL:
3049  AcceptsEquality = false;
3050  ReverseOrderSLT = true;
3051  IsUnsigned = ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
3052  IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
3053  ZeroSrcOpcode = Mips::BLTZ;
3054  ZeroTrgOpcode = Mips::BGTZ;
3055  break;
3056  default:
3057  llvm_unreachable("unknown opcode for branch pseudo-instruction");
3058  }
3059 
3060  bool IsTrgRegZero = (TrgReg == Mips::ZERO);
3061  bool IsSrcRegZero = (SrcReg == Mips::ZERO);
3062  if (IsSrcRegZero && IsTrgRegZero) {
3063  // FIXME: All of these Opcode-specific if's are needed for compatibility
3064  // with GAS' behaviour. However, they may not generate the most efficient
3065  // code in some circumstances.
3066  if (PseudoOpcode == Mips::BLT) {
3067  TOut.emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3068  IDLoc, STI);
3069  return false;
3070  }
3071  if (PseudoOpcode == Mips::BLE) {
3072  TOut.emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3073  IDLoc, STI);
3074  Warning(IDLoc, "branch is always taken");
3075  return false;
3076  }
3077  if (PseudoOpcode == Mips::BGE) {
3078  TOut.emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3079  IDLoc, STI);
3080  Warning(IDLoc, "branch is always taken");
3081  return false;
3082  }
3083  if (PseudoOpcode == Mips::BGT) {
3084  TOut.emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
3085  IDLoc, STI);
3086  return false;
3087  }
3088  if (PseudoOpcode == Mips::BGTU) {
3089  TOut.emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
3090  MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3091  return false;
3092  }
3093  if (AcceptsEquality) {
3094  // If both registers are $0 and the pseudo-branch accepts equality, it
3095  // will always be taken, so we emit an unconditional branch.
3096  TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
3097  MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3098  Warning(IDLoc, "branch is always taken");
3099  return false;
3100  }
3101  // If both registers are $0 and the pseudo-branch does not accept
3102  // equality, it will never be taken, so we don't have to emit anything.
3103  return false;
3104  }
3105  if (IsSrcRegZero || IsTrgRegZero) {
3106  if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
3107  (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
3108  // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
3109  // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
3110  // the pseudo-branch will never be taken, so we don't emit anything.
3111  // This only applies to unsigned pseudo-branches.
3112  return false;
3113  }
3114  if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
3115  (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
3116  // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
3117  // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
3118  // the pseudo-branch will always be taken, so we emit an unconditional
3119  // branch.
3120  // This only applies to unsigned pseudo-branches.
3121  TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
3122  MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3123  Warning(IDLoc, "branch is always taken");
3124  return false;
3125  }
3126  if (IsUnsigned) {
3127  // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
3128  // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
3129  // the pseudo-branch will be taken only when the non-zero register is
3130  // different from 0, so we emit a BNEZ.
3131  //
3132  // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
3133  // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
3134  // the pseudo-branch will be taken only when the non-zero register is
3135  // equal to 0, so we emit a BEQZ.
3136  //
3137  // Because only BLEU and BGEU branch on equality, we can use the
3138  // AcceptsEquality variable to decide when to emit the BEQZ.
3139  TOut.emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
3140  IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
3141  MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3142  return false;
3143  }
3144  // If we have a signed pseudo-branch and one of the registers is $0,
3145  // we can use an appropriate compare-to-zero branch. We select which one
3146  // to use in the switch statement above.
3147  TOut.emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
3148  IsSrcRegZero ? TrgReg : SrcReg,
3149  MCOperand::createExpr(OffsetExpr), IDLoc, STI);
3150  return false;
3151  }
3152 
3153  // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
3154  // expansions. If it is not available, we return.
3155  unsigned ATRegNum = getATReg(IDLoc);
3156  if (!ATRegNum)
3157  return true;
3158 
3159  if (!EmittedNoMacroWarning)
3160  warnIfNoMacro(IDLoc);
3161 
3162  // SLT fits well with 2 of our 4 pseudo-branches:
3163  // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
3164  // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
3165  // If the result of the SLT is 1, we branch, and if it's 0, we don't.
3166  // This is accomplished by using a BNEZ with the result of the SLT.
3167  //
3168  // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
3169  // and BLE with BGT), so we change the BNEZ into a a BEQZ.
3170  // Because only BGE and BLE branch on equality, we can use the
3171  // AcceptsEquality variable to decide when to emit the BEQZ.
3172  // Note that the order of the SLT arguments doesn't change between
3173  // opposites.
3174  //
3175  // The same applies to the unsigned variants, except that SLTu is used
3176  // instead of SLT.
3177  TOut.emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
3178  ReverseOrderSLT ? TrgReg : SrcReg,
3179  ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
3180 
3181  TOut.emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
3182  : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
3183  ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
3184  STI);
3185  return false;
3186 }
3187 
3188 bool MipsAsmParser::expandDiv(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3189  const MCSubtargetInfo *STI, const bool IsMips64,
3190  const bool Signed) {
3191  MipsTargetStreamer &TOut = getTargetStreamer();
3192 
3193  warnIfNoMacro(IDLoc);
3194 
3195  const MCOperand &RdRegOp = Inst.getOperand(0);
3196  assert(RdRegOp.isReg() && "expected register operand kind");
3197  unsigned RdReg = RdRegOp.getReg();
3198 
3199  const MCOperand &RsRegOp = Inst.getOperand(1);
3200  assert(RsRegOp.isReg() && "expected register operand kind");
3201  unsigned RsReg = RsRegOp.getReg();
3202 
3203  const MCOperand &RtRegOp = Inst.getOperand(2);
3204  assert(RtRegOp.isReg() && "expected register operand kind");
3205  unsigned RtReg = RtRegOp.getReg();
3206  unsigned DivOp;
3207  unsigned ZeroReg;
3208 
3209  if (IsMips64) {
3210  DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
3211  ZeroReg = Mips::ZERO_64;
3212  } else {
3213  DivOp = Signed ? Mips::SDIV : Mips::UDIV;
3214  ZeroReg = Mips::ZERO;
3215  }
3216 
3217  bool UseTraps = useTraps();
3218 
3219  if (RsReg == Mips::ZERO || RsReg == Mips::ZERO_64) {
3220  if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)
3221  Warning(IDLoc, "dividing zero by zero");
3222  if (IsMips64) {
3223  if (Signed && (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)) {
3224  if (UseTraps) {
3225  TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
3226  return false;
3227  }
3228 
3229  TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
3230  return false;
3231  }
3232  } else {
3233  TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
3234  return false;
3235  }
3236  }
3237 
3238  if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
3239  Warning(IDLoc, "division by zero");
3240  if (Signed) {
3241  if (UseTraps) {
3242  TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
3243  return false;
3244  }
3245 
3246  TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
3247  return false;
3248  }
3249  }
3250 
3251  // FIXME: The values for these two BranchTarget variables may be different in
3252  // micromips. These magic numbers need to be removed.
3253  unsigned BranchTargetNoTraps;
3254  unsigned BranchTarget;
3255 
3256  if (UseTraps) {
3257  BranchTarget = IsMips64 ? 12 : 8;
3258  TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
3259  } else {
3260  BranchTarget = IsMips64 ? 20 : 16;
3261  BranchTargetNoTraps = 8;
3262  // Branch to the li instruction.
3263  TOut.emitRRI(Mips::BNE, RtReg, ZeroReg, BranchTargetNoTraps, IDLoc, STI);
3264  }
3265 
3266  TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
3267 
3268  if (!UseTraps)
3269  TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
3270 
3271  if (!Signed) {
3272  TOut.emitR(Mips::MFLO, RdReg, IDLoc, STI);
3273  return false;
3274  }
3275 
3276  unsigned ATReg = getATReg(IDLoc);
3277  if (!ATReg)
3278  return true;
3279 
3280  TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, STI);
3281  if (IsMips64) {
3282  // Branch to the mflo instruction.
3283  TOut.emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, STI);
3284  TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, STI);
3285  TOut.emitRRI(Mips::DSLL32, ATReg, ATReg, 0x1f, IDLoc, STI);
3286  } else {
3287  // Branch to the mflo instruction.
3288  TOut.emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, STI);
3289  TOut.emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, STI);
3290  }
3291 
3292  if (UseTraps)
3293  TOut.emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, STI);
3294  else {
3295  // Branch to the mflo instruction.
3296  TOut.emitRRI(Mips::BNE, RsReg, ATReg, BranchTargetNoTraps, IDLoc, STI);
3297  TOut.emitRRI(Mips::SLL, ZeroReg, ZeroReg, 0, IDLoc, STI);
3298  TOut.emitII(Mips::BREAK, 0x6, 0, IDLoc, STI);
3299  }
3300  TOut.emitR(Mips::MFLO, RdReg, IDLoc, STI);
3301  return false;
3302 }
3303 
3304 bool MipsAsmParser::expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU,
3305  SMLoc IDLoc, MCStreamer &Out,
3306  const MCSubtargetInfo *STI) {
3307  MipsTargetStreamer &TOut = getTargetStreamer();
3308 
3309  assert(Inst.getNumOperands() == 3 && "Invalid operand count");
3310  assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() &&
3311  Inst.getOperand(2).isReg() && "Invalid instruction operand.");
3312 
3313  unsigned FirstReg = Inst.getOperand(0).getReg();
3314  unsigned SecondReg = Inst.getOperand(1).getReg();
3315  unsigned ThirdReg = Inst.getOperand(2).getReg();
3316 
3317  if (hasMips1() && !hasMips2()) {
3318  unsigned ATReg = getATReg(IDLoc);
3319  if (!ATReg)
3320  return true;
3321  TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
3322  TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
3323  TOut.emitNop(IDLoc, STI);
3324  TOut.emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
3325  TOut.emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
3326  TOut.emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
3327  TOut.emitNop(IDLoc, STI);
3328  TOut.emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
3329  : Mips::CVT_W_S,
3330  FirstReg, SecondReg, IDLoc, STI);
3331  TOut.emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
3332  TOut.emitNop(IDLoc, STI);
3333  return false;
3334  }
3335 
3336  TOut.emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
3337  : Mips::TRUNC_W_S,
3338  FirstReg, SecondReg, IDLoc, STI);
3339 
3340  return false;
3341 }
3342 
3343 bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
3344  MCStreamer &Out, const MCSubtargetInfo *STI) {
3345  if (hasMips32r6() || hasMips64r6()) {
3346  return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3347  }
3348 
3349  const MCOperand &DstRegOp = Inst.getOperand(0);
3350  assert(DstRegOp.isReg() && "expected register operand kind");
3351  const MCOperand &SrcRegOp = Inst.getOperand(1);
3352  assert(SrcRegOp.isReg() && "expected register operand kind");
3353  const MCOperand &OffsetImmOp = Inst.getOperand(2);
3354  assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3355 
3356  MipsTargetStreamer &TOut = getTargetStreamer();
3357  unsigned DstReg = DstRegOp.getReg();
3358  unsigned SrcReg = SrcRegOp.getReg();
3359  int64_t OffsetValue = OffsetImmOp.getImm();
3360 
3361  // NOTE: We always need AT for ULHU, as it is always used as the source
3362  // register for one of the LBu's.
3363  warnIfNoMacro(IDLoc);
3364  unsigned ATReg = getATReg(IDLoc);
3365  if (!ATReg)
3366  return true;
3367 
3368  bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
3369  if (IsLargeOffset) {
3370  if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
3371  IDLoc, Out, STI))
3372  return true;
3373  }
3374 
3375  int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
3376  int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
3377  if (isLittle())
3378  std::swap(FirstOffset, SecondOffset);
3379 
3380  unsigned FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
3381  unsigned SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
3382 
3383  unsigned LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
3384  unsigned SllReg = IsLargeOffset ? DstReg : ATReg;
3385 
3386  TOut.emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
3387  FirstOffset, IDLoc, STI);
3388  TOut.emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
3389  TOut.emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
3390  TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
3391 
3392  return false;
3393 }
3394 
3395 bool MipsAsmParser::expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3396  const MCSubtargetInfo *STI) {
3397  if (hasMips32r6() || hasMips64r6()) {
3398  return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3399  }
3400 
3401  const MCOperand &DstRegOp = Inst.getOperand(0);
3402  assert(DstRegOp.isReg() && "expected register operand kind");
3403  const MCOperand &SrcRegOp = Inst.getOperand(1);
3404  assert(SrcRegOp.isReg() && "expected register operand kind");
3405  const MCOperand &OffsetImmOp = Inst.getOperand(2);
3406  assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3407 
3408  MipsTargetStreamer &TOut = getTargetStreamer();
3409  unsigned DstReg = DstRegOp.getReg();
3410  unsigned SrcReg = SrcRegOp.getReg();
3411  int64_t OffsetValue = OffsetImmOp.getImm();
3412 
3413  warnIfNoMacro(IDLoc);
3414  unsigned ATReg = getATReg(IDLoc);
3415  if (!ATReg)
3416  return true;
3417 
3418  bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
3419  if (IsLargeOffset) {
3420  if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
3421  IDLoc, Out, STI))
3422  return true;
3423  }
3424 
3425  int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
3426  int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
3427  if (isLittle())
3428  std::swap(FirstOffset, SecondOffset);
3429 
3430  if (IsLargeOffset) {
3431  TOut.emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
3432  TOut.emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
3433  TOut.emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
3434  TOut.emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
3435  TOut.emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
3436  TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
3437  } else {
3438  TOut.emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
3439  TOut.emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
3440  TOut.emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
3441  }
3442 
3443  return false;
3444 }
3445 
3446 bool MipsAsmParser::expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3447  const MCSubtargetInfo *STI) {
3448  if (hasMips32r6() || hasMips64r6()) {
3449  return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3450  }
3451 
3452  const MCOperand &DstRegOp = Inst.getOperand(0);
3453  assert(DstRegOp.isReg() && "expected register operand kind");
3454  const MCOperand &SrcRegOp = Inst.getOperand(1);
3455  assert(SrcRegOp.isReg() && "expected register operand kind");
3456  const MCOperand &OffsetImmOp = Inst.getOperand(2);
3457  assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3458 
3459  MipsTargetStreamer &TOut = getTargetStreamer();
3460  unsigned DstReg = DstRegOp.getReg();
3461  unsigned SrcReg = SrcRegOp.getReg();
3462  int64_t OffsetValue = OffsetImmOp.getImm();
3463 
3464  // Compute left/right load/store offsets.
3465  bool IsLargeOffset = !(isInt<16>(OffsetValue + 3) && isInt<16>(OffsetValue));
3466  int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
3467  int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
3468  if (isLittle())
3469  std::swap(LxlOffset, LxrOffset);
3470 
3471  bool IsLoadInst = (Inst.getOpcode() == Mips::Ulw);
3472  bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
3473  unsigned TmpReg = SrcReg;
3474  if (IsLargeOffset || DoMove) {
3475  warnIfNoMacro(IDLoc);
3476  TmpReg = getATReg(IDLoc);
3477  if (!TmpReg)
3478  return true;
3479  }
3480 
3481  if (IsLargeOffset) {
3482  if (loadImmediate(OffsetValue, TmpReg, SrcReg, !ABI.ArePtrs64bit(), true,
3483  IDLoc, Out, STI))
3484  return true;
3485  }
3486 
3487  if (DoMove)
3488  std::swap(DstReg, TmpReg);
3489 
3490  unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
3491  unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
3492  TOut.emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
3493  TOut.emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
3494 
3495  if (DoMove)
3496  TOut.emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
3497 
3498  return false;
3499 }
3500 
3501 bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
3502  MCStreamer &Out,
3503  const MCSubtargetInfo *STI) {
3504  MipsTargetStreamer &TOut = getTargetStreamer();
3505 
3506  assert (Inst.getNumOperands() == 3 && "Invalid operand count");
3507  assert (Inst.getOperand(0).isReg() &&
3508  Inst.getOperand(1).isReg() &&
3509  Inst.getOperand(2).isImm() && "Invalid instruction operand.");
3510 
3511  unsigned ATReg = Mips::NoRegister;
3512  unsigned FinalDstReg = Mips::NoRegister;
3513  unsigned DstReg = Inst.getOperand(0).getReg();
3514  unsigned SrcReg = Inst.getOperand(1).getReg();
3515  int64_t ImmValue = Inst.getOperand(2).getImm();
3516 
3517  bool Is32Bit = isInt<32>(ImmValue) || isUInt<32>(ImmValue);
3518 
3519  unsigned FinalOpcode = Inst.getOpcode();
3520 
3521  if (DstReg == SrcReg) {
3522  ATReg = getATReg(Inst.getLoc());
3523  if (!ATReg)
3524  return true;
3525  FinalDstReg = DstReg;
3526  DstReg = ATReg;
3527  }
3528 
3529  if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit, false, Inst.getLoc(), Out, STI)) {
3530  switch (FinalOpcode) {
3531  default:
3532  llvm_unreachable("unimplemented expansion");
3533  case (Mips::ADDi):
3534  FinalOpcode = Mips::ADD;
3535  break;
3536  case (Mips::ADDiu):
3537  FinalOpcode = Mips::ADDu;
3538  break;
3539  case (Mips::ANDi):
3540  FinalOpcode = Mips::AND;
3541  break;
3542  case (Mips::NORImm):
3543  FinalOpcode = Mips::NOR;
3544  break;
3545  case (Mips::ORi):
3546  FinalOpcode = Mips::OR;
3547  break;
3548  case (Mips::SLTi):
3549  FinalOpcode = Mips::SLT;
3550  break;
3551  case (Mips::SLTiu):
3552  FinalOpcode = Mips::SLTu;
3553  break;
3554  case (Mips::XORi):
3555  FinalOpcode = Mips::XOR;
3556  break;
3557  }
3558 
3559  if (FinalDstReg == Mips::NoRegister)
3560  TOut.emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
3561  else
3562  TOut.emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
3563  return false;
3564  }
3565  return true;
3566 }
3567 
3568 bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3569  const MCSubtargetInfo *STI) {
3570  MipsTargetStreamer &TOut = getTargetStreamer();
3571  unsigned ATReg = Mips::NoRegister;
3572  unsigned DReg = Inst.getOperand(0).getReg();
3573  unsigned SReg = Inst.getOperand(1).getReg();
3574  unsigned TReg = Inst.getOperand(2).getReg();
3575  unsigned TmpReg = DReg;
3576 
3577  unsigned FirstShift = Mips::NOP;
3578  unsigned SecondShift = Mips::NOP;
3579 
3580  if (hasMips32r2()) {
3581 
3582  if (DReg == SReg) {
3583  TmpReg = getATReg(Inst.getLoc());
3584  if (!TmpReg)
3585  return true;
3586  }
3587 
3588  if (Inst.getOpcode() == Mips::ROL) {
3589  TOut.emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
3590  TOut.emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
3591  return false;
3592  }
3593 
3594  if (Inst.getOpcode() == Mips::ROR) {
3595  TOut.emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
3596  return false;
3597  }
3598 
3599  return true;
3600  }
3601 
3602  if (hasMips32()) {
3603 
3604  switch (Inst.getOpcode()) {
3605  default:
3606  llvm_unreachable("unexpected instruction opcode");
3607  case Mips::ROL:
3608  FirstShift = Mips::SRLV;
3609  SecondShift = Mips::SLLV;
3610  break;
3611  case Mips::ROR:
3612  FirstShift = Mips::SLLV;
3613  SecondShift = Mips::SRLV;
3614  break;
3615  }
3616 
3617  ATReg = getATReg(Inst.getLoc());
3618  if (!ATReg)
3619  return true;
3620 
3621  TOut.emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
3622  TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
3623  TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
3624  TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
3625 
3626  return false;
3627  }
3628 
3629  return true;
3630 }
3631 
3632 bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
3633  MCStreamer &Out,
3634  const MCSubtargetInfo *STI) {
3635  MipsTargetStreamer &TOut = getTargetStreamer();
3636  unsigned ATReg = Mips::NoRegister;
3637  unsigned DReg = Inst.getOperand(0).getReg();
3638  unsigned SReg = Inst.getOperand(1).getReg();
3639  int64_t ImmValue = Inst.getOperand(2).getImm();
3640 
3641  unsigned FirstShift = Mips::NOP;
3642  unsigned SecondShift = Mips::NOP;
3643 
3644  if (hasMips32r2()) {
3645 
3646  if (Inst.getOpcode() == Mips::ROLImm) {
3647  uint64_t MaxShift = 32;
3648  uint64_t ShiftValue = ImmValue;
3649  if (ImmValue != 0)
3650  ShiftValue = MaxShift - ImmValue;
3651  TOut.emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
3652  return false;
3653  }
3654 
3655  if (Inst.getOpcode() == Mips::RORImm) {
3656  TOut.emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.getLoc(), STI);
3657  return false;
3658  }
3659 
3660  return true;
3661  }
3662 
3663  if (hasMips32()) {
3664 
3665  if (ImmValue == 0) {
3666  TOut.emitRRI(Mips::SRL, DReg, SReg, 0, Inst.getLoc(), STI);
3667  return false;
3668  }
3669 
3670  switch (Inst.getOpcode()) {
3671  default:
3672  llvm_unreachable("unexpected instruction opcode");
3673  case Mips::ROLImm:
3674  FirstShift = Mips::SLL;
3675  SecondShift = Mips::SRL;
3676  break;
3677  case Mips::RORImm:
3678  FirstShift = Mips::SRL;
3679  SecondShift = Mips::SLL;
3680  break;
3681  }
3682 
3683  ATReg = getATReg(Inst.getLoc());
3684  if (!ATReg)
3685  return true;
3686 
3687  TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.getLoc(), STI);
3688  TOut.emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.getLoc(), STI);
3689  TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
3690 
3691  return false;
3692  }
3693 
3694  return true;
3695 }
3696 
3697 bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3698  const MCSubtargetInfo *STI) {
3699  MipsTargetStreamer &TOut = getTargetStreamer();
3700  unsigned ATReg = Mips::NoRegister;
3701  unsigned DReg = Inst.getOperand(0).getReg();
3702  unsigned SReg = Inst.getOperand(1).getReg();
3703  unsigned TReg = Inst.getOperand(2).getReg();
3704  unsigned TmpReg = DReg;
3705 
3706  unsigned FirstShift = Mips::NOP;
3707  unsigned SecondShift = Mips::NOP;
3708 
3709  if (hasMips64r2()) {
3710 
3711  if (TmpReg == SReg) {
3712  TmpReg = getATReg(Inst.getLoc());
3713  if (!TmpReg)
3714  return true;
3715  }
3716 
3717  if (Inst.getOpcode() == Mips::DROL) {
3718  TOut.emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
3719  TOut.emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
3720  return false;
3721  }
3722 
3723  if (Inst.getOpcode() == Mips::DROR) {
3724  TOut.emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
3725  return false;
3726  }
3727 
3728  return true;
3729  }
3730 
3731  if (hasMips64()) {
3732 
3733  switch (Inst.getOpcode()) {
3734  default:
3735  llvm_unreachable("unexpected instruction opcode");
3736  case Mips::DROL:
3737  FirstShift = Mips::DSRLV;
3738  SecondShift = Mips::DSLLV;
3739  break;
3740  case Mips::DROR:
3741  FirstShift = Mips::DSLLV;
3742  SecondShift = Mips::DSRLV;
3743  break;
3744  }
3745 
3746  ATReg = getATReg(Inst.getLoc());
3747  if (!ATReg)
3748  return true;
3749 
3750  TOut.emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
3751  TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
3752  TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
3753  TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
3754 
3755  return false;
3756  }
3757 
3758  return true;
3759 }
3760 
3761 bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
3762  MCStreamer &Out,
3763  const MCSubtargetInfo *STI) {
3764  MipsTargetStreamer &TOut = getTargetStreamer();
3765  unsigned ATReg = Mips::NoRegister;
3766  unsigned DReg = Inst.getOperand(0).getReg();
3767  unsigned SReg = Inst.getOperand(1).getReg();
3768  int64_t ImmValue = Inst.getOperand(2).getImm() % 64;
3769 
3770  unsigned FirstShift = Mips::NOP;
3771  unsigned SecondShift = Mips::NOP;
3772 
3773  MCInst TmpInst;
3774 
3775  if (hasMips64r2()) {
3776 
3777  unsigned FinalOpcode = Mips::NOP;
3778  if (ImmValue == 0)
3779  FinalOpcode = Mips::DROTR;
3780  else if (ImmValue % 32 == 0)
3781  FinalOpcode = Mips::DROTR32;
3782  else if ((ImmValue >= 1) && (ImmValue <= 32)) {
3783  if (Inst.getOpcode() == Mips::DROLImm)
3784  FinalOpcode = Mips::DROTR32;
3785  else
3786  FinalOpcode = Mips::DROTR;
3787  } else if (ImmValue >= 33) {
3788  if (Inst.getOpcode() == Mips::DROLImm)
3789  FinalOpcode = Mips::DROTR;
3790  else
3791  FinalOpcode = Mips::DROTR32;
3792  }
3793 
3794  uint64_t ShiftValue = ImmValue % 32;
3795  if (Inst.getOpcode() == Mips::DROLImm)
3796  ShiftValue = (32 - ImmValue % 32) % 32;
3797 
3798  TOut.emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
3799 
3800  return false;
3801  }
3802 
3803  if (hasMips64()) {
3804 
3805  if (ImmValue == 0) {
3806  TOut.emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.getLoc(), STI);
3807  return false;
3808  }
3809 
3810  switch (Inst.getOpcode()) {
3811  default:
3812  llvm_unreachable("unexpected instruction opcode");
3813  case Mips::DROLImm:
3814  if ((ImmValue >= 1) && (ImmValue <= 31)) {
3815  FirstShift = Mips::DSLL;
3816  SecondShift = Mips::DSRL32;
3817  }
3818  if (ImmValue == 32) {
3819  FirstShift = Mips::DSLL32;
3820  SecondShift = Mips::DSRL32;
3821  }
3822  if ((ImmValue >= 33) && (ImmValue <= 63)) {
3823  FirstShift = Mips::DSLL32;
3824  SecondShift = Mips::DSRL;
3825  }
3826  break;
3827  case Mips::DRORImm:
3828  if ((ImmValue >= 1) && (ImmValue <= 31)) {
3829  FirstShift = Mips::DSRL;
3830  SecondShift = Mips::DSLL32;
3831  }
3832  if (ImmValue == 32) {
3833  FirstShift = Mips::DSRL32;
3834  SecondShift = Mips::DSLL32;
3835  }
3836  if ((ImmValue >= 33) && (ImmValue <= 63)) {
3837  FirstShift = Mips::DSRL32;
3838  SecondShift = Mips::DSLL;
3839  }
3840  break;
3841  }
3842 
3843  ATReg = getATReg(Inst.getLoc());
3844  if (!ATReg)
3845  return true;
3846 
3847  TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.getLoc(), STI);
3848  TOut.emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
3849  Inst.getLoc(), STI);
3850  TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
3851 
3852  return false;
3853  }
3854 
3855  return true;
3856 }
3857 
3858 bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3859  const MCSubtargetInfo *STI) {
3860  MipsTargetStreamer &TOut = getTargetStreamer();
3861  unsigned FirstRegOp = Inst.getOperand(0).getReg();
3862  unsigned SecondRegOp = Inst.getOperand(1).getReg();
3863 
3864  TOut.emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
3865  if (FirstRegOp != SecondRegOp)
3866  TOut.emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
3867  else
3868  TOut.emitEmptyDelaySlot(false, IDLoc, STI);
3869  TOut.emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
3870 
3871  return false;
3872 }
3873 
3874 static unsigned nextReg(unsigned Reg) {
3875  switch (Reg) {
3876  case Mips::ZERO: return Mips::AT;
3877  case Mips::AT: return Mips::V0;
3878  case Mips::V0: return Mips::V1;
3879  case Mips::V1: return Mips::A0;
3880  case Mips::A0: return Mips::A1;
3881  case Mips::A1: return Mips::A2;
3882  case Mips::A2: return Mips::A3;
3883  case Mips::A3: return Mips::T0;
3884  case Mips::T0: return Mips::T1;
3885  case Mips::T1: return Mips::T2;
3886  case Mips::T2: return Mips::T3;
3887  case Mips::T3: return Mips::T4;
3888  case Mips::T4: return Mips::T5;
3889  case Mips::T5: return Mips::T6;
3890  case Mips::T6: return Mips::T7;
3891  case Mips::T7: return Mips::S0;
3892  case Mips::S0: return Mips::S1;
3893  case Mips::S1: return Mips::S2;
3894  case Mips::S2: return Mips::S3;
3895  case Mips::S3: return Mips::S4;
3896  case Mips::S4: return Mips::S5;
3897  case Mips::S5: return Mips::S6;
3898  case Mips::S6: return Mips::S7;
3899  case Mips::S7: return Mips::T8;
3900  case Mips::T8: return Mips::T9;
3901  case Mips::T9: return Mips::K0;
3902  case Mips::K0: return Mips::K1;
3903  case Mips::K1: return Mips::GP;
3904  case Mips::GP: return Mips::SP;
3905  case Mips::SP: return Mips::FP;
3906  case Mips::FP: return Mips::RA;
3907  case Mips::RA: return Mips::ZERO;
3908  default: return 0;
3909  }
3910 
3911 }
3912 
3913 // Expand 'ld $<reg> offset($reg2)' to 'lw $<reg>, offset($reg2);
3914 // lw $<reg+1>>, offset+4($reg2)'
3915 // or expand 'sd $<reg> offset($reg2)' to 'sw $<reg>, offset($reg2);
3916 // sw $<reg+1>>, offset+4($reg2)'
3917 // for O32.
3918 bool MipsAsmParser::expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc,
3919  MCStreamer &Out,
3920  const MCSubtargetInfo *STI,
3921  bool IsLoad) {
3922  if (!isABI_O32())
3923  return true;
3924 
3925  warnIfNoMacro(IDLoc);
3926 
3927  MipsTargetStreamer &TOut = getTargetStreamer();
3928  unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
3929  unsigned FirstReg = Inst.getOperand(0).getReg();
3930  unsigned SecondReg = nextReg(FirstReg);
3931  unsigned BaseReg = Inst.getOperand(1).getReg();
3932  if (!SecondReg)
3933  return true;
3934 
3935  warnIfRegIndexIsAT(FirstReg, IDLoc);
3936 
3937  assert(Inst.getOperand(2).isImm() &&
3938  "Offset for load macro is not immediate!");
3939 
3940  MCOperand &FirstOffset = Inst.getOperand(2);
3941  signed NextOffset = FirstOffset.getImm() + 4;
3942  MCOperand SecondOffset = MCOperand::createImm(NextOffset);
3943 
3944  if (!isInt<16>(FirstOffset.getImm()) || !isInt<16>(NextOffset))
3945  return true;
3946 
3947  // For loads, clobber the base register with the second load instead of the
3948  // first if the BaseReg == FirstReg.
3949  if (FirstReg != BaseReg || !IsLoad) {
3950  TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
3951  TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
3952  } else {
3953  TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
3954  TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
3955  }
3956 
3957  return false;
3958 }
3959 
3960 bool MipsAsmParser::expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3961  const MCSubtargetInfo *STI) {
3962 
3963  warnIfNoMacro(IDLoc);
3964  MipsTargetStreamer &TOut = getTargetStreamer();
3965 
3966  if (Inst.getOperand(1).getReg() != Mips::ZERO &&
3967  Inst.getOperand(2).getReg() != Mips::ZERO) {
3968  TOut.emitRRR(Mips::XOR, Inst.getOperand(0).getReg(),
3969  Inst.getOperand(1).getReg(), Inst.getOperand(2).getReg(),
3970  IDLoc, STI);
3971  TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
3972  Inst.getOperand(0).getReg(), 1, IDLoc, STI);
3973  return false;
3974  }
3975 
3976  unsigned Reg = 0;
3977  if (Inst.getOperand(1).getReg() == Mips::ZERO) {
3978  Reg = Inst.getOperand(2).getReg();
3979  } else {
3980  Reg = Inst.getOperand(1).getReg();
3981  }
3982  TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(), Reg, 1, IDLoc, STI);
3983  return false;
3984 }
3985 
3986 bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3987  const MCSubtargetInfo *STI) {
3988 
3989  warnIfNoMacro(IDLoc);
3990  MipsTargetStreamer &TOut = getTargetStreamer();
3991 
3992  unsigned Opc;
3993  int64_t Imm = Inst.getOperand(2).getImm();
3994  unsigned Reg = Inst.getOperand(1).getReg();
3995 
3996  if (Imm == 0) {
3997  TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
3998  Inst.getOperand(1).getReg(), 1, IDLoc, STI);
3999  return false;
4000  } else {
4001 
4002  if (Reg == Mips::ZERO) {
4003  Warning(IDLoc, "comparison is always false");
4004  TOut.emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
4005  Inst.getOperand(0).getReg(), Reg, Reg, IDLoc, STI);
4006  return false;
4007  }
4008 
4009  if (Imm > -0x8000 && Imm < 0) {
4010  Imm = -Imm;
4011  Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
4012  } else {
4013  Opc = Mips::XORi;
4014  }
4015  }
4016  if (!isUInt<16>(Imm)) {
4017  unsigned ATReg = getATReg(IDLoc);
4018  if (!ATReg)
4019  return true;
4020 
4021  if (loadImmediate(Imm, ATReg, Mips::NoRegister, true, isGP64bit(), IDLoc,
4022  Out, STI))
4023  return true;
4024 
4025  TOut.emitRRR(Mips::XOR, Inst.getOperand(0).getReg(),
4026  Inst.getOperand(1).getReg(), ATReg, IDLoc, STI);
4027  TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
4028  Inst.getOperand(0).getReg(), 1, IDLoc, STI);
4029  return false;
4030  }
4031 
4032  TOut.emitRRI(Opc, Inst.getOperand(0).getReg(), Inst.getOperand(1).getReg(),
4033  Imm, IDLoc, STI);
4034  TOut.emitRRI(Mips::SLTiu, Inst.getOperand(0).getReg(),
4035  Inst.getOperand(0).getReg(), 1, IDLoc, STI);
4036  return false;
4037 }
4038 
4039 unsigned
4040 MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
4041  const OperandVector &Operands) {
4042  switch (Inst.getOpcode()) {
4043  default:
4044  return Match_Success;
4045  case Mips::DATI:
4046  case Mips::DAHI:
4047  case Mips::DATI_MM64R6:
4048  case Mips::DAHI_MM64R6:
4049  if (static_cast<MipsOperand &>(*Operands[1])
4050  .isValidForTie(static_cast<MipsOperand &>(*Operands[2])))
4051  return Match_Success;
4052  return Match_RequiresSameSrcAndDst;
4053  }
4054 }
4055 
4056 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
4057  switch (Inst.getOpcode()) {
4058  // As described by the MIPSR6 spec, daui must not use the zero operand for
4059  // its source operand.
4060  case Mips::DAUI:
4061  case Mips::DAUI_MM64R6:
4062  if (Inst.getOperand(1).getReg() == Mips::ZERO ||
4063  Inst.getOperand(1).getReg() == Mips::ZERO_64)
4064  return Match_RequiresNoZeroRegister;
4065  return Match_Success;
4066  // As described by the Mips32r2 spec, the registers Rd and Rs for
4067  // jalr.hb must be different.
4068  // It also applies for registers Rt and Rs of microMIPSr6 jalrc.hb instruction
4069  // and registers Rd and Base for microMIPS lwp instruction
4070  case Mips::JALR_HB:
4071  case Mips::JALRC_HB_MMR6:
4072  case Mips::JALRC_MMR6:
4073  if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
4074  return Match_RequiresDifferentSrcAndDst;
4075  return Match_Success;
4076  case Mips::LWP_MM:
4077  case Mips::LWP_MMR6:
4078  if (Inst.getOperand(0).getReg() == Inst.getOperand(2).getReg())
4079  return Match_RequiresDifferentSrcAndDst;
4080  return Match_Success;
4081  case Mips::SYNC:
4082  if (Inst.getOperand(0).getImm() != 0 && !hasMips32())
4083  return Match_NonZeroOperandForSync;
4084  return Match_Success;
4085  // As described the MIPSR6 spec, the compact branches that compare registers
4086  // must:
4087  // a) Not use the zero register.
4088  // b) Not use the same register twice.
4089  // c) rs < rt for bnec, beqc.
4090  // NB: For this case, the encoding will swap the operands as their
4091  // ordering doesn't matter. GAS performs this transformation too.
4092  // Hence, that constraint does not have to be enforced.
4093  //
4094  // The compact branches that branch iff the signed addition of two registers
4095  // would overflow must have rs >= rt. That can be handled like beqc/bnec with
4096  // operand swapping. They do not have restriction of using the zero register.
4097  case Mips::BLEZC: case Mips::BLEZC_MMR6:
4098  case Mips::BGEZC: case Mips::BGEZC_MMR6:
4099  case Mips::BGTZC: case Mips::BGTZC_MMR6:
4100  case Mips::BLTZC: case Mips::BLTZC_MMR6:
4101  case Mips::BEQZC: case Mips::BEQZC_MMR6:
4102  case Mips::BNEZC: case Mips::BNEZC_MMR6:
4103  case Mips::BLEZC64:
4104  case Mips::BGEZC64:
4105  case Mips::BGTZC64:
4106  case Mips::BLTZC64:
4107  case Mips::BEQZC64:
4108  case Mips::BNEZC64:
4109  if (Inst.getOperand(0).getReg() == Mips::ZERO ||
4110  Inst.getOperand(0).getReg() == Mips::ZERO_64)
4111  return Match_RequiresNoZeroRegister;
4112  return Match_Success;
4113  case Mips::BGEC: case Mips::BGEC_MMR6:
4114  case Mips::BLTC: case Mips::BLTC_MMR6:
4115  case Mips::BGEUC: case Mips::BGEUC_MMR6:
4116  case Mips::BLTUC: case Mips::BLTUC_MMR6:
4117  case Mips::BEQC: case Mips::BEQC_MMR6:
4118  case Mips::BNEC: case Mips::BNEC_MMR6:
4119  case Mips::BGEC64:
4120  case Mips::BLTC64:
4121  case Mips::BGEUC64:
4122  case Mips::BLTUC64:
4123  case Mips::BEQC64:
4124  case Mips::BNEC64:
4125  if (Inst.getOperand(0).getReg() == Mips::ZERO ||
4126  Inst.getOperand(0).getReg() == Mips::ZERO_64)
4127  return Match_RequiresNoZeroRegister;
4128  if (Inst.getOperand(1).getReg() == Mips::ZERO ||
4129  Inst.getOperand(1).getReg() == Mips::ZERO_64)
4130  return Match_RequiresNoZeroRegister;
4131  if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
4132  return Match_RequiresDifferentOperands;
4133  return Match_Success;
4134  }
4135 
4136  uint64_t TSFlags = getInstDesc(Inst.getOpcode()).TSFlags;
4137  if ((TSFlags & MipsII::HasFCCRegOperand) &&
4138  (Inst.getOperand(0).getReg() != Mips::FCC0) && !hasEightFccRegisters())
4139  return Match_NoFCCRegisterForCurrentISA;
4140 
4141  return Match_Success;
4142 
4143 }
4144 
4145 static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands,
4146  uint64_t ErrorInfo) {
4147  if (ErrorInfo != ~0ULL && ErrorInfo < Operands.size()) {
4148  SMLoc ErrorLoc = Operands[ErrorInfo]->getStartLoc();
4149  if (ErrorLoc == SMLoc())
4150  return Loc;
4151  return ErrorLoc;
4152  }
4153  return Loc;
4154 }
4155 
4156 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
4157  OperandVector &Operands,
4158  MCStreamer &Out,
4159  uint64_t &ErrorInfo,
4160  bool MatchingInlineAsm) {
4161 
4162  MCInst Inst;
4163  unsigned MatchResult =
4164  MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
4165 
4166  switch (MatchResult) {
4167  case Match_Success: {
4168  if (processInstruction(Inst, IDLoc, Out, STI))
4169  return true;
4170  return false;
4171  }
4172  case Match_MissingFeature:
4173  Error(IDLoc, "instruction requires a CPU feature not currently enabled");
4174  return true;
4175  case Match_InvalidOperand: {
4176  SMLoc ErrorLoc = IDLoc;
4177  if (ErrorInfo != ~0ULL) {
4178  if (ErrorInfo >= Operands.size())
4179  return Error(IDLoc, "too few operands for instruction");
4180 
4181  ErrorLoc = Operands[ErrorInfo]->getStartLoc();
4182  if (ErrorLoc == SMLoc())
4183  ErrorLoc = IDLoc;
4184  }
4185 
4186  return Error(ErrorLoc, "invalid operand for instruction");
4187  }
4188  case Match_NonZeroOperandForSync:
4189  return Error(IDLoc, "s-type must be zero or unspecified for pre-MIPS32 ISAs");
4190  case Match_MnemonicFail:
4191  return Error(IDLoc, "invalid instruction");
4192  case Match_RequiresDifferentSrcAndDst:
4193  return Error(IDLoc, "source and destination must be different");
4194  case Match_RequiresDifferentOperands:
4195  return Error(IDLoc, "registers must be different");
4196  case Match_RequiresNoZeroRegister:
4197  return Error(IDLoc, "invalid operand ($zero) for instruction");
4198  case Match_RequiresSameSrcAndDst:
4199  return Error(IDLoc, "source and destination must match");
4200  case Match_NoFCCRegisterForCurrentISA:
4201  return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4202  "non-zero fcc register doesn't exist in current ISA level");
4203  case Match_Immz:
4204  return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected '0'");
4205  case Match_UImm1_0:
4206  return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4207  "expected 1-bit unsigned immediate");
4208  case Match_UImm2_0:
4209  return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4210  "expected 2-bit unsigned immediate");
4211  case Match_UImm2_1:
4212  return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4213  "expected immediate in range 1 .. 4");
4214  case Match_UImm3_0:
4215  return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4216  "expected 3-bit unsigned immediate");
4217  case Match_UImm4_0:
4218  return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4219  "expected 4-bit unsigned immediate");
4220  case Match_SImm4_0:
4221  return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4222  "expected 4-bit signed immediate");
4223  case Match_UImm5_0:
4224  return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4225  "expected 5-bit unsigned immediate");
4226  case Match_SImm5_0:
4227  return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4228  "expected 5-bit signed immediate");
4229  case Match_UImm5_1:
4230  return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4231  "expected immediate in range 1 .. 32");
4232  case Match_UImm5_32:
4233  return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4234  "expected immediate in range 32 .. 63");
4235  case Match_UImm5_33:
4236  return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4237  "expected immediate in range 33 .. 64");
4238  case Match_UImm5_0_Report_UImm6:
4239  // This is used on UImm5 operands that have a corresponding UImm5_32
4240  // operand to avoid confusing the user.
4241  return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4242  "expected 6-bit unsigned immediate");
4243  case Match_UImm5_Lsl2:
4244  return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4245  "expected both 7-bit unsigned immediate and multiple of 4");
4246  case Match_UImmRange2_64:
4247  return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4248  "expected immediate in range 2 .. 64");
4249  case Match_UImm6_0:
4250  return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4251  "expected 6-bit unsigned immediate");
4252  case Match_UImm6_Lsl2:
4253  return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4254  "expected both 8-bit unsigned immediate and multiple of 4");
4255  case Match_SImm6_0:
4256  return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4257  "expected 6-bit signed immediate");
4258  case Match_UImm7_0:
4259  return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4260  "expected 7-bit unsigned immediate");
4261  case Match_UImm7_N1:
4262  return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4263  "expected immediate in range -1 .. 126");
4264  case Match_SImm7_Lsl2:
4265  return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4266  "expected both 9-bit signed immediate and multiple of 4");
4267  case Match_UImm8_0:
4268  return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4269  "expected 8-bit unsigned immediate");
4270  case Match_UImm10_0:
4271  return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4272  "expected 10-bit unsigned immediate");
4273  case Match_SImm10_0:
4274  return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4275  "expected 10-bit signed immediate");
4276  case Match_SImm11_0:
4277  return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4278  "expected 11-bit signed immediate");
4279  case Match_UImm16:
4280  case Match_UImm16_Relaxed:
4281  return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4282  "expected 16-bit unsigned immediate");
4283  case Match_SImm16:
4284  case Match_SImm16_Relaxed:
4285  return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4286  "expected 16-bit signed immediate");
4287  case Match_SImm19_Lsl2:
4288  return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4289  "expected both 19-bit signed immediate and multiple of 4");
4290  case Match_UImm20_0:
4291  return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4292  "expected 20-bit unsigned immediate");
4293  case Match_UImm26_0:
4294  return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4295  "expected 26-bit unsigned immediate");
4296  case Match_SImm32:
4297  case Match_SImm32_Relaxed:
4298  return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4299  "expected 32-bit signed immediate");
4300  case Match_UImm32_Coerced:
4301  return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4302  "expected 32-bit immediate");
4303  case Match_MemSImm9:
4304  return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4305  "expected memory with 9-bit signed offset");
4306  case Match_MemSImm10:
4307  return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4308  "expected memory with 10-bit signed offset");
4309  case Match_MemSImm10Lsl1:
4310  return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4311  "expected memory with 11-bit signed offset and multiple of 2");
4312  case Match_MemSImm10Lsl2:
4313  return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4314  "expected memory with 12-bit signed offset and multiple of 4");
4315  case Match_MemSImm10Lsl3:
4316  return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4317  "expected memory with 13-bit signed offset and multiple of 8");
4318  case Match_MemSImm11:
4319  return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4320  "expected memory with 11-bit signed offset");
4321  case Match_MemSImm12:
4322  return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4323  "expected memory with 12-bit signed offset");
4324  case Match_MemSImm16:
4325  return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4326  "expected memory with 16-bit signed offset");
4327  }
4328 
4329  llvm_unreachable("Implement any new match types added!");
4330 }
4331 
4332 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
4333  if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
4334  Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
4335  ") without \".set noat\"");
4336 }
4337 
4338 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
4339  if (!AssemblerOptions.back()->isMacro())
4340  Warning(Loc, "macro instruction expanded into multiple instructions");
4341 }
4342 
4343 void
4344 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
4345  SMRange Range, bool ShowColors) {
4346  getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
4347  Range, SMFixIt(Range, FixMsg),
4348  ShowColors);
4349 }
4350 
4351 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
4352  int CC;
4353 
4355  .Case("zero", 0)
4356  .Case("at", 1)
4357  .Case("a0", 4)
4358  .Case("a1", 5)
4359  .Case("a2", 6)
4360  .Case("a3", 7)
4361  .Case("v0", 2)
4362  .Case("v1", 3)
4363  .Case("s0", 16)
4364  .Case("s1", 17)
4365  .Case("s2", 18)
4366  .Case("s3", 19)
4367  .Case("s4", 20)
4368  .Case("s5", 21)
4369  .Case("s6", 22)
4370  .Case("s7", 23)
4371  .Case("k0", 26)
4372  .Case("k1", 27)
4373  .Case("gp", 28)
4374  .Case("sp", 29)
4375  .Case("fp", 30)
4376  .Case("s8", 30)
4377  .Case("ra", 31)
4378  .Case("t0", 8)
4379  .Case("t1", 9)
4380  .Case("t2", 10)
4381  .Case("t3", 11)
4382  .Case("t4", 12)
4383  .Case("t5", 13)
4384  .Case("t6", 14)
4385  .Case("t7", 15)
4386  .Case("t8", 24)
4387  .Case("t9", 25)
4388  .Default(-1);
4389 
4390  if (!(isABI_N32() || isABI_N64()))
4391  return CC;
4392 
4393  if (12 <= CC && CC <= 15) {
4394  // Name is one of t4-t7
4395  AsmToken RegTok = getLexer().peekTok();
4396  SMRange RegRange = RegTok.getLocRange();
4397 
4399  .Case("t4", "t0")
4400  .Case("t5", "t1")
4401  .Case("t6", "t2")
4402  .Case("t7", "t3")
4403  .Default("");
4404  assert(FixedName != "" && "Register name is not one of t4-t7.");
4405 
4406  printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
4407  "Did you mean $" + FixedName + "?", RegRange);
4408  }
4409 
4410  // Although SGI documentation just cuts out t0-t3 for n32/n64,
4411  // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
4412  // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
4413  if (8 <= CC && CC <= 11)
4414  CC += 4;
4415 
4416  if (CC == -1)
4418  .Case("a4", 8)
4419  .Case("a5", 9)
4420  .Case("a6", 10)
4421  .Case("a7", 11)
4422  .Case("kt0", 26)
4423  .Case("kt1", 27)
4424  .Default(-1);
4425 
4426  return CC;
4427 }
4428 
4429 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
4430  int CC;
4431 
4433  .Case("hwr_cpunum", 0)
4434  .Case("hwr_synci_step", 1)
4435  .Case("hwr_cc", 2)
4436  .Case("hwr_ccres", 3)
4437  .Case("hwr_ulr", 29)
4438  .Default(-1);
4439 
4440  return CC;
4441 }
4442 
4443 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
4444 
4445  if (Name[0] == 'f') {
4446  StringRef NumString = Name.substr(1);
4447  unsigned IntVal;
4448  if (NumString.getAsInteger(10, IntVal))
4449  return -1; // This is not an integer.
4450  if (IntVal > 31) // Maximum index for fpu register.
4451  return -1;
4452  return IntVal;
4453  }
4454  return -1;
4455 }
4456 
4457 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
4458 
4459  if (Name.startswith("fcc")) {
4460  StringRef NumString = Name.substr(3);
4461  unsigned IntVal;
4462  if (NumString.getAsInteger(10, IntVal))
4463  return -1; // This is not an integer.
4464  if (IntVal > 7) // There are only 8 fcc registers.
4465  return -1;
4466  return IntVal;
4467  }
4468  return -1;
4469 }
4470 
4471 int MipsAsmParser::matchACRegisterName(StringRef Name) {
4472 
4473  if (Name.startswith("ac")) {
4474  StringRef NumString = Name.substr(2);
4475  unsigned IntVal;
4476  if (NumString.getAsInteger(10, IntVal))
4477  return -1; // This is not an integer.
4478  if (IntVal > 3) // There are only 3 acc registers.
4479  return -1;
4480  return IntVal;
4481  }
4482  return -1;
4483 }
4484 
4485 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
4486  unsigned IntVal;
4487 
4488  if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
4489  return -1;
4490 
4491  if (IntVal > 31)
4492  return -1;
4493 
4494  return IntVal;
4495 }
4496 
4497 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
4498  int CC;
4499 
4501  .Case("msair", 0)
4502  .Case("msacsr", 1)
4503  .Case("msaaccess", 2)
4504  .Case("msasave", 3)
4505  .Case("msamodify", 4)
4506  .Case("msarequest", 5)
4507  .Case("msamap", 6)
4508  .Case("msaunmap", 7)
4509  .Default(-1);
4510 
4511  return CC;
4512 }
4513 
4514 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
4515  unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
4516  if (ATIndex == 0) {
4517  reportParseError(Loc,
4518  "pseudo-instruction requires $at, which is not available");
4519  return 0;
4520  }
4521  unsigned AT = getReg(
4522  (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
4523  return AT;
4524 }
4525 
4526 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
4527  return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
4528 }
4529 
4530 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
4531  MCAsmParser &Parser = getParser();
4532  DEBUG(dbgs() << "parseOperand\n");
4533 
4534  // Check if the current operand has a custom associated parser, if so, try to
4535  // custom parse the operand, or fallback to the general approach.
4536  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
4537  if (ResTy == MatchOperand_Success)
4538  return false;
4539  // If there wasn't a custom match, try the generic matcher below. Otherwise,
4540  // there was a match, but an error occurred, in which case, just return that
4541  // the operand parsing failed.
4542  if (ResTy == MatchOperand_ParseFail)
4543  return true;
4544 
4545  DEBUG(dbgs() << ".. Generic Parser\n");
4546 
4547  switch (getLexer().getKind()) {
4548  case AsmToken::Dollar: {
4549  // Parse the register.
4550  SMLoc S = Parser.getTok().getLoc();
4551 
4552  // Almost all registers have been parsed by custom parsers. There is only
4553  // one exception to this. $zero (and it's alias $0) will reach this point
4554  // for div, divu, and similar instructions because it is not an operand
4555  // to the instruction definition but an explicit register. Special case
4556  // this situation for now.
4557  if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
4558  return false;
4559 
4560  // Maybe it is a symbol reference.
4561  StringRef Identifier;
4562  if (Parser.parseIdentifier(Identifier))
4563  return true;
4564 
4565  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4566  MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
4567  // Otherwise create a symbol reference.
4568  const MCExpr *Res =
4570 
4571  Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
4572  return false;
4573  }
4574  default: {
4575  DEBUG(dbgs() << ".. generic integer expression\n");
4576 
4577  const MCExpr *Expr;
4578  SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
4579  if (getParser().parseExpression(Expr))
4580  return true;
4581 
4582  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4583 
4584  Operands.push_back(MipsOperand::CreateImm(Expr, S, E, *this));
4585  return false;
4586  }
4587  } // switch(getLexer().getKind())
4588  return true;
4589 }
4590 
4591 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
4592 
4593  switch (Expr->getKind()) {
4594  case MCExpr::Constant:
4595  return true;
4596  case MCExpr::SymbolRef:
4597  return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
4598  case MCExpr::Binary:
4599  if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
4600  if (!isEvaluated(BE->getLHS()))
4601  return false;
4602  return isEvaluated(BE->getRHS());
4603  }
4604  case MCExpr::Unary:
4605  return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
4606  case MCExpr::Target:
4607  return true;
4608  }
4609  return false;
4610 }
4611 
4612 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
4613  SMLoc &EndLoc) {
4615  OperandMatchResultTy ResTy = parseAnyRegister(Operands);
4616  if (ResTy == MatchOperand_Success) {
4617  assert(Operands.size() == 1);
4618  MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
4619  StartLoc = Operand.getStartLoc();
4620  EndLoc = Operand.getEndLoc();
4621 
4622  // AFAIK, we only support numeric registers and named GPR's in CFI
4623  // directives.
4624  // Don't worry about eating tokens before failing. Using an unrecognised
4625  // register is a parse error.
4626  if (Operand.isGPRAsmReg()) {
4627  // Resolve to GPR32 or GPR64 appropriately.
4628  RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
4629  }
4630 
4631  return (RegNo == (unsigned)-1);
4632  }
4633 
4634  assert(Operands.size() == 0);
4635  return (RegNo == (unsigned)-1);
4636 }
4637 
4638 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
4639  SMLoc S;
4640 
4641  if (isParenExpr)
4642  return getParser().parseParenExprOfDepth(0, Res, S);
4643  return getParser().parseExpression(Res);
4644 }
4645 
4647 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
4648  MCAsmParser &Parser = getParser();
4649  DEBUG(dbgs() << "parseMemOperand\n");
4650  const MCExpr *IdVal = nullptr;
4651  SMLoc S;
4652  bool isParenExpr = false;
4654  // First operand is the offset.
4655  S = Parser.getTok().getLoc();
4656 
4657  if (getLexer().getKind() == AsmToken::LParen) {
4658  Parser.Lex();
4659  isParenExpr = true;
4660  }
4661 
4662  if (getLexer().getKind() != AsmToken::Dollar) {
4663  if (parseMemOffset(IdVal, isParenExpr))
4664  return MatchOperand_ParseFail;
4665 
4666  const AsmToken &Tok = Parser.getTok(); // Get the next token.
4667  if (Tok.isNot(AsmToken::LParen)) {
4668  MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
4669  if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
4670  SMLoc E =
4671  SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4672  Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
4673  return MatchOperand_Success;
4674  }
4675  if (Tok.is(AsmToken::EndOfStatement)) {
4676  SMLoc E =
4677  SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4678 
4679  // Zero register assumed, add a memory operand with ZERO as its base.
4680  // "Base" will be managed by k_Memory.
4681  auto Base = MipsOperand::createGPRReg(
4682  0, "0", getContext().getRegisterInfo(), S, E, *this);
4683  Operands.push_back(
4684  MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
4685  return MatchOperand_Success;
4686  }
4687  MCBinaryExpr::Opcode Opcode;
4688  // GAS and LLVM treat comparison operators different. GAS will generate -1
4689  // or 0, while LLVM will generate 0 or 1. Since a comparsion operator is
4690  // highly unlikely to be found in a memory offset expression, we don't
4691  // handle them.
4692  switch (Tok.getKind()) {
4693  case AsmToken::Plus:
4694  Opcode = MCBinaryExpr::Add;
4695  Parser.Lex();
4696  break;
4697  case AsmToken::Minus:
4698  Opcode = MCBinaryExpr::Sub;
4699  Parser.Lex();
4700  break;
4701  case AsmToken::Star:
4702  Opcode = MCBinaryExpr::Mul;
4703  Parser.Lex();
4704  break;
4705  case AsmToken::Pipe:
4706  Opcode = MCBinaryExpr::Or;
4707  Parser.Lex();
4708  break;
4709  case AsmToken::Amp:
4710  Opcode = MCBinaryExpr::And;
4711  Parser.Lex();
4712  break;
4713  case AsmToken::LessLess:
4714  Opcode = MCBinaryExpr::Shl;
4715  Parser.Lex();
4716  break;
4718  Opcode = MCBinaryExpr::LShr;
4719  Parser.Lex();
4720  break;
4721  case AsmToken::Caret:
4722  Opcode = MCBinaryExpr::Xor;
4723  Parser.Lex();
4724  break;
4725  case AsmToken::Slash:
4726  Opcode = MCBinaryExpr::Div;
4727  Parser.Lex();
4728  break;
4729  case AsmToken::Percent:
4730  Opcode = MCBinaryExpr::Mod;
4731  Parser.Lex();
4732  break;
4733  default:
4734  Error(Parser.getTok().getLoc(), "'(' or expression expected");
4735  return MatchOperand_ParseFail;
4736  }
4737  const MCExpr * NextExpr;
4738  if (getParser().parseExpression(NextExpr))
4739  return MatchOperand_ParseFail;
4740  IdVal = MCBinaryExpr::create(Opcode, IdVal, NextExpr, getContext());
4741  }
4742 
4743  Parser.Lex(); // Eat the '(' token.
4744  }
4745 
4746  Res = parseAnyRegister(Operands);
4747  if (Res != MatchOperand_Success)
4748  return Res;
4749 
4750  if (Parser.getTok().isNot(AsmToken::RParen)) {
4751  Error(Parser.getTok().getLoc(), "')' expected");
4752  return MatchOperand_ParseFail;
4753  }
4754 
4755  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4756 
4757  Parser.Lex(); // Eat the ')' token.
4758 
4759  if (!IdVal)
4760  IdVal = MCConstantExpr::create(0, getContext());
4761 
4762  // Replace the register operand with the memory operand.
4763  std::unique_ptr<MipsOperand> op(
4764  static_cast<MipsOperand *>(Operands.back().release()));
4765  // Remove the register from the operands.
4766  // "op" will be managed by k_Memory.
4767  Operands.pop_back();
4768  // Add the memory operand.
4769  if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
4770  int64_t Imm;
4771  if (IdVal->evaluateAsAbsolute(Imm))
4772  IdVal = MCConstantExpr::create(Imm, getContext());
4773  else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
4774  IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
4775  getContext());
4776  }
4777 
4778  Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
4779  return MatchOperand_Success;
4780 }
4781 
4782 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
4783  MCAsmParser &Parser = getParser();
4784  MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
4785  if (Sym) {
4786  SMLoc S = Parser.getTok().getLoc();
4787  const MCExpr *Expr;
4788  if (Sym->isVariable())
4789  Expr = Sym->getVariableValue();
4790  else
4791  return false;
4792  if (Expr->getKind() == MCExpr::SymbolRef) {
4793  const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
4794  StringRef DefSymbol = Ref->getSymbol().getName();
4795  if (DefSymbol.startswith("$")) {
4796  OperandMatchResultTy ResTy =
4797  matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
4798  if (ResTy == MatchOperand_Success) {
4799  Parser.Lex();
4800  return true;
4801  } else if (ResTy == MatchOperand_ParseFail)
4802  llvm_unreachable("Should never ParseFail");
4803  return false;
4804  }
4805  }
4806  }
4807  return false;
4808 }
4809 
4811 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
4812  StringRef Identifier,
4813  SMLoc S) {
4814  int Index = matchCPURegisterName(Identifier);
4815  if (Index != -1) {
4816  Operands.push_back(MipsOperand::createGPRReg(
4817  Index, Identifier, getContext().getRegisterInfo(), S,
4818  getLexer().getLoc(), *this));
4819  return MatchOperand_Success;
4820  }
4821 
4822  Index = matchHWRegsRegisterName(Identifier);
4823  if (Index != -1) {
4824  Operands.push_back(MipsOperand::createHWRegsReg(
4825  Index, Identifier, getContext().getRegisterInfo(), S,
4826  getLexer().getLoc(), *this));
4827  return MatchOperand_Success;
4828  }
4829 
4830  Index = matchFPURegisterName(Identifier);
4831  if (Index != -1) {
4832  Operands.push_back(MipsOperand::createFGRReg(
4833  Index, Identifier, getContext().getRegisterInfo(), S,
4834  getLexer().getLoc(), *this));
4835  return MatchOperand_Success;
4836  }
4837 
4838  Index = matchFCCRegisterName(Identifier);
4839  if (Index != -1) {
4840  Operands.push_back(MipsOperand::createFCCReg(
4841  Index, Identifier, getContext().getRegisterInfo(), S,
4842  getLexer().getLoc(), *this));
4843  return MatchOperand_Success;
4844  }
4845 
4846  Index = matchACRegisterName(Identifier);
4847  if (Index != -1) {
4848  Operands.push_back(MipsOperand::createACCReg(
4849  Index, Identifier, getContext().getRegisterInfo(), S,
4850  getLexer().getLoc(), *this));
4851  return MatchOperand_Success;
4852  }
4853 
4854  Index = matchMSA128RegisterName(Identifier);
4855  if (Index != -1) {
4856  Operands.push_back(MipsOperand::createMSA128Reg(
4857  Index, Identifier, getContext().getRegisterInfo(), S,
4858  getLexer().getLoc(), *this));
4859  return MatchOperand_Success;
4860  }
4861 
4862  Index = matchMSA128CtrlRegisterName(Identifier);
4863  if (Index != -1) {
4864  Operands.push_back(MipsOperand::createMSACtrlReg(
4865  Index, Identifier, getContext().getRegisterInfo(), S,
4866  getLexer().getLoc(), *this));
4867  return MatchOperand_Success;
4868  }
4869 
4870  return MatchOperand_NoMatch;
4871 }
4872 
4874 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
4875  MCAsmParser &Parser = getParser();
4876  auto Token = Parser.getLexer().peekTok(false);
4877 
4878  if (Token.is(AsmToken::Identifier)) {
4879  DEBUG(dbgs() << ".. identifier\n");
4880  StringRef Identifier = Token.getIdentifier();
4881  OperandMatchResultTy ResTy =
4882  matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
4883  return ResTy;
4884  } else if (Token.is(AsmToken::Integer)) {
4885  DEBUG(dbgs() << ".. integer\n");
4886  Operands.push_back(MipsOperand::createNumericReg(
4887  Token.getIntVal(), Token.getString(), getContext().getRegisterInfo(), S,
4888  Token.getLoc(), *this));
4889  return MatchOperand_Success;
4890  }
4891 
4892  DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
4893 
4894  return MatchOperand_NoMatch;
4895 }
4896 
4898 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
4899  MCAsmParser &Parser = getParser();
4900  DEBUG(dbgs() << "parseAnyRegister\n");
4901 
4902  auto Token = Parser.getTok();
4903 
4904  SMLoc S = Token.getLoc();
4905 
4906  if (Token.isNot(AsmToken::Dollar)) {
4907  DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
4908  if (Token.is(AsmToken::Identifier)) {
4909  if (searchSymbolAlias(Operands))
4910  return MatchOperand_Success;
4911  }
4912  DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
4913  return MatchOperand_NoMatch;
4914  }
4915  DEBUG(dbgs() << ".. $\n");
4916 
4917  OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
4918  if (ResTy == MatchOperand_Success) {
4919  Parser.Lex(); // $
4920  Parser.Lex(); // identifier
4921  }
4922  return ResTy;
4923 }
4924 
4926 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
4927  MCAsmParser &Parser = getParser();
4928  DEBUG(dbgs() << "parseJumpTarget\n");
4929 
4930  SMLoc S = getLexer().getLoc();
4931 
4932  // Registers are a valid target and have priority over symbols.
4933  OperandMatchResultTy ResTy = parseAnyRegister(Operands);
4934  if (ResTy != MatchOperand_NoMatch)
4935  return ResTy;
4936 
4937  // Integers and expressions are acceptable
4938  const MCExpr *Expr = nullptr;
4939  if (Parser.parseExpression(Expr)) {
4940  // We have no way of knowing if a symbol was consumed so we must ParseFail
4941  return MatchOperand_ParseFail;
4942  }
4943  Operands.push_back(
4944  MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
4945  return MatchOperand_Success;
4946 }
4947 
4949 MipsAsmParser::parseInvNum(OperandVector &Operands) {
4950  MCAsmParser &Parser = getParser();
4951  const MCExpr *IdVal;
4952  // If the first token is '$' we may have register operand.
4953  if (Parser.getTok().is(AsmToken::Dollar))
4954  return MatchOperand_NoMatch;
4955  SMLoc S = Parser.getTok().getLoc();
4956  if (getParser().parseExpression(IdVal))
4957  return MatchOperand_ParseFail;
4958  const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
4959  assert(MCE && "Unexpected MCExpr type.");
4960  int64_t Val = MCE->getValue();
4961  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4962  Operands.push_back(MipsOperand::CreateImm(
4963  MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
4964  return MatchOperand_Success;
4965 }
4966 
4968 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
4969  MCAsmParser &Parser = getParser();
4971  unsigned RegNo;
4972  unsigned PrevReg = Mips::NoRegister;
4973  bool RegRange = false;
4975 
4976  if (Parser.getTok().isNot(AsmToken::Dollar))
4977  return MatchOperand_ParseFail;
4978 
4979  SMLoc S = Parser.getTok().getLoc();
4980  while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
4981  SMLoc E = getLexer().getLoc();
4982  MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
4983  RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
4984  if (RegRange) {
4985  // Remove last register operand because registers from register range
4986  // should be inserted first.
4987  if ((isGP64bit() && RegNo == Mips::RA_64) ||
4988  (!isGP64bit() && RegNo == Mips::RA)) {
4989  Regs.push_back(RegNo);
4990  } else {
4991  unsigned TmpReg = PrevReg + 1;
4992  while (TmpReg <= RegNo) {
4993  if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
4994  (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
4995  isGP64bit())) {
4996  Error(E, "invalid register operand");
4997  return MatchOperand_ParseFail;
4998  }
4999 
5000  PrevReg = TmpReg;
5001  Regs.push_back(TmpReg++);
5002  }
5003  }
5004 
5005  RegRange = false;
5006  } else {
5007  if ((PrevReg == Mips::NoRegister) &&
5008  ((isGP64bit() && (RegNo != Mips::S0_64) && (RegNo != Mips::RA_64)) ||
5009  (!isGP64bit() && (RegNo != Mips::S0) && (RegNo != Mips::RA)))) {
5010  Error(E, "$16 or $31 expected");
5011  return MatchOperand_ParseFail;
5012  } else if (!(((RegNo == Mips::FP || RegNo == Mips::RA ||
5013  (RegNo >= Mips::S0 && RegNo <= Mips::S7)) &&
5014  !isGP64bit()) ||
5015  ((RegNo == Mips::FP_64 || RegNo == Mips::RA_64 ||
5016  (RegNo >= Mips::S0_64 && RegNo <= Mips::S7_64)) &&
5017  isGP64bit()))) {
5018  Error(E, "invalid register operand");
5019  return MatchOperand_ParseFail;
5020  } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
5021  ((RegNo != Mips::FP && RegNo != Mips::RA && !isGP64bit()) ||
5022  (RegNo != Mips::FP_64 && RegNo != Mips::RA_64 &&
5023  isGP64bit()))) {
5024  Error(E, "consecutive register numbers expected");
5025  return MatchOperand_ParseFail;
5026  }
5027 
5028  Regs.push_back(RegNo);
5029  }
5030 
5031  if (Parser.getTok().is(AsmToken::Minus))
5032  RegRange = true;
5033 
5034  if (!Parser.getTok().isNot(AsmToken::Minus) &&
5035  !Parser.getTok().isNot(AsmToken::Comma)) {
5036  Error(E, "',' or '-' expected");
5037  return MatchOperand_ParseFail;
5038  }
5039 
5040  Lex(); // Consume comma or minus
5041  if (Parser.getTok().isNot(AsmToken::Dollar))
5042  break;
5043 
5044  PrevReg = RegNo;
5045  }
5046 
5047  SMLoc E = Parser.getTok().getLoc();
5048  Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
5049  parseMemOperand(Operands);
5050  return MatchOperand_Success;
5051 }
5052 
5054 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
5055  MCAsmParser &Parser = getParser();
5056 
5057  SMLoc S = Parser.getTok().getLoc();
5058  if (parseAnyRegister(Operands) != MatchOperand_Success)
5059  return MatchOperand_ParseFail;
5060 
5061  SMLoc E = Parser.getTok().getLoc();
5062  MipsOperand Op = static_cast<MipsOperand &>(*Operands.back());
5063 
5064  Operands.pop_back();
5065  Operands.push_back(MipsOperand::CreateRegPair(Op, S, E, *this));
5066  return MatchOperand_Success;
5067 }
5068 
5070 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
5071  MCAsmParser &Parser = getParser();
5074 
5075  if (Parser.getTok().isNot(AsmToken::Dollar))
5076  return MatchOperand_ParseFail;
5077 
5078  SMLoc S = Parser.getTok().getLoc();
5079 
5080  if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
5081  return MatchOperand_ParseFail;
5082 
5083  MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
5084  unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
5085  Regs.push_back(RegNo);
5086 
5087  SMLoc E = Parser.getTok().getLoc();
5088  if (Parser.getTok().isNot(AsmToken::Comma)) {
5089  Error(E, "',' expected");
5090  return MatchOperand_ParseFail;
5091  }
5092 
5093  // Remove comma.
5094  Parser.Lex();
5095 
5096  if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
5097  return MatchOperand_ParseFail;
5098 
5099  Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
5100  RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
5101  Regs.push_back(RegNo);
5102 
5103  Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
5104 
5105  return MatchOperand_Success;
5106 }
5107 
5108 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
5109 /// either this.
5110 /// ::= '(', register, ')'
5111 /// handle it before we iterate so we don't get tripped up by the lack of
5112 /// a comma.
5113 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
5114  MCAsmParser &Parser = getParser();
5115  if (getLexer().is(AsmToken::LParen)) {
5116  Operands.push_back(
5117  MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
5118  Parser.Lex();
5119  if (parseOperand(Operands, Name)) {
5120  SMLoc Loc = getLexer().getLoc();
5121  return Error(Loc, "unexpected token in argument list");
5122  }
5123  if (Parser.getTok().isNot(AsmToken::RParen)) {
5124  SMLoc Loc = getLexer().getLoc();
5125  return Error(Loc, "unexpected token, expected ')'");
5126  }
5127  Operands.push_back(
5128  MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
5129  Parser.Lex();
5130  }
5131  return false;
5132 }
5133 
5134 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
5135 /// either one of these.
5136 /// ::= '[', register, ']'
5137 /// ::= '[', integer, ']'
5138 /// handle it before we iterate so we don't get tripped up by the lack of
5139 /// a comma.
5140 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
5141  OperandVector &Operands) {
5142  MCAsmParser &Parser = getParser();
5143  if (getLexer().is(AsmToken::LBrac)) {
5144  Operands.push_back(
5145  MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
5146  Parser.Lex();
5147  if (parseOperand(Operands, Name)) {
5148  SMLoc Loc = getLexer().getLoc();
5149  return Error(Loc, "unexpected token in argument list");
5150  }
5151  if (Parser.getTok().isNot(AsmToken::RBrac)) {
5152  SMLoc Loc = getLexer().getLoc();
5153  return Error(Loc, "unexpected token, expected ']'");
5154  }
5155  Operands.push_back(
5156  MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
5157  Parser.Lex();
5158  }
5159  return false;
5160 }
5161 
5162 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
5163  SMLoc NameLoc, OperandVector &Operands) {
5164  MCAsmParser &Parser = getParser();
5165  DEBUG(dbgs() << "ParseInstruction\n");
5166 
5167  // We have reached first instruction, module directive are now forbidden.
5168  getTargetStreamer().forbidModuleDirective();
5169 
5170  // Check if we have valid mnemonic
5171  if (!mnemonicIsValid(Name, 0)) {
5172  return Error(NameLoc, "unknown instruction");
5173  }
5174  // First operand in MCInst is instruction mnemonic.
5175  Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
5176 
5177  // Read the remaining operands.
5178  if (getLexer().isNot(AsmToken::EndOfStatement)) {
5179  // Read the first operand.
5180  if (parseOperand(Operands, Name)) {
5181  SMLoc Loc = getLexer().getLoc();
5182  return Error(Loc, "unexpected token in argument list");
5183  }
5184  if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
5185  return true;
5186  // AFAIK, parenthesis suffixes are never on the first operand
5187 
5188  while (getLexer().is(AsmToken::Comma)) {
5189  Parser.Lex(); // Eat the comma.
5190  // Parse and remember the operand.
5191  if (parseOperand(Operands, Name)) {
5192  SMLoc Loc = getLexer().getLoc();
5193  return Error(Loc, "unexpected token in argument list");
5194  }
5195  // Parse bracket and parenthesis suffixes before we iterate
5196  if (getLexer().is(AsmToken::LBrac)) {
5197  if (parseBracketSuffix(Name, Operands))
5198  return true;
5199  } else if (getLexer().is(AsmToken::LParen) &&
5200  parseParenSuffix(Name, Operands))
5201  return true;
5202  }
5203  }
5204  if (getLexer().isNot(AsmToken::EndOfStatement)) {
5205  SMLoc Loc = getLexer().getLoc();
5206  return Error(Loc, "unexpected token in argument list");
5207  }
5208  Parser.Lex(); // Consume the EndOfStatement.
5209  return false;
5210 }
5211 
5212 // FIXME: Given that these have the same name, these should both be
5213 // consistent on affecting the Parser.
5214 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
5215  SMLoc Loc = getLexer().getLoc();
5216  return Error(Loc, ErrorMsg);
5217 }
5218 
5219 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
5220  return Error(Loc, ErrorMsg);
5221 }
5222 
5223 bool MipsAsmParser::parseSetNoAtDirective() {
5224  MCAsmParser &Parser = getParser();
5225  // Line should look like: ".set noat".
5226 
5227  // Set the $at register to $0.
5228  AssemblerOptions.back()->setATRegIndex(0);
5229 
5230  Parser.Lex(); // Eat "noat".
5231 
5232  // If this is not the end of the statement, report an error.
5233  if (getLexer().isNot(AsmToken::EndOfStatement)) {
5234  reportParseError("unexpected token, expected end of statement");
5235  return false;
5236  }
5237 
5238  getTargetStreamer().emitDirectiveSetNoAt();
5239  Parser.Lex(); // Consume the EndOfStatement.
5240  return false;
5241 }
5242 
5243 bool MipsAsmParser::parseSetAtDirective() {
5244  // Line can be: ".set at", which sets $at to $1
5245  // or ".set at=$reg", which sets $at to $reg.
5246  MCAsmParser &Parser = getParser();
5247  Parser.Lex(); // Eat "at".
5248 
5249  if (getLexer().is(AsmToken::EndOfStatement)) {
5250  // No register was specified, so we set $at to $1.
5251  AssemblerOptions.back()->setATRegIndex(1);
5252 
5253  getTargetStreamer().emitDirectiveSetAt();
5254  Parser.Lex(); // Consume the EndOfStatement.
5255  return false;
5256  }
5257 
5258  if (getLexer().isNot(AsmToken::Equal)) {
5259  reportParseError("unexpected token, expected equals sign");
5260  return false;
5261  }
5262  Parser.Lex(); // Eat "=".
5263 
5264  if (getLexer().isNot(AsmToken::Dollar)) {
5265  if (getLexer().is(AsmToken::EndOfStatement)) {
5266  reportParseError("no register specified");
5267  return false;
5268  } else {
5269  reportParseError("unexpected token, expected dollar sign '$'");
5270  return false;
5271  }
5272  }
5273  Parser.Lex(); // Eat "$".
5274 
5275  // Find out what "reg" is.
5276  unsigned AtRegNo;
5277  const AsmToken &Reg = Parser.getTok();
5278  if (Reg.is(AsmToken::Identifier)) {
5279  AtRegNo = matchCPURegisterName(Reg.getIdentifier());
5280  } else if (Reg.is(AsmToken::Integer)) {
5281  AtRegNo = Reg.getIntVal();
5282  } else {
5283  reportParseError("unexpected token, expected identifier or integer");
5284  return false;
5285  }
5286 
5287  // Check if $reg is a valid register. If it is, set $at to $reg.
5288  if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
5289  reportParseError("invalid register");
5290  return false;
5291  }
5292  Parser.Lex(); // Eat "reg".
5293 
5294  // If this is not the end of the statement, report an error.
5295  if (getLexer().isNot(AsmToken::EndOfStatement)) {
5296  reportParseError("unexpected token, expected end of statement");
5297  return false;
5298  }
5299 
5300  getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
5301 
5302  Parser.Lex(); // Consume the EndOfStatement.
5303  return false;
5304 }
5305 
5306 bool MipsAsmParser::parseSetReorderDirective() {
5307  MCAsmParser &Parser = getParser();
5308  Parser.Lex();
5309  // If this is not the end of the statement, report an error.
5310  if (getLexer().isNot(AsmToken::EndOfStatement)) {
5311  reportParseError("unexpected token, expected end of statement");
5312  return false;
5313  }
5314  AssemblerOptions.back()->setReorder();
5315  getTargetStreamer().emitDirectiveSetReorder();
5316  Parser.Lex(); // Consume the EndOfStatement.
5317  return false;
5318 }
5319 
5320 bool MipsAsmParser::parseSetNoReorderDirective() {
5321  MCAsmParser &Parser = getParser();
5322  Parser.Lex();
5323  // If this is not the end of the statement, report an error.
5324  if (getLexer().isNot(AsmToken::EndOfStatement)) {
5325  reportParseError("unexpected token, expected end of statement");
5326  return false;
5327  }
5328  AssemblerOptions.back()->setNoReorder();
5329  getTargetStreamer().emitDirectiveSetNoReorder();
5330  Parser.Lex(); // Consume the EndOfStatement.
5331  return false;
5332 }
5333 
5334 bool MipsAsmParser::parseSetMacroDirective() {
5335  MCAsmParser &Parser = getParser();
5336  Parser.Lex();
5337  // If this is not the end of the statement, report an error.
5338  if (getLexer().isNot(AsmToken::EndOfStatement)) {
5339  reportParseError("unexpected token, expected end of statement");
5340  return false;
5341  }
5342  AssemblerOptions.back()->setMacro();
5343  getTargetStreamer().emitDirectiveSetMacro();
5344  Parser.Lex(); // Consume the EndOfStatement.
5345  return false;
5346 }
5347 
5348 bool MipsAsmParser::parseSetNoMacroDirective() {
5349  MCAsmParser &Parser = getParser();
5350  Parser.Lex();
5351  // If this is not the end of the statement, report an error.
5352  if (getLexer().isNot(AsmToken::EndOfStatement)) {
5353  reportParseError("unexpected token, expected end of statement");
5354  return false;
5355  }
5356  if (AssemblerOptions.back()->isReorder()) {
5357  reportParseError("`noreorder' must be set before `nomacro'");
5358  return false;
5359  }
5360  AssemblerOptions.back()->setNoMacro();
5361  getTargetStreamer().emitDirectiveSetNoMacro();
5362  Parser.Lex(); // Consume the EndOfStatement.
5363  return false;
5364 }
5365 
5366 bool MipsAsmParser::parseSetMsaDirective() {
5367  MCAsmParser &Parser = getParser();
5368  Parser.Lex();
5369 
5370  // If this is not the end of the statement, report an error.
5371  if (getLexer().isNot(AsmToken::EndOfStatement))
5372  return reportParseError("unexpected token, expected end of statement");
5373 
5374  setFeatureBits(Mips::FeatureMSA, "msa");
5375  getTargetStreamer().emitDirectiveSetMsa();
5376  return false;
5377 }
5378 
5379 bool MipsAsmParser::parseSetNoMsaDirective() {
5380  MCAsmParser &Parser = getParser();
5381  Parser.Lex();
5382 
5383  // If this is not the end of the statement, report an error.
5384  if (getLexer().isNot(AsmToken::EndOfStatement))
5385  return reportParseError("unexpected token, expected end of statement");
5386 
5387  clearFeatureBits(Mips::FeatureMSA, "msa");
5388  getTargetStreamer().emitDirectiveSetNoMsa();
5389  return false;
5390 }
5391 
5392 bool MipsAsmParser::parseSetNoDspDirective() {
5393  MCAsmParser &Parser = getParser();
5394  Parser.Lex(); // Eat "nodsp".
5395 
5396  // If this is not the end of the statement, report an error.
5397  if (getLexer().isNot(AsmToken::EndOfStatement)) {
5398  reportParseError("unexpected token, expected end of statement");
5399  return false;
5400  }
5401 
5402  clearFeatureBits(Mips::FeatureDSP, "dsp");
5403  getTargetStreamer().emitDirectiveSetNoDsp();
5404  return false;
5405 }
5406 
5407 bool MipsAsmParser::parseSetMips16Directive() {
5408  MCAsmParser &Parser = getParser();
5409  Parser.Lex(); // Eat "mips16".
5410 
5411  // If this is not the end of the statement, report an error.
5412  if (getLexer().isNot(AsmToken::EndOfStatement)) {
5413  reportParseError("unexpected token, expected end of statement");
5414  return false;
5415  }
5416 
5417  setFeatureBits(Mips::FeatureMips16, "mips16");
5418  getTargetStreamer().emitDirectiveSetMips16();
5419  Parser.Lex(); // Consume the EndOfStatement.
5420  return false;
5421 }
5422 
5423 bool MipsAsmParser::parseSetNoMips16Directive() {
5424  MCAsmParser &Parser = getParser();
5425  Parser.Lex(); // Eat "nomips16".
5426 
5427  // If this is not the end of the statement, report an error.
5428  if (getLexer().isNot(AsmToken::EndOfStatement)) {
5429  reportParseError("unexpected token, expected end of statement");
5430  return false;
5431  }
5432 
5433  clearFeatureBits(Mips::FeatureMips16, "mips16");
5434  getTargetStreamer().emitDirectiveSetNoMips16();
5435  Parser.Lex(); // Consume the EndOfStatement.
5436  return false;
5437 }
5438 
5439 bool MipsAsmParser::parseSetFpDirective() {
5440  MCAsmParser &Parser = getParser();
5442  // Line can be: .set fp=32
5443  // .set fp=xx
5444  // .set fp=64
5445  Parser.Lex(); // Eat fp token
5446  AsmToken Tok = Parser.getTok();
5447  if (Tok.isNot(AsmToken::Equal)) {
5448  reportParseError("unexpected token, expected equals sign '='");
5449  return false;
5450  }
5451  Parser.Lex(); // Eat '=' token.
5452  Tok = Parser.getTok();
5453 
5454  if (!parseFpABIValue(FpAbiVal, ".set"))
5455  return false;
5456 
5457  if (getLexer().isNot(AsmToken::EndOfStatement)) {
5458  reportParseError("unexpected token, expected end of statement");
5459  return false;
5460  }
5461  getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
5462  Parser.Lex(); // Consume the EndOfStatement.
5463  return false;
5464 }
5465 
5466 bool MipsAsmParser::parseSetOddSPRegDirective() {
5467  MCAsmParser &Parser = getParser();
5468 
5469  Parser.Lex(); // Eat "oddspreg".
5470  if (getLexer().isNot(AsmToken::EndOfStatement)) {
5471  reportParseError("unexpected token, expected end of statement");
5472  return false;
5473  }
5474 
5475  clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5476  getTargetStreamer().emitDirectiveSetOddSPReg();
5477  return false;
5478 }
5479 
5480 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
5481  MCAsmParser &Parser = getParser();
5482 
5483  Parser.Lex(); // Eat "nooddspreg".
5484  if (getLexer().isNot(AsmToken::EndOfStatement)) {
5485  reportParseError("unexpected token, expected end of statement");
5486  return false;
5487  }
5488 
5489  setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5490  getTargetStreamer().emitDirectiveSetNoOddSPReg();
5491  return false;
5492 }
5493 
5494 bool MipsAsmParser::parseSetPopDirective() {
5495  MCAsmParser &Parser = getParser();
5496  SMLoc Loc = getLexer().getLoc();
5497 
5498  Parser.Lex();
5499  if (getLexer().isNot(AsmToken::EndOfStatement))
5500  return reportParseError("unexpected token, expected end of statement");
5501 
5502  // Always keep an element on the options "stack" to prevent the user
5503  // from changing the initial options. This is how we remember them.
5504  if (AssemblerOptions.size() == 2)
5505  return reportParseError(Loc, ".set pop with no .set push");
5506 
5507  MCSubtargetInfo &STI = copySTI();
5508  AssemblerOptions.pop_back();
5509  setAvailableFeatures(
5510  ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
5511  STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
5512 
5513  getTargetStreamer().emitDirectiveSetPop();
5514  return false;
5515 }
5516 
5517 bool MipsAsmParser::parseSetPushDirective() {
5518  MCAsmParser &Parser = getParser();
5519  Parser.Lex();
5520  if (getLexer().isNot(AsmToken::EndOfStatement))
5521  return reportParseError("unexpected token, expected end of statement");
5522 
5523  // Create a copy of the current assembler options environment and push it.
5524  AssemblerOptions.push_back(
5525  make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
5526 
5527  getTargetStreamer().emitDirectiveSetPush();
5528  return false;
5529 }
5530 
5531 bool MipsAsmParser::parseSetSoftFloatDirective() {
5532  MCAsmParser &Parser = getParser();
5533  Parser.Lex();
5534  if (getLexer().isNot(AsmToken::EndOfStatement))
5535  return reportParseError("unexpected token, expected end of statement");
5536 
5537  setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5538  getTargetStreamer().emitDirectiveSetSoftFloat();
5539  return false;
5540 }
5541 
5542 bool MipsAsmParser::parseSetHardFloatDirective() {
5543  MCAsmParser &Parser = getParser();
5544  Parser.Lex();
5545  if (getLexer().isNot(AsmToken::EndOfStatement))
5546  return reportParseError("unexpected token, expected end of statement");
5547 
5548  clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5549  getTargetStreamer().emitDirectiveSetHardFloat();
5550  return false;
5551 }
5552 
5553 bool MipsAsmParser::parseSetAssignment() {
5554  StringRef Name;
5555  const MCExpr *Value;
5556  MCAsmParser &Parser = getParser();
5557 
5558  if (Parser.parseIdentifier(Name))
5559  reportParseError("expected identifier after .set");
5560 
5561  if (getLexer().isNot(AsmToken::Comma))
5562  return reportParseError("unexpected token, expected comma");
5563  Lex(); // Eat comma
5564 
5565  if (Parser.parseExpression(Value))
5566  return reportParseError("expected valid expression after comma");
5567 
5568  MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
5569  Sym->setVariableValue(Value);
5570 
5571  return false;
5572 }
5573 
5574 bool MipsAsmParser::parseSetMips0Directive() {
5575  MCAsmParser &Parser = getParser();
5576  Parser.Lex();
5577  if (getLexer().isNot(AsmToken::EndOfStatement))
5578  return reportParseError("unexpected token, expected end of statement");
5579 
5580  // Reset assembler options to their initial values.
5581  MCSubtargetInfo &STI = copySTI();
5582  setAvailableFeatures(
5583  ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
5584  STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
5585  AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
5586 
5587  getTargetStreamer().emitDirectiveSetMips0();
5588  return false;
5589 }
5590 
5591 bool MipsAsmParser::parseSetArchDirective() {
5592  MCAsmParser &Parser = getParser();
5593  Parser.Lex();
5594  if (getLexer().isNot(AsmToken::Equal))
5595  return reportParseError("unexpected token, expected equals sign");
5596 
5597  Parser.Lex();
5598  StringRef Arch;
5599  if (Parser.parseIdentifier(Arch))
5600  return reportParseError("expected arch identifier");
5601 
5602  StringRef ArchFeatureName =
5604  .Case("mips1", "mips1")
5605  .Case("mips2", "mips2")
5606  .Case("mips3", "mips3")
5607  .Case("mips4", "mips4")
5608  .Case("mips5", "mips5")
5609  .Case("mips32", "mips32")
5610  .Case("mips32r2", "mips32r2")
5611  .Case("mips32r3", "mips32r3")
5612  .Case("mips32r5", "mips32r5")
5613  .Case("mips32r6", "mips32r6")
5614  .Case("mips64", "mips64")
5615  .Case("mips64r2", "mips64r2")
5616  .Case("mips64r3", "mips64r3")
5617  .Case("mips64r5", "mips64r5")
5618  .Case("mips64r6", "mips64r6")
5619  .Case("octeon", "cnmips")
5620  .Case("r4000", "mips3") // This is an implementation of Mips3.
5621  .Default("");
5622 
5623  if (ArchFeatureName.empty())
5624  return reportParseError("unsupported architecture");
5625 
5626  selectArch(ArchFeatureName);
5627  getTargetStreamer().emitDirectiveSetArch(Arch);
5628  return false;
5629 }
5630 
5631 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
5632  MCAsmParser &Parser = getParser();
5633  Parser.Lex();
5634  if (getLexer().isNot(AsmToken::EndOfStatement))
5635  return reportParseError("unexpected token, expected end of statement");
5636 
5637  switch (Feature) {
5638  default:
5639  llvm_unreachable("Unimplemented feature");
5640  case Mips::FeatureDSP:
5641  setFeatureBits(Mips::FeatureDSP, "dsp");
5642  getTargetStreamer().emitDirectiveSetDsp();
5643  break;
5644  case Mips::FeatureMicroMips:
5645  setFeatureBits(Mips::FeatureMicroMips, "micromips");
5646  getTargetStreamer().emitDirectiveSetMicroMips();
5647  break;
5648  case Mips::FeatureMips1:
5649  selectArch("mips1");
5650  getTargetStreamer().emitDirectiveSetMips1();
5651  break;
5652  case Mips::FeatureMips2:
5653  selectArch("mips2");
5654  getTargetStreamer().emitDirectiveSetMips2();
5655  break;
5656  case Mips::FeatureMips3:
5657  selectArch("mips3");
5658  getTargetStreamer().emitDirectiveSetMips3();
5659  break;
5660  case Mips::FeatureMips4:
5661  selectArch("mips4");
5662  getTargetStreamer().emitDirectiveSetMips4();
5663  break;
5664  case Mips::FeatureMips5:
5665  selectArch("mips5");
5666  getTargetStreamer().emitDirectiveSetMips5();
5667  break;
5668  case Mips::FeatureMips32:
5669  selectArch("mips32");
5670  getTargetStreamer().emitDirectiveSetMips32();
5671  break;
5672  case Mips::FeatureMips32r2:
5673  selectArch("mips32r2");
5674  getTargetStreamer().emitDirectiveSetMips32R2();
5675  break;
5676  case Mips::FeatureMips32r3:
5677  selectArch("mips32r3");
5678  getTargetStreamer().emitDirectiveSetMips32R3();
5679  break;
5680  case Mips::FeatureMips32r5:
5681  selectArch("mips32r5");
5682  getTargetStreamer().emitDirectiveSetMips32R5();
5683  break;
5684  case Mips::FeatureMips32r6:
5685  selectArch("mips32r6");
5686  getTargetStreamer().emitDirectiveSetMips32R6();
5687  break;
5688  case Mips::FeatureMips64:
5689  selectArch("mips64");
5690  getTargetStreamer().emitDirectiveSetMips64();
5691  break;
5692  case Mips::FeatureMips64r2:
5693  selectArch("mips64r2");
5694  getTargetStreamer().emitDirectiveSetMips64R2();
5695  break;
5696  case Mips::FeatureMips64r3:
5697  selectArch("mips64r3");
5698  getTargetStreamer().emitDirectiveSetMips64R3();
5699  break;
5700  case Mips::FeatureMips64r5:
5701  selectArch("mips64r5");
5702  getTargetStreamer().emitDirectiveSetMips64R5();
5703  break;
5704  case Mips::FeatureMips64r6:
5705  selectArch("mips64r6");
5706  getTargetStreamer().emitDirectiveSetMips64R6();
5707  break;
5708  }
5709  return false;
5710 }
5711 
5712 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
5713  MCAsmParser &Parser = getParser();
5714  if (getLexer().isNot(AsmToken::Comma)) {
5715  SMLoc Loc = getLexer().getLoc();
5716  return Error(Loc, ErrorStr);
5717  }
5718 
5719  Parser.Lex(); // Eat the comma.
5720  return true;
5721 }
5722 
5723 // Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
5724 // In this class, it is only used for .cprestore.
5725 // FIXME: Only keep track of IsPicEnabled in one place, instead of in both
5726 // MipsTargetELFStreamer and MipsAsmParser.
5727 bool MipsAsmParser::isPicAndNotNxxAbi() {
5728  return inPicMode() && !(isABI_N32() || isABI_N64());
5729 }
5730 
5731 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
5732  if (AssemblerOptions.back()->isReorder())
5733  Warning(Loc, ".cpload should be inside a noreorder section");
5734 
5735  if (inMips16Mode()) {
5736  reportParseError(".cpload is not supported in Mips16 mode");
5737  return false;
5738  }
5739 
5741  OperandMatchResultTy ResTy = parseAnyRegister(Reg);
5742  if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5743  reportParseError("expected register containing function address");
5744  return false;
5745  }
5746 
5747  MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
5748  if (!RegOpnd.isGPRAsmReg()) {
5749  reportParseError(RegOpnd.getStartLoc(), "invalid register");
5750  return false;
5751  }
5752 
5753  // If this is not the end of the statement, report an error.
5754  if (getLexer().isNot(AsmToken::EndOfStatement)) {
5755  reportParseError("unexpected token, expected end of statement");
5756  return false;
5757  }
5758 
5759  getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
5760  return false;
5761 }
5762 
5763 bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
5764  MCAsmParser &Parser = getParser();
5765 
5766  // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
5767  // is used in non-PIC mode.
5768 
5769  if (inMips16Mode()) {
5770  reportParseError(".cprestore is not supported in Mips16 mode");
5771  return false;
5772  }
5773 
5774  // Get the stack offset value.
5775  const MCExpr *StackOffset;
5776  int64_t StackOffsetVal;
5777  if (Parser.parseExpression(StackOffset)) {
5778  reportParseError("expected stack offset value");
5779  return false;
5780  }
5781 
5782  if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
5783  reportParseError("stack offset is not an absolute expression");
5784  return false;
5785  }
5786 
5787  if (StackOffsetVal < 0) {
5788  Warning(Loc, ".cprestore with negative stack offset has no effect");
5789  IsCpRestoreSet = false;
5790  } else {
5791  IsCpRestoreSet = true;
5792  CpRestoreOffset = StackOffsetVal;
5793  }
5794 
5795  // If this is not the end of the statement, report an error.
5796  if (getLexer().isNot(AsmToken::EndOfStatement)) {
5797  reportParseError("unexpected token, expected end of statement");
5798  return false;
5799  }
5800 
5801  if (!getTargetStreamer().emitDirectiveCpRestore(
5802  CpRestoreOffset, [&]() { return getATReg(Loc); }, Loc, STI))
5803  return true;
5804  Parser.Lex(); // Consume the EndOfStatement.
5805  return false;
5806 }
5807 
5808 bool MipsAsmParser::parseDirectiveCPSetup() {
5809  MCAsmParser &Parser = getParser();
5810  unsigned FuncReg;
5811  unsigned Save;
5812  bool SaveIsReg = true;
5813 
5815  OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5816  if (ResTy == MatchOperand_NoMatch) {
5817  reportParseError("expected register containing function address");
5818  return false;
5819  }
5820 
5821  MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5822  if (!FuncRegOpnd.isGPRAsmReg()) {
5823  reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
5824  return false;
5825  }
5826 
5827  FuncReg = FuncRegOpnd.getGPR32Reg();
5828  TmpReg.clear();
5829 
5830  if (!eatComma("unexpected token, expected comma"))
5831  return true;
5832 
5833  ResTy = parseAnyRegister(TmpReg);
5834  if (ResTy == MatchOperand_NoMatch) {
5835  const MCExpr *OffsetExpr;
5836  int64_t OffsetVal;
5837  SMLoc ExprLoc = getLexer().getLoc();
5838 
5839  if (Parser.parseExpression(OffsetExpr) ||
5840  !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
5841  reportParseError(ExprLoc, "expected save register or stack offset");
5842  return false;
5843  }
5844 
5845  Save = OffsetVal;
5846  SaveIsReg = false;
5847  } else {
5848  MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5849  if (!SaveOpnd.isGPRAsmReg()) {
5850  reportParseError(SaveOpnd.getStartLoc(), "invalid register");
5851  return false;
5852  }
5853  Save = SaveOpnd.getGPR32Reg();
5854  }
5855 
5856  if (!eatComma("unexpected token, expected comma"))
5857  return true;
5858 
5859  const MCExpr *Expr;
5860  if (Parser.parseExpression(Expr)) {
5861  reportParseError("expected expression");
5862  return false;
5863  }
5864 
5865  if (Expr->getKind() != MCExpr::SymbolRef) {
5866  reportParseError("expected symbol");
5867  return false;
5868  }
5869  const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
5870 
5871  CpSaveLocation = Save;
5872  CpSaveLocationIsRegister = SaveIsReg;
5873 
5874  getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
5875  SaveIsReg);
5876  return false;
5877 }
5878 
5879 bool MipsAsmParser::parseDirectiveCPReturn() {
5880  getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
5881  CpSaveLocationIsRegister);
5882  return false;
5883 }
5884 
5885 bool MipsAsmParser::parseDirectiveNaN() {
5886  MCAsmParser &Parser = getParser();
5887  if (getLexer().isNot(AsmToken::EndOfStatement)) {
5888  const AsmToken &Tok = Parser.getTok();
5889 
5890  if (Tok.getString() == "2008") {
5891  Parser.Lex();
5892  getTargetStreamer().emitDirectiveNaN2008();
5893  return false;
5894  } else if (Tok.getString() == "legacy") {
5895  Parser.Lex();
5896  getTargetStreamer().emitDirectiveNaNLegacy();
5897  return false;
5898  }
5899  }
5900  // If we don't recognize the option passed to the .nan
5901  // directive (e.g. no option or unknown option), emit an error.
5902  reportParseError("invalid option in .nan directive");
5903  return false;
5904 }
5905 
5906 bool MipsAsmParser::parseDirectiveSet() {
5907  MCAsmParser &Parser = getParser();
5908  // Get the next token.
5909  const AsmToken &Tok = Parser.getTok();
5910 
5911  if (Tok.getString() == "noat") {
5912  return parseSetNoAtDirective();
5913  } else if (Tok.getString() == "at") {
5914  return parseSetAtDirective();
5915  } else if (Tok.getString() == "arch") {
5916  return parseSetArchDirective();
5917  } else if (Tok.getString() == "fp") {
5918  return parseSetFpDirective();
5919  } else if (Tok.getString() == "oddspreg") {
5920  return parseSetOddSPRegDirective();
5921  } else if (Tok.getString() == "nooddspreg") {
5922  return parseSetNoOddSPRegDirective();
5923  } else if (Tok.getString() == "pop") {
5924  return parseSetPopDirective();
5925  } else if (Tok.getString() == "push") {
5926  return parseSetPushDirective();
5927  } else if (Tok.getString() == "reorder") {
5928  return parseSetReorderDirective();
5929  } else if (Tok.getString() == "noreorder") {
5930  return parseSetNoReorderDirective();
5931  } else if (Tok.getString() == "macro") {
5932  return parseSetMacroDirective();
5933  } else if (Tok.getString() == "nomacro") {
5934  return parseSetNoMacroDirective();
5935  } else if (Tok.getString() == "mips16") {
5936  return parseSetMips16Directive();
5937  } else if (Tok.getString() == "nomips16") {
5938  return parseSetNoMips16Directive();
5939  } else if (Tok.getString() == "nomicromips") {
5940  clearFeatureBits(Mips::FeatureMicroMips, "micromips");
5941  getTargetStreamer().emitDirectiveSetNoMicroMips();
5942  Parser.eatToEndOfStatement();
5943  return false;
5944  } else if (Tok.getString() == "micromips") {
5945  return parseSetFeature(Mips::FeatureMicroMips);
5946  } else if (Tok.getString() == "mips0") {
5947  return parseSetMips0Directive();
5948  } else if (Tok.getString() == "mips1") {
5949  return parseSetFeature(Mips::FeatureMips1);
5950  } else if (Tok.getString() == "mips2") {
5951  return parseSetFeature(Mips::FeatureMips2);
5952  } else if (Tok.getString() == "mips3") {
5953  return parseSetFeature(Mips::FeatureMips3);
5954  } else if (Tok.getString() == "mips4") {
5955  return parseSetFeature(Mips::FeatureMips4);
5956  } else if (Tok.getString() == "mips5") {
5957  return parseSetFeature(Mips::FeatureMips5);
5958  } else if (Tok.getString() == "mips32") {
5959  return parseSetFeature(Mips::FeatureMips32);
5960  } else if (Tok.getString() == "mips32r2") {
5961  return parseSetFeature(Mips::FeatureMips32r2);
5962  } else if (Tok.getString() == "mips32r3") {
5963  return parseSetFeature(Mips::FeatureMips32r3);
5964  } else if (Tok.getString() == "mips32r5") {
5965  return parseSetFeature(Mips::FeatureMips32r5);
5966  } else if (Tok.getString() == "mips32r6") {
5967  return parseSetFeature(Mips::FeatureMips32r6);
5968  } else if (Tok.getString() == "mips64") {
5969  return parseSetFeature(Mips::FeatureMips64);
5970  } else if (Tok.getString() == "mips64r2") {
5971  return parseSetFeature(Mips::FeatureMips64r2);
5972  } else if (Tok.getString() == "mips64r3") {
5973  return parseSetFeature(Mips::FeatureMips64r3);
5974  } else if (Tok.getString() == "mips64r5") {
5975  return parseSetFeature(Mips::FeatureMips64r5);
5976  } else if (Tok.getString() == "mips64r6") {
5977  return parseSetFeature(Mips::FeatureMips64r6);
5978  } else if (Tok.getString() == "dsp") {
5979  return parseSetFeature(Mips::FeatureDSP);
5980  } else if (Tok.getString() == "nodsp") {
5981  return parseSetNoDspDirective();
5982  } else if (Tok.getString() == "msa") {
5983  return parseSetMsaDirective();
5984  } else if (Tok.getString() == "nomsa") {
5985  return parseSetNoMsaDirective();
5986  } else if (Tok.getString() == "softfloat") {
5987  return parseSetSoftFloatDirective();
5988  } else if (Tok.getString() == "hardfloat") {
5989  return parseSetHardFloatDirective();
5990  } else {
5991  // It is just an identifier, look for an assignment.
5992  parseSetAssignment();
5993  return false;
5994  }
5995 
5996  return true;
5997 }
5998 
5999 /// parseDataDirective
6000 /// ::= .word [ expression (, expression)* ]
6001 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
6002  MCAsmParser &Parser = getParser();
6003  if (getLexer().isNot(AsmToken::EndOfStatement)) {
6004  for (;;) {
6005  const MCExpr *Value;
6006  if (getParser().parseExpression(Value))
6007  return true;
6008 
6009  getParser().getStreamer().EmitValue(Value, Size);
6010 
6011  if (getLexer().is(AsmToken::EndOfStatement))
6012  break;
6013 
6014  if (getLexer().isNot(AsmToken::Comma))
6015  return Error(L, "unexpected token, expected comma");
6016  Parser.Lex();
6017  }
6018  }
6019 
6020  Parser.Lex();
6021  return false;
6022 }
6023 
6024 /// parseDirectiveGpWord
6025 /// ::= .gpword local_sym
6026 bool MipsAsmParser::parseDirectiveGpWord() {
6027  MCAsmParser &Parser = getParser();
6028  const MCExpr *Value;
6029  // EmitGPRel32Value requires an expression, so we are using base class
6030  // method to evaluate the expression.
6031  if (getParser().parseExpression(Value))
6032  return true;
6033  getParser().getStreamer().EmitGPRel32Value(Value);
6034 
6035  if (getLexer().isNot(AsmToken::EndOfStatement))
6036  return Error(getLexer().getLoc(),
6037  "unexpected token, expected end of statement");
6038  Parser.Lex(); // Eat EndOfStatement token.
6039  return false;
6040 }
6041 
6042 /// parseDirectiveGpDWord
6043 /// ::= .gpdword local_sym
6044 bool MipsAsmParser::parseDirectiveGpDWord() {
6045  MCAsmParser &Parser = getParser();
6046  const MCExpr *Value;
6047  // EmitGPRel64Value requires an expression, so we are using base class
6048  // method to evaluate the expression.
6049  if (getParser().parseExpression(Value))
6050  return true;
6051  getParser().getStreamer().EmitGPRel64Value(Value);
6052 
6053  if (getLexer().isNot(AsmToken::EndOfStatement))
6054  return Error(getLexer().getLoc(),
6055  "unexpected token, expected end of statement");
6056  Parser.Lex(); // Eat EndOfStatement token.
6057  return false;
6058 }
6059 
6060 /// parseDirectiveDtpRelWord
6061 /// ::= .dtprelword tls_sym
6062 bool MipsAsmParser::parseDirectiveDtpRelWord() {
6063  MCAsmParser &Parser = getParser();
6064  const MCExpr *Value;
6065  // EmitDTPRel32Value requires an expression, so we are using base class
6066  // method to evaluate the expression.
6067  if (getParser().parseExpression(Value))
6068  return true;
6069  getParser().getStreamer().EmitDTPRel32Value(Value);
6070 
6071  if (getLexer().isNot(AsmToken::EndOfStatement))
6072  return Error(getLexer().getLoc(),
6073  "unexpected token, expected end of statement");
6074  Parser.Lex(); // Eat EndOfStatement token.
6075  return false;
6076 }
6077 
6078 /// parseDirectiveDtpRelDWord
6079 /// ::= .dtpreldword tls_sym
6080 bool MipsAsmParser::parseDirectiveDtpRelDWord() {
6081  MCAsmParser &Parser = getParser();
6082  const MCExpr *Value;
6083  // EmitDTPRel64Value requires an expression, so we are using base class
6084  // method to evaluate the expression.
6085  if (getParser().parseExpression(Value))
6086  return true;
6087  getParser().getStreamer().EmitDTPRel64Value(Value);
6088 
6089  if (getLexer().isNot(AsmToken::EndOfStatement))
6090  return Error(getLexer().getLoc(),
6091  "unexpected token, expected end of statement");
6092  Parser.Lex(); // Eat EndOfStatement token.
6093  return false;
6094 }
6095 
6096 /// parseDirectiveTpRelWord
6097 /// ::= .tprelword tls_sym
6098 bool MipsAsmParser::parseDirectiveTpRelWord() {
6099  MCAsmParser &Parser = getParser();
6100  const MCExpr *Value;
6101  // EmitTPRel32Value requires an expression, so we are using base class
6102  // method to evaluate the expression.
6103  if (getParser().parseExpression(Value))
6104  return true;
6105  getParser().getStreamer().EmitTPRel32Value(Value);
6106 
6107  if (getLexer().isNot(AsmToken::EndOfStatement))
6108  return Error(getLexer().getLoc(),
6109  "unexpected token, expected end of statement");
6110  Parser.Lex(); // Eat EndOfStatement token.
6111  return false;
6112 }
6113 
6114 /// parseDirectiveTpRelDWord
6115 /// ::= .tpreldword tls_sym
6116 bool MipsAsmParser::parseDirectiveTpRelDWord() {
6117  MCAsmParser &Parser = getParser();
6118  const MCExpr *Value;
6119  // EmitTPRel64Value requires an expression, so we are using base class
6120  // method to evaluate the expression.
6121  if (getParser().parseExpression(Value))
6122  return true;
6123  getParser().getStreamer().EmitTPRel64Value(Value);
6124 
6125  if (getLexer().isNot(AsmToken::EndOfStatement))
6126  return Error(getLexer().getLoc(),
6127  "unexpected token, expected end of statement");
6128  Parser.Lex(); // Eat EndOfStatement token.
6129  return false;
6130 }
6131 
6132 bool MipsAsmParser::parseDirectiveOption() {
6133  MCAsmParser &Parser = getParser();
6134  // Get the option token.
6135  AsmToken Tok = Parser.getTok();
6136  // At the moment only identifiers are supported.
6137  if (Tok.isNot(AsmToken::Identifier)) {
6138  return Error(Parser.getTok().getLoc(),
6139  "unexpected token, expected identifier");
6140  }
6141 
6142  StringRef Option = Tok.getIdentifier();
6143 
6144  if (Option == "pic0") {
6145  // MipsAsmParser needs to know if the current PIC mode changes.
6146  IsPicEnabled = false;
6147 
6148  getTargetStreamer().emitDirectiveOptionPic0();
6149  Parser.Lex();
6150  if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
6151  return Error(Parser.getTok().getLoc(),
6152  "unexpected token, expected end of statement");
6153  }
6154  return false;
6155  }
6156 
6157  if (Option == "pic2") {
6158  // MipsAsmParser needs to know if the current PIC mode changes.
6159  IsPicEnabled = true;
6160 
6161  getTargetStreamer().emitDirectiveOptionPic2();
6162  Parser.Lex();
6163  if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
6164  return Error(Parser.getTok().getLoc(),
6165  "unexpected token, expected end of statement");
6166  }
6167  return false;
6168  }
6169 
6170  // Unknown option.
6171  Warning(Parser.getTok().getLoc(),
6172  "unknown option, expected 'pic0' or 'pic2'");
6173  Parser.eatToEndOfStatement();
6174  return false;
6175 }
6176 
6177 /// parseInsnDirective
6178 /// ::= .insn
6179 bool MipsAsmParser::parseInsnDirective() {
6180  // If this is not the end of the statement, report an error.
6181  if (getLexer().isNot(AsmToken::EndOfStatement)) {
6182  reportParseError("unexpected token, expected end of statement");
6183  return false;
6184  }
6185 
6186  // The actual label marking happens in
6187  // MipsELFStreamer::createPendingLabelRelocs().
6188  getTargetStreamer().emitDirectiveInsn();
6189 
6190  getParser().Lex(); // Eat EndOfStatement token.
6191  return false;
6192 }
6193 
6194 /// parseSSectionDirective
6195 /// ::= .sbss
6196 /// ::= .sdata
6197 bool MipsAsmParser::parseSSectionDirective(StringRef Section, unsigned Type) {
6198  // If this is not the end of the statement, report an error.
6199  if (getLexer().isNot(AsmToken::EndOfStatement)) {
6200  reportParseError("unexpected token, expected end of statement");
6201  return false;
6202  }
6203 
6204  MCSection *ELFSection = getContext().getELFSection(
6206  getParser().getStreamer().SwitchSection(ELFSection);
6207 
6208  getParser().Lex(); // Eat EndOfStatement token.
6209  return false;
6210 }
6211 
6212 /// parseDirectiveModule
6213 /// ::= .module oddspreg
6214 /// ::= .module nooddspreg
6215 /// ::= .module fp=value
6216 /// ::= .module softfloat
6217 /// ::= .module hardfloat
6218 bool MipsAsmParser::parseDirectiveModule() {
6219  MCAsmParser &Parser = getParser();
6220  MCAsmLexer &Lexer = getLexer();
6221  SMLoc L = Lexer.getLoc();
6222 
6223  if (!getTargetStreamer().isModuleDirectiveAllowed()) {
6224  // TODO : get a better message.
6225  reportParseError(".module directive must appear before any code");
6226  return false;
6227  }
6228 
6229  StringRef Option;
6230  if (Parser.parseIdentifier(Option)) {
6231  reportParseError("expected .module option identifier");
6232  return false;
6233  }
6234 
6235  if (Option == "oddspreg") {
6236  clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
6237 
6238  // Synchronize the abiflags information with the FeatureBits information we
6239  // changed above.
6240  getTargetStreamer().updateABIInfo(*this);
6241 
6242  // If printing assembly, use the recently updated abiflags information.
6243  // If generating ELF, don't do anything (the .MIPS.abiflags section gets
6244  // emitted at the end).
6245  getTargetStreamer().emitDirectiveModuleOddSPReg();
6246 
6247  // If this is not the end of the statement, report an error.
6248  if (getLexer().isNot(AsmToken::EndOfStatement)) {
6249  reportParseError("unexpected token, expected end of statement");
6250  return false;
6251  }
6252 
6253  return false; // parseDirectiveModule has finished successfully.
6254  } else if (Option == "nooddspreg") {
6255  if (!isABI_O32()) {
6256  return Error(L, "'.module nooddspreg' requires the O32 ABI");
6257  }
6258 
6259  setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
6260 
6261  // Synchronize the abiflags information with the FeatureBits information we
6262  // changed above.
6263  getTargetStreamer().updateABIInfo(*this);
6264 
6265  // If printing assembly, use the recently updated abiflags information.
6266  // If generating ELF, don't do anything (the .MIPS.abiflags section gets
6267  // emitted at the end).
6268  getTargetStreamer().emitDirectiveModuleOddSPReg();
6269 
6270  // If this is not the end of the statement, report an error.
6271  if (getLexer().isNot(AsmToken::EndOfStatement)) {
6272  reportParseError("unexpected token, expected end of statement");
6273  return false;
6274  }
6275 
6276  return false; // parseDirectiveModule has finished successfully.
6277  } else if (Option == "fp") {
6278  return parseDirectiveModuleFP();
6279  } else if (Option == "softfloat") {
6280  setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
6281 
6282  // Synchronize the ABI Flags information with the FeatureBits information we
6283  // updated above.
6284  getTargetStreamer().updateABIInfo(*this);
6285 
6286  // If printing assembly, use the recently updated ABI Flags information.
6287  // If generating ELF, don't do anything (the .MIPS.abiflags section gets
6288  // emitted later).
6289  getTargetStreamer().emitDirectiveModuleSoftFloat();
6290 
6291  // If this is not the end of the statement, report an error.
6292  if (getLexer().isNot(AsmToken::EndOfStatement)) {
6293  reportParseError("unexpected token, expected end of statement");
6294  return false;
6295  }
6296 
6297  return false; // parseDirectiveModule has finished successfully.
6298  } else if (Option == "hardfloat") {
6299  clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
6300 
6301  // Synchronize the ABI Flags information with the FeatureBits information we
6302  // updated above.
6303  getTargetStreamer().updateABIInfo(*this);
6304 
6305  // If printing assembly, use the recently updated ABI Flags information.
6306  // If generating ELF, don't do anything (the .MIPS.abiflags section gets
6307  // emitted later).
6308  getTargetStreamer().emitDirectiveModuleHardFloat();
6309 
6310  // If this is not the end of the statement, report an error.
6311  if (getLexer().isNot(AsmToken::EndOfStatement)) {
6312  reportParseError("unexpected token, expected end of statement");
6313  return false;
6314  }
6315 
6316  return false; // parseDirectiveModule has finished successfully.
6317  } else {
6318  return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
6319  }
6320 }
6321 
6322 /// parseDirectiveModuleFP
6323 /// ::= =32
6324 /// ::= =xx
6325 /// ::= =64
6326 bool MipsAsmParser::parseDirectiveModuleFP() {
6327  MCAsmParser &Parser = getParser();
6328  MCAsmLexer &Lexer = getLexer();
6329 
6330  if (Lexer.isNot(AsmToken::Equal)) {
6331  reportParseError("unexpected token, expected equals sign '='");
6332  return false;
6333  }
6334  Parser.Lex(); // Eat '=' token.
6335 
6337  if (!parseFpABIValue(FpABI, ".module"))
6338  return false;
6339 
6340  if (getLexer().isNot(AsmToken::EndOfStatement)) {
6341  reportParseError("unexpected token, expected end of statement");
6342  return false;
6343  }
6344 
6345  // Synchronize the abiflags information with the FeatureBits information we
6346  // changed above.
6347  getTargetStreamer().updateABIInfo(*this);
6348 
6349  // If printing assembly, use the recently updated abiflags information.
6350  // If generating ELF, don't do anything (the .MIPS.abiflags section gets
6351  // emitted at the end).
6352  getTargetStreamer().emitDirectiveModuleFP();
6353 
6354  Parser.Lex(); // Consume the EndOfStatement.
6355  return false;
6356 }
6357 
6358 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
6359  StringRef Directive) {
6360  MCAsmParser &Parser = getParser();
6361  MCAsmLexer &Lexer = getLexer();
6362  bool ModuleLevelOptions = Directive == ".module";
6363 
6364  if (Lexer.is(AsmToken::Identifier)) {
6365  StringRef Value = Parser.getTok().getString();
6366  Parser.Lex();
6367 
6368  if (Value != "xx") {
6369  reportParseError("unsupported value, expected 'xx', '32' or '64'");
6370  return false;
6371  }
6372 
6373  if (!isABI_O32()) {
6374  reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
6375  return false;
6376  }
6377 
6379  if (ModuleLevelOptions) {
6380  setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
6381  clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
6382  } else {
6383  setFeatureBits(Mips::FeatureFPXX, "fpxx");
6384  clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
6385  }
6386  return true;
6387  }
6388 
6389  if (Lexer.is(AsmToken::Integer)) {
6390  unsigned Value = Parser.getTok().getIntVal();
6391  Parser.Lex();
6392 
6393  if (Value != 32 && Value != 64) {
6394  reportParseError("unsupported value, expected 'xx', '32' or '64'");
6395  return false;
6396  }
6397 
6398  if (Value == 32) {
6399  if (!isABI_O32()) {
6400  reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
6401  return false;
6402  }
6403 
6405  if (ModuleLevelOptions) {
6406  clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
6407  clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
6408  } else {
6409  clearFeatureBits(Mips::FeatureFPXX, "fpxx");
6410  clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
6411  }
6412  } else {
6414  if (ModuleLevelOptions) {
6415  clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
6416  setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
6417  } else {
6418  clearFeatureBits(Mips::FeatureFPXX, "fpxx");
6419  setFeatureBits(Mips::FeatureFP64Bit, "fp64");
6420  }
6421  }
6422 
6423  return true;
6424  }
6425 
6426  return false;
6427 }
6428 
6429 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
6430  // This returns false if this function recognizes the directive
6431  // regardless of whether it is successfully handles or reports an
6432  // error. Otherwise it returns true to give the generic parser a
6433  // chance at recognizing it.
6434 
6435  MCAsmParser &Parser = getParser();
6436  StringRef IDVal = DirectiveID.getString();
6437 
6438  if (IDVal == ".cpload") {
6439  parseDirectiveCpLoad(DirectiveID.getLoc());
6440  return false;
6441  }
6442  if (IDVal == ".cprestore") {
6443  parseDirectiveCpRestore(DirectiveID.getLoc());
6444  return false;
6445  }
6446  if (IDVal == ".dword") {
6447  parseDataDirective(8, DirectiveID.getLoc());
6448  return false;
6449  }
6450  if (IDVal == ".ent") {
6451  StringRef SymbolName;
6452 
6453  if (Parser.parseIdentifier(SymbolName)) {
6454  reportParseError("expected identifier after .ent");
6455  return false;
6456  }
6457 
6458  // There's an undocumented extension that allows an integer to
6459  // follow the name of the procedure which AFAICS is ignored by GAS.
6460  // Example: .ent foo,2
6461  if (getLexer().isNot(AsmToken::EndOfStatement)) {
6462  if (getLexer().isNot(AsmToken::Comma)) {
6463  // Even though we accept this undocumented extension for compatibility
6464  // reasons, the additional integer argument does not actually change
6465  // the behaviour of the '.ent' directive, so we would like to discourage
6466  // its use. We do this by not referring to the extended version in
6467  // error messages which are not directly related to its use.
6468  reportParseError("unexpected token, expected end of statement");
6469  return false;
6470  }
6471  Parser.Lex(); // Eat the comma.
6472  const MCExpr *DummyNumber;
6473  int64_t DummyNumberVal;
6474  // If the user was explicitly trying to use the extended version,
6475  // we still give helpful extension-related error messages.
6476  if (Parser.parseExpression(DummyNumber)) {
6477  reportParseError("expected number after comma");
6478  return false;
6479  }
6480  if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
6481  reportParseError("expected an absolute expression after comma");
6482  return false;
6483  }
6484  }
6485 
6486  // If this is not the end of the statement, report an error.
6487  if (getLexer().isNot(AsmToken::EndOfStatement)) {
6488  reportParseError("unexpected token, expected end of statement");
6489  return false;
6490  }
6491 
6492  MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
6493 
6494  getTargetStreamer().emitDirectiveEnt(*Sym);
6495  CurrentFn = Sym;
6496  IsCpRestoreSet = false;
6497  return false;
6498  }
6499 
6500  if (IDVal == ".end") {
6501  StringRef SymbolName;
6502 
6503  if (Parser.parseIdentifier(SymbolName)) {
6504  reportParseError("expected identifier after .end");
6505  return false;
6506  }
6507 
6508  if (getLexer().isNot(AsmToken::EndOfStatement)) {
6509  reportParseError("unexpected token, expected end of statement");
6510  return false;
6511  }
6512 
6513  if (CurrentFn == nullptr) {
6514  reportParseError(".end used without .ent");
6515  return false;
6516  }
6517 
6518  if ((SymbolName != CurrentFn->getName())) {
6519  reportParseError(".end symbol does not match .ent symbol");
6520  return false;
6521  }
6522 
6523  getTargetStreamer().emitDirectiveEnd(SymbolName);
6524  CurrentFn = nullptr;
6525  IsCpRestoreSet = false;
6526  return false;
6527  }
6528 
6529  if (IDVal == ".frame") {
6530  // .frame $stack_reg, frame_size_in_bytes, $return_reg
6532  OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
6533  if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
6534  reportParseError("expected stack register");
6535  return false;
6536  }
6537 
6538  MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
6539  if (!StackRegOpnd.isGPRAsmReg()) {
6540  reportParseError(StackRegOpnd.getStartLoc(),
6541  "expected general purpose register");
6542  return false;
6543  }
6544  unsigned StackReg = StackRegOpnd.getGPR32Reg();
6545 
6546  if (Parser.getTok().is(AsmToken::Comma))
6547  Parser.Lex();
6548  else {
6549  reportParseError("unexpected token, expected comma");
6550  return false;
6551  }
6552 
6553  // Parse the frame size.
6554  const MCExpr *FrameSize;
6555  int64_t FrameSizeVal;
6556 
6557  if (Parser.parseExpression(FrameSize)) {
6558  reportParseError("expected frame size value");
6559  return false;
6560  }
6561 
6562  if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
6563  reportParseError("frame size not an absolute expression");
6564  return false;
6565  }
6566 
6567  if (Parser.getTok().is(AsmToken::Comma))
6568  Parser.Lex();
6569  else {
6570  reportParseError("unexpected token, expected comma");
6571  return false;
6572  }
6573 
6574  // Parse the return register.
6575  TmpReg.clear();
6576  ResTy = parseAnyRegister(TmpReg);
6577  if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
6578  reportParseError("expected return register");
6579  return false;
6580  }
6581 
6582  MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
6583  if (!ReturnRegOpnd.isGPRAsmReg()) {
6584  reportParseError(ReturnRegOpnd.getStartLoc(),
6585  "expected general purpose register");
6586  return false;
6587  }
6588 
6589  // If this is not the end of the statement, report an error.
6590  if (getLexer().isNot(AsmToken::EndOfStatement)) {
6591  reportParseError("unexpected token, expected end of statement");
6592  return false;
6593  }
6594 
6595  getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
6596  ReturnRegOpnd.getGPR32Reg());
6597  IsCpRestoreSet = false;
6598  return false;
6599  }
6600 
6601  if (IDVal == ".set") {
6602  parseDirectiveSet();
6603  return false;
6604  }
6605 
6606  if (IDVal == ".mask" || IDVal == ".fmask") {
6607  // .mask bitmask, frame_offset
6608  // bitmask: One bit for each register used.
6609  // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
6610  // first register is expected to be saved.
6611  // Examples:
6612  // .mask 0x80000000, -4
6613  // .fmask 0x80000000, -4
6614  //
6615 
6616  // Parse the bitmask
6617  const MCExpr *BitMask;
6618  int64_t BitMaskVal;
6619 
6620  if (Parser.parseExpression(BitMask)) {
6621  reportParseError("expected bitmask value");
6622  return false;
6623  }
6624 
6625  if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
6626  reportParseError("bitmask not an absolute expression");
6627  return false;
6628  }
6629 
6630  if (Parser.getTok().is(AsmToken::Comma))
6631  Parser.Lex();
6632  else {
6633  reportParseError("unexpected token, expected comma");
6634  return false;
6635  }
6636 
6637  // Parse the frame_offset
6638  const MCExpr *FrameOffset;
6639  int64_t FrameOffsetVal;
6640 
6641  if (Parser.parseExpression(FrameOffset)) {
6642  reportParseError("expected frame offset value");
6643  return false;
6644  }
6645 
6646  if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
6647  reportParseError("frame offset not an absolute expression");
6648  return false;
6649  }
6650 
6651  // If this is not the end of the statement, report an error.
6652  if (getLexer().isNot(AsmToken::EndOfStatement)) {
6653  reportParseError("unexpected token, expected end of statement");
6654  return false;
6655  }
6656 
6657  if (IDVal == ".mask")
6658  getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
6659  else
6660  getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
6661  return false;
6662  }
6663 
6664  if (IDVal == ".nan")
6665  return parseDirectiveNaN();
6666 
6667  if (IDVal == ".gpword") {
6668  parseDirectiveGpWord();
6669  return false;
6670  }
6671 
6672  if (IDVal == ".gpdword") {
6673  parseDirectiveGpDWord();
6674  return false;
6675  }
6676 
6677  if (IDVal == ".dtprelword") {
6678  parseDirectiveDtpRelWord();
6679  return false;
6680  }
6681 
6682  if (IDVal == ".dtpreldword") {
6683  parseDirectiveDtpRelDWord();
6684  return false;
6685  }
6686 
6687  if (IDVal == ".tprelword") {
6688  parseDirectiveTpRelWord();
6689  return false;
6690  }
6691 
6692  if (IDVal == ".tpreldword") {
6693  parseDirectiveTpRelDWord();
6694  return false;
6695  }
6696 
6697  if (IDVal == ".word") {
6698  parseDataDirective(4, DirectiveID.getLoc());
6699  return false;
6700  }
6701 
6702  if (IDVal == ".hword") {
6703  parseDataDirective(2, DirectiveID.getLoc());
6704  return false;
6705  }
6706 
6707  if (IDVal == ".option") {
6708  parseDirectiveOption();
6709  return false;
6710  }
6711 
6712  if (IDVal == ".abicalls") {
6713  getTargetStreamer().emitDirectiveAbiCalls();
6714  if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
6715  Error(Parser.getTok().getLoc(),
6716  "unexpected token, expected end of statement");
6717  }
6718  return false;
6719  }
6720 
6721  if (IDVal == ".cpsetup") {
6722  parseDirectiveCPSetup();
6723  return false;
6724  }
6725  if (IDVal == ".cpreturn") {
6726  parseDirectiveCPReturn();
6727  return false;
6728  }
6729  if (IDVal == ".module") {
6730  parseDirectiveModule();
6731  return false;
6732  }
6733  if (IDVal == ".llvm_internal_mips_reallow_module_directive") {
6734  parseInternalDirectiveReallowModule();
6735  return false;
6736  }
6737  if (IDVal == ".insn") {
6738  parseInsnDirective();
6739  return false;
6740  }
6741  if (IDVal == ".sbss") {
6742  parseSSectionDirective(IDVal, ELF::SHT_NOBITS);
6743  return false;
6744  }
6745  if (IDVal == ".sdata") {
6746  parseSSectionDirective(IDVal, ELF::SHT_PROGBITS);
6747  return false;
6748  }
6749 
6750  return true;
6751 }
6752 
6753 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
6754  // If this is not the end of the statement, report an error.
6755  if (getLexer().isNot(AsmToken::EndOfStatement)) {
6756  reportParseError("unexpected token, expected end of statement");
6757  return false;
6758  }
6759 
6760  getTargetStreamer().reallowModuleDirective();
6761 
6762  getParser().Lex(); // Eat EndOfStatement token.
6763  return false;
6764 }
6765 
6766 extern "C" void LLVMInitializeMipsAsmParser() {
6771 }
6772 
6773 #define GET_REGISTER_MATCHER
6774 #define GET_MATCHER_IMPLEMENTATION
6775 #include "MipsGenAsmMatcher.inc"
MachineLoop * L
static bool isReg(const MCInst &MI, unsigned OpNo)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
Definition: StringRef.h:634
void emitRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, SMLoc IDLoc, const MCSubtargetInfo *STI)
std::enable_if< std::numeric_limits< T >::is_signed, bool >::type getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
Definition: StringRef.h:494
constexpr bool isUInt< 32 >(uint64_t x)
Definition: MathExtras.h:315
Represents a range in source code.
Definition: SMLoc.h:49
Instances of this class represent a uniqued identifier for a section in the current translation unit...
Definition: MCSection.h:40
void push_back(const T &Elt)
Definition: SmallVector.h:211
static ARMBaseTargetMachine::ARMABI computeTargetABI(const Triple &TT, StringRef CPU, const TargetOptions &Options)
T findLastSet(T Val, ZeroBehavior ZB=ZB_Max)
Get the index of the last set bit starting from the least significant bit.
Definition: MathExtras.h:208
uint64_t Token
const MCSymbol & getSymbol() const
Definition: MCExpr.h:311
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:298
const char * getPointer() const
Definition: SMLoc.h:35
size_t i
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
TokenKind getKind() const
Definition: MCAsmLexer.h:85
void setFeatureBits(const FeatureBitset &FeatureBits_)
setFeatureBits - Set the feature bits.
This represents an "assembler immediate".
Definition: MCValue.h:40
void clear()
Definition: MCInst.h:172
bool isReg() const
Definition: MCInst.h:56
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:39
Generic assembler parser interface, for use by target specific assembly parsers.
Definition: MCAsmParser.h:66
Bitwise and.
Definition: MCExpr.h:392
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
static MCOperand createExpr(const MCExpr *Val)
Definition: MCInst.h:129
MCTargetAsmParser - Generic interface to target specific assembly parsers.
bool mayStore() const
Return true if this instruction could possibly modify memory.
Definition: MCInstrDesc.h:384
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:163
MachineInstrBuilder MachineInstrBuilder &DefMI const MCInstrDesc & Desc
Multiplication.
Definition: MCExpr.h:406
Target specific streamer interface.
Definition: MCStreamer.h:73
ExprKind getKind() const
Definition: MCExpr.h:70
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
Definition: MCAsmLexer.h:114
Target & getTheMipselTarget()
virtual void emitDirectiveSetNoReorder()
constexpr bool isInt< 8 >(int64_t x)
Definition: MathExtras.h:268
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
bool isNot(TokenKind K) const
Definition: MCAsmLexer.h:87
OperandMatchResultTy
constexpr bool isInt< 16 >(int64_t x)
Definition: MathExtras.h:271
SMLoc getLoc() const
Get the current source location.
Definition: MCAsmLexer.cpp:24
void emitGPRestore(int Offset, SMLoc IDLoc, const MCSubtargetInfo *STI)
Emit the $gp restore operation for .cprestore.
static const MCInstrDesc & getInstDesc(unsigned Opcode)
static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands, uint64_t ErrorInfo)
#define op(i)
Bitwise or.
Definition: MCExpr.h:408
virtual void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
Definition: MCStreamer.cpp:765
return AArch64::GPR64RegClass contains(Reg)
SMLoc Start
Definition: SMLoc.h:51
static const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.cpp:139
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:111
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
void emitLoadWithImmOffset(unsigned Opcode, unsigned DstReg, unsigned BaseReg, int64_t Offset, unsigned TmpReg, SMLoc IDLoc, const MCSubtargetInfo *STI)
Emit a load instruction with an immediate offset.
Generic assembler lexer interface, for use by target specific assembly lexers.
Definition: MCAsmLexer.h:147
std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
bool isBranch() const
Returns true if this is a conditional, unconditional, or indirect branch.
Definition: MCInstrDesc.h:261
bool isCall() const
Return true if the instruction is a call.
Definition: MCInstrDesc.h:242
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:32
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:34
LLVM_ATTRIBUTE_ALWAYS_INLINE R Default(const T &Value) const
Definition: StringSwitch.h:244
Reg
All possible values of the reg field in the ModR/M byte.
Target independent representation for an assembler token.
Definition: MCAsmLexer.h:25
static int getRegClass(RegisterKind Is, unsigned RegWidth)
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:161
Windows NT (Windows on ARM)
static bool isMem(const MachineInstr &MI, unsigned Op)
Definition: X86InstrInfo.h:135
ELFYAML::ELF_STO Other
Definition: ELFYAML.cpp:662
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand...
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
Context object for machine code objects.
Definition: MCContext.h:51
void emitNop(SMLoc IDLoc, const MCSubtargetInfo *STI)
uint8_t OperandType
Information about the type of the operand.
Definition: MCInstrDesc.h:82
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Case(const char(&S)[N], const T &Value)
Definition: StringSwitch.h:74
bool isNot(AsmToken::TokenKind K) const
Check if the current token has kind K.
Definition: MCAsmLexer.h:245
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:264
unsigned getReg() const
Returns the register number.
Definition: MCInst.h:63
Signed remainder.
Definition: MCExpr.h:405
Target & getTheMips64Target()
const RegList & Regs
Unary assembler expressions.
Definition: MCExpr.h:335
Simple integer binary arithmetic operators.
Definition: ISDOpcodes.h:200
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
ArchType getArch() const
getArch - Get the parsed architecture type of this triple.
Definition: Triple.h:270
Signed division.
Definition: MCExpr.h:393
LLVM_NODISCARD char front() const
front - Get the first character in the string.
Definition: StringRef.h:139
int64_t getIntVal() const
Definition: MCAsmLexer.h:119
IsPCRelativeLoad - A Load instruction with implicit source register ($pc) with explicit offset and de...
Definition: MipsBaseInfo.h:126
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
Definition: StringRef.h:135
static bool isShiftedUIntAtAnyPosition(uint64_t x)
Can the value be represented by a unsigned N-bit value and a shift left?
HasFCCRegOperand - Instruction uses an $fcc<x> register.
Definition: MipsBaseInfo.h:128
const AsmToken & getTok() const
Get the current AsmToken from the stream.
Definition: MCAsmParser.cpp:33
Unary expressions.
Definition: MCExpr.h:40
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:150
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
void emitRX(unsigned Opcode, unsigned Reg0, MCOperand Op1, SMLoc IDLoc, const MCSubtargetInfo *STI)
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Shift left.
Definition: MCExpr.h:409
bool isImm() const
Definition: MCInst.h:57
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
INITIALIZE_PASS(HexagonEarlyIfConversion,"hexagon-eif","Hexagon early if conversion", false, false) bool HexagonEarlyIfConversion MachineBasicBlock * SB
FeatureBitset ToggleFeature(uint64_t FB)
ToggleFeature - Toggle a feature and returns the re-computed feature bits.
const MCExpr * getExpr() const
Definition: MCInst.h:93
void setImm(int64_t Val)
Definition: MCInst.h:78
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:43
Streaming machine code generation interface.
Definition: MCStreamer.h:161
Target & getTheMips64elTarget()
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
int64_t getValue() const
Definition: MCExpr.h:147
bool IsN32() const
Definition: MipsABIInfo.h:43
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
Definition: SmallVector.h:115
SMLoc getLoc() const
Definition: MCAsmLexer.cpp:28
static ManagedStatic< OptionRegistry > OR
Definition: Options.cpp:31
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:587
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:24
static unsigned countMCSymbolRefExpr(const MCExpr *Expr)
virtual MCAsmLexer & getLexer()=0
void emitRI(unsigned Opcode, unsigned Reg0, int32_t Imm, SMLoc IDLoc, const MCSubtargetInfo *STI)
bool isExpr() const
Definition: MCInst.h:59
uint32_t Offset
void emitR(unsigned Opcode, unsigned Reg0, SMLoc IDLoc, const MCSubtargetInfo *STI)
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang","erlang-compatible garbage collector")
static const MCSymbol * getSingleMCSymbol(const MCExpr *Expr)
static unsigned nextReg(unsigned Reg)
const AsmToken peekTok(bool ShouldSkipSpace=true)
Look ahead at the next token to be lexed.
Definition: MCAsmLexer.h:212
SMLoc getLoc() const
Definition: MCInst.h:162
Represents a single fixit, a replacement of one range of text with another.
Definition: SourceMgr.h:195
bool isInSection(bool SetUsed=true) const
isInSection - Check if this symbol is defined in some section (i.e., it is defined but not absolute)...
Definition: MCSymbol.h:251
bool isIntN(unsigned N, int64_t x)
isIntN - Checks if an signed integer fits into the given (dynamic) bit width.
Definition: MathExtras.h:366
const MCSymbolRefExpr * getSymB() const
Definition: MCValue.h:48
Binary assembler expressions.
Definition: MCExpr.h:388
T findFirstSet(T Val, ZeroBehavior ZB=ZB_Max)
Get the index of the first set bit starting from the least significant bit.
Definition: MathExtras.h:194
void setLoc(SMLoc loc)
Definition: MCInst.h:161
void emitLoadWithSymOffset(unsigned Opcode, unsigned DstReg, unsigned BaseReg, MCOperand &HiOperand, MCOperand &LoOperand, unsigned ATReg, SMLoc IDLoc, const MCSubtargetInfo *STI)
Emit a load instruction with an symbol offset.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool is(AsmToken::TokenKind K) const
Check if the current token has kind K.
Definition: MCAsmLexer.h:242
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
void emitRRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, unsigned Reg2, SMLoc IDLoc, const MCSubtargetInfo *STI)
void setOpcode(unsigned Op)
Definition: MCInst.h:158
constexpr bool isInt< 32 >(int64_t x)
Definition: MathExtras.h:274
const MCSymbolRefExpr * getSymA() const
Definition: MCValue.h:47
SMRange getLocRange() const
Definition: MCAsmLexer.cpp:36
void emitDSLL(unsigned DstReg, unsigned SrcReg, int16_t ShiftAmount, SMLoc IDLoc, const MCSubtargetInfo *STI)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:843
void emitEmptyDelaySlot(bool hasShortDelaySlot, SMLoc IDLoc, const MCSubtargetInfo *STI)
bool mayLoad() const
Return true if this instruction could possibly read memory.
Definition: MCInstrDesc.h:378
const FeatureBitset & getFeatureBits() const
getFeatureBits - Return the feature bits.
bool is(TokenKind K) const
Definition: MCAsmLexer.h:86
void setVariableValue(const MCExpr *Value)
Definition: MCSymbol.cpp:42
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:586
bool evaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout, const MCFixup *Fixup) const
Try to evaluate the expression to a relocatable value, i.e.
Definition: MCExpr.cpp:581
unsigned getOpcode() const
Definition: MCInst.h:159
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
const MCExpr * getVariableValue(bool SetUsed=true) const
getVariableValue - Get the value for variable symbols.
Definition: MCSymbol.h:294
bool isTemporary() const
isTemporary - Check if this is an assembler temporary symbol.
Definition: MCSymbol.h:216
Base class for user error types.
Bitwise exclusive or.
Definition: MCExpr.h:413
int64_t getImm() const
Definition: MCInst.h:74
static const MipsMCExpr * create(MipsExprKind Kind, const MCExpr *Expr, MCContext &Ctx)
Definition: MipsMCExpr.cpp:22
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:130
Target & getTheMipsTarget()
void emitStoreWithImmOffset(unsigned Opcode, unsigned SrcReg, unsigned BaseReg, int64_t Offset, function_ref< unsigned()> GetATReg, SMLoc IDLoc, const MCSubtargetInfo *STI)
Emit a store instruction with an offset.
static SMLoc getFromPointer(const char *Ptr)
Definition: SMLoc.h:37
#define Success
Bit rotate left.
Basic Alias true
Logical shift right.
Definition: MCExpr.h:411
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string...
Definition: MCAsmLexer.h:103
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
Definition: SmallVector.h:119
RegisterMCAsmParser - Helper template for registering a target specific assembly parser, for use in the target machine initialization function.
StringRef getName() const
getName - Get the symbol name.
Definition: MCSymbol.h:199
Bitwise operators - logical and, logical or, logical xor.
Definition: ISDOpcodes.h:333
int16_t RegClass
This specifies the register class enumeration of the operand if the operand is a register.
Definition: MCInstrDesc.h:76
unsigned getNumOperands() const
Definition: MCInst.h:166
const NodeList & List
Definition: RDFGraph.cpp:205
#define N
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
Definition: SmallVector.h:135
MCSubtargetInfo - Generic base class for all target subtargets.
bool hasDelaySlot() const
Returns true if the specified instruction has a delay slot which must be filled by the code generator...
Definition: MCInstrDesc.h:314
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Definition: Casting.h:287
References to labels and assigned expressions.
Definition: MCExpr.h:39
const Triple & getTargetTriple() const
getTargetTriple - Return the target triple string.
constexpr bool isUInt< 16 >(uint64_t x)
Definition: MathExtras.h:312
static bool hasShortDelaySlot(unsigned Opcode)
const MCInstrDesc MipsInsts[]
bool isVariable() const
isVariable - Check if this is a variable symbol.
Definition: MCSymbol.h:289
const unsigned Kind
static StringRef getCPU(StringRef CPU)
Processes a CPU name.
void emitRRI(unsigned Opcode, unsigned Reg0, unsigned Reg1, int16_t Imm, SMLoc IDLoc, const MCSubtargetInfo *STI)
VariantKind getKind() const
Definition: MCExpr.h:313
void emitRRX(unsigned Opcode, unsigned Reg0, unsigned Reg1, MCOperand Op2, SMLoc IDLoc, const MCSubtargetInfo *STI)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
int64_t getConstant() const
Definition: MCValue.h:46
virtual void emitDirectiveSetReorder()
LLVM Value Representation.
Definition: Value.h:71
Constant expressions.
Definition: MCExpr.h:38
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
Definition: Compiler.h:239
Binary expressions.
Definition: MCExpr.h:37
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
Definition: MCInstrDesc.h:210
const FeatureBitset Features
const MCOperandInfo * OpInfo
Definition: MCInstrDesc.h:174
uint64_t OffsetToAlignment(uint64_t Value, uint64_t Align)
Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...
Definition: MathExtras.h:701
void emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2, SMLoc IDLoc, const MCSubtargetInfo *STI)
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:44
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:125
static TraceState * TS
#define DEBUG(X)
Definition: Debug.h:100
Subtraction.
Definition: MCExpr.h:412
void addOperand(const MCOperand &Op)
Definition: MCInst.h:168
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:47
virtual bool parseIdentifier(StringRef &Res)=0
Parse an identifier or string (as a quoted identifier) and set Res to the identifier contents...
static FeatureBitset getFeatures(StringRef CPU, StringRef FS, ArrayRef< SubtargetFeatureKV > ProcDesc, ArrayRef< SubtargetFeatureKV > ProcFeatures)
Target specific expression.
Definition: MCExpr.h:41
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml","ocaml 3.10-compatible collector")
Represents a location in source code.
Definition: SMLoc.h:24
This holds information about one operand of a machine instruction, indicating the register class for ...
Definition: MCInstrDesc.h:70
bool isELF() const
Definition: MCSymbol.h:278
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:33
static GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:117
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx)
Definition: MCExpr.cpp:149
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:164
#define T1
void emitStoreWithSymOffset(unsigned Opcode, unsigned SrcReg, unsigned BaseReg, MCOperand &HiOperand, MCOperand &LoOperand, unsigned ATReg, SMLoc IDLoc, const MCSubtargetInfo *STI)
Emit a store instruction with an symbol offset.
void LLVMInitializeMipsAsmParser()