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