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