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