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