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 bool UseXGOT = STI->hasFeature(Mips::FeatureXGOT) && !IsLocalSym; 2924 2925 // The case where the result register is $25 is somewhat special. If the 2926 // symbol in the final relocation is external and not modified with a 2927 // constant then we must use R_MIPS_CALL16 instead of R_MIPS_GOT16 2928 // or R_MIPS_CALL16 instead of R_MIPS_GOT_DISP in 64-bit case. 2929 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg && 2930 Res.getConstant() == 0 && !IsLocalSym) { 2931 if (UseXGOT) { 2932 const MCExpr *CallHiExpr = MipsMCExpr::create(MipsMCExpr::MEK_CALL_HI16, 2933 SymExpr, getContext()); 2934 const MCExpr *CallLoExpr = MipsMCExpr::create(MipsMCExpr::MEK_CALL_LO16, 2935 SymExpr, getContext()); 2936 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(CallHiExpr), IDLoc, 2937 STI); 2938 TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, DstReg, GPReg, 2939 IDLoc, STI); 2940 TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, DstReg, 2941 MCOperand::createExpr(CallLoExpr), IDLoc, STI); 2942 } else { 2943 const MCExpr *CallExpr = 2944 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, SymExpr, getContext()); 2945 TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, GPReg, 2946 MCOperand::createExpr(CallExpr), IDLoc, STI); 2947 } 2948 return false; 2949 } 2950 2951 unsigned TmpReg = DstReg; 2952 if (UseSrcReg && 2953 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, 2954 SrcReg)) { 2955 // If $rs is the same as $rd, we need to use AT. 2956 // If it is not available we exit. 2957 unsigned ATReg = getATReg(IDLoc); 2958 if (!ATReg) 2959 return true; 2960 TmpReg = ATReg; 2961 } 2962 2963 // FIXME: In case of N32 / N64 ABI and emabled XGOT, local addresses 2964 // loaded using R_MIPS_GOT_PAGE / R_MIPS_GOT_OFST pair of relocations. 2965 // FIXME: Implement XGOT for microMIPS. 2966 if (UseXGOT) { 2967 // Loading address from XGOT 2968 // External GOT: lui $tmp, %got_hi(symbol)($gp) 2969 // addu $tmp, $tmp, $gp 2970 // lw $tmp, %got_lo(symbol)($tmp) 2971 // >addiu $tmp, $tmp, offset 2972 // >addiu $rd, $tmp, $rs 2973 // The addiu's marked with a '>' may be omitted if they are redundant. If 2974 // this happens then the last instruction must use $rd as the result 2975 // register. 2976 const MCExpr *CallHiExpr = 2977 MipsMCExpr::create(MipsMCExpr::MEK_GOT_HI16, SymExpr, getContext()); 2978 const MCExpr *CallLoExpr = MipsMCExpr::create( 2979 MipsMCExpr::MEK_GOT_LO16, Res.getSymA(), getContext()); 2980 2981 TOut.emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(CallHiExpr), IDLoc, 2982 STI); 2983 TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg, GPReg, 2984 IDLoc, STI); 2985 TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, TmpReg, 2986 MCOperand::createExpr(CallLoExpr), IDLoc, STI); 2987 2988 if (Res.getConstant() != 0) 2989 TOut.emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg, 2990 MCOperand::createExpr(MCConstantExpr::create( 2991 Res.getConstant(), getContext())), 2992 IDLoc, STI); 2993 2994 if (UseSrcReg) 2995 TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg, 2996 IDLoc, STI); 2997 return false; 2998 } 2999 3000 const MipsMCExpr *GotExpr = nullptr; 3001 const MCExpr *LoExpr = nullptr; 3002 if (ABI.IsN32() || ABI.IsN64()) { 3003 // The remaining cases are: 3004 // Small offset: ld $tmp, %got_disp(symbol)($gp) 3005 // >daddiu $tmp, $tmp, offset 3006 // >daddu $rd, $tmp, $rs 3007 // The daddiu's marked with a '>' may be omitted if they are redundant. If 3008 // this happens then the last instruction must use $rd as the result 3009 // register. 3010 GotExpr = MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP, Res.getSymA(), 3011 getContext()); 3012 if (Res.getConstant() != 0) { 3013 // Symbols fully resolve with just the %got_disp(symbol) but we 3014 // must still account for any offset to the symbol for 3015 // expressions like symbol+8. 3016 LoExpr = MCConstantExpr::create(Res.getConstant(), getContext()); 3017 3018 // FIXME: Offsets greater than 16 bits are not yet implemented. 3019 // FIXME: The correct range is a 32-bit sign-extended number. 3020 if (Res.getConstant() < -0x8000 || Res.getConstant() > 0x7fff) { 3021 Error(IDLoc, "macro instruction uses large offset, which is not " 3022 "currently supported"); 3023 return true; 3024 } 3025 } 3026 } else { 3027 // The remaining cases are: 3028 // External GOT: lw $tmp, %got(symbol)($gp) 3029 // >addiu $tmp, $tmp, offset 3030 // >addiu $rd, $tmp, $rs 3031 // Local GOT: lw $tmp, %got(symbol+offset)($gp) 3032 // addiu $tmp, $tmp, %lo(symbol+offset)($gp) 3033 // >addiu $rd, $tmp, $rs 3034 // The addiu's marked with a '>' may be omitted if they are redundant. If 3035 // this happens then the last instruction must use $rd as the result 3036 // register. 3037 if (IsLocalSym) { 3038 GotExpr = 3039 MipsMCExpr::create(MipsMCExpr::MEK_GOT, SymExpr, getContext()); 3040 LoExpr = MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext()); 3041 } else { 3042 // External symbols fully resolve the symbol with just the %got(symbol) 3043 // but we must still account for any offset to the symbol for 3044 // expressions like symbol+8. 3045 GotExpr = MipsMCExpr::create(MipsMCExpr::MEK_GOT, Res.getSymA(), 3046 getContext()); 3047 if (Res.getConstant() != 0) 3048 LoExpr = MCConstantExpr::create(Res.getConstant(), getContext()); 3049 } 3050 } 3051 3052 TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, GPReg, 3053 MCOperand::createExpr(GotExpr), IDLoc, STI); 3054 3055 if (LoExpr) 3056 TOut.emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg, 3057 MCOperand::createExpr(LoExpr), IDLoc, STI); 3058 3059 if (UseSrcReg) 3060 TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg, 3061 IDLoc, STI); 3062 3063 return false; 3064 } 3065 3066 const MipsMCExpr *HiExpr = 3067 MipsMCExpr::create(MipsMCExpr::MEK_HI, SymExpr, getContext()); 3068 const MipsMCExpr *LoExpr = 3069 MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext()); 3070 3071 // This is the 64-bit symbol address expansion. 3072 if (ABI.ArePtrs64bit() && isGP64bit()) { 3073 // We need AT for the 64-bit expansion in the cases where the optional 3074 // source register is the destination register and for the superscalar 3075 // scheduled form. 3076 // 3077 // If it is not available we exit if the destination is the same as the 3078 // source register. 3079 3080 const MipsMCExpr *HighestExpr = 3081 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, SymExpr, getContext()); 3082 const MipsMCExpr *HigherExpr = 3083 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, SymExpr, getContext()); 3084 3085 bool RdRegIsRsReg = 3086 UseSrcReg && 3087 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg); 3088 3089 if (canUseATReg() && UseSrcReg && RdRegIsRsReg) { 3090 unsigned ATReg = getATReg(IDLoc); 3091 3092 // If $rs is the same as $rd: 3093 // (d)la $rd, sym($rd) => lui $at, %highest(sym) 3094 // daddiu $at, $at, %higher(sym) 3095 // dsll $at, $at, 16 3096 // daddiu $at, $at, %hi(sym) 3097 // dsll $at, $at, 16 3098 // daddiu $at, $at, %lo(sym) 3099 // daddu $rd, $at, $rd 3100 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc, 3101 STI); 3102 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, 3103 MCOperand::createExpr(HigherExpr), IDLoc, STI); 3104 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI); 3105 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr), 3106 IDLoc, STI); 3107 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI); 3108 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), 3109 IDLoc, STI); 3110 TOut.emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI); 3111 3112 return false; 3113 } else if (canUseATReg() && !RdRegIsRsReg && DstReg != getATReg(IDLoc)) { 3114 unsigned ATReg = getATReg(IDLoc); 3115 3116 // If the $rs is different from $rd or if $rs isn't specified and we 3117 // have $at available: 3118 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym) 3119 // lui $at, %hi(sym) 3120 // daddiu $rd, $rd, %higher(sym) 3121 // daddiu $at, $at, %lo(sym) 3122 // dsll32 $rd, $rd, 0 3123 // daddu $rd, $rd, $at 3124 // (daddu $rd, $rd, $rs) 3125 // 3126 // Which is preferred for superscalar issue. 3127 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc, 3128 STI); 3129 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI); 3130 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg, 3131 MCOperand::createExpr(HigherExpr), IDLoc, STI); 3132 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), 3133 IDLoc, STI); 3134 TOut.emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI); 3135 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI); 3136 if (UseSrcReg) 3137 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI); 3138 3139 return false; 3140 } else if ((!canUseATReg() && !RdRegIsRsReg) || 3141 (canUseATReg() && DstReg == getATReg(IDLoc))) { 3142 // Otherwise, synthesize the address in the destination register 3143 // serially: 3144 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym) 3145 // daddiu $rd, $rd, %higher(sym) 3146 // dsll $rd, $rd, 16 3147 // daddiu $rd, $rd, %hi(sym) 3148 // dsll $rd, $rd, 16 3149 // daddiu $rd, $rd, %lo(sym) 3150 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc, 3151 STI); 3152 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg, 3153 MCOperand::createExpr(HigherExpr), IDLoc, STI); 3154 TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI); 3155 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg, 3156 MCOperand::createExpr(HiExpr), IDLoc, STI); 3157 TOut.emitRRI(Mips::DSLL, DstReg, DstReg, 16, IDLoc, STI); 3158 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg, 3159 MCOperand::createExpr(LoExpr), IDLoc, STI); 3160 if (UseSrcReg) 3161 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI); 3162 3163 return false; 3164 } else { 3165 // We have a case where SrcReg == DstReg and we don't have $at 3166 // available. We can't expand this case, so error out appropriately. 3167 assert(SrcReg == DstReg && !canUseATReg() && 3168 "Could have expanded dla but didn't?"); 3169 reportParseError(IDLoc, 3170 "pseudo-instruction requires $at, which is not available"); 3171 return true; 3172 } 3173 } 3174 3175 // And now, the 32-bit symbol address expansion: 3176 // If $rs is the same as $rd: 3177 // (d)la $rd, sym($rd) => lui $at, %hi(sym) 3178 // ori $at, $at, %lo(sym) 3179 // addu $rd, $at, $rd 3180 // Otherwise, if the $rs is different from $rd or if $rs isn't specified: 3181 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym) 3182 // ori $rd, $rd, %lo(sym) 3183 // (addu $rd, $rd, $rs) 3184 unsigned TmpReg = DstReg; 3185 if (UseSrcReg && 3186 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) { 3187 // If $rs is the same as $rd, we need to use AT. 3188 // If it is not available we exit. 3189 unsigned ATReg = getATReg(IDLoc); 3190 if (!ATReg) 3191 return true; 3192 TmpReg = ATReg; 3193 } 3194 3195 TOut.emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, STI); 3196 TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr), 3197 IDLoc, STI); 3198 3199 if (UseSrcReg) 3200 TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI); 3201 else 3202 assert( 3203 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg)); 3204 3205 return false; 3206 } 3207 3208 // Each double-precision register DO-D15 overlaps with two of the single 3209 // precision registers F0-F31. As an example, all of the following hold true: 3210 // D0 + 1 == F1, F1 + 1 == D1, F1 + 1 == F2, depending on the context. 3211 static unsigned nextReg(unsigned Reg) { 3212 if (MipsMCRegisterClasses[Mips::FGR32RegClassID].contains(Reg)) 3213 return Reg == (unsigned)Mips::F31 ? (unsigned)Mips::F0 : Reg + 1; 3214 switch (Reg) { 3215 default: llvm_unreachable("Unknown register in assembly macro expansion!"); 3216 case Mips::ZERO: return Mips::AT; 3217 case Mips::AT: return Mips::V0; 3218 case Mips::V0: return Mips::V1; 3219 case Mips::V1: return Mips::A0; 3220 case Mips::A0: return Mips::A1; 3221 case Mips::A1: return Mips::A2; 3222 case Mips::A2: return Mips::A3; 3223 case Mips::A3: return Mips::T0; 3224 case Mips::T0: return Mips::T1; 3225 case Mips::T1: return Mips::T2; 3226 case Mips::T2: return Mips::T3; 3227 case Mips::T3: return Mips::T4; 3228 case Mips::T4: return Mips::T5; 3229 case Mips::T5: return Mips::T6; 3230 case Mips::T6: return Mips::T7; 3231 case Mips::T7: return Mips::S0; 3232 case Mips::S0: return Mips::S1; 3233 case Mips::S1: return Mips::S2; 3234 case Mips::S2: return Mips::S3; 3235 case Mips::S3: return Mips::S4; 3236 case Mips::S4: return Mips::S5; 3237 case Mips::S5: return Mips::S6; 3238 case Mips::S6: return Mips::S7; 3239 case Mips::S7: return Mips::T8; 3240 case Mips::T8: return Mips::T9; 3241 case Mips::T9: return Mips::K0; 3242 case Mips::K0: return Mips::K1; 3243 case Mips::K1: return Mips::GP; 3244 case Mips::GP: return Mips::SP; 3245 case Mips::SP: return Mips::FP; 3246 case Mips::FP: return Mips::RA; 3247 case Mips::RA: return Mips::ZERO; 3248 case Mips::D0: return Mips::F1; 3249 case Mips::D1: return Mips::F3; 3250 case Mips::D2: return Mips::F5; 3251 case Mips::D3: return Mips::F7; 3252 case Mips::D4: return Mips::F9; 3253 case Mips::D5: return Mips::F11; 3254 case Mips::D6: return Mips::F13; 3255 case Mips::D7: return Mips::F15; 3256 case Mips::D8: return Mips::F17; 3257 case Mips::D9: return Mips::F19; 3258 case Mips::D10: return Mips::F21; 3259 case Mips::D11: return Mips::F23; 3260 case Mips::D12: return Mips::F25; 3261 case Mips::D13: return Mips::F27; 3262 case Mips::D14: return Mips::F29; 3263 case Mips::D15: return Mips::F31; 3264 } 3265 } 3266 3267 // FIXME: This method is too general. In principle we should compute the number 3268 // of instructions required to synthesize the immediate inline compared to 3269 // synthesizing the address inline and relying on non .text sections. 3270 // For static O32 and N32 this may yield a small benefit, for static N64 this is 3271 // likely to yield a much larger benefit as we have to synthesize a 64bit 3272 // address to load a 64 bit value. 3273 bool MipsAsmParser::emitPartialAddress(MipsTargetStreamer &TOut, SMLoc IDLoc, 3274 MCSymbol *Sym) { 3275 unsigned ATReg = getATReg(IDLoc); 3276 if (!ATReg) 3277 return true; 3278 3279 if(IsPicEnabled) { 3280 const MCExpr *GotSym = 3281 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 3282 const MipsMCExpr *GotExpr = 3283 MipsMCExpr::create(MipsMCExpr::MEK_GOT, GotSym, getContext()); 3284 3285 if(isABI_O32() || isABI_N32()) { 3286 TOut.emitRRX(Mips::LW, ATReg, GPReg, MCOperand::createExpr(GotExpr), 3287 IDLoc, STI); 3288 } else { //isABI_N64() 3289 TOut.emitRRX(Mips::LD, ATReg, GPReg, MCOperand::createExpr(GotExpr), 3290 IDLoc, STI); 3291 } 3292 } else { //!IsPicEnabled 3293 const MCExpr *HiSym = 3294 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 3295 const MipsMCExpr *HiExpr = 3296 MipsMCExpr::create(MipsMCExpr::MEK_HI, HiSym, getContext()); 3297 3298 // FIXME: This is technically correct but gives a different result to gas, 3299 // but gas is incomplete there (it has a fixme noting it doesn't work with 3300 // 64-bit addresses). 3301 // FIXME: With -msym32 option, the address expansion for N64 should probably 3302 // use the O32 / N32 case. It's safe to use the 64 address expansion as the 3303 // symbol's value is considered sign extended. 3304 if(isABI_O32() || isABI_N32()) { 3305 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI); 3306 } else { //isABI_N64() 3307 const MCExpr *HighestSym = 3308 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 3309 const MipsMCExpr *HighestExpr = 3310 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, HighestSym, getContext()); 3311 const MCExpr *HigherSym = 3312 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 3313 const MipsMCExpr *HigherExpr = 3314 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, HigherSym, getContext()); 3315 3316 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc, 3317 STI); 3318 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, 3319 MCOperand::createExpr(HigherExpr), IDLoc, STI); 3320 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI); 3321 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr), 3322 IDLoc, STI); 3323 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI); 3324 } 3325 } 3326 return false; 3327 } 3328 3329 static uint64_t convertIntToDoubleImm(uint64_t ImmOp64) { 3330 // If ImmOp64 is AsmToken::Integer type (all bits set to zero in the 3331 // exponent field), convert it to double (e.g. 1 to 1.0) 3332 if ((Hi_32(ImmOp64) & 0x7ff00000) == 0) { 3333 APFloat RealVal(APFloat::IEEEdouble(), ImmOp64); 3334 ImmOp64 = RealVal.bitcastToAPInt().getZExtValue(); 3335 } 3336 return ImmOp64; 3337 } 3338 3339 static uint32_t covertDoubleImmToSingleImm(uint64_t ImmOp64) { 3340 // Conversion of a double in an uint64_t to a float in a uint32_t, 3341 // retaining the bit pattern of a float. 3342 double DoubleImm = llvm::bit_cast<double>(ImmOp64); 3343 float TmpFloat = static_cast<float>(DoubleImm); 3344 return llvm::bit_cast<uint32_t>(TmpFloat); 3345 } 3346 3347 bool MipsAsmParser::expandLoadSingleImmToGPR(MCInst &Inst, SMLoc IDLoc, 3348 MCStreamer &Out, 3349 const MCSubtargetInfo *STI) { 3350 assert(Inst.getNumOperands() == 2 && "Invalid operand count"); 3351 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() && 3352 "Invalid instruction operand."); 3353 3354 unsigned FirstReg = Inst.getOperand(0).getReg(); 3355 uint64_t ImmOp64 = Inst.getOperand(1).getImm(); 3356 3357 uint32_t ImmOp32 = covertDoubleImmToSingleImm(convertIntToDoubleImm(ImmOp64)); 3358 3359 return loadImmediate(ImmOp32, FirstReg, Mips::NoRegister, true, false, IDLoc, 3360 Out, STI); 3361 } 3362 3363 bool MipsAsmParser::expandLoadSingleImmToFPR(MCInst &Inst, SMLoc IDLoc, 3364 MCStreamer &Out, 3365 const MCSubtargetInfo *STI) { 3366 MipsTargetStreamer &TOut = getTargetStreamer(); 3367 assert(Inst.getNumOperands() == 2 && "Invalid operand count"); 3368 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() && 3369 "Invalid instruction operand."); 3370 3371 unsigned FirstReg = Inst.getOperand(0).getReg(); 3372 uint64_t ImmOp64 = Inst.getOperand(1).getImm(); 3373 3374 ImmOp64 = convertIntToDoubleImm(ImmOp64); 3375 3376 uint32_t ImmOp32 = covertDoubleImmToSingleImm(ImmOp64); 3377 3378 unsigned TmpReg = Mips::ZERO; 3379 if (ImmOp32 != 0) { 3380 TmpReg = getATReg(IDLoc); 3381 if (!TmpReg) 3382 return true; 3383 } 3384 3385 if (Lo_32(ImmOp64) == 0) { 3386 if (TmpReg != Mips::ZERO && loadImmediate(ImmOp32, TmpReg, Mips::NoRegister, 3387 true, false, IDLoc, Out, STI)) 3388 return true; 3389 TOut.emitRR(Mips::MTC1, FirstReg, TmpReg, IDLoc, STI); 3390 return false; 3391 } 3392 3393 MCSection *CS = getStreamer().getCurrentSectionOnly(); 3394 // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections 3395 // where appropriate. 3396 MCSection *ReadOnlySection = 3397 getContext().getELFSection(".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC); 3398 3399 MCSymbol *Sym = getContext().createTempSymbol(); 3400 const MCExpr *LoSym = 3401 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 3402 const MipsMCExpr *LoExpr = 3403 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext()); 3404 3405 getStreamer().switchSection(ReadOnlySection); 3406 getStreamer().emitLabel(Sym, IDLoc); 3407 getStreamer().emitInt32(ImmOp32); 3408 getStreamer().switchSection(CS); 3409 3410 if (emitPartialAddress(TOut, IDLoc, Sym)) 3411 return true; 3412 TOut.emitRRX(Mips::LWC1, FirstReg, TmpReg, MCOperand::createExpr(LoExpr), 3413 IDLoc, STI); 3414 return false; 3415 } 3416 3417 bool MipsAsmParser::expandLoadDoubleImmToGPR(MCInst &Inst, SMLoc IDLoc, 3418 MCStreamer &Out, 3419 const MCSubtargetInfo *STI) { 3420 MipsTargetStreamer &TOut = getTargetStreamer(); 3421 assert(Inst.getNumOperands() == 2 && "Invalid operand count"); 3422 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() && 3423 "Invalid instruction operand."); 3424 3425 unsigned FirstReg = Inst.getOperand(0).getReg(); 3426 uint64_t ImmOp64 = Inst.getOperand(1).getImm(); 3427 3428 ImmOp64 = convertIntToDoubleImm(ImmOp64); 3429 3430 if (Lo_32(ImmOp64) == 0) { 3431 if (isGP64bit()) { 3432 if (loadImmediate(ImmOp64, FirstReg, Mips::NoRegister, false, false, 3433 IDLoc, Out, STI)) 3434 return true; 3435 } else { 3436 if (loadImmediate(Hi_32(ImmOp64), FirstReg, Mips::NoRegister, true, false, 3437 IDLoc, Out, STI)) 3438 return true; 3439 3440 if (loadImmediate(0, nextReg(FirstReg), Mips::NoRegister, true, false, 3441 IDLoc, Out, STI)) 3442 return true; 3443 } 3444 return false; 3445 } 3446 3447 MCSection *CS = getStreamer().getCurrentSectionOnly(); 3448 MCSection *ReadOnlySection = 3449 getContext().getELFSection(".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC); 3450 3451 MCSymbol *Sym = getContext().createTempSymbol(); 3452 const MCExpr *LoSym = 3453 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 3454 const MipsMCExpr *LoExpr = 3455 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext()); 3456 3457 getStreamer().switchSection(ReadOnlySection); 3458 getStreamer().emitLabel(Sym, IDLoc); 3459 getStreamer().emitValueToAlignment(Align(8)); 3460 getStreamer().emitIntValue(ImmOp64, 8); 3461 getStreamer().switchSection(CS); 3462 3463 unsigned TmpReg = getATReg(IDLoc); 3464 if (!TmpReg) 3465 return true; 3466 3467 if (emitPartialAddress(TOut, IDLoc, Sym)) 3468 return true; 3469 3470 TOut.emitRRX(isABI_N64() ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg, 3471 MCOperand::createExpr(LoExpr), IDLoc, STI); 3472 3473 if (isGP64bit()) 3474 TOut.emitRRI(Mips::LD, FirstReg, TmpReg, 0, IDLoc, STI); 3475 else { 3476 TOut.emitRRI(Mips::LW, FirstReg, TmpReg, 0, IDLoc, STI); 3477 TOut.emitRRI(Mips::LW, nextReg(FirstReg), TmpReg, 4, IDLoc, STI); 3478 } 3479 return false; 3480 } 3481 3482 bool MipsAsmParser::expandLoadDoubleImmToFPR(MCInst &Inst, bool Is64FPU, 3483 SMLoc IDLoc, MCStreamer &Out, 3484 const MCSubtargetInfo *STI) { 3485 MipsTargetStreamer &TOut = getTargetStreamer(); 3486 assert(Inst.getNumOperands() == 2 && "Invalid operand count"); 3487 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isImm() && 3488 "Invalid instruction operand."); 3489 3490 unsigned FirstReg = Inst.getOperand(0).getReg(); 3491 uint64_t ImmOp64 = Inst.getOperand(1).getImm(); 3492 3493 ImmOp64 = convertIntToDoubleImm(ImmOp64); 3494 3495 unsigned TmpReg = Mips::ZERO; 3496 if (ImmOp64 != 0) { 3497 TmpReg = getATReg(IDLoc); 3498 if (!TmpReg) 3499 return true; 3500 } 3501 3502 if ((Lo_32(ImmOp64) == 0) && 3503 !((Hi_32(ImmOp64) & 0xffff0000) && (Hi_32(ImmOp64) & 0x0000ffff))) { 3504 if (isGP64bit()) { 3505 if (TmpReg != Mips::ZERO && 3506 loadImmediate(ImmOp64, TmpReg, Mips::NoRegister, false, false, IDLoc, 3507 Out, STI)) 3508 return true; 3509 TOut.emitRR(Mips::DMTC1, FirstReg, TmpReg, IDLoc, STI); 3510 return false; 3511 } 3512 3513 if (TmpReg != Mips::ZERO && 3514 loadImmediate(Hi_32(ImmOp64), TmpReg, Mips::NoRegister, true, false, 3515 IDLoc, Out, STI)) 3516 return true; 3517 3518 if (hasMips32r2()) { 3519 TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI); 3520 TOut.emitRRR(Mips::MTHC1_D32, FirstReg, FirstReg, TmpReg, IDLoc, STI); 3521 } else { 3522 TOut.emitRR(Mips::MTC1, nextReg(FirstReg), TmpReg, IDLoc, STI); 3523 TOut.emitRR(Mips::MTC1, FirstReg, Mips::ZERO, IDLoc, STI); 3524 } 3525 return false; 3526 } 3527 3528 MCSection *CS = getStreamer().getCurrentSectionOnly(); 3529 // FIXME: Enhance this expansion to use the .lit4 & .lit8 sections 3530 // where appropriate. 3531 MCSection *ReadOnlySection = 3532 getContext().getELFSection(".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC); 3533 3534 MCSymbol *Sym = getContext().createTempSymbol(); 3535 const MCExpr *LoSym = 3536 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 3537 const MipsMCExpr *LoExpr = 3538 MipsMCExpr::create(MipsMCExpr::MEK_LO, LoSym, getContext()); 3539 3540 getStreamer().switchSection(ReadOnlySection); 3541 getStreamer().emitLabel(Sym, IDLoc); 3542 getStreamer().emitValueToAlignment(Align(8)); 3543 getStreamer().emitIntValue(ImmOp64, 8); 3544 getStreamer().switchSection(CS); 3545 3546 if (emitPartialAddress(TOut, IDLoc, Sym)) 3547 return true; 3548 3549 TOut.emitRRX(Is64FPU ? Mips::LDC164 : Mips::LDC1, FirstReg, TmpReg, 3550 MCOperand::createExpr(LoExpr), IDLoc, STI); 3551 3552 return false; 3553 } 3554 3555 bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc, 3556 MCStreamer &Out, 3557 const MCSubtargetInfo *STI) { 3558 MipsTargetStreamer &TOut = getTargetStreamer(); 3559 3560 assert(MII.get(Inst.getOpcode()).getNumOperands() == 1 && 3561 "unexpected number of operands"); 3562 3563 MCOperand Offset = Inst.getOperand(0); 3564 if (Offset.isExpr()) { 3565 Inst.clear(); 3566 Inst.setOpcode(Mips::BEQ_MM); 3567 Inst.addOperand(MCOperand::createReg(Mips::ZERO)); 3568 Inst.addOperand(MCOperand::createReg(Mips::ZERO)); 3569 Inst.addOperand(MCOperand::createExpr(Offset.getExpr())); 3570 } else { 3571 assert(Offset.isImm() && "expected immediate operand kind"); 3572 if (isInt<11>(Offset.getImm())) { 3573 // If offset fits into 11 bits then this instruction becomes microMIPS 3574 // 16-bit unconditional branch instruction. 3575 if (inMicroMipsMode()) 3576 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM); 3577 } else { 3578 if (!isInt<17>(Offset.getImm())) 3579 return Error(IDLoc, "branch target out of range"); 3580 if (offsetToAlignment(Offset.getImm(), Align(2))) 3581 return Error(IDLoc, "branch to misaligned address"); 3582 Inst.clear(); 3583 Inst.setOpcode(Mips::BEQ_MM); 3584 Inst.addOperand(MCOperand::createReg(Mips::ZERO)); 3585 Inst.addOperand(MCOperand::createReg(Mips::ZERO)); 3586 Inst.addOperand(MCOperand::createImm(Offset.getImm())); 3587 } 3588 } 3589 Out.emitInstruction(Inst, *STI); 3590 3591 // If .set reorder is active and branch instruction has a delay slot, 3592 // emit a NOP after it. 3593 const MCInstrDesc &MCID = MII.get(Inst.getOpcode()); 3594 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) 3595 TOut.emitEmptyDelaySlot(true, IDLoc, STI); 3596 3597 return false; 3598 } 3599 3600 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 3601 const MCSubtargetInfo *STI) { 3602 MipsTargetStreamer &TOut = getTargetStreamer(); 3603 const MCOperand &DstRegOp = Inst.getOperand(0); 3604 assert(DstRegOp.isReg() && "expected register operand kind"); 3605 3606 const MCOperand &ImmOp = Inst.getOperand(1); 3607 assert(ImmOp.isImm() && "expected immediate operand kind"); 3608 3609 const MCOperand &MemOffsetOp = Inst.getOperand(2); 3610 assert((MemOffsetOp.isImm() || MemOffsetOp.isExpr()) && 3611 "expected immediate or expression operand"); 3612 3613 bool IsLikely = false; 3614 3615 unsigned OpCode = 0; 3616 switch(Inst.getOpcode()) { 3617 case Mips::BneImm: 3618 OpCode = Mips::BNE; 3619 break; 3620 case Mips::BeqImm: 3621 OpCode = Mips::BEQ; 3622 break; 3623 case Mips::BEQLImmMacro: 3624 OpCode = Mips::BEQL; 3625 IsLikely = true; 3626 break; 3627 case Mips::BNELImmMacro: 3628 OpCode = Mips::BNEL; 3629 IsLikely = true; 3630 break; 3631 default: 3632 llvm_unreachable("Unknown immediate branch pseudo-instruction."); 3633 break; 3634 } 3635 3636 int64_t ImmValue = ImmOp.getImm(); 3637 if (ImmValue == 0) { 3638 if (IsLikely) { 3639 TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, 3640 MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI); 3641 TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI); 3642 } else 3643 TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc, 3644 STI); 3645 } else { 3646 warnIfNoMacro(IDLoc); 3647 3648 unsigned ATReg = getATReg(IDLoc); 3649 if (!ATReg) 3650 return true; 3651 3652 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true, 3653 IDLoc, Out, STI)) 3654 return true; 3655 3656 if (IsLikely) { 3657 TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg, 3658 MCOperand::createExpr(MemOffsetOp.getExpr()), IDLoc, STI); 3659 TOut.emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI); 3660 } else 3661 TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, STI); 3662 } 3663 return false; 3664 } 3665 3666 void MipsAsmParser::expandMem16Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 3667 const MCSubtargetInfo *STI, bool IsLoad) { 3668 unsigned NumOp = Inst.getNumOperands(); 3669 assert((NumOp == 3 || NumOp == 4) && "unexpected operands number"); 3670 unsigned StartOp = NumOp == 3 ? 0 : 1; 3671 3672 const MCOperand &DstRegOp = Inst.getOperand(StartOp); 3673 assert(DstRegOp.isReg() && "expected register operand kind"); 3674 const MCOperand &BaseRegOp = Inst.getOperand(StartOp + 1); 3675 assert(BaseRegOp.isReg() && "expected register operand kind"); 3676 const MCOperand &OffsetOp = Inst.getOperand(StartOp + 2); 3677 3678 MipsTargetStreamer &TOut = getTargetStreamer(); 3679 unsigned OpCode = Inst.getOpcode(); 3680 unsigned DstReg = DstRegOp.getReg(); 3681 unsigned BaseReg = BaseRegOp.getReg(); 3682 unsigned TmpReg = DstReg; 3683 3684 const MCInstrDesc &Desc = MII.get(OpCode); 3685 int16_t DstRegClass = Desc.operands()[StartOp].RegClass; 3686 unsigned DstRegClassID = 3687 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID(); 3688 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) || 3689 (DstRegClassID == Mips::GPR64RegClassID); 3690 3691 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) { 3692 // At this point we need AT to perform the expansions 3693 // and we exit if it is not available. 3694 TmpReg = getATReg(IDLoc); 3695 if (!TmpReg) 3696 return; 3697 } 3698 3699 auto emitInstWithOffset = [&](const MCOperand &Off) { 3700 if (NumOp == 3) 3701 TOut.emitRRX(OpCode, DstReg, TmpReg, Off, IDLoc, STI); 3702 else 3703 TOut.emitRRRX(OpCode, DstReg, DstReg, TmpReg, Off, IDLoc, STI); 3704 }; 3705 3706 if (OffsetOp.isImm()) { 3707 int64_t LoOffset = OffsetOp.getImm() & 0xffff; 3708 int64_t HiOffset = OffsetOp.getImm() & ~0xffff; 3709 3710 // If msb of LoOffset is 1(negative number) we must increment 3711 // HiOffset to account for the sign-extension of the low part. 3712 if (LoOffset & 0x8000) 3713 HiOffset += 0x10000; 3714 3715 bool IsLargeOffset = HiOffset != 0; 3716 3717 if (IsLargeOffset) { 3718 bool Is32BitImm = isInt<32>(OffsetOp.getImm()); 3719 if (loadImmediate(HiOffset, TmpReg, Mips::NoRegister, Is32BitImm, true, 3720 IDLoc, Out, STI)) 3721 return; 3722 } 3723 3724 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64) 3725 TOut.emitRRR(ABI.ArePtrs64bit() ? Mips::DADDu : Mips::ADDu, TmpReg, 3726 TmpReg, BaseReg, IDLoc, STI); 3727 emitInstWithOffset(MCOperand::createImm(int16_t(LoOffset))); 3728 return; 3729 } 3730 3731 if (OffsetOp.isExpr()) { 3732 if (inPicMode()) { 3733 // FIXME: 3734 // c) Check that immediates of R_MIPS_GOT16/R_MIPS_LO16 relocations 3735 // do not exceed 16-bit. 3736 // d) Use R_MIPS_GOT_PAGE/R_MIPS_GOT_OFST relocations instead 3737 // of R_MIPS_GOT_DISP in appropriate cases to reduce number 3738 // of GOT entries. 3739 MCValue Res; 3740 if (!OffsetOp.getExpr()->evaluateAsRelocatable(Res, nullptr, nullptr)) { 3741 Error(IDLoc, "expected relocatable expression"); 3742 return; 3743 } 3744 if (Res.getSymB() != nullptr) { 3745 Error(IDLoc, "expected relocatable expression with only one symbol"); 3746 return; 3747 } 3748 3749 loadAndAddSymbolAddress(Res.getSymA(), TmpReg, BaseReg, 3750 !ABI.ArePtrs64bit(), IDLoc, Out, STI); 3751 emitInstWithOffset(MCOperand::createImm(int16_t(Res.getConstant()))); 3752 } else { 3753 // FIXME: Implement 64-bit case. 3754 // 1) lw $8, sym => lui $8, %hi(sym) 3755 // lw $8, %lo(sym)($8) 3756 // 2) sw $8, sym => lui $at, %hi(sym) 3757 // sw $8, %lo(sym)($at) 3758 const MCExpr *OffExpr = OffsetOp.getExpr(); 3759 MCOperand LoOperand = MCOperand::createExpr( 3760 MipsMCExpr::create(MipsMCExpr::MEK_LO, OffExpr, getContext())); 3761 MCOperand HiOperand = MCOperand::createExpr( 3762 MipsMCExpr::create(MipsMCExpr::MEK_HI, OffExpr, getContext())); 3763 3764 if (ABI.IsN64()) { 3765 MCOperand HighestOperand = MCOperand::createExpr( 3766 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, OffExpr, getContext())); 3767 MCOperand HigherOperand = MCOperand::createExpr( 3768 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, OffExpr, getContext())); 3769 3770 TOut.emitRX(Mips::LUi, TmpReg, HighestOperand, IDLoc, STI); 3771 TOut.emitRRX(Mips::DADDiu, TmpReg, TmpReg, HigherOperand, IDLoc, STI); 3772 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI); 3773 TOut.emitRRX(Mips::DADDiu, TmpReg, TmpReg, HiOperand, IDLoc, STI); 3774 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI); 3775 if (BaseReg != Mips::ZERO && BaseReg != Mips::ZERO_64) 3776 TOut.emitRRR(Mips::DADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI); 3777 emitInstWithOffset(LoOperand); 3778 } else { 3779 // Generate the base address in TmpReg. 3780 TOut.emitRX(Mips::LUi, TmpReg, HiOperand, IDLoc, STI); 3781 if (BaseReg != Mips::ZERO) 3782 TOut.emitRRR(Mips::ADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI); 3783 // Emit the load or store with the adjusted base and offset. 3784 emitInstWithOffset(LoOperand); 3785 } 3786 } 3787 return; 3788 } 3789 3790 llvm_unreachable("unexpected operand type"); 3791 } 3792 3793 void MipsAsmParser::expandMem9Inst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 3794 const MCSubtargetInfo *STI, bool IsLoad) { 3795 unsigned NumOp = Inst.getNumOperands(); 3796 assert((NumOp == 3 || NumOp == 4) && "unexpected operands number"); 3797 unsigned StartOp = NumOp == 3 ? 0 : 1; 3798 3799 const MCOperand &DstRegOp = Inst.getOperand(StartOp); 3800 assert(DstRegOp.isReg() && "expected register operand kind"); 3801 const MCOperand &BaseRegOp = Inst.getOperand(StartOp + 1); 3802 assert(BaseRegOp.isReg() && "expected register operand kind"); 3803 const MCOperand &OffsetOp = Inst.getOperand(StartOp + 2); 3804 3805 MipsTargetStreamer &TOut = getTargetStreamer(); 3806 unsigned OpCode = Inst.getOpcode(); 3807 unsigned DstReg = DstRegOp.getReg(); 3808 unsigned BaseReg = BaseRegOp.getReg(); 3809 unsigned TmpReg = DstReg; 3810 3811 const MCInstrDesc &Desc = MII.get(OpCode); 3812 int16_t DstRegClass = Desc.operands()[StartOp].RegClass; 3813 unsigned DstRegClassID = 3814 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID(); 3815 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) || 3816 (DstRegClassID == Mips::GPR64RegClassID); 3817 3818 if (!IsLoad || !IsGPR || (BaseReg == DstReg)) { 3819 // At this point we need AT to perform the expansions 3820 // and we exit if it is not available. 3821 TmpReg = getATReg(IDLoc); 3822 if (!TmpReg) 3823 return; 3824 } 3825 3826 auto emitInst = [&]() { 3827 if (NumOp == 3) 3828 TOut.emitRRX(OpCode, DstReg, TmpReg, MCOperand::createImm(0), IDLoc, STI); 3829 else 3830 TOut.emitRRRX(OpCode, DstReg, DstReg, TmpReg, MCOperand::createImm(0), 3831 IDLoc, STI); 3832 }; 3833 3834 if (OffsetOp.isImm()) { 3835 loadImmediate(OffsetOp.getImm(), TmpReg, BaseReg, !ABI.ArePtrs64bit(), true, 3836 IDLoc, Out, STI); 3837 emitInst(); 3838 return; 3839 } 3840 3841 if (OffsetOp.isExpr()) { 3842 loadAndAddSymbolAddress(OffsetOp.getExpr(), TmpReg, BaseReg, 3843 !ABI.ArePtrs64bit(), IDLoc, Out, STI); 3844 emitInst(); 3845 return; 3846 } 3847 3848 llvm_unreachable("unexpected operand type"); 3849 } 3850 3851 bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc, 3852 MCStreamer &Out, 3853 const MCSubtargetInfo *STI) { 3854 unsigned OpNum = Inst.getNumOperands(); 3855 unsigned Opcode = Inst.getOpcode(); 3856 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM; 3857 3858 assert(Inst.getOperand(OpNum - 1).isImm() && 3859 Inst.getOperand(OpNum - 2).isReg() && 3860 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand."); 3861 3862 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 && 3863 Inst.getOperand(OpNum - 1).getImm() >= 0 && 3864 (Inst.getOperand(OpNum - 2).getReg() == Mips::SP || 3865 Inst.getOperand(OpNum - 2).getReg() == Mips::SP_64) && 3866 (Inst.getOperand(OpNum - 3).getReg() == Mips::RA || 3867 Inst.getOperand(OpNum - 3).getReg() == Mips::RA_64)) { 3868 // It can be implemented as SWM16 or LWM16 instruction. 3869 if (inMicroMipsMode() && hasMips32r6()) 3870 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6; 3871 else 3872 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM; 3873 } 3874 3875 Inst.setOpcode(NewOpcode); 3876 Out.emitInstruction(Inst, *STI); 3877 return false; 3878 } 3879 3880 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc, 3881 MCStreamer &Out, 3882 const MCSubtargetInfo *STI) { 3883 MipsTargetStreamer &TOut = getTargetStreamer(); 3884 bool EmittedNoMacroWarning = false; 3885 unsigned PseudoOpcode = Inst.getOpcode(); 3886 unsigned SrcReg = Inst.getOperand(0).getReg(); 3887 const MCOperand &TrgOp = Inst.getOperand(1); 3888 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr(); 3889 3890 unsigned ZeroSrcOpcode, ZeroTrgOpcode; 3891 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality; 3892 3893 unsigned TrgReg; 3894 if (TrgOp.isReg()) 3895 TrgReg = TrgOp.getReg(); 3896 else if (TrgOp.isImm()) { 3897 warnIfNoMacro(IDLoc); 3898 EmittedNoMacroWarning = true; 3899 3900 TrgReg = getATReg(IDLoc); 3901 if (!TrgReg) 3902 return true; 3903 3904 switch(PseudoOpcode) { 3905 default: 3906 llvm_unreachable("unknown opcode for branch pseudo-instruction"); 3907 case Mips::BLTImmMacro: 3908 PseudoOpcode = Mips::BLT; 3909 break; 3910 case Mips::BLEImmMacro: 3911 PseudoOpcode = Mips::BLE; 3912 break; 3913 case Mips::BGEImmMacro: 3914 PseudoOpcode = Mips::BGE; 3915 break; 3916 case Mips::BGTImmMacro: 3917 PseudoOpcode = Mips::BGT; 3918 break; 3919 case Mips::BLTUImmMacro: 3920 PseudoOpcode = Mips::BLTU; 3921 break; 3922 case Mips::BLEUImmMacro: 3923 PseudoOpcode = Mips::BLEU; 3924 break; 3925 case Mips::BGEUImmMacro: 3926 PseudoOpcode = Mips::BGEU; 3927 break; 3928 case Mips::BGTUImmMacro: 3929 PseudoOpcode = Mips::BGTU; 3930 break; 3931 case Mips::BLTLImmMacro: 3932 PseudoOpcode = Mips::BLTL; 3933 break; 3934 case Mips::BLELImmMacro: 3935 PseudoOpcode = Mips::BLEL; 3936 break; 3937 case Mips::BGELImmMacro: 3938 PseudoOpcode = Mips::BGEL; 3939 break; 3940 case Mips::BGTLImmMacro: 3941 PseudoOpcode = Mips::BGTL; 3942 break; 3943 case Mips::BLTULImmMacro: 3944 PseudoOpcode = Mips::BLTUL; 3945 break; 3946 case Mips::BLEULImmMacro: 3947 PseudoOpcode = Mips::BLEUL; 3948 break; 3949 case Mips::BGEULImmMacro: 3950 PseudoOpcode = Mips::BGEUL; 3951 break; 3952 case Mips::BGTULImmMacro: 3953 PseudoOpcode = Mips::BGTUL; 3954 break; 3955 } 3956 3957 if (loadImmediate(TrgOp.getImm(), TrgReg, Mips::NoRegister, !isGP64bit(), 3958 false, IDLoc, Out, STI)) 3959 return true; 3960 } 3961 3962 switch (PseudoOpcode) { 3963 case Mips::BLT: 3964 case Mips::BLTU: 3965 case Mips::BLTL: 3966 case Mips::BLTUL: 3967 AcceptsEquality = false; 3968 ReverseOrderSLT = false; 3969 IsUnsigned = 3970 ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL)); 3971 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL)); 3972 ZeroSrcOpcode = Mips::BGTZ; 3973 ZeroTrgOpcode = Mips::BLTZ; 3974 break; 3975 case Mips::BLE: 3976 case Mips::BLEU: 3977 case Mips::BLEL: 3978 case Mips::BLEUL: 3979 AcceptsEquality = true; 3980 ReverseOrderSLT = true; 3981 IsUnsigned = 3982 ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL)); 3983 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL)); 3984 ZeroSrcOpcode = Mips::BGEZ; 3985 ZeroTrgOpcode = Mips::BLEZ; 3986 break; 3987 case Mips::BGE: 3988 case Mips::BGEU: 3989 case Mips::BGEL: 3990 case Mips::BGEUL: 3991 AcceptsEquality = true; 3992 ReverseOrderSLT = false; 3993 IsUnsigned = 3994 ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL)); 3995 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL)); 3996 ZeroSrcOpcode = Mips::BLEZ; 3997 ZeroTrgOpcode = Mips::BGEZ; 3998 break; 3999 case Mips::BGT: 4000 case Mips::BGTU: 4001 case Mips::BGTL: 4002 case Mips::BGTUL: 4003 AcceptsEquality = false; 4004 ReverseOrderSLT = true; 4005 IsUnsigned = 4006 ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL)); 4007 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL)); 4008 ZeroSrcOpcode = Mips::BLTZ; 4009 ZeroTrgOpcode = Mips::BGTZ; 4010 break; 4011 default: 4012 llvm_unreachable("unknown opcode for branch pseudo-instruction"); 4013 } 4014 4015 bool IsTrgRegZero = (TrgReg == Mips::ZERO); 4016 bool IsSrcRegZero = (SrcReg == Mips::ZERO); 4017 if (IsSrcRegZero && IsTrgRegZero) { 4018 // FIXME: All of these Opcode-specific if's are needed for compatibility 4019 // with GAS' behaviour. However, they may not generate the most efficient 4020 // code in some circumstances. 4021 if (PseudoOpcode == Mips::BLT) { 4022 TOut.emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), 4023 IDLoc, STI); 4024 return false; 4025 } 4026 if (PseudoOpcode == Mips::BLE) { 4027 TOut.emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), 4028 IDLoc, STI); 4029 Warning(IDLoc, "branch is always taken"); 4030 return false; 4031 } 4032 if (PseudoOpcode == Mips::BGE) { 4033 TOut.emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), 4034 IDLoc, STI); 4035 Warning(IDLoc, "branch is always taken"); 4036 return false; 4037 } 4038 if (PseudoOpcode == Mips::BGT) { 4039 TOut.emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), 4040 IDLoc, STI); 4041 return false; 4042 } 4043 if (PseudoOpcode == Mips::BGTU) { 4044 TOut.emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO, 4045 MCOperand::createExpr(OffsetExpr), IDLoc, STI); 4046 return false; 4047 } 4048 if (AcceptsEquality) { 4049 // If both registers are $0 and the pseudo-branch accepts equality, it 4050 // will always be taken, so we emit an unconditional branch. 4051 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO, 4052 MCOperand::createExpr(OffsetExpr), IDLoc, STI); 4053 Warning(IDLoc, "branch is always taken"); 4054 return false; 4055 } 4056 // If both registers are $0 and the pseudo-branch does not accept 4057 // equality, it will never be taken, so we don't have to emit anything. 4058 return false; 4059 } 4060 if (IsSrcRegZero || IsTrgRegZero) { 4061 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) || 4062 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) { 4063 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or 4064 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0), 4065 // the pseudo-branch will never be taken, so we don't emit anything. 4066 // This only applies to unsigned pseudo-branches. 4067 return false; 4068 } 4069 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) || 4070 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) { 4071 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or 4072 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0), 4073 // the pseudo-branch will always be taken, so we emit an unconditional 4074 // branch. 4075 // This only applies to unsigned pseudo-branches. 4076 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO, 4077 MCOperand::createExpr(OffsetExpr), IDLoc, STI); 4078 Warning(IDLoc, "branch is always taken"); 4079 return false; 4080 } 4081 if (IsUnsigned) { 4082 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or 4083 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0), 4084 // the pseudo-branch will be taken only when the non-zero register is 4085 // different from 0, so we emit a BNEZ. 4086 // 4087 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or 4088 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0), 4089 // the pseudo-branch will be taken only when the non-zero register is 4090 // equal to 0, so we emit a BEQZ. 4091 // 4092 // Because only BLEU and BGEU branch on equality, we can use the 4093 // AcceptsEquality variable to decide when to emit the BEQZ. 4094 TOut.emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE, 4095 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO, 4096 MCOperand::createExpr(OffsetExpr), IDLoc, STI); 4097 return false; 4098 } 4099 // If we have a signed pseudo-branch and one of the registers is $0, 4100 // we can use an appropriate compare-to-zero branch. We select which one 4101 // to use in the switch statement above. 4102 TOut.emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode, 4103 IsSrcRegZero ? TrgReg : SrcReg, 4104 MCOperand::createExpr(OffsetExpr), IDLoc, STI); 4105 return false; 4106 } 4107 4108 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the 4109 // expansions. If it is not available, we return. 4110 unsigned ATRegNum = getATReg(IDLoc); 4111 if (!ATRegNum) 4112 return true; 4113 4114 if (!EmittedNoMacroWarning) 4115 warnIfNoMacro(IDLoc); 4116 4117 // SLT fits well with 2 of our 4 pseudo-branches: 4118 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and 4119 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs". 4120 // If the result of the SLT is 1, we branch, and if it's 0, we don't. 4121 // This is accomplished by using a BNEZ with the result of the SLT. 4122 // 4123 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT 4124 // and BLE with BGT), so we change the BNEZ into a BEQZ. 4125 // Because only BGE and BLE branch on equality, we can use the 4126 // AcceptsEquality variable to decide when to emit the BEQZ. 4127 // Note that the order of the SLT arguments doesn't change between 4128 // opposites. 4129 // 4130 // The same applies to the unsigned variants, except that SLTu is used 4131 // instead of SLT. 4132 TOut.emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum, 4133 ReverseOrderSLT ? TrgReg : SrcReg, 4134 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI); 4135 4136 TOut.emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL) 4137 : (AcceptsEquality ? Mips::BEQ : Mips::BNE), 4138 ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc, 4139 STI); 4140 return false; 4141 } 4142 4143 // Expand a integer division macro. 4144 // 4145 // Notably we don't have to emit a warning when encountering $rt as the $zero 4146 // register, or 0 as an immediate. processInstruction() has already done that. 4147 // 4148 // The destination register can only be $zero when expanding (S)DivIMacro or 4149 // D(S)DivMacro. 4150 4151 bool MipsAsmParser::expandDivRem(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 4152 const MCSubtargetInfo *STI, 4153 const bool IsMips64, const bool Signed) { 4154 MipsTargetStreamer &TOut = getTargetStreamer(); 4155 4156 warnIfNoMacro(IDLoc); 4157 4158 const MCOperand &RdRegOp = Inst.getOperand(0); 4159 assert(RdRegOp.isReg() && "expected register operand kind"); 4160 unsigned RdReg = RdRegOp.getReg(); 4161 4162 const MCOperand &RsRegOp = Inst.getOperand(1); 4163 assert(RsRegOp.isReg() && "expected register operand kind"); 4164 unsigned RsReg = RsRegOp.getReg(); 4165 4166 unsigned RtReg; 4167 int64_t ImmValue; 4168 4169 const MCOperand &RtOp = Inst.getOperand(2); 4170 assert((RtOp.isReg() || RtOp.isImm()) && 4171 "expected register or immediate operand kind"); 4172 if (RtOp.isReg()) 4173 RtReg = RtOp.getReg(); 4174 else 4175 ImmValue = RtOp.getImm(); 4176 4177 unsigned DivOp; 4178 unsigned ZeroReg; 4179 unsigned SubOp; 4180 4181 if (IsMips64) { 4182 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV; 4183 ZeroReg = Mips::ZERO_64; 4184 SubOp = Mips::DSUB; 4185 } else { 4186 DivOp = Signed ? Mips::SDIV : Mips::UDIV; 4187 ZeroReg = Mips::ZERO; 4188 SubOp = Mips::SUB; 4189 } 4190 4191 bool UseTraps = useTraps(); 4192 4193 unsigned Opcode = Inst.getOpcode(); 4194 bool isDiv = Opcode == Mips::SDivMacro || Opcode == Mips::SDivIMacro || 4195 Opcode == Mips::UDivMacro || Opcode == Mips::UDivIMacro || 4196 Opcode == Mips::DSDivMacro || Opcode == Mips::DSDivIMacro || 4197 Opcode == Mips::DUDivMacro || Opcode == Mips::DUDivIMacro; 4198 4199 bool isRem = Opcode == Mips::SRemMacro || Opcode == Mips::SRemIMacro || 4200 Opcode == Mips::URemMacro || Opcode == Mips::URemIMacro || 4201 Opcode == Mips::DSRemMacro || Opcode == Mips::DSRemIMacro || 4202 Opcode == Mips::DURemMacro || Opcode == Mips::DURemIMacro; 4203 4204 if (RtOp.isImm()) { 4205 unsigned ATReg = getATReg(IDLoc); 4206 if (!ATReg) 4207 return true; 4208 4209 if (ImmValue == 0) { 4210 if (UseTraps) 4211 TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI); 4212 else 4213 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI); 4214 return false; 4215 } 4216 4217 if (isRem && (ImmValue == 1 || (Signed && (ImmValue == -1)))) { 4218 TOut.emitRRR(Mips::OR, RdReg, ZeroReg, ZeroReg, IDLoc, STI); 4219 return false; 4220 } else if (isDiv && ImmValue == 1) { 4221 TOut.emitRRR(Mips::OR, RdReg, RsReg, Mips::ZERO, IDLoc, STI); 4222 return false; 4223 } else if (isDiv && Signed && ImmValue == -1) { 4224 TOut.emitRRR(SubOp, RdReg, ZeroReg, RsReg, IDLoc, STI); 4225 return false; 4226 } else { 4227 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, isInt<32>(ImmValue), 4228 false, Inst.getLoc(), Out, STI)) 4229 return true; 4230 TOut.emitRR(DivOp, RsReg, ATReg, IDLoc, STI); 4231 TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI); 4232 return false; 4233 } 4234 return true; 4235 } 4236 4237 // If the macro expansion of (d)div(u) or (d)rem(u) would always trap or 4238 // break, insert the trap/break and exit. This gives a different result to 4239 // GAS. GAS has an inconsistency/missed optimization in that not all cases 4240 // are handled equivalently. As the observed behaviour is the same, we're ok. 4241 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) { 4242 if (UseTraps) { 4243 TOut.emitRRI(Mips::TEQ, ZeroReg, ZeroReg, 0x7, IDLoc, STI); 4244 return false; 4245 } 4246 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI); 4247 return false; 4248 } 4249 4250 // (d)rem(u) $0, $X, $Y is a special case. Like div $zero, $X, $Y, it does 4251 // not expand to macro sequence. 4252 if (isRem && (RdReg == Mips::ZERO || RdReg == Mips::ZERO_64)) { 4253 TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI); 4254 return false; 4255 } 4256 4257 // Temporary label for first branch traget 4258 MCContext &Context = TOut.getStreamer().getContext(); 4259 MCSymbol *BrTarget; 4260 MCOperand LabelOp; 4261 4262 if (UseTraps) { 4263 TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI); 4264 } else { 4265 // Branch to the li instruction. 4266 BrTarget = Context.createTempSymbol(); 4267 LabelOp = MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context)); 4268 TOut.emitRRX(Mips::BNE, RtReg, ZeroReg, LabelOp, IDLoc, STI); 4269 } 4270 4271 TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI); 4272 4273 if (!UseTraps) 4274 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI); 4275 4276 if (!Signed) { 4277 if (!UseTraps) 4278 TOut.getStreamer().emitLabel(BrTarget); 4279 4280 TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI); 4281 return false; 4282 } 4283 4284 unsigned ATReg = getATReg(IDLoc); 4285 if (!ATReg) 4286 return true; 4287 4288 if (!UseTraps) 4289 TOut.getStreamer().emitLabel(BrTarget); 4290 4291 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, STI); 4292 4293 // Temporary label for the second branch target. 4294 MCSymbol *BrTargetEnd = Context.createTempSymbol(); 4295 MCOperand LabelOpEnd = 4296 MCOperand::createExpr(MCSymbolRefExpr::create(BrTargetEnd, Context)); 4297 4298 // Branch to the mflo instruction. 4299 TOut.emitRRX(Mips::BNE, RtReg, ATReg, LabelOpEnd, IDLoc, STI); 4300 4301 if (IsMips64) { 4302 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, STI); 4303 TOut.emitDSLL(ATReg, ATReg, 63, IDLoc, STI); 4304 } else { 4305 TOut.emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, STI); 4306 } 4307 4308 if (UseTraps) 4309 TOut.emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, STI); 4310 else { 4311 // Branch to the mflo instruction. 4312 TOut.emitRRX(Mips::BNE, RsReg, ATReg, LabelOpEnd, IDLoc, STI); 4313 TOut.emitNop(IDLoc, STI); 4314 TOut.emitII(Mips::BREAK, 0x6, 0, IDLoc, STI); 4315 } 4316 4317 TOut.getStreamer().emitLabel(BrTargetEnd); 4318 TOut.emitR(isDiv ? Mips::MFLO : Mips::MFHI, RdReg, IDLoc, STI); 4319 return false; 4320 } 4321 4322 bool MipsAsmParser::expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU, 4323 SMLoc IDLoc, MCStreamer &Out, 4324 const MCSubtargetInfo *STI) { 4325 MipsTargetStreamer &TOut = getTargetStreamer(); 4326 4327 assert(Inst.getNumOperands() == 3 && "Invalid operand count"); 4328 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() && 4329 Inst.getOperand(2).isReg() && "Invalid instruction operand."); 4330 4331 unsigned FirstReg = Inst.getOperand(0).getReg(); 4332 unsigned SecondReg = Inst.getOperand(1).getReg(); 4333 unsigned ThirdReg = Inst.getOperand(2).getReg(); 4334 4335 if (hasMips1() && !hasMips2()) { 4336 unsigned ATReg = getATReg(IDLoc); 4337 if (!ATReg) 4338 return true; 4339 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI); 4340 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI); 4341 TOut.emitNop(IDLoc, STI); 4342 TOut.emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI); 4343 TOut.emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI); 4344 TOut.emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI); 4345 TOut.emitNop(IDLoc, STI); 4346 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32) 4347 : Mips::CVT_W_S, 4348 FirstReg, SecondReg, IDLoc, STI); 4349 TOut.emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI); 4350 TOut.emitNop(IDLoc, STI); 4351 return false; 4352 } 4353 4354 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32) 4355 : Mips::TRUNC_W_S, 4356 FirstReg, SecondReg, IDLoc, STI); 4357 4358 return false; 4359 } 4360 4361 bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc, 4362 MCStreamer &Out, const MCSubtargetInfo *STI) { 4363 if (hasMips32r6() || hasMips64r6()) { 4364 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6"); 4365 } 4366 4367 const MCOperand &DstRegOp = Inst.getOperand(0); 4368 assert(DstRegOp.isReg() && "expected register operand kind"); 4369 const MCOperand &SrcRegOp = Inst.getOperand(1); 4370 assert(SrcRegOp.isReg() && "expected register operand kind"); 4371 const MCOperand &OffsetImmOp = Inst.getOperand(2); 4372 assert(OffsetImmOp.isImm() && "expected immediate operand kind"); 4373 4374 MipsTargetStreamer &TOut = getTargetStreamer(); 4375 unsigned DstReg = DstRegOp.getReg(); 4376 unsigned SrcReg = SrcRegOp.getReg(); 4377 int64_t OffsetValue = OffsetImmOp.getImm(); 4378 4379 // NOTE: We always need AT for ULHU, as it is always used as the source 4380 // register for one of the LBu's. 4381 warnIfNoMacro(IDLoc); 4382 unsigned ATReg = getATReg(IDLoc); 4383 if (!ATReg) 4384 return true; 4385 4386 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue)); 4387 if (IsLargeOffset) { 4388 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true, 4389 IDLoc, Out, STI)) 4390 return true; 4391 } 4392 4393 int64_t FirstOffset = IsLargeOffset ? 0 : OffsetValue; 4394 int64_t SecondOffset = IsLargeOffset ? 1 : (OffsetValue + 1); 4395 if (isLittle()) 4396 std::swap(FirstOffset, SecondOffset); 4397 4398 unsigned FirstLbuDstReg = IsLargeOffset ? DstReg : ATReg; 4399 unsigned SecondLbuDstReg = IsLargeOffset ? ATReg : DstReg; 4400 4401 unsigned LbuSrcReg = IsLargeOffset ? ATReg : SrcReg; 4402 unsigned SllReg = IsLargeOffset ? DstReg : ATReg; 4403 4404 TOut.emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg, 4405 FirstOffset, IDLoc, STI); 4406 TOut.emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondOffset, IDLoc, STI); 4407 TOut.emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI); 4408 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI); 4409 4410 return false; 4411 } 4412 4413 bool MipsAsmParser::expandUsh(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 4414 const MCSubtargetInfo *STI) { 4415 if (hasMips32r6() || hasMips64r6()) { 4416 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6"); 4417 } 4418 4419 const MCOperand &DstRegOp = Inst.getOperand(0); 4420 assert(DstRegOp.isReg() && "expected register operand kind"); 4421 const MCOperand &SrcRegOp = Inst.getOperand(1); 4422 assert(SrcRegOp.isReg() && "expected register operand kind"); 4423 const MCOperand &OffsetImmOp = Inst.getOperand(2); 4424 assert(OffsetImmOp.isImm() && "expected immediate operand kind"); 4425 4426 MipsTargetStreamer &TOut = getTargetStreamer(); 4427 unsigned DstReg = DstRegOp.getReg(); 4428 unsigned SrcReg = SrcRegOp.getReg(); 4429 int64_t OffsetValue = OffsetImmOp.getImm(); 4430 4431 warnIfNoMacro(IDLoc); 4432 unsigned ATReg = getATReg(IDLoc); 4433 if (!ATReg) 4434 return true; 4435 4436 bool IsLargeOffset = !(isInt<16>(OffsetValue + 1) && isInt<16>(OffsetValue)); 4437 if (IsLargeOffset) { 4438 if (loadImmediate(OffsetValue, ATReg, SrcReg, !ABI.ArePtrs64bit(), true, 4439 IDLoc, Out, STI)) 4440 return true; 4441 } 4442 4443 int64_t FirstOffset = IsLargeOffset ? 1 : (OffsetValue + 1); 4444 int64_t SecondOffset = IsLargeOffset ? 0 : OffsetValue; 4445 if (isLittle()) 4446 std::swap(FirstOffset, SecondOffset); 4447 4448 if (IsLargeOffset) { 4449 TOut.emitRRI(Mips::SB, DstReg, ATReg, FirstOffset, IDLoc, STI); 4450 TOut.emitRRI(Mips::SRL, DstReg, DstReg, 8, IDLoc, STI); 4451 TOut.emitRRI(Mips::SB, DstReg, ATReg, SecondOffset, IDLoc, STI); 4452 TOut.emitRRI(Mips::LBu, ATReg, ATReg, 0, IDLoc, STI); 4453 TOut.emitRRI(Mips::SLL, DstReg, DstReg, 8, IDLoc, STI); 4454 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI); 4455 } else { 4456 TOut.emitRRI(Mips::SB, DstReg, SrcReg, FirstOffset, IDLoc, STI); 4457 TOut.emitRRI(Mips::SRL, ATReg, DstReg, 8, IDLoc, STI); 4458 TOut.emitRRI(Mips::SB, ATReg, SrcReg, SecondOffset, IDLoc, STI); 4459 } 4460 4461 return false; 4462 } 4463 4464 bool MipsAsmParser::expandUxw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 4465 const MCSubtargetInfo *STI) { 4466 if (hasMips32r6() || hasMips64r6()) { 4467 return Error(IDLoc, "instruction not supported on mips32r6 or mips64r6"); 4468 } 4469 4470 const MCOperand &DstRegOp = Inst.getOperand(0); 4471 assert(DstRegOp.isReg() && "expected register operand kind"); 4472 const MCOperand &SrcRegOp = Inst.getOperand(1); 4473 assert(SrcRegOp.isReg() && "expected register operand kind"); 4474 const MCOperand &OffsetImmOp = Inst.getOperand(2); 4475 assert(OffsetImmOp.isImm() && "expected immediate operand kind"); 4476 4477 MipsTargetStreamer &TOut = getTargetStreamer(); 4478 unsigned DstReg = DstRegOp.getReg(); 4479 unsigned SrcReg = SrcRegOp.getReg(); 4480 int64_t OffsetValue = OffsetImmOp.getImm(); 4481 4482 // Compute left/right load/store offsets. 4483 bool IsLargeOffset = !(isInt<16>(OffsetValue + 3) && isInt<16>(OffsetValue)); 4484 int64_t LxlOffset = IsLargeOffset ? 0 : OffsetValue; 4485 int64_t LxrOffset = IsLargeOffset ? 3 : (OffsetValue + 3); 4486 if (isLittle()) 4487 std::swap(LxlOffset, LxrOffset); 4488 4489 bool IsLoadInst = (Inst.getOpcode() == Mips::Ulw); 4490 bool DoMove = IsLoadInst && (SrcReg == DstReg) && !IsLargeOffset; 4491 unsigned TmpReg = SrcReg; 4492 if (IsLargeOffset || DoMove) { 4493 warnIfNoMacro(IDLoc); 4494 TmpReg = getATReg(IDLoc); 4495 if (!TmpReg) 4496 return true; 4497 } 4498 4499 if (IsLargeOffset) { 4500 if (loadImmediate(OffsetValue, TmpReg, SrcReg, !ABI.ArePtrs64bit(), true, 4501 IDLoc, Out, STI)) 4502 return true; 4503 } 4504 4505 if (DoMove) 4506 std::swap(DstReg, TmpReg); 4507 4508 unsigned XWL = IsLoadInst ? Mips::LWL : Mips::SWL; 4509 unsigned XWR = IsLoadInst ? Mips::LWR : Mips::SWR; 4510 TOut.emitRRI(XWL, DstReg, TmpReg, LxlOffset, IDLoc, STI); 4511 TOut.emitRRI(XWR, DstReg, TmpReg, LxrOffset, IDLoc, STI); 4512 4513 if (DoMove) 4514 TOut.emitRRR(Mips::OR, TmpReg, DstReg, Mips::ZERO, IDLoc, STI); 4515 4516 return false; 4517 } 4518 4519 bool MipsAsmParser::expandSge(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 4520 const MCSubtargetInfo *STI) { 4521 MipsTargetStreamer &TOut = getTargetStreamer(); 4522 4523 assert(Inst.getNumOperands() == 3 && "Invalid operand count"); 4524 assert(Inst.getOperand(0).isReg() && 4525 Inst.getOperand(1).isReg() && 4526 Inst.getOperand(2).isReg() && "Invalid instruction operand."); 4527 4528 unsigned DstReg = Inst.getOperand(0).getReg(); 4529 unsigned SrcReg = Inst.getOperand(1).getReg(); 4530 unsigned OpReg = Inst.getOperand(2).getReg(); 4531 unsigned OpCode; 4532 4533 warnIfNoMacro(IDLoc); 4534 4535 switch (Inst.getOpcode()) { 4536 case Mips::SGE: 4537 OpCode = Mips::SLT; 4538 break; 4539 case Mips::SGEU: 4540 OpCode = Mips::SLTu; 4541 break; 4542 default: 4543 llvm_unreachable("unexpected 'sge' opcode"); 4544 } 4545 4546 // $SrcReg >= $OpReg is equal to (not ($SrcReg < $OpReg)) 4547 TOut.emitRRR(OpCode, DstReg, SrcReg, OpReg, IDLoc, STI); 4548 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI); 4549 4550 return false; 4551 } 4552 4553 bool MipsAsmParser::expandSgeImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 4554 const MCSubtargetInfo *STI) { 4555 MipsTargetStreamer &TOut = getTargetStreamer(); 4556 4557 assert(Inst.getNumOperands() == 3 && "Invalid operand count"); 4558 assert(Inst.getOperand(0).isReg() && 4559 Inst.getOperand(1).isReg() && 4560 Inst.getOperand(2).isImm() && "Invalid instruction operand."); 4561 4562 unsigned DstReg = Inst.getOperand(0).getReg(); 4563 unsigned SrcReg = Inst.getOperand(1).getReg(); 4564 int64_t ImmValue = Inst.getOperand(2).getImm(); 4565 unsigned OpRegCode, OpImmCode; 4566 4567 warnIfNoMacro(IDLoc); 4568 4569 switch (Inst.getOpcode()) { 4570 case Mips::SGEImm: 4571 case Mips::SGEImm64: 4572 OpRegCode = Mips::SLT; 4573 OpImmCode = Mips::SLTi; 4574 break; 4575 case Mips::SGEUImm: 4576 case Mips::SGEUImm64: 4577 OpRegCode = Mips::SLTu; 4578 OpImmCode = Mips::SLTiu; 4579 break; 4580 default: 4581 llvm_unreachable("unexpected 'sge' opcode with immediate"); 4582 } 4583 4584 // $SrcReg >= Imm is equal to (not ($SrcReg < Imm)) 4585 if (isInt<16>(ImmValue)) { 4586 // Use immediate version of STL. 4587 TOut.emitRRI(OpImmCode, DstReg, SrcReg, ImmValue, IDLoc, STI); 4588 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI); 4589 } else { 4590 unsigned ImmReg = DstReg; 4591 if (DstReg == SrcReg) { 4592 unsigned ATReg = getATReg(Inst.getLoc()); 4593 if (!ATReg) 4594 return true; 4595 ImmReg = ATReg; 4596 } 4597 4598 if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue), 4599 false, IDLoc, Out, STI)) 4600 return true; 4601 4602 TOut.emitRRR(OpRegCode, DstReg, SrcReg, ImmReg, IDLoc, STI); 4603 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI); 4604 } 4605 4606 return false; 4607 } 4608 4609 bool MipsAsmParser::expandSgtImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 4610 const MCSubtargetInfo *STI) { 4611 MipsTargetStreamer &TOut = getTargetStreamer(); 4612 4613 assert(Inst.getNumOperands() == 3 && "Invalid operand count"); 4614 assert(Inst.getOperand(0).isReg() && 4615 Inst.getOperand(1).isReg() && 4616 Inst.getOperand(2).isImm() && "Invalid instruction operand."); 4617 4618 unsigned DstReg = Inst.getOperand(0).getReg(); 4619 unsigned SrcReg = Inst.getOperand(1).getReg(); 4620 unsigned ImmReg = DstReg; 4621 int64_t ImmValue = Inst.getOperand(2).getImm(); 4622 unsigned OpCode; 4623 4624 warnIfNoMacro(IDLoc); 4625 4626 switch (Inst.getOpcode()) { 4627 case Mips::SGTImm: 4628 case Mips::SGTImm64: 4629 OpCode = Mips::SLT; 4630 break; 4631 case Mips::SGTUImm: 4632 case Mips::SGTUImm64: 4633 OpCode = Mips::SLTu; 4634 break; 4635 default: 4636 llvm_unreachable("unexpected 'sgt' opcode with immediate"); 4637 } 4638 4639 if (DstReg == SrcReg) { 4640 unsigned ATReg = getATReg(Inst.getLoc()); 4641 if (!ATReg) 4642 return true; 4643 ImmReg = ATReg; 4644 } 4645 4646 if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue), 4647 false, IDLoc, Out, STI)) 4648 return true; 4649 4650 // $SrcReg > $ImmReg is equal to $ImmReg < $SrcReg 4651 TOut.emitRRR(OpCode, DstReg, ImmReg, SrcReg, IDLoc, STI); 4652 4653 return false; 4654 } 4655 4656 bool MipsAsmParser::expandSle(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 4657 const MCSubtargetInfo *STI) { 4658 MipsTargetStreamer &TOut = getTargetStreamer(); 4659 4660 assert(Inst.getNumOperands() == 3 && "Invalid operand count"); 4661 assert(Inst.getOperand(0).isReg() && 4662 Inst.getOperand(1).isReg() && 4663 Inst.getOperand(2).isReg() && "Invalid instruction operand."); 4664 4665 unsigned DstReg = Inst.getOperand(0).getReg(); 4666 unsigned SrcReg = Inst.getOperand(1).getReg(); 4667 unsigned OpReg = Inst.getOperand(2).getReg(); 4668 unsigned OpCode; 4669 4670 warnIfNoMacro(IDLoc); 4671 4672 switch (Inst.getOpcode()) { 4673 case Mips::SLE: 4674 OpCode = Mips::SLT; 4675 break; 4676 case Mips::SLEU: 4677 OpCode = Mips::SLTu; 4678 break; 4679 default: 4680 llvm_unreachable("unexpected 'sge' opcode"); 4681 } 4682 4683 // $SrcReg <= $OpReg is equal to (not ($OpReg < $SrcReg)) 4684 TOut.emitRRR(OpCode, DstReg, OpReg, SrcReg, IDLoc, STI); 4685 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI); 4686 4687 return false; 4688 } 4689 4690 bool MipsAsmParser::expandSleImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 4691 const MCSubtargetInfo *STI) { 4692 MipsTargetStreamer &TOut = getTargetStreamer(); 4693 4694 assert(Inst.getNumOperands() == 3 && "Invalid operand count"); 4695 assert(Inst.getOperand(0).isReg() && 4696 Inst.getOperand(1).isReg() && 4697 Inst.getOperand(2).isImm() && "Invalid instruction operand."); 4698 4699 unsigned DstReg = Inst.getOperand(0).getReg(); 4700 unsigned SrcReg = Inst.getOperand(1).getReg(); 4701 int64_t ImmValue = Inst.getOperand(2).getImm(); 4702 unsigned OpRegCode; 4703 4704 warnIfNoMacro(IDLoc); 4705 4706 switch (Inst.getOpcode()) { 4707 case Mips::SLEImm: 4708 case Mips::SLEImm64: 4709 OpRegCode = Mips::SLT; 4710 break; 4711 case Mips::SLEUImm: 4712 case Mips::SLEUImm64: 4713 OpRegCode = Mips::SLTu; 4714 break; 4715 default: 4716 llvm_unreachable("unexpected 'sge' opcode with immediate"); 4717 } 4718 4719 // $SrcReg <= Imm is equal to (not (Imm < $SrcReg)) 4720 unsigned ImmReg = DstReg; 4721 if (DstReg == SrcReg) { 4722 unsigned ATReg = getATReg(Inst.getLoc()); 4723 if (!ATReg) 4724 return true; 4725 ImmReg = ATReg; 4726 } 4727 4728 if (loadImmediate(ImmValue, ImmReg, Mips::NoRegister, isInt<32>(ImmValue), 4729 false, IDLoc, Out, STI)) 4730 return true; 4731 4732 TOut.emitRRR(OpRegCode, DstReg, ImmReg, SrcReg, IDLoc, STI); 4733 TOut.emitRRI(Mips::XORi, DstReg, DstReg, 1, IDLoc, STI); 4734 4735 return false; 4736 } 4737 4738 bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc, 4739 MCStreamer &Out, 4740 const MCSubtargetInfo *STI) { 4741 MipsTargetStreamer &TOut = getTargetStreamer(); 4742 4743 assert(Inst.getNumOperands() == 3 && "Invalid operand count"); 4744 assert(Inst.getOperand(0).isReg() && 4745 Inst.getOperand(1).isReg() && 4746 Inst.getOperand(2).isImm() && "Invalid instruction operand."); 4747 4748 unsigned ATReg = Mips::NoRegister; 4749 unsigned FinalDstReg = Mips::NoRegister; 4750 unsigned DstReg = Inst.getOperand(0).getReg(); 4751 unsigned SrcReg = Inst.getOperand(1).getReg(); 4752 int64_t ImmValue = Inst.getOperand(2).getImm(); 4753 4754 bool Is32Bit = isInt<32>(ImmValue) || (!isGP64bit() && isUInt<32>(ImmValue)); 4755 4756 unsigned FinalOpcode = Inst.getOpcode(); 4757 4758 if (DstReg == SrcReg) { 4759 ATReg = getATReg(Inst.getLoc()); 4760 if (!ATReg) 4761 return true; 4762 FinalDstReg = DstReg; 4763 DstReg = ATReg; 4764 } 4765 4766 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit, false, 4767 Inst.getLoc(), Out, STI)) { 4768 switch (FinalOpcode) { 4769 default: 4770 llvm_unreachable("unimplemented expansion"); 4771 case Mips::ADDi: 4772 FinalOpcode = Mips::ADD; 4773 break; 4774 case Mips::ADDiu: 4775 FinalOpcode = Mips::ADDu; 4776 break; 4777 case Mips::ANDi: 4778 FinalOpcode = Mips::AND; 4779 break; 4780 case Mips::NORImm: 4781 FinalOpcode = Mips::NOR; 4782 break; 4783 case Mips::ORi: 4784 FinalOpcode = Mips::OR; 4785 break; 4786 case Mips::SLTi: 4787 FinalOpcode = Mips::SLT; 4788 break; 4789 case Mips::SLTiu: 4790 FinalOpcode = Mips::SLTu; 4791 break; 4792 case Mips::XORi: 4793 FinalOpcode = Mips::XOR; 4794 break; 4795 case Mips::ADDi_MM: 4796 FinalOpcode = Mips::ADD_MM; 4797 break; 4798 case Mips::ADDiu_MM: 4799 FinalOpcode = Mips::ADDu_MM; 4800 break; 4801 case Mips::ANDi_MM: 4802 FinalOpcode = Mips::AND_MM; 4803 break; 4804 case Mips::ORi_MM: 4805 FinalOpcode = Mips::OR_MM; 4806 break; 4807 case Mips::SLTi_MM: 4808 FinalOpcode = Mips::SLT_MM; 4809 break; 4810 case Mips::SLTiu_MM: 4811 FinalOpcode = Mips::SLTu_MM; 4812 break; 4813 case Mips::XORi_MM: 4814 FinalOpcode = Mips::XOR_MM; 4815 break; 4816 case Mips::ANDi64: 4817 FinalOpcode = Mips::AND64; 4818 break; 4819 case Mips::NORImm64: 4820 FinalOpcode = Mips::NOR64; 4821 break; 4822 case Mips::ORi64: 4823 FinalOpcode = Mips::OR64; 4824 break; 4825 case Mips::SLTImm64: 4826 FinalOpcode = Mips::SLT64; 4827 break; 4828 case Mips::SLTUImm64: 4829 FinalOpcode = Mips::SLTu64; 4830 break; 4831 case Mips::XORi64: 4832 FinalOpcode = Mips::XOR64; 4833 break; 4834 } 4835 4836 if (FinalDstReg == Mips::NoRegister) 4837 TOut.emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI); 4838 else 4839 TOut.emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI); 4840 return false; 4841 } 4842 return true; 4843 } 4844 4845 bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 4846 const MCSubtargetInfo *STI) { 4847 MipsTargetStreamer &TOut = getTargetStreamer(); 4848 unsigned ATReg = Mips::NoRegister; 4849 unsigned DReg = Inst.getOperand(0).getReg(); 4850 unsigned SReg = Inst.getOperand(1).getReg(); 4851 unsigned TReg = Inst.getOperand(2).getReg(); 4852 unsigned TmpReg = DReg; 4853 4854 unsigned FirstShift = Mips::NOP; 4855 unsigned SecondShift = Mips::NOP; 4856 4857 if (hasMips32r2()) { 4858 if (DReg == SReg) { 4859 TmpReg = getATReg(Inst.getLoc()); 4860 if (!TmpReg) 4861 return true; 4862 } 4863 4864 if (Inst.getOpcode() == Mips::ROL) { 4865 TOut.emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI); 4866 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI); 4867 return false; 4868 } 4869 4870 if (Inst.getOpcode() == Mips::ROR) { 4871 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.getLoc(), STI); 4872 return false; 4873 } 4874 4875 return true; 4876 } 4877 4878 if (hasMips32()) { 4879 switch (Inst.getOpcode()) { 4880 default: 4881 llvm_unreachable("unexpected instruction opcode"); 4882 case Mips::ROL: 4883 FirstShift = Mips::SRLV; 4884 SecondShift = Mips::SLLV; 4885 break; 4886 case Mips::ROR: 4887 FirstShift = Mips::SLLV; 4888 SecondShift = Mips::SRLV; 4889 break; 4890 } 4891 4892 ATReg = getATReg(Inst.getLoc()); 4893 if (!ATReg) 4894 return true; 4895 4896 TOut.emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI); 4897 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI); 4898 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI); 4899 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI); 4900 4901 return false; 4902 } 4903 4904 return true; 4905 } 4906 4907 bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc, 4908 MCStreamer &Out, 4909 const MCSubtargetInfo *STI) { 4910 MipsTargetStreamer &TOut = getTargetStreamer(); 4911 unsigned ATReg = Mips::NoRegister; 4912 unsigned DReg = Inst.getOperand(0).getReg(); 4913 unsigned SReg = Inst.getOperand(1).getReg(); 4914 int64_t ImmValue = Inst.getOperand(2).getImm(); 4915 4916 unsigned FirstShift = Mips::NOP; 4917 unsigned SecondShift = Mips::NOP; 4918 4919 if (hasMips32r2()) { 4920 if (Inst.getOpcode() == Mips::ROLImm) { 4921 uint64_t MaxShift = 32; 4922 uint64_t ShiftValue = ImmValue; 4923 if (ImmValue != 0) 4924 ShiftValue = MaxShift - ImmValue; 4925 TOut.emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.getLoc(), STI); 4926 return false; 4927 } 4928 4929 if (Inst.getOpcode() == Mips::RORImm) { 4930 TOut.emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.getLoc(), STI); 4931 return false; 4932 } 4933 4934 return true; 4935 } 4936 4937 if (hasMips32()) { 4938 if (ImmValue == 0) { 4939 TOut.emitRRI(Mips::SRL, DReg, SReg, 0, Inst.getLoc(), STI); 4940 return false; 4941 } 4942 4943 switch (Inst.getOpcode()) { 4944 default: 4945 llvm_unreachable("unexpected instruction opcode"); 4946 case Mips::ROLImm: 4947 FirstShift = Mips::SLL; 4948 SecondShift = Mips::SRL; 4949 break; 4950 case Mips::RORImm: 4951 FirstShift = Mips::SRL; 4952 SecondShift = Mips::SLL; 4953 break; 4954 } 4955 4956 ATReg = getATReg(Inst.getLoc()); 4957 if (!ATReg) 4958 return true; 4959 4960 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.getLoc(), STI); 4961 TOut.emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.getLoc(), STI); 4962 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI); 4963 4964 return false; 4965 } 4966 4967 return true; 4968 } 4969 4970 bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 4971 const MCSubtargetInfo *STI) { 4972 MipsTargetStreamer &TOut = getTargetStreamer(); 4973 unsigned ATReg = Mips::NoRegister; 4974 unsigned DReg = Inst.getOperand(0).getReg(); 4975 unsigned SReg = Inst.getOperand(1).getReg(); 4976 unsigned TReg = Inst.getOperand(2).getReg(); 4977 unsigned TmpReg = DReg; 4978 4979 unsigned FirstShift = Mips::NOP; 4980 unsigned SecondShift = Mips::NOP; 4981 4982 if (hasMips64r2()) { 4983 if (TmpReg == SReg) { 4984 TmpReg = getATReg(Inst.getLoc()); 4985 if (!TmpReg) 4986 return true; 4987 } 4988 4989 if (Inst.getOpcode() == Mips::DROL) { 4990 TOut.emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI); 4991 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI); 4992 return false; 4993 } 4994 4995 if (Inst.getOpcode() == Mips::DROR) { 4996 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.getLoc(), STI); 4997 return false; 4998 } 4999 5000 return true; 5001 } 5002 5003 if (hasMips64()) { 5004 switch (Inst.getOpcode()) { 5005 default: 5006 llvm_unreachable("unexpected instruction opcode"); 5007 case Mips::DROL: 5008 FirstShift = Mips::DSRLV; 5009 SecondShift = Mips::DSLLV; 5010 break; 5011 case Mips::DROR: 5012 FirstShift = Mips::DSLLV; 5013 SecondShift = Mips::DSRLV; 5014 break; 5015 } 5016 5017 ATReg = getATReg(Inst.getLoc()); 5018 if (!ATReg) 5019 return true; 5020 5021 TOut.emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI); 5022 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI); 5023 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI); 5024 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI); 5025 5026 return false; 5027 } 5028 5029 return true; 5030 } 5031 5032 bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc, 5033 MCStreamer &Out, 5034 const MCSubtargetInfo *STI) { 5035 MipsTargetStreamer &TOut = getTargetStreamer(); 5036 unsigned ATReg = Mips::NoRegister; 5037 unsigned DReg = Inst.getOperand(0).getReg(); 5038 unsigned SReg = Inst.getOperand(1).getReg(); 5039 int64_t ImmValue = Inst.getOperand(2).getImm() % 64; 5040 5041 unsigned FirstShift = Mips::NOP; 5042 unsigned SecondShift = Mips::NOP; 5043 5044 MCInst TmpInst; 5045 5046 if (hasMips64r2()) { 5047 unsigned FinalOpcode = Mips::NOP; 5048 if (ImmValue == 0) 5049 FinalOpcode = Mips::DROTR; 5050 else if (ImmValue % 32 == 0) 5051 FinalOpcode = Mips::DROTR32; 5052 else if ((ImmValue >= 1) && (ImmValue <= 32)) { 5053 if (Inst.getOpcode() == Mips::DROLImm) 5054 FinalOpcode = Mips::DROTR32; 5055 else 5056 FinalOpcode = Mips::DROTR; 5057 } else if (ImmValue >= 33) { 5058 if (Inst.getOpcode() == Mips::DROLImm) 5059 FinalOpcode = Mips::DROTR; 5060 else 5061 FinalOpcode = Mips::DROTR32; 5062 } 5063 5064 uint64_t ShiftValue = ImmValue % 32; 5065 if (Inst.getOpcode() == Mips::DROLImm) 5066 ShiftValue = (32 - ImmValue % 32) % 32; 5067 5068 TOut.emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.getLoc(), STI); 5069 5070 return false; 5071 } 5072 5073 if (hasMips64()) { 5074 if (ImmValue == 0) { 5075 TOut.emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.getLoc(), STI); 5076 return false; 5077 } 5078 5079 switch (Inst.getOpcode()) { 5080 default: 5081 llvm_unreachable("unexpected instruction opcode"); 5082 case Mips::DROLImm: 5083 if ((ImmValue >= 1) && (ImmValue <= 31)) { 5084 FirstShift = Mips::DSLL; 5085 SecondShift = Mips::DSRL32; 5086 } 5087 if (ImmValue == 32) { 5088 FirstShift = Mips::DSLL32; 5089 SecondShift = Mips::DSRL32; 5090 } 5091 if ((ImmValue >= 33) && (ImmValue <= 63)) { 5092 FirstShift = Mips::DSLL32; 5093 SecondShift = Mips::DSRL; 5094 } 5095 break; 5096 case Mips::DRORImm: 5097 if ((ImmValue >= 1) && (ImmValue <= 31)) { 5098 FirstShift = Mips::DSRL; 5099 SecondShift = Mips::DSLL32; 5100 } 5101 if (ImmValue == 32) { 5102 FirstShift = Mips::DSRL32; 5103 SecondShift = Mips::DSLL32; 5104 } 5105 if ((ImmValue >= 33) && (ImmValue <= 63)) { 5106 FirstShift = Mips::DSRL32; 5107 SecondShift = Mips::DSLL; 5108 } 5109 break; 5110 } 5111 5112 ATReg = getATReg(Inst.getLoc()); 5113 if (!ATReg) 5114 return true; 5115 5116 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.getLoc(), STI); 5117 TOut.emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32, 5118 Inst.getLoc(), STI); 5119 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI); 5120 5121 return false; 5122 } 5123 5124 return true; 5125 } 5126 5127 bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 5128 const MCSubtargetInfo *STI) { 5129 MipsTargetStreamer &TOut = getTargetStreamer(); 5130 unsigned FirstRegOp = Inst.getOperand(0).getReg(); 5131 unsigned SecondRegOp = Inst.getOperand(1).getReg(); 5132 5133 TOut.emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI); 5134 if (FirstRegOp != SecondRegOp) 5135 TOut.emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI); 5136 else 5137 TOut.emitEmptyDelaySlot(false, IDLoc, STI); 5138 TOut.emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI); 5139 5140 return false; 5141 } 5142 5143 bool MipsAsmParser::expandMulImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 5144 const MCSubtargetInfo *STI) { 5145 MipsTargetStreamer &TOut = getTargetStreamer(); 5146 unsigned ATReg = Mips::NoRegister; 5147 unsigned DstReg = Inst.getOperand(0).getReg(); 5148 unsigned SrcReg = Inst.getOperand(1).getReg(); 5149 int32_t ImmValue = Inst.getOperand(2).getImm(); 5150 5151 ATReg = getATReg(IDLoc); 5152 if (!ATReg) 5153 return true; 5154 5155 loadImmediate(ImmValue, ATReg, Mips::NoRegister, true, false, IDLoc, Out, 5156 STI); 5157 5158 TOut.emitRR(Inst.getOpcode() == Mips::MULImmMacro ? Mips::MULT : Mips::DMULT, 5159 SrcReg, ATReg, IDLoc, STI); 5160 5161 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI); 5162 5163 return false; 5164 } 5165 5166 bool MipsAsmParser::expandMulO(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 5167 const MCSubtargetInfo *STI) { 5168 MipsTargetStreamer &TOut = getTargetStreamer(); 5169 unsigned ATReg = Mips::NoRegister; 5170 unsigned DstReg = Inst.getOperand(0).getReg(); 5171 unsigned SrcReg = Inst.getOperand(1).getReg(); 5172 unsigned TmpReg = Inst.getOperand(2).getReg(); 5173 5174 ATReg = getATReg(Inst.getLoc()); 5175 if (!ATReg) 5176 return true; 5177 5178 TOut.emitRR(Inst.getOpcode() == Mips::MULOMacro ? Mips::MULT : Mips::DMULT, 5179 SrcReg, TmpReg, IDLoc, STI); 5180 5181 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI); 5182 5183 TOut.emitRRI(Inst.getOpcode() == Mips::MULOMacro ? Mips::SRA : Mips::DSRA32, 5184 DstReg, DstReg, 0x1F, IDLoc, STI); 5185 5186 TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI); 5187 5188 if (useTraps()) { 5189 TOut.emitRRI(Mips::TNE, DstReg, ATReg, 6, IDLoc, STI); 5190 } else { 5191 MCContext & Context = TOut.getStreamer().getContext(); 5192 MCSymbol * BrTarget = Context.createTempSymbol(); 5193 MCOperand LabelOp = 5194 MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context)); 5195 5196 TOut.emitRRX(Mips::BEQ, DstReg, ATReg, LabelOp, IDLoc, STI); 5197 if (AssemblerOptions.back()->isReorder()) 5198 TOut.emitNop(IDLoc, STI); 5199 TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI); 5200 5201 TOut.getStreamer().emitLabel(BrTarget); 5202 } 5203 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI); 5204 5205 return false; 5206 } 5207 5208 bool MipsAsmParser::expandMulOU(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 5209 const MCSubtargetInfo *STI) { 5210 MipsTargetStreamer &TOut = getTargetStreamer(); 5211 unsigned ATReg = Mips::NoRegister; 5212 unsigned DstReg = Inst.getOperand(0).getReg(); 5213 unsigned SrcReg = Inst.getOperand(1).getReg(); 5214 unsigned TmpReg = Inst.getOperand(2).getReg(); 5215 5216 ATReg = getATReg(IDLoc); 5217 if (!ATReg) 5218 return true; 5219 5220 TOut.emitRR(Inst.getOpcode() == Mips::MULOUMacro ? Mips::MULTu : Mips::DMULTu, 5221 SrcReg, TmpReg, IDLoc, STI); 5222 5223 TOut.emitR(Mips::MFHI, ATReg, IDLoc, STI); 5224 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI); 5225 if (useTraps()) { 5226 TOut.emitRRI(Mips::TNE, ATReg, Mips::ZERO, 6, IDLoc, STI); 5227 } else { 5228 MCContext & Context = TOut.getStreamer().getContext(); 5229 MCSymbol * BrTarget = Context.createTempSymbol(); 5230 MCOperand LabelOp = 5231 MCOperand::createExpr(MCSymbolRefExpr::create(BrTarget, Context)); 5232 5233 TOut.emitRRX(Mips::BEQ, ATReg, Mips::ZERO, LabelOp, IDLoc, STI); 5234 if (AssemblerOptions.back()->isReorder()) 5235 TOut.emitNop(IDLoc, STI); 5236 TOut.emitII(Mips::BREAK, 6, 0, IDLoc, STI); 5237 5238 TOut.getStreamer().emitLabel(BrTarget); 5239 } 5240 5241 return false; 5242 } 5243 5244 bool MipsAsmParser::expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 5245 const MCSubtargetInfo *STI) { 5246 MipsTargetStreamer &TOut = getTargetStreamer(); 5247 unsigned DstReg = Inst.getOperand(0).getReg(); 5248 unsigned SrcReg = Inst.getOperand(1).getReg(); 5249 unsigned TmpReg = Inst.getOperand(2).getReg(); 5250 5251 TOut.emitRR(Mips::DMULTu, SrcReg, TmpReg, IDLoc, STI); 5252 TOut.emitR(Mips::MFLO, DstReg, IDLoc, STI); 5253 5254 return false; 5255 } 5256 5257 // Expand 'ld $<reg> offset($reg2)' to 'lw $<reg>, offset($reg2); 5258 // lw $<reg+1>>, offset+4($reg2)' 5259 // or expand 'sd $<reg> offset($reg2)' to 'sw $<reg>, offset($reg2); 5260 // sw $<reg+1>>, offset+4($reg2)' 5261 // for O32. 5262 bool MipsAsmParser::expandLoadStoreDMacro(MCInst &Inst, SMLoc IDLoc, 5263 MCStreamer &Out, 5264 const MCSubtargetInfo *STI, 5265 bool IsLoad) { 5266 if (!isABI_O32()) 5267 return true; 5268 5269 warnIfNoMacro(IDLoc); 5270 5271 MipsTargetStreamer &TOut = getTargetStreamer(); 5272 unsigned Opcode = IsLoad ? Mips::LW : Mips::SW; 5273 unsigned FirstReg = Inst.getOperand(0).getReg(); 5274 unsigned SecondReg = nextReg(FirstReg); 5275 unsigned BaseReg = Inst.getOperand(1).getReg(); 5276 if (!SecondReg) 5277 return true; 5278 5279 warnIfRegIndexIsAT(FirstReg, IDLoc); 5280 5281 assert(Inst.getOperand(2).isImm() && 5282 "Offset for load macro is not immediate!"); 5283 5284 MCOperand &FirstOffset = Inst.getOperand(2); 5285 signed NextOffset = FirstOffset.getImm() + 4; 5286 MCOperand SecondOffset = MCOperand::createImm(NextOffset); 5287 5288 if (!isInt<16>(FirstOffset.getImm()) || !isInt<16>(NextOffset)) 5289 return true; 5290 5291 // For loads, clobber the base register with the second load instead of the 5292 // first if the BaseReg == FirstReg. 5293 if (FirstReg != BaseReg || !IsLoad) { 5294 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI); 5295 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI); 5296 } else { 5297 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI); 5298 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI); 5299 } 5300 5301 return false; 5302 } 5303 5304 5305 // Expand 's.d $<reg> offset($reg2)' to 'swc1 $<reg+1>, offset($reg2); 5306 // swc1 $<reg>, offset+4($reg2)' 5307 // or if little endian to 'swc1 $<reg>, offset($reg2); 5308 // swc1 $<reg+1>, offset+4($reg2)' 5309 // for Mips1. 5310 bool MipsAsmParser::expandStoreDM1Macro(MCInst &Inst, SMLoc IDLoc, 5311 MCStreamer &Out, 5312 const MCSubtargetInfo *STI) { 5313 if (!isABI_O32()) 5314 return true; 5315 5316 warnIfNoMacro(IDLoc); 5317 5318 MipsTargetStreamer &TOut = getTargetStreamer(); 5319 unsigned Opcode = Mips::SWC1; 5320 unsigned FirstReg = Inst.getOperand(0).getReg(); 5321 unsigned SecondReg = nextReg(FirstReg); 5322 unsigned BaseReg = Inst.getOperand(1).getReg(); 5323 if (!SecondReg) 5324 return true; 5325 5326 warnIfRegIndexIsAT(FirstReg, IDLoc); 5327 5328 assert(Inst.getOperand(2).isImm() && 5329 "Offset for macro is not immediate!"); 5330 5331 MCOperand &FirstOffset = Inst.getOperand(2); 5332 signed NextOffset = FirstOffset.getImm() + 4; 5333 MCOperand SecondOffset = MCOperand::createImm(NextOffset); 5334 5335 if (!isInt<16>(FirstOffset.getImm()) || !isInt<16>(NextOffset)) 5336 return true; 5337 5338 if (!IsLittleEndian) 5339 std::swap(FirstReg, SecondReg); 5340 5341 TOut.emitRRX(Opcode, FirstReg, BaseReg, FirstOffset, IDLoc, STI); 5342 TOut.emitRRX(Opcode, SecondReg, BaseReg, SecondOffset, IDLoc, STI); 5343 5344 return false; 5345 } 5346 5347 bool MipsAsmParser::expandSeq(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 5348 const MCSubtargetInfo *STI) { 5349 MipsTargetStreamer &TOut = getTargetStreamer(); 5350 5351 assert(Inst.getNumOperands() == 3 && "Invalid operand count"); 5352 assert(Inst.getOperand(0).isReg() && 5353 Inst.getOperand(1).isReg() && 5354 Inst.getOperand(2).isReg() && "Invalid instruction operand."); 5355 5356 unsigned DstReg = Inst.getOperand(0).getReg(); 5357 unsigned SrcReg = Inst.getOperand(1).getReg(); 5358 unsigned OpReg = Inst.getOperand(2).getReg(); 5359 5360 warnIfNoMacro(IDLoc); 5361 5362 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) { 5363 TOut.emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI); 5364 TOut.emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI); 5365 return false; 5366 } 5367 5368 unsigned Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg; 5369 TOut.emitRRI(Mips::SLTiu, DstReg, Reg, 1, IDLoc, STI); 5370 return false; 5371 } 5372 5373 bool MipsAsmParser::expandSeqI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 5374 const MCSubtargetInfo *STI) { 5375 MipsTargetStreamer &TOut = getTargetStreamer(); 5376 5377 assert(Inst.getNumOperands() == 3 && "Invalid operand count"); 5378 assert(Inst.getOperand(0).isReg() && 5379 Inst.getOperand(1).isReg() && 5380 Inst.getOperand(2).isImm() && "Invalid instruction operand."); 5381 5382 unsigned DstReg = Inst.getOperand(0).getReg(); 5383 unsigned SrcReg = Inst.getOperand(1).getReg(); 5384 int64_t Imm = Inst.getOperand(2).getImm(); 5385 5386 warnIfNoMacro(IDLoc); 5387 5388 if (Imm == 0) { 5389 TOut.emitRRI(Mips::SLTiu, DstReg, SrcReg, 1, IDLoc, STI); 5390 return false; 5391 } 5392 5393 if (SrcReg == Mips::ZERO) { 5394 Warning(IDLoc, "comparison is always false"); 5395 TOut.emitRRR(isGP64bit() ? Mips::DADDu : Mips::ADDu, 5396 DstReg, SrcReg, SrcReg, IDLoc, STI); 5397 return false; 5398 } 5399 5400 unsigned Opc; 5401 if (Imm > -0x8000 && Imm < 0) { 5402 Imm = -Imm; 5403 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu; 5404 } else { 5405 Opc = Mips::XORi; 5406 } 5407 5408 if (!isUInt<16>(Imm)) { 5409 unsigned ATReg = getATReg(IDLoc); 5410 if (!ATReg) 5411 return true; 5412 5413 if (loadImmediate(Imm, ATReg, Mips::NoRegister, true, isGP64bit(), IDLoc, 5414 Out, STI)) 5415 return true; 5416 5417 TOut.emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI); 5418 TOut.emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI); 5419 return false; 5420 } 5421 5422 TOut.emitRRI(Opc, DstReg, SrcReg, Imm, IDLoc, STI); 5423 TOut.emitRRI(Mips::SLTiu, DstReg, DstReg, 1, IDLoc, STI); 5424 return false; 5425 } 5426 5427 bool MipsAsmParser::expandSne(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 5428 const MCSubtargetInfo *STI) { 5429 5430 MipsTargetStreamer &TOut = getTargetStreamer(); 5431 5432 assert(Inst.getNumOperands() == 3 && "Invalid operand count"); 5433 assert(Inst.getOperand(0).isReg() && 5434 Inst.getOperand(1).isReg() && 5435 Inst.getOperand(2).isReg() && "Invalid instruction operand."); 5436 5437 unsigned DstReg = Inst.getOperand(0).getReg(); 5438 unsigned SrcReg = Inst.getOperand(1).getReg(); 5439 unsigned OpReg = Inst.getOperand(2).getReg(); 5440 5441 warnIfNoMacro(IDLoc); 5442 5443 if (SrcReg != Mips::ZERO && OpReg != Mips::ZERO) { 5444 TOut.emitRRR(Mips::XOR, DstReg, SrcReg, OpReg, IDLoc, STI); 5445 TOut.emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI); 5446 return false; 5447 } 5448 5449 unsigned Reg = SrcReg == Mips::ZERO ? OpReg : SrcReg; 5450 TOut.emitRRR(Mips::SLTu, DstReg, Mips::ZERO, Reg, IDLoc, STI); 5451 return false; 5452 } 5453 5454 bool MipsAsmParser::expandSneI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 5455 const MCSubtargetInfo *STI) { 5456 MipsTargetStreamer &TOut = getTargetStreamer(); 5457 5458 assert(Inst.getNumOperands() == 3 && "Invalid operand count"); 5459 assert(Inst.getOperand(0).isReg() && 5460 Inst.getOperand(1).isReg() && 5461 Inst.getOperand(2).isImm() && "Invalid instruction operand."); 5462 5463 unsigned DstReg = Inst.getOperand(0).getReg(); 5464 unsigned SrcReg = Inst.getOperand(1).getReg(); 5465 int64_t ImmValue = Inst.getOperand(2).getImm(); 5466 5467 warnIfNoMacro(IDLoc); 5468 5469 if (ImmValue == 0) { 5470 TOut.emitRRR(Mips::SLTu, DstReg, Mips::ZERO, SrcReg, IDLoc, STI); 5471 return false; 5472 } 5473 5474 if (SrcReg == Mips::ZERO) { 5475 Warning(IDLoc, "comparison is always true"); 5476 if (loadImmediate(1, DstReg, Mips::NoRegister, true, false, IDLoc, Out, 5477 STI)) 5478 return true; 5479 return false; 5480 } 5481 5482 unsigned Opc; 5483 if (ImmValue > -0x8000 && ImmValue < 0) { 5484 ImmValue = -ImmValue; 5485 Opc = isGP64bit() ? Mips::DADDiu : Mips::ADDiu; 5486 } else { 5487 Opc = Mips::XORi; 5488 } 5489 5490 if (isUInt<16>(ImmValue)) { 5491 TOut.emitRRI(Opc, DstReg, SrcReg, ImmValue, IDLoc, STI); 5492 TOut.emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI); 5493 return false; 5494 } 5495 5496 unsigned ATReg = getATReg(IDLoc); 5497 if (!ATReg) 5498 return true; 5499 5500 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, isInt<32>(ImmValue), 5501 false, IDLoc, Out, STI)) 5502 return true; 5503 5504 TOut.emitRRR(Mips::XOR, DstReg, SrcReg, ATReg, IDLoc, STI); 5505 TOut.emitRRR(Mips::SLTu, DstReg, Mips::ZERO, DstReg, IDLoc, STI); 5506 return false; 5507 } 5508 5509 // Map the DSP accumulator and control register to the corresponding gpr 5510 // operand. Unlike the other alias, the m(f|t)t(lo|hi|acx) instructions 5511 // do not map the DSP registers contigously to gpr registers. 5512 static unsigned getRegisterForMxtrDSP(MCInst &Inst, bool IsMFDSP) { 5513 switch (Inst.getOpcode()) { 5514 case Mips::MFTLO: 5515 case Mips::MTTLO: 5516 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) { 5517 case Mips::AC0: 5518 return Mips::ZERO; 5519 case Mips::AC1: 5520 return Mips::A0; 5521 case Mips::AC2: 5522 return Mips::T0; 5523 case Mips::AC3: 5524 return Mips::T4; 5525 default: 5526 llvm_unreachable("Unknown register for 'mttr' alias!"); 5527 } 5528 case Mips::MFTHI: 5529 case Mips::MTTHI: 5530 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) { 5531 case Mips::AC0: 5532 return Mips::AT; 5533 case Mips::AC1: 5534 return Mips::A1; 5535 case Mips::AC2: 5536 return Mips::T1; 5537 case Mips::AC3: 5538 return Mips::T5; 5539 default: 5540 llvm_unreachable("Unknown register for 'mttr' alias!"); 5541 } 5542 case Mips::MFTACX: 5543 case Mips::MTTACX: 5544 switch (Inst.getOperand(IsMFDSP ? 1 : 0).getReg()) { 5545 case Mips::AC0: 5546 return Mips::V0; 5547 case Mips::AC1: 5548 return Mips::A2; 5549 case Mips::AC2: 5550 return Mips::T2; 5551 case Mips::AC3: 5552 return Mips::T6; 5553 default: 5554 llvm_unreachable("Unknown register for 'mttr' alias!"); 5555 } 5556 case Mips::MFTDSP: 5557 case Mips::MTTDSP: 5558 return Mips::S0; 5559 default: 5560 llvm_unreachable("Unknown instruction for 'mttr' dsp alias!"); 5561 } 5562 } 5563 5564 // Map the floating point register operand to the corresponding register 5565 // operand. 5566 static unsigned getRegisterForMxtrFP(MCInst &Inst, bool IsMFTC1) { 5567 switch (Inst.getOperand(IsMFTC1 ? 1 : 0).getReg()) { 5568 case Mips::F0: return Mips::ZERO; 5569 case Mips::F1: return Mips::AT; 5570 case Mips::F2: return Mips::V0; 5571 case Mips::F3: return Mips::V1; 5572 case Mips::F4: return Mips::A0; 5573 case Mips::F5: return Mips::A1; 5574 case Mips::F6: return Mips::A2; 5575 case Mips::F7: return Mips::A3; 5576 case Mips::F8: return Mips::T0; 5577 case Mips::F9: return Mips::T1; 5578 case Mips::F10: return Mips::T2; 5579 case Mips::F11: return Mips::T3; 5580 case Mips::F12: return Mips::T4; 5581 case Mips::F13: return Mips::T5; 5582 case Mips::F14: return Mips::T6; 5583 case Mips::F15: return Mips::T7; 5584 case Mips::F16: return Mips::S0; 5585 case Mips::F17: return Mips::S1; 5586 case Mips::F18: return Mips::S2; 5587 case Mips::F19: return Mips::S3; 5588 case Mips::F20: return Mips::S4; 5589 case Mips::F21: return Mips::S5; 5590 case Mips::F22: return Mips::S6; 5591 case Mips::F23: return Mips::S7; 5592 case Mips::F24: return Mips::T8; 5593 case Mips::F25: return Mips::T9; 5594 case Mips::F26: return Mips::K0; 5595 case Mips::F27: return Mips::K1; 5596 case Mips::F28: return Mips::GP; 5597 case Mips::F29: return Mips::SP; 5598 case Mips::F30: return Mips::FP; 5599 case Mips::F31: return Mips::RA; 5600 default: llvm_unreachable("Unknown register for mttc1 alias!"); 5601 } 5602 } 5603 5604 // Map the coprocessor operand the corresponding gpr register operand. 5605 static unsigned getRegisterForMxtrC0(MCInst &Inst, bool IsMFTC0) { 5606 switch (Inst.getOperand(IsMFTC0 ? 1 : 0).getReg()) { 5607 case Mips::COP00: return Mips::ZERO; 5608 case Mips::COP01: return Mips::AT; 5609 case Mips::COP02: return Mips::V0; 5610 case Mips::COP03: return Mips::V1; 5611 case Mips::COP04: return Mips::A0; 5612 case Mips::COP05: return Mips::A1; 5613 case Mips::COP06: return Mips::A2; 5614 case Mips::COP07: return Mips::A3; 5615 case Mips::COP08: return Mips::T0; 5616 case Mips::COP09: return Mips::T1; 5617 case Mips::COP010: return Mips::T2; 5618 case Mips::COP011: return Mips::T3; 5619 case Mips::COP012: return Mips::T4; 5620 case Mips::COP013: return Mips::T5; 5621 case Mips::COP014: return Mips::T6; 5622 case Mips::COP015: return Mips::T7; 5623 case Mips::COP016: return Mips::S0; 5624 case Mips::COP017: return Mips::S1; 5625 case Mips::COP018: return Mips::S2; 5626 case Mips::COP019: return Mips::S3; 5627 case Mips::COP020: return Mips::S4; 5628 case Mips::COP021: return Mips::S5; 5629 case Mips::COP022: return Mips::S6; 5630 case Mips::COP023: return Mips::S7; 5631 case Mips::COP024: return Mips::T8; 5632 case Mips::COP025: return Mips::T9; 5633 case Mips::COP026: return Mips::K0; 5634 case Mips::COP027: return Mips::K1; 5635 case Mips::COP028: return Mips::GP; 5636 case Mips::COP029: return Mips::SP; 5637 case Mips::COP030: return Mips::FP; 5638 case Mips::COP031: return Mips::RA; 5639 default: llvm_unreachable("Unknown register for mttc0 alias!"); 5640 } 5641 } 5642 5643 /// Expand an alias of 'mftr' or 'mttr' into the full instruction, by producing 5644 /// an mftr or mttr with the correctly mapped gpr register, u, sel and h bits. 5645 bool MipsAsmParser::expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 5646 const MCSubtargetInfo *STI) { 5647 MipsTargetStreamer &TOut = getTargetStreamer(); 5648 unsigned rd = 0; 5649 unsigned u = 1; 5650 unsigned sel = 0; 5651 unsigned h = 0; 5652 bool IsMFTR = false; 5653 switch (Inst.getOpcode()) { 5654 case Mips::MFTC0: 5655 IsMFTR = true; 5656 [[fallthrough]]; 5657 case Mips::MTTC0: 5658 u = 0; 5659 rd = getRegisterForMxtrC0(Inst, IsMFTR); 5660 sel = Inst.getOperand(2).getImm(); 5661 break; 5662 case Mips::MFTGPR: 5663 IsMFTR = true; 5664 [[fallthrough]]; 5665 case Mips::MTTGPR: 5666 rd = Inst.getOperand(IsMFTR ? 1 : 0).getReg(); 5667 break; 5668 case Mips::MFTLO: 5669 case Mips::MFTHI: 5670 case Mips::MFTACX: 5671 case Mips::MFTDSP: 5672 IsMFTR = true; 5673 [[fallthrough]]; 5674 case Mips::MTTLO: 5675 case Mips::MTTHI: 5676 case Mips::MTTACX: 5677 case Mips::MTTDSP: 5678 rd = getRegisterForMxtrDSP(Inst, IsMFTR); 5679 sel = 1; 5680 break; 5681 case Mips::MFTHC1: 5682 h = 1; 5683 [[fallthrough]]; 5684 case Mips::MFTC1: 5685 IsMFTR = true; 5686 rd = getRegisterForMxtrFP(Inst, IsMFTR); 5687 sel = 2; 5688 break; 5689 case Mips::MTTHC1: 5690 h = 1; 5691 [[fallthrough]]; 5692 case Mips::MTTC1: 5693 rd = getRegisterForMxtrFP(Inst, IsMFTR); 5694 sel = 2; 5695 break; 5696 case Mips::CFTC1: 5697 IsMFTR = true; 5698 [[fallthrough]]; 5699 case Mips::CTTC1: 5700 rd = getRegisterForMxtrFP(Inst, IsMFTR); 5701 sel = 3; 5702 break; 5703 } 5704 unsigned Op0 = IsMFTR ? Inst.getOperand(0).getReg() : rd; 5705 unsigned Op1 = 5706 IsMFTR ? rd 5707 : (Inst.getOpcode() != Mips::MTTDSP ? Inst.getOperand(1).getReg() 5708 : Inst.getOperand(0).getReg()); 5709 5710 TOut.emitRRIII(IsMFTR ? Mips::MFTR : Mips::MTTR, Op0, Op1, u, sel, h, IDLoc, 5711 STI); 5712 return false; 5713 } 5714 5715 bool MipsAsmParser::expandSaaAddr(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 5716 const MCSubtargetInfo *STI) { 5717 assert(Inst.getNumOperands() == 3 && "expected three operands"); 5718 assert(Inst.getOperand(0).isReg() && "expected register operand kind"); 5719 assert(Inst.getOperand(1).isReg() && "expected register operand kind"); 5720 5721 warnIfNoMacro(IDLoc); 5722 5723 MipsTargetStreamer &TOut = getTargetStreamer(); 5724 unsigned Opcode = Inst.getOpcode() == Mips::SaaAddr ? Mips::SAA : Mips::SAAD; 5725 unsigned RtReg = Inst.getOperand(0).getReg(); 5726 unsigned BaseReg = Inst.getOperand(1).getReg(); 5727 const MCOperand &BaseOp = Inst.getOperand(2); 5728 5729 if (BaseOp.isImm()) { 5730 int64_t ImmValue = BaseOp.getImm(); 5731 if (ImmValue == 0) { 5732 TOut.emitRR(Opcode, RtReg, BaseReg, IDLoc, STI); 5733 return false; 5734 } 5735 } 5736 5737 unsigned ATReg = getATReg(IDLoc); 5738 if (!ATReg) 5739 return true; 5740 5741 if (expandLoadAddress(ATReg, BaseReg, BaseOp, !isGP64bit(), IDLoc, Out, STI)) 5742 return true; 5743 5744 TOut.emitRR(Opcode, RtReg, ATReg, IDLoc, STI); 5745 return false; 5746 } 5747 5748 unsigned 5749 MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst, 5750 const OperandVector &Operands) { 5751 switch (Inst.getOpcode()) { 5752 default: 5753 return Match_Success; 5754 case Mips::DATI: 5755 case Mips::DAHI: 5756 if (static_cast<MipsOperand &>(*Operands[1]) 5757 .isValidForTie(static_cast<MipsOperand &>(*Operands[2]))) 5758 return Match_Success; 5759 return Match_RequiresSameSrcAndDst; 5760 } 5761 } 5762 5763 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) { 5764 switch (Inst.getOpcode()) { 5765 // As described by the MIPSR6 spec, daui must not use the zero operand for 5766 // its source operand. 5767 case Mips::DAUI: 5768 if (Inst.getOperand(1).getReg() == Mips::ZERO || 5769 Inst.getOperand(1).getReg() == Mips::ZERO_64) 5770 return Match_RequiresNoZeroRegister; 5771 return Match_Success; 5772 // As described by the Mips32r2 spec, the registers Rd and Rs for 5773 // jalr.hb must be different. 5774 // It also applies for registers Rt and Rs of microMIPSr6 jalrc.hb instruction 5775 // and registers Rd and Base for microMIPS lwp instruction 5776 case Mips::JALR_HB: 5777 case Mips::JALR_HB64: 5778 case Mips::JALRC_HB_MMR6: 5779 case Mips::JALRC_MMR6: 5780 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()) 5781 return Match_RequiresDifferentSrcAndDst; 5782 return Match_Success; 5783 case Mips::LWP_MM: 5784 if (Inst.getOperand(0).getReg() == Inst.getOperand(2).getReg()) 5785 return Match_RequiresDifferentSrcAndDst; 5786 return Match_Success; 5787 case Mips::SYNC: 5788 if (Inst.getOperand(0).getImm() != 0 && !hasMips32()) 5789 return Match_NonZeroOperandForSync; 5790 return Match_Success; 5791 case Mips::MFC0: 5792 case Mips::MTC0: 5793 case Mips::MTC2: 5794 case Mips::MFC2: 5795 if (Inst.getOperand(2).getImm() != 0 && !hasMips32()) 5796 return Match_NonZeroOperandForMTCX; 5797 return Match_Success; 5798 // As described the MIPSR6 spec, the compact branches that compare registers 5799 // must: 5800 // a) Not use the zero register. 5801 // b) Not use the same register twice. 5802 // c) rs < rt for bnec, beqc. 5803 // NB: For this case, the encoding will swap the operands as their 5804 // ordering doesn't matter. GAS performs this transformation too. 5805 // Hence, that constraint does not have to be enforced. 5806 // 5807 // The compact branches that branch iff the signed addition of two registers 5808 // would overflow must have rs >= rt. That can be handled like beqc/bnec with 5809 // operand swapping. They do not have restriction of using the zero register. 5810 case Mips::BLEZC: case Mips::BLEZC_MMR6: 5811 case Mips::BGEZC: case Mips::BGEZC_MMR6: 5812 case Mips::BGTZC: case Mips::BGTZC_MMR6: 5813 case Mips::BLTZC: case Mips::BLTZC_MMR6: 5814 case Mips::BEQZC: case Mips::BEQZC_MMR6: 5815 case Mips::BNEZC: case Mips::BNEZC_MMR6: 5816 case Mips::BLEZC64: 5817 case Mips::BGEZC64: 5818 case Mips::BGTZC64: 5819 case Mips::BLTZC64: 5820 case Mips::BEQZC64: 5821 case Mips::BNEZC64: 5822 if (Inst.getOperand(0).getReg() == Mips::ZERO || 5823 Inst.getOperand(0).getReg() == Mips::ZERO_64) 5824 return Match_RequiresNoZeroRegister; 5825 return Match_Success; 5826 case Mips::BGEC: case Mips::BGEC_MMR6: 5827 case Mips::BLTC: case Mips::BLTC_MMR6: 5828 case Mips::BGEUC: case Mips::BGEUC_MMR6: 5829 case Mips::BLTUC: case Mips::BLTUC_MMR6: 5830 case Mips::BEQC: case Mips::BEQC_MMR6: 5831 case Mips::BNEC: case Mips::BNEC_MMR6: 5832 case Mips::BGEC64: 5833 case Mips::BLTC64: 5834 case Mips::BGEUC64: 5835 case Mips::BLTUC64: 5836 case Mips::BEQC64: 5837 case Mips::BNEC64: 5838 if (Inst.getOperand(0).getReg() == Mips::ZERO || 5839 Inst.getOperand(0).getReg() == Mips::ZERO_64) 5840 return Match_RequiresNoZeroRegister; 5841 if (Inst.getOperand(1).getReg() == Mips::ZERO || 5842 Inst.getOperand(1).getReg() == Mips::ZERO_64) 5843 return Match_RequiresNoZeroRegister; 5844 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()) 5845 return Match_RequiresDifferentOperands; 5846 return Match_Success; 5847 case Mips::DINS: { 5848 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() && 5849 "Operands must be immediates for dins!"); 5850 const signed Pos = Inst.getOperand(2).getImm(); 5851 const signed Size = Inst.getOperand(3).getImm(); 5852 if ((0 > (Pos + Size)) || ((Pos + Size) > 32)) 5853 return Match_RequiresPosSizeRange0_32; 5854 return Match_Success; 5855 } 5856 case Mips::DINSM: 5857 case Mips::DINSU: { 5858 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() && 5859 "Operands must be immediates for dinsm/dinsu!"); 5860 const signed Pos = Inst.getOperand(2).getImm(); 5861 const signed Size = Inst.getOperand(3).getImm(); 5862 if ((32 >= (Pos + Size)) || ((Pos + Size) > 64)) 5863 return Match_RequiresPosSizeRange33_64; 5864 return Match_Success; 5865 } 5866 case Mips::DEXT: { 5867 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() && 5868 "Operands must be immediates for DEXTM!"); 5869 const signed Pos = Inst.getOperand(2).getImm(); 5870 const signed Size = Inst.getOperand(3).getImm(); 5871 if ((1 > (Pos + Size)) || ((Pos + Size) > 63)) 5872 return Match_RequiresPosSizeUImm6; 5873 return Match_Success; 5874 } 5875 case Mips::DEXTM: 5876 case Mips::DEXTU: { 5877 assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() && 5878 "Operands must be immediates for dextm/dextu!"); 5879 const signed Pos = Inst.getOperand(2).getImm(); 5880 const signed Size = Inst.getOperand(3).getImm(); 5881 if ((32 > (Pos + Size)) || ((Pos + Size) > 64)) 5882 return Match_RequiresPosSizeRange33_64; 5883 return Match_Success; 5884 } 5885 case Mips::CRC32B: case Mips::CRC32CB: 5886 case Mips::CRC32H: case Mips::CRC32CH: 5887 case Mips::CRC32W: case Mips::CRC32CW: 5888 case Mips::CRC32D: case Mips::CRC32CD: 5889 if (Inst.getOperand(0).getReg() != Inst.getOperand(2).getReg()) 5890 return Match_RequiresSameSrcAndDst; 5891 return Match_Success; 5892 } 5893 5894 uint64_t TSFlags = MII.get(Inst.getOpcode()).TSFlags; 5895 if ((TSFlags & MipsII::HasFCCRegOperand) && 5896 (Inst.getOperand(0).getReg() != Mips::FCC0) && !hasEightFccRegisters()) 5897 return Match_NoFCCRegisterForCurrentISA; 5898 5899 return Match_Success; 5900 5901 } 5902 5903 static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands, 5904 uint64_t ErrorInfo) { 5905 if (ErrorInfo != ~0ULL && ErrorInfo < Operands.size()) { 5906 SMLoc ErrorLoc = Operands[ErrorInfo]->getStartLoc(); 5907 if (ErrorLoc == SMLoc()) 5908 return Loc; 5909 return ErrorLoc; 5910 } 5911 return Loc; 5912 } 5913 5914 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 5915 OperandVector &Operands, 5916 MCStreamer &Out, 5917 uint64_t &ErrorInfo, 5918 bool MatchingInlineAsm) { 5919 MCInst Inst; 5920 unsigned MatchResult = 5921 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm); 5922 5923 switch (MatchResult) { 5924 case Match_Success: 5925 if (processInstruction(Inst, IDLoc, Out, STI)) 5926 return true; 5927 return false; 5928 case Match_MissingFeature: 5929 Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 5930 return true; 5931 case Match_InvalidTiedOperand: 5932 Error(IDLoc, "operand must match destination register"); 5933 return true; 5934 case Match_InvalidOperand: { 5935 SMLoc ErrorLoc = IDLoc; 5936 if (ErrorInfo != ~0ULL) { 5937 if (ErrorInfo >= Operands.size()) 5938 return Error(IDLoc, "too few operands for instruction"); 5939 5940 ErrorLoc = Operands[ErrorInfo]->getStartLoc(); 5941 if (ErrorLoc == SMLoc()) 5942 ErrorLoc = IDLoc; 5943 } 5944 5945 return Error(ErrorLoc, "invalid operand for instruction"); 5946 } 5947 case Match_NonZeroOperandForSync: 5948 return Error(IDLoc, 5949 "s-type must be zero or unspecified for pre-MIPS32 ISAs"); 5950 case Match_NonZeroOperandForMTCX: 5951 return Error(IDLoc, "selector must be zero for pre-MIPS32 ISAs"); 5952 case Match_MnemonicFail: 5953 return Error(IDLoc, "invalid instruction"); 5954 case Match_RequiresDifferentSrcAndDst: 5955 return Error(IDLoc, "source and destination must be different"); 5956 case Match_RequiresDifferentOperands: 5957 return Error(IDLoc, "registers must be different"); 5958 case Match_RequiresNoZeroRegister: 5959 return Error(IDLoc, "invalid operand ($zero) for instruction"); 5960 case Match_RequiresSameSrcAndDst: 5961 return Error(IDLoc, "source and destination must match"); 5962 case Match_NoFCCRegisterForCurrentISA: 5963 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 5964 "non-zero fcc register doesn't exist in current ISA level"); 5965 case Match_Immz: 5966 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected '0'"); 5967 case Match_UImm1_0: 5968 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 5969 "expected 1-bit unsigned immediate"); 5970 case Match_UImm2_0: 5971 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 5972 "expected 2-bit unsigned immediate"); 5973 case Match_UImm2_1: 5974 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 5975 "expected immediate in range 1 .. 4"); 5976 case Match_UImm3_0: 5977 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 5978 "expected 3-bit unsigned immediate"); 5979 case Match_UImm4_0: 5980 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 5981 "expected 4-bit unsigned immediate"); 5982 case Match_SImm4_0: 5983 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 5984 "expected 4-bit signed immediate"); 5985 case Match_UImm5_0: 5986 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 5987 "expected 5-bit unsigned immediate"); 5988 case Match_SImm5_0: 5989 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 5990 "expected 5-bit signed immediate"); 5991 case Match_UImm5_1: 5992 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 5993 "expected immediate in range 1 .. 32"); 5994 case Match_UImm5_32: 5995 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 5996 "expected immediate in range 32 .. 63"); 5997 case Match_UImm5_33: 5998 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 5999 "expected immediate in range 33 .. 64"); 6000 case Match_UImm5_0_Report_UImm6: 6001 // This is used on UImm5 operands that have a corresponding UImm5_32 6002 // operand to avoid confusing the user. 6003 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 6004 "expected 6-bit unsigned immediate"); 6005 case Match_UImm5_Lsl2: 6006 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 6007 "expected both 7-bit unsigned immediate and multiple of 4"); 6008 case Match_UImmRange2_64: 6009 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 6010 "expected immediate in range 2 .. 64"); 6011 case Match_UImm6_0: 6012 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 6013 "expected 6-bit unsigned immediate"); 6014 case Match_UImm6_Lsl2: 6015 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 6016 "expected both 8-bit unsigned immediate and multiple of 4"); 6017 case Match_SImm6_0: 6018 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 6019 "expected 6-bit signed immediate"); 6020 case Match_UImm7_0: 6021 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 6022 "expected 7-bit unsigned immediate"); 6023 case Match_UImm7_N1: 6024 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 6025 "expected immediate in range -1 .. 126"); 6026 case Match_SImm7_Lsl2: 6027 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 6028 "expected both 9-bit signed immediate and multiple of 4"); 6029 case Match_UImm8_0: 6030 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 6031 "expected 8-bit unsigned immediate"); 6032 case Match_UImm10_0: 6033 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 6034 "expected 10-bit unsigned immediate"); 6035 case Match_SImm10_0: 6036 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 6037 "expected 10-bit signed immediate"); 6038 case Match_SImm11_0: 6039 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 6040 "expected 11-bit signed immediate"); 6041 case Match_UImm16: 6042 case Match_UImm16_Relaxed: 6043 case Match_UImm16_AltRelaxed: 6044 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 6045 "expected 16-bit unsigned immediate"); 6046 case Match_SImm16: 6047 case Match_SImm16_Relaxed: 6048 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 6049 "expected 16-bit signed immediate"); 6050 case Match_SImm19_Lsl2: 6051 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 6052 "expected both 19-bit signed immediate and multiple of 4"); 6053 case Match_UImm20_0: 6054 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 6055 "expected 20-bit unsigned immediate"); 6056 case Match_UImm26_0: 6057 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 6058 "expected 26-bit unsigned immediate"); 6059 case Match_SImm32: 6060 case Match_SImm32_Relaxed: 6061 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 6062 "expected 32-bit signed immediate"); 6063 case Match_UImm32_Coerced: 6064 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 6065 "expected 32-bit immediate"); 6066 case Match_MemSImm9: 6067 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 6068 "expected memory with 9-bit signed offset"); 6069 case Match_MemSImm10: 6070 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 6071 "expected memory with 10-bit signed offset"); 6072 case Match_MemSImm10Lsl1: 6073 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 6074 "expected memory with 11-bit signed offset and multiple of 2"); 6075 case Match_MemSImm10Lsl2: 6076 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 6077 "expected memory with 12-bit signed offset and multiple of 4"); 6078 case Match_MemSImm10Lsl3: 6079 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 6080 "expected memory with 13-bit signed offset and multiple of 8"); 6081 case Match_MemSImm11: 6082 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 6083 "expected memory with 11-bit signed offset"); 6084 case Match_MemSImm12: 6085 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 6086 "expected memory with 12-bit signed offset"); 6087 case Match_MemSImm16: 6088 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 6089 "expected memory with 16-bit signed offset"); 6090 case Match_MemSImmPtr: 6091 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 6092 "expected memory with 32-bit signed offset"); 6093 case Match_RequiresPosSizeRange0_32: { 6094 SMLoc ErrorStart = Operands[3]->getStartLoc(); 6095 SMLoc ErrorEnd = Operands[4]->getEndLoc(); 6096 return Error(ErrorStart, "size plus position are not in the range 0 .. 32", 6097 SMRange(ErrorStart, ErrorEnd)); 6098 } 6099 case Match_RequiresPosSizeUImm6: { 6100 SMLoc ErrorStart = Operands[3]->getStartLoc(); 6101 SMLoc ErrorEnd = Operands[4]->getEndLoc(); 6102 return Error(ErrorStart, "size plus position are not in the range 1 .. 63", 6103 SMRange(ErrorStart, ErrorEnd)); 6104 } 6105 case Match_RequiresPosSizeRange33_64: { 6106 SMLoc ErrorStart = Operands[3]->getStartLoc(); 6107 SMLoc ErrorEnd = Operands[4]->getEndLoc(); 6108 return Error(ErrorStart, "size plus position are not in the range 33 .. 64", 6109 SMRange(ErrorStart, ErrorEnd)); 6110 } 6111 } 6112 6113 llvm_unreachable("Implement any new match types added!"); 6114 } 6115 6116 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) { 6117 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex) 6118 Warning(Loc, "used $at (currently $" + Twine(RegIndex) + 6119 ") without \".set noat\""); 6120 } 6121 6122 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) { 6123 if (!AssemblerOptions.back()->isMacro()) 6124 Warning(Loc, "macro instruction expanded into multiple instructions"); 6125 } 6126 6127 void MipsAsmParser::ConvertXWPOperands(MCInst &Inst, 6128 const OperandVector &Operands) { 6129 assert( 6130 (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM) && 6131 "Unexpected instruction!"); 6132 ((MipsOperand &)*Operands[1]).addGPR32ZeroAsmRegOperands(Inst, 1); 6133 int NextReg = nextReg(((MipsOperand &)*Operands[1]).getGPR32Reg()); 6134 Inst.addOperand(MCOperand::createReg(NextReg)); 6135 ((MipsOperand &)*Operands[2]).addMemOperands(Inst, 2); 6136 } 6137 6138 void 6139 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg, 6140 SMRange Range, bool ShowColors) { 6141 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg, 6142 Range, SMFixIt(Range, FixMsg), 6143 ShowColors); 6144 } 6145 6146 int MipsAsmParser::matchCPURegisterName(StringRef Name) { 6147 int CC; 6148 6149 CC = StringSwitch<unsigned>(Name) 6150 .Case("zero", 0) 6151 .Cases("at", "AT", 1) 6152 .Case("a0", 4) 6153 .Case("a1", 5) 6154 .Case("a2", 6) 6155 .Case("a3", 7) 6156 .Case("v0", 2) 6157 .Case("v1", 3) 6158 .Case("s0", 16) 6159 .Case("s1", 17) 6160 .Case("s2", 18) 6161 .Case("s3", 19) 6162 .Case("s4", 20) 6163 .Case("s5", 21) 6164 .Case("s6", 22) 6165 .Case("s7", 23) 6166 .Case("k0", 26) 6167 .Case("k1", 27) 6168 .Case("gp", 28) 6169 .Case("sp", 29) 6170 .Case("fp", 30) 6171 .Case("s8", 30) 6172 .Case("ra", 31) 6173 .Case("t0", 8) 6174 .Case("t1", 9) 6175 .Case("t2", 10) 6176 .Case("t3", 11) 6177 .Case("t4", 12) 6178 .Case("t5", 13) 6179 .Case("t6", 14) 6180 .Case("t7", 15) 6181 .Case("t8", 24) 6182 .Case("t9", 25) 6183 .Default(-1); 6184 6185 if (!(isABI_N32() || isABI_N64())) 6186 return CC; 6187 6188 if (12 <= CC && CC <= 15) { 6189 // Name is one of t4-t7 6190 AsmToken RegTok = getLexer().peekTok(); 6191 SMRange RegRange = RegTok.getLocRange(); 6192 6193 StringRef FixedName = StringSwitch<StringRef>(Name) 6194 .Case("t4", "t0") 6195 .Case("t5", "t1") 6196 .Case("t6", "t2") 6197 .Case("t7", "t3") 6198 .Default(""); 6199 assert(FixedName != "" && "Register name is not one of t4-t7."); 6200 6201 printWarningWithFixIt("register names $t4-$t7 are only available in O32.", 6202 "Did you mean $" + FixedName + "?", RegRange); 6203 } 6204 6205 // Although SGI documentation just cuts out t0-t3 for n32/n64, 6206 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7 6207 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7. 6208 if (8 <= CC && CC <= 11) 6209 CC += 4; 6210 6211 if (CC == -1) 6212 CC = StringSwitch<unsigned>(Name) 6213 .Case("a4", 8) 6214 .Case("a5", 9) 6215 .Case("a6", 10) 6216 .Case("a7", 11) 6217 .Case("kt0", 26) 6218 .Case("kt1", 27) 6219 .Default(-1); 6220 6221 return CC; 6222 } 6223 6224 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) { 6225 int CC; 6226 6227 CC = StringSwitch<unsigned>(Name) 6228 .Case("hwr_cpunum", 0) 6229 .Case("hwr_synci_step", 1) 6230 .Case("hwr_cc", 2) 6231 .Case("hwr_ccres", 3) 6232 .Case("hwr_ulr", 29) 6233 .Default(-1); 6234 6235 return CC; 6236 } 6237 6238 int MipsAsmParser::matchFPURegisterName(StringRef Name) { 6239 if (Name[0] == 'f') { 6240 StringRef NumString = Name.substr(1); 6241 unsigned IntVal; 6242 if (NumString.getAsInteger(10, IntVal)) 6243 return -1; // This is not an integer. 6244 if (IntVal > 31) // Maximum index for fpu register. 6245 return -1; 6246 return IntVal; 6247 } 6248 return -1; 6249 } 6250 6251 int MipsAsmParser::matchFCCRegisterName(StringRef Name) { 6252 if (Name.starts_with("fcc")) { 6253 StringRef NumString = Name.substr(3); 6254 unsigned IntVal; 6255 if (NumString.getAsInteger(10, IntVal)) 6256 return -1; // This is not an integer. 6257 if (IntVal > 7) // There are only 8 fcc registers. 6258 return -1; 6259 return IntVal; 6260 } 6261 return -1; 6262 } 6263 6264 int MipsAsmParser::matchACRegisterName(StringRef Name) { 6265 if (Name.starts_with("ac")) { 6266 StringRef NumString = Name.substr(2); 6267 unsigned IntVal; 6268 if (NumString.getAsInteger(10, IntVal)) 6269 return -1; // This is not an integer. 6270 if (IntVal > 3) // There are only 3 acc registers. 6271 return -1; 6272 return IntVal; 6273 } 6274 return -1; 6275 } 6276 6277 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) { 6278 unsigned IntVal; 6279 6280 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal)) 6281 return -1; 6282 6283 if (IntVal > 31) 6284 return -1; 6285 6286 return IntVal; 6287 } 6288 6289 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) { 6290 int CC; 6291 6292 CC = StringSwitch<unsigned>(Name) 6293 .Case("msair", 0) 6294 .Case("msacsr", 1) 6295 .Case("msaaccess", 2) 6296 .Case("msasave", 3) 6297 .Case("msamodify", 4) 6298 .Case("msarequest", 5) 6299 .Case("msamap", 6) 6300 .Case("msaunmap", 7) 6301 .Default(-1); 6302 6303 return CC; 6304 } 6305 6306 bool MipsAsmParser::canUseATReg() { 6307 return AssemblerOptions.back()->getATRegIndex() != 0; 6308 } 6309 6310 unsigned MipsAsmParser::getATReg(SMLoc Loc) { 6311 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex(); 6312 if (ATIndex == 0) { 6313 reportParseError(Loc, 6314 "pseudo-instruction requires $at, which is not available"); 6315 return 0; 6316 } 6317 unsigned AT = getReg( 6318 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex); 6319 return AT; 6320 } 6321 6322 unsigned MipsAsmParser::getReg(int RC, int RegNo) { 6323 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo); 6324 } 6325 6326 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { 6327 MCAsmParser &Parser = getParser(); 6328 LLVM_DEBUG(dbgs() << "parseOperand\n"); 6329 6330 // Check if the current operand has a custom associated parser, if so, try to 6331 // custom parse the operand, or fallback to the general approach. 6332 ParseStatus Res = MatchOperandParserImpl(Operands, Mnemonic); 6333 if (Res.isSuccess()) 6334 return false; 6335 // If there wasn't a custom match, try the generic matcher below. Otherwise, 6336 // there was a match, but an error occurred, in which case, just return that 6337 // the operand parsing failed. 6338 if (Res.isFailure()) 6339 return true; 6340 6341 LLVM_DEBUG(dbgs() << ".. Generic Parser\n"); 6342 6343 switch (getLexer().getKind()) { 6344 case AsmToken::Dollar: { 6345 // Parse the register. 6346 SMLoc S = Parser.getTok().getLoc(); 6347 6348 // Almost all registers have been parsed by custom parsers. There is only 6349 // one exception to this. $zero (and it's alias $0) will reach this point 6350 // for div, divu, and similar instructions because it is not an operand 6351 // to the instruction definition but an explicit register. Special case 6352 // this situation for now. 6353 if (!parseAnyRegister(Operands).isNoMatch()) 6354 return false; 6355 6356 // Maybe it is a symbol reference. 6357 StringRef Identifier; 6358 if (Parser.parseIdentifier(Identifier)) 6359 return true; 6360 6361 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 6362 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier); 6363 // Otherwise create a symbol reference. 6364 const MCExpr *SymRef = 6365 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 6366 6367 Operands.push_back(MipsOperand::CreateImm(SymRef, S, E, *this)); 6368 return false; 6369 } 6370 default: { 6371 LLVM_DEBUG(dbgs() << ".. generic integer expression\n"); 6372 6373 const MCExpr *Expr; 6374 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand. 6375 if (getParser().parseExpression(Expr)) 6376 return true; 6377 6378 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 6379 6380 Operands.push_back(MipsOperand::CreateImm(Expr, S, E, *this)); 6381 return false; 6382 } 6383 } // switch(getLexer().getKind()) 6384 return true; 6385 } 6386 6387 bool MipsAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc, 6388 SMLoc &EndLoc) { 6389 return !tryParseRegister(Reg, StartLoc, EndLoc).isSuccess(); 6390 } 6391 6392 ParseStatus MipsAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc, 6393 SMLoc &EndLoc) { 6394 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands; 6395 ParseStatus Res = parseAnyRegister(Operands); 6396 if (Res.isSuccess()) { 6397 assert(Operands.size() == 1); 6398 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front()); 6399 StartLoc = Operand.getStartLoc(); 6400 EndLoc = Operand.getEndLoc(); 6401 6402 // AFAIK, we only support numeric registers and named GPR's in CFI 6403 // directives. 6404 // Don't worry about eating tokens before failing. Using an unrecognised 6405 // register is a parse error. 6406 if (Operand.isGPRAsmReg()) { 6407 // Resolve to GPR32 or GPR64 appropriately. 6408 Reg = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg(); 6409 } 6410 6411 return (Reg == (unsigned)-1) ? ParseStatus::NoMatch : ParseStatus::Success; 6412 } 6413 6414 assert(Operands.size() == 0); 6415 return (Reg == (unsigned)-1) ? ParseStatus::NoMatch : ParseStatus::Success; 6416 } 6417 6418 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) { 6419 SMLoc S; 6420 6421 if (isParenExpr) 6422 return getParser().parseParenExprOfDepth(0, Res, S); 6423 return getParser().parseExpression(Res); 6424 } 6425 6426 ParseStatus MipsAsmParser::parseMemOperand(OperandVector &Operands) { 6427 MCAsmParser &Parser = getParser(); 6428 LLVM_DEBUG(dbgs() << "parseMemOperand\n"); 6429 const MCExpr *IdVal = nullptr; 6430 SMLoc S; 6431 bool isParenExpr = false; 6432 ParseStatus Res = ParseStatus::NoMatch; 6433 // First operand is the offset. 6434 S = Parser.getTok().getLoc(); 6435 6436 if (getLexer().getKind() == AsmToken::LParen) { 6437 Parser.Lex(); 6438 isParenExpr = true; 6439 } 6440 6441 if (getLexer().getKind() != AsmToken::Dollar) { 6442 if (parseMemOffset(IdVal, isParenExpr)) 6443 return ParseStatus::Failure; 6444 6445 const AsmToken &Tok = Parser.getTok(); // Get the next token. 6446 if (Tok.isNot(AsmToken::LParen)) { 6447 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]); 6448 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") { 6449 SMLoc E = 6450 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 6451 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this)); 6452 return ParseStatus::Success; 6453 } 6454 if (Tok.is(AsmToken::EndOfStatement)) { 6455 SMLoc E = 6456 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 6457 6458 // Zero register assumed, add a memory operand with ZERO as its base. 6459 // "Base" will be managed by k_Memory. 6460 auto Base = MipsOperand::createGPRReg( 6461 0, "0", getContext().getRegisterInfo(), S, E, *this); 6462 Operands.push_back( 6463 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this)); 6464 return ParseStatus::Success; 6465 } 6466 MCBinaryExpr::Opcode Opcode; 6467 // GAS and LLVM treat comparison operators different. GAS will generate -1 6468 // or 0, while LLVM will generate 0 or 1. Since a comparsion operator is 6469 // highly unlikely to be found in a memory offset expression, we don't 6470 // handle them. 6471 switch (Tok.getKind()) { 6472 case AsmToken::Plus: 6473 Opcode = MCBinaryExpr::Add; 6474 Parser.Lex(); 6475 break; 6476 case AsmToken::Minus: 6477 Opcode = MCBinaryExpr::Sub; 6478 Parser.Lex(); 6479 break; 6480 case AsmToken::Star: 6481 Opcode = MCBinaryExpr::Mul; 6482 Parser.Lex(); 6483 break; 6484 case AsmToken::Pipe: 6485 Opcode = MCBinaryExpr::Or; 6486 Parser.Lex(); 6487 break; 6488 case AsmToken::Amp: 6489 Opcode = MCBinaryExpr::And; 6490 Parser.Lex(); 6491 break; 6492 case AsmToken::LessLess: 6493 Opcode = MCBinaryExpr::Shl; 6494 Parser.Lex(); 6495 break; 6496 case AsmToken::GreaterGreater: 6497 Opcode = MCBinaryExpr::LShr; 6498 Parser.Lex(); 6499 break; 6500 case AsmToken::Caret: 6501 Opcode = MCBinaryExpr::Xor; 6502 Parser.Lex(); 6503 break; 6504 case AsmToken::Slash: 6505 Opcode = MCBinaryExpr::Div; 6506 Parser.Lex(); 6507 break; 6508 case AsmToken::Percent: 6509 Opcode = MCBinaryExpr::Mod; 6510 Parser.Lex(); 6511 break; 6512 default: 6513 return Error(Parser.getTok().getLoc(), "'(' or expression expected"); 6514 } 6515 const MCExpr * NextExpr; 6516 if (getParser().parseExpression(NextExpr)) 6517 return ParseStatus::Failure; 6518 IdVal = MCBinaryExpr::create(Opcode, IdVal, NextExpr, getContext()); 6519 } 6520 6521 Parser.Lex(); // Eat the '(' token. 6522 } 6523 6524 Res = parseAnyRegister(Operands); 6525 if (!Res.isSuccess()) 6526 return Res; 6527 6528 if (Parser.getTok().isNot(AsmToken::RParen)) 6529 return Error(Parser.getTok().getLoc(), "')' expected"); 6530 6531 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 6532 6533 Parser.Lex(); // Eat the ')' token. 6534 6535 if (!IdVal) 6536 IdVal = MCConstantExpr::create(0, getContext()); 6537 6538 // Replace the register operand with the memory operand. 6539 std::unique_ptr<MipsOperand> op( 6540 static_cast<MipsOperand *>(Operands.back().release())); 6541 // Remove the register from the operands. 6542 // "op" will be managed by k_Memory. 6543 Operands.pop_back(); 6544 // Add the memory operand. 6545 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) { 6546 int64_t Imm; 6547 if (IdVal->evaluateAsAbsolute(Imm)) 6548 IdVal = MCConstantExpr::create(Imm, getContext()); 6549 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef) 6550 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(), 6551 getContext()); 6552 } 6553 6554 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this)); 6555 return ParseStatus::Success; 6556 } 6557 6558 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) { 6559 MCAsmParser &Parser = getParser(); 6560 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier()); 6561 if (!Sym) 6562 return false; 6563 6564 SMLoc S = Parser.getTok().getLoc(); 6565 if (Sym->isVariable()) { 6566 const MCExpr *Expr = Sym->getVariableValue(); 6567 if (Expr->getKind() == MCExpr::SymbolRef) { 6568 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr); 6569 StringRef DefSymbol = Ref->getSymbol().getName(); 6570 if (DefSymbol.starts_with("$")) { 6571 ParseStatus Res = 6572 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S); 6573 if (Res.isSuccess()) { 6574 Parser.Lex(); 6575 return true; 6576 } 6577 if (Res.isFailure()) 6578 llvm_unreachable("Should never fail"); 6579 } 6580 } 6581 } else if (Sym->isUnset()) { 6582 // If symbol is unset, it might be created in the `parseSetAssignment` 6583 // routine as an alias for a numeric register name. 6584 // Lookup in the aliases list. 6585 auto Entry = RegisterSets.find(Sym->getName()); 6586 if (Entry != RegisterSets.end()) { 6587 ParseStatus Res = 6588 matchAnyRegisterWithoutDollar(Operands, Entry->getValue(), S); 6589 if (Res.isSuccess()) { 6590 Parser.Lex(); 6591 return true; 6592 } 6593 } 6594 } 6595 6596 return false; 6597 } 6598 6599 ParseStatus MipsAsmParser::matchAnyRegisterNameWithoutDollar( 6600 OperandVector &Operands, StringRef Identifier, SMLoc S) { 6601 int Index = matchCPURegisterName(Identifier); 6602 if (Index != -1) { 6603 Operands.push_back(MipsOperand::createGPRReg( 6604 Index, Identifier, getContext().getRegisterInfo(), S, 6605 getLexer().getLoc(), *this)); 6606 return ParseStatus::Success; 6607 } 6608 6609 Index = matchHWRegsRegisterName(Identifier); 6610 if (Index != -1) { 6611 Operands.push_back(MipsOperand::createHWRegsReg( 6612 Index, Identifier, getContext().getRegisterInfo(), S, 6613 getLexer().getLoc(), *this)); 6614 return ParseStatus::Success; 6615 } 6616 6617 Index = matchFPURegisterName(Identifier); 6618 if (Index != -1) { 6619 Operands.push_back(MipsOperand::createFGRReg( 6620 Index, Identifier, getContext().getRegisterInfo(), S, 6621 getLexer().getLoc(), *this)); 6622 return ParseStatus::Success; 6623 } 6624 6625 Index = matchFCCRegisterName(Identifier); 6626 if (Index != -1) { 6627 Operands.push_back(MipsOperand::createFCCReg( 6628 Index, Identifier, getContext().getRegisterInfo(), S, 6629 getLexer().getLoc(), *this)); 6630 return ParseStatus::Success; 6631 } 6632 6633 Index = matchACRegisterName(Identifier); 6634 if (Index != -1) { 6635 Operands.push_back(MipsOperand::createACCReg( 6636 Index, Identifier, getContext().getRegisterInfo(), S, 6637 getLexer().getLoc(), *this)); 6638 return ParseStatus::Success; 6639 } 6640 6641 Index = matchMSA128RegisterName(Identifier); 6642 if (Index != -1) { 6643 Operands.push_back(MipsOperand::createMSA128Reg( 6644 Index, Identifier, getContext().getRegisterInfo(), S, 6645 getLexer().getLoc(), *this)); 6646 return ParseStatus::Success; 6647 } 6648 6649 Index = matchMSA128CtrlRegisterName(Identifier); 6650 if (Index != -1) { 6651 Operands.push_back(MipsOperand::createMSACtrlReg( 6652 Index, Identifier, getContext().getRegisterInfo(), S, 6653 getLexer().getLoc(), *this)); 6654 return ParseStatus::Success; 6655 } 6656 6657 return ParseStatus::NoMatch; 6658 } 6659 6660 ParseStatus 6661 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, 6662 const AsmToken &Token, SMLoc S) { 6663 if (Token.is(AsmToken::Identifier)) { 6664 LLVM_DEBUG(dbgs() << ".. identifier\n"); 6665 StringRef Identifier = Token.getIdentifier(); 6666 return matchAnyRegisterNameWithoutDollar(Operands, Identifier, S); 6667 } 6668 if (Token.is(AsmToken::Integer)) { 6669 LLVM_DEBUG(dbgs() << ".. integer\n"); 6670 int64_t RegNum = Token.getIntVal(); 6671 if (RegNum < 0 || RegNum > 31) { 6672 // Show the error, but treat invalid register 6673 // number as a normal one to continue parsing 6674 // and catch other possible errors. 6675 Error(getLexer().getLoc(), "invalid register number"); 6676 } 6677 Operands.push_back(MipsOperand::createNumericReg( 6678 RegNum, Token.getString(), getContext().getRegisterInfo(), S, 6679 Token.getLoc(), *this)); 6680 return ParseStatus::Success; 6681 } 6682 6683 LLVM_DEBUG(dbgs() << Token.getKind() << "\n"); 6684 6685 return ParseStatus::NoMatch; 6686 } 6687 6688 ParseStatus 6689 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) { 6690 auto Token = getLexer().peekTok(false); 6691 return matchAnyRegisterWithoutDollar(Operands, Token, S); 6692 } 6693 6694 ParseStatus MipsAsmParser::parseAnyRegister(OperandVector &Operands) { 6695 MCAsmParser &Parser = getParser(); 6696 LLVM_DEBUG(dbgs() << "parseAnyRegister\n"); 6697 6698 auto Token = Parser.getTok(); 6699 6700 SMLoc S = Token.getLoc(); 6701 6702 if (Token.isNot(AsmToken::Dollar)) { 6703 LLVM_DEBUG(dbgs() << ".. !$ -> try sym aliasing\n"); 6704 if (Token.is(AsmToken::Identifier)) { 6705 if (searchSymbolAlias(Operands)) 6706 return ParseStatus::Success; 6707 } 6708 LLVM_DEBUG(dbgs() << ".. !symalias -> NoMatch\n"); 6709 return ParseStatus::NoMatch; 6710 } 6711 LLVM_DEBUG(dbgs() << ".. $\n"); 6712 6713 ParseStatus Res = matchAnyRegisterWithoutDollar(Operands, S); 6714 if (Res.isSuccess()) { 6715 Parser.Lex(); // $ 6716 Parser.Lex(); // identifier 6717 } 6718 return Res; 6719 } 6720 6721 ParseStatus MipsAsmParser::parseJumpTarget(OperandVector &Operands) { 6722 MCAsmParser &Parser = getParser(); 6723 LLVM_DEBUG(dbgs() << "parseJumpTarget\n"); 6724 6725 SMLoc S = getLexer().getLoc(); 6726 6727 // Registers are a valid target and have priority over symbols. 6728 ParseStatus Res = parseAnyRegister(Operands); 6729 if (!Res.isNoMatch()) 6730 return Res; 6731 6732 // Integers and expressions are acceptable 6733 const MCExpr *Expr = nullptr; 6734 if (Parser.parseExpression(Expr)) { 6735 // We have no way of knowing if a symbol was consumed so we must ParseFail 6736 return ParseStatus::Failure; 6737 } 6738 Operands.push_back( 6739 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this)); 6740 return ParseStatus::Success; 6741 } 6742 6743 ParseStatus MipsAsmParser::parseInvNum(OperandVector &Operands) { 6744 MCAsmParser &Parser = getParser(); 6745 const MCExpr *IdVal; 6746 // If the first token is '$' we may have register operand. We have to reject 6747 // cases where it is not a register. Complicating the matter is that 6748 // register names are not reserved across all ABIs. 6749 // Peek past the dollar to see if it's a register name for this ABI. 6750 SMLoc S = Parser.getTok().getLoc(); 6751 if (Parser.getTok().is(AsmToken::Dollar)) { 6752 return matchCPURegisterName(Parser.getLexer().peekTok().getString()) == -1 6753 ? ParseStatus::Failure 6754 : ParseStatus::NoMatch; 6755 } 6756 if (getParser().parseExpression(IdVal)) 6757 return ParseStatus::Failure; 6758 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal); 6759 if (!MCE) 6760 return ParseStatus::NoMatch; 6761 int64_t Val = MCE->getValue(); 6762 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 6763 Operands.push_back(MipsOperand::CreateImm( 6764 MCConstantExpr::create(0 - Val, getContext()), S, E, *this)); 6765 return ParseStatus::Success; 6766 } 6767 6768 ParseStatus MipsAsmParser::parseRegisterList(OperandVector &Operands) { 6769 MCAsmParser &Parser = getParser(); 6770 SmallVector<unsigned, 10> Regs; 6771 unsigned RegNo; 6772 unsigned PrevReg = Mips::NoRegister; 6773 bool RegRange = false; 6774 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands; 6775 6776 if (Parser.getTok().isNot(AsmToken::Dollar)) 6777 return ParseStatus::Failure; 6778 6779 SMLoc S = Parser.getTok().getLoc(); 6780 while (parseAnyRegister(TmpOperands).isSuccess()) { 6781 SMLoc E = getLexer().getLoc(); 6782 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back()); 6783 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg(); 6784 if (RegRange) { 6785 // Remove last register operand because registers from register range 6786 // should be inserted first. 6787 if ((isGP64bit() && RegNo == Mips::RA_64) || 6788 (!isGP64bit() && RegNo == Mips::RA)) { 6789 Regs.push_back(RegNo); 6790 } else { 6791 unsigned TmpReg = PrevReg + 1; 6792 while (TmpReg <= RegNo) { 6793 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) || 6794 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) && 6795 isGP64bit())) 6796 return Error(E, "invalid register operand"); 6797 6798 PrevReg = TmpReg; 6799 Regs.push_back(TmpReg++); 6800 } 6801 } 6802 6803 RegRange = false; 6804 } else { 6805 if ((PrevReg == Mips::NoRegister) && 6806 ((isGP64bit() && (RegNo != Mips::S0_64) && (RegNo != Mips::RA_64)) || 6807 (!isGP64bit() && (RegNo != Mips::S0) && (RegNo != Mips::RA)))) 6808 return Error(E, "$16 or $31 expected"); 6809 if (!(((RegNo == Mips::FP || RegNo == Mips::RA || 6810 (RegNo >= Mips::S0 && RegNo <= Mips::S7)) && 6811 !isGP64bit()) || 6812 ((RegNo == Mips::FP_64 || RegNo == Mips::RA_64 || 6813 (RegNo >= Mips::S0_64 && RegNo <= Mips::S7_64)) && 6814 isGP64bit()))) 6815 return Error(E, "invalid register operand"); 6816 if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) && 6817 ((RegNo != Mips::FP && RegNo != Mips::RA && !isGP64bit()) || 6818 (RegNo != Mips::FP_64 && RegNo != Mips::RA_64 && isGP64bit()))) 6819 return Error(E, "consecutive register numbers expected"); 6820 6821 Regs.push_back(RegNo); 6822 } 6823 6824 if (Parser.getTok().is(AsmToken::Minus)) 6825 RegRange = true; 6826 6827 if (!Parser.getTok().isNot(AsmToken::Minus) && 6828 !Parser.getTok().isNot(AsmToken::Comma)) 6829 return Error(E, "',' or '-' expected"); 6830 6831 Lex(); // Consume comma or minus 6832 if (Parser.getTok().isNot(AsmToken::Dollar)) 6833 break; 6834 6835 PrevReg = RegNo; 6836 } 6837 6838 SMLoc E = Parser.getTok().getLoc(); 6839 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this)); 6840 parseMemOperand(Operands); 6841 return ParseStatus::Success; 6842 } 6843 6844 /// Sometimes (i.e. load/stores) the operand may be followed immediately by 6845 /// either this. 6846 /// ::= '(', register, ')' 6847 /// handle it before we iterate so we don't get tripped up by the lack of 6848 /// a comma. 6849 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) { 6850 MCAsmParser &Parser = getParser(); 6851 if (getLexer().is(AsmToken::LParen)) { 6852 Operands.push_back( 6853 MipsOperand::CreateToken("(", getLexer().getLoc(), *this)); 6854 Parser.Lex(); 6855 if (parseOperand(Operands, Name)) { 6856 SMLoc Loc = getLexer().getLoc(); 6857 return Error(Loc, "unexpected token in argument list"); 6858 } 6859 if (Parser.getTok().isNot(AsmToken::RParen)) { 6860 SMLoc Loc = getLexer().getLoc(); 6861 return Error(Loc, "unexpected token, expected ')'"); 6862 } 6863 Operands.push_back( 6864 MipsOperand::CreateToken(")", getLexer().getLoc(), *this)); 6865 Parser.Lex(); 6866 } 6867 return false; 6868 } 6869 6870 /// Sometimes (i.e. in MSA) the operand may be followed immediately by 6871 /// either one of these. 6872 /// ::= '[', register, ']' 6873 /// ::= '[', integer, ']' 6874 /// handle it before we iterate so we don't get tripped up by the lack of 6875 /// a comma. 6876 bool MipsAsmParser::parseBracketSuffix(StringRef Name, 6877 OperandVector &Operands) { 6878 MCAsmParser &Parser = getParser(); 6879 if (getLexer().is(AsmToken::LBrac)) { 6880 Operands.push_back( 6881 MipsOperand::CreateToken("[", getLexer().getLoc(), *this)); 6882 Parser.Lex(); 6883 if (parseOperand(Operands, Name)) { 6884 SMLoc Loc = getLexer().getLoc(); 6885 return Error(Loc, "unexpected token in argument list"); 6886 } 6887 if (Parser.getTok().isNot(AsmToken::RBrac)) { 6888 SMLoc Loc = getLexer().getLoc(); 6889 return Error(Loc, "unexpected token, expected ']'"); 6890 } 6891 Operands.push_back( 6892 MipsOperand::CreateToken("]", getLexer().getLoc(), *this)); 6893 Parser.Lex(); 6894 } 6895 return false; 6896 } 6897 6898 static std::string MipsMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, 6899 unsigned VariantID = 0); 6900 6901 bool MipsAsmParser::areEqualRegs(const MCParsedAsmOperand &Op1, 6902 const MCParsedAsmOperand &Op2) const { 6903 // This target-overriden function exists to maintain current behaviour for 6904 // e.g. 6905 // dahi $3, $3, 0x5678 6906 // as tested in test/MC/Mips/mips64r6/valid.s. 6907 // FIXME: Should this test actually fail with an error? If so, then remove 6908 // this overloaded method. 6909 if (!Op1.isReg() || !Op2.isReg()) 6910 return true; 6911 return Op1.getReg() == Op2.getReg(); 6912 } 6913 6914 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 6915 SMLoc NameLoc, OperandVector &Operands) { 6916 MCAsmParser &Parser = getParser(); 6917 LLVM_DEBUG(dbgs() << "ParseInstruction\n"); 6918 6919 // We have reached first instruction, module directive are now forbidden. 6920 getTargetStreamer().forbidModuleDirective(); 6921 6922 // Check if we have valid mnemonic 6923 if (!mnemonicIsValid(Name, 0)) { 6924 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits()); 6925 std::string Suggestion = MipsMnemonicSpellCheck(Name, FBS); 6926 return Error(NameLoc, "unknown instruction" + Suggestion); 6927 } 6928 // First operand in MCInst is instruction mnemonic. 6929 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this)); 6930 6931 // Read the remaining operands. 6932 if (getLexer().isNot(AsmToken::EndOfStatement)) { 6933 // Read the first operand. 6934 if (parseOperand(Operands, Name)) { 6935 SMLoc Loc = getLexer().getLoc(); 6936 return Error(Loc, "unexpected token in argument list"); 6937 } 6938 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands)) 6939 return true; 6940 // AFAIK, parenthesis suffixes are never on the first operand 6941 6942 while (getLexer().is(AsmToken::Comma)) { 6943 Parser.Lex(); // Eat the comma. 6944 // Parse and remember the operand. 6945 if (parseOperand(Operands, Name)) { 6946 SMLoc Loc = getLexer().getLoc(); 6947 return Error(Loc, "unexpected token in argument list"); 6948 } 6949 // Parse bracket and parenthesis suffixes before we iterate 6950 if (getLexer().is(AsmToken::LBrac)) { 6951 if (parseBracketSuffix(Name, Operands)) 6952 return true; 6953 } else if (getLexer().is(AsmToken::LParen) && 6954 parseParenSuffix(Name, Operands)) 6955 return true; 6956 } 6957 } 6958 if (getLexer().isNot(AsmToken::EndOfStatement)) { 6959 SMLoc Loc = getLexer().getLoc(); 6960 return Error(Loc, "unexpected token in argument list"); 6961 } 6962 Parser.Lex(); // Consume the EndOfStatement. 6963 return false; 6964 } 6965 6966 // FIXME: Given that these have the same name, these should both be 6967 // consistent on affecting the Parser. 6968 bool MipsAsmParser::reportParseError(const Twine &ErrorMsg) { 6969 SMLoc Loc = getLexer().getLoc(); 6970 return Error(Loc, ErrorMsg); 6971 } 6972 6973 bool MipsAsmParser::reportParseError(SMLoc Loc, const Twine &ErrorMsg) { 6974 return Error(Loc, ErrorMsg); 6975 } 6976 6977 bool MipsAsmParser::parseSetNoAtDirective() { 6978 MCAsmParser &Parser = getParser(); 6979 // Line should look like: ".set noat". 6980 6981 // Set the $at register to $0. 6982 AssemblerOptions.back()->setATRegIndex(0); 6983 6984 Parser.Lex(); // Eat "noat". 6985 6986 // If this is not the end of the statement, report an error. 6987 if (getLexer().isNot(AsmToken::EndOfStatement)) { 6988 reportParseError("unexpected token, expected end of statement"); 6989 return false; 6990 } 6991 6992 getTargetStreamer().emitDirectiveSetNoAt(); 6993 Parser.Lex(); // Consume the EndOfStatement. 6994 return false; 6995 } 6996 6997 bool MipsAsmParser::parseSetAtDirective() { 6998 // Line can be: ".set at", which sets $at to $1 6999 // or ".set at=$reg", which sets $at to $reg. 7000 MCAsmParser &Parser = getParser(); 7001 Parser.Lex(); // Eat "at". 7002 7003 if (getLexer().is(AsmToken::EndOfStatement)) { 7004 // No register was specified, so we set $at to $1. 7005 AssemblerOptions.back()->setATRegIndex(1); 7006 7007 getTargetStreamer().emitDirectiveSetAt(); 7008 Parser.Lex(); // Consume the EndOfStatement. 7009 return false; 7010 } 7011 7012 if (getLexer().isNot(AsmToken::Equal)) { 7013 reportParseError("unexpected token, expected equals sign"); 7014 return false; 7015 } 7016 Parser.Lex(); // Eat "=". 7017 7018 if (getLexer().isNot(AsmToken::Dollar)) { 7019 if (getLexer().is(AsmToken::EndOfStatement)) { 7020 reportParseError("no register specified"); 7021 return false; 7022 } else { 7023 reportParseError("unexpected token, expected dollar sign '$'"); 7024 return false; 7025 } 7026 } 7027 Parser.Lex(); // Eat "$". 7028 7029 // Find out what "reg" is. 7030 unsigned AtRegNo; 7031 const AsmToken &Reg = Parser.getTok(); 7032 if (Reg.is(AsmToken::Identifier)) { 7033 AtRegNo = matchCPURegisterName(Reg.getIdentifier()); 7034 } else if (Reg.is(AsmToken::Integer)) { 7035 AtRegNo = Reg.getIntVal(); 7036 } else { 7037 reportParseError("unexpected token, expected identifier or integer"); 7038 return false; 7039 } 7040 7041 // Check if $reg is a valid register. If it is, set $at to $reg. 7042 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) { 7043 reportParseError("invalid register"); 7044 return false; 7045 } 7046 Parser.Lex(); // Eat "reg". 7047 7048 // If this is not the end of the statement, report an error. 7049 if (getLexer().isNot(AsmToken::EndOfStatement)) { 7050 reportParseError("unexpected token, expected end of statement"); 7051 return false; 7052 } 7053 7054 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo); 7055 7056 Parser.Lex(); // Consume the EndOfStatement. 7057 return false; 7058 } 7059 7060 bool MipsAsmParser::parseSetReorderDirective() { 7061 MCAsmParser &Parser = getParser(); 7062 Parser.Lex(); 7063 // If this is not the end of the statement, report an error. 7064 if (getLexer().isNot(AsmToken::EndOfStatement)) { 7065 reportParseError("unexpected token, expected end of statement"); 7066 return false; 7067 } 7068 AssemblerOptions.back()->setReorder(); 7069 getTargetStreamer().emitDirectiveSetReorder(); 7070 Parser.Lex(); // Consume the EndOfStatement. 7071 return false; 7072 } 7073 7074 bool MipsAsmParser::parseSetNoReorderDirective() { 7075 MCAsmParser &Parser = getParser(); 7076 Parser.Lex(); 7077 // If this is not the end of the statement, report an error. 7078 if (getLexer().isNot(AsmToken::EndOfStatement)) { 7079 reportParseError("unexpected token, expected end of statement"); 7080 return false; 7081 } 7082 AssemblerOptions.back()->setNoReorder(); 7083 getTargetStreamer().emitDirectiveSetNoReorder(); 7084 Parser.Lex(); // Consume the EndOfStatement. 7085 return false; 7086 } 7087 7088 bool MipsAsmParser::parseSetMacroDirective() { 7089 MCAsmParser &Parser = getParser(); 7090 Parser.Lex(); 7091 // If this is not the end of the statement, report an error. 7092 if (getLexer().isNot(AsmToken::EndOfStatement)) { 7093 reportParseError("unexpected token, expected end of statement"); 7094 return false; 7095 } 7096 AssemblerOptions.back()->setMacro(); 7097 getTargetStreamer().emitDirectiveSetMacro(); 7098 Parser.Lex(); // Consume the EndOfStatement. 7099 return false; 7100 } 7101 7102 bool MipsAsmParser::parseSetNoMacroDirective() { 7103 MCAsmParser &Parser = getParser(); 7104 Parser.Lex(); 7105 // If this is not the end of the statement, report an error. 7106 if (getLexer().isNot(AsmToken::EndOfStatement)) { 7107 reportParseError("unexpected token, expected end of statement"); 7108 return false; 7109 } 7110 if (AssemblerOptions.back()->isReorder()) { 7111 reportParseError("`noreorder' must be set before `nomacro'"); 7112 return false; 7113 } 7114 AssemblerOptions.back()->setNoMacro(); 7115 getTargetStreamer().emitDirectiveSetNoMacro(); 7116 Parser.Lex(); // Consume the EndOfStatement. 7117 return false; 7118 } 7119 7120 bool MipsAsmParser::parseSetMsaDirective() { 7121 MCAsmParser &Parser = getParser(); 7122 Parser.Lex(); 7123 7124 // If this is not the end of the statement, report an error. 7125 if (getLexer().isNot(AsmToken::EndOfStatement)) 7126 return reportParseError("unexpected token, expected end of statement"); 7127 7128 setFeatureBits(Mips::FeatureMSA, "msa"); 7129 getTargetStreamer().emitDirectiveSetMsa(); 7130 return false; 7131 } 7132 7133 bool MipsAsmParser::parseSetNoMsaDirective() { 7134 MCAsmParser &Parser = getParser(); 7135 Parser.Lex(); 7136 7137 // If this is not the end of the statement, report an error. 7138 if (getLexer().isNot(AsmToken::EndOfStatement)) 7139 return reportParseError("unexpected token, expected end of statement"); 7140 7141 clearFeatureBits(Mips::FeatureMSA, "msa"); 7142 getTargetStreamer().emitDirectiveSetNoMsa(); 7143 return false; 7144 } 7145 7146 bool MipsAsmParser::parseSetNoDspDirective() { 7147 MCAsmParser &Parser = getParser(); 7148 Parser.Lex(); // Eat "nodsp". 7149 7150 // If this is not the end of the statement, report an error. 7151 if (getLexer().isNot(AsmToken::EndOfStatement)) { 7152 reportParseError("unexpected token, expected end of statement"); 7153 return false; 7154 } 7155 7156 clearFeatureBits(Mips::FeatureDSP, "dsp"); 7157 getTargetStreamer().emitDirectiveSetNoDsp(); 7158 return false; 7159 } 7160 7161 bool MipsAsmParser::parseSetNoMips3DDirective() { 7162 MCAsmParser &Parser = getParser(); 7163 Parser.Lex(); // Eat "nomips3d". 7164 7165 // If this is not the end of the statement, report an error. 7166 if (getLexer().isNot(AsmToken::EndOfStatement)) { 7167 reportParseError("unexpected token, expected end of statement"); 7168 return false; 7169 } 7170 7171 clearFeatureBits(Mips::FeatureMips3D, "mips3d"); 7172 getTargetStreamer().emitDirectiveSetNoMips3D(); 7173 return false; 7174 } 7175 7176 bool MipsAsmParser::parseSetMips16Directive() { 7177 MCAsmParser &Parser = getParser(); 7178 Parser.Lex(); // Eat "mips16". 7179 7180 // If this is not the end of the statement, report an error. 7181 if (getLexer().isNot(AsmToken::EndOfStatement)) { 7182 reportParseError("unexpected token, expected end of statement"); 7183 return false; 7184 } 7185 7186 setFeatureBits(Mips::FeatureMips16, "mips16"); 7187 getTargetStreamer().emitDirectiveSetMips16(); 7188 Parser.Lex(); // Consume the EndOfStatement. 7189 return false; 7190 } 7191 7192 bool MipsAsmParser::parseSetNoMips16Directive() { 7193 MCAsmParser &Parser = getParser(); 7194 Parser.Lex(); // Eat "nomips16". 7195 7196 // If this is not the end of the statement, report an error. 7197 if (getLexer().isNot(AsmToken::EndOfStatement)) { 7198 reportParseError("unexpected token, expected end of statement"); 7199 return false; 7200 } 7201 7202 clearFeatureBits(Mips::FeatureMips16, "mips16"); 7203 getTargetStreamer().emitDirectiveSetNoMips16(); 7204 Parser.Lex(); // Consume the EndOfStatement. 7205 return false; 7206 } 7207 7208 bool MipsAsmParser::parseSetFpDirective() { 7209 MCAsmParser &Parser = getParser(); 7210 MipsABIFlagsSection::FpABIKind FpAbiVal; 7211 // Line can be: .set fp=32 7212 // .set fp=xx 7213 // .set fp=64 7214 Parser.Lex(); // Eat fp token 7215 AsmToken Tok = Parser.getTok(); 7216 if (Tok.isNot(AsmToken::Equal)) { 7217 reportParseError("unexpected token, expected equals sign '='"); 7218 return false; 7219 } 7220 Parser.Lex(); // Eat '=' token. 7221 Tok = Parser.getTok(); 7222 7223 if (!parseFpABIValue(FpAbiVal, ".set")) 7224 return false; 7225 7226 if (getLexer().isNot(AsmToken::EndOfStatement)) { 7227 reportParseError("unexpected token, expected end of statement"); 7228 return false; 7229 } 7230 getTargetStreamer().emitDirectiveSetFp(FpAbiVal); 7231 Parser.Lex(); // Consume the EndOfStatement. 7232 return false; 7233 } 7234 7235 bool MipsAsmParser::parseSetOddSPRegDirective() { 7236 MCAsmParser &Parser = getParser(); 7237 7238 Parser.Lex(); // Eat "oddspreg". 7239 if (getLexer().isNot(AsmToken::EndOfStatement)) { 7240 reportParseError("unexpected token, expected end of statement"); 7241 return false; 7242 } 7243 7244 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg"); 7245 getTargetStreamer().emitDirectiveSetOddSPReg(); 7246 return false; 7247 } 7248 7249 bool MipsAsmParser::parseSetNoOddSPRegDirective() { 7250 MCAsmParser &Parser = getParser(); 7251 7252 Parser.Lex(); // Eat "nooddspreg". 7253 if (getLexer().isNot(AsmToken::EndOfStatement)) { 7254 reportParseError("unexpected token, expected end of statement"); 7255 return false; 7256 } 7257 7258 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg"); 7259 getTargetStreamer().emitDirectiveSetNoOddSPReg(); 7260 return false; 7261 } 7262 7263 bool MipsAsmParser::parseSetMtDirective() { 7264 MCAsmParser &Parser = getParser(); 7265 Parser.Lex(); // Eat "mt". 7266 7267 // If this is not the end of the statement, report an error. 7268 if (getLexer().isNot(AsmToken::EndOfStatement)) { 7269 reportParseError("unexpected token, expected end of statement"); 7270 return false; 7271 } 7272 7273 setFeatureBits(Mips::FeatureMT, "mt"); 7274 getTargetStreamer().emitDirectiveSetMt(); 7275 Parser.Lex(); // Consume the EndOfStatement. 7276 return false; 7277 } 7278 7279 bool MipsAsmParser::parseSetNoMtDirective() { 7280 MCAsmParser &Parser = getParser(); 7281 Parser.Lex(); // Eat "nomt". 7282 7283 // If this is not the end of the statement, report an error. 7284 if (getLexer().isNot(AsmToken::EndOfStatement)) { 7285 reportParseError("unexpected token, expected end of statement"); 7286 return false; 7287 } 7288 7289 clearFeatureBits(Mips::FeatureMT, "mt"); 7290 7291 getTargetStreamer().emitDirectiveSetNoMt(); 7292 Parser.Lex(); // Consume the EndOfStatement. 7293 return false; 7294 } 7295 7296 bool MipsAsmParser::parseSetNoCRCDirective() { 7297 MCAsmParser &Parser = getParser(); 7298 Parser.Lex(); // Eat "nocrc". 7299 7300 // If this is not the end of the statement, report an error. 7301 if (getLexer().isNot(AsmToken::EndOfStatement)) { 7302 reportParseError("unexpected token, expected end of statement"); 7303 return false; 7304 } 7305 7306 clearFeatureBits(Mips::FeatureCRC, "crc"); 7307 7308 getTargetStreamer().emitDirectiveSetNoCRC(); 7309 Parser.Lex(); // Consume the EndOfStatement. 7310 return false; 7311 } 7312 7313 bool MipsAsmParser::parseSetNoVirtDirective() { 7314 MCAsmParser &Parser = getParser(); 7315 Parser.Lex(); // Eat "novirt". 7316 7317 // If this is not the end of the statement, report an error. 7318 if (getLexer().isNot(AsmToken::EndOfStatement)) { 7319 reportParseError("unexpected token, expected end of statement"); 7320 return false; 7321 } 7322 7323 clearFeatureBits(Mips::FeatureVirt, "virt"); 7324 7325 getTargetStreamer().emitDirectiveSetNoVirt(); 7326 Parser.Lex(); // Consume the EndOfStatement. 7327 return false; 7328 } 7329 7330 bool MipsAsmParser::parseSetNoGINVDirective() { 7331 MCAsmParser &Parser = getParser(); 7332 Parser.Lex(); // Eat "noginv". 7333 7334 // If this is not the end of the statement, report an error. 7335 if (getLexer().isNot(AsmToken::EndOfStatement)) { 7336 reportParseError("unexpected token, expected end of statement"); 7337 return false; 7338 } 7339 7340 clearFeatureBits(Mips::FeatureGINV, "ginv"); 7341 7342 getTargetStreamer().emitDirectiveSetNoGINV(); 7343 Parser.Lex(); // Consume the EndOfStatement. 7344 return false; 7345 } 7346 7347 bool MipsAsmParser::parseSetPopDirective() { 7348 MCAsmParser &Parser = getParser(); 7349 SMLoc Loc = getLexer().getLoc(); 7350 7351 Parser.Lex(); 7352 if (getLexer().isNot(AsmToken::EndOfStatement)) 7353 return reportParseError("unexpected token, expected end of statement"); 7354 7355 // Always keep an element on the options "stack" to prevent the user 7356 // from changing the initial options. This is how we remember them. 7357 if (AssemblerOptions.size() == 2) 7358 return reportParseError(Loc, ".set pop with no .set push"); 7359 7360 MCSubtargetInfo &STI = copySTI(); 7361 AssemblerOptions.pop_back(); 7362 setAvailableFeatures( 7363 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures())); 7364 STI.setFeatureBits(AssemblerOptions.back()->getFeatures()); 7365 7366 getTargetStreamer().emitDirectiveSetPop(); 7367 return false; 7368 } 7369 7370 bool MipsAsmParser::parseSetPushDirective() { 7371 MCAsmParser &Parser = getParser(); 7372 Parser.Lex(); 7373 if (getLexer().isNot(AsmToken::EndOfStatement)) 7374 return reportParseError("unexpected token, expected end of statement"); 7375 7376 // Create a copy of the current assembler options environment and push it. 7377 AssemblerOptions.push_back( 7378 std::make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get())); 7379 7380 getTargetStreamer().emitDirectiveSetPush(); 7381 return false; 7382 } 7383 7384 bool MipsAsmParser::parseSetSoftFloatDirective() { 7385 MCAsmParser &Parser = getParser(); 7386 Parser.Lex(); 7387 if (getLexer().isNot(AsmToken::EndOfStatement)) 7388 return reportParseError("unexpected token, expected end of statement"); 7389 7390 setFeatureBits(Mips::FeatureSoftFloat, "soft-float"); 7391 getTargetStreamer().emitDirectiveSetSoftFloat(); 7392 return false; 7393 } 7394 7395 bool MipsAsmParser::parseSetHardFloatDirective() { 7396 MCAsmParser &Parser = getParser(); 7397 Parser.Lex(); 7398 if (getLexer().isNot(AsmToken::EndOfStatement)) 7399 return reportParseError("unexpected token, expected end of statement"); 7400 7401 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float"); 7402 getTargetStreamer().emitDirectiveSetHardFloat(); 7403 return false; 7404 } 7405 7406 bool MipsAsmParser::parseSetAssignment() { 7407 StringRef Name; 7408 MCAsmParser &Parser = getParser(); 7409 7410 if (Parser.parseIdentifier(Name)) 7411 return reportParseError("expected identifier after .set"); 7412 7413 if (getLexer().isNot(AsmToken::Comma)) 7414 return reportParseError("unexpected token, expected comma"); 7415 Lex(); // Eat comma 7416 7417 if (getLexer().is(AsmToken::Dollar) && 7418 getLexer().peekTok().is(AsmToken::Integer)) { 7419 // Parse assignment of a numeric register: 7420 // .set r1,$1 7421 Parser.Lex(); // Eat $. 7422 RegisterSets[Name] = Parser.getTok(); 7423 Parser.Lex(); // Eat identifier. 7424 getContext().getOrCreateSymbol(Name); 7425 return false; 7426 } 7427 7428 MCSymbol *Sym; 7429 const MCExpr *Value; 7430 if (MCParserUtils::parseAssignmentExpression(Name, /* allow_redef */ true, 7431 Parser, Sym, Value)) 7432 return true; 7433 Sym->setVariableValue(Value); 7434 7435 return false; 7436 } 7437 7438 bool MipsAsmParser::parseSetMips0Directive() { 7439 MCAsmParser &Parser = getParser(); 7440 Parser.Lex(); 7441 if (getLexer().isNot(AsmToken::EndOfStatement)) 7442 return reportParseError("unexpected token, expected end of statement"); 7443 7444 // Reset assembler options to their initial values. 7445 MCSubtargetInfo &STI = copySTI(); 7446 setAvailableFeatures( 7447 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures())); 7448 STI.setFeatureBits(AssemblerOptions.front()->getFeatures()); 7449 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures()); 7450 7451 getTargetStreamer().emitDirectiveSetMips0(); 7452 return false; 7453 } 7454 7455 bool MipsAsmParser::parseSetArchDirective() { 7456 MCAsmParser &Parser = getParser(); 7457 Parser.Lex(); 7458 if (getLexer().isNot(AsmToken::Equal)) 7459 return reportParseError("unexpected token, expected equals sign"); 7460 7461 Parser.Lex(); 7462 StringRef Arch = getParser().parseStringToEndOfStatement().trim(); 7463 if (Arch.empty()) 7464 return reportParseError("expected arch identifier"); 7465 7466 StringRef ArchFeatureName = 7467 StringSwitch<StringRef>(Arch) 7468 .Case("mips1", "mips1") 7469 .Case("mips2", "mips2") 7470 .Case("mips3", "mips3") 7471 .Case("mips4", "mips4") 7472 .Case("mips5", "mips5") 7473 .Case("mips32", "mips32") 7474 .Case("mips32r2", "mips32r2") 7475 .Case("mips32r3", "mips32r3") 7476 .Case("mips32r5", "mips32r5") 7477 .Case("mips32r6", "mips32r6") 7478 .Case("mips64", "mips64") 7479 .Case("mips64r2", "mips64r2") 7480 .Case("mips64r3", "mips64r3") 7481 .Case("mips64r5", "mips64r5") 7482 .Case("mips64r6", "mips64r6") 7483 .Case("octeon", "cnmips") 7484 .Case("octeon+", "cnmipsp") 7485 .Case("r4000", "mips3") // This is an implementation of Mips3. 7486 .Default(""); 7487 7488 if (ArchFeatureName.empty()) 7489 return reportParseError("unsupported architecture"); 7490 7491 if (ArchFeatureName == "mips64r6" && inMicroMipsMode()) 7492 return reportParseError("mips64r6 does not support microMIPS"); 7493 7494 selectArch(ArchFeatureName); 7495 getTargetStreamer().emitDirectiveSetArch(Arch); 7496 return false; 7497 } 7498 7499 bool MipsAsmParser::parseSetFeature(uint64_t Feature) { 7500 MCAsmParser &Parser = getParser(); 7501 Parser.Lex(); 7502 if (getLexer().isNot(AsmToken::EndOfStatement)) 7503 return reportParseError("unexpected token, expected end of statement"); 7504 7505 switch (Feature) { 7506 default: 7507 llvm_unreachable("Unimplemented feature"); 7508 case Mips::FeatureMips3D: 7509 setFeatureBits(Mips::FeatureMips3D, "mips3d"); 7510 getTargetStreamer().emitDirectiveSetMips3D(); 7511 break; 7512 case Mips::FeatureDSP: 7513 setFeatureBits(Mips::FeatureDSP, "dsp"); 7514 getTargetStreamer().emitDirectiveSetDsp(); 7515 break; 7516 case Mips::FeatureDSPR2: 7517 setFeatureBits(Mips::FeatureDSPR2, "dspr2"); 7518 getTargetStreamer().emitDirectiveSetDspr2(); 7519 break; 7520 case Mips::FeatureMicroMips: 7521 setFeatureBits(Mips::FeatureMicroMips, "micromips"); 7522 getTargetStreamer().emitDirectiveSetMicroMips(); 7523 break; 7524 case Mips::FeatureMips1: 7525 selectArch("mips1"); 7526 getTargetStreamer().emitDirectiveSetMips1(); 7527 break; 7528 case Mips::FeatureMips2: 7529 selectArch("mips2"); 7530 getTargetStreamer().emitDirectiveSetMips2(); 7531 break; 7532 case Mips::FeatureMips3: 7533 selectArch("mips3"); 7534 getTargetStreamer().emitDirectiveSetMips3(); 7535 break; 7536 case Mips::FeatureMips4: 7537 selectArch("mips4"); 7538 getTargetStreamer().emitDirectiveSetMips4(); 7539 break; 7540 case Mips::FeatureMips5: 7541 selectArch("mips5"); 7542 getTargetStreamer().emitDirectiveSetMips5(); 7543 break; 7544 case Mips::FeatureMips32: 7545 selectArch("mips32"); 7546 getTargetStreamer().emitDirectiveSetMips32(); 7547 break; 7548 case Mips::FeatureMips32r2: 7549 selectArch("mips32r2"); 7550 getTargetStreamer().emitDirectiveSetMips32R2(); 7551 break; 7552 case Mips::FeatureMips32r3: 7553 selectArch("mips32r3"); 7554 getTargetStreamer().emitDirectiveSetMips32R3(); 7555 break; 7556 case Mips::FeatureMips32r5: 7557 selectArch("mips32r5"); 7558 getTargetStreamer().emitDirectiveSetMips32R5(); 7559 break; 7560 case Mips::FeatureMips32r6: 7561 selectArch("mips32r6"); 7562 getTargetStreamer().emitDirectiveSetMips32R6(); 7563 break; 7564 case Mips::FeatureMips64: 7565 selectArch("mips64"); 7566 getTargetStreamer().emitDirectiveSetMips64(); 7567 break; 7568 case Mips::FeatureMips64r2: 7569 selectArch("mips64r2"); 7570 getTargetStreamer().emitDirectiveSetMips64R2(); 7571 break; 7572 case Mips::FeatureMips64r3: 7573 selectArch("mips64r3"); 7574 getTargetStreamer().emitDirectiveSetMips64R3(); 7575 break; 7576 case Mips::FeatureMips64r5: 7577 selectArch("mips64r5"); 7578 getTargetStreamer().emitDirectiveSetMips64R5(); 7579 break; 7580 case Mips::FeatureMips64r6: 7581 selectArch("mips64r6"); 7582 getTargetStreamer().emitDirectiveSetMips64R6(); 7583 break; 7584 case Mips::FeatureCRC: 7585 setFeatureBits(Mips::FeatureCRC, "crc"); 7586 getTargetStreamer().emitDirectiveSetCRC(); 7587 break; 7588 case Mips::FeatureVirt: 7589 setFeatureBits(Mips::FeatureVirt, "virt"); 7590 getTargetStreamer().emitDirectiveSetVirt(); 7591 break; 7592 case Mips::FeatureGINV: 7593 setFeatureBits(Mips::FeatureGINV, "ginv"); 7594 getTargetStreamer().emitDirectiveSetGINV(); 7595 break; 7596 } 7597 return false; 7598 } 7599 7600 bool MipsAsmParser::eatComma(StringRef ErrorStr) { 7601 MCAsmParser &Parser = getParser(); 7602 if (getLexer().isNot(AsmToken::Comma)) { 7603 SMLoc Loc = getLexer().getLoc(); 7604 return Error(Loc, ErrorStr); 7605 } 7606 7607 Parser.Lex(); // Eat the comma. 7608 return true; 7609 } 7610 7611 // Used to determine if .cpload, .cprestore, and .cpsetup have any effect. 7612 // In this class, it is only used for .cprestore. 7613 // FIXME: Only keep track of IsPicEnabled in one place, instead of in both 7614 // MipsTargetELFStreamer and MipsAsmParser. 7615 bool MipsAsmParser::isPicAndNotNxxAbi() { 7616 return inPicMode() && !(isABI_N32() || isABI_N64()); 7617 } 7618 7619 bool MipsAsmParser::parseDirectiveCpAdd(SMLoc Loc) { 7620 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg; 7621 ParseStatus Res = parseAnyRegister(Reg); 7622 if (Res.isNoMatch() || Res.isFailure()) { 7623 reportParseError("expected register"); 7624 return false; 7625 } 7626 7627 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]); 7628 if (!RegOpnd.isGPRAsmReg()) { 7629 reportParseError(RegOpnd.getStartLoc(), "invalid register"); 7630 return false; 7631 } 7632 7633 // If this is not the end of the statement, report an error. 7634 if (getLexer().isNot(AsmToken::EndOfStatement)) { 7635 reportParseError("unexpected token, expected end of statement"); 7636 return false; 7637 } 7638 getParser().Lex(); // Consume the EndOfStatement. 7639 7640 getTargetStreamer().emitDirectiveCpAdd(RegOpnd.getGPR32Reg()); 7641 return false; 7642 } 7643 7644 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) { 7645 if (AssemblerOptions.back()->isReorder()) 7646 Warning(Loc, ".cpload should be inside a noreorder section"); 7647 7648 if (inMips16Mode()) { 7649 reportParseError(".cpload is not supported in Mips16 mode"); 7650 return false; 7651 } 7652 7653 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg; 7654 ParseStatus Res = parseAnyRegister(Reg); 7655 if (Res.isNoMatch() || Res.isFailure()) { 7656 reportParseError("expected register containing function address"); 7657 return false; 7658 } 7659 7660 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]); 7661 if (!RegOpnd.isGPRAsmReg()) { 7662 reportParseError(RegOpnd.getStartLoc(), "invalid register"); 7663 return false; 7664 } 7665 7666 // If this is not the end of the statement, report an error. 7667 if (getLexer().isNot(AsmToken::EndOfStatement)) { 7668 reportParseError("unexpected token, expected end of statement"); 7669 return false; 7670 } 7671 7672 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg()); 7673 return false; 7674 } 7675 7676 bool MipsAsmParser::parseDirectiveCpLocal(SMLoc Loc) { 7677 if (!isABI_N32() && !isABI_N64()) { 7678 reportParseError(".cplocal is allowed only in N32 or N64 mode"); 7679 return false; 7680 } 7681 7682 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg; 7683 ParseStatus Res = parseAnyRegister(Reg); 7684 if (Res.isNoMatch() || Res.isFailure()) { 7685 reportParseError("expected register containing global pointer"); 7686 return false; 7687 } 7688 7689 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]); 7690 if (!RegOpnd.isGPRAsmReg()) { 7691 reportParseError(RegOpnd.getStartLoc(), "invalid register"); 7692 return false; 7693 } 7694 7695 // If this is not the end of the statement, report an error. 7696 if (getLexer().isNot(AsmToken::EndOfStatement)) { 7697 reportParseError("unexpected token, expected end of statement"); 7698 return false; 7699 } 7700 getParser().Lex(); // Consume the EndOfStatement. 7701 7702 unsigned NewReg = RegOpnd.getGPR32Reg(); 7703 if (IsPicEnabled) 7704 GPReg = NewReg; 7705 7706 getTargetStreamer().emitDirectiveCpLocal(NewReg); 7707 return false; 7708 } 7709 7710 bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) { 7711 MCAsmParser &Parser = getParser(); 7712 7713 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it 7714 // is used in non-PIC mode. 7715 7716 if (inMips16Mode()) { 7717 reportParseError(".cprestore is not supported in Mips16 mode"); 7718 return false; 7719 } 7720 7721 // Get the stack offset value. 7722 const MCExpr *StackOffset; 7723 int64_t StackOffsetVal; 7724 if (Parser.parseExpression(StackOffset)) { 7725 reportParseError("expected stack offset value"); 7726 return false; 7727 } 7728 7729 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) { 7730 reportParseError("stack offset is not an absolute expression"); 7731 return false; 7732 } 7733 7734 if (StackOffsetVal < 0) { 7735 Warning(Loc, ".cprestore with negative stack offset has no effect"); 7736 IsCpRestoreSet = false; 7737 } else { 7738 IsCpRestoreSet = true; 7739 CpRestoreOffset = StackOffsetVal; 7740 } 7741 7742 // If this is not the end of the statement, report an error. 7743 if (getLexer().isNot(AsmToken::EndOfStatement)) { 7744 reportParseError("unexpected token, expected end of statement"); 7745 return false; 7746 } 7747 7748 if (!getTargetStreamer().emitDirectiveCpRestore( 7749 CpRestoreOffset, [&]() { return getATReg(Loc); }, Loc, STI)) 7750 return true; 7751 Parser.Lex(); // Consume the EndOfStatement. 7752 return false; 7753 } 7754 7755 bool MipsAsmParser::parseDirectiveCPSetup() { 7756 MCAsmParser &Parser = getParser(); 7757 unsigned FuncReg; 7758 unsigned Save; 7759 bool SaveIsReg = true; 7760 7761 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg; 7762 ParseStatus Res = parseAnyRegister(TmpReg); 7763 if (Res.isNoMatch()) { 7764 reportParseError("expected register containing function address"); 7765 return false; 7766 } 7767 7768 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]); 7769 if (!FuncRegOpnd.isGPRAsmReg()) { 7770 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register"); 7771 return false; 7772 } 7773 7774 FuncReg = FuncRegOpnd.getGPR32Reg(); 7775 TmpReg.clear(); 7776 7777 if (!eatComma("unexpected token, expected comma")) 7778 return true; 7779 7780 Res = parseAnyRegister(TmpReg); 7781 if (Res.isNoMatch()) { 7782 const MCExpr *OffsetExpr; 7783 int64_t OffsetVal; 7784 SMLoc ExprLoc = getLexer().getLoc(); 7785 7786 if (Parser.parseExpression(OffsetExpr) || 7787 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) { 7788 reportParseError(ExprLoc, "expected save register or stack offset"); 7789 return false; 7790 } 7791 7792 Save = OffsetVal; 7793 SaveIsReg = false; 7794 } else { 7795 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]); 7796 if (!SaveOpnd.isGPRAsmReg()) { 7797 reportParseError(SaveOpnd.getStartLoc(), "invalid register"); 7798 return false; 7799 } 7800 Save = SaveOpnd.getGPR32Reg(); 7801 } 7802 7803 if (!eatComma("unexpected token, expected comma")) 7804 return true; 7805 7806 const MCExpr *Expr; 7807 if (Parser.parseExpression(Expr)) { 7808 reportParseError("expected expression"); 7809 return false; 7810 } 7811 7812 if (Expr->getKind() != MCExpr::SymbolRef) { 7813 reportParseError("expected symbol"); 7814 return false; 7815 } 7816 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr); 7817 7818 CpSaveLocation = Save; 7819 CpSaveLocationIsRegister = SaveIsReg; 7820 7821 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(), 7822 SaveIsReg); 7823 return false; 7824 } 7825 7826 bool MipsAsmParser::parseDirectiveCPReturn() { 7827 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation, 7828 CpSaveLocationIsRegister); 7829 return false; 7830 } 7831 7832 bool MipsAsmParser::parseDirectiveNaN() { 7833 MCAsmParser &Parser = getParser(); 7834 if (getLexer().isNot(AsmToken::EndOfStatement)) { 7835 const AsmToken &Tok = Parser.getTok(); 7836 7837 if (Tok.getString() == "2008") { 7838 Parser.Lex(); 7839 getTargetStreamer().emitDirectiveNaN2008(); 7840 return false; 7841 } else if (Tok.getString() == "legacy") { 7842 Parser.Lex(); 7843 getTargetStreamer().emitDirectiveNaNLegacy(); 7844 return false; 7845 } 7846 } 7847 // If we don't recognize the option passed to the .nan 7848 // directive (e.g. no option or unknown option), emit an error. 7849 reportParseError("invalid option in .nan directive"); 7850 return false; 7851 } 7852 7853 bool MipsAsmParser::parseDirectiveSet() { 7854 const AsmToken &Tok = getParser().getTok(); 7855 StringRef IdVal = Tok.getString(); 7856 SMLoc Loc = Tok.getLoc(); 7857 7858 if (IdVal == "noat") 7859 return parseSetNoAtDirective(); 7860 if (IdVal == "at") 7861 return parseSetAtDirective(); 7862 if (IdVal == "arch") 7863 return parseSetArchDirective(); 7864 if (IdVal == "bopt") { 7865 Warning(Loc, "'bopt' feature is unsupported"); 7866 getParser().Lex(); 7867 return false; 7868 } 7869 if (IdVal == "nobopt") { 7870 // We're already running in nobopt mode, so nothing to do. 7871 getParser().Lex(); 7872 return false; 7873 } 7874 if (IdVal == "fp") 7875 return parseSetFpDirective(); 7876 if (IdVal == "oddspreg") 7877 return parseSetOddSPRegDirective(); 7878 if (IdVal == "nooddspreg") 7879 return parseSetNoOddSPRegDirective(); 7880 if (IdVal == "pop") 7881 return parseSetPopDirective(); 7882 if (IdVal == "push") 7883 return parseSetPushDirective(); 7884 if (IdVal == "reorder") 7885 return parseSetReorderDirective(); 7886 if (IdVal == "noreorder") 7887 return parseSetNoReorderDirective(); 7888 if (IdVal == "macro") 7889 return parseSetMacroDirective(); 7890 if (IdVal == "nomacro") 7891 return parseSetNoMacroDirective(); 7892 if (IdVal == "mips16") 7893 return parseSetMips16Directive(); 7894 if (IdVal == "nomips16") 7895 return parseSetNoMips16Directive(); 7896 if (IdVal == "nomicromips") { 7897 clearFeatureBits(Mips::FeatureMicroMips, "micromips"); 7898 getTargetStreamer().emitDirectiveSetNoMicroMips(); 7899 getParser().eatToEndOfStatement(); 7900 return false; 7901 } 7902 if (IdVal == "micromips") { 7903 if (hasMips64r6()) { 7904 Error(Loc, ".set micromips directive is not supported with MIPS64R6"); 7905 return false; 7906 } 7907 return parseSetFeature(Mips::FeatureMicroMips); 7908 } 7909 if (IdVal == "mips0") 7910 return parseSetMips0Directive(); 7911 if (IdVal == "mips1") 7912 return parseSetFeature(Mips::FeatureMips1); 7913 if (IdVal == "mips2") 7914 return parseSetFeature(Mips::FeatureMips2); 7915 if (IdVal == "mips3") 7916 return parseSetFeature(Mips::FeatureMips3); 7917 if (IdVal == "mips4") 7918 return parseSetFeature(Mips::FeatureMips4); 7919 if (IdVal == "mips5") 7920 return parseSetFeature(Mips::FeatureMips5); 7921 if (IdVal == "mips32") 7922 return parseSetFeature(Mips::FeatureMips32); 7923 if (IdVal == "mips32r2") 7924 return parseSetFeature(Mips::FeatureMips32r2); 7925 if (IdVal == "mips32r3") 7926 return parseSetFeature(Mips::FeatureMips32r3); 7927 if (IdVal == "mips32r5") 7928 return parseSetFeature(Mips::FeatureMips32r5); 7929 if (IdVal == "mips32r6") 7930 return parseSetFeature(Mips::FeatureMips32r6); 7931 if (IdVal == "mips64") 7932 return parseSetFeature(Mips::FeatureMips64); 7933 if (IdVal == "mips64r2") 7934 return parseSetFeature(Mips::FeatureMips64r2); 7935 if (IdVal == "mips64r3") 7936 return parseSetFeature(Mips::FeatureMips64r3); 7937 if (IdVal == "mips64r5") 7938 return parseSetFeature(Mips::FeatureMips64r5); 7939 if (IdVal == "mips64r6") { 7940 if (inMicroMipsMode()) { 7941 Error(Loc, "MIPS64R6 is not supported with microMIPS"); 7942 return false; 7943 } 7944 return parseSetFeature(Mips::FeatureMips64r6); 7945 } 7946 if (IdVal == "dsp") 7947 return parseSetFeature(Mips::FeatureDSP); 7948 if (IdVal == "dspr2") 7949 return parseSetFeature(Mips::FeatureDSPR2); 7950 if (IdVal == "nodsp") 7951 return parseSetNoDspDirective(); 7952 if (IdVal == "mips3d") 7953 return parseSetFeature(Mips::FeatureMips3D); 7954 if (IdVal == "nomips3d") 7955 return parseSetNoMips3DDirective(); 7956 if (IdVal == "msa") 7957 return parseSetMsaDirective(); 7958 if (IdVal == "nomsa") 7959 return parseSetNoMsaDirective(); 7960 if (IdVal == "mt") 7961 return parseSetMtDirective(); 7962 if (IdVal == "nomt") 7963 return parseSetNoMtDirective(); 7964 if (IdVal == "softfloat") 7965 return parseSetSoftFloatDirective(); 7966 if (IdVal == "hardfloat") 7967 return parseSetHardFloatDirective(); 7968 if (IdVal == "crc") 7969 return parseSetFeature(Mips::FeatureCRC); 7970 if (IdVal == "nocrc") 7971 return parseSetNoCRCDirective(); 7972 if (IdVal == "virt") 7973 return parseSetFeature(Mips::FeatureVirt); 7974 if (IdVal == "novirt") 7975 return parseSetNoVirtDirective(); 7976 if (IdVal == "ginv") 7977 return parseSetFeature(Mips::FeatureGINV); 7978 if (IdVal == "noginv") 7979 return parseSetNoGINVDirective(); 7980 7981 // It is just an identifier, look for an assignment. 7982 return parseSetAssignment(); 7983 } 7984 7985 /// parseDirectiveGpWord 7986 /// ::= .gpword local_sym 7987 bool MipsAsmParser::parseDirectiveGpWord() { 7988 MCAsmParser &Parser = getParser(); 7989 const MCExpr *Value; 7990 // EmitGPRel32Value requires an expression, so we are using base class 7991 // method to evaluate the expression. 7992 if (getParser().parseExpression(Value)) 7993 return true; 7994 getParser().getStreamer().emitGPRel32Value(Value); 7995 7996 if (getLexer().isNot(AsmToken::EndOfStatement)) 7997 return Error(getLexer().getLoc(), 7998 "unexpected token, expected end of statement"); 7999 Parser.Lex(); // Eat EndOfStatement token. 8000 return false; 8001 } 8002 8003 /// parseDirectiveGpDWord 8004 /// ::= .gpdword local_sym 8005 bool MipsAsmParser::parseDirectiveGpDWord() { 8006 MCAsmParser &Parser = getParser(); 8007 const MCExpr *Value; 8008 // EmitGPRel64Value requires an expression, so we are using base class 8009 // method to evaluate the expression. 8010 if (getParser().parseExpression(Value)) 8011 return true; 8012 getParser().getStreamer().emitGPRel64Value(Value); 8013 8014 if (getLexer().isNot(AsmToken::EndOfStatement)) 8015 return Error(getLexer().getLoc(), 8016 "unexpected token, expected end of statement"); 8017 Parser.Lex(); // Eat EndOfStatement token. 8018 return false; 8019 } 8020 8021 /// parseDirectiveDtpRelWord 8022 /// ::= .dtprelword tls_sym 8023 bool MipsAsmParser::parseDirectiveDtpRelWord() { 8024 MCAsmParser &Parser = getParser(); 8025 const MCExpr *Value; 8026 // EmitDTPRel32Value requires an expression, so we are using base class 8027 // method to evaluate the expression. 8028 if (getParser().parseExpression(Value)) 8029 return true; 8030 getParser().getStreamer().emitDTPRel32Value(Value); 8031 8032 if (getLexer().isNot(AsmToken::EndOfStatement)) 8033 return Error(getLexer().getLoc(), 8034 "unexpected token, expected end of statement"); 8035 Parser.Lex(); // Eat EndOfStatement token. 8036 return false; 8037 } 8038 8039 /// parseDirectiveDtpRelDWord 8040 /// ::= .dtpreldword tls_sym 8041 bool MipsAsmParser::parseDirectiveDtpRelDWord() { 8042 MCAsmParser &Parser = getParser(); 8043 const MCExpr *Value; 8044 // EmitDTPRel64Value requires an expression, so we are using base class 8045 // method to evaluate the expression. 8046 if (getParser().parseExpression(Value)) 8047 return true; 8048 getParser().getStreamer().emitDTPRel64Value(Value); 8049 8050 if (getLexer().isNot(AsmToken::EndOfStatement)) 8051 return Error(getLexer().getLoc(), 8052 "unexpected token, expected end of statement"); 8053 Parser.Lex(); // Eat EndOfStatement token. 8054 return false; 8055 } 8056 8057 /// parseDirectiveTpRelWord 8058 /// ::= .tprelword tls_sym 8059 bool MipsAsmParser::parseDirectiveTpRelWord() { 8060 MCAsmParser &Parser = getParser(); 8061 const MCExpr *Value; 8062 // EmitTPRel32Value requires an expression, so we are using base class 8063 // method to evaluate the expression. 8064 if (getParser().parseExpression(Value)) 8065 return true; 8066 getParser().getStreamer().emitTPRel32Value(Value); 8067 8068 if (getLexer().isNot(AsmToken::EndOfStatement)) 8069 return Error(getLexer().getLoc(), 8070 "unexpected token, expected end of statement"); 8071 Parser.Lex(); // Eat EndOfStatement token. 8072 return false; 8073 } 8074 8075 /// parseDirectiveTpRelDWord 8076 /// ::= .tpreldword tls_sym 8077 bool MipsAsmParser::parseDirectiveTpRelDWord() { 8078 MCAsmParser &Parser = getParser(); 8079 const MCExpr *Value; 8080 // EmitTPRel64Value requires an expression, so we are using base class 8081 // method to evaluate the expression. 8082 if (getParser().parseExpression(Value)) 8083 return true; 8084 getParser().getStreamer().emitTPRel64Value(Value); 8085 8086 if (getLexer().isNot(AsmToken::EndOfStatement)) 8087 return Error(getLexer().getLoc(), 8088 "unexpected token, expected end of statement"); 8089 Parser.Lex(); // Eat EndOfStatement token. 8090 return false; 8091 } 8092 8093 bool MipsAsmParser::parseDirectiveOption() { 8094 MCAsmParser &Parser = getParser(); 8095 // Get the option token. 8096 AsmToken Tok = Parser.getTok(); 8097 // At the moment only identifiers are supported. 8098 if (Tok.isNot(AsmToken::Identifier)) { 8099 return Error(Parser.getTok().getLoc(), 8100 "unexpected token, expected identifier"); 8101 } 8102 8103 StringRef Option = Tok.getIdentifier(); 8104 8105 if (Option == "pic0") { 8106 // MipsAsmParser needs to know if the current PIC mode changes. 8107 IsPicEnabled = false; 8108 8109 getTargetStreamer().emitDirectiveOptionPic0(); 8110 Parser.Lex(); 8111 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) { 8112 return Error(Parser.getTok().getLoc(), 8113 "unexpected token, expected end of statement"); 8114 } 8115 return false; 8116 } 8117 8118 if (Option == "pic2") { 8119 // MipsAsmParser needs to know if the current PIC mode changes. 8120 IsPicEnabled = true; 8121 8122 getTargetStreamer().emitDirectiveOptionPic2(); 8123 Parser.Lex(); 8124 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) { 8125 return Error(Parser.getTok().getLoc(), 8126 "unexpected token, expected end of statement"); 8127 } 8128 return false; 8129 } 8130 8131 // Unknown option. 8132 Warning(Parser.getTok().getLoc(), 8133 "unknown option, expected 'pic0' or 'pic2'"); 8134 Parser.eatToEndOfStatement(); 8135 return false; 8136 } 8137 8138 /// parseInsnDirective 8139 /// ::= .insn 8140 bool MipsAsmParser::parseInsnDirective() { 8141 // If this is not the end of the statement, report an error. 8142 if (getLexer().isNot(AsmToken::EndOfStatement)) { 8143 reportParseError("unexpected token, expected end of statement"); 8144 return false; 8145 } 8146 8147 // The actual label marking happens in 8148 // MipsELFStreamer::createPendingLabelRelocs(). 8149 getTargetStreamer().emitDirectiveInsn(); 8150 8151 getParser().Lex(); // Eat EndOfStatement token. 8152 return false; 8153 } 8154 8155 /// parseRSectionDirective 8156 /// ::= .rdata 8157 bool MipsAsmParser::parseRSectionDirective(StringRef Section) { 8158 // If this is not the end of the statement, report an error. 8159 if (getLexer().isNot(AsmToken::EndOfStatement)) { 8160 reportParseError("unexpected token, expected end of statement"); 8161 return false; 8162 } 8163 8164 MCSection *ELFSection = getContext().getELFSection( 8165 Section, ELF::SHT_PROGBITS, ELF::SHF_ALLOC); 8166 getParser().getStreamer().switchSection(ELFSection); 8167 8168 getParser().Lex(); // Eat EndOfStatement token. 8169 return false; 8170 } 8171 8172 /// parseSSectionDirective 8173 /// ::= .sbss 8174 /// ::= .sdata 8175 bool MipsAsmParser::parseSSectionDirective(StringRef Section, unsigned Type) { 8176 // If this is not the end of the statement, report an error. 8177 if (getLexer().isNot(AsmToken::EndOfStatement)) { 8178 reportParseError("unexpected token, expected end of statement"); 8179 return false; 8180 } 8181 8182 MCSection *ELFSection = getContext().getELFSection( 8183 Section, Type, ELF::SHF_WRITE | ELF::SHF_ALLOC | ELF::SHF_MIPS_GPREL); 8184 getParser().getStreamer().switchSection(ELFSection); 8185 8186 getParser().Lex(); // Eat EndOfStatement token. 8187 return false; 8188 } 8189 8190 /// parseDirectiveModule 8191 /// ::= .module oddspreg 8192 /// ::= .module nooddspreg 8193 /// ::= .module fp=value 8194 /// ::= .module softfloat 8195 /// ::= .module hardfloat 8196 /// ::= .module mt 8197 /// ::= .module crc 8198 /// ::= .module nocrc 8199 /// ::= .module virt 8200 /// ::= .module novirt 8201 /// ::= .module ginv 8202 /// ::= .module noginv 8203 bool MipsAsmParser::parseDirectiveModule() { 8204 MCAsmParser &Parser = getParser(); 8205 MCAsmLexer &Lexer = getLexer(); 8206 SMLoc L = Lexer.getLoc(); 8207 8208 if (!getTargetStreamer().isModuleDirectiveAllowed()) { 8209 // TODO : get a better message. 8210 reportParseError(".module directive must appear before any code"); 8211 return false; 8212 } 8213 8214 StringRef Option; 8215 if (Parser.parseIdentifier(Option)) { 8216 reportParseError("expected .module option identifier"); 8217 return false; 8218 } 8219 8220 if (Option == "oddspreg") { 8221 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg"); 8222 8223 // Synchronize the abiflags information with the FeatureBits information we 8224 // changed above. 8225 getTargetStreamer().updateABIInfo(*this); 8226 8227 // If printing assembly, use the recently updated abiflags information. 8228 // If generating ELF, don't do anything (the .MIPS.abiflags section gets 8229 // emitted at the end). 8230 getTargetStreamer().emitDirectiveModuleOddSPReg(); 8231 8232 // If this is not the end of the statement, report an error. 8233 if (getLexer().isNot(AsmToken::EndOfStatement)) { 8234 reportParseError("unexpected token, expected end of statement"); 8235 return false; 8236 } 8237 8238 return false; // parseDirectiveModule has finished successfully. 8239 } else if (Option == "nooddspreg") { 8240 if (!isABI_O32()) { 8241 return Error(L, "'.module nooddspreg' requires the O32 ABI"); 8242 } 8243 8244 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg"); 8245 8246 // Synchronize the abiflags information with the FeatureBits information we 8247 // changed above. 8248 getTargetStreamer().updateABIInfo(*this); 8249 8250 // If printing assembly, use the recently updated abiflags information. 8251 // If generating ELF, don't do anything (the .MIPS.abiflags section gets 8252 // emitted at the end). 8253 getTargetStreamer().emitDirectiveModuleOddSPReg(); 8254 8255 // If this is not the end of the statement, report an error. 8256 if (getLexer().isNot(AsmToken::EndOfStatement)) { 8257 reportParseError("unexpected token, expected end of statement"); 8258 return false; 8259 } 8260 8261 return false; // parseDirectiveModule has finished successfully. 8262 } else if (Option == "fp") { 8263 return parseDirectiveModuleFP(); 8264 } else if (Option == "softfloat") { 8265 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float"); 8266 8267 // Synchronize the ABI Flags information with the FeatureBits information we 8268 // updated above. 8269 getTargetStreamer().updateABIInfo(*this); 8270 8271 // If printing assembly, use the recently updated ABI Flags information. 8272 // If generating ELF, don't do anything (the .MIPS.abiflags section gets 8273 // emitted later). 8274 getTargetStreamer().emitDirectiveModuleSoftFloat(); 8275 8276 // If this is not the end of the statement, report an error. 8277 if (getLexer().isNot(AsmToken::EndOfStatement)) { 8278 reportParseError("unexpected token, expected end of statement"); 8279 return false; 8280 } 8281 8282 return false; // parseDirectiveModule has finished successfully. 8283 } else if (Option == "hardfloat") { 8284 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float"); 8285 8286 // Synchronize the ABI Flags information with the FeatureBits information we 8287 // updated above. 8288 getTargetStreamer().updateABIInfo(*this); 8289 8290 // If printing assembly, use the recently updated ABI Flags information. 8291 // If generating ELF, don't do anything (the .MIPS.abiflags section gets 8292 // emitted later). 8293 getTargetStreamer().emitDirectiveModuleHardFloat(); 8294 8295 // If this is not the end of the statement, report an error. 8296 if (getLexer().isNot(AsmToken::EndOfStatement)) { 8297 reportParseError("unexpected token, expected end of statement"); 8298 return false; 8299 } 8300 8301 return false; // parseDirectiveModule has finished successfully. 8302 } else if (Option == "mt") { 8303 setModuleFeatureBits(Mips::FeatureMT, "mt"); 8304 8305 // Synchronize the ABI Flags information with the FeatureBits information we 8306 // updated above. 8307 getTargetStreamer().updateABIInfo(*this); 8308 8309 // If printing assembly, use the recently updated ABI Flags information. 8310 // If generating ELF, don't do anything (the .MIPS.abiflags section gets 8311 // emitted later). 8312 getTargetStreamer().emitDirectiveModuleMT(); 8313 8314 // If this is not the end of the statement, report an error. 8315 if (getLexer().isNot(AsmToken::EndOfStatement)) { 8316 reportParseError("unexpected token, expected end of statement"); 8317 return false; 8318 } 8319 8320 return false; // parseDirectiveModule has finished successfully. 8321 } else if (Option == "crc") { 8322 setModuleFeatureBits(Mips::FeatureCRC, "crc"); 8323 8324 // Synchronize the ABI Flags information with the FeatureBits information we 8325 // updated above. 8326 getTargetStreamer().updateABIInfo(*this); 8327 8328 // If printing assembly, use the recently updated ABI Flags information. 8329 // If generating ELF, don't do anything (the .MIPS.abiflags section gets 8330 // emitted later). 8331 getTargetStreamer().emitDirectiveModuleCRC(); 8332 8333 // If this is not the end of the statement, report an error. 8334 if (getLexer().isNot(AsmToken::EndOfStatement)) { 8335 reportParseError("unexpected token, expected end of statement"); 8336 return false; 8337 } 8338 8339 return false; // parseDirectiveModule has finished successfully. 8340 } else if (Option == "nocrc") { 8341 clearModuleFeatureBits(Mips::FeatureCRC, "crc"); 8342 8343 // Synchronize the ABI Flags information with the FeatureBits information we 8344 // updated above. 8345 getTargetStreamer().updateABIInfo(*this); 8346 8347 // If printing assembly, use the recently updated ABI Flags information. 8348 // If generating ELF, don't do anything (the .MIPS.abiflags section gets 8349 // emitted later). 8350 getTargetStreamer().emitDirectiveModuleNoCRC(); 8351 8352 // If this is not the end of the statement, report an error. 8353 if (getLexer().isNot(AsmToken::EndOfStatement)) { 8354 reportParseError("unexpected token, expected end of statement"); 8355 return false; 8356 } 8357 8358 return false; // parseDirectiveModule has finished successfully. 8359 } else if (Option == "virt") { 8360 setModuleFeatureBits(Mips::FeatureVirt, "virt"); 8361 8362 // Synchronize the ABI Flags information with the FeatureBits information we 8363 // updated above. 8364 getTargetStreamer().updateABIInfo(*this); 8365 8366 // If printing assembly, use the recently updated ABI Flags information. 8367 // If generating ELF, don't do anything (the .MIPS.abiflags section gets 8368 // emitted later). 8369 getTargetStreamer().emitDirectiveModuleVirt(); 8370 8371 // If this is not the end of the statement, report an error. 8372 if (getLexer().isNot(AsmToken::EndOfStatement)) { 8373 reportParseError("unexpected token, expected end of statement"); 8374 return false; 8375 } 8376 8377 return false; // parseDirectiveModule has finished successfully. 8378 } else if (Option == "novirt") { 8379 clearModuleFeatureBits(Mips::FeatureVirt, "virt"); 8380 8381 // Synchronize the ABI Flags information with the FeatureBits information we 8382 // updated above. 8383 getTargetStreamer().updateABIInfo(*this); 8384 8385 // If printing assembly, use the recently updated ABI Flags information. 8386 // If generating ELF, don't do anything (the .MIPS.abiflags section gets 8387 // emitted later). 8388 getTargetStreamer().emitDirectiveModuleNoVirt(); 8389 8390 // If this is not the end of the statement, report an error. 8391 if (getLexer().isNot(AsmToken::EndOfStatement)) { 8392 reportParseError("unexpected token, expected end of statement"); 8393 return false; 8394 } 8395 8396 return false; // parseDirectiveModule has finished successfully. 8397 } else if (Option == "ginv") { 8398 setModuleFeatureBits(Mips::FeatureGINV, "ginv"); 8399 8400 // Synchronize the ABI Flags information with the FeatureBits information we 8401 // updated above. 8402 getTargetStreamer().updateABIInfo(*this); 8403 8404 // If printing assembly, use the recently updated ABI Flags information. 8405 // If generating ELF, don't do anything (the .MIPS.abiflags section gets 8406 // emitted later). 8407 getTargetStreamer().emitDirectiveModuleGINV(); 8408 8409 // If this is not the end of the statement, report an error. 8410 if (getLexer().isNot(AsmToken::EndOfStatement)) { 8411 reportParseError("unexpected token, expected end of statement"); 8412 return false; 8413 } 8414 8415 return false; // parseDirectiveModule has finished successfully. 8416 } else if (Option == "noginv") { 8417 clearModuleFeatureBits(Mips::FeatureGINV, "ginv"); 8418 8419 // Synchronize the ABI Flags information with the FeatureBits information we 8420 // updated above. 8421 getTargetStreamer().updateABIInfo(*this); 8422 8423 // If printing assembly, use the recently updated ABI Flags information. 8424 // If generating ELF, don't do anything (the .MIPS.abiflags section gets 8425 // emitted later). 8426 getTargetStreamer().emitDirectiveModuleNoGINV(); 8427 8428 // If this is not the end of the statement, report an error. 8429 if (getLexer().isNot(AsmToken::EndOfStatement)) { 8430 reportParseError("unexpected token, expected end of statement"); 8431 return false; 8432 } 8433 8434 return false; // parseDirectiveModule has finished successfully. 8435 } else { 8436 return Error(L, "'" + Twine(Option) + "' is not a valid .module option."); 8437 } 8438 } 8439 8440 /// parseDirectiveModuleFP 8441 /// ::= =32 8442 /// ::= =xx 8443 /// ::= =64 8444 bool MipsAsmParser::parseDirectiveModuleFP() { 8445 MCAsmParser &Parser = getParser(); 8446 MCAsmLexer &Lexer = getLexer(); 8447 8448 if (Lexer.isNot(AsmToken::Equal)) { 8449 reportParseError("unexpected token, expected equals sign '='"); 8450 return false; 8451 } 8452 Parser.Lex(); // Eat '=' token. 8453 8454 MipsABIFlagsSection::FpABIKind FpABI; 8455 if (!parseFpABIValue(FpABI, ".module")) 8456 return false; 8457 8458 if (getLexer().isNot(AsmToken::EndOfStatement)) { 8459 reportParseError("unexpected token, expected end of statement"); 8460 return false; 8461 } 8462 8463 // Synchronize the abiflags information with the FeatureBits information we 8464 // changed above. 8465 getTargetStreamer().updateABIInfo(*this); 8466 8467 // If printing assembly, use the recently updated abiflags information. 8468 // If generating ELF, don't do anything (the .MIPS.abiflags section gets 8469 // emitted at the end). 8470 getTargetStreamer().emitDirectiveModuleFP(); 8471 8472 Parser.Lex(); // Consume the EndOfStatement. 8473 return false; 8474 } 8475 8476 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI, 8477 StringRef Directive) { 8478 MCAsmParser &Parser = getParser(); 8479 MCAsmLexer &Lexer = getLexer(); 8480 bool ModuleLevelOptions = Directive == ".module"; 8481 8482 if (Lexer.is(AsmToken::Identifier)) { 8483 StringRef Value = Parser.getTok().getString(); 8484 Parser.Lex(); 8485 8486 if (Value != "xx") { 8487 reportParseError("unsupported value, expected 'xx', '32' or '64'"); 8488 return false; 8489 } 8490 8491 if (!isABI_O32()) { 8492 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI"); 8493 return false; 8494 } 8495 8496 FpABI = MipsABIFlagsSection::FpABIKind::XX; 8497 if (ModuleLevelOptions) { 8498 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx"); 8499 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64"); 8500 } else { 8501 setFeatureBits(Mips::FeatureFPXX, "fpxx"); 8502 clearFeatureBits(Mips::FeatureFP64Bit, "fp64"); 8503 } 8504 return true; 8505 } 8506 8507 if (Lexer.is(AsmToken::Integer)) { 8508 unsigned Value = Parser.getTok().getIntVal(); 8509 Parser.Lex(); 8510 8511 if (Value != 32 && Value != 64) { 8512 reportParseError("unsupported value, expected 'xx', '32' or '64'"); 8513 return false; 8514 } 8515 8516 if (Value == 32) { 8517 if (!isABI_O32()) { 8518 reportParseError("'" + Directive + " fp=32' requires the O32 ABI"); 8519 return false; 8520 } 8521 8522 FpABI = MipsABIFlagsSection::FpABIKind::S32; 8523 if (ModuleLevelOptions) { 8524 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx"); 8525 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64"); 8526 } else { 8527 clearFeatureBits(Mips::FeatureFPXX, "fpxx"); 8528 clearFeatureBits(Mips::FeatureFP64Bit, "fp64"); 8529 } 8530 } else { 8531 FpABI = MipsABIFlagsSection::FpABIKind::S64; 8532 if (ModuleLevelOptions) { 8533 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx"); 8534 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64"); 8535 } else { 8536 clearFeatureBits(Mips::FeatureFPXX, "fpxx"); 8537 setFeatureBits(Mips::FeatureFP64Bit, "fp64"); 8538 } 8539 } 8540 8541 return true; 8542 } 8543 8544 return false; 8545 } 8546 8547 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) { 8548 // This returns false if this function recognizes the directive 8549 // regardless of whether it is successfully handles or reports an 8550 // error. Otherwise it returns true to give the generic parser a 8551 // chance at recognizing it. 8552 8553 MCAsmParser &Parser = getParser(); 8554 StringRef IDVal = DirectiveID.getString(); 8555 8556 if (IDVal == ".cpadd") { 8557 parseDirectiveCpAdd(DirectiveID.getLoc()); 8558 return false; 8559 } 8560 if (IDVal == ".cpload") { 8561 parseDirectiveCpLoad(DirectiveID.getLoc()); 8562 return false; 8563 } 8564 if (IDVal == ".cprestore") { 8565 parseDirectiveCpRestore(DirectiveID.getLoc()); 8566 return false; 8567 } 8568 if (IDVal == ".cplocal") { 8569 parseDirectiveCpLocal(DirectiveID.getLoc()); 8570 return false; 8571 } 8572 if (IDVal == ".ent") { 8573 StringRef SymbolName; 8574 8575 if (Parser.parseIdentifier(SymbolName)) { 8576 reportParseError("expected identifier after .ent"); 8577 return false; 8578 } 8579 8580 // There's an undocumented extension that allows an integer to 8581 // follow the name of the procedure which AFAICS is ignored by GAS. 8582 // Example: .ent foo,2 8583 if (getLexer().isNot(AsmToken::EndOfStatement)) { 8584 if (getLexer().isNot(AsmToken::Comma)) { 8585 // Even though we accept this undocumented extension for compatibility 8586 // reasons, the additional integer argument does not actually change 8587 // the behaviour of the '.ent' directive, so we would like to discourage 8588 // its use. We do this by not referring to the extended version in 8589 // error messages which are not directly related to its use. 8590 reportParseError("unexpected token, expected end of statement"); 8591 return false; 8592 } 8593 Parser.Lex(); // Eat the comma. 8594 const MCExpr *DummyNumber; 8595 int64_t DummyNumberVal; 8596 // If the user was explicitly trying to use the extended version, 8597 // we still give helpful extension-related error messages. 8598 if (Parser.parseExpression(DummyNumber)) { 8599 reportParseError("expected number after comma"); 8600 return false; 8601 } 8602 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) { 8603 reportParseError("expected an absolute expression after comma"); 8604 return false; 8605 } 8606 } 8607 8608 // If this is not the end of the statement, report an error. 8609 if (getLexer().isNot(AsmToken::EndOfStatement)) { 8610 reportParseError("unexpected token, expected end of statement"); 8611 return false; 8612 } 8613 8614 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName); 8615 8616 getTargetStreamer().emitDirectiveEnt(*Sym); 8617 CurrentFn = Sym; 8618 IsCpRestoreSet = false; 8619 return false; 8620 } 8621 8622 if (IDVal == ".end") { 8623 StringRef SymbolName; 8624 8625 if (Parser.parseIdentifier(SymbolName)) { 8626 reportParseError("expected identifier after .end"); 8627 return false; 8628 } 8629 8630 if (getLexer().isNot(AsmToken::EndOfStatement)) { 8631 reportParseError("unexpected token, expected end of statement"); 8632 return false; 8633 } 8634 8635 if (CurrentFn == nullptr) { 8636 reportParseError(".end used without .ent"); 8637 return false; 8638 } 8639 8640 if ((SymbolName != CurrentFn->getName())) { 8641 reportParseError(".end symbol does not match .ent symbol"); 8642 return false; 8643 } 8644 8645 getTargetStreamer().emitDirectiveEnd(SymbolName); 8646 CurrentFn = nullptr; 8647 IsCpRestoreSet = false; 8648 return false; 8649 } 8650 8651 if (IDVal == ".frame") { 8652 // .frame $stack_reg, frame_size_in_bytes, $return_reg 8653 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg; 8654 ParseStatus Res = parseAnyRegister(TmpReg); 8655 if (Res.isNoMatch() || Res.isFailure()) { 8656 reportParseError("expected stack register"); 8657 return false; 8658 } 8659 8660 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]); 8661 if (!StackRegOpnd.isGPRAsmReg()) { 8662 reportParseError(StackRegOpnd.getStartLoc(), 8663 "expected general purpose register"); 8664 return false; 8665 } 8666 unsigned StackReg = StackRegOpnd.getGPR32Reg(); 8667 8668 if (Parser.getTok().is(AsmToken::Comma)) 8669 Parser.Lex(); 8670 else { 8671 reportParseError("unexpected token, expected comma"); 8672 return false; 8673 } 8674 8675 // Parse the frame size. 8676 const MCExpr *FrameSize; 8677 int64_t FrameSizeVal; 8678 8679 if (Parser.parseExpression(FrameSize)) { 8680 reportParseError("expected frame size value"); 8681 return false; 8682 } 8683 8684 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) { 8685 reportParseError("frame size not an absolute expression"); 8686 return false; 8687 } 8688 8689 if (Parser.getTok().is(AsmToken::Comma)) 8690 Parser.Lex(); 8691 else { 8692 reportParseError("unexpected token, expected comma"); 8693 return false; 8694 } 8695 8696 // Parse the return register. 8697 TmpReg.clear(); 8698 Res = parseAnyRegister(TmpReg); 8699 if (Res.isNoMatch() || Res.isFailure()) { 8700 reportParseError("expected return register"); 8701 return false; 8702 } 8703 8704 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]); 8705 if (!ReturnRegOpnd.isGPRAsmReg()) { 8706 reportParseError(ReturnRegOpnd.getStartLoc(), 8707 "expected general purpose register"); 8708 return false; 8709 } 8710 8711 // If this is not the end of the statement, report an error. 8712 if (getLexer().isNot(AsmToken::EndOfStatement)) { 8713 reportParseError("unexpected token, expected end of statement"); 8714 return false; 8715 } 8716 8717 getTargetStreamer().emitFrame(StackReg, FrameSizeVal, 8718 ReturnRegOpnd.getGPR32Reg()); 8719 IsCpRestoreSet = false; 8720 return false; 8721 } 8722 8723 if (IDVal == ".set") { 8724 parseDirectiveSet(); 8725 return false; 8726 } 8727 8728 if (IDVal == ".mask" || IDVal == ".fmask") { 8729 // .mask bitmask, frame_offset 8730 // bitmask: One bit for each register used. 8731 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where 8732 // first register is expected to be saved. 8733 // Examples: 8734 // .mask 0x80000000, -4 8735 // .fmask 0x80000000, -4 8736 // 8737 8738 // Parse the bitmask 8739 const MCExpr *BitMask; 8740 int64_t BitMaskVal; 8741 8742 if (Parser.parseExpression(BitMask)) { 8743 reportParseError("expected bitmask value"); 8744 return false; 8745 } 8746 8747 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) { 8748 reportParseError("bitmask not an absolute expression"); 8749 return false; 8750 } 8751 8752 if (Parser.getTok().is(AsmToken::Comma)) 8753 Parser.Lex(); 8754 else { 8755 reportParseError("unexpected token, expected comma"); 8756 return false; 8757 } 8758 8759 // Parse the frame_offset 8760 const MCExpr *FrameOffset; 8761 int64_t FrameOffsetVal; 8762 8763 if (Parser.parseExpression(FrameOffset)) { 8764 reportParseError("expected frame offset value"); 8765 return false; 8766 } 8767 8768 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) { 8769 reportParseError("frame offset not an absolute expression"); 8770 return false; 8771 } 8772 8773 // If this is not the end of the statement, report an error. 8774 if (getLexer().isNot(AsmToken::EndOfStatement)) { 8775 reportParseError("unexpected token, expected end of statement"); 8776 return false; 8777 } 8778 8779 if (IDVal == ".mask") 8780 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal); 8781 else 8782 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal); 8783 return false; 8784 } 8785 8786 if (IDVal == ".nan") 8787 return parseDirectiveNaN(); 8788 8789 if (IDVal == ".gpword") { 8790 parseDirectiveGpWord(); 8791 return false; 8792 } 8793 8794 if (IDVal == ".gpdword") { 8795 parseDirectiveGpDWord(); 8796 return false; 8797 } 8798 8799 if (IDVal == ".dtprelword") { 8800 parseDirectiveDtpRelWord(); 8801 return false; 8802 } 8803 8804 if (IDVal == ".dtpreldword") { 8805 parseDirectiveDtpRelDWord(); 8806 return false; 8807 } 8808 8809 if (IDVal == ".tprelword") { 8810 parseDirectiveTpRelWord(); 8811 return false; 8812 } 8813 8814 if (IDVal == ".tpreldword") { 8815 parseDirectiveTpRelDWord(); 8816 return false; 8817 } 8818 8819 if (IDVal == ".option") { 8820 parseDirectiveOption(); 8821 return false; 8822 } 8823 8824 if (IDVal == ".abicalls") { 8825 getTargetStreamer().emitDirectiveAbiCalls(); 8826 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) { 8827 Error(Parser.getTok().getLoc(), 8828 "unexpected token, expected end of statement"); 8829 } 8830 return false; 8831 } 8832 8833 if (IDVal == ".cpsetup") { 8834 parseDirectiveCPSetup(); 8835 return false; 8836 } 8837 if (IDVal == ".cpreturn") { 8838 parseDirectiveCPReturn(); 8839 return false; 8840 } 8841 if (IDVal == ".module") { 8842 parseDirectiveModule(); 8843 return false; 8844 } 8845 if (IDVal == ".llvm_internal_mips_reallow_module_directive") { 8846 parseInternalDirectiveReallowModule(); 8847 return false; 8848 } 8849 if (IDVal == ".insn") { 8850 parseInsnDirective(); 8851 return false; 8852 } 8853 if (IDVal == ".rdata") { 8854 parseRSectionDirective(".rodata"); 8855 return false; 8856 } 8857 if (IDVal == ".sbss") { 8858 parseSSectionDirective(IDVal, ELF::SHT_NOBITS); 8859 return false; 8860 } 8861 if (IDVal == ".sdata") { 8862 parseSSectionDirective(IDVal, ELF::SHT_PROGBITS); 8863 return false; 8864 } 8865 8866 return true; 8867 } 8868 8869 bool MipsAsmParser::parseInternalDirectiveReallowModule() { 8870 // If this is not the end of the statement, report an error. 8871 if (getLexer().isNot(AsmToken::EndOfStatement)) { 8872 reportParseError("unexpected token, expected end of statement"); 8873 return false; 8874 } 8875 8876 getTargetStreamer().reallowModuleDirective(); 8877 8878 getParser().Lex(); // Eat EndOfStatement token. 8879 return false; 8880 } 8881 8882 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMipsAsmParser() { 8883 RegisterMCAsmParser<MipsAsmParser> X(getTheMipsTarget()); 8884 RegisterMCAsmParser<MipsAsmParser> Y(getTheMipselTarget()); 8885 RegisterMCAsmParser<MipsAsmParser> A(getTheMips64Target()); 8886 RegisterMCAsmParser<MipsAsmParser> B(getTheMips64elTarget()); 8887 } 8888 8889 #define GET_REGISTER_MATCHER 8890 #define GET_MATCHER_IMPLEMENTATION 8891 #define GET_MNEMONIC_SPELL_CHECKER 8892 #include "MipsGenAsmMatcher.inc" 8893 8894 bool MipsAsmParser::mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) { 8895 // Find the appropriate table for this asm variant. 8896 const MatchEntry *Start, *End; 8897 switch (VariantID) { 8898 default: llvm_unreachable("invalid variant!"); 8899 case 0: Start = std::begin(MatchTable0); End = std::end(MatchTable0); break; 8900 } 8901 // Search the table. 8902 auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode()); 8903 return MnemonicRange.first != MnemonicRange.second; 8904 } 8905