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