LLVM  16.0.0git
MipsAsmParser.cpp
Go to the documentation of this file.
1 //===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
14 #include "MipsTargetStreamer.h"
16 #include "llvm/ADT/APFloat.h"
17 #include "llvm/ADT/STLExtras.h"
18 #include "llvm/ADT/SmallVector.h"
19 #include "llvm/ADT/StringRef.h"
20 #include "llvm/ADT/StringSwitch.h"
21 #include "llvm/ADT/Triple.h"
22 #include "llvm/ADT/Twine.h"
23 #include "llvm/BinaryFormat/ELF.h"
24 #include "llvm/MC/MCContext.h"
25 #include "llvm/MC/MCExpr.h"
26 #include "llvm/MC/MCInst.h"
27 #include "llvm/MC/MCInstrDesc.h"
28 #include "llvm/MC/MCInstrInfo.h"
36 #include "llvm/MC/MCSectionELF.h"
37 #include "llvm/MC/MCStreamer.h"
39 #include "llvm/MC/MCSymbol.h"
40 #include "llvm/MC/MCSymbolELF.h"
41 #include "llvm/MC/MCValue.h"
43 #include "llvm/MC/TargetRegistry.h"
44 #include "llvm/Support/Alignment.h"
45 #include "llvm/Support/Casting.h"
47 #include "llvm/Support/Compiler.h"
48 #include "llvm/Support/Debug.h"
51 #include "llvm/Support/SMLoc.h"
52 #include "llvm/Support/SourceMgr.h"
54 #include <algorithm>
55 #include <cassert>
56 #include <cstdint>
57 #include <memory>
58 #include <string>
59 #include <utility>
60 
61 using namespace llvm;
62 
63 #define DEBUG_TYPE "mips-asm-parser"
64 
65 namespace llvm {
66 
67 class MCInstrInfo;
68 
69 } // end namespace llvm
70 
72 
73 namespace {
74 
75 class MipsAssemblerOptions {
76 public:
77  MipsAssemblerOptions(const FeatureBitset &Features_) : Features(Features_) {}
78 
79  MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
80  ATReg = Opts->getATRegIndex();
81  Reorder = Opts->isReorder();
82  Macro = Opts->isMacro();
83  Features = Opts->getFeatures();
84  }
85 
86  unsigned getATRegIndex() const { return ATReg; }
87  bool setATRegIndex(unsigned Reg) {
88  if (Reg > 31)
89  return false;
90 
91  ATReg = Reg;
92  return true;
93  }
94 
95  bool isReorder() const { return Reorder; }
96  void setReorder() { Reorder = true; }
97  void setNoReorder() { Reorder = false; }
98 
99  bool isMacro() const { return Macro; }
100  void setMacro() { Macro = true; }
101  void setNoMacro() { Macro = false; }
102 
103  const FeatureBitset &getFeatures() const { return Features; }
104  void setFeatures(const FeatureBitset &Features_) { Features = Features_; }
105 
106  // Set of features that are either architecture features or referenced
107  // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
108  // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
109  // The reason we need this mask is explained in the selectArch function.
110  // FIXME: Ideally we would like TableGen to generate this information.
111  static const FeatureBitset AllArchRelatedMask;
112 
113 private:
114  unsigned ATReg = 1;
115  bool Reorder = true;
116  bool Macro = true;
117  FeatureBitset Features;
118 };
119 
120 } // end anonymous namespace
121 
122 const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
123  Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
124  Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
125  Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
126  Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
127  Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
128  Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
129  Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
130  Mips::FeatureCnMipsP, Mips::FeatureFP64Bit, Mips::FeatureGP64Bit,
131  Mips::FeatureNaN2008
132 };
133 
134 namespace {
135 
136 class MipsAsmParser : public MCTargetAsmParser {
137  MipsTargetStreamer &getTargetStreamer() {
138  assert(getParser().getStreamer().getTargetStreamer() &&
139  "do not have a target streamer");
140  MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
141  return static_cast<MipsTargetStreamer &>(TS);
142  }
143 
146  MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
147  // nullptr, which indicates that no function is currently
148  // selected. This usually happens after an '.end func'
149  // directive.
150  bool IsLittleEndian;
151  bool IsPicEnabled;
152  bool IsCpRestoreSet;
153  int CpRestoreOffset;
154  unsigned GPReg;
155  unsigned CpSaveLocation;
156  /// If true, then CpSaveLocation is a register, otherwise it's an offset.
157  bool CpSaveLocationIsRegister;
158 
159  // Map of register aliases created via the .set directive.
160  StringMap<AsmToken> RegisterSets;
161 
162  // Print a warning along with its fix-it message at the given range.
163  void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
164  SMRange Range, bool ShowColors = true);
165 
166  void ConvertXWPOperands(MCInst &Inst, const OperandVector &Operands);
167 
168 #define GET_ASSEMBLER_HEADER
169 #include "MipsGenAsmMatcher.inc"
170 
171  unsigned
172  checkEarlyTargetMatchPredicate(MCInst &Inst,
173  const OperandVector &Operands) override;
174  unsigned checkTargetMatchPredicate(MCInst &Inst) override;
175 
176  bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
179  bool MatchingInlineAsm) override;
180 
181  /// Parse a register as used in CFI directives
182  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
183  OperandMatchResultTy tryParseRegister(unsigned &RegNo, SMLoc &StartLoc,
184  SMLoc &EndLoc) override;
185 
186  bool parseParenSuffix(StringRef Name, OperandVector &Operands);
187 
188  bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
189 
190  bool mnemonicIsValid(StringRef Mnemonic, unsigned VariantID);
191 
192  bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
193  SMLoc NameLoc, OperandVector &Operands) override;
194 
195  bool ParseDirective(AsmToken DirectiveID) override;
196 
197  OperandMatchResultTy parseMemOperand(OperandVector &Operands);
199  matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
200  StringRef Identifier, SMLoc S);
201  OperandMatchResultTy matchAnyRegisterWithoutDollar(OperandVector &Operands,
202  const AsmToken &Token,
203  SMLoc S);
204  OperandMatchResultTy matchAnyRegisterWithoutDollar(OperandVector &Operands,
205  SMLoc S);
206  OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
208  OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
210  OperandMatchResultTy parseRegisterList(OperandVector &Operands);
211 
212  bool searchSymbolAlias(OperandVector &Operands);
213 
214  bool parseOperand(OperandVector &, StringRef Mnemonic);
215 
216  enum MacroExpanderResultTy {
217  MER_NotAMacro,
218  MER_Success,
219  MER_Fail,
220  };
221 
222  // Expands assembly pseudo instructions.
223  MacroExpanderResultTy tryExpandInstruction(MCInst &Inst, SMLoc IDLoc,
224  MCStreamer &Out,
225  const MCSubtargetInfo *STI);
226 
227  bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
228  const MCSubtargetInfo *STI);
229 
230  bool loadImmediate(int64_t ImmValue, unsigned DstReg, unsigned SrcReg,
231  bool Is32BitImm, bool IsAddress, SMLoc IDLoc,
232  MCStreamer &Out, const MCSubtargetInfo *STI);
233 
234  bool loadAndAddSymbolAddress(const MCExpr *SymExpr, unsigned DstReg,
235  unsigned SrcReg, bool Is32BitSym, SMLoc IDLoc,
236  MCStreamer &Out, const MCSubtargetInfo *STI);
237 
238  bool emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc, MCSymbol *Sym);
239 
240  bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
241  MCStreamer &Out, const MCSubtargetInfo *STI);
242 
243  bool expandLoadSingleImmToGPR(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
244  const MCSubtargetInfo *STI);
245  bool expandLoadSingleImmToFPR(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
246  const MCSubtargetInfo *STI);
247  bool expandLoadDoubleImmToGPR(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
248  const MCSubtargetInfo *STI);
249  bool expandLoadDoubleImmToFPR(MCInst &Inst, bool Is64FPU, SMLoc IDLoc,
250  MCStreamer &Out, const MCSubtargetInfo *STI);
251 
252  bool expandLoadAddress(unsigned DstReg, unsigned BaseReg,
253  const MCOperand &Offset, bool Is32BitAddress,
254  SMLoc IDLoc, MCStreamer &Out,
255  const MCSubtargetInfo *STI);
256 
257  bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
258  const MCSubtargetInfo *STI);
259 
260  void expandMem16Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
261  const MCSubtargetInfo *STI, bool IsLoad);
262  void expandMem9Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
263  const MCSubtargetInfo *STI, bool IsLoad);
264 
265  bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
266  const MCSubtargetInfo *STI);
267 
268  bool expandAliasImmediate(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
269  const MCSubtargetInfo *STI);
270 
271  bool expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
272  const MCSubtargetInfo *STI);
273 
274  bool expandCondBranches(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
275  const MCSubtargetInfo *STI);
276 
277  bool expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
278  const MCSubtargetInfo *STI, const bool IsMips64,
279  const bool Signed);
280 
281  bool expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU, SMLoc IDLoc,
282  MCStreamer &Out, const MCSubtargetInfo *STI);
283 
284  bool expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc, MCStreamer &Out,
285  const MCSubtargetInfo *STI);
286 
287  bool expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
288  const MCSubtargetInfo *STI);
289 
290  bool expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
291  const MCSubtargetInfo *STI);
292 
293  bool expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
294  const MCSubtargetInfo *STI);
295 
296  bool expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
297  const MCSubtargetInfo *STI);
298 
299  bool expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
300  const MCSubtargetInfo *STI);
301 
302  bool expandSle(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
303  const MCSubtargetInfo *STI);
304 
305  bool expandSleImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
306  const MCSubtargetInfo *STI);
307 
308  bool expandRotation(MCInst &Inst, SMLoc IDLoc,
309  MCStreamer &Out, const MCSubtargetInfo *STI);
310  bool expandRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
311  const MCSubtargetInfo *STI);
312  bool expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
313  const MCSubtargetInfo *STI);
314  bool expandDRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
315  const MCSubtargetInfo *STI);
316 
317  bool expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
318  const MCSubtargetInfo *STI);
319 
320  bool expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
321  const MCSubtargetInfo *STI);
322 
323  bool expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
324  const MCSubtargetInfo *STI);
325 
326  bool expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
327  const MCSubtargetInfo *STI);
328 
329  bool expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
330  const MCSubtargetInfo *STI);
331 
332  bool expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
333  const MCSubtargetInfo *STI, bool IsLoad);
334 
335  bool expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
336  const MCSubtargetInfo *STI);
337 
338  bool expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
339  const MCSubtargetInfo *STI);
340 
341  bool expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
342  const MCSubtargetInfo *STI);
343 
344  bool expandSne(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
345  const MCSubtargetInfo *STI);
346 
347  bool expandSneI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
348  const MCSubtargetInfo *STI);
349 
350  bool expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
351  const MCSubtargetInfo *STI);
352 
353  bool expandSaaAddr(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
354  const MCSubtargetInfo *STI);
355 
356  bool reportParseError(const Twine &ErrorMsg);
357  bool reportParseError(SMLoc Loc, const Twine &ErrorMsg);
358 
359  bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
360 
361  bool parseSetMips0Directive();
362  bool parseSetArchDirective();
363  bool parseSetFeature(uint64_t Feature);
364  bool isPicAndNotNxxAbi(); // Used by .cpload, .cprestore, and .cpsetup.
365  bool parseDirectiveCpAdd(SMLoc Loc);
366  bool parseDirectiveCpLoad(SMLoc Loc);
367  bool parseDirectiveCpLocal(SMLoc Loc);
368  bool parseDirectiveCpRestore(SMLoc Loc);
369  bool parseDirectiveCPSetup();
370  bool parseDirectiveCPReturn();
371  bool parseDirectiveNaN();
372  bool parseDirectiveSet();
373  bool parseDirectiveOption();
374  bool parseInsnDirective();
375  bool parseRSectionDirective(StringRef Section);
376  bool parseSSectionDirective(StringRef Section, unsigned Type);
377 
378  bool parseSetAtDirective();
379  bool parseSetNoAtDirective();
380  bool parseSetMacroDirective();
381  bool parseSetNoMacroDirective();
382  bool parseSetMsaDirective();
383  bool parseSetNoMsaDirective();
384  bool parseSetNoDspDirective();
385  bool parseSetNoMips3DDirective();
386  bool parseSetReorderDirective();
387  bool parseSetNoReorderDirective();
388  bool parseSetMips16Directive();
389  bool parseSetNoMips16Directive();
390  bool parseSetFpDirective();
391  bool parseSetOddSPRegDirective();
392  bool parseSetNoOddSPRegDirective();
393  bool parseSetPopDirective();
394  bool parseSetPushDirective();
395  bool parseSetSoftFloatDirective();
396  bool parseSetHardFloatDirective();
397  bool parseSetMtDirective();
398  bool parseSetNoMtDirective();
399  bool parseSetNoCRCDirective();
400  bool parseSetNoVirtDirective();
401  bool parseSetNoGINVDirective();
402 
403  bool parseSetAssignment();
404 
405  bool parseDirectiveGpWord();
406  bool parseDirectiveGpDWord();
407  bool parseDirectiveDtpRelWord();
408  bool parseDirectiveDtpRelDWord();
409  bool parseDirectiveTpRelWord();
410  bool parseDirectiveTpRelDWord();
411  bool parseDirectiveModule();
412  bool parseDirectiveModuleFP();
413  bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
415 
416  bool parseInternalDirectiveReallowModule();
417 
418  bool eatComma(StringRef ErrorStr);
419 
420  int matchCPURegisterName(StringRef Symbol);
421 
422  int matchHWRegsRegisterName(StringRef Symbol);
423 
424  int matchFPURegisterName(StringRef Name);
425 
426  int matchFCCRegisterName(StringRef Name);
427 
428  int matchACRegisterName(StringRef Name);
429 
430  int matchMSA128RegisterName(StringRef Name);
431 
432  int matchMSA128CtrlRegisterName(StringRef Name);
433 
434  unsigned getReg(int RC, int RegNo);
435 
436  /// Returns the internal register number for the current AT. Also checks if
437  /// the current AT is unavailable (set to $0) and gives an error if it is.
438  /// This should be used in pseudo-instruction expansions which need AT.
439  unsigned getATReg(SMLoc Loc);
440 
441  bool canUseATReg();
442 
443  bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
444  const MCSubtargetInfo *STI);
445 
446  // Helper function that checks if the value of a vector index is within the
447  // boundaries of accepted values for each RegisterKind
448  // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
449  bool validateMSAIndex(int Val, int RegKind);
450 
451  // Selects a new architecture by updating the FeatureBits with the necessary
452  // info including implied dependencies.
453  // Internally, it clears all the feature bits related to *any* architecture
454  // and selects the new one using the ToggleFeature functionality of the
455  // MCSubtargetInfo object that handles implied dependencies. The reason we
456  // clear all the arch related bits manually is because ToggleFeature only
457  // clears the features that imply the feature being cleared and not the
458  // features implied by the feature being cleared. This is easier to see
459  // with an example:
460  // --------------------------------------------------
461  // | Feature | Implies |
462  // | -------------------------------------------------|
463  // | FeatureMips1 | None |
464  // | FeatureMips2 | FeatureMips1 |
465  // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
466  // | FeatureMips4 | FeatureMips3 |
467  // | ... | |
468  // --------------------------------------------------
469  //
470  // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
471  // FeatureMipsGP64 | FeatureMips1)
472  // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
473  void selectArch(StringRef ArchFeature) {
474  MCSubtargetInfo &STI = copySTI();
475  FeatureBitset FeatureBits = STI.getFeatureBits();
476  FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
477  STI.setFeatureBits(FeatureBits);
478  setAvailableFeatures(
479  ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
480  AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
481  }
482 
483  void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
484  if (!(getSTI().getFeatureBits()[Feature])) {
485  MCSubtargetInfo &STI = copySTI();
486  setAvailableFeatures(
487  ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
488  AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
489  }
490  }
491 
492  void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
493  if (getSTI().getFeatureBits()[Feature]) {
494  MCSubtargetInfo &STI = copySTI();
495  setAvailableFeatures(
496  ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
497  AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
498  }
499  }
500 
501  void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
502  setFeatureBits(Feature, FeatureString);
503  AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
504  }
505 
506  void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
507  clearFeatureBits(Feature, FeatureString);
508  AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
509  }
510 
511 public:
512  enum MipsMatchResultTy {
513  Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY,
514  Match_RequiresDifferentOperands,
515  Match_RequiresNoZeroRegister,
516  Match_RequiresSameSrcAndDst,
517  Match_NoFCCRegisterForCurrentISA,
518  Match_NonZeroOperandForSync,
519  Match_NonZeroOperandForMTCX,
520  Match_RequiresPosSizeRange0_32,
521  Match_RequiresPosSizeRange33_64,
522  Match_RequiresPosSizeUImm6,
523 #define GET_OPERAND_DIAGNOSTIC_TYPES
524 #include "MipsGenAsmMatcher.inc"
525 #undef GET_OPERAND_DIAGNOSTIC_TYPES
526  };
527 
528  MipsAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
529  const MCInstrInfo &MII, const MCTargetOptions &Options)
530  : MCTargetAsmParser(Options, sti, MII),
531  ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
532  sti.getCPU(), Options)) {
534 
535  parser.addAliasForDirective(".asciiz", ".asciz");
536  parser.addAliasForDirective(".hword", ".2byte");
537  parser.addAliasForDirective(".word", ".4byte");
538  parser.addAliasForDirective(".dword", ".8byte");
539 
540  // Initialize the set of available features.
541  setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
542 
543  // Remember the initial assembler options. The user can not modify these.
544  AssemblerOptions.push_back(
545  std::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
546 
547  // Create an assembler options environment for the user to modify.
548  AssemblerOptions.push_back(
549  std::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
550 
551  getTargetStreamer().updateABIInfo(*this);
552 
553  if (!isABI_O32() && !useOddSPReg() != 0)
554  report_fatal_error("-mno-odd-spreg requires the O32 ABI");
555 
556  CurrentFn = nullptr;
557 
558  IsPicEnabled = getContext().getObjectFileInfo()->isPositionIndependent();
559 
560  IsCpRestoreSet = false;
561  CpRestoreOffset = -1;
562  GPReg = ABI.GetGlobalPtr();
563 
564  const Triple &TheTriple = sti.getTargetTriple();
565  IsLittleEndian = TheTriple.isLittleEndian();
566 
567  if (getSTI().getCPU() == "mips64r6" && inMicroMipsMode())
568  report_fatal_error("microMIPS64R6 is not supported", false);
569 
570  if (!isABI_O32() && inMicroMipsMode())
571  report_fatal_error("microMIPS64 is not supported", false);
572  }
573 
574  /// True if all of $fcc0 - $fcc7 exist for the current ISA.
575  bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
576 
577  bool isGP64bit() const {
578  return getSTI().getFeatureBits()[Mips::FeatureGP64Bit];
579  }
580 
581  bool isFP64bit() const {
582  return getSTI().getFeatureBits()[Mips::FeatureFP64Bit];
583  }
584 
585  bool isJalrRelocAvailable(const MCExpr *JalExpr) {
586  if (!EmitJalrReloc)
587  return false;
588  MCValue Res;
589  if (!JalExpr->evaluateAsRelocatable(Res, nullptr, nullptr))
590  return false;
591  if (Res.getSymB() != nullptr)
592  return false;
593  if (Res.getConstant() != 0)
594  return ABI.IsN32() || ABI.IsN64();
595  return true;
596  }
597 
598  const MipsABIInfo &getABI() const { return ABI; }
599  bool isABI_N32() const { return ABI.IsN32(); }
600  bool isABI_N64() const { return ABI.IsN64(); }
601  bool isABI_O32() const { return ABI.IsO32(); }
602  bool isABI_FPXX() const {
603  return getSTI().getFeatureBits()[Mips::FeatureFPXX];
604  }
605 
606  bool useOddSPReg() const {
607  return !(getSTI().getFeatureBits()[Mips::FeatureNoOddSPReg]);
608  }
609 
610  bool inMicroMipsMode() const {
611  return getSTI().getFeatureBits()[Mips::FeatureMicroMips];
612  }
613 
614  bool hasMips1() const {
615  return getSTI().getFeatureBits()[Mips::FeatureMips1];
616  }
617 
618  bool hasMips2() const {
619  return getSTI().getFeatureBits()[Mips::FeatureMips2];
620  }
621 
622  bool hasMips3() const {
623  return getSTI().getFeatureBits()[Mips::FeatureMips3];
624  }
625 
626  bool hasMips4() const {
627  return getSTI().getFeatureBits()[Mips::FeatureMips4];
628  }
629 
630  bool hasMips5() const {
631  return getSTI().getFeatureBits()[Mips::FeatureMips5];
632  }
633 
634  bool hasMips32() const {
635  return getSTI().getFeatureBits()[Mips::FeatureMips32];
636  }
637 
638  bool hasMips64() const {
639  return getSTI().getFeatureBits()[Mips::FeatureMips64];
640  }
641 
642  bool hasMips32r2() const {
643  return getSTI().getFeatureBits()[Mips::FeatureMips32r2];
644  }
645 
646  bool hasMips64r2() const {
647  return getSTI().getFeatureBits()[Mips::FeatureMips64r2];
648  }
649 
650  bool hasMips32r3() const {
651  return (getSTI().getFeatureBits()[Mips::FeatureMips32r3]);
652  }
653 
654  bool hasMips64r3() const {
655  return (getSTI().getFeatureBits()[Mips::FeatureMips64r3]);
656  }
657 
658  bool hasMips32r5() const {
659  return (getSTI().getFeatureBits()[Mips::FeatureMips32r5]);
660  }
661 
662  bool hasMips64r5() const {
663  return (getSTI().getFeatureBits()[Mips::FeatureMips64r5]);
664  }
665 
666  bool hasMips32r6() const {
667  return getSTI().getFeatureBits()[Mips::FeatureMips32r6];
668  }
669 
670  bool hasMips64r6() const {
671  return getSTI().getFeatureBits()[Mips::FeatureMips64r6];
672  }
673 
674  bool hasDSP() const {
675  return getSTI().getFeatureBits()[Mips::FeatureDSP];
676  }
677 
678  bool hasDSPR2() const {
679  return getSTI().getFeatureBits()[Mips::FeatureDSPR2];
680  }
681 
682  bool hasDSPR3() const {
683  return getSTI().getFeatureBits()[Mips::FeatureDSPR3];
684  }
685 
686  bool hasMSA() const {
687  return getSTI().getFeatureBits()[Mips::FeatureMSA];
688  }
689 
690  bool hasCnMips() const {
691  return (getSTI().getFeatureBits()[Mips::FeatureCnMips]);
692  }
693 
694  bool hasCnMipsP() const {
695  return (getSTI().getFeatureBits()[Mips::FeatureCnMipsP]);
696  }
697 
698  bool inPicMode() {
699  return IsPicEnabled;
700  }
701 
702  bool inMips16Mode() const {
703  return getSTI().getFeatureBits()[Mips::FeatureMips16];
704  }
705 
706  bool useTraps() const {
707  return getSTI().getFeatureBits()[Mips::FeatureUseTCCInDIV];
708  }
709 
710  bool useSoftFloat() const {
711  return getSTI().getFeatureBits()[Mips::FeatureSoftFloat];
712  }
713  bool hasMT() const {
714  return getSTI().getFeatureBits()[Mips::FeatureMT];
715  }
716 
717  bool hasCRC() const {
718  return getSTI().getFeatureBits()[Mips::FeatureCRC];
719  }
720 
721  bool hasVirt() const {
722  return getSTI().getFeatureBits()[Mips::FeatureVirt];
723  }
724 
725  bool hasGINV() const {
726  return getSTI().getFeatureBits()[Mips::FeatureGINV];
727  }
728 
729  /// Warn if RegIndex is the same as the current AT.
730  void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
731 
732  void warnIfNoMacro(SMLoc Loc);
733 
734  bool isLittle() const { return IsLittleEndian; }
735 
736  const MCExpr *createTargetUnaryExpr(const MCExpr *E,
737  AsmToken::TokenKind OperatorToken,
738  MCContext &Ctx) override {
739  switch(OperatorToken) {
740  default:
741  llvm_unreachable("Unknown token");
742  return nullptr;
769  case AsmToken::PercentHi:
775  case AsmToken::PercentLo:
791  }
792  }
793 
794  bool areEqualRegs(const MCParsedAsmOperand &Op1,
795  const MCParsedAsmOperand &Op2) const override;
796 };
797 
798 /// MipsOperand - Instances of this class represent a parsed Mips machine
799 /// instruction.
800 class MipsOperand : public MCParsedAsmOperand {
801 public:
802  /// Broad categories of register classes
803  /// The exact class is finalized by the render method.
804  enum RegKind {
805  RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
806  RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
807  /// isFP64bit())
808  RegKind_FCC = 4, /// FCC
809  RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
810  RegKind_MSACtrl = 16, /// MSA control registers
811  RegKind_COP2 = 32, /// COP2
812  RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
813  /// context).
814  RegKind_CCR = 128, /// CCR
815  RegKind_HWRegs = 256, /// HWRegs
816  RegKind_COP3 = 512, /// COP3
817  RegKind_COP0 = 1024, /// COP0
818  /// Potentially any (e.g. $1)
819  RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
820  RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
821  RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
822  };
823 
824 private:
825  enum KindTy {
826  k_Immediate, /// An immediate (possibly involving symbol references)
827  k_Memory, /// Base + Offset Memory Address
828  k_RegisterIndex, /// A register index in one or more RegKind.
829  k_Token, /// A simple token
830  k_RegList, /// A physical register list
831  } Kind;
832 
833 public:
834  MipsOperand(KindTy K, MipsAsmParser &Parser) : Kind(K), AsmParser(Parser) {}
835 
836  ~MipsOperand() override {
837  switch (Kind) {
838  case k_Memory:
839  delete Mem.Base;
840  break;
841  case k_RegList:
842  delete RegList.List;
843  break;
844  case k_Immediate:
845  case k_RegisterIndex:
846  case k_Token:
847  break;
848  }
849  }
850 
851 private:
852  /// For diagnostics, and checking the assembler temporary
853  MipsAsmParser &AsmParser;
854 
855  struct Token {
856  const char *Data;
857  unsigned Length;
858  };
859 
860  struct RegIdxOp {
861  unsigned Index; /// Index into the register class
862  RegKind Kind; /// Bitfield of the kinds it could possibly be
863  struct Token Tok; /// The input token this operand originated from.
864  const MCRegisterInfo *RegInfo;
865  };
866 
867  struct ImmOp {
868  const MCExpr *Val;
869  };
870 
871  struct MemOp {
872  MipsOperand *Base;
873  const MCExpr *Off;
874  };
875 
876  struct RegListOp {
878  };
879 
880  union {
881  struct Token Tok;
882  struct RegIdxOp RegIdx;
883  struct ImmOp Imm;
884  struct MemOp Mem;
885  struct RegListOp RegList;
886  };
887 
888  SMLoc StartLoc, EndLoc;
889 
890  /// Internal constructor for register kinds
891  static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, StringRef Str,
892  RegKind RegKind,
893  const MCRegisterInfo *RegInfo,
894  SMLoc S, SMLoc E,
895  MipsAsmParser &Parser) {
896  auto Op = std::make_unique<MipsOperand>(k_RegisterIndex, Parser);
897  Op->RegIdx.Index = Index;
898  Op->RegIdx.RegInfo = RegInfo;
899  Op->RegIdx.Kind = RegKind;
900  Op->RegIdx.Tok.Data = Str.data();
901  Op->RegIdx.Tok.Length = Str.size();
902  Op->StartLoc = S;
903  Op->EndLoc = E;
904  return Op;
905  }
906 
907 public:
908  /// Coerce the register to GPR32 and return the real register for the current
909  /// target.
910  unsigned getGPR32Reg() const {
911  assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
912  AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
913  unsigned ClassID = Mips::GPR32RegClassID;
914  return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
915  }
916 
917  /// Coerce the register to GPR32 and return the real register for the current
918  /// target.
919  unsigned getGPRMM16Reg() const {
920  assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
921  unsigned ClassID = Mips::GPR32RegClassID;
922  return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
923  }
924 
925  /// Coerce the register to GPR64 and return the real register for the current
926  /// target.
927  unsigned getGPR64Reg() const {
928  assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
929  unsigned ClassID = Mips::GPR64RegClassID;
930  return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
931  }
932 
933 private:
934  /// Coerce the register to AFGR64 and return the real register for the current
935  /// target.
936  unsigned getAFGR64Reg() const {
937  assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
938  if (RegIdx.Index % 2 != 0)
939  AsmParser.Warning(StartLoc, "Float register should be even.");
940  return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
941  .getRegister(RegIdx.Index / 2);
942  }
943 
944  /// Coerce the register to FGR64 and return the real register for the current
945  /// target.
946  unsigned getFGR64Reg() const {
947  assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
948  return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
949  .getRegister(RegIdx.Index);
950  }
951 
952  /// Coerce the register to FGR32 and return the real register for the current
953  /// target.
954  unsigned getFGR32Reg() const {
955  assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
956  return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
957  .getRegister(RegIdx.Index);
958  }
959 
960  /// Coerce the register to FCC and return the real register for the current
961  /// target.
962  unsigned getFCCReg() const {
963  assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
964  return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
965  .getRegister(RegIdx.Index);
966  }
967 
968  /// Coerce the register to MSA128 and return the real register for the current
969  /// target.
970  unsigned getMSA128Reg() const {
971  assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
972  // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
973  // identical
974  unsigned ClassID = Mips::MSA128BRegClassID;
975  return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
976  }
977 
978  /// Coerce the register to MSACtrl and return the real register for the
979  /// current target.
980  unsigned getMSACtrlReg() const {
981  assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
982  unsigned ClassID = Mips::MSACtrlRegClassID;
983  return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
984  }
985 
986  /// Coerce the register to COP0 and return the real register for the
987  /// current target.
988  unsigned getCOP0Reg() const {
989  assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) && "Invalid access!");
990  unsigned ClassID = Mips::COP0RegClassID;
991  return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
992  }
993 
994  /// Coerce the register to COP2 and return the real register for the
995  /// current target.
996  unsigned getCOP2Reg() const {
997  assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
998  unsigned ClassID = Mips::COP2RegClassID;
999  return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1000  }
1001 
1002  /// Coerce the register to COP3 and return the real register for the
1003  /// current target.
1004  unsigned getCOP3Reg() const {
1005  assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
1006  unsigned ClassID = Mips::COP3RegClassID;
1007  return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1008  }
1009 
1010  /// Coerce the register to ACC64DSP and return the real register for the
1011  /// current target.
1012  unsigned getACC64DSPReg() const {
1013  assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
1014  unsigned ClassID = Mips::ACC64DSPRegClassID;
1015  return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1016  }
1017 
1018  /// Coerce the register to HI32DSP and return the real register for the
1019  /// current target.
1020  unsigned getHI32DSPReg() const {
1021  assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
1022  unsigned ClassID = Mips::HI32DSPRegClassID;
1023  return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1024  }
1025 
1026  /// Coerce the register to LO32DSP and return the real register for the
1027  /// current target.
1028  unsigned getLO32DSPReg() const {
1029  assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
1030  unsigned ClassID = Mips::LO32DSPRegClassID;
1031  return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1032  }
1033 
1034  /// Coerce the register to CCR and return the real register for the
1035  /// current target.
1036  unsigned getCCRReg() const {
1037  assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
1038  unsigned ClassID = Mips::CCRRegClassID;
1039  return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1040  }
1041 
1042  /// Coerce the register to HWRegs and return the real register for the
1043  /// current target.
1044  unsigned getHWRegsReg() const {
1045  assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
1046  unsigned ClassID = Mips::HWRegsRegClassID;
1047  return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
1048  }
1049 
1050 public:
1051  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
1052  // Add as immediate when possible. Null MCExpr = 0.
1053  if (!Expr)
1055  else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
1056  Inst.addOperand(MCOperand::createImm(CE->getValue()));
1057  else
1058  Inst.addOperand(MCOperand::createExpr(Expr));
1059  }
1060 
1061  void addRegOperands(MCInst &Inst, unsigned N) const {
1062  llvm_unreachable("Use a custom parser instead");
1063  }
1064 
1065  /// Render the operand to an MCInst as a GPR32
1066  /// Asserts if the wrong number of operands are requested, or the operand
1067  /// is not a k_RegisterIndex compatible with RegKind_GPR
1068  void addGPR32ZeroAsmRegOperands(MCInst &Inst, unsigned N) const {
1069  assert(N == 1 && "Invalid number of operands!");
1070  Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
1071  }
1072 
1073  void addGPR32NonZeroAsmRegOperands(MCInst &Inst, unsigned N) const {
1074  assert(N == 1 && "Invalid number of operands!");
1075  Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
1076  }
1077 
1078  void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1079  assert(N == 1 && "Invalid number of operands!");
1080  Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
1081  }
1082 
1083  void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
1084  assert(N == 1 && "Invalid number of operands!");
1085  Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1086  }
1087 
1088  void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
1089  assert(N == 1 && "Invalid number of operands!");
1090  Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1091  }
1092 
1093  void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
1094  assert(N == 1 && "Invalid number of operands!");
1095  Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1096  }
1097 
1098  void addGPRMM16AsmRegMovePPairFirstOperands(MCInst &Inst, unsigned N) const {
1099  assert(N == 1 && "Invalid number of operands!");
1100  Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1101  }
1102 
1103  void addGPRMM16AsmRegMovePPairSecondOperands(MCInst &Inst,
1104  unsigned N) const {
1105  assert(N == 1 && "Invalid number of operands!");
1106  Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
1107  }
1108 
1109  /// Render the operand to an MCInst as a GPR64
1110  /// Asserts if the wrong number of operands are requested, or the operand
1111  /// is not a k_RegisterIndex compatible with RegKind_GPR
1112  void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1113  assert(N == 1 && "Invalid number of operands!");
1114  Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
1115  }
1116 
1117  void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1118  assert(N == 1 && "Invalid number of operands!");
1119  Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
1120  }
1121 
1122  void addStrictlyAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1123  assert(N == 1 && "Invalid number of operands!");
1124  Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
1125  }
1126 
1127  void addStrictlyFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1128  assert(N == 1 && "Invalid number of operands!");
1129  Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
1130  }
1131 
1132  void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
1133  assert(N == 1 && "Invalid number of operands!");
1134  Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
1135  }
1136 
1137  void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1138  assert(N == 1 && "Invalid number of operands!");
1139  Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
1140  // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
1141  // FIXME: This should propagate failure up to parseStatement.
1142  if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1143  AsmParser.getParser().printError(
1144  StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
1145  "registers");
1146  }
1147 
1148  void addStrictlyFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
1149  assert(N == 1 && "Invalid number of operands!");
1150  Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
1151  // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
1152  if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
1153  AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
1154  "registers");
1155  }
1156 
1157  void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
1158  assert(N == 1 && "Invalid number of operands!");
1159  Inst.addOperand(MCOperand::createReg(getFCCReg()));
1160  }
1161 
1162  void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
1163  assert(N == 1 && "Invalid number of operands!");
1164  Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
1165  }
1166 
1167  void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
1168  assert(N == 1 && "Invalid number of operands!");
1169  Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
1170  }
1171 
1172  void addCOP0AsmRegOperands(MCInst &Inst, unsigned N) const {
1173  assert(N == 1 && "Invalid number of operands!");
1174  Inst.addOperand(MCOperand::createReg(getCOP0Reg()));
1175  }
1176 
1177  void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
1178  assert(N == 1 && "Invalid number of operands!");
1179  Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
1180  }
1181 
1182  void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
1183  assert(N == 1 && "Invalid number of operands!");
1184  Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
1185  }
1186 
1187  void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1188  assert(N == 1 && "Invalid number of operands!");
1189  Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
1190  }
1191 
1192  void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1193  assert(N == 1 && "Invalid number of operands!");
1194  Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
1195  }
1196 
1197  void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
1198  assert(N == 1 && "Invalid number of operands!");
1199  Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
1200  }
1201 
1202  void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
1203  assert(N == 1 && "Invalid number of operands!");
1204  Inst.addOperand(MCOperand::createReg(getCCRReg()));
1205  }
1206 
1207  void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
1208  assert(N == 1 && "Invalid number of operands!");
1209  Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
1210  }
1211 
1212  template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
1213  void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
1214  assert(N == 1 && "Invalid number of operands!");
1215  uint64_t Imm = getConstantImm() - Offset;
1216  Imm &= (1ULL << Bits) - 1;
1217  Imm += Offset;
1218  Imm += AdjustOffset;
1220  }
1221 
1222  template <unsigned Bits>
1223  void addSImmOperands(MCInst &Inst, unsigned N) const {
1224  if (isImm() && !isConstantImm()) {
1225  addExpr(Inst, getImm());
1226  return;
1227  }
1228  addConstantSImmOperands<Bits, 0, 0>(Inst, N);
1229  }
1230 
1231  template <unsigned Bits>
1232  void addUImmOperands(MCInst &Inst, unsigned N) const {
1233  if (isImm() && !isConstantImm()) {
1234  addExpr(Inst, getImm());
1235  return;
1236  }
1237  addConstantUImmOperands<Bits, 0, 0>(Inst, N);
1238  }
1239 
1240  template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
1241  void addConstantSImmOperands(MCInst &Inst, unsigned N) const {
1242  assert(N == 1 && "Invalid number of operands!");
1243  int64_t Imm = getConstantImm() - Offset;
1244  Imm = SignExtend64<Bits>(Imm);
1245  Imm += Offset;
1246  Imm += AdjustOffset;
1248  }
1249 
1250  void addImmOperands(MCInst &Inst, unsigned N) const {
1251  assert(N == 1 && "Invalid number of operands!");
1252  const MCExpr *Expr = getImm();
1253  addExpr(Inst, Expr);
1254  }
1255 
1256  void addMemOperands(MCInst &Inst, unsigned N) const {
1257  assert(N == 2 && "Invalid number of operands!");
1258 
1259  Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit()
1260  ? getMemBase()->getGPR64Reg()
1261  : getMemBase()->getGPR32Reg()));
1262 
1263  const MCExpr *Expr = getMemOff();
1264  addExpr(Inst, Expr);
1265  }
1266 
1267  void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
1268  assert(N == 2 && "Invalid number of operands!");
1269 
1270  Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
1271 
1272  const MCExpr *Expr = getMemOff();
1273  addExpr(Inst, Expr);
1274  }
1275 
1276  void addRegListOperands(MCInst &Inst, unsigned N) const {
1277  assert(N == 1 && "Invalid number of operands!");
1278 
1279  for (auto RegNo : getRegList())
1280  Inst.addOperand(MCOperand::createReg(RegNo));
1281  }
1282 
1283  bool isReg() const override {
1284  // As a special case until we sort out the definition of div/divu, accept
1285  // $0/$zero here so that MCK_ZERO works correctly.
1286  return isGPRAsmReg() && RegIdx.Index == 0;
1287  }
1288 
1289  bool isRegIdx() const { return Kind == k_RegisterIndex; }
1290  bool isImm() const override { return Kind == k_Immediate; }
1291 
1292  bool isConstantImm() const {
1293  int64_t Res;
1294  return isImm() && getImm()->evaluateAsAbsolute(Res);
1295  }
1296 
1297  bool isConstantImmz() const {
1298  return isConstantImm() && getConstantImm() == 0;
1299  }
1300 
1301  template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
1302  return isConstantImm() && isUInt<Bits>(getConstantImm() - Offset);
1303  }
1304 
1305  template <unsigned Bits> bool isSImm() const {
1306  return isConstantImm() ? isInt<Bits>(getConstantImm()) : isImm();
1307  }
1308 
1309  template <unsigned Bits> bool isUImm() const {
1310  return isConstantImm() ? isUInt<Bits>(getConstantImm()) : isImm();
1311  }
1312 
1313  template <unsigned Bits> bool isAnyImm() const {
1314  return isConstantImm() ? (isInt<Bits>(getConstantImm()) ||
1315  isUInt<Bits>(getConstantImm()))
1316  : isImm();
1317  }
1318 
1319  template <unsigned Bits, int Offset = 0> bool isConstantSImm() const {
1320  return isConstantImm() && isInt<Bits>(getConstantImm() - Offset);
1321  }
1322 
1323  template <unsigned Bottom, unsigned Top> bool isConstantUImmRange() const {
1324  return isConstantImm() && getConstantImm() >= Bottom &&
1325  getConstantImm() <= Top;
1326  }
1327 
1328  bool isToken() const override {
1329  // Note: It's not possible to pretend that other operand kinds are tokens.
1330  // The matcher emitter checks tokens first.
1331  return Kind == k_Token;
1332  }
1333 
1334  bool isMem() const override { return Kind == k_Memory; }
1335 
1336  bool isConstantMemOff() const {
1337  return isMem() && isa<MCConstantExpr>(getMemOff());
1338  }
1339 
1340  // Allow relocation operators.
1341  template <unsigned Bits, unsigned ShiftAmount = 0>
1342  bool isMemWithSimmOffset() const {
1343  if (!isMem())
1344  return false;
1345  if (!getMemBase()->isGPRAsmReg())
1346  return false;
1347  if (isa<MCTargetExpr>(getMemOff()) ||
1348  (isConstantMemOff() &&
1349  isShiftedInt<Bits, ShiftAmount>(getConstantMemOff())))
1350  return true;
1351  MCValue Res;
1352  bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr);
1353  return IsReloc && isShiftedInt<Bits, ShiftAmount>(Res.getConstant());
1354  }
1355 
1356  bool isMemWithPtrSizeOffset() const {
1357  if (!isMem())
1358  return false;
1359  if (!getMemBase()->isGPRAsmReg())
1360  return false;
1361  const unsigned PtrBits = AsmParser.getABI().ArePtrs64bit() ? 64 : 32;
1362  if (isa<MCTargetExpr>(getMemOff()) ||
1363  (isConstantMemOff() && isIntN(PtrBits, getConstantMemOff())))
1364  return true;
1365  MCValue Res;
1366  bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr);
1367  return IsReloc && isIntN(PtrBits, Res.getConstant());
1368  }
1369 
1370  bool isMemWithGRPMM16Base() const {
1371  return isMem() && getMemBase()->isMM16AsmReg();
1372  }
1373 
1374  template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
1375  return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1376  && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
1377  }
1378 
1379  template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
1380  return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1381  && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1382  && (getMemBase()->getGPR32Reg() == Mips::SP);
1383  }
1384 
1385  template <unsigned Bits> bool isMemWithSimmWordAlignedOffsetGP() const {
1386  return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
1387  && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1388  && (getMemBase()->getGPR32Reg() == Mips::GP);
1389  }
1390 
1391  template <unsigned Bits, unsigned ShiftLeftAmount>
1392  bool isScaledUImm() const {
1393  return isConstantImm() &&
1394  isShiftedUInt<Bits, ShiftLeftAmount>(getConstantImm());
1395  }
1396 
1397  template <unsigned Bits, unsigned ShiftLeftAmount>
1398  bool isScaledSImm() const {
1399  if (isConstantImm() &&
1400  isShiftedInt<Bits, ShiftLeftAmount>(getConstantImm()))
1401  return true;
1402  // Operand can also be a symbol or symbol plus
1403  // offset in case of relocations.
1404  if (Kind != k_Immediate)
1405  return false;
1406  MCValue Res;
1407  bool Success = getImm()->evaluateAsRelocatable(Res, nullptr, nullptr);
1408  return Success && isShiftedInt<Bits, ShiftLeftAmount>(Res.getConstant());
1409  }
1410 
1411  bool isRegList16() const {
1412  if (!isRegList())
1413  return false;
1414 
1415  int Size = RegList.List->size();
1416  if (Size < 2 || Size > 5)
1417  return false;
1418 
1419  unsigned R0 = RegList.List->front();
1420  unsigned R1 = RegList.List->back();
1421  if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1422  (R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1423  return false;
1424 
1425  int PrevReg = *RegList.List->begin();
1426  for (int i = 1; i < Size - 1; i++) {
1427  int Reg = (*(RegList.List))[i];
1428  if ( Reg != PrevReg + 1)
1429  return false;
1430  PrevReg = Reg;
1431  }
1432 
1433  return true;
1434  }
1435 
1436  bool isInvNum() const { return Kind == k_Immediate; }
1437 
1438  bool isLSAImm() const {
1439  if (!isConstantImm())
1440  return false;
1441  int64_t Val = getConstantImm();
1442  return 1 <= Val && Val <= 4;
1443  }
1444 
1445  bool isRegList() const { return Kind == k_RegList; }
1446 
1447  StringRef getToken() const {
1448  assert(Kind == k_Token && "Invalid access!");
1449  return StringRef(Tok.Data, Tok.Length);
1450  }
1451 
1452  unsigned getReg() const override {
1453  // As a special case until we sort out the definition of div/divu, accept
1454  // $0/$zero here so that MCK_ZERO works correctly.
1455  if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1456  RegIdx.Kind & RegKind_GPR)
1457  return getGPR32Reg(); // FIXME: GPR64 too
1458 
1459  llvm_unreachable("Invalid access!");
1460  return 0;
1461  }
1462 
1463  const MCExpr *getImm() const {
1464  assert((Kind == k_Immediate) && "Invalid access!");
1465  return Imm.Val;
1466  }
1467 
1468  int64_t getConstantImm() const {
1469  const MCExpr *Val = getImm();
1470  int64_t Value = 0;
1471  (void)Val->evaluateAsAbsolute(Value);
1472  return Value;
1473  }
1474 
1475  MipsOperand *getMemBase() const {
1476  assert((Kind == k_Memory) && "Invalid access!");
1477  return Mem.Base;
1478  }
1479 
1480  const MCExpr *getMemOff() const {
1481  assert((Kind == k_Memory) && "Invalid access!");
1482  return Mem.Off;
1483  }
1484 
1485  int64_t getConstantMemOff() const {
1486  return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1487  }
1488 
1489  const SmallVectorImpl<unsigned> &getRegList() const {
1490  assert((Kind == k_RegList) && "Invalid access!");
1491  return *(RegList.List);
1492  }
1493 
1494  static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1495  MipsAsmParser &Parser) {
1496  auto Op = std::make_unique<MipsOperand>(k_Token, Parser);
1497  Op->Tok.Data = Str.data();
1498  Op->Tok.Length = Str.size();
1499  Op->StartLoc = S;
1500  Op->EndLoc = S;
1501  return Op;
1502  }
1503 
1504  /// Create a numeric register (e.g. $1). The exact register remains
1505  /// unresolved until an instruction successfully matches
1506  static std::unique_ptr<MipsOperand>
1507  createNumericReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1508  SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1509  LLVM_DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1510  return CreateReg(Index, Str, RegKind_Numeric, RegInfo, S, E, Parser);
1511  }
1512 
1513  /// Create a register that is definitely a GPR.
1514  /// This is typically only used for named registers such as $gp.
1515  static std::unique_ptr<MipsOperand>
1516  createGPRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1517  SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1518  return CreateReg(Index, Str, RegKind_GPR, RegInfo, S, E, Parser);
1519  }
1520 
1521  /// Create a register that is definitely a FGR.
1522  /// This is typically only used for named registers such as $f0.
1523  static std::unique_ptr<MipsOperand>
1524  createFGRReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1525  SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1526  return CreateReg(Index, Str, RegKind_FGR, RegInfo, S, E, Parser);
1527  }
1528 
1529  /// Create a register that is definitely a HWReg.
1530  /// This is typically only used for named registers such as $hwr_cpunum.
1531  static std::unique_ptr<MipsOperand>
1532  createHWRegsReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1533  SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1534  return CreateReg(Index, Str, RegKind_HWRegs, RegInfo, S, E, Parser);
1535  }
1536 
1537  /// Create a register that is definitely an FCC.
1538  /// This is typically only used for named registers such as $fcc0.
1539  static std::unique_ptr<MipsOperand>
1540  createFCCReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1541  SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1542  return CreateReg(Index, Str, RegKind_FCC, RegInfo, S, E, Parser);
1543  }
1544 
1545  /// Create a register that is definitely an ACC.
1546  /// This is typically only used for named registers such as $ac0.
1547  static std::unique_ptr<MipsOperand>
1548  createACCReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1549  SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1550  return CreateReg(Index, Str, RegKind_ACC, RegInfo, S, E, Parser);
1551  }
1552 
1553  /// Create a register that is definitely an MSA128.
1554  /// This is typically only used for named registers such as $w0.
1555  static std::unique_ptr<MipsOperand>
1556  createMSA128Reg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1557  SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1558  return CreateReg(Index, Str, RegKind_MSA128, RegInfo, S, E, Parser);
1559  }
1560 
1561  /// Create a register that is definitely an MSACtrl.
1562  /// This is typically only used for named registers such as $msaaccess.
1563  static std::unique_ptr<MipsOperand>
1564  createMSACtrlReg(unsigned Index, StringRef Str, const MCRegisterInfo *RegInfo,
1565  SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1566  return CreateReg(Index, Str, RegKind_MSACtrl, RegInfo, S, E, Parser);
1567  }
1568 
1569  static std::unique_ptr<MipsOperand>
1570  CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1571  auto Op = std::make_unique<MipsOperand>(k_Immediate, Parser);
1572  Op->Imm.Val = Val;
1573  Op->StartLoc = S;
1574  Op->EndLoc = E;
1575  return Op;
1576  }
1577 
1578  static std::unique_ptr<MipsOperand>
1579  CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1580  SMLoc E, MipsAsmParser &Parser) {
1581  auto Op = std::make_unique<MipsOperand>(k_Memory, Parser);
1582  Op->Mem.Base = Base.release();
1583  Op->Mem.Off = Off;
1584  Op->StartLoc = S;
1585  Op->EndLoc = E;
1586  return Op;
1587  }
1588 
1589  static std::unique_ptr<MipsOperand>
1590  CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1591  MipsAsmParser &Parser) {
1592  assert(Regs.size() > 0 && "Empty list not allowed");
1593 
1594  auto Op = std::make_unique<MipsOperand>(k_RegList, Parser);
1595  Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1596  Op->StartLoc = StartLoc;
1597  Op->EndLoc = EndLoc;
1598  return Op;
1599  }
1600 
1601  bool isGPRZeroAsmReg() const {
1602  return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index == 0;
1603  }
1604 
1605  bool isGPRNonZeroAsmReg() const {
1606  return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index > 0 &&
1607  RegIdx.Index <= 31;
1608  }
1609 
1610  bool isGPRAsmReg() const {
1611  return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1612  }
1613 
1614  bool isMM16AsmReg() const {
1615  if (!(isRegIdx() && RegIdx.Kind))
1616  return false;
1617  return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1618  || RegIdx.Index == 16 || RegIdx.Index == 17);
1619 
1620  }
1621  bool isMM16AsmRegZero() const {
1622  if (!(isRegIdx() && RegIdx.Kind))
1623  return false;
1624  return (RegIdx.Index == 0 ||
1625  (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1626  RegIdx.Index == 17);
1627  }
1628 
1629  bool isMM16AsmRegMoveP() const {
1630  if (!(isRegIdx() && RegIdx.Kind))
1631  return false;
1632  return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1633  (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1634  }
1635 
1636  bool isMM16AsmRegMovePPairFirst() const {
1637  if (!(isRegIdx() && RegIdx.Kind))
1638  return false;
1639  return RegIdx.Index >= 4 && RegIdx.Index <= 6;
1640  }
1641 
1642  bool isMM16AsmRegMovePPairSecond() const {
1643  if (!(isRegIdx() && RegIdx.Kind))
1644  return false;
1645  return (RegIdx.Index == 21 || RegIdx.Index == 22 ||
1646  (RegIdx.Index >= 5 && RegIdx.Index <= 7));
1647  }
1648 
1649  bool isFGRAsmReg() const {
1650  // AFGR64 is $0-$15 but we handle this in getAFGR64()
1651  return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1652  }
1653 
1654  bool isStrictlyFGRAsmReg() const {
1655  // AFGR64 is $0-$15 but we handle this in getAFGR64()
1656  return isRegIdx() && RegIdx.Kind == RegKind_FGR && RegIdx.Index <= 31;
1657  }
1658 
1659  bool isHWRegsAsmReg() const {
1660  return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1661  }
1662 
1663  bool isCCRAsmReg() const {
1664  return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1665  }
1666 
1667  bool isFCCAsmReg() const {
1668  if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1669  return false;
1670  return RegIdx.Index <= 7;
1671  }
1672 
1673  bool isACCAsmReg() const {
1674  return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1675  }
1676 
1677  bool isCOP0AsmReg() const {
1678  return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1679  }
1680 
1681  bool isCOP2AsmReg() const {
1682  return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1683  }
1684 
1685  bool isCOP3AsmReg() const {
1686  return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1687  }
1688 
1689  bool isMSA128AsmReg() const {
1690  return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1691  }
1692 
1693  bool isMSACtrlAsmReg() const {
1694  return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1695  }
1696 
1697  /// getStartLoc - Get the location of the first token of this operand.
1698  SMLoc getStartLoc() const override { return StartLoc; }
1699  /// getEndLoc - Get the location of the last token of this operand.
1700  SMLoc getEndLoc() const override { return EndLoc; }
1701 
1702  void print(raw_ostream &OS) const override {
1703  switch (Kind) {
1704  case k_Immediate:
1705  OS << "Imm<";
1706  OS << *Imm.Val;
1707  OS << ">";
1708  break;
1709  case k_Memory:
1710  OS << "Mem<";
1711  Mem.Base->print(OS);
1712  OS << ", ";
1713  OS << *Mem.Off;
1714  OS << ">";
1715  break;
1716  case k_RegisterIndex:
1717  OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ", "
1718  << StringRef(RegIdx.Tok.Data, RegIdx.Tok.Length) << ">";
1719  break;
1720  case k_Token:
1721  OS << getToken();
1722  break;
1723  case k_RegList:
1724  OS << "RegList< ";
1725  for (auto Reg : (*RegList.List))
1726  OS << Reg << " ";
1727  OS << ">";
1728  break;
1729  }
1730  }
1731 
1732  bool isValidForTie(const MipsOperand &Other) const {
1733  if (Kind != Other.Kind)
1734  return false;
1735 
1736  switch (Kind) {
1737  default:
1738  llvm_unreachable("Unexpected kind");
1739  return false;
1740  case k_RegisterIndex: {
1741  StringRef Token(RegIdx.Tok.Data, RegIdx.Tok.Length);
1742  StringRef OtherToken(Other.RegIdx.Tok.Data, Other.RegIdx.Tok.Length);
1743  return Token == OtherToken;
1744  }
1745  }
1746  }
1747 }; // class MipsOperand
1748 
1749 } // end anonymous namespace
1750 
1751 namespace llvm {
1752 
1753 extern const MCInstrDesc MipsInsts[];
1754 
1755 } // end namespace llvm
1756 
1757 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1758  return MipsInsts[Opcode];
1759 }
1760 
1761 static bool hasShortDelaySlot(MCInst &Inst) {
1762  switch (Inst.getOpcode()) {
1763  case Mips::BEQ_MM:
1764  case Mips::BNE_MM:
1765  case Mips::BLTZ_MM:
1766  case Mips::BGEZ_MM:
1767  case Mips::BLEZ_MM:
1768  case Mips::BGTZ_MM:
1769  case Mips::JRC16_MM:
1770  case Mips::JALS_MM:
1771  case Mips::JALRS_MM:
1772  case Mips::JALRS16_MM:
1773  case Mips::BGEZALS_MM:
1774  case Mips::BLTZALS_MM:
1775  return true;
1776  case Mips::J_MM:
1777  return !Inst.getOperand(0).isReg();
1778  default:
1779  return false;
1780  }
1781 }
1782 
1783 static const MCSymbol *getSingleMCSymbol(const MCExpr *Expr) {
1784  if (const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1785  return &SRExpr->getSymbol();
1786  }
1787 
1788  if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1789  const MCSymbol *LHSSym = getSingleMCSymbol(BExpr->getLHS());
1790  const MCSymbol *RHSSym = getSingleMCSymbol(BExpr->getRHS());
1791 
1792  if (LHSSym)
1793  return LHSSym;
1794 
1795  if (RHSSym)
1796  return RHSSym;
1797 
1798  return nullptr;
1799  }
1800 
1801  if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1802  return getSingleMCSymbol(UExpr->getSubExpr());
1803 
1804  return nullptr;
1805 }
1806 
1807 static unsigned countMCSymbolRefExpr(const MCExpr *Expr) {
1808  if (isa<MCSymbolRefExpr>(Expr))
1809  return 1;
1810 
1811  if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1812  return countMCSymbolRefExpr(BExpr->getLHS()) +
1813  countMCSymbolRefExpr(BExpr->getRHS());
1814 
1815  if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1816  return countMCSymbolRefExpr(UExpr->getSubExpr());
1817 
1818  return 0;
1819 }
1820 
1821 static bool isEvaluated(const MCExpr *Expr) {
1822  switch (Expr->getKind()) {
1823  case MCExpr::Constant:
1824  return true;
1825  case MCExpr::SymbolRef:
1826  return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1827  case MCExpr::Binary: {
1828  const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);
1829  if (!isEvaluated(BE->getLHS()))
1830  return false;
1831  return isEvaluated(BE->getRHS());
1832  }
1833  case MCExpr::Unary:
1834  return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
1835  case MCExpr::Target:
1836  return true;
1837  }
1838  return false;
1839 }
1840 
1841 static bool needsExpandMemInst(MCInst &Inst) {
1842  const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1843 
1844  unsigned NumOp = MCID.getNumOperands();
1845  if (NumOp != 3 && NumOp != 4)
1846  return false;
1847 
1848  const MCOperandInfo &OpInfo = MCID.OpInfo[NumOp - 1];
1849  if (OpInfo.OperandType != MCOI::OPERAND_MEMORY &&
1850  OpInfo.OperandType != MCOI::OPERAND_UNKNOWN &&
1852  return false;
1853 
1854  MCOperand &Op = Inst.getOperand(NumOp - 1);
1855  if (Op.isImm()) {
1856  if (OpInfo.OperandType == MipsII::OPERAND_MEM_SIMM9)
1857  return !isInt<9>(Op.getImm());
1858  // Offset can't exceed 16bit value.
1859  return !isInt<16>(Op.getImm());
1860  }
1861 
1862  if (Op.isExpr()) {
1863  const MCExpr *Expr = Op.getExpr();
1864  if (Expr->getKind() != MCExpr::SymbolRef)
1865  return !isEvaluated(Expr);
1866 
1867  // Expand symbol.
1868  const MCSymbolRefExpr *SR = static_cast<const MCSymbolRefExpr *>(Expr);
1869  return SR->getKind() == MCSymbolRefExpr::VK_None;
1870  }
1871 
1872  return false;
1873 }
1874 
1875 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1876  MCStreamer &Out,
1877  const MCSubtargetInfo *STI) {
1878  MipsTargetStreamer &TOut = getTargetStreamer();
1879  const unsigned Opcode = Inst.getOpcode();
1880  const MCInstrDesc &MCID = getInstDesc(Opcode);
1881  bool ExpandedJalSym = false;
1882 
1883  Inst.setLoc(IDLoc);
1884 
1885  if (MCID.isBranch() || MCID.isCall()) {
1886  MCOperand Offset;
1887 
1888  switch (Opcode) {
1889  default:
1890  break;
1891  case Mips::BBIT0:
1892  case Mips::BBIT032:
1893  case Mips::BBIT1:
1894  case Mips::BBIT132:
1895  assert(hasCnMips() && "instruction only valid for octeon cpus");
1896  [[fallthrough]];
1897 
1898  case Mips::BEQ:
1899  case Mips::BNE:
1900  case Mips::BEQ_MM:
1901  case Mips::BNE_MM:
1902  assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1903  Offset = Inst.getOperand(2);
1904  if (!Offset.isImm())
1905  break; // We'll deal with this situation later on when applying fixups.
1906  if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1907  return Error(IDLoc, "branch target out of range");
1908  if (offsetToAlignment(Offset.getImm(),
1909  (inMicroMipsMode() ? Align(2) : Align(4))))
1910  return Error(IDLoc, "branch to misaligned address");
1911  break;
1912  case Mips::BGEZ:
1913  case Mips::BGTZ:
1914  case Mips::BLEZ:
1915  case Mips::BLTZ:
1916  case Mips::BGEZAL:
1917  case Mips::BLTZAL:
1918  case Mips::BC1F:
1919  case Mips::BC1T:
1920  case Mips::BGEZ_MM:
1921  case Mips::BGTZ_MM:
1922  case Mips::BLEZ_MM:
1923  case Mips::BLTZ_MM:
1924  case Mips::BGEZAL_MM:
1925  case Mips::BLTZAL_MM:
1926  case Mips::BC1F_MM:
1927  case Mips::BC1T_MM:
1928  case Mips::BC1EQZC_MMR6:
1929  case Mips::BC1NEZC_MMR6:
1930  case Mips::BC2EQZC_MMR6:
1931  case Mips::BC2NEZC_MMR6:
1932  assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1933  Offset = Inst.getOperand(1);
1934  if (!Offset.isImm())
1935  break; // We'll deal with this situation later on when applying fixups.
1936  if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1937  return Error(IDLoc, "branch target out of range");
1938  if (offsetToAlignment(Offset.getImm(),
1939  (inMicroMipsMode() ? Align(2) : Align(4))))
1940  return Error(IDLoc, "branch to misaligned address");
1941  break;
1942  case Mips::BGEC: case Mips::BGEC_MMR6:
1943  case Mips::BLTC: case Mips::BLTC_MMR6:
1944  case Mips::BGEUC: case Mips::BGEUC_MMR6:
1945  case Mips::BLTUC: case Mips::BLTUC_MMR6:
1946  case Mips::BEQC: case Mips::BEQC_MMR6:
1947  case Mips::BNEC: case Mips::BNEC_MMR6:
1948  assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1949  Offset = Inst.getOperand(2);
1950  if (!Offset.isImm())
1951  break; // We'll deal with this situation later on when applying fixups.
1952  if (!isIntN(18, Offset.getImm()))
1953  return Error(IDLoc, "branch target out of range");
1954  if (offsetToAlignment(Offset.getImm(), Align(4)))
1955  return Error(IDLoc, "branch to misaligned address");
1956  break;
1957  case Mips::BLEZC: case Mips::BLEZC_MMR6:
1958  case Mips::BGEZC: case Mips::BGEZC_MMR6:
1959  case Mips::BGTZC: case Mips::BGTZC_MMR6:
1960  case Mips::BLTZC: case Mips::BLTZC_MMR6:
1961  assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1962  Offset = Inst.getOperand(1);
1963  if (!Offset.isImm())
1964  break; // We'll deal with this situation later on when applying fixups.
1965  if (!isIntN(18, Offset.getImm()))
1966  return Error(IDLoc, "branch target out of range");
1967  if (offsetToAlignment(Offset.getImm(), Align(4)))
1968  return Error(IDLoc, "branch to misaligned address");
1969  break;
1970  case Mips::BEQZC: case Mips::BEQZC_MMR6:
1971  case Mips::BNEZC: case Mips::BNEZC_MMR6:
1972  assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1973  Offset = Inst.getOperand(1);
1974  if (!Offset.isImm())
1975  break; // We'll deal with this situation later on when applying fixups.
1976  if (!isIntN(23, Offset.getImm()))
1977  return Error(IDLoc, "branch target out of range");
1978  if (offsetToAlignment(Offset.getImm(), Align(4)))
1979  return Error(IDLoc, "branch to misaligned address");
1980  break;
1981  case Mips::BEQZ16_MM:
1982  case Mips::BEQZC16_MMR6:
1983  case Mips::BNEZ16_MM:
1984  case Mips::BNEZC16_MMR6:
1985  assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1986  Offset = Inst.getOperand(1);
1987  if (!Offset.isImm())
1988  break; // We'll deal with this situation later on when applying fixups.
1989  if (!isInt<8>(Offset.getImm()))
1990  return Error(IDLoc, "branch target out of range");
1991  if (offsetToAlignment(Offset.getImm(), Align(2)))
1992  return Error(IDLoc, "branch to misaligned address");
1993  break;
1994  }
1995  }
1996 
1997  // SSNOP is deprecated on MIPS32r6/MIPS64r6
1998  // We still accept it but it is a normal nop.
1999  if (hasMips32r6() && Opcode == Mips::SSNOP) {
2000  std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
2001  Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
2002  "nop instruction");
2003  }
2004 
2005  if (hasCnMips()) {
2006  MCOperand Opnd;
2007  int Imm;
2008 
2009  switch (Opcode) {
2010  default:
2011  break;
2012 
2013  case Mips::BBIT0:
2014  case Mips::BBIT032:
2015  case Mips::BBIT1:
2016  case Mips::BBIT132:
2017  assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
2018  // The offset is handled above
2019  Opnd = Inst.getOperand(1);
2020  if (!Opnd.isImm())
2021  return Error(IDLoc, "expected immediate operand kind");
2022  Imm = Opnd.getImm();
2023  if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
2024  Opcode == Mips::BBIT1 ? 63 : 31))
2025  return Error(IDLoc, "immediate operand value out of range");
2026  if (Imm > 31) {
2027  Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
2028  : Mips::BBIT132);
2029  Inst.getOperand(1).setImm(Imm - 32);
2030  }
2031  break;
2032 
2033  case Mips::SEQi:
2034  case Mips::SNEi:
2035  assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
2036  Opnd = Inst.getOperand(2);
2037  if (!Opnd.isImm())
2038  return Error(IDLoc, "expected immediate operand kind");
2039  Imm = Opnd.getImm();
2040  if (!isInt<10>(Imm))
2041  return Error(IDLoc, "immediate operand value out of range");
2042  break;
2043  }
2044  }
2045 
2046  // Warn on division by zero. We're checking here as all instructions get
2047  // processed here, not just the macros that need expansion.
2048  //
2049  // The MIPS backend models most of the divison instructions and macros as
2050  // three operand instructions. The pre-R6 divide instructions however have
2051  // two operands and explicitly define HI/LO as part of the instruction,
2052  // not in the operands.
2053  unsigned FirstOp = 1;
2054  unsigned SecondOp = 2;
2055  switch (Opcode) {
2056  default:
2057  break;
2058  case Mips::SDivIMacro:
2059  case Mips::UDivIMacro:
2060  case Mips::DSDivIMacro:
2061  case Mips::DUDivIMacro:
2062  if (Inst.getOperand(2).getImm() == 0) {
2063  if (Inst.getOperand(1).getReg() == Mips::ZERO ||
2064  Inst.getOperand(1).getReg() == Mips::ZERO_64)
2065  Warning(IDLoc, "dividing zero by zero");
2066  else
2067  Warning(IDLoc, "division by zero");
2068  }
2069  break;
2070  case Mips::DSDIV:
2071  case Mips::SDIV:
2072  case Mips::UDIV:
2073  case Mips::DUDIV:
2074  case Mips::UDIV_MM:
2075  case Mips::SDIV_MM:
2076  FirstOp = 0;
2077  SecondOp = 1;
2078  [[fallthrough]];
2079  case Mips::SDivMacro:
2080  case Mips::DSDivMacro:
2081  case Mips::UDivMacro:
2082  case Mips::DUDivMacro:
2083  case Mips::DIV:
2084  case Mips::DIVU:
2085  case Mips::DDIV:
2086  case Mips::DDIVU:
2087  case Mips::DIVU_MMR6:
2088  case Mips::DIV_MMR6:
2089  if (Inst.getOperand(SecondOp).getReg() == Mips::ZERO ||
2090  Inst.getOperand(SecondOp).getReg() == Mips::ZERO_64) {
2091  if (Inst.getOperand(FirstOp).getReg() == Mips::ZERO ||
2092  Inst.getOperand(FirstOp).getReg() == Mips::ZERO_64)
2093  Warning(IDLoc, "dividing zero by zero");
2094  else
2095  Warning(IDLoc, "division by zero");
2096  }
2097  break;
2098  }
2099 
2100  // For PIC code convert unconditional jump to unconditional branch.
2101  if ((Opcode == Mips::J || Opcode == Mips::J_MM) && inPicMode()) {
2102  MCInst BInst;
2103  BInst.setOpcode(inMicroMipsMode() ? Mips::BEQ_MM : Mips::BEQ);
2104  BInst.addOperand(MCOperand::createReg(Mips::ZERO));
2105  BInst.addOperand(MCOperand::createReg(Mips::ZERO));
2106  BInst.addOperand(Inst.getOperand(0));
2107  Inst = BInst;
2108  }
2109 
2110  // This expansion is not in a function called by tryExpandInstruction()
2111  // because the pseudo-instruction doesn't have a distinct opcode.
2112  if ((Opcode == Mips::JAL || Opcode == Mips::JAL_MM) && inPicMode()) {
2113  warnIfNoMacro(IDLoc);
2114 
2115  const MCExpr *JalExpr = Inst.getOperand(0).getExpr();
2116 
2117  // We can do this expansion if there's only 1 symbol in the argument
2118  // expression.
2119  if (countMCSymbolRefExpr(JalExpr) > 1)
2120  return Error(IDLoc, "jal doesn't support multiple symbols in PIC mode");
2121 
2122  // FIXME: This is checking the expression can be handled by the later stages
2123  // of the assembler. We ought to leave it to those later stages.
2124  const MCSymbol *JalSym = getSingleMCSymbol(JalExpr);
2125 
2126  if (expandLoadAddress(Mips::T9, Mips::NoRegister, Inst.getOperand(0),
2127  !isGP64bit(), IDLoc, Out, STI))
2128  return true;
2129 
2130  MCInst JalrInst;
2131  if (inMicroMipsMode())
2132  JalrInst.setOpcode(IsCpRestoreSet ? Mips::JALRS_MM : Mips::JALR_MM);
2133  else
2134  JalrInst.setOpcode(Mips::JALR);
2136  JalrInst.addOperand(MCOperand::createReg(Mips::T9));
2137 
2138  if (isJalrRelocAvailable(JalExpr)) {
2139  // As an optimization hint for the linker, before the JALR we add:
2140  // .reloc tmplabel, R_{MICRO}MIPS_JALR, symbol
2141  // tmplabel:
2142  MCSymbol *TmpLabel = getContext().createTempSymbol();
2143  const MCExpr *TmpExpr = MCSymbolRefExpr::create(TmpLabel, getContext());
2144  const MCExpr *RelocJalrExpr =
2146  getContext(), IDLoc);
2147 
2149  *TmpExpr, inMicroMipsMode() ? "R_MICROMIPS_JALR" : "R_MIPS_JALR",
2150  RelocJalrExpr, IDLoc, *STI);
2151  TOut.getStreamer().emitLabel(TmpLabel);
2152  }
2153 
2154  Inst = JalrInst;
2155  ExpandedJalSym = true;
2156  }
2157 
2158  if (MCID.mayLoad() || MCID.mayStore()) {
2159  // Check the offset of memory operand, if it is a symbol
2160  // reference or immediate we may have to expand instructions.
2161  if (needsExpandMemInst(Inst)) {
2162  const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
2163  switch (MCID.OpInfo[MCID.getNumOperands() - 1].OperandType) {
2165  expandMem9Inst(Inst, IDLoc, Out, STI, MCID.mayLoad());
2166  break;
2167  default:
2168  expandMem16Inst(Inst, IDLoc, Out, STI, MCID.mayLoad());
2169  break;
2170  }
2171  return getParser().hasPendingError();
2172  }
2173  }
2174 
2175  if (inMicroMipsMode()) {
2176  if (MCID.mayLoad() && Opcode != Mips::LWP_MM) {
2177  // Try to create 16-bit GP relative load instruction.
2178  for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
2179  const MCOperandInfo &OpInfo = MCID.OpInfo[i];
2180  if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
2181  (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
2182  MCOperand &Op = Inst.getOperand(i);
2183  if (Op.isImm()) {
2184  int MemOffset = Op.getImm();
2185  MCOperand &DstReg = Inst.getOperand(0);
2186  MCOperand &BaseReg = Inst.getOperand(1);
2187  if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
2188  getContext().getRegisterInfo()->getRegClass(
2189  Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
2190  (BaseReg.getReg() == Mips::GP ||
2191  BaseReg.getReg() == Mips::GP_64)) {
2192 
2193  TOut.emitRRI(Mips::LWGP_MM, DstReg.getReg(), Mips::GP, MemOffset,
2194  IDLoc, STI);
2195  return false;
2196  }
2197  }
2198  }
2199  } // for
2200  } // if load
2201 
2202  // TODO: Handle this with the AsmOperandClass.PredicateMethod.
2203 
2204  MCOperand Opnd;
2205  int Imm;
2206 
2207  switch (Opcode) {
2208  default:
2209  break;
2210  case Mips::ADDIUSP_MM:
2211  Opnd = Inst.getOperand(0);
2212  if (!Opnd.isImm())
2213  return Error(IDLoc, "expected immediate operand kind");
2214  Imm = Opnd.getImm();
2215  if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
2216  Imm % 4 != 0)
2217  return Error(IDLoc, "immediate operand value out of range");
2218  break;
2219  case Mips::SLL16_MM:
2220  case Mips::SRL16_MM:
2221  Opnd = Inst.getOperand(2);
2222  if (!Opnd.isImm())
2223  return Error(IDLoc, "expected immediate operand kind");
2224  Imm = Opnd.getImm();
2225  if (Imm < 1 || Imm > 8)
2226  return Error(IDLoc, "immediate operand value out of range");
2227  break;
2228  case Mips::LI16_MM:
2229  Opnd = Inst.getOperand(1);
2230  if (!Opnd.isImm())
2231  return Error(IDLoc, "expected immediate operand kind");
2232  Imm = Opnd.getImm();
2233  if (Imm < -1 || Imm > 126)
2234  return Error(IDLoc, "immediate operand value out of range");
2235  break;
2236  case Mips::ADDIUR2_MM:
2237  Opnd = Inst.getOperand(2);
2238  if (!Opnd.isImm())
2239  return Error(IDLoc, "expected immediate operand kind");
2240  Imm = Opnd.getImm();
2241  if (!(Imm == 1 || Imm == -1 ||
2242  ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
2243  return Error(IDLoc, "immediate operand value out of range");
2244  break;
2245  case Mips::ANDI16_MM:
2246  Opnd = Inst.getOperand(2);
2247  if (!Opnd.isImm())
2248  return Error(IDLoc, "expected immediate operand kind");
2249  Imm = Opnd.getImm();
2250  if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
2251  Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
2252  Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
2253  return Error(IDLoc, "immediate operand value out of range");
2254  break;
2255  case Mips::LBU16_MM:
2256  Opnd = Inst.getOperand(2);
2257  if (!Opnd.isImm())
2258  return Error(IDLoc, "expected immediate operand kind");
2259  Imm = Opnd.getImm();
2260  if (Imm < -1 || Imm > 14)
2261  return Error(IDLoc, "immediate operand value out of range");
2262  break;
2263  case Mips::SB16_MM:
2264  case Mips::SB16_MMR6:
2265  Opnd = Inst.getOperand(2);
2266  if (!Opnd.isImm())
2267  return Error(IDLoc, "expected immediate operand kind");
2268  Imm = Opnd.getImm();
2269  if (Imm < 0 || Imm > 15)
2270  return Error(IDLoc, "immediate operand value out of range");
2271  break;
2272  case Mips::LHU16_MM:
2273  case Mips::SH16_MM:
2274  case Mips::SH16_MMR6:
2275  Opnd = Inst.getOperand(2);
2276  if (!Opnd.isImm())
2277  return Error(IDLoc, "expected immediate operand kind");
2278  Imm = Opnd.getImm();
2279  if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
2280  return Error(IDLoc, "immediate operand value out of range");
2281  break;
2282  case Mips::LW16_MM:
2283  case Mips::SW16_MM:
2284  case Mips::SW16_MMR6:
2285  Opnd = Inst.getOperand(2);
2286  if (!Opnd.isImm())
2287  return Error(IDLoc, "expected immediate operand kind");
2288  Imm = Opnd.getImm();
2289  if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
2290  return Error(IDLoc, "immediate operand value out of range");
2291  break;
2292  case Mips::ADDIUPC_MM:
2293  Opnd = Inst.getOperand(1);
2294  if (!Opnd.isImm())
2295  return Error(IDLoc, "expected immediate operand kind");
2296  Imm = Opnd.getImm();
2297  if ((Imm % 4 != 0) || !isInt<25>(Imm))
2298  return Error(IDLoc, "immediate operand value out of range");
2299  break;
2300  case Mips::LWP_MM:
2301  case Mips::SWP_MM:
2302  if (Inst.getOperand(0).getReg() == Mips::RA)
2303  return Error(IDLoc, "invalid operand for instruction");
2304  break;
2305  case Mips::MOVEP_MM:
2306  case Mips::MOVEP_MMR6: {
2307  unsigned R0 = Inst.getOperand(0).getReg();
2308  unsigned R1 = Inst.getOperand(1).getReg();
2309  bool RegPair = ((R0 == Mips::A1 && R1 == Mips::A2) ||
2310  (R0 == Mips::A1 && R1 == Mips::A3) ||
2311  (R0 == Mips::A2 && R1 == Mips::A3) ||
2312  (R0 == Mips::A0 && R1 == Mips::S5) ||
2313  (R0 == Mips::A0 && R1 == Mips::S6) ||
2314  (R0 == Mips::A0 && R1 == Mips::A1) ||
2315  (R0 == Mips::A0 && R1 == Mips::A2) ||
2316  (R0 == Mips::A0 && R1 == Mips::A3));
2317  if (!RegPair)
2318  return Error(IDLoc, "invalid operand for instruction");
2319  break;
2320  }
2321  }
2322  }
2323 
2324  bool FillDelaySlot =
2325  MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder();
2326  if (FillDelaySlot)
2328 
2329  MacroExpanderResultTy ExpandResult =
2330  tryExpandInstruction(Inst, IDLoc, Out, STI);
2331  switch (ExpandResult) {
2332  case MER_NotAMacro:
2333  Out.emitInstruction(Inst, *STI);
2334  break;
2335  case MER_Success:
2336  break;
2337  case MER_Fail:
2338  return true;
2339  }
2340 
2341  // We know we emitted an instruction on the MER_NotAMacro or MER_Success path.
2342  // If we're in microMIPS mode then we must also set EF_MIPS_MICROMIPS.
2343  if (inMicroMipsMode()) {
2344  TOut.setUsesMicroMips();
2345  TOut.updateABIInfo(*this);
2346  }
2347 
2348  // If this instruction has a delay slot and .set reorder is active,
2349  // emit a NOP after it.
2350  if (FillDelaySlot) {
2351  TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst), IDLoc, STI);
2352  TOut.emitDirectiveSetReorder();
2353  }
2354 
2355  if ((Opcode == Mips::JalOneReg || Opcode == Mips::JalTwoReg ||
2356  ExpandedJalSym) &&
2357  isPicAndNotNxxAbi()) {
2358  if (IsCpRestoreSet) {
2359  // We need a NOP between the JALR and the LW:
2360  // If .set reorder has been used, we've already emitted a NOP.
2361  // If .set noreorder has been used, we need to emit a NOP at this point.
2362  if (!AssemblerOptions.back()->isReorder())
2363  TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst), IDLoc,
2364  STI);
2365 
2366  // Load the $gp from the stack.
2367  TOut.emitGPRestore(CpRestoreOffset, IDLoc, STI);
2368  } else
2369  Warning(IDLoc, "no .cprestore used in PIC mode");
2370  }
2371 
2372  return false;
2373 }
2374 
2375 MipsAsmParser::MacroExpanderResultTy
2376 MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2377  const MCSubtargetInfo *STI) {
2378  switch (Inst.getOpcode()) {
2379  default:
2380  return MER_NotAMacro;
2381  case Mips::LoadImm32:
2382  return expandLoadImm(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2383  case Mips::LoadImm64:
2384  return expandLoadImm(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2385  case Mips::LoadAddrImm32:
2386  case Mips::LoadAddrImm64:
2387  assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2388  assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
2389  "expected immediate operand kind");
2390 
2391  return expandLoadAddress(Inst.getOperand(0).getReg(), Mips::NoRegister,
2392  Inst.getOperand(1),
2393  Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc,
2394  Out, STI)
2395  ? MER_Fail
2396  : MER_Success;
2397  case Mips::LoadAddrReg32:
2398  case Mips::LoadAddrReg64:
2399  assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2400  assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2401  assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
2402  "expected immediate operand kind");
2403 
2404  return expandLoadAddress(Inst.getOperand(0).getReg(),
2405  Inst.getOperand(1).getReg(), Inst.getOperand(2),
2406  Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc,
2407  Out, STI)
2408  ? MER_Fail
2409  : MER_Success;
2410  case Mips::B_MM_Pseudo:
2411  case Mips::B_MMR6_Pseudo:
2412  return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
2413  : MER_Success;
2414  case Mips::SWM_MM:
2415  case Mips::LWM_MM:
2416  return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
2417  : MER_Success;
2418  case Mips::JalOneReg:
2419  case Mips::JalTwoReg:
2420  return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2421  case Mips::BneImm:
2422  case Mips::BeqImm:
2423  case Mips::BEQLImmMacro:
2424  case Mips::BNELImmMacro:
2425  return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2426  case Mips::BLT:
2427  case Mips::BLE:
2428  case Mips::BGE:
2429  case Mips::BGT:
2430  case Mips::BLTU:
2431  case Mips::BLEU:
2432  case Mips::BGEU:
2433  case Mips::BGTU:
2434  case Mips::BLTL:
2435  case Mips::BLEL:
2436  case Mips::BGEL:
2437  case Mips::BGTL:
2438  case Mips::BLTUL:
2439  case Mips::BLEUL:
2440  case Mips::BGEUL:
2441  case Mips::BGTUL:
2442  case Mips::BLTImmMacro:
2443  case Mips::BLEImmMacro:
2444  case Mips::BGEImmMacro:
2445  case Mips::BGTImmMacro:
2446  case Mips::BLTUImmMacro:
2447  case Mips::BLEUImmMacro:
2448  case Mips::BGEUImmMacro:
2449  case Mips::BGTUImmMacro:
2450  case Mips::BLTLImmMacro:
2451  case Mips::BLELImmMacro:
2452  case Mips::BGELImmMacro:
2453  case Mips::BGTLImmMacro:
2454  case Mips::BLTULImmMacro:
2455  case Mips::BLEULImmMacro:
2456  case Mips::BGEULImmMacro:
2457  case Mips::BGTULImmMacro:
2458  return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2459  case Mips::SDivMacro:
2460  case Mips::SDivIMacro:
2461  case Mips::SRemMacro:
2462  case Mips::SRemIMacro:
2463  return expandDivRem(Inst, IDLoc, Out, STI, false, true) ? MER_Fail
2464  : MER_Success;
2465  case Mips::DSDivMacro:
2466  case Mips::DSDivIMacro:
2467  case Mips::DSRemMacro:
2468  case Mips::DSRemIMacro:
2469  return expandDivRem(Inst, IDLoc, Out, STI, true, true) ? MER_Fail
2470  : MER_Success;
2471  case Mips::UDivMacro:
2472  case Mips::UDivIMacro:
2473  case Mips::URemMacro:
2474  case Mips::URemIMacro:
2475  return expandDivRem(Inst, IDLoc, Out, STI, false, false) ? MER_Fail
2476  : MER_Success;
2477  case Mips::DUDivMacro:
2478  case Mips::DUDivIMacro:
2479  case Mips::DURemMacro:
2480  case Mips::DURemIMacro:
2481  return expandDivRem(Inst, IDLoc, Out, STI, true, false) ? MER_Fail
2482  : MER_Success;
2483  case Mips::PseudoTRUNC_W_S:
2484  return expandTrunc(Inst, false, false, IDLoc, Out, STI) ? MER_Fail
2485  : MER_Success;
2486  case Mips::PseudoTRUNC_W_D32:
2487  return expandTrunc(Inst, true, false, IDLoc, Out, STI) ? MER_Fail
2488  : MER_Success;
2489  case Mips::PseudoTRUNC_W_D:
2490  return expandTrunc(Inst, true, true, IDLoc, Out, STI) ? MER_Fail
2491  : MER_Success;
2492 
2493  case Mips::LoadImmSingleGPR:
2494  return expandLoadSingleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2495  : MER_Success;
2496  case Mips::LoadImmSingleFGR:
2497  return expandLoadSingleImmToFPR(Inst, IDLoc, Out, STI) ? MER_Fail
2498  : MER_Success;
2499  case Mips::LoadImmDoubleGPR:
2500  return expandLoadDoubleImmToGPR(Inst, IDLoc, Out, STI) ? MER_Fail
2501  : MER_Success;
2502  case Mips::LoadImmDoubleFGR:
2503  return expandLoadDoubleImmToFPR(Inst, true, IDLoc, Out, STI) ? MER_Fail
2504  : MER_Success;
2505  case Mips::LoadImmDoubleFGR_32:
2506  return expandLoadDoubleImmToFPR(Inst, false, IDLoc, Out, STI) ? MER_Fail
2507  : MER_Success;
2508 
2509  case Mips::Ulh:
2510  return expandUlh(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2511  case Mips::Ulhu:
2512  return expandUlh(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2513  case Mips::Ush:
2514  return expandUsh(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2515  case Mips::Ulw:
2516  case Mips::Usw:
2517  return expandUxw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2518  case Mips::NORImm:
2519  case Mips::NORImm64:
2520  return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2521  case Mips::SGE:
2522  case Mips::SGEU:
2523  return expandSge(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2524  case Mips::SGEImm:
2525  case Mips::SGEUImm:
2526  case Mips::SGEImm64:
2527  case Mips::SGEUImm64:
2528  return expandSgeImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2529  case Mips::SGTImm:
2530  case Mips::SGTUImm:
2531  case Mips::SGTImm64:
2532  case Mips::SGTUImm64:
2533  return expandSgtImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2534  case Mips::SLE:
2535  case Mips::SLEU:
2536  return expandSle(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2537  case Mips::SLEImm:
2538  case Mips::SLEUImm:
2539  case Mips::SLEImm64:
2540  case Mips::SLEUImm64:
2541  return expandSleImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2542  case Mips::SLTImm64:
2543  if (isInt<16>(Inst.getOperand(2).getImm())) {
2544  Inst.setOpcode(Mips::SLTi64);
2545  return MER_NotAMacro;
2546  }
2547  return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2548  case Mips::SLTUImm64:
2549  if (isInt<16>(Inst.getOperand(2).getImm())) {
2550  Inst.setOpcode(Mips::SLTiu64);
2551  return MER_NotAMacro;
2552  }
2553  return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2554  case Mips::ADDi: case Mips::ADDi_MM:
2555  case Mips::ADDiu: case Mips::ADDiu_MM:
2556  case Mips::SLTi: case Mips::SLTi_MM:
2557  case Mips::SLTiu: case Mips::SLTiu_MM:
2558  if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2559  Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2560  int64_t ImmValue = Inst.getOperand(2).getImm();
2561  if (isInt<16>(ImmValue))
2562  return MER_NotAMacro;
2563  return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2564  : MER_Success;
2565  }
2566  return MER_NotAMacro;
2567  case Mips::ANDi: case Mips::ANDi_MM: case Mips::ANDi64:
2568  case Mips::ORi: case Mips::ORi_MM: case Mips::ORi64:
2569  case Mips::XORi: case Mips::XORi_MM: case Mips::XORi64:
2570  if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2571  Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2572  int64_t ImmValue = Inst.getOperand(2).getImm();
2573  if (isUInt<16>(ImmValue))
2574  return MER_NotAMacro;
2575  return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2576  : MER_Success;
2577  }
2578  return MER_NotAMacro;
2579  case Mips::ROL:
2580  case Mips::ROR:
2581  return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2582  case Mips::ROLImm:
2583  case Mips::RORImm:
2584  return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2585  case Mips::DROL:
2586  case Mips::DROR:
2587  return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2588  case Mips::DROLImm:
2589  case Mips::DRORImm:
2590  return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2591  case Mips::ABSMacro:
2592  return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2593  case Mips::MULImmMacro:
2594  case Mips::DMULImmMacro:
2595  return expandMulImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2596  case Mips::MULOMacro:
2597  case Mips::DMULOMacro:
2598  return expandMulO(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2599  case Mips::MULOUMacro:
2600  case Mips::DMULOUMacro:
2601  return expandMulOU(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2602  case Mips::DMULMacro:
2603  return expandDMULMacro(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2604  case Mips::LDMacro:
2605  case Mips::SDMacro:
2606  return expandLoadStoreDMacro(Inst, IDLoc, Out, STI,
2607  Inst.getOpcode() == Mips::LDMacro)
2608  ? MER_Fail
2609  : MER_Success;
2610  case Mips::SDC1_M1:
2611  return expandStoreDM1Macro(Inst, IDLoc, Out, STI)
2612  ? MER_Fail
2613  : MER_Success;
2614  case Mips::SEQMacro:
2615  return expandSeq(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2616  case Mips::SEQIMacro:
2617  return expandSeqI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2618  case Mips::SNEMacro:
2619  return expandSne(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2620  case Mips::SNEIMacro:
2621  return expandSneI(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2622  case Mips::MFTC0: case Mips::MTTC0:
2623  case Mips::MFTGPR: case Mips::MTTGPR:
2624  case Mips::MFTLO: case Mips::MTTLO:
2625  case Mips::MFTHI: case Mips::MTTHI:
2626  case Mips::MFTACX: case Mips::MTTACX:
2627  case Mips::MFTDSP: case Mips::MTTDSP:
2628  case Mips::MFTC1: case Mips::MTTC1:
2629  case Mips::MFTHC1: case Mips::MTTHC1:
2630  case Mips::CFTC1: case Mips::CTTC1:
2631  return expandMXTRAlias(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2632  case Mips::SaaAddr:
2633  case Mips::SaadAddr:
2634  return expandSaaAddr(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2635  }
2636 }
2637 
2638 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2639  MCStreamer &Out,
2640  const MCSubtargetInfo *STI) {
2641  MipsTargetStreamer &TOut = getTargetStreamer();
2642 
2643  // Create a JALR instruction which is going to replace the pseudo-JAL.
2644  MCInst JalrInst;
2645  JalrInst.setLoc(IDLoc);
2646  const MCOperand FirstRegOp = Inst.getOperand(0);
2647  const unsigned Opcode = Inst.getOpcode();
2648 
2649  if (Opcode == Mips::JalOneReg) {
2650  // jal $rs => jalr $rs
2651  if (IsCpRestoreSet && inMicroMipsMode()) {
2652  JalrInst.setOpcode(Mips::JALRS16_MM);
2653  JalrInst.addOperand(FirstRegOp);
2654  } else if (inMicroMipsMode()) {
2655  JalrInst.setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2656  JalrInst.addOperand(FirstRegOp);
2657  } else {
2658  JalrInst.setOpcode(Mips::JALR);
2660  JalrInst.addOperand(FirstRegOp);
2661  }
2662  } else if (Opcode == Mips::JalTwoReg) {
2663  // jal $rd, $rs => jalr $rd, $rs
2664  if (IsCpRestoreSet && inMicroMipsMode())
2665  JalrInst.setOpcode(Mips::JALRS_MM);
2666  else
2667  JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2668  JalrInst.addOperand(FirstRegOp);
2669  const MCOperand SecondRegOp = Inst.getOperand(1);
2670  JalrInst.addOperand(SecondRegOp);
2671  }
2672  Out.emitInstruction(JalrInst, *STI);
2673 
2674  // If .set reorder is active and branch instruction has a delay slot,
2675  // emit a NOP after it.
2676  const MCInstrDesc &MCID = getInstDesc(JalrInst.getOpcode());
2677  if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2678  TOut.emitEmptyDelaySlot(hasShortDelaySlot(JalrInst), IDLoc,
2679  STI);
2680 
2681  return false;
2682 }
2683 
2684 /// Can the value be represented by a unsigned N-bit value and a shift left?
2685 template <unsigned N> static bool isShiftedUIntAtAnyPosition(uint64_t x) {
2686  unsigned BitNum = findFirstSet(x);
2687 
2688  return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
2689 }
2690 
2691 /// Load (or add) an immediate into a register.
2692 ///
2693 /// @param ImmValue The immediate to load.
2694 /// @param DstReg The register that will hold the immediate.
2695 /// @param SrcReg A register to add to the immediate or Mips::NoRegister
2696 /// for a simple initialization.
2697 /// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2698 /// @param IsAddress True if the immediate represents an address. False if it
2699 /// is an integer.
2700 /// @param IDLoc Location of the immediate in the source file.
2701 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2702  unsigned SrcReg, bool Is32BitImm,
2703  bool IsAddress, SMLoc IDLoc, MCStreamer &Out,
2704  const MCSubtargetInfo *STI) {
2705  MipsTargetStreamer &TOut = getTargetStreamer();
2706 
2707  if (!Is32BitImm && !isGP64bit()) {
2708  Error(IDLoc, "instruction requires a 64-bit architecture");
2709  return true;
2710  }
2711 
2712  if (Is32BitImm) {
2713  if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2714  // Sign extend up to 64-bit so that the predicates match the hardware
2715  // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2716  // true.
2717  ImmValue = SignExtend64<32>(ImmValue);
2718  } else {
2719  Error(IDLoc, "instruction requires a 32-bit immediate");
2720  return true;
2721  }
2722  }
2723 
2724  unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2725  unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2726 
2727  bool UseSrcReg = false;
2728  if (SrcReg != Mips::NoRegister)
2729  UseSrcReg = true;
2730 
2731  unsigned TmpReg = DstReg;
2732  if (UseSrcReg &&
2733  getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2734  // At this point we need AT to perform the expansions and we exit if it is
2735  // not available.
2736  unsigned ATReg = getATReg(IDLoc);
2737  if (!ATReg)
2738  return true;
2739  TmpReg = ATReg;
2740  }
2741 
2742  if (isInt<16>(ImmValue)) {
2743  if (!UseSrcReg)
2744  SrcReg = ZeroReg;
2745 
2746  // This doesn't quite follow the usual ABI expectations for N32 but matches
2747  // traditional assembler behaviour. N32 would normally use addiu for both
2748  // integers and addresses.
2749  if (IsAddress && !Is32BitImm) {
2750  TOut.emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2751  return false;
2752  }
2753 
2754  TOut.emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2755  return false;
2756  }
2757 
2758  if (isUInt<16>(ImmValue)) {
2759  unsigned TmpReg = DstReg;
2760  if (SrcReg == DstReg) {
2761  TmpReg = getATReg(IDLoc);
2762  if (!TmpReg)
2763  return true;
2764  }
2765 
2766  TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2767  if (UseSrcReg)
2768  TOut.emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2769  return false;
2770  }
2771 
2772  if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2773  warnIfNoMacro(IDLoc);
2774 
2775  uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2776  uint16_t Bits15To0 = ImmValue & 0xffff;
2777  if (!Is32BitImm && !isInt<32>(ImmValue)) {
2778  // Traditional behaviour seems to special case this particular value. It's
2779  // not clear why other masks are handled differently.
2780  if (ImmValue == 0xffffffff) {
2781  TOut.emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2782  TOut.emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2783  if (UseSrcReg)
2784  TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2785  return false;
2786  }
2787 
2788  // Expand to an ORi instead of a LUi to avoid sign-extending into the
2789  // upper 32 bits.
2790  TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2791  TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2792  if (Bits15To0)
2793  TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2794  if (UseSrcReg)
2795  TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2796  return false;
2797  }
2798 
2799  TOut.emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2800  if (Bits15To0)
2801  TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2802  if (UseSrcReg)
2803  TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2804  return false;
2805  }
2806 
2807  if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2808  if (Is32BitImm) {
2809  Error(IDLoc, "instruction requires a 32-bit immediate");
2810  return true;
2811  }
2812 
2813  // Traditionally, these immediates are shifted as little as possible and as
2814  // such we align the most significant bit to bit 15 of our temporary.
2815  unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
2816  unsigned LastSet = findLastSet((uint64_t)ImmValue);
2817  unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2818  uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2819  TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2820  TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2821 
2822  if (UseSrcReg)
2823  TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2824 
2825  return false;
2826  }
2827 
2828  warnIfNoMacro(IDLoc);
2829 
2830  // The remaining case is packed with a sequence of dsll and ori with zeros
2831  // being omitted and any neighbouring dsll's being coalesced.
2832  // The highest 32-bit's are equivalent to a 32-bit immediate load.
2833 
2834  // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2835  if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2836  IDLoc, Out, STI))
2837  return false;
2838 
2839  // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2840  // skip it and defer the shift to the next chunk.
2841  unsigned ShiftCarriedForwards = 16;
2842  for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2843  uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2844 
2845  if (ImmChunk != 0) {
2846  TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2847  TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2848  ShiftCarriedForwards = 0;
2849  }
2850 
2851  ShiftCarriedForwards += 16;
2852  }
2853  ShiftCarriedForwards -= 16;
2854 
2855  // Finish any remaining shifts left by trailing zeros.
2856  if (ShiftCarriedForwards)
2857  TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2858 
2859  if (UseSrcReg)
2860  TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2861 
2862  return false;
2863 }
2864 
2865 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2866  MCStreamer &Out, const MCSubtargetInfo *STI) {
2867  const MCOperand &ImmOp = Inst.getOperand(1);
2868  assert(ImmOp.isImm() && "expected immediate operand kind");
2869  const MCOperand &DstRegOp = Inst.getOperand(0);
2870  assert(DstRegOp.isReg() && "expected register operand kind");
2871 
2872  if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2873  Is32BitImm, false, IDLoc, Out, STI))
2874  return true;
2875 
2876  return false;
2877 }
2878 
2879 bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2880  const MCOperand &Offset,
2881  bool Is32BitAddress, SMLoc IDLoc,
2882  MCStreamer &Out,
2883  const MCSubtargetInfo *STI) {
2884  // la can't produce a usable address when addresses are 64-bit.
2885  if (Is32BitAddress && ABI.ArePtrs64bit()) {
2886  Warning(IDLoc, "la used to load 64-bit address");
2887  // Continue as if we had 'dla' instead.
2888  Is32BitAddress = false;
2889  }
2890 
2891  // dla requires 64-bit addresses.
2892  if (!Is32BitAddress && !hasMips3()) {
2893  Error(IDLoc, "instruction requires a 64-bit architecture");
2894  return true;
2895  }
2896 
2897  if (!Offset.isImm())
2898  return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2899  Is32BitAddress, IDLoc, Out, STI);
2900 
2901  if (!ABI.ArePtrs64bit()) {
2902  // Continue as if we had 'la' whether we had 'la' or 'dla'.
2903  Is32BitAddress = true;
2904  }
2905 
2906  return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2907  IDLoc, Out, STI);
2908 }
2909 
2910 bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr,
2911  unsigned DstReg, unsigned SrcReg,
2912  bool Is32BitSym, SMLoc IDLoc,
2913  MCStreamer &Out,
2914  const MCSubtargetInfo *STI) {
2915  MipsTargetStreamer &TOut = getTargetStreamer();
2916  bool UseSrcReg = SrcReg != Mips::NoRegister && SrcReg != Mips::ZERO &&
2917  SrcReg != Mips::ZERO_64;
2918  warnIfNoMacro(IDLoc);
2919 
2920  if (inPicMode()) {
2921  MCValue Res;
2922  if (!SymExpr->evaluateAsRelocatable(Res, nullptr, nullptr)) {
2923  Error(IDLoc, "expected relocatable expression");
2924  return true;
2925  }
2926  if (Res.getSymB() != nullptr) {
2927  Error(IDLoc, "expected relocatable expression with only one symbol");
2928  return true;
2929  }
2930 
2931  bool IsPtr64 = ABI.ArePtrs64bit();
2932  bool IsLocalSym =
2933  Res.getSymA()->getSymbol().isInSection() ||
2934  Res.getSymA()->getSymbol().isTemporary() ||
2935  (Res.getSymA()->getSymbol().isELF() &&
2936  cast<MCSymbolELF>(Res.getSymA()->getSymbol()).getBinding() ==
2937  ELF::STB_LOCAL);
2938  bool UseXGOT = STI->getFeatureBits()[Mips::FeatureXGOT] && !IsLocalSym;
2939 
2940  // The case where the result register is $25 is somewhat special. If the
2941  // symbol in the final relocation is external and not modified with a
2942  // constant then we must use R_MIPS_CALL16 instead of R_MIPS_GOT16
2943  // or R_MIPS_CALL16 instead of R_MIPS_GOT_DISP in 64-bit case.
2944  if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2945  Res.getConstant() == 0 && !IsLocalSym) {
2946  if (UseXGOT) {
2948  SymExpr, getContext());
2950  SymExpr, getContext());
2951  TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(CallHiExpr), IDLoc,
2952  STI);
2953  TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, DstReg, GPReg,
2954  IDLoc, STI);
2955  TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, DstReg,
2956  MCOperand::createExpr(CallLoExpr), IDLoc, STI);
2957  } else {
2958  const MCExpr *CallExpr =
2959  MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, SymExpr, getContext());
2960  TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, GPReg,
2961  MCOperand::createExpr(CallExpr), IDLoc, STI);
2962  }
2963  return false;
2964  }
2965 
2966  unsigned TmpReg = DstReg;
2967  if (UseSrcReg &&
2968  getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2969  SrcReg)) {
2970  // If $rs is the same as $rd, we need to use AT.
2971  // If it is not available we exit.
2972  unsigned ATReg = getATReg(IDLoc);
2973  if (!ATReg)
2974  return true;
2975  TmpReg = ATReg;
2976  }
2977 
2978  // FIXME: In case of N32 / N64 ABI and emabled XGOT, local addresses
2979  // loaded using R_MIPS_GOT_PAGE / R_MIPS_GOT_OFST pair of relocations.
2980  // FIXME: Implement XGOT for microMIPS.
2981  if (UseXGOT) {
2982  // Loading address from XGOT
2983  // External GOT: lui $tmp, %got_hi(symbol)($gp)
2984  // addu $tmp, $tmp, $gp
2985  // lw $tmp, %got_lo(symbol)($tmp)
2986  // >addiu $tmp, $tmp, offset
2987  // >addiu $rd, $tmp, $rs
2988  // The addiu's marked with a '>' may be omitted if they are redundant. If
2989  // this happens then the last instruction must use $rd as the result
2990  // register.
2991  const MCExpr *CallHiExpr =
2992  MipsMCExpr::create(MipsMCExpr::MEK_GOT_HI16, SymExpr, getContext());
2993  const MCExpr *CallLoExpr = MipsMCExpr::create(
2994  MipsMCExpr::MEK_GOT_LO16, Res.getSymA(), getContext());
2995 
2996  TOut.emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(CallHiExpr), IDLoc,
2997  STI);
2998  TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg, GPReg,
2999  IDLoc, STI);
3000  TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, TmpReg,
3001  MCOperand::createExpr(CallLoExpr), IDLoc, STI);
3002 
3003  if (Res.getConstant() != 0)
3004  TOut.emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3006  Res.getConstant(), getContext())),
3007  IDLoc, STI);
3008 
3009  if (UseSrcReg)
3010  TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3011  IDLoc, STI);
3012  return false;
3013  }
3014 
3015  const MipsMCExpr *GotExpr = nullptr;
3016  const MCExpr *LoExpr = nullptr;
3017  if (ABI.IsN32() || ABI.IsN64()) {
3018  // The remaining cases are:
3019  // Small offset: ld $tmp, %got_disp(symbol)($gp)
3020  // >daddiu $tmp, $tmp, offset
3021  // >daddu $rd, $tmp, $rs
3022  // The daddiu's marked with a '>' may be omitted if they are redundant. If
3023  // this happens then the last instruction must use $rd as the result
3024  // register.
3026  getContext());
3027  if (Res.getConstant() != 0) {
3028  // Symbols fully resolve with just the %got_disp(symbol) but we
3029  // must still account for any offset to the symbol for
3030  // expressions like symbol+8.
3031  LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
3032 
3033  // FIXME: Offsets greater than 16 bits are not yet implemented.
3034  // FIXME: The correct range is a 32-bit sign-extended number.
3035  if (Res.getConstant() < -0x8000 || Res.getConstant() > 0x7fff) {
3036  Error(IDLoc, "macro instruction uses large offset, which is not "
3037  "currently supported");
3038  return true;
3039  }
3040  }
3041  } else {
3042  // The remaining cases are:
3043  // External GOT: lw $tmp, %got(symbol)($gp)
3044  // >addiu $tmp, $tmp, offset
3045  // >addiu $rd, $tmp, $rs
3046  // Local GOT: lw $tmp, %got(symbol+offset)($gp)
3047  // addiu $tmp, $tmp, %lo(symbol+offset)($gp)
3048  // >addiu $rd, $tmp, $rs
3049  // The addiu's marked with a '>' may be omitted if they are redundant. If
3050  // this happens then the last instruction must use $rd as the result
3051  // register.
3052  if (IsLocalSym) {
3053  GotExpr =
3054  MipsMCExpr::create(MipsMCExpr::MEK_GOT, SymExpr, getContext());
3055  LoExpr = MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
3056  } else {
3057  // External symbols fully resolve the symbol with just the %got(symbol)
3058  // but we must still account for any offset to the symbol for
3059  // expressions like symbol+8.
3061  getContext());
3062  if (Res.getConstant() != 0)
3063  LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
3064  }
3065  }
3066 
3067  TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, GPReg,
3068  MCOperand::createExpr(GotExpr), IDLoc, STI);
3069 
3070  if (LoExpr)
3071  TOut.emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3072  MCOperand::createExpr(LoExpr), IDLoc, STI);
3073 
3074  if (UseSrcReg)
3075  TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
3076  IDLoc, STI);
3077 
3078  return false;
3079  }
3080 
3081  const MipsMCExpr *HiExpr =
3082  MipsMCExpr::create(MipsMCExpr::MEK_HI, SymExpr, getContext());
3083  const MipsMCExpr *LoExpr =
3084  MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
3085 
3086  // This is the 64-bit symbol address expansion.
3087  if (ABI.ArePtrs64bit() && isGP64bit()) {
3088  // We need AT for the 64-bit expansion in the cases where the optional
3089  // source register is the destination register and for the superscalar
3090  // scheduled form.
3091  //
3092  // If it is not available we exit if the destination is the same as the
3093  // source register.
3094 
3095  const MipsMCExpr *HighestExpr =
3096  MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, SymExpr, getContext());
3097  const MipsMCExpr *HigherExpr =
3098  MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, SymExpr, getContext());
3099 
3100  bool RdRegIsRsReg =
3101  getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg);
3102 
3103  if (canUseATReg() && UseSrcReg && RdRegIsRsReg) {
3104  unsigned ATReg = getATReg(IDLoc);
3105 
3106  // If $rs is the same as $rd:
3107  // (d)la $rd, sym($rd) => lui $at, %highest(sym)
3108  // daddiu $at, $at, %higher(sym)
3109  // dsll $at, $at, 16
3110  // daddiu $at, $at, %hi(sym)
3111  // dsll $at, $at, 16
3112  // daddiu $at, $at, %lo(sym)
3113  // daddu $rd, $at, $rd
3114  TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
3115  STI);
3116  TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3117  MCOperand::createExpr(HigherExpr), IDLoc, STI);
3118  TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3119  TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
3120  IDLoc, STI);
3121  TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3122  TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
3123  IDLoc, STI);
3124  TOut.emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
3125 
3126  return false;
3127  } else if (canUseATReg() && !RdRegIsRsReg && DstReg != getATReg(IDLoc)) {
3128  unsigned ATReg = getATReg(IDLoc);
3129 
3130  // If the $rs is different from $rd or if $rs isn't specified and we
3131  // have $at available:
3132  // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
3133  // lui $at, %hi(sym)
3134  // daddiu $rd, $rd, %higher(sym)
3135  // daddiu $at, $at, %lo(sym)
3136  // dsll32 $rd, $rd, 0
3137  // daddu $rd, $rd, $at
3138  // (daddu $rd, $rd, $rs)
3139  //
3140  // Which is preferred for superscalar issue.
3141  TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
3142  STI);
3143  TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3144  TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3145  MCOperand::createExpr(HigherExpr), IDLoc, STI);
3146  TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
3147  IDLoc, STI);
3148  TOut.emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
3149  TOut.emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
3150  if (UseSrcReg)
3151  TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3152 
3153  return false;
3154  } else if ((!canUseATReg() && !RdRegIsRsReg) ||
3155  (canUseATReg() && DstReg == getATReg(IDLoc))) {
3156  // Otherwise, synthesize the address in the destination register
3157  // serially:
3158  // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
3159  // daddiu $rd, $rd, %higher(sym)
3160  // dsll $rd, $rd, 16
3161  // daddiu $rd, $rd, %hi(sym)
3162  // dsll $rd, $rd, 16
3163  // daddiu $rd, $rd, %lo(sym)
3164  TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
3165  STI);
3166  TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3167  MCOperand::createExpr(HigherExpr), IDLoc, STI);
3168  TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3169  TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3170  MCOperand::createExpr(HiExpr), IDLoc, STI);
3171  TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI);
3172  TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
3173  MCOperand::createExpr(LoExpr), IDLoc, STI);
3174  if (UseSrcReg)
3175  TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
3176 
3177  return false;
3178  } else {
3179  // We have a case where SrcReg == DstReg and we don't have $at
3180  // available. We can't expand this case, so error out appropriately.
3181  assert(SrcReg == DstReg && !canUseATReg() &&
3182  "Could have expanded dla but didn't?");
3183  reportParseError(IDLoc,
3184  "pseudo-instruction requires $at, which is not available");
3185  return true;
3186  }
3187  }
3188 
3189  // And now, the 32-bit symbol address expansion:
3190  // If $rs is the same as $rd:
3191  // (d)la $rd, sym($rd) => lui $at, %hi(sym)
3192  // ori $at, $at, %lo(sym)
3193  // addu $rd, $at, $rd
3194  // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
3195  // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
3196  // ori $rd, $rd, %lo(sym)
3197  // (addu $rd, $rd, $rs)
3198  unsigned TmpReg = DstReg;
3199  if (UseSrcReg &&
3200  getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
3201  // If $rs is the same as $rd, we need to use AT.
3202  // If it is not available we exit.
3203  unsigned ATReg = getATReg(IDLoc);
3204  if (!ATReg)
3205  return true;
3206  TmpReg = ATReg;
3207  }
3208 
3209  TOut.emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3210  TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
3211  IDLoc, STI);
3212 
3213  if (UseSrcReg)
3214  TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
3215  else
3216  assert(
3217  getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
3218 
3219  return false;
3220 }
3221 
3222 // Each double-precision register DO-D15 overlaps with two of the single
3223 // precision registers F0-F31. As an example, all of the following hold true:
3224 // D0 + 1 == F1, F1 + 1 == D1, F1 + 1 == F2, depending on the context.
3225 static unsigned nextReg(unsigned Reg) {
3226  if (MipsMCRegisterClasses[Mips::FGR32RegClassID].contains(Reg))
3227  return Reg == (unsigned)Mips::F31 ? (unsigned)Mips::F0 : Reg + 1;
3228  switch (Reg) {
3229  default: llvm_unreachable("Unknown register in assembly macro expansion!");
3230  case Mips::ZERO: return Mips::AT;
3231  case Mips::AT: return Mips::V0;
3232  case Mips::V0: return Mips::V1;
3233  case Mips::V1: return Mips::A0;
3234  case Mips::A0: return Mips::A1;
3235  case Mips::A1: return Mips::A2;
3236  case Mips::A2: return Mips::A3;
3237  case Mips::A3: return Mips::T0;
3238  case Mips::T0: return Mips::T1;
3239  case Mips::T1: return Mips::T2;
3240  case Mips::T2: return Mips::T3;
3241  case Mips::T3: return Mips::T4;
3242  case Mips::T4: return Mips::T5;
3243  case Mips::T5: return Mips::T6;
3244  case Mips::T6: return Mips::T7;
3245  case Mips::T7: return Mips::S0;
3246  case Mips::S0: return Mips::S1;
3247  case Mips::S1: return Mips::S2;
3248  case Mips::S2: return Mips::S3;
3249  case Mips::S3: return Mips::S4;
3250  case Mips::S4: return Mips::S5;
3251  case Mips::S5: return Mips::S6;
3252  case Mips::S6: return Mips::S7;
3253  case Mips::S7: return Mips::T8;
3254  case Mips::T8: return Mips::T9;
3255  case Mips::T9: return Mips::K0;
3256  case Mips::K0: return Mips::K1;
3257  case Mips::K1: return Mips::GP;
3258  case Mips::GP: return Mips::SP;
3259  case Mips::SP: return Mips::FP;
3260  case Mips::FP: return Mips::RA;
3261  case Mips::RA: return Mips::ZERO;
3262  case Mips::D0: return Mips::F1;
3263  case Mips::D1: return Mips::F3;
3264  case Mips::D2: return Mips::F5;
3265  case Mips::D3: return Mips::F7;
3266  case Mips::D4: return Mips::F9;
3267  case Mips::D5: return Mips::F11;
3268  case Mips::D6: return Mips::F13;
3269  case Mips::D7: return Mips::F15;
3270  case Mips::D8: return Mips::F17;
3271  case Mips::D9: return Mips::F19;
3272  case Mips::D10: return Mips::F21;
3273  case Mips::D11: return Mips::F23;
3274  case Mips::D12: return Mips::F25;
3275  case Mips::D13: return Mips::F27;
3276  case Mips::D14: return Mips::F29;
3277  case Mips::D15: return Mips::F31;
3278  }
3279 }
3280 
3281 // FIXME: This method is too general. In principle we should compute the number
3282 // of instructions required to synthesize the immediate inline compared to
3283 // synthesizing the address inline and relying on non .text sections.
3284 // For static O32 and N32 this may yield a small benefit, for static N64 this is
3285 // likely to yield a much larger benefit as we have to synthesize a 64bit
3286 // address to load a 64 bit value.
3287 bool MipsAsmParser::emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc,
3288  MCSymbol *Sym) {
3289  unsigned ATReg = getATReg(IDLoc);
3290  if (!ATReg)
3291  return true;
3292 
3293  if(IsPicEnabled) {
3294  const MCExpr *GotSym =
3296  const MipsMCExpr *GotExpr =
3297  MipsMCExpr::create(MipsMCExpr::MEK_GOT, GotSym, getContext());
3298 
3299  if(isABI_O32() || isABI_N32()) {
3300  TOut.emitRRX(Mips::LW, ATReg, GPReg, MCOperand::createExpr(GotExpr),
3301  IDLoc, STI);
3302  } else { //isABI_N64()
3303  TOut.emitRRX(Mips::LD, ATReg, GPReg, MCOperand::createExpr(GotExpr),
3304  IDLoc, STI);
3305  }
3306  } else { //!IsPicEnabled
3307  const MCExpr *HiSym =
3309  const MipsMCExpr *HiExpr =
3310  MipsMCExpr::create(MipsMCExpr::MEK_HI, HiSym, getContext());
3311 
3312  // FIXME: This is technically correct but gives a different result to gas,
3313  // but gas is incomplete there (it has a fixme noting it doesn't work with
3314  // 64-bit addresses).
3315  // FIXME: With -msym32 option, the address expansion for N64 should probably
3316  // use the O32 / N32 case. It's safe to use the 64 address expansion as the
3317  // symbol's value is considered sign extended.
3318  if(isABI_O32() || isABI_N32()) {
3319  TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
3320  } else { //isABI_N64()
3321  const MCExpr *HighestSym =
3323  const MipsMCExpr *HighestExpr =
3324  MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, HighestSym, getContext());
3325  const MCExpr *HigherSym =
3327  const MipsMCExpr *HigherExpr =
3328  MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, HigherSym, getContext());
3329 
3330  TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
3331  STI);
3332  TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
3333  MCOperand::createExpr(HigherExpr), IDLoc, STI);
3334  TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3335  TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
3336  IDLoc, STI);
3337  TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
3338  }
3339  }
3340  return false;
3341 }
3342 
3344  // If ImmOp64 is AsmToken::Integer type (all bits set to zero in the
3345  // exponent field), convert it to double (e.g. 1 to 1.0)
3346  if ((Hi_32(ImmOp64) & 0x7ff00000) == 0) {
3347  APFloat RealVal(APFloat::IEEEdouble(), ImmOp64);
3348  ImmOp64 = RealVal.bitcastToAPInt().getZExtValue();
3349  }
3350  return ImmOp64;
3351 }
3352 
3354  // Conversion of a double in an uint64_t to a float in a uint32_t,
3355  // retaining the bit pattern of a float.
3356  double DoubleImm = BitsToDouble(ImmOp64);
3357  float TmpFloat = static_cast<float>(DoubleImm);
3358  return FloatToBits(TmpFloat);
3359 }
3360 
3361 bool MipsAsmParser::expandLoadSingleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3362  MCStreamer &Out,
3363  const MCSubtargetInfo *STI) {
3364  assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3365  assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3366  "Invalid instruction operand.");
3367 
3368  unsigned FirstReg = Inst.getOperand(0).getReg();
3369  uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3370 
3372 
3373  return loadImmediate(ImmOp32, FirstReg, Mips::NoRegister, true, false, IDLoc,
3374  Out, STI);
3375 }
3376 
3377 bool MipsAsmParser::expandLoadSingleImmToFPR(MCInst &Inst, SMLoc IDLoc,
3378  MCStreamer &Out,
3379  const MCSubtargetInfo *STI) {
3380  MipsTargetStreamer &TOut = getTargetStreamer();
3381  assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3382  assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3383  "Invalid instruction operand.");
3384 
3385  unsigned FirstReg = Inst.getOperand(0).getReg();
3386  uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3387 
3388  ImmOp64 = convertIntToDoubleImm(ImmOp64);
3389 
3390  uint32_t ImmOp32 = covertDoubleImmToSingleImm(ImmOp64);
3391 
3392  unsigned TmpReg = Mips::ZERO;
3393  if (ImmOp32 != 0) {
3394  TmpReg = getATReg(IDLoc);
3395  if (!TmpReg)
3396  return true;
3397  }
3398 
3399  if (Lo_32(ImmOp64) == 0) {
3400  if (TmpReg != Mips::ZERO && loadImmediate(ImmOp32, TmpReg, Mips::NoRegister,
3401  true, false, IDLoc, Out, STI))
3402  return true;
3403  TOut.emitRR(Mips::MTC1, FirstReg, TmpReg, IDLoc, STI);
3404  return false;
3405  }
3406 
3407  MCSection *CS = getStreamer().getCurrentSectionOnly();
3408  // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3409  // where appropriate.
3410  MCSection *ReadOnlySection =
3411  getContext().getELFSection(".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3412 
3413  MCSymbol *Sym = getContext().createTempSymbol();
3414  const MCExpr *LoSym =
3416  const MipsMCExpr *LoExpr =
3417  MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3418 
3419  getStreamer().switchSection(ReadOnlySection);
3420  getStreamer().emitLabel(Sym, IDLoc);
3421  getStreamer().emitInt32(ImmOp32);
3422  getStreamer().switchSection(CS);
3423 
3424  if (emitPartialAddress(TOut, IDLoc, Sym))
3425  return true;
3426  TOut.emitRRX(Mips::LWC1, FirstReg, TmpReg, MCOperand::createExpr(LoExpr),
3427  IDLoc, STI);
3428  return false;
3429 }
3430 
3431 bool MipsAsmParser::expandLoadDoubleImmToGPR(MCInst &Inst, SMLoc IDLoc,
3432  MCStreamer &Out,
3433  const MCSubtargetInfo *STI) {
3434  MipsTargetStreamer &TOut = getTargetStreamer();
3435  assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3436  assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3437  "Invalid instruction operand.");
3438 
3439  unsigned FirstReg = Inst.getOperand(0).getReg();
3440  uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3441 
3442  ImmOp64 = convertIntToDoubleImm(ImmOp64);
3443 
3444  if (Lo_32(ImmOp64) == 0) {
3445  if (isGP64bit()) {
3446  if (loadImmediate(ImmOp64, FirstReg, Mips::NoRegister, false, false,
3447  IDLoc, Out, STI))
3448  return true;
3449  } else {
3450  if (loadImmediate(Hi_32(ImmOp64), FirstReg, Mips::NoRegister, true, false,
3451  IDLoc, Out, STI))
3452  return true;
3453 
3454  if (loadImmediate(0, nextReg(FirstReg), Mips::NoRegister, true, false,
3455  IDLoc, Out, STI))
3456  return true;
3457  }
3458  return false;
3459  }
3460 
3461  MCSection *CS = getStreamer().getCurrentSectionOnly();
3462  MCSection *ReadOnlySection =
3463  getContext().getELFSection(".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3464 
3465  MCSymbol *Sym = getContext().createTempSymbol();
3466  const MCExpr *LoSym =
3468  const MipsMCExpr *LoExpr =
3469  MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3470 
3471  getStreamer().switchSection(ReadOnlySection);
3472  getStreamer().emitLabel(Sym, IDLoc);
3473  getStreamer().emitValueToAlignment(Align(8));
3474  getStreamer().emitIntValue(ImmOp64, 8);
3475  getStreamer().switchSection(CS);
3476 
3477  unsigned TmpReg = getATReg(IDLoc);
3478  if (!TmpReg)
3479  return true;
3480 
3481  if (emitPartialAddress(TOut, IDLoc, Sym))
3482  return true;
3483 
3484  TOut.emitRRX(isABI_N64() ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
3485  MCOperand::createExpr(LoExpr), IDLoc, STI);
3486 
3487  if (isGP64bit())
3488  TOut.emitRRI(Mips::LD, FirstReg, TmpReg, 0, IDLoc, STI);
3489  else {
3490  TOut.emitRRI(Mips::LW, FirstReg, TmpReg, 0, IDLoc, STI);
3491  TOut.emitRRI(Mips::LW, nextReg(FirstReg), TmpReg, 4, IDLoc, STI);
3492  }
3493  return false;
3494 }
3495 
3496 bool MipsAsmParser::expandLoadDoubleImmToFPR(MCInst &Inst, bool Is64FPU,
3497  SMLoc IDLoc, MCStreamer &Out,
3498  const MCSubtargetInfo *STI) {
3499  MipsTargetStreamer &TOut = getTargetStreamer();
3500  assert(Inst.getNumOperands() == 2 && "Invalid operand count");
3501  assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() &&
3502  "Invalid instruction operand.");
3503 
3504  unsigned FirstReg = Inst.getOperand(0).getReg();
3505  uint64_t ImmOp64 = Inst.getOperand(1).getImm();
3506 
3507  ImmOp64 = convertIntToDoubleImm(ImmOp64);
3508 
3509  unsigned TmpReg = Mips::ZERO;
3510  if (ImmOp64 != 0) {
3511  TmpReg = getATReg(IDLoc);
3512  if (!TmpReg)
3513  return true;
3514  }
3515 
3516  if ((Lo_32(ImmOp64) == 0) &&
3517  !((Hi_32(ImmOp64) & 0xffff0000) && (Hi_32(ImmOp64) & 0x0000ffff))) {
3518  if (isGP64bit()) {
3519  if (TmpReg != Mips::ZERO &&
3520  loadImmediate(ImmOp64, TmpReg, Mips::NoRegister, false, false, IDLoc,
3521  Out, STI))
3522  return true;
3523  TOut.emitRR(Mips::DMTC1, FirstReg, TmpReg, IDLoc, STI);
3524  return false;
3525  }
3526 
3527  if (TmpReg != Mips::ZERO &&
3528  loadImmediate(Hi_32(ImmOp64), TmpReg, Mips::NoRegister, true, false,
3529  IDLoc, Out, STI))
3530  return true;
3531 
3532  if (hasMips32r2()) {
3533  TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3534  TOut.emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, TmpReg, IDLoc, STI);
3535  } else {
3536  TOut.emitRR(Mips::MTC1, nextReg(FirstReg), TmpReg, IDLoc, STI);
3537  TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI);
3538  }
3539  return false;
3540  }
3541 
3542  MCSection *CS = getStreamer().getCurrentSectionOnly();
3543  // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections
3544  // where appropriate.
3545  MCSection *ReadOnlySection =
3546  getContext().getELFSection(".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
3547 
3548  MCSymbol *Sym = getContext().createTempSymbol();
3549  const MCExpr *LoSym =
3551  const MipsMCExpr *LoExpr =
3552  MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext());
3553 
3554  getStreamer().switchSection(ReadOnlySection);
3555  getStreamer().emitLabel(Sym, IDLoc);
3556  getStreamer().emitValueToAlignment(Align(8));
3557  getStreamer().emitIntValue(ImmOp64, 8);
3558  getStreamer().switchSection(CS);
3559 
3560  if (emitPartialAddress(TOut, IDLoc, Sym))
3561  return true;
3562 
3563  TOut.emitRRX(Is64FPU ? Mips::LDC164 : Mips::LDC1, FirstReg, TmpReg,
3564  MCOperand::createExpr(LoExpr), IDLoc, STI);
3565 
3566  return false;
3567 }
3568 
3569 bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
3570  MCStreamer &Out,
3571  const MCSubtargetInfo *STI) {
3572  MipsTargetStreamer &TOut = getTargetStreamer();
3573 
3574  assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
3575  "unexpected number of operands");
3576 
3577  MCOperand Offset = Inst.getOperand(0);
3578  if (Offset.isExpr()) {
3579  Inst.clear();
3580  Inst.setOpcode(Mips::BEQ_MM);
3581  Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3582  Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3583  Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
3584  } else {
3585  assert(Offset.isImm() && "expected immediate operand kind");
3586  if (isInt<11>(Offset.getImm())) {
3587  // If offset fits into 11 bits then this instruction becomes microMIPS
3588  // 16-bit unconditional branch instruction.
3589  if (inMicroMipsMode())
3590  Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
3591  } else {
3592  if (!isInt<17>(Offset.getImm()))
3593  return Error(IDLoc, "branch target out of range");
3594  if (offsetToAlignment(Offset.getImm(), Align(2)))
3595  return Error(IDLoc, "branch to misaligned address");
3596  Inst.clear();
3597  Inst.setOpcode(Mips::BEQ_MM);
3598  Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3599  Inst.addOperand(MCOperand::createReg(Mips::ZERO));
3600  Inst.addOperand(MCOperand::createImm(Offset.getImm()));
3601  }
3602  }
3603  Out.emitInstruction(Inst, *STI);
3604 
3605  // If .set reorder is active and branch instruction has a delay slot,
3606  // emit a NOP after it.
3607  const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
3608  if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
3609  TOut.emitEmptyDelaySlot(true, IDLoc, STI);
3610 
3611  return false;
3612 }
3613 
3614 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3615  const MCSubtargetInfo *STI) {
3616  MipsTargetStreamer &TOut = getTargetStreamer();
3617  const MCOperand &DstRegOp = Inst.getOperand(0);
3618  assert(DstRegOp.isReg() && "expected register operand kind");
3619 
3620  const MCOperand &ImmOp = Inst.getOperand(1);
3621  assert(ImmOp.isImm() && "expected immediate operand kind");
3622 
3623  const MCOperand &MemOffsetOp = Inst.getOperand(2);
3624  assert((MemOffsetOp.isImm() || MemOffsetOp.isExpr()) &&
3625  "expected immediate or expression operand");
3626 
3627  bool IsLikely = false;
3628 
3629  unsigned OpCode = 0;
3630  switch(Inst.getOpcode()) {
3631  case Mips::BneImm:
3632  OpCode = Mips::BNE;
3633  break;
3634  case Mips::BeqImm:
3635  OpCode = Mips::BEQ;
3636  break;
3637  case Mips::BEQLImmMacro:
3638  OpCode = Mips::BEQL;
3639  IsLikely = true;
3640  break;
3641  case Mips::BNELImmMacro:
3642  OpCode = Mips::BNEL;
3643  IsLikely = true;
3644  break;
3645  default:
3646  llvm_unreachable("Unknown immediate branch pseudo-instruction.");
3647  break;
3648  }
3649 
3650  int64_t ImmValue = ImmOp.getImm();
3651  if (ImmValue == 0) {
3652  if (IsLikely) {
3653  TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO,
3654  MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3655  TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3656  } else
3657  TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
3658  STI);
3659  } else {
3660  warnIfNoMacro(IDLoc);
3661 
3662  unsigned ATReg = getATReg(IDLoc);
3663  if (!ATReg)
3664  return true;
3665 
3666  if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
3667  IDLoc, Out, STI))
3668  return true;
3669 
3670  if (IsLikely) {
3671  TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg,
3672  MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI);
3673  TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
3674  } else
3675  TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, STI);
3676  }
3677  return false;
3678 }
3679 
3680 void MipsAsmParser::expandMem16Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3681  const MCSubtargetInfo *STI, bool IsLoad) {
3682  unsigned NumOp = Inst.getNumOperands();
3683  assert((NumOp == 3 || NumOp == 4) && "unexpected operands number");
3684  unsigned StartOp = NumOp == 3 ? 0 : 1;
3685 
3686  const MCOperand &DstRegOp = Inst.getOperand(StartOp);
3687  assert(DstRegOp.isReg() && "expected register operand kind");
3688  const MCOperand &BaseRegOp = Inst.getOperand(StartOp + 1);
3689  assert(BaseRegOp.isReg() && "expected register operand kind");
3690  const MCOperand &OffsetOp = Inst.getOperand(StartOp + 2);
3691 
3692  MipsTargetStreamer &TOut = getTargetStreamer();
3693  unsigned OpCode = Inst.getOpcode();
3694  unsigned DstReg = DstRegOp.getReg();
3695  unsigned BaseReg = BaseRegOp.getReg();
3696  unsigned TmpReg = DstReg;
3697 
3698  const MCInstrDesc &Desc = getInstDesc(OpCode);
3699  int16_t DstRegClass = Desc.OpInfo[StartOp].RegClass;
3700  unsigned DstRegClassID =
3701  getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3702  bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3703  (DstRegClassID == Mips::GPR64RegClassID);
3704 
3705  if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3706  // At this point we need AT to perform the expansions
3707  // and we exit if it is not available.
3708  TmpReg = getATReg(IDLoc);
3709  if (!TmpReg)
3710  return;
3711  }
3712 
3713  auto emitInstWithOffset = [&](const MCOperand &Off) {
3714  if (NumOp == 3)
3715  TOut.emitRRX(OpCode, DstReg, TmpReg, Off, IDLoc, STI);
3716  else
3717  TOut.emitRRRX(OpCode, DstReg, DstReg, TmpReg, Off, IDLoc, STI);
3718  };
3719 
3720  if (OffsetOp.isImm()) {
3721  int64_t LoOffset = OffsetOp.getImm() & 0xffff;
3722  int64_t HiOffset = OffsetOp.getImm() & ~0xffff;
3723 
3724  // If msb of LoOffset is 1(negative number) we must increment
3725  // HiOffset to account for the sign-extension of the low part.
3726  if (LoOffset & 0x8000)
3727  HiOffset += 0x10000;
3728 
3729  bool IsLargeOffset = HiOffset != 0;
3730 
3731  if (IsLargeOffset) {
3732  bool Is32BitImm = isInt<32>(OffsetOp.getImm());
3733  if (loadImmediate(HiOffset, TmpReg, Mips::NoRegister, Is32BitImm, true,
3734  IDLoc, Out, STI))
3735  return;
3736  }
3737 
3738  if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3739  TOut.emitRRR(ABI.ArePtrs64bit() ? Mips::DADDu : Mips::ADDu, TmpReg,
3740  TmpReg, BaseReg, IDLoc, STI);
3741  emitInstWithOffset(MCOperand::createImm(int16_t(LoOffset)));
3742  return;
3743  }
3744 
3745  if (OffsetOp.isExpr()) {
3746  if (inPicMode()) {
3747  // FIXME:
3748  // c) Check that immediates of R_MIPS_GOT16/R_MIPS_LO16 relocations
3749  // do not exceed 16-bit.
3750  // d) Use R_MIPS_GOT_PAGE/R_MIPS_GOT_OFST relocations instead
3751  // of R_MIPS_GOT_DISP in appropriate cases to reduce number
3752  // of GOT entries.
3753  MCValue Res;
3754  if (!OffsetOp.getExpr()->evaluateAsRelocatable(Res, nullptr, nullptr)) {
3755  Error(IDLoc, "expected relocatable expression");
3756  return;
3757  }
3758  if (Res.getSymB() != nullptr) {
3759  Error(IDLoc, "expected relocatable expression with only one symbol");
3760  return;
3761  }
3762 
3763  loadAndAddSymbolAddress(Res.getSymA(), TmpReg, BaseReg,
3764  !ABI.ArePtrs64bit(), IDLoc, Out, STI);
3765  emitInstWithOffset(MCOperand::createImm(int16_t(Res.getConstant())));
3766  } else {
3767  // FIXME: Implement 64-bit case.
3768  // 1) lw $8, sym => lui $8, %hi(sym)
3769  // lw $8, %lo(sym)($8)
3770  // 2) sw $8, sym => lui $at, %hi(sym)
3771  // sw $8, %lo(sym)($at)
3772  const MCExpr *OffExpr = OffsetOp.getExpr();
3773  MCOperand LoOperand = MCOperand::createExpr(
3774  MipsMCExpr::create(MipsMCExpr::MEK_LO, OffExpr, getContext()));
3775  MCOperand HiOperand = MCOperand::createExpr(
3776  MipsMCExpr::create(MipsMCExpr::MEK_HI, OffExpr, getContext()));
3777 
3778  if (ABI.IsN64()) {
3779  MCOperand HighestOperand = MCOperand::createExpr(
3780  MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, OffExpr, getContext()));
3781  MCOperand HigherOperand = MCOperand::createExpr(
3782  MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, OffExpr, getContext()));
3783 
3784  TOut.emitRX(Mips::LUi, TmpReg, HighestOperand, IDLoc, STI);
3785  TOut.emitRRX(Mips::DADDiu, TmpReg, TmpReg, HigherOperand, IDLoc, STI);
3786  TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3787  TOut.emitRRX(Mips::DADDiu, TmpReg, TmpReg, HiOperand, IDLoc, STI);
3788  TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
3789  if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64)
3790  TOut.emitRRR(Mips::DADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3791  emitInstWithOffset(LoOperand);
3792  } else {
3793  // Generate the base address in TmpReg.
3794  TOut.emitRX(Mips::LUi, TmpReg, HiOperand, IDLoc, STI);
3795  if (BaseReg != Mips::ZERO)
3796  TOut.emitRRR(Mips::ADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
3797  // Emit the load or store with the adjusted base and offset.
3798  emitInstWithOffset(LoOperand);
3799  }
3800  }
3801  return;
3802  }
3803 
3804  llvm_unreachable("unexpected operand type");
3805 }
3806 
3807 void MipsAsmParser::expandMem9Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3808  const MCSubtargetInfo *STI, bool IsLoad) {
3809  unsigned NumOp = Inst.getNumOperands();
3810  assert((NumOp == 3 || NumOp == 4) && "unexpected operands number");
3811  unsigned StartOp = NumOp == 3 ? 0 : 1;
3812 
3813  const MCOperand &DstRegOp = Inst.getOperand(StartOp);
3814  assert(DstRegOp.isReg() && "expected register operand kind");
3815  const MCOperand &BaseRegOp = Inst.getOperand(StartOp + 1);
3816  assert(BaseRegOp.isReg() && "expected register operand kind");
3817  const MCOperand &OffsetOp = Inst.getOperand(StartOp + 2);
3818 
3819  MipsTargetStreamer &TOut = getTargetStreamer();
3820  unsigned OpCode = Inst.getOpcode();
3821  unsigned DstReg = DstRegOp.getReg();
3822  unsigned BaseReg = BaseRegOp.getReg();
3823  unsigned TmpReg = DstReg;
3824 
3825  const MCInstrDesc &Desc = getInstDesc(OpCode);
3826  int16_t DstRegClass = Desc.OpInfo[StartOp].RegClass;
3827  unsigned DstRegClassID =
3828  getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
3829  bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
3830  (DstRegClassID == Mips::GPR64RegClassID);
3831 
3832  if (!IsLoad || !IsGPR || (BaseReg == DstReg)) {
3833  // At this point we need AT to perform the expansions
3834  // and we exit if it is not available.
3835  TmpReg = getATReg(IDLoc);
3836  if (!TmpReg)
3837  return;
3838  }
3839 
3840  auto emitInst = [&]() {
3841  if (NumOp == 3)
3842  TOut.emitRRX(OpCode, DstReg, TmpReg, MCOperand::createImm(0), IDLoc, STI);
3843  else
3844  TOut.emitRRRX(OpCode, DstReg, DstReg, TmpReg, MCOperand::createImm(0),
3845  IDLoc, STI);
3846  };
3847 
3848  if (OffsetOp.isImm()) {
3849  loadImmediate(OffsetOp.getImm(), TmpReg, BaseReg, !ABI.ArePtrs64bit(), true,
3850  IDLoc, Out, STI);
3851  emitInst();
3852  return;
3853  }
3854 
3855  if (OffsetOp.isExpr()) {
3856  loadAndAddSymbolAddress(OffsetOp.getExpr(), TmpReg, BaseReg,
3857  !ABI.ArePtrs64bit(), IDLoc, Out, STI);
3858  emitInst();
3859  return;
3860  }
3861 
3862  llvm_unreachable("unexpected operand type");
3863 }
3864 
3865 bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
3866  MCStreamer &Out,
3867  const MCSubtargetInfo *STI) {
3868  unsigned OpNum = Inst.getNumOperands();
3869  unsigned Opcode = Inst.getOpcode();
3870  unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
3871 
3872  assert(Inst.getOperand(OpNum - 1).isImm() &&
3873  Inst.getOperand(OpNum - 2).isReg() &&
3874  Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
3875 
3876  if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
3877  Inst.getOperand(OpNum - 1).getImm() >= 0 &&
3878  (Inst.getOperand(OpNum - 2).getReg() == Mips::SP ||
3879  Inst.getOperand(OpNum - 2).getReg() == Mips::SP_64) &&
3880  (Inst.getOperand(OpNum - 3).getReg() == Mips::RA ||
3881  Inst.getOperand(OpNum - 3).getReg() == Mips::RA_64)) {
3882  // It can be implemented as SWM16 or LWM16 instruction.
3883  if (inMicroMipsMode() && hasMips32r6())
3884  NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
3885  else
3886  NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
3887  }
3888 
3889  Inst.setOpcode(NewOpcode);
3890  Out.emitInstruction(Inst, *STI);
3891  return false;
3892 }
3893 
3894 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
3895  MCStreamer &Out,
3896  const MCSubtargetInfo *STI) {
3897  MipsTargetStreamer &TOut = getTargetStreamer();
3898  bool EmittedNoMacroWarning = false;
3899  unsigned PseudoOpcode = Inst.getOpcode();
3900  unsigned SrcReg = Inst.getOperand(0).getReg();
3901  const MCOperand &TrgOp = Inst.getOperand(1);
3902  const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
3903 
3904  unsigned ZeroSrcOpcode, ZeroTrgOpcode;
3905  bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
3906 
3907  unsigned TrgReg;
3908  if (TrgOp.isReg())
3909  TrgReg = TrgOp.getReg();
3910  else if (TrgOp.isImm()) {
3911  warnIfNoMacro(IDLoc);
3912  EmittedNoMacroWarning = true;
3913 
3914  TrgReg = getATReg(IDLoc);
3915  if (!TrgReg)
3916  return true;
3917 
3918  switch(PseudoOpcode) {
3919  default:
3920  llvm_unreachable("unknown opcode for branch pseudo-instruction");
3921  case Mips::BLTImmMacro:
3922  PseudoOpcode = Mips::BLT;
3923  break;
3924  case Mips::BLEImmMacro:
3925  PseudoOpcode = Mips::BLE;
3926  break;
3927  case Mips::BGEImmMacro:
3928  PseudoOpcode = Mips::BGE;
3929  break;
3930  case Mips::BGTImmMacro:
3931  PseudoOpcode = Mips::BGT;
3932  break;
3933  case Mips::BLTUImmMacro:
3934  PseudoOpcode = Mips::BLTU;
3935  break;
3936  case Mips::BLEUImmMacro:
3937  PseudoOpcode = Mips::BLEU;
3938  break;
3939  case Mips::BGEUImmMacro:
3940  PseudoOpcode = Mips::BGEU;
3941  break;
3942  case Mips::BGTUImmMacro:
3943  PseudoOpcode = Mips::BGTU;
3944  break;
3945  case Mips::BLTLImmMacro:
3946  PseudoOpcode = Mips::BLTL;
3947  break;
3948  case Mips::BLELImmMacro:
3949  PseudoOpcode = Mips::BLEL;
3950  break;
3951  case Mips::BGELImmMacro:
3952  PseudoOpcode = Mips::BGEL;
3953  break;
3954  case Mips::BGTLImmMacro:
3955  PseudoOpcode = Mips::BGTL;
3956  break;
3957  case Mips::BLTULImmMacro:
3958  PseudoOpcode = Mips::BLTUL;
3959  break;
3960  case Mips::BLEULImmMacro:
3961  PseudoOpcode = Mips::BLEUL;
3962  break;
3963  case Mips::BGEULImmMacro:
3964  PseudoOpcode = Mips::BGEUL;
3965  break;
3966  case Mips::BGTULImmMacro:
3967  PseudoOpcode = Mips::BGTUL;
3968  break;
3969  }
3970 
3971  if (loadImmediate(TrgOp.getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
3972  false, IDLoc, Out, STI))
3973  return true;
3974  }
3975 
3976  switch (PseudoOpcode) {
3977  case Mips::BLT:
3978  case Mips::BLTU:
3979  case Mips::BLTL:
3980  case Mips::BLTUL:
3981  AcceptsEquality = false;
3982  ReverseOrderSLT = false;
3983  IsUnsigned =
3984  ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
3985  IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
3986  ZeroSrcOpcode = Mips::BGTZ;
3987  ZeroTrgOpcode = Mips::BLTZ;
3988  break;
3989  case Mips::BLE:
3990  case Mips::BLEU:
3991  case Mips::BLEL:
3992  case Mips::BLEUL:
3993  AcceptsEquality = true;
3994  ReverseOrderSLT = true;
3995  IsUnsigned =
3996  ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
3997  IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
3998  ZeroSrcOpcode = Mips::BGEZ;
3999  ZeroTrgOpcode = Mips::BLEZ;
4000  break;
4001  case Mips::BGE:
4002  case Mips::BGEU:
4003  case Mips::BGEL:
4004  case Mips::BGEUL:
4005  AcceptsEquality = true;
4006  ReverseOrderSLT = false;
4007  IsUnsigned =
4008  ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
4009  IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
4010  ZeroSrcOpcode = Mips::BLEZ;
4011  ZeroTrgOpcode = Mips::BGEZ;
4012  break;
4013  case Mips::BGT:
4014  case Mips::BGTU:
4015  case Mips::BGTL:
4016  case Mips::BGTUL:
4017  AcceptsEquality = false;
4018  ReverseOrderSLT = true;
4019  IsUnsigned =
4020  ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
4021  IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
4022  ZeroSrcOpcode = Mips::BLTZ;
4023  ZeroTrgOpcode = Mips::BGTZ;
4024  break;
4025  default:
4026  llvm_unreachable("unknown opcode for branch pseudo-instruction");
4027  }
4028 
4029  bool IsTrgRegZero = (TrgReg == Mips::ZERO);
4030  bool IsSrcRegZero = (SrcReg == Mips::ZERO);
4031  if (IsSrcRegZero && IsTrgRegZero) {
4032  // FIXME: All of these Opcode-specific if's are needed for compatibility
4033  // with GAS' behaviour. However, they may not generate the most efficient
4034  // code in some circumstances.
4035  if (PseudoOpcode == Mips::BLT) {
4036  TOut.emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
4037  IDLoc, STI);
4038  return false;
4039  }
4040  if (PseudoOpcode == Mips::BLE) {
4041  TOut.emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
4042  IDLoc, STI);
4043  Warning(IDLoc, "branch is always taken");
4044  return false;
4045  }
4046  if (PseudoOpcode == Mips::BGE) {
4047  TOut.emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
4048  IDLoc, STI);
4049  Warning(IDLoc, "branch is always taken");
4050  return false;
4051  }
4052  if (PseudoOpcode == Mips::BGT) {
4053  TOut.emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
4054  IDLoc, STI);
4055  return false;
4056  }
4057  if (PseudoOpcode == Mips::BGTU) {
4058  TOut.emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
4059  MCOperand::createExpr(OffsetExpr), IDLoc, STI);
4060  return false;
4061  }
4062  if (AcceptsEquality) {
4063  // If both registers are $0 and the pseudo-branch accepts equality, it
4064  // will always be taken, so we emit an unconditional branch.
4065  TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4066  MCOperand::createExpr(OffsetExpr), IDLoc, STI);
4067  Warning(IDLoc, "branch is always taken");
4068  return false;
4069  }
4070  // If both registers are $0 and the pseudo-branch does not accept
4071  // equality, it will never be taken, so we don't have to emit anything.
4072  return false;
4073  }
4074  if (IsSrcRegZero || IsTrgRegZero) {
4075  if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
4076  (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
4077  // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
4078  // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
4079  // the pseudo-branch will never be taken, so we don't emit anything.
4080  // This only applies to unsigned pseudo-branches.
4081  return false;
4082  }
4083  if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
4084  (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
4085  // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
4086  // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
4087  // the pseudo-branch will always be taken, so we emit an unconditional
4088  // branch.
4089  // This only applies to unsigned pseudo-branches.
4090  TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
4091  MCOperand::createExpr(OffsetExpr), IDLoc, STI);
4092  Warning(IDLoc, "branch is always taken");
4093  return false;
4094  }
4095  if (IsUnsigned) {
4096  // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
4097  // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
4098  // the pseudo-branch will be taken only when the non-zero register is
4099  // different from 0, so we emit a BNEZ.
4100  //
4101  // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
4102  // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
4103  // the pseudo-branch will be taken only when the non-zero register is
4104  // equal to 0, so we emit a BEQZ.
4105  //
4106  // Because only BLEU and BGEU branch on equality, we can use the
4107  // AcceptsEquality variable to decide when to emit the BEQZ.
4108  TOut.emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
4109  IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
4110  MCOperand::createExpr(OffsetExpr), IDLoc, STI);
4111  return false;
4112  }
4113  // If we have a signed pseudo-branch and one of the registers is $0,
4114  // we can use an appropriate compare-to-zero branch. We select which one
4115  // to use in the switch statement above.
4116  TOut.emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
4117  IsSrcRegZero ? TrgReg : SrcReg,
4118  MCOperand::createExpr(OffsetExpr), IDLoc, STI);
4119  return false;
4120  }
4121 
4122  // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
4123  // expansions. If it is not available, we return.
4124  unsigned ATRegNum = getATReg(IDLoc);
4125  if (!ATRegNum)
4126  return true;
4127 
4128  if (!EmittedNoMacroWarning)
4129  warnIfNoMacro(IDLoc);
4130 
4131  // SLT fits well with 2 of our 4 pseudo-branches:
4132  // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
4133  // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
4134  // If the result of the SLT is 1, we branch, and if it's 0, we don't.
4135  // This is accomplished by using a BNEZ with the result of the SLT.
4136  //
4137  // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
4138  // and BLE with BGT), so we change the BNEZ into a BEQZ.
4139  // Because only BGE and BLE branch on equality, we can use the
4140  // AcceptsEquality variable to decide when to emit the BEQZ.
4141  // Note that the order of the SLT arguments doesn't change between
4142  // opposites.
4143  //
4144  // The same applies to the unsigned variants, except that SLTu is used
4145  // instead of SLT.
4146  TOut.emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
4147  ReverseOrderSLT ? TrgReg : SrcReg,
4148  ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
4149 
4150  TOut.emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
4151  : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
4152  ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
4153  STI);
4154  return false;
4155 }
4156 
4157 // Expand a integer division macro.
4158 //
4159 // Notably we don't have to emit a warning when encountering $rt as the $zero
4160 // register, or 0 as an immediate. processInstruction() has already done that.
4161 //
4162 // The destination register can only be $zero when expanding (S)DivIMacro or
4163 // D(S)DivMacro.
4164 
4165 bool MipsAsmParser::expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4166  const MCSubtargetInfo *STI,
4167  const bool IsMips64, const bool Signed) {
4168  MipsTargetStreamer &TOut = getTargetStreamer();
4169 
4170  warnIfNoMacro(IDLoc);
4171 
4172  const MCOperand &RdRegOp = Inst.getOperand(0);
4173  assert(RdRegOp.isReg() && "expected register operand kind");
4174  unsigned RdReg = RdRegOp.getReg();
4175 
4176  const MCOperand &RsRegOp = Inst.getOperand(1);
4177  assert(RsRegOp.isReg() && "expected register operand kind");
4178  unsigned RsReg = RsRegOp.getReg();
4179 
4180  unsigned RtReg;
4181  int64_t ImmValue;
4182 
4183  const MCOperand &RtOp = Inst.getOperand(2);
4184  assert((RtOp.isReg() || RtOp.isImm()) &&
4185  "expected register or immediate operand kind");
4186  if (RtOp.isReg())
4187  RtReg = RtOp.getReg();
4188  else
4189  ImmValue = RtOp.getImm();
4190 
4191  unsigned DivOp;
4192  unsigned ZeroReg;
4193  unsigned SubOp;
4194 
4195  if (IsMips64) {
4196  DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
4197  ZeroReg = Mips::ZERO_64;
4198  SubOp = Mips::DSUB;
4199  } else {
4200  DivOp = Signed ? Mips::SDIV : Mips::UDIV;
4201  ZeroReg = Mips::ZERO;
4202  SubOp = Mips::SUB;
4203  }
4204 
4205  bool UseTraps = useTraps();
4206 
4207  unsigned Opcode = Inst.getOpcode();
4208  bool isDiv = Opcode == Mips::SDivMacro || Opcode == Mips::SDivIMacro ||
4209  Opcode == Mips::UDivMacro || Opcode == Mips::UDivIMacro ||
4210  Opcode == Mips::DSDivMacro || Opcode == Mips::DSDivIMacro ||
4211  Opcode == Mips::DUDivMacro || Opcode == Mips::DUDivIMacro;
4212 
4213  bool isRem = Opcode == Mips::SRemMacro || Opcode == Mips::SRemIMacro ||
4214  Opcode == Mips::URemMacro || Opcode == Mips::URemIMacro ||
4215  Opcode == Mips::DSRemMacro || Opcode == Mips::DSRemIMacro ||
4216  Opcode == Mips::DURemMacro || Opcode == Mips::DURemIMacro;
4217 
4218  if (RtOp.isImm()) {
4219  unsigned ATReg = getATReg(IDLoc);
4220  if (!ATReg)
4221  return true;
4222 
4223  if (ImmValue == 0) {
4224  if (UseTraps)
4225  TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4226  else
4227  TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4228  return false;
4229  }
4230 
4231  if (isRem && (ImmValue == 1 || (Signed && (ImmValue == -1)))) {
4232  TOut.emitRRR(Mips::OR, RdReg, ZeroReg, ZeroReg, IDLoc, STI);
4233  return false;
4234  } else if (isDiv && ImmValue == 1) {
4235  TOut.emitRRR(Mips::OR, RdReg, RsReg, Mips::ZERO, IDLoc, STI);
4236  return false;
4237  } else if (isDiv && Signed && ImmValue == -1) {
4238  TOut.emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI);
4239  return false;
4240  } else {
4241  if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, isInt<32>(ImmValue),
4242  false, Inst.getLoc(), Out, STI))
4243  return true;
4244  TOut.emitRR(DivOp, RsReg, ATReg, IDLoc, STI);
4245  TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4246  return false;
4247  }
4248  return true;
4249  }
4250 
4251  // If the macro expansion of (d)div(u) or (d)rem(u) would always trap or
4252  // break, insert the trap/break and exit. This gives a different result to
4253  // GAS. GAS has an inconsistency/missed optimization in that not all cases
4254  // are handled equivalently. As the observed behaviour is the same, we're ok.
4255  if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
4256  if (UseTraps) {
4257  TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI);
4258  return false;
4259  }
4260  TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4261  return false;
4262  }
4263 
4264  // (d)rem(u) $0, $X, $Y is a special case. Like div $zero, $X, $Y, it does
4265  // not expand to macro sequence.
4266  if (isRem && (RdReg == Mips::ZERO || RdReg == Mips::ZERO_64)) {
4267  TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4268  return false;
4269  }
4270 
4271  // Temporary label for first branch traget
4273  MCSymbol *BrTarget;
4274  MCOperand LabelOp;
4275 
4276  if (UseTraps) {
4277  TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
4278  } else {
4279  // Branch to the li instruction.
4280  BrTarget = Context.createTempSymbol();
4282  TOut.emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI);
4283  }
4284 
4285  TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
4286 
4287  if (!UseTraps)
4288  TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
4289 
4290  if (!Signed) {
4291  if (!UseTraps)
4292  TOut.getStreamer().emitLabel(BrTarget);
4293 
4294  TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4295  return false;
4296  }
4297 
4298  unsigned ATReg = getATReg(IDLoc);
4299  if (!ATReg)
4300  return true;
4301 
4302  if (!UseTraps)
4303  TOut.getStreamer().emitLabel(BrTarget);
4304 
4305  TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, STI);
4306 
4307  // Temporary label for the second branch target.
4308  MCSymbol *BrTargetEnd = Context.createTempSymbol();
4309  MCOperand LabelOpEnd =
4311 
4312  // Branch to the mflo instruction.
4313  TOut.emitRRX(Mips::BNE, RtReg, ATReg, LabelOpEnd, IDLoc, STI);
4314 
4315  if (IsMips64) {
4316  TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, STI);
4317  TOut.emitDSLL(ATReg, ATReg, 63, IDLoc, STI);
4318  } else {
4319  TOut.emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, STI);
4320  }
4321 
4322  if (UseTraps)
4323  TOut.emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, STI);
4324  else {
4325  // Branch to the mflo instruction.
4326  TOut.emitRRX(Mips::BNE, RsReg, ATReg, LabelOpEnd, IDLoc, STI);
4327  TOut.emitNop(IDLoc, STI);
4328  TOut.emitII(Mips::BREAK, 0x6, 0, IDLoc, STI);
4329  }
4330 
4331  TOut.getStreamer().emitLabel(BrTargetEnd);
4332  TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI);
4333  return false;
4334 }
4335 
4336 bool MipsAsmParser::expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU,
4337  SMLoc IDLoc, MCStreamer &Out,
4338  const MCSubtargetInfo *STI) {
4339  MipsTargetStreamer &TOut = getTargetStreamer();
4340 
4341  assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4342  assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() &&
4343  Inst.getOperand(2).isReg() && "Invalid instruction operand.");
4344 
4345  unsigned FirstReg = Inst.getOperand(0).getReg();
4346  unsigned SecondReg = Inst.getOperand(1).getReg();
4347  unsigned ThirdReg = Inst.getOperand(2).getReg();
4348 
4349  if (hasMips1() && !hasMips2()) {
4350  unsigned ATReg = getATReg(IDLoc);
4351  if (!ATReg)
4352  return true;
4353  TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4354  TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
4355  TOut.emitNop(IDLoc, STI);
4356  TOut.emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
4357  TOut.emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
4358  TOut.emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
4359  TOut.emitNop(IDLoc, STI);
4360  TOut.emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
4361  : Mips::CVT_W_S,
4362  FirstReg, SecondReg, IDLoc, STI);
4363  TOut.emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
4364  TOut.emitNop(IDLoc, STI);
4365  return false;
4366  }
4367 
4368  TOut.emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
4369  : Mips::TRUNC_W_S,
4370  FirstReg, SecondReg, IDLoc, STI);
4371 
4372  return false;
4373 }
4374 
4375 bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
4376  MCStreamer &Out, const MCSubtargetInfo *STI) {
4377  if (hasMips32r6() || hasMips64r6()) {
4378  return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4379  }
4380 
4381  const MCOperand &DstRegOp = Inst.getOperand(0);
4382  assert(DstRegOp.isReg() && "expected register operand kind");
4383  const MCOperand &SrcRegOp = Inst.getOperand(1);
4384  assert(SrcRegOp.isReg() && "expected register operand kind");
4385  const MCOperand &OffsetImmOp = Inst.getOperand(2);
4386  assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4387 
4388  MipsTargetStreamer &TOut = getTargetStreamer();
4389  unsigned DstReg = DstRegOp.getReg();
4390  unsigned SrcReg = SrcRegOp.getReg();
4391  int64_t OffsetValue = OffsetImmOp.getImm();
4392 
4393  // NOTE: We always need AT for ULHU, as it is always used as the source
4394  // register for one of the LBu's.
4395  warnIfNoMacro(IDLoc);
4396  unsigned ATReg = getATReg(IDLoc);
4397  if (!ATReg)
4398  return true;
4399 
4400  bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4401  if (IsLargeOffset) {
4402  if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4403  IDLoc, Out, STI))
4404  return true;
4405  }
4406 
4407  int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue;
4408  int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4409  if (isLittle())
4410  std::swap(FirstOffset, SecondOffset);
4411 
4412  unsigned FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg;
4413  unsigned SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg;
4414 
4415  unsigned LbuSrcReg = IsLargeOffset ? ATReg : SrcReg;
4416  unsigned SllReg = IsLargeOffset ? DstReg : ATReg;
4417 
4418  TOut.emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
4419  FirstOffset, IDLoc, STI);
4420  TOut.emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI);
4421  TOut.emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
4422  TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4423 
4424  return false;
4425 }
4426 
4427 bool MipsAsmParser::expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4428  const MCSubtargetInfo *STI) {
4429  if (hasMips32r6() || hasMips64r6()) {
4430  return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4431  }
4432 
4433  const MCOperand &DstRegOp = Inst.getOperand(0);
4434  assert(DstRegOp.isReg() && "expected register operand kind");
4435  const MCOperand &SrcRegOp = Inst.getOperand(1);
4436  assert(SrcRegOp.isReg() && "expected register operand kind");
4437  const MCOperand &OffsetImmOp = Inst.getOperand(2);
4438  assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4439 
4440  MipsTargetStreamer &TOut = getTargetStreamer();
4441  unsigned DstReg = DstRegOp.getReg();
4442  unsigned SrcReg = SrcRegOp.getReg();
4443  int64_t OffsetValue = OffsetImmOp.getImm();
4444 
4445  warnIfNoMacro(IDLoc);
4446  unsigned ATReg = getATReg(IDLoc);
4447  if (!ATReg)
4448  return true;
4449 
4450  bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue));
4451  if (IsLargeOffset) {
4452  if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true,
4453  IDLoc, Out, STI))
4454  return true;
4455  }
4456 
4457  int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1);
4458  int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue;
4459  if (isLittle())
4460  std::swap(FirstOffset, SecondOffset);
4461 
4462  if (IsLargeOffset) {
4463  TOut.emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI);
4464  TOut.emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI);
4465  TOut.emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI);
4466  TOut.emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI);
4467  TOut.emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI);
4468  TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
4469  } else {
4470  TOut.emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI);
4471  TOut.emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI);
4472  TOut.emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI);
4473  }
4474 
4475  return false;
4476 }
4477 
4478 bool MipsAsmParser::expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4479  const MCSubtargetInfo *STI) {
4480  if (hasMips32r6() || hasMips64r6()) {
4481  return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
4482  }
4483 
4484  const MCOperand &DstRegOp = Inst.getOperand(0);
4485  assert(DstRegOp.isReg() && "expected register operand kind");
4486  const MCOperand &SrcRegOp = Inst.getOperand(1);
4487  assert(SrcRegOp.isReg() && "expected register operand kind");
4488  const MCOperand &OffsetImmOp = Inst.getOperand(2);
4489  assert(OffsetImmOp.isImm() && "expected immediate operand kind");
4490 
4491  MipsTargetStreamer &TOut = getTargetStreamer();
4492  unsigned DstReg = DstRegOp.getReg();
4493  unsigned SrcReg = SrcRegOp.getReg();
4494  int64_t OffsetValue = OffsetImmOp.getImm();
4495 
4496  // Compute left/right load/store offsets.
4497  bool IsLargeOffset = !(isInt<16>(OffsetValue + 3) && isInt<16>(OffsetValue));
4498  int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue;
4499  int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3);
4500  if (isLittle())
4501  std::swap(LxlOffset, LxrOffset);
4502 
4503  bool IsLoadInst = (Inst.getOpcode() == Mips::Ulw);
4504  bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset;
4505  unsigned TmpReg = SrcReg;
4506  if (IsLargeOffset || DoMove) {
4507  warnIfNoMacro(IDLoc);
4508  TmpReg = getATReg(IDLoc);
4509  if (!TmpReg)
4510  return true;
4511  }
4512 
4513  if (IsLargeOffset) {
4514  if (loadImmediate(OffsetValue, TmpReg, SrcReg, !ABI.ArePtrs64bit(), true,
4515  IDLoc, Out, STI))
4516  return true;
4517  }
4518 
4519  if (DoMove)
4520  std::swap(DstReg, TmpReg);
4521 
4522  unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL;
4523  unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR;
4524  TOut.emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI);
4525  TOut.emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI);
4526 
4527  if (DoMove)
4528  TOut.emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI);
4529 
4530  return false;
4531 }
4532 
4533 bool MipsAsmParser::expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4534  const MCSubtargetInfo *STI) {
4535  MipsTargetStreamer &TOut = getTargetStreamer();
4536 
4537  assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4538  assert(Inst.getOperand(0).isReg() &&
4539  Inst.getOperand(1).isReg() &&
4540  Inst.getOperand(2).isReg() && "Invalid instruction operand.");
4541 
4542  unsigned DstReg = Inst.getOperand(0).getReg();
4543  unsigned SrcReg = Inst.getOperand(1).getReg();
4544  unsigned OpReg = Inst.getOperand(2).getReg();
4545  unsigned OpCode;
4546 
4547  warnIfNoMacro(IDLoc);
4548 
4549  switch (Inst.getOpcode()) {
4550  case Mips::SGE:
4551  OpCode = Mips::SLT;
4552  break;
4553  case Mips::SGEU:
4554  OpCode = Mips::SLTu;
4555  break;
4556  default:
4557  llvm_unreachable("unexpected 'sge' opcode");
4558  }
4559 
4560  // $SrcReg >= $OpReg is equal to (not ($SrcReg < $OpReg))
4561  TOut.emitRRR(OpCode, DstReg, SrcReg, OpReg, IDLoc, STI);
4562  TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4563 
4564  return false;
4565 }
4566 
4567 bool MipsAsmParser::expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4568  const MCSubtargetInfo *STI) {
4569  MipsTargetStreamer &TOut = getTargetStreamer();
4570 
4571  assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4572  assert(Inst.getOperand(0).isReg() &&
4573  Inst.getOperand(1).isReg() &&
4574  Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4575 
4576  unsigned DstReg = Inst.getOperand(0).getReg();
4577  unsigned SrcReg = Inst.getOperand(1).getReg();
4578  int64_t ImmValue = Inst.getOperand(2).getImm();
4579  unsigned OpRegCode, OpImmCode;
4580 
4581  warnIfNoMacro(IDLoc);
4582 
4583  switch (Inst.getOpcode()) {
4584  case Mips::SGEImm:
4585  case Mips::SGEImm64:
4586  OpRegCode = Mips::SLT;
4587  OpImmCode = Mips::SLTi;
4588  break;
4589  case Mips::SGEUImm:
4590  case Mips::SGEUImm64:
4591  OpRegCode = Mips::SLTu;
4592  OpImmCode = Mips::SLTiu;
4593  break;
4594  default:
4595  llvm_unreachable("unexpected 'sge' opcode with immediate");
4596  }
4597 
4598  // $SrcReg >= Imm is equal to (not ($SrcReg < Imm))
4599  if (isInt<16>(ImmValue)) {
4600  // Use immediate version of STL.
4601  TOut.emitRRI(OpImmCode, DstReg, SrcReg, ImmValue, IDLoc, STI);
4602  TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4603  } else {
4604  unsigned ImmReg = DstReg;
4605  if (DstReg == SrcReg) {
4606  unsigned ATReg = getATReg(Inst.getLoc());
4607  if (!ATReg)
4608  return true;
4609  ImmReg = ATReg;
4610  }
4611 
4612  if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4613  false, IDLoc, Out, STI))
4614  return true;
4615 
4616  TOut.emitRRR(OpRegCode, DstReg, SrcReg, ImmReg, IDLoc, STI);
4617  TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4618  }
4619 
4620  return false;
4621 }
4622 
4623 bool MipsAsmParser::expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4624  const MCSubtargetInfo *STI) {
4625  MipsTargetStreamer &TOut = getTargetStreamer();
4626 
4627  assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4628  assert(Inst.getOperand(0).isReg() &&
4629  Inst.getOperand(1).isReg() &&
4630  Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4631 
4632  unsigned DstReg = Inst.getOperand(0).getReg();
4633  unsigned SrcReg = Inst.getOperand(1).getReg();
4634  unsigned ImmReg = DstReg;
4635  int64_t ImmValue = Inst.getOperand(2).getImm();
4636  unsigned OpCode;
4637 
4638  warnIfNoMacro(IDLoc);
4639 
4640  switch (Inst.getOpcode()) {
4641  case Mips::SGTImm:
4642  case Mips::SGTImm64:
4643  OpCode = Mips::SLT;
4644  break;
4645  case Mips::SGTUImm:
4646  case Mips::SGTUImm64:
4647  OpCode = Mips::SLTu;
4648  break;
4649  default:
4650  llvm_unreachable("unexpected 'sgt' opcode with immediate");
4651  }
4652 
4653  if (DstReg == SrcReg) {
4654  unsigned ATReg = getATReg(Inst.getLoc());
4655  if (!ATReg)
4656  return true;
4657  ImmReg = ATReg;
4658  }
4659 
4660  if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4661  false, IDLoc, Out, STI))
4662  return true;
4663 
4664  // $SrcReg > $ImmReg is equal to $ImmReg < $SrcReg
4665  TOut.emitRRR(OpCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4666 
4667  return false;
4668 }
4669 
4670 bool MipsAsmParser::expandSle(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4671  const MCSubtargetInfo *STI) {
4672  MipsTargetStreamer &TOut = getTargetStreamer();
4673 
4674  assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4675  assert(Inst.getOperand(0).isReg() &&
4676  Inst.getOperand(1).isReg() &&
4677  Inst.getOperand(2).isReg() && "Invalid instruction operand.");
4678 
4679  unsigned DstReg = Inst.getOperand(0).getReg();
4680  unsigned SrcReg = Inst.getOperand(1).getReg();
4681  unsigned OpReg = Inst.getOperand(2).getReg();
4682  unsigned OpCode;
4683 
4684  warnIfNoMacro(IDLoc);
4685 
4686  switch (Inst.getOpcode()) {
4687  case Mips::SLE:
4688  OpCode = Mips::SLT;
4689  break;
4690  case Mips::SLEU:
4691  OpCode = Mips::SLTu;
4692  break;
4693  default:
4694  llvm_unreachable("unexpected 'sge' opcode");
4695  }
4696 
4697  // $SrcReg <= $OpReg is equal to (not ($OpReg < $SrcReg))
4698  TOut.emitRRR(OpCode, DstReg, OpReg, SrcReg, IDLoc, STI);
4699  TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4700 
4701  return false;
4702 }
4703 
4704 bool MipsAsmParser::expandSleImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4705  const MCSubtargetInfo *STI) {
4706  MipsTargetStreamer &TOut = getTargetStreamer();
4707 
4708  assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4709  assert(Inst.getOperand(0).isReg() &&
4710  Inst.getOperand(1).isReg() &&
4711  Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4712 
4713  unsigned DstReg = Inst.getOperand(0).getReg();
4714  unsigned SrcReg = Inst.getOperand(1).getReg();
4715  int64_t ImmValue = Inst.getOperand(2).getImm();
4716  unsigned OpRegCode;
4717 
4718  warnIfNoMacro(IDLoc);
4719 
4720  switch (Inst.getOpcode()) {
4721  case Mips::SLEImm:
4722  case Mips::SLEImm64:
4723  OpRegCode = Mips::SLT;
4724  break;
4725  case Mips::SLEUImm:
4726  case Mips::SLEUImm64:
4727  OpRegCode = Mips::SLTu;
4728  break;
4729  default:
4730  llvm_unreachable("unexpected 'sge' opcode with immediate");
4731  }
4732 
4733  // $SrcReg <= Imm is equal to (not (Imm < $SrcReg))
4734  unsigned ImmReg = DstReg;
4735  if (DstReg == SrcReg) {
4736  unsigned ATReg = getATReg(Inst.getLoc());
4737  if (!ATReg)
4738  return true;
4739  ImmReg = ATReg;
4740  }
4741 
4742  if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue),
4743  false, IDLoc, Out, STI))
4744  return true;
4745 
4746  TOut.emitRRR(OpRegCode, DstReg, ImmReg, SrcReg, IDLoc, STI);
4747  TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI);
4748 
4749  return false;
4750 }
4751 
4752 bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
4753  MCStreamer &Out,
4754  const MCSubtargetInfo *STI) {
4755  MipsTargetStreamer &TOut = getTargetStreamer();
4756 
4757  assert(Inst.getNumOperands() == 3 && "Invalid operand count");
4758  assert(Inst.getOperand(0).isReg() &&
4759  Inst.getOperand(1).isReg() &&
4760  Inst.getOperand(2).isImm() && "Invalid instruction operand.");
4761 
4762  unsigned ATReg = Mips::NoRegister;
4763  unsigned FinalDstReg = Mips::NoRegister;
4764  unsigned DstReg = Inst.getOperand(0).getReg();
4765  unsigned SrcReg = Inst.getOperand(1).getReg();
4766  int64_t ImmValue = Inst.getOperand(2).getImm();
4767 
4768  bool Is32Bit = isInt<32>(ImmValue) || (!isGP64bit() && isUInt<32>(ImmValue));
4769 
4770  unsigned FinalOpcode = Inst.getOpcode();
4771 
4772  if (DstReg == SrcReg) {
4773  ATReg = getATReg(Inst.getLoc());
4774  if (!ATReg)
4775  return true;
4776  FinalDstReg = DstReg;
4777  DstReg = ATReg;
4778  }
4779 
4780  if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit, false,
4781  Inst.getLoc(), Out, STI)) {
4782  switch (FinalOpcode) {
4783  default:
4784  llvm_unreachable("unimplemented expansion");
4785  case Mips::ADDi:
4786  FinalOpcode = Mips::ADD;
4787  break;
4788  case Mips::ADDiu:
4789  FinalOpcode = Mips::ADDu;
4790  break;
4791  case Mips::ANDi:
4792  FinalOpcode = Mips::AND;
4793  break;
4794  case Mips::NORImm:
4795  FinalOpcode = Mips::NOR;
4796  break;
4797  case Mips::ORi:
4798  FinalOpcode = Mips::OR;
4799  break;
4800  case Mips::SLTi:
4801  FinalOpcode = Mips::SLT;
4802  break;
4803  case Mips::SLTiu:
4804  FinalOpcode = Mips::SLTu;
4805  break;
4806  case Mips::XORi:
4807  FinalOpcode = Mips::XOR;
4808  break;
4809  case Mips::ADDi_MM:
4810  FinalOpcode = Mips::ADD_MM;
4811  break;
4812  case Mips::ADDiu_MM:
4813  FinalOpcode = Mips::ADDu_MM;
4814  break;
4815  case Mips::ANDi_MM:
4816  FinalOpcode = Mips::AND_MM;
4817  break;
4818  case Mips::ORi_MM:
4819  FinalOpcode = Mips::OR_MM;
4820  break;
4821  case Mips::SLTi_MM:
4822  FinalOpcode = Mips::SLT_MM;
4823  break;
4824  case Mips::SLTiu_MM:
4825  FinalOpcode = Mips::SLTu_MM;
4826  break;
4827  case Mips::XORi_MM:
4828  FinalOpcode = Mips::XOR_MM;
4829  break;
4830  case Mips::ANDi64:
4831  FinalOpcode = Mips::AND64;
4832  break;
4833  case Mips::NORImm64:
4834  FinalOpcode = Mips::NOR64;
4835  break;
4836  case Mips::ORi64:
4837  FinalOpcode = Mips::OR64;
4838  break;
4839  case Mips::SLTImm64:
4840  FinalOpcode = Mips::SLT64;
4841  break;
4842  case Mips::SLTUImm64:
4843  FinalOpcode = Mips::SLTu64;
4844  break;
4845  case Mips::XORi64:
4846  FinalOpcode = Mips::XOR64;
4847  break;
4848  }
4849 
4850  if (FinalDstReg == Mips::NoRegister)
4851  TOut.emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
4852  else
4853  TOut.emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
4854  return false;
4855  }
4856  return true;
4857 }
4858 
4859 bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4860  const MCSubtargetInfo *STI) {
4861  MipsTargetStreamer &TOut = getTargetStreamer();
4862  unsigned ATReg = Mips::NoRegister;
4863  unsigned DReg = Inst.getOperand(0).getReg();
4864  unsigned SReg = Inst.getOperand(1).getReg();
4865  unsigned TReg = Inst.getOperand(2).getReg();
4866  unsigned TmpReg = DReg;
4867 
4868  unsigned FirstShift = Mips::NOP;
4869  unsigned SecondShift = Mips::NOP;
4870 
4871  if (hasMips32r2()) {
4872  if (DReg == SReg) {
4873  TmpReg = getATReg(Inst.getLoc());
4874  if (!TmpReg)
4875  return true;
4876  }
4877 
4878  if (Inst.getOpcode() == Mips::ROL) {
4879  TOut.emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4880  TOut.emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
4881  return false;
4882  }
4883 
4884  if (Inst.getOpcode() == Mips::ROR) {
4885  TOut.emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
4886  return false;
4887  }
4888 
4889  return true;
4890  }
4891 
4892  if (hasMips32()) {
4893  switch (Inst.getOpcode()) {
4894  default:
4895  llvm_unreachable("unexpected instruction opcode");
4896  case Mips::ROL:
4897  FirstShift = Mips::SRLV;
4898  SecondShift = Mips::SLLV;
4899  break;
4900  case Mips::ROR:
4901  FirstShift = Mips::SLLV;
4902  SecondShift = Mips::SRLV;
4903  break;
4904  }
4905 
4906  ATReg = getATReg(Inst.getLoc());
4907  if (!ATReg)
4908  return true;
4909 
4910  TOut.emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
4911  TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
4912  TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
4913  TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4914 
4915  return false;
4916  }
4917 
4918  return true;
4919 }
4920 
4921 bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
4922  MCStreamer &Out,
4923  const MCSubtargetInfo *STI) {
4924  MipsTargetStreamer &TOut = getTargetStreamer();
4925  unsigned ATReg = Mips::NoRegister;
4926  unsigned DReg = Inst.getOperand(0).getReg();
4927  unsigned SReg = Inst.getOperand(1).getReg();
4928  int64_t ImmValue = Inst.getOperand(2).getImm();
4929 
4930  unsigned FirstShift = Mips::NOP;
4931  unsigned SecondShift = Mips::NOP;
4932 
4933  if (hasMips32r2()) {
4934  if (Inst.getOpcode() == Mips::ROLImm) {
4935  uint64_t MaxShift = 32;
4936  uint64_t ShiftValue = ImmValue;
4937  if (ImmValue != 0)
4938  ShiftValue = MaxShift - ImmValue;
4939  TOut.emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
4940  return false;
4941  }
4942 
4943  if (Inst.getOpcode() == Mips::RORImm) {
4944  TOut.emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.getLoc(), STI);
4945  return false;
4946  }
4947 
4948  return true;
4949  }
4950 
4951  if (hasMips32()) {
4952  if (ImmValue == 0) {
4953  TOut.emitRRI(Mips::SRL, DReg, SReg, 0, Inst.getLoc(), STI);
4954  return false;
4955  }
4956 
4957  switch (Inst.getOpcode()) {
4958  default:
4959  llvm_unreachable("unexpected instruction opcode");
4960  case Mips::ROLImm:
4961  FirstShift = Mips::SLL;
4962  SecondShift = Mips::SRL;
4963  break;
4964  case Mips::RORImm:
4965  FirstShift = Mips::SRL;
4966  SecondShift = Mips::SLL;
4967  break;
4968  }
4969 
4970  ATReg = getATReg(Inst.getLoc());
4971  if (!ATReg)
4972  return true;
4973 
4974  TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.getLoc(), STI);
4975  TOut.emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.getLoc(), STI);
4976  TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
4977 
4978  return false;
4979  }
4980 
4981  return true;
4982 }
4983 
4984 bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
4985  const MCSubtargetInfo *STI) {
4986  MipsTargetStreamer &TOut = getTargetStreamer();
4987  unsigned ATReg = Mips::NoRegister;
4988  unsigned DReg = Inst.getOperand(0).getReg();
4989  unsigned SReg = Inst.getOperand(1).getReg();
4990  unsigned TReg = Inst.getOperand(2).getReg();
4991  unsigned TmpReg = DReg;
4992 
4993  unsigned FirstShift = Mips::NOP;
4994  unsigned SecondShift = Mips::NOP;
4995 
4996  if (hasMips64r2()) {
4997  if (TmpReg == SReg) {
4998  TmpReg = getATReg(Inst.getLoc());
4999  if (!TmpReg)
5000  return true;
5001  }
5002 
5003  if (Inst.getOpcode() == Mips::DROL) {
5004  TOut.emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
5005  TOut.emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
5006  return false;
5007  }
5008 
5009  if (Inst.getOpcode() == Mips::DROR) {
5010  TOut.emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
5011  return false;
5012  }
5013 
5014  return true;
5015  }
5016 
5017  if (hasMips64()) {
5018  switch (Inst.getOpcode()) {
5019  default:
5020  llvm_unreachable("unexpected instruction opcode");
5021  case Mips::DROL:
5022  FirstShift = Mips::DSRLV;
5023  SecondShift = Mips::DSLLV;
5024  break;
5025  case Mips::DROR:
5026  FirstShift = Mips::DSLLV;
5027  SecondShift = Mips::DSRLV;
5028  break;
5029  }
5030 
5031  ATReg = getATReg(Inst.getLoc());
5032  if (!ATReg)
5033  return true;
5034 
5035  TOut.emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
5036  TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
5037  TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
5038  TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
5039 
5040  return false;
5041  }
5042 
5043  return true;
5044 }
5045 
5046 bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
5047  MCStreamer &Out,
5048  const MCSubtargetInfo *STI) {
5049  MipsTargetStreamer &TOut = getTargetStreamer();
5050  unsigned ATReg = Mips::NoRegister;
5051  unsigned DReg = Inst.getOperand(0).getReg();
5052  unsigned SReg = Inst.getOperand(1).getReg();
5053  int64_t ImmValue = Inst.getOperand(2).getImm() % 64;
5054 
5055  unsigned FirstShift = Mips::NOP;
5056  unsigned SecondShift = Mips::NOP;
5057 
5058  MCInst TmpInst;
5059 
5060  if (hasMips64r2()) {
5061  unsigned FinalOpcode = Mips::NOP;
5062  if (ImmValue == 0)
5063  FinalOpcode = Mips::DROTR;
5064  else if (ImmValue % 32 == 0)
5065  FinalOpcode = Mips::DROTR32;
5066  else if ((ImmValue >= 1) && (ImmValue <= 32)) {
5067  if (Inst.getOpcode() == Mips::DROLImm)
5068  FinalOpcode = Mips::DROTR32;
5069  else
5070  FinalOpcode = Mips::DROTR;
5071  } else if (ImmValue >= 33) {
5072  if (Inst.getOpcode() == Mips::DROLImm)
5073  FinalOpcode = Mips::DROTR;
5074  else
5075  FinalOpcode = Mips::DROTR32;
5076  }
5077 
5078  uint64_t ShiftValue = ImmValue % 32;
5079  if (Inst.getOpcode() == Mips::DROLImm)
5080  ShiftValue = (32 - ImmValue % 32) % 32;
5081 
5082  TOut.emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
5083 
5084  return false;
5085  }
5086 
5087  if (hasMips64()) {
5088  if (ImmValue == 0) {
5089  TOut.emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.getLoc(), STI);
5090  return false;
5091  }
5092 
5093  switch (Inst.getOpcode()) {
5094  default:
5095  llvm_unreachable("unexpected instruction opcode");
5096  case Mips::DROLImm:
5097  if ((ImmValue >= 1) && (ImmValue <= 31)) {
5098  FirstShift = Mips::DSLL;
5099  SecondShift = Mips::DSRL32;
5100  }
5101  if (ImmValue == 32) {
5102  FirstShift = Mips::DSLL32;
5103  SecondShift = Mips::DSRL32;
5104  }
5105  if ((ImmValue >= 33) && (ImmValue <= 63)) {
5106  FirstShift = Mips::DSLL32;
5107  SecondShift = Mips::DSRL;
5108  }
5109  break;
5110  case Mips::DRORImm:
5111  if ((ImmValue >= 1) && (ImmValue <= 31)) {
5112  FirstShift = Mips::DSRL;
5113  SecondShift = Mips::DSLL32;
5114  }
5115  if (ImmValue == 32) {
5116  FirstShift = Mips::DSRL32;
5117  SecondShift = Mips::DSLL32;
5118  }
5119  if ((ImmValue >= 33) && (ImmValue <= 63)) {
5120  FirstShift = Mips::DSRL32;
5121  SecondShift = Mips::DSLL;
5122  }
5123  break;
5124  }
5125 
5126  ATReg = getATReg(Inst.getLoc());
5127  if (!ATReg)
5128  return true;
5129 
5130  TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.getLoc(), STI);
5131  TOut.emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
5132  Inst.getLoc(), STI);
5133  TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
5134 
5135  return false;
5136  }
5137 
5138  return true;
5139 }
5140 
5141 bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5142  const MCSubtargetInfo *STI) {
5143  MipsTargetStreamer &TOut = getTargetStreamer();
5144  unsigned FirstRegOp = Inst.getOperand(0).getReg();
5145  unsigned SecondRegOp = Inst.getOperand(1).getReg();
5146 
5147  TOut.emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
5148  if (FirstRegOp != SecondRegOp)
5149  TOut.emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
5150  else
5151  TOut.emitEmptyDelaySlot(false, IDLoc, STI);
5152  TOut.emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
5153 
5154  return false;
5155 }
5156 
5157 bool MipsAsmParser::expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5158  const MCSubtargetInfo *STI) {
5159  MipsTargetStreamer &TOut = getTargetStreamer();
5160  unsigned ATReg = Mips::NoRegister;
5161  unsigned DstReg = Inst.getOperand(0).getReg();
5162  unsigned SrcReg = Inst.getOperand(1).getReg();
5163  int32_t ImmValue = Inst.getOperand(2).getImm();
5164 
5165  ATReg = getATReg(IDLoc);
5166  if (!ATReg)
5167  return true;
5168 
5169  loadImmediate(ImmValue, ATReg, Mips::NoRegister, true, false, IDLoc, Out,
5170  STI);
5171 
5172  TOut.emitRR(Inst.getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT,
5173  SrcReg, ATReg, IDLoc, STI);
5174 
5175  TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5176 
5177  return false;
5178 }
5179 
5180 bool MipsAsmParser::expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5181  const MCSubtargetInfo *STI) {
5182  MipsTargetStreamer &TOut = getTargetStreamer();
5183  unsigned ATReg = Mips::NoRegister;
5184  unsigned DstReg = Inst.getOperand(0).getReg();
5185  unsigned SrcReg = Inst.getOperand(1).getReg();
5186  unsigned TmpReg = Inst.getOperand(2).getReg();
5187 
5188  ATReg = getATReg(Inst.getLoc());
5189  if (!ATReg)
5190  return true;
5191 
5192  TOut.emitRR(Inst.getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT,
5193  SrcReg, TmpReg, IDLoc, STI);
5194 
5195  TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5196 
5197  TOut.emitRRI(Inst.getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32,
5198  DstReg, DstReg, 0x1F, IDLoc, STI);
5199 
5200  TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
5201 
5202  if (useTraps()) {
5203  TOut.emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI);
5204  } else {
5205  MCContext & Context = TOut.getStreamer().getContext();
5206  MCSymbol * BrTarget = Context.createTempSymbol();
5207  MCOperand LabelOp =
5209 
5210  TOut.emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI);
5211  if (AssemblerOptions.back()->isReorder())
5212  TOut.emitNop(IDLoc, STI);
5213  TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5214 
5215  TOut.getStreamer().emitLabel(BrTarget);
5216  }
5217  TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5218 
5219  return false;
5220 }
5221 
5222 bool MipsAsmParser::expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5223  const MCSubtargetInfo *STI) {
5224  MipsTargetStreamer &TOut = getTargetStreamer();
5225  unsigned ATReg = Mips::NoRegister;
5226  unsigned DstReg = Inst.getOperand(0).getReg();
5227  unsigned SrcReg = Inst.getOperand(1).getReg();
5228  unsigned TmpReg = Inst.getOperand(2).getReg();
5229 
5230  ATReg = getATReg(IDLoc);
5231  if (!ATReg)
5232  return true;
5233 
5234  TOut.emitRR(Inst.getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu,
5235  SrcReg, TmpReg, IDLoc, STI);
5236 
5237  TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI);
5238  TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5239  if (useTraps()) {
5240  TOut.emitRRI(Mips::TNE, ATReg, Mips::ZERO, 6, IDLoc, STI);
5241  } else {
5242  MCContext & Context = TOut.getStreamer().getContext();
5243  MCSymbol * BrTarget = Context.createTempSymbol();
5244  MCOperand LabelOp =
5246 
5247  TOut.emitRRX(Mips::BEQ, ATReg, Mips::ZERO, LabelOp, IDLoc, STI);
5248  if (AssemblerOptions.back()->isReorder())
5249  TOut.emitNop(IDLoc, STI);
5250  TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI);
5251 
5252  TOut.getStreamer().emitLabel(BrTarget);
5253  }
5254 
5255  return false;
5256 }
5257 
5258 bool MipsAsmParser::expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5259  const MCSubtargetInfo *STI) {
5260  MipsTargetStreamer &TOut = getTargetStreamer();
5261  unsigned DstReg = Inst.getOperand(0).getReg();
5262  unsigned SrcReg = Inst.getOperand(1).getReg();
5263  unsigned TmpReg = Inst.getOperand(2).getReg();
5264 
5265  TOut.emitRR(Mips::DMULTu, SrcReg, TmpReg, IDLoc, STI);
5266  TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI);
5267 
5268  return false;
5269 }
5270 
5271 // Expand 'ld $<reg> offset($reg2)' to 'lw $<reg>, offset($reg2);
5272 // lw $<reg+1>>, offset+4($reg2)'
5273 // or expand 'sd $<reg> offset($reg2)' to 'sw $<reg>, offset($reg2);
5274 // sw $<reg+1>>, offset+4($reg2)'
5275 // for O32.
5276 bool MipsAsmParser::expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc,
5277  MCStreamer &Out,
5278  const MCSubtargetInfo *STI,
5279  bool IsLoad) {
5280  if (!isABI_O32())
5281  return true;
5282 
5283  warnIfNoMacro(IDLoc);
5284 
5285  MipsTargetStreamer &TOut = getTargetStreamer();
5286  unsigned Opcode = IsLoad ? Mips::LW : Mips::SW;
5287  unsigned FirstReg = Inst.getOperand(0).getReg();
5288  unsigned SecondReg = nextReg(FirstReg);
5289  unsigned BaseReg = Inst.getOperand(1).getReg();
5290  if (!SecondReg)
5291  return true;
5292 
5293  warnIfRegIndexIsAT(FirstReg, IDLoc);
5294 
5295  assert(Inst.getOperand(2).isImm() &&
5296  "Offset for load macro is not immediate!");
5297 
5298  MCOperand &FirstOffset = Inst.getOperand(2);
5299  signed NextOffset = FirstOffset.getImm() + 4;
5300  MCOperand SecondOffset = MCOperand::createImm(NextOffset);
5301 
5302  if (!isInt<16>(FirstOffset.getImm()) || !isInt<16>(NextOffset))
5303  return true;
5304 
5305  // For loads, clobber the base register with the second load instead of the
5306  // first if the BaseReg == FirstReg.
5307  if (FirstReg != BaseReg || !IsLoad) {
5308  TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5309  TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5310  } else {
5311  TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5312  TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5313  }
5314 
5315  return false;
5316 }
5317 
5318 
5319 // Expand 's.d $<reg> offset($reg2)' to 'swc1 $<reg+1>, offset($reg2);
5320 // swc1 $<reg>, offset+4($reg2)'
5321 // or if little endian to 'swc1 $<reg>, offset($reg2);
5322 // swc1 $<reg+1>, offset+4($reg2)'
5323 // for Mips1.
5324 bool MipsAsmParser::expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc,
5325  MCStreamer &Out,
5326  const MCSubtargetInfo *STI) {
5327  if (!isABI_O32())
5328  return true;
5329 
5330  warnIfNoMacro(IDLoc);
5331 
5332  MipsTargetStreamer &TOut = getTargetStreamer();
5333  unsigned Opcode = Mips::SWC1;
5334  unsigned FirstReg = Inst.getOperand(0).getReg();
5335  unsigned SecondReg = nextReg(FirstReg);
5336  unsigned BaseReg = Inst.getOperand(1).getReg();
5337  if (!SecondReg)
5338  return true;
5339 
5340  warnIfRegIndexIsAT(FirstReg, IDLoc);
5341 
5342  assert(Inst.getOperand(2).isImm() &&
5343  "Offset for macro is not immediate!");
5344 
5345  MCOperand &FirstOffset = Inst.getOperand(2);
5346  signed NextOffset = FirstOffset.getImm() + 4;
5347  MCOperand SecondOffset = MCOperand::createImm(NextOffset);
5348 
5349  if (!isInt<16>(FirstOffset.getImm()) || !isInt<16>(NextOffset))
5350  return true;
5351 
5352  if (!IsLittleEndian)
5353  std::swap(FirstReg, SecondReg);
5354 
5355  TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI);
5356  TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI);
5357 
5358  return false;
5359 }
5360 
5361 bool MipsAsmParser::expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5362  const MCSubtargetInfo *STI) {
5363  MipsTargetStreamer &TOut = getTargetStreamer();
5364 
5365  assert(Inst.getNumOperands() == 3 && "Invalid operand count");
5366  assert(Inst.getOperand(0).isReg() &&
5367  Inst.getOperand(1).isReg() &&
5368  Inst.getOperand(2).isReg() && "Invalid instruction operand.");
5369 
5370  unsigned DstReg = Inst.getOperand(0).getReg();
5371  unsigned SrcReg = Inst.getOperand(1).getReg();
5372  unsigned OpReg = Inst.getOperand(2).getReg();
5373 
5374  warnIfNoMacro(IDLoc);
5375 
5376  if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5377  TOut.emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5378  TOut.emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5379  return false;
5380  }
5381 
5382  unsigned Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5383  TOut.emitRRI(Mips::SLTiu, DstReg, Reg, 1, IDLoc, STI);
5384  return false;
5385 }
5386 
5387 bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5388  const MCSubtargetInfo *STI) {
5389  MipsTargetStreamer &TOut = getTargetStreamer();
5390 
5391  assert(Inst.getNumOperands() == 3 && "Invalid operand count");
5392  assert(Inst.getOperand(0).isReg() &&
5393  Inst.getOperand(1).isReg() &&
5394  Inst.getOperand(2).isImm() && "Invalid instruction operand.");
5395 
5396  unsigned DstReg = Inst.getOperand(0).getReg();
5397  unsigned SrcReg = Inst.getOperand(1).getReg();
5398  int64_t Imm = Inst.getOperand(2).getImm();
5399 
5400  warnIfNoMacro(IDLoc);
5401 
5402  if (Imm == 0) {
5403  TOut.emitRRI(Mips::SLTiu, DstReg, SrcReg, 1, IDLoc, STI);
5404  return false;
5405  }
5406 
5407  if (SrcReg == Mips::ZERO) {
5408  Warning(IDLoc, "comparison is always false");
5409  TOut.emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu,
5410  DstReg, SrcReg, SrcReg, IDLoc, STI);
5411  return false;
5412  }
5413 
5414  unsigned Opc;
5415  if (Imm > -0x8000 && Imm < 0) {
5416  Imm = -Imm;
5417  Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5418  } else {
5419  Opc = Mips::XORi;
5420  }
5421 
5422  if (!isUInt<16>(Imm)) {
5423  unsigned ATReg = getATReg(IDLoc);
5424  if (!ATReg)
5425  return true;
5426 
5427  if (loadImmediate(Imm, ATReg, Mips::NoRegister, true, isGP64bit(), IDLoc,
5428  Out, STI))
5429  return true;
5430 
5431  TOut.emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI);
5432  TOut.emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5433  return false;
5434  }
5435 
5436  TOut.emitRRI(Opc, DstReg, SrcReg, Imm, IDLoc, STI);
5437  TOut.emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI);
5438  return false;
5439 }
5440 
5441 bool MipsAsmParser::expandSne(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5442  const MCSubtargetInfo *STI) {
5443 
5444  MipsTargetStreamer &TOut = getTargetStreamer();
5445 
5446  assert(Inst.getNumOperands() == 3 && "Invalid operand count");
5447  assert(Inst.getOperand(0).isReg() &&
5448  Inst.getOperand(1).isReg() &&
5449  Inst.getOperand(2).isReg() && "Invalid instruction operand.");
5450 
5451  unsigned DstReg = Inst.getOperand(0).getReg();
5452  unsigned SrcReg = Inst.getOperand(1).getReg();
5453  unsigned OpReg = Inst.getOperand(2).getReg();
5454 
5455  warnIfNoMacro(IDLoc);
5456 
5457  if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) {
5458  TOut.emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI);
5459  TOut.emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI);
5460  return false;
5461  }
5462 
5463  unsigned Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg;
5464  TOut.emitRRR(Mips::SLTu, DstReg, Mips::ZERO, Reg, IDLoc, STI);
5465  return false;
5466 }
5467 
5468 bool MipsAsmParser::expandSneI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5469  const MCSubtargetInfo *STI) {
5470  MipsTargetStreamer &TOut = getTargetStreamer();
5471 
5472  assert(Inst.getNumOperands() == 3 && "Invalid operand count");
5473  assert(Inst.getOperand(0).isReg() &&
5474  Inst.getOperand(1).isReg() &&
5475  Inst.getOperand(2).isImm() && "Invalid instruction operand.");
5476 
5477  unsigned DstReg = Inst.getOperand(0).getReg();
5478  unsigned SrcReg = Inst.getOperand(1).getReg();
5479  int64_t ImmValue = Inst.getOperand(2).getImm();
5480 
5481  warnIfNoMacro(IDLoc);
5482 
5483  if (ImmValue == 0) {
5484  TOut.emitRRR(Mips::SLTu, DstReg, Mips::ZERO, SrcReg, IDLoc, STI);
5485  return false;
5486  }
5487 
5488  if (SrcReg == Mips::ZERO) {
5489  Warning(IDLoc, "comparison is always true");
5490  if (loadImmediate(1, DstReg, Mips::NoRegister, true, false, IDLoc, Out,
5491  STI))
5492  return true;
5493  return false;
5494  }
5495 
5496  unsigned Opc;
5497  if (ImmValue > -0x8000 && ImmValue < 0) {
5498  ImmValue = -ImmValue;
5499  Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu;
5500  } else {
5501  Opc = Mips::XORi;
5502  }
5503