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