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