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