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