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