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