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