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