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