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