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