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