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