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