brintos

brintos / llvm-project-archived public Read only

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