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