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