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