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