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