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