1 //===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "MCTargetDesc/MipsABIInfo.h" 11 #include "MCTargetDesc/MipsMCExpr.h" 12 #include "MCTargetDesc/MipsMCTargetDesc.h" 13 #include "MipsRegisterInfo.h" 14 #include "MipsTargetObjectFile.h" 15 #include "MipsTargetStreamer.h" 16 #include "llvm/ADT/SmallVector.h" 17 #include "llvm/ADT/StringSwitch.h" 18 #include "llvm/MC/MCContext.h" 19 #include "llvm/MC/MCExpr.h" 20 #include "llvm/MC/MCInst.h" 21 #include "llvm/MC/MCInstBuilder.h" 22 #include "llvm/MC/MCParser/MCAsmLexer.h" 23 #include "llvm/MC/MCParser/MCParsedAsmOperand.h" 24 #include "llvm/MC/MCParser/MCTargetAsmParser.h" 25 #include "llvm/MC/MCSectionELF.h" 26 #include "llvm/MC/MCStreamer.h" 27 #include "llvm/MC/MCSubtargetInfo.h" 28 #include "llvm/MC/MCSymbol.h" 29 #include "llvm/Support/Debug.h" 30 #include "llvm/Support/ELF.h" 31 #include "llvm/Support/MathExtras.h" 32 #include "llvm/Support/SourceMgr.h" 33 #include "llvm/Support/TargetRegistry.h" 34 #include "llvm/Support/raw_ostream.h" 35 #include <memory> 36 37 using namespace llvm; 38 39 #define DEBUG_TYPE "mips-asm-parser" 40 41 namespace llvm { 42 class MCInstrInfo; 43 } 44 45 namespace { 46 class MipsAssemblerOptions { 47 public: 48 MipsAssemblerOptions(const FeatureBitset &Features_) : 49 ATReg(1), Reorder(true), Macro(true), Features(Features_) {} 50 51 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) { 52 ATReg = Opts->getATRegIndex(); 53 Reorder = Opts->isReorder(); 54 Macro = Opts->isMacro(); 55 Features = Opts->getFeatures(); 56 } 57 58 unsigned getATRegIndex() const { return ATReg; } 59 bool setATRegIndex(unsigned Reg) { 60 if (Reg > 31) 61 return false; 62 63 ATReg = Reg; 64 return true; 65 } 66 67 bool isReorder() const { return Reorder; } 68 void setReorder() { Reorder = true; } 69 void setNoReorder() { Reorder = false; } 70 71 bool isMacro() const { return Macro; } 72 void setMacro() { Macro = true; } 73 void setNoMacro() { Macro = false; } 74 75 const FeatureBitset &getFeatures() const { return Features; } 76 void setFeatures(const FeatureBitset &Features_) { Features = Features_; } 77 78 // Set of features that are either architecture features or referenced 79 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6). 80 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]). 81 // The reason we need this mask is explained in the selectArch function. 82 // FIXME: Ideally we would like TableGen to generate this information. 83 static const FeatureBitset AllArchRelatedMask; 84 85 private: 86 unsigned ATReg; 87 bool Reorder; 88 bool Macro; 89 FeatureBitset Features; 90 }; 91 } 92 93 const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = { 94 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3, 95 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4, 96 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5, 97 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2, 98 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6, 99 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3, 100 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips, 101 Mips::FeatureFP64Bit, Mips::FeatureGP64Bit, Mips::FeatureNaN2008 102 }; 103 104 namespace { 105 class MipsAsmParser : public MCTargetAsmParser { 106 MipsTargetStreamer &getTargetStreamer() { 107 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer(); 108 return static_cast<MipsTargetStreamer &>(TS); 109 } 110 111 MipsABIInfo ABI; 112 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions; 113 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a 114 // nullptr, which indicates that no function is currently 115 // selected. This usually happens after an '.end func' 116 // directive. 117 bool IsLittleEndian; 118 bool IsPicEnabled; 119 bool IsCpRestoreSet; 120 int CpRestoreOffset; 121 unsigned CpSaveLocation; 122 /// If true, then CpSaveLocation is a register, otherwise it's an offset. 123 bool CpSaveLocationIsRegister; 124 125 // Print a warning along with its fix-it message at the given range. 126 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg, 127 SMRange Range, bool ShowColors = true); 128 129 #define GET_ASSEMBLER_HEADER 130 #include "MipsGenAsmMatcher.inc" 131 132 unsigned checkTargetMatchPredicate(MCInst &Inst) override; 133 134 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 135 OperandVector &Operands, MCStreamer &Out, 136 uint64_t &ErrorInfo, 137 bool MatchingInlineAsm) override; 138 139 /// Parse a register as used in CFI directives 140 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override; 141 142 bool parseParenSuffix(StringRef Name, OperandVector &Operands); 143 144 bool parseBracketSuffix(StringRef Name, OperandVector &Operands); 145 146 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 147 SMLoc NameLoc, OperandVector &Operands) override; 148 149 bool ParseDirective(AsmToken DirectiveID) override; 150 151 OperandMatchResultTy parseMemOperand(OperandVector &Operands); 152 OperandMatchResultTy 153 matchAnyRegisterNameWithoutDollar(OperandVector &Operands, 154 StringRef Identifier, SMLoc S); 155 OperandMatchResultTy matchAnyRegisterWithoutDollar(OperandVector &Operands, 156 SMLoc S); 157 OperandMatchResultTy parseAnyRegister(OperandVector &Operands); 158 OperandMatchResultTy parseImm(OperandVector &Operands); 159 OperandMatchResultTy parseJumpTarget(OperandVector &Operands); 160 OperandMatchResultTy parseInvNum(OperandVector &Operands); 161 OperandMatchResultTy parseLSAImm(OperandVector &Operands); 162 OperandMatchResultTy parseRegisterPair(OperandVector &Operands); 163 OperandMatchResultTy parseMovePRegPair(OperandVector &Operands); 164 OperandMatchResultTy parseRegisterList(OperandVector &Operands); 165 166 bool searchSymbolAlias(OperandVector &Operands); 167 168 bool parseOperand(OperandVector &, StringRef Mnemonic); 169 170 enum MacroExpanderResultTy { 171 MER_NotAMacro, 172 MER_Success, 173 MER_Fail, 174 }; 175 176 // Expands assembly pseudo instructions. 177 MacroExpanderResultTy tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, 178 MCStreamer &Out, 179 const MCSubtargetInfo *STI); 180 181 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 182 const MCSubtargetInfo *STI); 183 184 bool loadImmediate(int64_t ImmValue, unsigned DstReg, unsigned SrcReg, 185 bool Is32BitImm, bool IsAddress, SMLoc IDLoc, 186 MCStreamer &Out, const MCSubtargetInfo *STI); 187 188 bool loadAndAddSymbolAddress(const MCExpr *SymExpr, unsigned DstReg, 189 unsigned SrcReg, bool Is32BitSym, SMLoc IDLoc, 190 MCStreamer &Out, const MCSubtargetInfo *STI); 191 192 bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc, 193 MCStreamer &Out, const MCSubtargetInfo *STI); 194 195 bool expandLoadAddress(unsigned DstReg, unsigned BaseReg, 196 const MCOperand &Offset, bool Is32BitAddress, 197 SMLoc IDLoc, MCStreamer &Out, 198 const MCSubtargetInfo *STI); 199 200 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 201 const MCSubtargetInfo *STI); 202 203 void expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 204 const MCSubtargetInfo *STI, bool IsLoad, bool IsImmOpnd); 205 206 void expandLoadInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 207 const MCSubtargetInfo *STI, bool IsImmOpnd); 208 209 void expandStoreInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 210 const MCSubtargetInfo *STI, bool IsImmOpnd); 211 212 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 213 const MCSubtargetInfo *STI); 214 215 bool expandAliasImmediate(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 216 const MCSubtargetInfo *STI); 217 218 bool expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 219 const MCSubtargetInfo *STI); 220 221 bool expandCondBranches(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 222 const MCSubtargetInfo *STI); 223 224 bool expandDiv(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 225 const MCSubtargetInfo *STI, const bool IsMips64, 226 const bool Signed); 227 228 bool expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU, SMLoc IDLoc, 229 MCStreamer &Out, const MCSubtargetInfo *STI); 230 231 bool expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc, MCStreamer &Out, 232 const MCSubtargetInfo *STI); 233 234 bool expandUlw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 235 const MCSubtargetInfo *STI); 236 237 bool expandRotation(MCInst &Inst, SMLoc IDLoc, 238 MCStreamer &Out, const MCSubtargetInfo *STI); 239 bool expandRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 240 const MCSubtargetInfo *STI); 241 bool expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 242 const MCSubtargetInfo *STI); 243 bool expandDRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 244 const MCSubtargetInfo *STI); 245 246 bool expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 247 const MCSubtargetInfo *STI); 248 249 void createCpRestoreMemOp(bool IsLoad, int StackOffset, SMLoc IDLoc, 250 MCStreamer &Out, const MCSubtargetInfo *STI); 251 252 bool reportParseError(Twine ErrorMsg); 253 bool reportParseError(SMLoc Loc, Twine ErrorMsg); 254 255 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr); 256 bool parseRelocOperand(const MCExpr *&Res); 257 258 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr); 259 260 bool isEvaluated(const MCExpr *Expr); 261 bool parseSetMips0Directive(); 262 bool parseSetArchDirective(); 263 bool parseSetFeature(uint64_t Feature); 264 bool isPicAndNotNxxAbi(); // Used by .cpload, .cprestore, and .cpsetup. 265 bool parseDirectiveCpLoad(SMLoc Loc); 266 bool parseDirectiveCpRestore(SMLoc Loc); 267 bool parseDirectiveCPSetup(); 268 bool parseDirectiveCPReturn(); 269 bool parseDirectiveNaN(); 270 bool parseDirectiveSet(); 271 bool parseDirectiveOption(); 272 bool parseInsnDirective(); 273 bool parseSSectionDirective(StringRef Section, unsigned Type); 274 275 bool parseSetAtDirective(); 276 bool parseSetNoAtDirective(); 277 bool parseSetMacroDirective(); 278 bool parseSetNoMacroDirective(); 279 bool parseSetMsaDirective(); 280 bool parseSetNoMsaDirective(); 281 bool parseSetNoDspDirective(); 282 bool parseSetReorderDirective(); 283 bool parseSetNoReorderDirective(); 284 bool parseSetMips16Directive(); 285 bool parseSetNoMips16Directive(); 286 bool parseSetFpDirective(); 287 bool parseSetOddSPRegDirective(); 288 bool parseSetNoOddSPRegDirective(); 289 bool parseSetPopDirective(); 290 bool parseSetPushDirective(); 291 bool parseSetSoftFloatDirective(); 292 bool parseSetHardFloatDirective(); 293 294 bool parseSetAssignment(); 295 296 bool parseDataDirective(unsigned Size, SMLoc L); 297 bool parseDirectiveGpWord(); 298 bool parseDirectiveGpDWord(); 299 bool parseDirectiveModule(); 300 bool parseDirectiveModuleFP(); 301 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI, 302 StringRef Directive); 303 304 bool parseInternalDirectiveReallowModule(); 305 306 bool eatComma(StringRef ErrorStr); 307 308 int matchCPURegisterName(StringRef Symbol); 309 310 int matchHWRegsRegisterName(StringRef Symbol); 311 312 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass); 313 314 int matchFPURegisterName(StringRef Name); 315 316 int matchFCCRegisterName(StringRef Name); 317 318 int matchACRegisterName(StringRef Name); 319 320 int matchMSA128RegisterName(StringRef Name); 321 322 int matchMSA128CtrlRegisterName(StringRef Name); 323 324 unsigned getReg(int RC, int RegNo); 325 326 unsigned getGPR(int RegNo); 327 328 /// Returns the internal register number for the current AT. Also checks if 329 /// the current AT is unavailable (set to $0) and gives an error if it is. 330 /// This should be used in pseudo-instruction expansions which need AT. 331 unsigned getATReg(SMLoc Loc); 332 333 bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 334 const MCSubtargetInfo *STI); 335 336 // Helper function that checks if the value of a vector index is within the 337 // boundaries of accepted values for each RegisterKind 338 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0 339 bool validateMSAIndex(int Val, int RegKind); 340 341 // Selects a new architecture by updating the FeatureBits with the necessary 342 // info including implied dependencies. 343 // Internally, it clears all the feature bits related to *any* architecture 344 // and selects the new one using the ToggleFeature functionality of the 345 // MCSubtargetInfo object that handles implied dependencies. The reason we 346 // clear all the arch related bits manually is because ToggleFeature only 347 // clears the features that imply the feature being cleared and not the 348 // features implied by the feature being cleared. This is easier to see 349 // with an example: 350 // -------------------------------------------------- 351 // | Feature | Implies | 352 // | -------------------------------------------------| 353 // | FeatureMips1 | None | 354 // | FeatureMips2 | FeatureMips1 | 355 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 | 356 // | FeatureMips4 | FeatureMips3 | 357 // | ... | | 358 // -------------------------------------------------- 359 // 360 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 | 361 // FeatureMipsGP64 | FeatureMips1) 362 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4). 363 void selectArch(StringRef ArchFeature) { 364 MCSubtargetInfo &STI = copySTI(); 365 FeatureBitset FeatureBits = STI.getFeatureBits(); 366 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask; 367 STI.setFeatureBits(FeatureBits); 368 setAvailableFeatures( 369 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature))); 370 AssemblerOptions.back()->setFeatures(STI.getFeatureBits()); 371 } 372 373 void setFeatureBits(uint64_t Feature, StringRef FeatureString) { 374 if (!(getSTI().getFeatureBits()[Feature])) { 375 MCSubtargetInfo &STI = copySTI(); 376 setAvailableFeatures( 377 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString))); 378 AssemblerOptions.back()->setFeatures(STI.getFeatureBits()); 379 } 380 } 381 382 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) { 383 if (getSTI().getFeatureBits()[Feature]) { 384 MCSubtargetInfo &STI = copySTI(); 385 setAvailableFeatures( 386 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString))); 387 AssemblerOptions.back()->setFeatures(STI.getFeatureBits()); 388 } 389 } 390 391 void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) { 392 setFeatureBits(Feature, FeatureString); 393 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits()); 394 } 395 396 void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) { 397 clearFeatureBits(Feature, FeatureString); 398 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits()); 399 } 400 401 public: 402 enum MipsMatchResultTy { 403 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY, 404 #define GET_OPERAND_DIAGNOSTIC_TYPES 405 #include "MipsGenAsmMatcher.inc" 406 #undef GET_OPERAND_DIAGNOSTIC_TYPES 407 }; 408 409 MipsAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser, 410 const MCInstrInfo &MII, const MCTargetOptions &Options) 411 : MCTargetAsmParser(Options, sti), 412 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()), 413 sti.getCPU(), Options)) { 414 MCAsmParserExtension::Initialize(parser); 415 416 parser.addAliasForDirective(".asciiz", ".asciz"); 417 418 // Initialize the set of available features. 419 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits())); 420 421 // Remember the initial assembler options. The user can not modify these. 422 AssemblerOptions.push_back( 423 llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits())); 424 425 // Create an assembler options environment for the user to modify. 426 AssemblerOptions.push_back( 427 llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits())); 428 429 getTargetStreamer().updateABIInfo(*this); 430 431 if (!isABI_O32() && !useOddSPReg() != 0) 432 report_fatal_error("-mno-odd-spreg requires the O32 ABI"); 433 434 CurrentFn = nullptr; 435 436 IsPicEnabled = getContext().getObjectFileInfo()->isPositionIndependent(); 437 438 IsCpRestoreSet = false; 439 CpRestoreOffset = -1; 440 441 Triple TheTriple(sti.getTargetTriple()); 442 if ((TheTriple.getArch() == Triple::mips) || 443 (TheTriple.getArch() == Triple::mips64)) 444 IsLittleEndian = false; 445 else 446 IsLittleEndian = true; 447 } 448 449 /// True if all of $fcc0 - $fcc7 exist for the current ISA. 450 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); } 451 452 bool isGP64bit() const { 453 return getSTI().getFeatureBits()[Mips::FeatureGP64Bit]; 454 } 455 bool isFP64bit() const { 456 return getSTI().getFeatureBits()[Mips::FeatureFP64Bit]; 457 } 458 const MipsABIInfo &getABI() const { return ABI; } 459 bool isABI_N32() const { return ABI.IsN32(); } 460 bool isABI_N64() const { return ABI.IsN64(); } 461 bool isABI_O32() const { return ABI.IsO32(); } 462 bool isABI_FPXX() const { 463 return getSTI().getFeatureBits()[Mips::FeatureFPXX]; 464 } 465 466 bool useOddSPReg() const { 467 return !(getSTI().getFeatureBits()[Mips::FeatureNoOddSPReg]); 468 } 469 470 bool inMicroMipsMode() const { 471 return getSTI().getFeatureBits()[Mips::FeatureMicroMips]; 472 } 473 bool hasMips1() const { 474 return getSTI().getFeatureBits()[Mips::FeatureMips1]; 475 } 476 bool hasMips2() const { 477 return getSTI().getFeatureBits()[Mips::FeatureMips2]; 478 } 479 bool hasMips3() const { 480 return getSTI().getFeatureBits()[Mips::FeatureMips3]; 481 } 482 bool hasMips4() const { 483 return getSTI().getFeatureBits()[Mips::FeatureMips4]; 484 } 485 bool hasMips5() const { 486 return getSTI().getFeatureBits()[Mips::FeatureMips5]; 487 } 488 bool hasMips32() const { 489 return getSTI().getFeatureBits()[Mips::FeatureMips32]; 490 } 491 bool hasMips64() const { 492 return getSTI().getFeatureBits()[Mips::FeatureMips64]; 493 } 494 bool hasMips32r2() const { 495 return getSTI().getFeatureBits()[Mips::FeatureMips32r2]; 496 } 497 bool hasMips64r2() const { 498 return getSTI().getFeatureBits()[Mips::FeatureMips64r2]; 499 } 500 bool hasMips32r3() const { 501 return (getSTI().getFeatureBits()[Mips::FeatureMips32r3]); 502 } 503 bool hasMips64r3() const { 504 return (getSTI().getFeatureBits()[Mips::FeatureMips64r3]); 505 } 506 bool hasMips32r5() const { 507 return (getSTI().getFeatureBits()[Mips::FeatureMips32r5]); 508 } 509 bool hasMips64r5() const { 510 return (getSTI().getFeatureBits()[Mips::FeatureMips64r5]); 511 } 512 bool hasMips32r6() const { 513 return getSTI().getFeatureBits()[Mips::FeatureMips32r6]; 514 } 515 bool hasMips64r6() const { 516 return getSTI().getFeatureBits()[Mips::FeatureMips64r6]; 517 } 518 519 bool hasDSP() const { 520 return getSTI().getFeatureBits()[Mips::FeatureDSP]; 521 } 522 bool hasDSPR2() const { 523 return getSTI().getFeatureBits()[Mips::FeatureDSPR2]; 524 } 525 bool hasDSPR3() const { 526 return getSTI().getFeatureBits()[Mips::FeatureDSPR3]; 527 } 528 bool hasMSA() const { 529 return getSTI().getFeatureBits()[Mips::FeatureMSA]; 530 } 531 bool hasCnMips() const { 532 return (getSTI().getFeatureBits()[Mips::FeatureCnMips]); 533 } 534 535 bool inPicMode() { 536 return IsPicEnabled; 537 } 538 539 bool inMips16Mode() const { 540 return getSTI().getFeatureBits()[Mips::FeatureMips16]; 541 } 542 543 bool useTraps() const { 544 return getSTI().getFeatureBits()[Mips::FeatureUseTCCInDIV]; 545 } 546 547 bool useSoftFloat() const { 548 return getSTI().getFeatureBits()[Mips::FeatureSoftFloat]; 549 } 550 551 /// Warn if RegIndex is the same as the current AT. 552 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc); 553 554 void warnIfNoMacro(SMLoc Loc); 555 556 bool isLittle() const { return IsLittleEndian; } 557 }; 558 } 559 560 namespace { 561 562 /// MipsOperand - Instances of this class represent a parsed Mips machine 563 /// instruction. 564 class MipsOperand : public MCParsedAsmOperand { 565 public: 566 /// Broad categories of register classes 567 /// The exact class is finalized by the render method. 568 enum RegKind { 569 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit()) 570 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and 571 /// isFP64bit()) 572 RegKind_FCC = 4, /// FCC 573 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which) 574 RegKind_MSACtrl = 16, /// MSA control registers 575 RegKind_COP2 = 32, /// COP2 576 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on 577 /// context). 578 RegKind_CCR = 128, /// CCR 579 RegKind_HWRegs = 256, /// HWRegs 580 RegKind_COP3 = 512, /// COP3 581 RegKind_COP0 = 1024, /// COP0 582 /// Potentially any (e.g. $1) 583 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 | 584 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC | 585 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0 586 }; 587 588 private: 589 enum KindTy { 590 k_Immediate, /// An immediate (possibly involving symbol references) 591 k_Memory, /// Base + Offset Memory Address 592 k_PhysRegister, /// A physical register from the Mips namespace 593 k_RegisterIndex, /// A register index in one or more RegKind. 594 k_Token, /// A simple token 595 k_RegList, /// A physical register list 596 k_RegPair /// A pair of physical register 597 } Kind; 598 599 public: 600 MipsOperand(KindTy K, MipsAsmParser &Parser) 601 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {} 602 603 private: 604 /// For diagnostics, and checking the assembler temporary 605 MipsAsmParser &AsmParser; 606 607 struct Token { 608 const char *Data; 609 unsigned Length; 610 }; 611 612 struct PhysRegOp { 613 unsigned Num; /// Register Number 614 }; 615 616 struct RegIdxOp { 617 unsigned Index; /// Index into the register class 618 RegKind Kind; /// Bitfield of the kinds it could possibly be 619 const MCRegisterInfo *RegInfo; 620 }; 621 622 struct ImmOp { 623 const MCExpr *Val; 624 }; 625 626 struct MemOp { 627 MipsOperand *Base; 628 const MCExpr *Off; 629 }; 630 631 struct RegListOp { 632 SmallVector<unsigned, 10> *List; 633 }; 634 635 union { 636 struct Token Tok; 637 struct PhysRegOp PhysReg; 638 struct RegIdxOp RegIdx; 639 struct ImmOp Imm; 640 struct MemOp Mem; 641 struct RegListOp RegList; 642 }; 643 644 SMLoc StartLoc, EndLoc; 645 646 /// Internal constructor for register kinds 647 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind, 648 const MCRegisterInfo *RegInfo, 649 SMLoc S, SMLoc E, 650 MipsAsmParser &Parser) { 651 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser); 652 Op->RegIdx.Index = Index; 653 Op->RegIdx.RegInfo = RegInfo; 654 Op->RegIdx.Kind = RegKind; 655 Op->StartLoc = S; 656 Op->EndLoc = E; 657 return Op; 658 } 659 660 public: 661 /// Coerce the register to GPR32 and return the real register for the current 662 /// target. 663 unsigned getGPR32Reg() const { 664 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!"); 665 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc); 666 unsigned ClassID = Mips::GPR32RegClassID; 667 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 668 } 669 670 /// Coerce the register to GPR32 and return the real register for the current 671 /// target. 672 unsigned getGPRMM16Reg() const { 673 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!"); 674 unsigned ClassID = Mips::GPR32RegClassID; 675 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 676 } 677 678 /// Coerce the register to GPR64 and return the real register for the current 679 /// target. 680 unsigned getGPR64Reg() const { 681 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!"); 682 unsigned ClassID = Mips::GPR64RegClassID; 683 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 684 } 685 686 private: 687 /// Coerce the register to AFGR64 and return the real register for the current 688 /// target. 689 unsigned getAFGR64Reg() const { 690 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!"); 691 if (RegIdx.Index % 2 != 0) 692 AsmParser.Warning(StartLoc, "Float register should be even."); 693 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID) 694 .getRegister(RegIdx.Index / 2); 695 } 696 697 /// Coerce the register to FGR64 and return the real register for the current 698 /// target. 699 unsigned getFGR64Reg() const { 700 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!"); 701 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID) 702 .getRegister(RegIdx.Index); 703 } 704 705 /// Coerce the register to FGR32 and return the real register for the current 706 /// target. 707 unsigned getFGR32Reg() const { 708 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!"); 709 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID) 710 .getRegister(RegIdx.Index); 711 } 712 713 /// Coerce the register to FGRH32 and return the real register for the current 714 /// target. 715 unsigned getFGRH32Reg() const { 716 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!"); 717 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID) 718 .getRegister(RegIdx.Index); 719 } 720 721 /// Coerce the register to FCC and return the real register for the current 722 /// target. 723 unsigned getFCCReg() const { 724 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!"); 725 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID) 726 .getRegister(RegIdx.Index); 727 } 728 729 /// Coerce the register to MSA128 and return the real register for the current 730 /// target. 731 unsigned getMSA128Reg() const { 732 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!"); 733 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all 734 // identical 735 unsigned ClassID = Mips::MSA128BRegClassID; 736 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 737 } 738 739 /// Coerce the register to MSACtrl and return the real register for the 740 /// current target. 741 unsigned getMSACtrlReg() const { 742 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!"); 743 unsigned ClassID = Mips::MSACtrlRegClassID; 744 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 745 } 746 747 /// Coerce the register to COP0 and return the real register for the 748 /// current target. 749 unsigned getCOP0Reg() const { 750 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) && "Invalid access!"); 751 unsigned ClassID = Mips::COP0RegClassID; 752 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 753 } 754 755 /// Coerce the register to COP2 and return the real register for the 756 /// current target. 757 unsigned getCOP2Reg() const { 758 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!"); 759 unsigned ClassID = Mips::COP2RegClassID; 760 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 761 } 762 763 /// Coerce the register to COP3 and return the real register for the 764 /// current target. 765 unsigned getCOP3Reg() const { 766 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!"); 767 unsigned ClassID = Mips::COP3RegClassID; 768 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 769 } 770 771 /// Coerce the register to ACC64DSP and return the real register for the 772 /// current target. 773 unsigned getACC64DSPReg() const { 774 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!"); 775 unsigned ClassID = Mips::ACC64DSPRegClassID; 776 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 777 } 778 779 /// Coerce the register to HI32DSP and return the real register for the 780 /// current target. 781 unsigned getHI32DSPReg() const { 782 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!"); 783 unsigned ClassID = Mips::HI32DSPRegClassID; 784 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 785 } 786 787 /// Coerce the register to LO32DSP and return the real register for the 788 /// current target. 789 unsigned getLO32DSPReg() const { 790 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!"); 791 unsigned ClassID = Mips::LO32DSPRegClassID; 792 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 793 } 794 795 /// Coerce the register to CCR and return the real register for the 796 /// current target. 797 unsigned getCCRReg() const { 798 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!"); 799 unsigned ClassID = Mips::CCRRegClassID; 800 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 801 } 802 803 /// Coerce the register to HWRegs and return the real register for the 804 /// current target. 805 unsigned getHWRegsReg() const { 806 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!"); 807 unsigned ClassID = Mips::HWRegsRegClassID; 808 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 809 } 810 811 public: 812 void addExpr(MCInst &Inst, const MCExpr *Expr) const { 813 // Add as immediate when possible. Null MCExpr = 0. 814 if (!Expr) 815 Inst.addOperand(MCOperand::createImm(0)); 816 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 817 Inst.addOperand(MCOperand::createImm(CE->getValue())); 818 else 819 Inst.addOperand(MCOperand::createExpr(Expr)); 820 } 821 822 void addRegOperands(MCInst &Inst, unsigned N) const { 823 llvm_unreachable("Use a custom parser instead"); 824 } 825 826 /// Render the operand to an MCInst as a GPR32 827 /// Asserts if the wrong number of operands are requested, or the operand 828 /// is not a k_RegisterIndex compatible with RegKind_GPR 829 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const { 830 assert(N == 1 && "Invalid number of operands!"); 831 Inst.addOperand(MCOperand::createReg(getGPR32Reg())); 832 } 833 834 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const { 835 assert(N == 1 && "Invalid number of operands!"); 836 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg())); 837 } 838 839 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const { 840 assert(N == 1 && "Invalid number of operands!"); 841 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg())); 842 } 843 844 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const { 845 assert(N == 1 && "Invalid number of operands!"); 846 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg())); 847 } 848 849 /// Render the operand to an MCInst as a GPR64 850 /// Asserts if the wrong number of operands are requested, or the operand 851 /// is not a k_RegisterIndex compatible with RegKind_GPR 852 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const { 853 assert(N == 1 && "Invalid number of operands!"); 854 Inst.addOperand(MCOperand::createReg(getGPR64Reg())); 855 } 856 857 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const { 858 assert(N == 1 && "Invalid number of operands!"); 859 Inst.addOperand(MCOperand::createReg(getAFGR64Reg())); 860 } 861 862 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const { 863 assert(N == 1 && "Invalid number of operands!"); 864 Inst.addOperand(MCOperand::createReg(getFGR64Reg())); 865 } 866 867 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const { 868 assert(N == 1 && "Invalid number of operands!"); 869 Inst.addOperand(MCOperand::createReg(getFGR32Reg())); 870 // FIXME: We ought to do this for -integrated-as without -via-file-asm too. 871 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1) 872 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU " 873 "registers"); 874 } 875 876 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const { 877 assert(N == 1 && "Invalid number of operands!"); 878 Inst.addOperand(MCOperand::createReg(getFGRH32Reg())); 879 } 880 881 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const { 882 assert(N == 1 && "Invalid number of operands!"); 883 Inst.addOperand(MCOperand::createReg(getFCCReg())); 884 } 885 886 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const { 887 assert(N == 1 && "Invalid number of operands!"); 888 Inst.addOperand(MCOperand::createReg(getMSA128Reg())); 889 } 890 891 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const { 892 assert(N == 1 && "Invalid number of operands!"); 893 Inst.addOperand(MCOperand::createReg(getMSACtrlReg())); 894 } 895 896 void addCOP0AsmRegOperands(MCInst &Inst, unsigned N) const { 897 assert(N == 1 && "Invalid number of operands!"); 898 Inst.addOperand(MCOperand::createReg(getCOP0Reg())); 899 } 900 901 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const { 902 assert(N == 1 && "Invalid number of operands!"); 903 Inst.addOperand(MCOperand::createReg(getCOP2Reg())); 904 } 905 906 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const { 907 assert(N == 1 && "Invalid number of operands!"); 908 Inst.addOperand(MCOperand::createReg(getCOP3Reg())); 909 } 910 911 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const { 912 assert(N == 1 && "Invalid number of operands!"); 913 Inst.addOperand(MCOperand::createReg(getACC64DSPReg())); 914 } 915 916 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const { 917 assert(N == 1 && "Invalid number of operands!"); 918 Inst.addOperand(MCOperand::createReg(getHI32DSPReg())); 919 } 920 921 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const { 922 assert(N == 1 && "Invalid number of operands!"); 923 Inst.addOperand(MCOperand::createReg(getLO32DSPReg())); 924 } 925 926 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const { 927 assert(N == 1 && "Invalid number of operands!"); 928 Inst.addOperand(MCOperand::createReg(getCCRReg())); 929 } 930 931 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const { 932 assert(N == 1 && "Invalid number of operands!"); 933 Inst.addOperand(MCOperand::createReg(getHWRegsReg())); 934 } 935 936 template <unsigned Bits, int Offset = 0, int AdjustOffset = 0> 937 void addConstantUImmOperands(MCInst &Inst, unsigned N) const { 938 assert(N == 1 && "Invalid number of operands!"); 939 uint64_t Imm = getConstantImm() - Offset; 940 Imm &= (1 << Bits) - 1; 941 Imm += Offset; 942 Imm += AdjustOffset; 943 Inst.addOperand(MCOperand::createImm(Imm)); 944 } 945 946 template <unsigned Bits> 947 void addSImmOperands(MCInst &Inst, unsigned N) const { 948 if (isImm() && !isConstantImm()) { 949 addExpr(Inst, getImm()); 950 return; 951 } 952 addConstantSImmOperands<Bits, 0, 0>(Inst, N); 953 } 954 955 template <unsigned Bits> 956 void addUImmOperands(MCInst &Inst, unsigned N) const { 957 if (isImm() && !isConstantImm()) { 958 addExpr(Inst, getImm()); 959 return; 960 } 961 addConstantUImmOperands<Bits, 0, 0>(Inst, N); 962 } 963 964 template <unsigned Bits, int Offset = 0, int AdjustOffset = 0> 965 void addConstantSImmOperands(MCInst &Inst, unsigned N) const { 966 assert(N == 1 && "Invalid number of operands!"); 967 int64_t Imm = getConstantImm() - Offset; 968 Imm = SignExtend64<Bits>(Imm); 969 Imm += Offset; 970 Imm += AdjustOffset; 971 Inst.addOperand(MCOperand::createImm(Imm)); 972 } 973 974 void addImmOperands(MCInst &Inst, unsigned N) const { 975 assert(N == 1 && "Invalid number of operands!"); 976 const MCExpr *Expr = getImm(); 977 addExpr(Inst, Expr); 978 } 979 980 void addMemOperands(MCInst &Inst, unsigned N) const { 981 assert(N == 2 && "Invalid number of operands!"); 982 983 Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit() 984 ? getMemBase()->getGPR64Reg() 985 : getMemBase()->getGPR32Reg())); 986 987 const MCExpr *Expr = getMemOff(); 988 addExpr(Inst, Expr); 989 } 990 991 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const { 992 assert(N == 2 && "Invalid number of operands!"); 993 994 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg())); 995 996 const MCExpr *Expr = getMemOff(); 997 addExpr(Inst, Expr); 998 } 999 1000 void addRegListOperands(MCInst &Inst, unsigned N) const { 1001 assert(N == 1 && "Invalid number of operands!"); 1002 1003 for (auto RegNo : getRegList()) 1004 Inst.addOperand(MCOperand::createReg(RegNo)); 1005 } 1006 1007 void addRegPairOperands(MCInst &Inst, unsigned N) const { 1008 assert(N == 2 && "Invalid number of operands!"); 1009 assert((RegIdx.Kind & RegKind_GPR) && "Invalid access!"); 1010 unsigned RegNo = getRegPair(); 1011 AsmParser.warnIfRegIndexIsAT(RegNo, StartLoc); 1012 Inst.addOperand(MCOperand::createReg( 1013 RegIdx.RegInfo->getRegClass( 1014 AsmParser.getABI().AreGprs64bit() 1015 ? Mips::GPR64RegClassID 1016 : Mips::GPR32RegClassID).getRegister(RegNo++))); 1017 Inst.addOperand(MCOperand::createReg( 1018 RegIdx.RegInfo->getRegClass( 1019 AsmParser.getABI().AreGprs64bit() 1020 ? Mips::GPR64RegClassID 1021 : Mips::GPR32RegClassID).getRegister(RegNo))); 1022 } 1023 1024 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const { 1025 assert(N == 2 && "Invalid number of operands!"); 1026 for (auto RegNo : getRegList()) 1027 Inst.addOperand(MCOperand::createReg(RegNo)); 1028 } 1029 1030 bool isReg() const override { 1031 // As a special case until we sort out the definition of div/divu, pretend 1032 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly. 1033 if (isGPRAsmReg() && RegIdx.Index == 0) 1034 return true; 1035 1036 return Kind == k_PhysRegister; 1037 } 1038 bool isRegIdx() const { return Kind == k_RegisterIndex; } 1039 bool isImm() const override { return Kind == k_Immediate; } 1040 bool isConstantImm() const { 1041 return isImm() && isa<MCConstantExpr>(getImm()); 1042 } 1043 bool isConstantImmz() const { 1044 return isConstantImm() && getConstantImm() == 0; 1045 } 1046 template <unsigned Bits, int Offset = 0> bool isConstantUImm() const { 1047 return isConstantImm() && isUInt<Bits>(getConstantImm() - Offset); 1048 } 1049 template <unsigned Bits> bool isSImm() const { 1050 return isConstantImm() ? isInt<Bits>(getConstantImm()) : isImm(); 1051 } 1052 template <unsigned Bits> bool isUImm() const { 1053 return isConstantImm() ? isUInt<Bits>(getConstantImm()) : isImm(); 1054 } 1055 template <unsigned Bits> bool isAnyImm() const { 1056 return isConstantImm() ? (isInt<Bits>(getConstantImm()) || 1057 isUInt<Bits>(getConstantImm())) 1058 : isImm(); 1059 } 1060 template <unsigned Bits, int Offset = 0> bool isConstantSImm() const { 1061 return isConstantImm() && isInt<Bits>(getConstantImm() - Offset); 1062 } 1063 template <unsigned Bottom, unsigned Top> bool isConstantUImmRange() const { 1064 return isConstantImm() && getConstantImm() >= Bottom && 1065 getConstantImm() <= Top; 1066 } 1067 bool isToken() const override { 1068 // Note: It's not possible to pretend that other operand kinds are tokens. 1069 // The matcher emitter checks tokens first. 1070 return Kind == k_Token; 1071 } 1072 bool isMem() const override { return Kind == k_Memory; } 1073 bool isConstantMemOff() const { 1074 return isMem() && isa<MCConstantExpr>(getMemOff()); 1075 } 1076 template <unsigned Bits, unsigned ShiftAmount = 0> 1077 bool isMemWithSimmOffset() const { 1078 return isMem() && isConstantMemOff() && 1079 isShiftedInt<Bits, ShiftAmount>(getConstantMemOff()) && 1080 getMemBase()->isGPRAsmReg(); 1081 } 1082 bool isMemWithGRPMM16Base() const { 1083 return isMem() && getMemBase()->isMM16AsmReg(); 1084 } 1085 template <unsigned Bits> bool isMemWithUimmOffsetSP() const { 1086 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff()) 1087 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP); 1088 } 1089 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const { 1090 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff()) 1091 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx() 1092 && (getMemBase()->getGPR32Reg() == Mips::SP); 1093 } 1094 template <unsigned Bits> bool isMemWithSimmWordAlignedOffsetGP() const { 1095 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff()) 1096 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx() 1097 && (getMemBase()->getGPR32Reg() == Mips::GP); 1098 } 1099 template <unsigned Bits, unsigned ShiftLeftAmount> 1100 bool isScaledUImm() const { 1101 return isConstantImm() && 1102 isShiftedUInt<Bits, ShiftLeftAmount>(getConstantImm()); 1103 } 1104 template <unsigned Bits, unsigned ShiftLeftAmount> 1105 bool isScaledSImm() const { 1106 return isConstantImm() && 1107 isShiftedInt<Bits, ShiftLeftAmount>(getConstantImm()); 1108 } 1109 bool isRegList16() const { 1110 if (!isRegList()) 1111 return false; 1112 1113 int Size = RegList.List->size(); 1114 if (Size < 2 || Size > 5) 1115 return false; 1116 1117 unsigned R0 = RegList.List->front(); 1118 unsigned R1 = RegList.List->back(); 1119 if (!((R0 == Mips::S0 && R1 == Mips::RA) || 1120 (R0 == Mips::S0_64 && R1 == Mips::RA_64))) 1121 return false; 1122 1123 int PrevReg = *RegList.List->begin(); 1124 for (int i = 1; i < Size - 1; i++) { 1125 int Reg = (*(RegList.List))[i]; 1126 if ( Reg != PrevReg + 1) 1127 return false; 1128 PrevReg = Reg; 1129 } 1130 1131 return true; 1132 } 1133 bool isInvNum() const { return Kind == k_Immediate; } 1134 bool isLSAImm() const { 1135 if (!isConstantImm()) 1136 return false; 1137 int64_t Val = getConstantImm(); 1138 return 1 <= Val && Val <= 4; 1139 } 1140 bool isRegList() const { return Kind == k_RegList; } 1141 bool isMovePRegPair() const { 1142 if (Kind != k_RegList || RegList.List->size() != 2) 1143 return false; 1144 1145 unsigned R0 = RegList.List->front(); 1146 unsigned R1 = RegList.List->back(); 1147 1148 if ((R0 == Mips::A1 && R1 == Mips::A2) || 1149 (R0 == Mips::A1 && R1 == Mips::A3) || 1150 (R0 == Mips::A2 && R1 == Mips::A3) || 1151 (R0 == Mips::A0 && R1 == Mips::S5) || 1152 (R0 == Mips::A0 && R1 == Mips::S6) || 1153 (R0 == Mips::A0 && R1 == Mips::A1) || 1154 (R0 == Mips::A0 && R1 == Mips::A2) || 1155 (R0 == Mips::A0 && R1 == Mips::A3) || 1156 (R0 == Mips::A1_64 && R1 == Mips::A2_64) || 1157 (R0 == Mips::A1_64 && R1 == Mips::A3_64) || 1158 (R0 == Mips::A2_64 && R1 == Mips::A3_64) || 1159 (R0 == Mips::A0_64 && R1 == Mips::S5_64) || 1160 (R0 == Mips::A0_64 && R1 == Mips::S6_64) || 1161 (R0 == Mips::A0_64 && R1 == Mips::A1_64) || 1162 (R0 == Mips::A0_64 && R1 == Mips::A2_64) || 1163 (R0 == Mips::A0_64 && R1 == Mips::A3_64)) 1164 return true; 1165 1166 return false; 1167 } 1168 1169 StringRef getToken() const { 1170 assert(Kind == k_Token && "Invalid access!"); 1171 return StringRef(Tok.Data, Tok.Length); 1172 } 1173 bool isRegPair() const { 1174 return Kind == k_RegPair && RegIdx.Index <= 30; 1175 } 1176 1177 unsigned getReg() const override { 1178 // As a special case until we sort out the definition of div/divu, pretend 1179 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly. 1180 if (Kind == k_RegisterIndex && RegIdx.Index == 0 && 1181 RegIdx.Kind & RegKind_GPR) 1182 return getGPR32Reg(); // FIXME: GPR64 too 1183 1184 assert(Kind == k_PhysRegister && "Invalid access!"); 1185 return PhysReg.Num; 1186 } 1187 1188 const MCExpr *getImm() const { 1189 assert((Kind == k_Immediate) && "Invalid access!"); 1190 return Imm.Val; 1191 } 1192 1193 int64_t getConstantImm() const { 1194 const MCExpr *Val = getImm(); 1195 return static_cast<const MCConstantExpr *>(Val)->getValue(); 1196 } 1197 1198 MipsOperand *getMemBase() const { 1199 assert((Kind == k_Memory) && "Invalid access!"); 1200 return Mem.Base; 1201 } 1202 1203 const MCExpr *getMemOff() const { 1204 assert((Kind == k_Memory) && "Invalid access!"); 1205 return Mem.Off; 1206 } 1207 1208 int64_t getConstantMemOff() const { 1209 return static_cast<const MCConstantExpr *>(getMemOff())->getValue(); 1210 } 1211 1212 const SmallVectorImpl<unsigned> &getRegList() const { 1213 assert((Kind == k_RegList) && "Invalid access!"); 1214 return *(RegList.List); 1215 } 1216 1217 unsigned getRegPair() const { 1218 assert((Kind == k_RegPair) && "Invalid access!"); 1219 return RegIdx.Index; 1220 } 1221 1222 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S, 1223 MipsAsmParser &Parser) { 1224 auto Op = make_unique<MipsOperand>(k_Token, Parser); 1225 Op->Tok.Data = Str.data(); 1226 Op->Tok.Length = Str.size(); 1227 Op->StartLoc = S; 1228 Op->EndLoc = S; 1229 return Op; 1230 } 1231 1232 /// Create a numeric register (e.g. $1). The exact register remains 1233 /// unresolved until an instruction successfully matches 1234 static std::unique_ptr<MipsOperand> 1235 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, 1236 SMLoc E, MipsAsmParser &Parser) { 1237 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n"); 1238 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser); 1239 } 1240 1241 /// Create a register that is definitely a GPR. 1242 /// This is typically only used for named registers such as $gp. 1243 static std::unique_ptr<MipsOperand> 1244 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E, 1245 MipsAsmParser &Parser) { 1246 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser); 1247 } 1248 1249 /// Create a register that is definitely a FGR. 1250 /// This is typically only used for named registers such as $f0. 1251 static std::unique_ptr<MipsOperand> 1252 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E, 1253 MipsAsmParser &Parser) { 1254 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser); 1255 } 1256 1257 /// Create a register that is definitely a HWReg. 1258 /// This is typically only used for named registers such as $hwr_cpunum. 1259 static std::unique_ptr<MipsOperand> 1260 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo, 1261 SMLoc S, SMLoc E, MipsAsmParser &Parser) { 1262 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser); 1263 } 1264 1265 /// Create a register that is definitely an FCC. 1266 /// This is typically only used for named registers such as $fcc0. 1267 static std::unique_ptr<MipsOperand> 1268 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E, 1269 MipsAsmParser &Parser) { 1270 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser); 1271 } 1272 1273 /// Create a register that is definitely an ACC. 1274 /// This is typically only used for named registers such as $ac0. 1275 static std::unique_ptr<MipsOperand> 1276 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E, 1277 MipsAsmParser &Parser) { 1278 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser); 1279 } 1280 1281 /// Create a register that is definitely an MSA128. 1282 /// This is typically only used for named registers such as $w0. 1283 static std::unique_ptr<MipsOperand> 1284 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, 1285 SMLoc E, MipsAsmParser &Parser) { 1286 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser); 1287 } 1288 1289 /// Create a register that is definitely an MSACtrl. 1290 /// This is typically only used for named registers such as $msaaccess. 1291 static std::unique_ptr<MipsOperand> 1292 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, 1293 SMLoc E, MipsAsmParser &Parser) { 1294 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser); 1295 } 1296 1297 static std::unique_ptr<MipsOperand> 1298 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) { 1299 auto Op = make_unique<MipsOperand>(k_Immediate, Parser); 1300 Op->Imm.Val = Val; 1301 Op->StartLoc = S; 1302 Op->EndLoc = E; 1303 return Op; 1304 } 1305 1306 static std::unique_ptr<MipsOperand> 1307 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S, 1308 SMLoc E, MipsAsmParser &Parser) { 1309 auto Op = make_unique<MipsOperand>(k_Memory, Parser); 1310 Op->Mem.Base = Base.release(); 1311 Op->Mem.Off = Off; 1312 Op->StartLoc = S; 1313 Op->EndLoc = E; 1314 return Op; 1315 } 1316 1317 static std::unique_ptr<MipsOperand> 1318 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc, 1319 MipsAsmParser &Parser) { 1320 assert (Regs.size() > 0 && "Empty list not allowed"); 1321 1322 auto Op = make_unique<MipsOperand>(k_RegList, Parser); 1323 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end()); 1324 Op->StartLoc = StartLoc; 1325 Op->EndLoc = EndLoc; 1326 return Op; 1327 } 1328 1329 static std::unique_ptr<MipsOperand> CreateRegPair(const MipsOperand &MOP, 1330 SMLoc S, SMLoc E, 1331 MipsAsmParser &Parser) { 1332 auto Op = make_unique<MipsOperand>(k_RegPair, Parser); 1333 Op->RegIdx.Index = MOP.RegIdx.Index; 1334 Op->RegIdx.RegInfo = MOP.RegIdx.RegInfo; 1335 Op->RegIdx.Kind = MOP.RegIdx.Kind; 1336 Op->StartLoc = S; 1337 Op->EndLoc = E; 1338 return Op; 1339 } 1340 1341 bool isGPRAsmReg() const { 1342 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31; 1343 } 1344 bool isMM16AsmReg() const { 1345 if (!(isRegIdx() && RegIdx.Kind)) 1346 return false; 1347 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7) 1348 || RegIdx.Index == 16 || RegIdx.Index == 17); 1349 } 1350 bool isMM16AsmRegZero() const { 1351 if (!(isRegIdx() && RegIdx.Kind)) 1352 return false; 1353 return (RegIdx.Index == 0 || 1354 (RegIdx.Index >= 2 && RegIdx.Index <= 7) || 1355 RegIdx.Index == 17); 1356 } 1357 bool isMM16AsmRegMoveP() const { 1358 if (!(isRegIdx() && RegIdx.Kind)) 1359 return false; 1360 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) || 1361 (RegIdx.Index >= 16 && RegIdx.Index <= 20)); 1362 } 1363 bool isFGRAsmReg() const { 1364 // AFGR64 is $0-$15 but we handle this in getAFGR64() 1365 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31; 1366 } 1367 bool isHWRegsAsmReg() const { 1368 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31; 1369 } 1370 bool isCCRAsmReg() const { 1371 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31; 1372 } 1373 bool isFCCAsmReg() const { 1374 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC)) 1375 return false; 1376 if (!AsmParser.hasEightFccRegisters()) 1377 return RegIdx.Index == 0; 1378 return RegIdx.Index <= 7; 1379 } 1380 bool isACCAsmReg() const { 1381 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3; 1382 } 1383 bool isCOP0AsmReg() const { 1384 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31; 1385 } 1386 bool isCOP2AsmReg() const { 1387 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31; 1388 } 1389 bool isCOP3AsmReg() const { 1390 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31; 1391 } 1392 bool isMSA128AsmReg() const { 1393 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31; 1394 } 1395 bool isMSACtrlAsmReg() const { 1396 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7; 1397 } 1398 1399 /// getStartLoc - Get the location of the first token of this operand. 1400 SMLoc getStartLoc() const override { return StartLoc; } 1401 /// getEndLoc - Get the location of the last token of this operand. 1402 SMLoc getEndLoc() const override { return EndLoc; } 1403 1404 virtual ~MipsOperand() { 1405 switch (Kind) { 1406 case k_Immediate: 1407 break; 1408 case k_Memory: 1409 delete Mem.Base; 1410 break; 1411 case k_RegList: 1412 delete RegList.List; 1413 case k_PhysRegister: 1414 case k_RegisterIndex: 1415 case k_Token: 1416 case k_RegPair: 1417 break; 1418 } 1419 } 1420 1421 void print(raw_ostream &OS) const override { 1422 switch (Kind) { 1423 case k_Immediate: 1424 OS << "Imm<"; 1425 OS << *Imm.Val; 1426 OS << ">"; 1427 break; 1428 case k_Memory: 1429 OS << "Mem<"; 1430 Mem.Base->print(OS); 1431 OS << ", "; 1432 OS << *Mem.Off; 1433 OS << ">"; 1434 break; 1435 case k_PhysRegister: 1436 OS << "PhysReg<" << PhysReg.Num << ">"; 1437 break; 1438 case k_RegisterIndex: 1439 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">"; 1440 break; 1441 case k_Token: 1442 OS << Tok.Data; 1443 break; 1444 case k_RegList: 1445 OS << "RegList< "; 1446 for (auto Reg : (*RegList.List)) 1447 OS << Reg << " "; 1448 OS << ">"; 1449 break; 1450 case k_RegPair: 1451 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">"; 1452 break; 1453 } 1454 } 1455 }; // class MipsOperand 1456 } // namespace 1457 1458 namespace llvm { 1459 extern const MCInstrDesc MipsInsts[]; 1460 } 1461 static const MCInstrDesc &getInstDesc(unsigned Opcode) { 1462 return MipsInsts[Opcode]; 1463 } 1464 1465 static bool hasShortDelaySlot(unsigned Opcode) { 1466 switch (Opcode) { 1467 case Mips::JALS_MM: 1468 case Mips::JALRS_MM: 1469 case Mips::JALRS16_MM: 1470 case Mips::BGEZALS_MM: 1471 case Mips::BLTZALS_MM: 1472 return true; 1473 default: 1474 return false; 1475 } 1476 } 1477 1478 static const MCSymbol *getSingleMCSymbol(const MCExpr *Expr) { 1479 if (const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) { 1480 return &SRExpr->getSymbol(); 1481 } 1482 1483 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) { 1484 const MCSymbol *LHSSym = getSingleMCSymbol(BExpr->getLHS()); 1485 const MCSymbol *RHSSym = getSingleMCSymbol(BExpr->getRHS()); 1486 1487 if (LHSSym) 1488 return LHSSym; 1489 1490 if (RHSSym) 1491 return RHSSym; 1492 1493 return nullptr; 1494 } 1495 1496 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr)) 1497 return getSingleMCSymbol(UExpr->getSubExpr()); 1498 1499 return nullptr; 1500 } 1501 1502 static unsigned countMCSymbolRefExpr(const MCExpr *Expr) { 1503 if (isa<MCSymbolRefExpr>(Expr)) 1504 return 1; 1505 1506 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) 1507 return countMCSymbolRefExpr(BExpr->getLHS()) + 1508 countMCSymbolRefExpr(BExpr->getRHS()); 1509 1510 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr)) 1511 return countMCSymbolRefExpr(UExpr->getSubExpr()); 1512 1513 return 0; 1514 } 1515 1516 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, 1517 MCStreamer &Out, 1518 const MCSubtargetInfo *STI) { 1519 MipsTargetStreamer &TOut = getTargetStreamer(); 1520 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode()); 1521 bool ExpandedJalSym = false; 1522 1523 Inst.setLoc(IDLoc); 1524 1525 if (MCID.isBranch() || MCID.isCall()) { 1526 const unsigned Opcode = Inst.getOpcode(); 1527 MCOperand Offset; 1528 1529 switch (Opcode) { 1530 default: 1531 break; 1532 case Mips::BBIT0: 1533 case Mips::BBIT032: 1534 case Mips::BBIT1: 1535 case Mips::BBIT132: 1536 assert(hasCnMips() && "instruction only valid for octeon cpus"); 1537 // Fall through 1538 1539 case Mips::BEQ: 1540 case Mips::BNE: 1541 case Mips::BEQ_MM: 1542 case Mips::BNE_MM: 1543 assert(MCID.getNumOperands() == 3 && "unexpected number of operands"); 1544 Offset = Inst.getOperand(2); 1545 if (!Offset.isImm()) 1546 break; // We'll deal with this situation later on when applying fixups. 1547 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm())) 1548 return Error(IDLoc, "branch target out of range"); 1549 if (OffsetToAlignment(Offset.getImm(), 1550 1LL << (inMicroMipsMode() ? 1 : 2))) 1551 return Error(IDLoc, "branch to misaligned address"); 1552 break; 1553 case Mips::BGEZ: 1554 case Mips::BGTZ: 1555 case Mips::BLEZ: 1556 case Mips::BLTZ: 1557 case Mips::BGEZAL: 1558 case Mips::BLTZAL: 1559 case Mips::BC1F: 1560 case Mips::BC1T: 1561 case Mips::BGEZ_MM: 1562 case Mips::BGTZ_MM: 1563 case Mips::BLEZ_MM: 1564 case Mips::BLTZ_MM: 1565 case Mips::BGEZAL_MM: 1566 case Mips::BLTZAL_MM: 1567 case Mips::BC1F_MM: 1568 case Mips::BC1T_MM: 1569 case Mips::BC1EQZC_MMR6: 1570 case Mips::BC1NEZC_MMR6: 1571 case Mips::BC2EQZC_MMR6: 1572 case Mips::BC2NEZC_MMR6: 1573 assert(MCID.getNumOperands() == 2 && "unexpected number of operands"); 1574 Offset = Inst.getOperand(1); 1575 if (!Offset.isImm()) 1576 break; // We'll deal with this situation later on when applying fixups. 1577 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm())) 1578 return Error(IDLoc, "branch target out of range"); 1579 if (OffsetToAlignment(Offset.getImm(), 1580 1LL << (inMicroMipsMode() ? 1 : 2))) 1581 return Error(IDLoc, "branch to misaligned address"); 1582 break; 1583 case Mips::BEQZ16_MM: 1584 case Mips::BEQZC16_MMR6: 1585 case Mips::BNEZ16_MM: 1586 case Mips::BNEZC16_MMR6: 1587 assert(MCID.getNumOperands() == 2 && "unexpected number of operands"); 1588 Offset = Inst.getOperand(1); 1589 if (!Offset.isImm()) 1590 break; // We'll deal with this situation later on when applying fixups. 1591 if (!isInt<8>(Offset.getImm())) 1592 return Error(IDLoc, "branch target out of range"); 1593 if (OffsetToAlignment(Offset.getImm(), 2LL)) 1594 return Error(IDLoc, "branch to misaligned address"); 1595 break; 1596 } 1597 } 1598 1599 // SSNOP is deprecated on MIPS32r6/MIPS64r6 1600 // We still accept it but it is a normal nop. 1601 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) { 1602 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6"; 1603 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a " 1604 "nop instruction"); 1605 } 1606 1607 if (hasCnMips()) { 1608 const unsigned Opcode = Inst.getOpcode(); 1609 MCOperand Opnd; 1610 int Imm; 1611 1612 switch (Opcode) { 1613 default: 1614 break; 1615 1616 case Mips::BBIT0: 1617 case Mips::BBIT032: 1618 case Mips::BBIT1: 1619 case Mips::BBIT132: 1620 assert(MCID.getNumOperands() == 3 && "unexpected number of operands"); 1621 // The offset is handled above 1622 Opnd = Inst.getOperand(1); 1623 if (!Opnd.isImm()) 1624 return Error(IDLoc, "expected immediate operand kind"); 1625 Imm = Opnd.getImm(); 1626 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 || 1627 Opcode == Mips::BBIT1 ? 63 : 31)) 1628 return Error(IDLoc, "immediate operand value out of range"); 1629 if (Imm > 31) { 1630 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032 1631 : Mips::BBIT132); 1632 Inst.getOperand(1).setImm(Imm - 32); 1633 } 1634 break; 1635 1636 case Mips::SEQi: 1637 case Mips::SNEi: 1638 assert(MCID.getNumOperands() == 3 && "unexpected number of operands"); 1639 Opnd = Inst.getOperand(2); 1640 if (!Opnd.isImm()) 1641 return Error(IDLoc, "expected immediate operand kind"); 1642 Imm = Opnd.getImm(); 1643 if (!isInt<10>(Imm)) 1644 return Error(IDLoc, "immediate operand value out of range"); 1645 break; 1646 } 1647 } 1648 1649 // This expansion is not in a function called by tryExpandInstruction() 1650 // because the pseudo-instruction doesn't have a distinct opcode. 1651 if ((Inst.getOpcode() == Mips::JAL || Inst.getOpcode() == Mips::JAL_MM) && 1652 inPicMode()) { 1653 warnIfNoMacro(IDLoc); 1654 1655 const MCExpr *JalExpr = Inst.getOperand(0).getExpr(); 1656 1657 // We can do this expansion if there's only 1 symbol in the argument 1658 // expression. 1659 if (countMCSymbolRefExpr(JalExpr) > 1) 1660 return Error(IDLoc, "jal doesn't support multiple symbols in PIC mode"); 1661 1662 // FIXME: This is checking the expression can be handled by the later stages 1663 // of the assembler. We ought to leave it to those later stages. 1664 const MCSymbol *JalSym = getSingleMCSymbol(JalExpr); 1665 1666 // FIXME: Add support for label+offset operands (currently causes an error). 1667 // FIXME: Add support for forward-declared local symbols. 1668 // FIXME: Add expansion for when the LargeGOT option is enabled. 1669 if (JalSym->isInSection() || JalSym->isTemporary()) { 1670 if (isABI_O32()) { 1671 // If it's a local symbol and the O32 ABI is being used, we expand to: 1672 // lw $25, 0($gp) 1673 // R_(MICRO)MIPS_GOT16 label 1674 // addiu $25, $25, 0 1675 // R_(MICRO)MIPS_LO16 label 1676 // jalr $25 1677 const MCExpr *Got16RelocExpr = 1678 MipsMCExpr::create(MipsMCExpr::MEK_GOT, JalExpr, getContext()); 1679 const MCExpr *Lo16RelocExpr = 1680 MipsMCExpr::create(MipsMCExpr::MEK_LO, JalExpr, getContext()); 1681 1682 TOut.emitRRX(Mips::LW, Mips::T9, Mips::GP, 1683 MCOperand::createExpr(Got16RelocExpr), IDLoc, STI); 1684 TOut.emitRRX(Mips::ADDiu, Mips::T9, Mips::T9, 1685 MCOperand::createExpr(Lo16RelocExpr), IDLoc, STI); 1686 } else if (isABI_N32() || isABI_N64()) { 1687 // If it's a local symbol and the N32/N64 ABIs are being used, 1688 // we expand to: 1689 // lw/ld $25, 0($gp) 1690 // R_(MICRO)MIPS_GOT_DISP label 1691 // jalr $25 1692 const MCExpr *GotDispRelocExpr = 1693 MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP, JalExpr, getContext()); 1694 1695 TOut.emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, 1696 Mips::GP, MCOperand::createExpr(GotDispRelocExpr), IDLoc, 1697 STI); 1698 } 1699 } else { 1700 // If it's an external/weak symbol, we expand to: 1701 // lw/ld $25, 0($gp) 1702 // R_(MICRO)MIPS_CALL16 label 1703 // jalr $25 1704 const MCExpr *Call16RelocExpr = 1705 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, JalExpr, getContext()); 1706 1707 TOut.emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, Mips::GP, 1708 MCOperand::createExpr(Call16RelocExpr), IDLoc, STI); 1709 } 1710 1711 MCInst JalrInst; 1712 if (IsCpRestoreSet && inMicroMipsMode()) 1713 JalrInst.setOpcode(Mips::JALRS_MM); 1714 else 1715 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR); 1716 JalrInst.addOperand(MCOperand::createReg(Mips::RA)); 1717 JalrInst.addOperand(MCOperand::createReg(Mips::T9)); 1718 1719 // FIXME: Add an R_(MICRO)MIPS_JALR relocation after the JALR. 1720 // This relocation is supposed to be an optimization hint for the linker 1721 // and is not necessary for correctness. 1722 1723 Inst = JalrInst; 1724 ExpandedJalSym = true; 1725 } 1726 1727 if (MCID.mayLoad() || MCID.mayStore()) { 1728 // Check the offset of memory operand, if it is a symbol 1729 // reference or immediate we may have to expand instructions. 1730 for (unsigned i = 0; i < MCID.getNumOperands(); i++) { 1731 const MCOperandInfo &OpInfo = MCID.OpInfo[i]; 1732 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) || 1733 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) { 1734 MCOperand &Op = Inst.getOperand(i); 1735 if (Op.isImm()) { 1736 int MemOffset = Op.getImm(); 1737 if (MemOffset < -32768 || MemOffset > 32767) { 1738 // Offset can't exceed 16bit value. 1739 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad(), true); 1740 return false; 1741 } 1742 } else if (Op.isExpr()) { 1743 const MCExpr *Expr = Op.getExpr(); 1744 if (Expr->getKind() == MCExpr::SymbolRef) { 1745 const MCSymbolRefExpr *SR = 1746 static_cast<const MCSymbolRefExpr *>(Expr); 1747 if (SR->getKind() == MCSymbolRefExpr::VK_None) { 1748 // Expand symbol. 1749 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad(), false); 1750 return false; 1751 } 1752 } else if (!isEvaluated(Expr)) { 1753 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad(), false); 1754 return false; 1755 } 1756 } 1757 } 1758 } // for 1759 } // if load/store 1760 1761 if (inMicroMipsMode()) { 1762 if (MCID.mayLoad()) { 1763 // Try to create 16-bit GP relative load instruction. 1764 for (unsigned i = 0; i < MCID.getNumOperands(); i++) { 1765 const MCOperandInfo &OpInfo = MCID.OpInfo[i]; 1766 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) || 1767 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) { 1768 MCOperand &Op = Inst.getOperand(i); 1769 if (Op.isImm()) { 1770 int MemOffset = Op.getImm(); 1771 MCOperand &DstReg = Inst.getOperand(0); 1772 MCOperand &BaseReg = Inst.getOperand(1); 1773 if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) && 1774 getContext().getRegisterInfo()->getRegClass( 1775 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) && 1776 (BaseReg.getReg() == Mips::GP || 1777 BaseReg.getReg() == Mips::GP_64)) { 1778 1779 TOut.emitRRI(Mips::LWGP_MM, DstReg.getReg(), Mips::GP, MemOffset, 1780 IDLoc, STI); 1781 return false; 1782 } 1783 } 1784 } 1785 } // for 1786 } // if load 1787 1788 // TODO: Handle this with the AsmOperandClass.PredicateMethod. 1789 1790 MCOperand Opnd; 1791 int Imm; 1792 1793 switch (Inst.getOpcode()) { 1794 default: 1795 break; 1796 case Mips::ADDIUSP_MM: 1797 Opnd = Inst.getOperand(0); 1798 if (!Opnd.isImm()) 1799 return Error(IDLoc, "expected immediate operand kind"); 1800 Imm = Opnd.getImm(); 1801 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) || 1802 Imm % 4 != 0) 1803 return Error(IDLoc, "immediate operand value out of range"); 1804 break; 1805 case Mips::SLL16_MM: 1806 case Mips::SRL16_MM: 1807 Opnd = Inst.getOperand(2); 1808 if (!Opnd.isImm()) 1809 return Error(IDLoc, "expected immediate operand kind"); 1810 Imm = Opnd.getImm(); 1811 if (Imm < 1 || Imm > 8) 1812 return Error(IDLoc, "immediate operand value out of range"); 1813 break; 1814 case Mips::LI16_MM: 1815 Opnd = Inst.getOperand(1); 1816 if (!Opnd.isImm()) 1817 return Error(IDLoc, "expected immediate operand kind"); 1818 Imm = Opnd.getImm(); 1819 if (Imm < -1 || Imm > 126) 1820 return Error(IDLoc, "immediate operand value out of range"); 1821 break; 1822 case Mips::ADDIUR2_MM: 1823 Opnd = Inst.getOperand(2); 1824 if (!Opnd.isImm()) 1825 return Error(IDLoc, "expected immediate operand kind"); 1826 Imm = Opnd.getImm(); 1827 if (!(Imm == 1 || Imm == -1 || 1828 ((Imm % 4 == 0) && Imm < 28 && Imm > 0))) 1829 return Error(IDLoc, "immediate operand value out of range"); 1830 break; 1831 case Mips::ANDI16_MM: 1832 Opnd = Inst.getOperand(2); 1833 if (!Opnd.isImm()) 1834 return Error(IDLoc, "expected immediate operand kind"); 1835 Imm = Opnd.getImm(); 1836 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 || 1837 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 || 1838 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535)) 1839 return Error(IDLoc, "immediate operand value out of range"); 1840 break; 1841 case Mips::LBU16_MM: 1842 Opnd = Inst.getOperand(2); 1843 if (!Opnd.isImm()) 1844 return Error(IDLoc, "expected immediate operand kind"); 1845 Imm = Opnd.getImm(); 1846 if (Imm < -1 || Imm > 14) 1847 return Error(IDLoc, "immediate operand value out of range"); 1848 break; 1849 case Mips::SB16_MM: 1850 case Mips::SB16_MMR6: 1851 Opnd = Inst.getOperand(2); 1852 if (!Opnd.isImm()) 1853 return Error(IDLoc, "expected immediate operand kind"); 1854 Imm = Opnd.getImm(); 1855 if (Imm < 0 || Imm > 15) 1856 return Error(IDLoc, "immediate operand value out of range"); 1857 break; 1858 case Mips::LHU16_MM: 1859 case Mips::SH16_MM: 1860 case Mips::SH16_MMR6: 1861 Opnd = Inst.getOperand(2); 1862 if (!Opnd.isImm()) 1863 return Error(IDLoc, "expected immediate operand kind"); 1864 Imm = Opnd.getImm(); 1865 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0)) 1866 return Error(IDLoc, "immediate operand value out of range"); 1867 break; 1868 case Mips::LW16_MM: 1869 case Mips::SW16_MM: 1870 case Mips::SW16_MMR6: 1871 Opnd = Inst.getOperand(2); 1872 if (!Opnd.isImm()) 1873 return Error(IDLoc, "expected immediate operand kind"); 1874 Imm = Opnd.getImm(); 1875 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0)) 1876 return Error(IDLoc, "immediate operand value out of range"); 1877 break; 1878 case Mips::ADDIUPC_MM: 1879 MCOperand Opnd = Inst.getOperand(1); 1880 if (!Opnd.isImm()) 1881 return Error(IDLoc, "expected immediate operand kind"); 1882 int Imm = Opnd.getImm(); 1883 if ((Imm % 4 != 0) || !isInt<25>(Imm)) 1884 return Error(IDLoc, "immediate operand value out of range"); 1885 break; 1886 } 1887 } 1888 1889 bool FillDelaySlot = 1890 MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder(); 1891 if (FillDelaySlot) 1892 TOut.emitDirectiveSetNoReorder(); 1893 1894 MacroExpanderResultTy ExpandResult = 1895 tryExpandInstruction(Inst, IDLoc, Out, STI); 1896 switch (ExpandResult) { 1897 case MER_NotAMacro: 1898 Out.EmitInstruction(Inst, *STI); 1899 break; 1900 case MER_Success: 1901 break; 1902 case MER_Fail: 1903 return true; 1904 } 1905 1906 // We know we emitted an instruction on the MER_NotAMacro or MER_Success path. 1907 // If we're in microMIPS mode then we must also set EF_MIPS_MICROMIPS. 1908 if (inMicroMipsMode()) 1909 TOut.setUsesMicroMips(); 1910 1911 // If this instruction has a delay slot and .set reorder is active, 1912 // emit a NOP after it. 1913 if (FillDelaySlot) { 1914 TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst.getOpcode()), IDLoc, STI); 1915 TOut.emitDirectiveSetReorder(); 1916 } 1917 1918 if ((Inst.getOpcode() == Mips::JalOneReg || 1919 Inst.getOpcode() == Mips::JalTwoReg || ExpandedJalSym) && 1920 isPicAndNotNxxAbi()) { 1921 if (IsCpRestoreSet) { 1922 // We need a NOP between the JALR and the LW: 1923 // If .set reorder has been used, we've already emitted a NOP. 1924 // If .set noreorder has been used, we need to emit a NOP at this point. 1925 if (!AssemblerOptions.back()->isReorder()) 1926 TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst.getOpcode()), IDLoc, 1927 STI); 1928 1929 // Load the $gp from the stack. 1930 TOut.emitGPRestore(CpRestoreOffset, IDLoc, STI); 1931 } else 1932 Warning(IDLoc, "no .cprestore used in PIC mode"); 1933 } 1934 1935 return false; 1936 } 1937 1938 MipsAsmParser::MacroExpanderResultTy 1939 MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 1940 const MCSubtargetInfo *STI) { 1941 switch (Inst.getOpcode()) { 1942 default: 1943 return MER_NotAMacro; 1944 case Mips::LoadImm32: 1945 return expandLoadImm(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success; 1946 case Mips::LoadImm64: 1947 return expandLoadImm(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success; 1948 case Mips::LoadAddrImm32: 1949 case Mips::LoadAddrImm64: 1950 assert(Inst.getOperand(0).isReg() && "expected register operand kind"); 1951 assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) && 1952 "expected immediate operand kind"); 1953 1954 return expandLoadAddress(Inst.getOperand(0).getReg(), Mips::NoRegister, 1955 Inst.getOperand(1), 1956 Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc, 1957 Out, STI) 1958 ? MER_Fail 1959 : MER_Success; 1960 case Mips::LoadAddrReg32: 1961 case Mips::LoadAddrReg64: 1962 assert(Inst.getOperand(0).isReg() && "expected register operand kind"); 1963 assert(Inst.getOperand(1).isReg() && "expected register operand kind"); 1964 assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) && 1965 "expected immediate operand kind"); 1966 1967 return expandLoadAddress(Inst.getOperand(0).getReg(), 1968 Inst.getOperand(1).getReg(), Inst.getOperand(2), 1969 Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc, 1970 Out, STI) 1971 ? MER_Fail 1972 : MER_Success; 1973 case Mips::B_MM_Pseudo: 1974 case Mips::B_MMR6_Pseudo: 1975 return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail 1976 : MER_Success; 1977 case Mips::SWM_MM: 1978 case Mips::LWM_MM: 1979 return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail 1980 : MER_Success; 1981 case Mips::JalOneReg: 1982 case Mips::JalTwoReg: 1983 return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success; 1984 case Mips::BneImm: 1985 case Mips::BeqImm: 1986 return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success; 1987 case Mips::BLT: 1988 case Mips::BLE: 1989 case Mips::BGE: 1990 case Mips::BGT: 1991 case Mips::BLTU: 1992 case Mips::BLEU: 1993 case Mips::BGEU: 1994 case Mips::BGTU: 1995 case Mips::BLTL: 1996 case Mips::BLEL: 1997 case Mips::BGEL: 1998 case Mips::BGTL: 1999 case Mips::BLTUL: 2000 case Mips::BLEUL: 2001 case Mips::BGEUL: 2002 case Mips::BGTUL: 2003 case Mips::BLTImmMacro: 2004 case Mips::BLEImmMacro: 2005 case Mips::BGEImmMacro: 2006 case Mips::BGTImmMacro: 2007 case Mips::BLTUImmMacro: 2008 case Mips::BLEUImmMacro: 2009 case Mips::BGEUImmMacro: 2010 case Mips::BGTUImmMacro: 2011 case Mips::BLTLImmMacro: 2012 case Mips::BLELImmMacro: 2013 case Mips::BGELImmMacro: 2014 case Mips::BGTLImmMacro: 2015 case Mips::BLTULImmMacro: 2016 case Mips::BLEULImmMacro: 2017 case Mips::BGEULImmMacro: 2018 case Mips::BGTULImmMacro: 2019 return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success; 2020 case Mips::SDivMacro: 2021 return expandDiv(Inst, IDLoc, Out, STI, false, true) ? MER_Fail 2022 : MER_Success; 2023 case Mips::DSDivMacro: 2024 return expandDiv(Inst, IDLoc, Out, STI, true, true) ? MER_Fail 2025 : MER_Success; 2026 case Mips::UDivMacro: 2027 return expandDiv(Inst, IDLoc, Out, STI, false, false) ? MER_Fail 2028 : MER_Success; 2029 case Mips::DUDivMacro: 2030 return expandDiv(Inst, IDLoc, Out, STI, true, false) ? MER_Fail 2031 : MER_Success; 2032 case Mips::PseudoTRUNC_W_S: 2033 return expandTrunc(Inst, false, false, IDLoc, Out, STI) ? MER_Fail 2034 : MER_Success; 2035 case Mips::PseudoTRUNC_W_D32: 2036 return expandTrunc(Inst, true, false, IDLoc, Out, STI) ? MER_Fail 2037 : MER_Success; 2038 case Mips::PseudoTRUNC_W_D: 2039 return expandTrunc(Inst, true, true, IDLoc, Out, STI) ? MER_Fail 2040 : MER_Success; 2041 case Mips::Ulh: 2042 return expandUlh(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success; 2043 case Mips::Ulhu: 2044 return expandUlh(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success; 2045 case Mips::Ulw: 2046 return expandUlw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success; 2047 case Mips::NORImm: 2048 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success; 2049 case Mips::ADDi: 2050 case Mips::ADDiu: 2051 case Mips::SLTi: 2052 case Mips::SLTiu: 2053 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() && 2054 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) { 2055 int64_t ImmValue = Inst.getOperand(2).getImm(); 2056 if (isInt<16>(ImmValue)) 2057 return MER_NotAMacro; 2058 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail 2059 : MER_Success; 2060 } 2061 return MER_NotAMacro; 2062 case Mips::ANDi: 2063 case Mips::ORi: 2064 case Mips::XORi: 2065 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() && 2066 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) { 2067 int64_t ImmValue = Inst.getOperand(2).getImm(); 2068 if (isUInt<16>(ImmValue)) 2069 return MER_NotAMacro; 2070 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail 2071 : MER_Success; 2072 } 2073 return MER_NotAMacro; 2074 case Mips::ROL: 2075 case Mips::ROR: 2076 return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success; 2077 case Mips::ROLImm: 2078 case Mips::RORImm: 2079 return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success; 2080 case Mips::DROL: 2081 case Mips::DROR: 2082 return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success; 2083 case Mips::DROLImm: 2084 case Mips::DRORImm: 2085 return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success; 2086 case Mips::ABSMacro: 2087 return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success; 2088 } 2089 } 2090 2091 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc, 2092 MCStreamer &Out, 2093 const MCSubtargetInfo *STI) { 2094 MipsTargetStreamer &TOut = getTargetStreamer(); 2095 2096 // Create a JALR instruction which is going to replace the pseudo-JAL. 2097 MCInst JalrInst; 2098 JalrInst.setLoc(IDLoc); 2099 const MCOperand FirstRegOp = Inst.getOperand(0); 2100 const unsigned Opcode = Inst.getOpcode(); 2101 2102 if (Opcode == Mips::JalOneReg) { 2103 // jal $rs => jalr $rs 2104 if (IsCpRestoreSet && inMicroMipsMode()) { 2105 JalrInst.setOpcode(Mips::JALRS16_MM); 2106 JalrInst.addOperand(FirstRegOp); 2107 } else if (inMicroMipsMode()) { 2108 JalrInst.setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM); 2109 JalrInst.addOperand(FirstRegOp); 2110 } else { 2111 JalrInst.setOpcode(Mips::JALR); 2112 JalrInst.addOperand(MCOperand::createReg(Mips::RA)); 2113 JalrInst.addOperand(FirstRegOp); 2114 } 2115 } else if (Opcode == Mips::JalTwoReg) { 2116 // jal $rd, $rs => jalr $rd, $rs 2117 if (IsCpRestoreSet && inMicroMipsMode()) 2118 JalrInst.setOpcode(Mips::JALRS_MM); 2119 else 2120 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR); 2121 JalrInst.addOperand(FirstRegOp); 2122 const MCOperand SecondRegOp = Inst.getOperand(1); 2123 JalrInst.addOperand(SecondRegOp); 2124 } 2125 Out.EmitInstruction(JalrInst, *STI); 2126 2127 // If .set reorder is active and branch instruction has a delay slot, 2128 // emit a NOP after it. 2129 const MCInstrDesc &MCID = getInstDesc(JalrInst.getOpcode()); 2130 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) 2131 TOut.emitEmptyDelaySlot(hasShortDelaySlot(JalrInst.getOpcode()), IDLoc, 2132 STI); 2133 2134 return false; 2135 } 2136 2137 /// Can the value be represented by a unsigned N-bit value and a shift left? 2138 template <unsigned N> static bool isShiftedUIntAtAnyPosition(uint64_t x) { 2139 unsigned BitNum = findFirstSet(x); 2140 2141 return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum); 2142 } 2143 2144 /// Load (or add) an immediate into a register. 2145 /// 2146 /// @param ImmValue The immediate to load. 2147 /// @param DstReg The register that will hold the immediate. 2148 /// @param SrcReg A register to add to the immediate or Mips::NoRegister 2149 /// for a simple initialization. 2150 /// @param Is32BitImm Is ImmValue 32-bit or 64-bit? 2151 /// @param IsAddress True if the immediate represents an address. False if it 2152 /// is an integer. 2153 /// @param IDLoc Location of the immediate in the source file. 2154 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg, 2155 unsigned SrcReg, bool Is32BitImm, 2156 bool IsAddress, SMLoc IDLoc, MCStreamer &Out, 2157 const MCSubtargetInfo *STI) { 2158 MipsTargetStreamer &TOut = getTargetStreamer(); 2159 2160 if (!Is32BitImm && !isGP64bit()) { 2161 Error(IDLoc, "instruction requires a 64-bit architecture"); 2162 return true; 2163 } 2164 2165 if (Is32BitImm) { 2166 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) { 2167 // Sign extend up to 64-bit so that the predicates match the hardware 2168 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be 2169 // true. 2170 ImmValue = SignExtend64<32>(ImmValue); 2171 } else { 2172 Error(IDLoc, "instruction requires a 32-bit immediate"); 2173 return true; 2174 } 2175 } 2176 2177 unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg(); 2178 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu; 2179 2180 bool UseSrcReg = false; 2181 if (SrcReg != Mips::NoRegister) 2182 UseSrcReg = true; 2183 2184 unsigned TmpReg = DstReg; 2185 if (UseSrcReg && 2186 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) { 2187 // At this point we need AT to perform the expansions and we exit if it is 2188 // not available. 2189 unsigned ATReg = getATReg(IDLoc); 2190 if (!ATReg) 2191 return true; 2192 TmpReg = ATReg; 2193 } 2194 2195 if (isInt<16>(ImmValue)) { 2196 if (!UseSrcReg) 2197 SrcReg = ZeroReg; 2198 2199 // This doesn't quite follow the usual ABI expectations for N32 but matches 2200 // traditional assembler behaviour. N32 would normally use addiu for both 2201 // integers and addresses. 2202 if (IsAddress && !Is32BitImm) { 2203 TOut.emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI); 2204 return false; 2205 } 2206 2207 TOut.emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI); 2208 return false; 2209 } 2210 2211 if (isUInt<16>(ImmValue)) { 2212 unsigned TmpReg = DstReg; 2213 if (SrcReg == DstReg) { 2214 TmpReg = getATReg(IDLoc); 2215 if (!TmpReg) 2216 return true; 2217 } 2218 2219 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI); 2220 if (UseSrcReg) 2221 TOut.emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI); 2222 return false; 2223 } 2224 2225 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) { 2226 warnIfNoMacro(IDLoc); 2227 2228 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff; 2229 uint16_t Bits15To0 = ImmValue & 0xffff; 2230 2231 if (!Is32BitImm && !isInt<32>(ImmValue)) { 2232 // Traditional behaviour seems to special case this particular value. It's 2233 // not clear why other masks are handled differently. 2234 if (ImmValue == 0xffffffff) { 2235 TOut.emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI); 2236 TOut.emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI); 2237 if (UseSrcReg) 2238 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI); 2239 return false; 2240 } 2241 2242 // Expand to an ORi instead of a LUi to avoid sign-extending into the 2243 // upper 32 bits. 2244 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI); 2245 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI); 2246 if (Bits15To0) 2247 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI); 2248 if (UseSrcReg) 2249 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI); 2250 return false; 2251 } 2252 2253 TOut.emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI); 2254 if (Bits15To0) 2255 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI); 2256 if (UseSrcReg) 2257 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI); 2258 return false; 2259 } 2260 2261 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) { 2262 if (Is32BitImm) { 2263 Error(IDLoc, "instruction requires a 32-bit immediate"); 2264 return true; 2265 } 2266 2267 // Traditionally, these immediates are shifted as little as possible and as 2268 // such we align the most significant bit to bit 15 of our temporary. 2269 unsigned FirstSet = findFirstSet((uint64_t)ImmValue); 2270 unsigned LastSet = findLastSet((uint64_t)ImmValue); 2271 unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet)); 2272 uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff; 2273 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI); 2274 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI); 2275 2276 if (UseSrcReg) 2277 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI); 2278 2279 return false; 2280 } 2281 2282 warnIfNoMacro(IDLoc); 2283 2284 // The remaining case is packed with a sequence of dsll and ori with zeros 2285 // being omitted and any neighbouring dsll's being coalesced. 2286 // The highest 32-bit's are equivalent to a 32-bit immediate load. 2287 2288 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register. 2289 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false, 2290 IDLoc, Out, STI)) 2291 return false; 2292 2293 // Shift and accumulate into the register. If a 16-bit chunk is zero, then 2294 // skip it and defer the shift to the next chunk. 2295 unsigned ShiftCarriedForwards = 16; 2296 for (int BitNum = 16; BitNum >= 0; BitNum -= 16) { 2297 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff; 2298 2299 if (ImmChunk != 0) { 2300 TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI); 2301 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI); 2302 ShiftCarriedForwards = 0; 2303 } 2304 2305 ShiftCarriedForwards += 16; 2306 } 2307 ShiftCarriedForwards -= 16; 2308 2309 // Finish any remaining shifts left by trailing zeros. 2310 if (ShiftCarriedForwards) 2311 TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI); 2312 2313 if (UseSrcReg) 2314 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI); 2315 2316 return false; 2317 } 2318 2319 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc, 2320 MCStreamer &Out, const MCSubtargetInfo *STI) { 2321 const MCOperand &ImmOp = Inst.getOperand(1); 2322 assert(ImmOp.isImm() && "expected immediate operand kind"); 2323 const MCOperand &DstRegOp = Inst.getOperand(0); 2324 assert(DstRegOp.isReg() && "expected register operand kind"); 2325 2326 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister, 2327 Is32BitImm, false, IDLoc, Out, STI)) 2328 return true; 2329 2330 return false; 2331 } 2332 2333 bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg, 2334 const MCOperand &Offset, 2335 bool Is32BitAddress, SMLoc IDLoc, 2336 MCStreamer &Out, 2337 const MCSubtargetInfo *STI) { 2338 // la can't produce a usable address when addresses are 64-bit. 2339 if (Is32BitAddress && ABI.ArePtrs64bit()) { 2340 // FIXME: Demote this to a warning and continue as if we had 'dla' instead. 2341 // We currently can't do this because we depend on the equality 2342 // operator and N64 can end up with a GPR32/GPR64 mismatch. 2343 Error(IDLoc, "la used to load 64-bit address"); 2344 // Continue as if we had 'dla' instead. 2345 Is32BitAddress = false; 2346 } 2347 2348 // dla requires 64-bit addresses. 2349 if (!Is32BitAddress && !hasMips3()) { 2350 Error(IDLoc, "instruction requires a 64-bit architecture"); 2351 return true; 2352 } 2353 2354 if (!Offset.isImm()) 2355 return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg, 2356 Is32BitAddress, IDLoc, Out, STI); 2357 2358 if (!ABI.ArePtrs64bit()) { 2359 // Continue as if we had 'la' whether we had 'la' or 'dla'. 2360 Is32BitAddress = true; 2361 } 2362 2363 return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true, 2364 IDLoc, Out, STI); 2365 } 2366 2367 bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr, 2368 unsigned DstReg, unsigned SrcReg, 2369 bool Is32BitSym, SMLoc IDLoc, 2370 MCStreamer &Out, 2371 const MCSubtargetInfo *STI) { 2372 MipsTargetStreamer &TOut = getTargetStreamer(); 2373 warnIfNoMacro(IDLoc); 2374 2375 const MCExpr *Symbol = cast<MCExpr>(SymExpr); 2376 const MipsMCExpr *HiExpr = 2377 MipsMCExpr::create(MipsMCExpr::MEK_HI, Symbol, getContext()); 2378 const MipsMCExpr *LoExpr = 2379 MipsMCExpr::create(MipsMCExpr::MEK_LO, Symbol, getContext()); 2380 2381 bool UseSrcReg = SrcReg != Mips::NoRegister; 2382 2383 // This is the 64-bit symbol address expansion. 2384 if (ABI.ArePtrs64bit() && isGP64bit()) { 2385 // We always need AT for the 64-bit expansion. 2386 // If it is not available we exit. 2387 unsigned ATReg = getATReg(IDLoc); 2388 if (!ATReg) 2389 return true; 2390 2391 const MipsMCExpr *HighestExpr = 2392 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, Symbol, getContext()); 2393 const MipsMCExpr *HigherExpr = 2394 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, Symbol, getContext()); 2395 2396 if (UseSrcReg && 2397 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, 2398 SrcReg)) { 2399 // If $rs is the same as $rd: 2400 // (d)la $rd, sym($rd) => lui $at, %highest(sym) 2401 // daddiu $at, $at, %higher(sym) 2402 // dsll $at, $at, 16 2403 // daddiu $at, $at, %hi(sym) 2404 // dsll $at, $at, 16 2405 // daddiu $at, $at, %lo(sym) 2406 // daddu $rd, $at, $rd 2407 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc, 2408 STI); 2409 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, 2410 MCOperand::createExpr(HigherExpr), IDLoc, STI); 2411 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI); 2412 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr), 2413 IDLoc, STI); 2414 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI); 2415 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), 2416 IDLoc, STI); 2417 TOut.emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI); 2418 2419 return false; 2420 } 2421 2422 // Otherwise, if the $rs is different from $rd or if $rs isn't specified: 2423 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym) 2424 // lui $at, %hi(sym) 2425 // daddiu $rd, $rd, %higher(sym) 2426 // daddiu $at, $at, %lo(sym) 2427 // dsll32 $rd, $rd, 0 2428 // daddu $rd, $rd, $at 2429 // (daddu $rd, $rd, $rs) 2430 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc, 2431 STI); 2432 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI); 2433 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg, 2434 MCOperand::createExpr(HigherExpr), IDLoc, STI); 2435 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), 2436 IDLoc, STI); 2437 TOut.emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI); 2438 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI); 2439 if (UseSrcReg) 2440 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI); 2441 2442 return false; 2443 } 2444 2445 // And now, the 32-bit symbol address expansion: 2446 // If $rs is the same as $rd: 2447 // (d)la $rd, sym($rd) => lui $at, %hi(sym) 2448 // ori $at, $at, %lo(sym) 2449 // addu $rd, $at, $rd 2450 // Otherwise, if the $rs is different from $rd or if $rs isn't specified: 2451 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym) 2452 // ori $rd, $rd, %lo(sym) 2453 // (addu $rd, $rd, $rs) 2454 unsigned TmpReg = DstReg; 2455 if (UseSrcReg && 2456 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) { 2457 // If $rs is the same as $rd, we need to use AT. 2458 // If it is not available we exit. 2459 unsigned ATReg = getATReg(IDLoc); 2460 if (!ATReg) 2461 return true; 2462 TmpReg = ATReg; 2463 } 2464 2465 TOut.emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, STI); 2466 TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr), 2467 IDLoc, STI); 2468 2469 if (UseSrcReg) 2470 TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI); 2471 else 2472 assert( 2473 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg)); 2474 2475 return false; 2476 } 2477 2478 bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc, 2479 MCStreamer &Out, 2480 const MCSubtargetInfo *STI) { 2481 MipsTargetStreamer &TOut = getTargetStreamer(); 2482 2483 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 && 2484 "unexpected number of operands"); 2485 2486 MCOperand Offset = Inst.getOperand(0); 2487 if (Offset.isExpr()) { 2488 Inst.clear(); 2489 Inst.setOpcode(Mips::BEQ_MM); 2490 Inst.addOperand(MCOperand::createReg(Mips::ZERO)); 2491 Inst.addOperand(MCOperand::createReg(Mips::ZERO)); 2492 Inst.addOperand(MCOperand::createExpr(Offset.getExpr())); 2493 } else { 2494 assert(Offset.isImm() && "expected immediate operand kind"); 2495 if (isInt<11>(Offset.getImm())) { 2496 // If offset fits into 11 bits then this instruction becomes microMIPS 2497 // 16-bit unconditional branch instruction. 2498 if (inMicroMipsMode()) 2499 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM); 2500 } else { 2501 if (!isInt<17>(Offset.getImm())) 2502 Error(IDLoc, "branch target out of range"); 2503 if (OffsetToAlignment(Offset.getImm(), 1LL << 1)) 2504 Error(IDLoc, "branch to misaligned address"); 2505 Inst.clear(); 2506 Inst.setOpcode(Mips::BEQ_MM); 2507 Inst.addOperand(MCOperand::createReg(Mips::ZERO)); 2508 Inst.addOperand(MCOperand::createReg(Mips::ZERO)); 2509 Inst.addOperand(MCOperand::createImm(Offset.getImm())); 2510 } 2511 } 2512 Out.EmitInstruction(Inst, *STI); 2513 2514 // If .set reorder is active and branch instruction has a delay slot, 2515 // emit a NOP after it. 2516 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode()); 2517 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) 2518 TOut.emitEmptyDelaySlot(true, IDLoc, STI); 2519 2520 return false; 2521 } 2522 2523 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 2524 const MCSubtargetInfo *STI) { 2525 MipsTargetStreamer &TOut = getTargetStreamer(); 2526 const MCOperand &DstRegOp = Inst.getOperand(0); 2527 assert(DstRegOp.isReg() && "expected register operand kind"); 2528 2529 const MCOperand &ImmOp = Inst.getOperand(1); 2530 assert(ImmOp.isImm() && "expected immediate operand kind"); 2531 2532 const MCOperand &MemOffsetOp = Inst.getOperand(2); 2533 assert((MemOffsetOp.isImm() || MemOffsetOp.isExpr()) && 2534 "expected immediate or expression operand"); 2535 2536 unsigned OpCode = 0; 2537 switch(Inst.getOpcode()) { 2538 case Mips::BneImm: 2539 OpCode = Mips::BNE; 2540 break; 2541 case Mips::BeqImm: 2542 OpCode = Mips::BEQ; 2543 break; 2544 default: 2545 llvm_unreachable("Unknown immediate branch pseudo-instruction."); 2546 break; 2547 } 2548 2549 int64_t ImmValue = ImmOp.getImm(); 2550 if (ImmValue == 0) 2551 TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc, 2552 STI); 2553 else { 2554 warnIfNoMacro(IDLoc); 2555 2556 unsigned ATReg = getATReg(IDLoc); 2557 if (!ATReg) 2558 return true; 2559 2560 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true, 2561 IDLoc, Out, STI)) 2562 return true; 2563 2564 TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, STI); 2565 } 2566 return false; 2567 } 2568 2569 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 2570 const MCSubtargetInfo *STI, bool IsLoad, 2571 bool IsImmOpnd) { 2572 if (IsLoad) { 2573 expandLoadInst(Inst, IDLoc, Out, STI, IsImmOpnd); 2574 return; 2575 } 2576 expandStoreInst(Inst, IDLoc, Out, STI, IsImmOpnd); 2577 } 2578 2579 void MipsAsmParser::expandLoadInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 2580 const MCSubtargetInfo *STI, bool IsImmOpnd) { 2581 MipsTargetStreamer &TOut = getTargetStreamer(); 2582 2583 unsigned DstReg = Inst.getOperand(0).getReg(); 2584 unsigned BaseReg = Inst.getOperand(1).getReg(); 2585 2586 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode()); 2587 int16_t DstRegClass = Desc.OpInfo[0].RegClass; 2588 unsigned DstRegClassID = 2589 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID(); 2590 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) || 2591 (DstRegClassID == Mips::GPR64RegClassID); 2592 2593 if (IsImmOpnd) { 2594 // Try to use DstReg as the temporary. 2595 if (IsGPR && (BaseReg != DstReg)) { 2596 TOut.emitLoadWithImmOffset(Inst.getOpcode(), DstReg, BaseReg, 2597 Inst.getOperand(2).getImm(), DstReg, IDLoc, 2598 STI); 2599 return; 2600 } 2601 2602 // At this point we need AT to perform the expansions and we exit if it is 2603 // not available. 2604 unsigned ATReg = getATReg(IDLoc); 2605 if (!ATReg) 2606 return; 2607 2608 TOut.emitLoadWithImmOffset(Inst.getOpcode(), DstReg, BaseReg, 2609 Inst.getOperand(2).getImm(), ATReg, IDLoc, STI); 2610 return; 2611 } 2612 2613 const MCExpr *ExprOffset = Inst.getOperand(2).getExpr(); 2614 MCOperand LoOperand = MCOperand::createExpr( 2615 MipsMCExpr::create(MipsMCExpr::MEK_LO, ExprOffset, getContext())); 2616 MCOperand HiOperand = MCOperand::createExpr( 2617 MipsMCExpr::create(MipsMCExpr::MEK_HI, ExprOffset, getContext())); 2618 2619 // Try to use DstReg as the temporary. 2620 if (IsGPR && (BaseReg != DstReg)) { 2621 TOut.emitLoadWithSymOffset(Inst.getOpcode(), DstReg, BaseReg, HiOperand, 2622 LoOperand, DstReg, IDLoc, STI); 2623 return; 2624 } 2625 2626 // At this point we need AT to perform the expansions and we exit if it is 2627 // not available. 2628 unsigned ATReg = getATReg(IDLoc); 2629 if (!ATReg) 2630 return; 2631 2632 TOut.emitLoadWithSymOffset(Inst.getOpcode(), DstReg, BaseReg, HiOperand, 2633 LoOperand, ATReg, IDLoc, STI); 2634 } 2635 2636 void MipsAsmParser::expandStoreInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 2637 const MCSubtargetInfo *STI, 2638 bool IsImmOpnd) { 2639 MipsTargetStreamer &TOut = getTargetStreamer(); 2640 2641 unsigned SrcReg = Inst.getOperand(0).getReg(); 2642 unsigned BaseReg = Inst.getOperand(1).getReg(); 2643 2644 if (IsImmOpnd) { 2645 TOut.emitStoreWithImmOffset(Inst.getOpcode(), SrcReg, BaseReg, 2646 Inst.getOperand(2).getImm(), 2647 [&]() { return getATReg(IDLoc); }, IDLoc, STI); 2648 return; 2649 } 2650 2651 unsigned ATReg = getATReg(IDLoc); 2652 if (!ATReg) 2653 return; 2654 2655 const MCExpr *ExprOffset = Inst.getOperand(2).getExpr(); 2656 MCOperand LoOperand = MCOperand::createExpr( 2657 MipsMCExpr::create(MipsMCExpr::MEK_LO, ExprOffset, getContext())); 2658 MCOperand HiOperand = MCOperand::createExpr( 2659 MipsMCExpr::create(MipsMCExpr::MEK_HI, ExprOffset, getContext())); 2660 TOut.emitStoreWithSymOffset(Inst.getOpcode(), SrcReg, BaseReg, HiOperand, 2661 LoOperand, ATReg, IDLoc, STI); 2662 } 2663 2664 bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc, 2665 MCStreamer &Out, 2666 const MCSubtargetInfo *STI) { 2667 unsigned OpNum = Inst.getNumOperands(); 2668 unsigned Opcode = Inst.getOpcode(); 2669 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM; 2670 2671 assert (Inst.getOperand(OpNum - 1).isImm() && 2672 Inst.getOperand(OpNum - 2).isReg() && 2673 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand."); 2674 2675 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 && 2676 Inst.getOperand(OpNum - 1).getImm() >= 0 && 2677 (Inst.getOperand(OpNum - 2).getReg() == Mips::SP || 2678 Inst.getOperand(OpNum - 2).getReg() == Mips::SP_64) && 2679 (Inst.getOperand(OpNum - 3).getReg() == Mips::RA || 2680 Inst.getOperand(OpNum - 3).getReg() == Mips::RA_64)) { 2681 // It can be implemented as SWM16 or LWM16 instruction. 2682 if (inMicroMipsMode() && hasMips32r6()) 2683 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6; 2684 else 2685 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM; 2686 } 2687 2688 Inst.setOpcode(NewOpcode); 2689 Out.EmitInstruction(Inst, *STI); 2690 return false; 2691 } 2692 2693 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc, 2694 MCStreamer &Out, 2695 const MCSubtargetInfo *STI) { 2696 MipsTargetStreamer &TOut = getTargetStreamer(); 2697 bool EmittedNoMacroWarning = false; 2698 unsigned PseudoOpcode = Inst.getOpcode(); 2699 unsigned SrcReg = Inst.getOperand(0).getReg(); 2700 const MCOperand &TrgOp = Inst.getOperand(1); 2701 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr(); 2702 2703 unsigned ZeroSrcOpcode, ZeroTrgOpcode; 2704 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality; 2705 2706 unsigned TrgReg; 2707 if (TrgOp.isReg()) 2708 TrgReg = TrgOp.getReg(); 2709 else if (TrgOp.isImm()) { 2710 warnIfNoMacro(IDLoc); 2711 EmittedNoMacroWarning = true; 2712 2713 TrgReg = getATReg(IDLoc); 2714 if (!TrgReg) 2715 return true; 2716 2717 switch(PseudoOpcode) { 2718 default: 2719 llvm_unreachable("unknown opcode for branch pseudo-instruction"); 2720 case Mips::BLTImmMacro: 2721 PseudoOpcode = Mips::BLT; 2722 break; 2723 case Mips::BLEImmMacro: 2724 PseudoOpcode = Mips::BLE; 2725 break; 2726 case Mips::BGEImmMacro: 2727 PseudoOpcode = Mips::BGE; 2728 break; 2729 case Mips::BGTImmMacro: 2730 PseudoOpcode = Mips::BGT; 2731 break; 2732 case Mips::BLTUImmMacro: 2733 PseudoOpcode = Mips::BLTU; 2734 break; 2735 case Mips::BLEUImmMacro: 2736 PseudoOpcode = Mips::BLEU; 2737 break; 2738 case Mips::BGEUImmMacro: 2739 PseudoOpcode = Mips::BGEU; 2740 break; 2741 case Mips::BGTUImmMacro: 2742 PseudoOpcode = Mips::BGTU; 2743 break; 2744 case Mips::BLTLImmMacro: 2745 PseudoOpcode = Mips::BLTL; 2746 break; 2747 case Mips::BLELImmMacro: 2748 PseudoOpcode = Mips::BLEL; 2749 break; 2750 case Mips::BGELImmMacro: 2751 PseudoOpcode = Mips::BGEL; 2752 break; 2753 case Mips::BGTLImmMacro: 2754 PseudoOpcode = Mips::BGTL; 2755 break; 2756 case Mips::BLTULImmMacro: 2757 PseudoOpcode = Mips::BLTUL; 2758 break; 2759 case Mips::BLEULImmMacro: 2760 PseudoOpcode = Mips::BLEUL; 2761 break; 2762 case Mips::BGEULImmMacro: 2763 PseudoOpcode = Mips::BGEUL; 2764 break; 2765 case Mips::BGTULImmMacro: 2766 PseudoOpcode = Mips::BGTUL; 2767 break; 2768 } 2769 2770 if (loadImmediate(TrgOp.getImm(), TrgReg, Mips::NoRegister, !isGP64bit(), 2771 false, IDLoc, Out, STI)) 2772 return true; 2773 } 2774 2775 switch (PseudoOpcode) { 2776 case Mips::BLT: 2777 case Mips::BLTU: 2778 case Mips::BLTL: 2779 case Mips::BLTUL: 2780 AcceptsEquality = false; 2781 ReverseOrderSLT = false; 2782 IsUnsigned = ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL)); 2783 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL)); 2784 ZeroSrcOpcode = Mips::BGTZ; 2785 ZeroTrgOpcode = Mips::BLTZ; 2786 break; 2787 case Mips::BLE: 2788 case Mips::BLEU: 2789 case Mips::BLEL: 2790 case Mips::BLEUL: 2791 AcceptsEquality = true; 2792 ReverseOrderSLT = true; 2793 IsUnsigned = ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL)); 2794 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL)); 2795 ZeroSrcOpcode = Mips::BGEZ; 2796 ZeroTrgOpcode = Mips::BLEZ; 2797 break; 2798 case Mips::BGE: 2799 case Mips::BGEU: 2800 case Mips::BGEL: 2801 case Mips::BGEUL: 2802 AcceptsEquality = true; 2803 ReverseOrderSLT = false; 2804 IsUnsigned = ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL)); 2805 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL)); 2806 ZeroSrcOpcode = Mips::BLEZ; 2807 ZeroTrgOpcode = Mips::BGEZ; 2808 break; 2809 case Mips::BGT: 2810 case Mips::BGTU: 2811 case Mips::BGTL: 2812 case Mips::BGTUL: 2813 AcceptsEquality = false; 2814 ReverseOrderSLT = true; 2815 IsUnsigned = ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL)); 2816 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL)); 2817 ZeroSrcOpcode = Mips::BLTZ; 2818 ZeroTrgOpcode = Mips::BGTZ; 2819 break; 2820 default: 2821 llvm_unreachable("unknown opcode for branch pseudo-instruction"); 2822 } 2823 2824 bool IsTrgRegZero = (TrgReg == Mips::ZERO); 2825 bool IsSrcRegZero = (SrcReg == Mips::ZERO); 2826 if (IsSrcRegZero && IsTrgRegZero) { 2827 // FIXME: All of these Opcode-specific if's are needed for compatibility 2828 // with GAS' behaviour. However, they may not generate the most efficient 2829 // code in some circumstances. 2830 if (PseudoOpcode == Mips::BLT) { 2831 TOut.emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), 2832 IDLoc, STI); 2833 return false; 2834 } 2835 if (PseudoOpcode == Mips::BLE) { 2836 TOut.emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), 2837 IDLoc, STI); 2838 Warning(IDLoc, "branch is always taken"); 2839 return false; 2840 } 2841 if (PseudoOpcode == Mips::BGE) { 2842 TOut.emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), 2843 IDLoc, STI); 2844 Warning(IDLoc, "branch is always taken"); 2845 return false; 2846 } 2847 if (PseudoOpcode == Mips::BGT) { 2848 TOut.emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), 2849 IDLoc, STI); 2850 return false; 2851 } 2852 if (PseudoOpcode == Mips::BGTU) { 2853 TOut.emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO, 2854 MCOperand::createExpr(OffsetExpr), IDLoc, STI); 2855 return false; 2856 } 2857 if (AcceptsEquality) { 2858 // If both registers are $0 and the pseudo-branch accepts equality, it 2859 // will always be taken, so we emit an unconditional branch. 2860 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO, 2861 MCOperand::createExpr(OffsetExpr), IDLoc, STI); 2862 Warning(IDLoc, "branch is always taken"); 2863 return false; 2864 } 2865 // If both registers are $0 and the pseudo-branch does not accept 2866 // equality, it will never be taken, so we don't have to emit anything. 2867 return false; 2868 } 2869 if (IsSrcRegZero || IsTrgRegZero) { 2870 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) || 2871 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) { 2872 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or 2873 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0), 2874 // the pseudo-branch will never be taken, so we don't emit anything. 2875 // This only applies to unsigned pseudo-branches. 2876 return false; 2877 } 2878 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) || 2879 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) { 2880 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or 2881 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0), 2882 // the pseudo-branch will always be taken, so we emit an unconditional 2883 // branch. 2884 // This only applies to unsigned pseudo-branches. 2885 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO, 2886 MCOperand::createExpr(OffsetExpr), IDLoc, STI); 2887 Warning(IDLoc, "branch is always taken"); 2888 return false; 2889 } 2890 if (IsUnsigned) { 2891 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or 2892 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0), 2893 // the pseudo-branch will be taken only when the non-zero register is 2894 // different from 0, so we emit a BNEZ. 2895 // 2896 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or 2897 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0), 2898 // the pseudo-branch will be taken only when the non-zero register is 2899 // equal to 0, so we emit a BEQZ. 2900 // 2901 // Because only BLEU and BGEU branch on equality, we can use the 2902 // AcceptsEquality variable to decide when to emit the BEQZ. 2903 TOut.emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE, 2904 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO, 2905 MCOperand::createExpr(OffsetExpr), IDLoc, STI); 2906 return false; 2907 } 2908 // If we have a signed pseudo-branch and one of the registers is $0, 2909 // we can use an appropriate compare-to-zero branch. We select which one 2910 // to use in the switch statement above. 2911 TOut.emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode, 2912 IsSrcRegZero ? TrgReg : SrcReg, 2913 MCOperand::createExpr(OffsetExpr), IDLoc, STI); 2914 return false; 2915 } 2916 2917 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the 2918 // expansions. If it is not available, we return. 2919 unsigned ATRegNum = getATReg(IDLoc); 2920 if (!ATRegNum) 2921 return true; 2922 2923 if (!EmittedNoMacroWarning) 2924 warnIfNoMacro(IDLoc); 2925 2926 // SLT fits well with 2 of our 4 pseudo-branches: 2927 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and 2928 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs". 2929 // If the result of the SLT is 1, we branch, and if it's 0, we don't. 2930 // This is accomplished by using a BNEZ with the result of the SLT. 2931 // 2932 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT 2933 // and BLE with BGT), so we change the BNEZ into a a BEQZ. 2934 // Because only BGE and BLE branch on equality, we can use the 2935 // AcceptsEquality variable to decide when to emit the BEQZ. 2936 // Note that the order of the SLT arguments doesn't change between 2937 // opposites. 2938 // 2939 // The same applies to the unsigned variants, except that SLTu is used 2940 // instead of SLT. 2941 TOut.emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum, 2942 ReverseOrderSLT ? TrgReg : SrcReg, 2943 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI); 2944 2945 TOut.emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL) 2946 : (AcceptsEquality ? Mips::BEQ : Mips::BNE), 2947 ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc, 2948 STI); 2949 return false; 2950 } 2951 2952 bool MipsAsmParser::expandDiv(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 2953 const MCSubtargetInfo *STI, const bool IsMips64, 2954 const bool Signed) { 2955 MipsTargetStreamer &TOut = getTargetStreamer(); 2956 2957 warnIfNoMacro(IDLoc); 2958 2959 const MCOperand &RdRegOp = Inst.getOperand(0); 2960 assert(RdRegOp.isReg() && "expected register operand kind"); 2961 unsigned RdReg = RdRegOp.getReg(); 2962 2963 const MCOperand &RsRegOp = Inst.getOperand(1); 2964 assert(RsRegOp.isReg() && "expected register operand kind"); 2965 unsigned RsReg = RsRegOp.getReg(); 2966 2967 const MCOperand &RtRegOp = Inst.getOperand(2); 2968 assert(RtRegOp.isReg() && "expected register operand kind"); 2969 unsigned RtReg = RtRegOp.getReg(); 2970 unsigned DivOp; 2971 unsigned ZeroReg; 2972 2973 if (IsMips64) { 2974 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV; 2975 ZeroReg = Mips::ZERO_64; 2976 } else { 2977 DivOp = Signed ? Mips::SDIV : Mips::UDIV; 2978 ZeroReg = Mips::ZERO; 2979 } 2980 2981 bool UseTraps = useTraps(); 2982 2983 if (RsReg == Mips::ZERO || RsReg == Mips::ZERO_64) { 2984 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) 2985 Warning(IDLoc, "dividing zero by zero"); 2986 if (IsMips64) { 2987 if (Signed && (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)) { 2988 if (UseTraps) { 2989 TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI); 2990 return false; 2991 } 2992 2993 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI); 2994 return false; 2995 } 2996 } else { 2997 TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI); 2998 return false; 2999 } 3000 } 3001 3002 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) { 3003 Warning(IDLoc, "division by zero"); 3004 if (Signed) { 3005 if (UseTraps) { 3006 TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI); 3007 return false; 3008 } 3009 3010 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI); 3011 return false; 3012 } 3013 } 3014 3015 // FIXME: The values for these two BranchTarget variables may be different in 3016 // micromips. These magic numbers need to be removed. 3017 unsigned BranchTargetNoTraps; 3018 unsigned BranchTarget; 3019 3020 if (UseTraps) { 3021 BranchTarget = IsMips64 ? 12 : 8; 3022 TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI); 3023 } else { 3024 BranchTarget = IsMips64 ? 20 : 16; 3025 BranchTargetNoTraps = 8; 3026 // Branch to the li instruction. 3027 TOut.emitRRI(Mips::BNE, RtReg, ZeroReg, BranchTargetNoTraps, IDLoc, STI); 3028 } 3029 3030 TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI); 3031 3032 if (!UseTraps) 3033 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI); 3034 3035 if (!Signed) { 3036 TOut.emitR(Mips::MFLO, RdReg, IDLoc, STI); 3037 return false; 3038 } 3039 3040 unsigned ATReg = getATReg(IDLoc); 3041 if (!ATReg) 3042 return true; 3043 3044 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, STI); 3045 if (IsMips64) { 3046 // Branch to the mflo instruction. 3047 TOut.emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, STI); 3048 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, STI); 3049 TOut.emitRRI(Mips::DSLL32, ATReg, ATReg, 0x1f, IDLoc, STI); 3050 } else { 3051 // Branch to the mflo instruction. 3052 TOut.emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, STI); 3053 TOut.emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, STI); 3054 } 3055 3056 if (UseTraps) 3057 TOut.emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, STI); 3058 else { 3059 // Branch to the mflo instruction. 3060 TOut.emitRRI(Mips::BNE, RsReg, ATReg, BranchTargetNoTraps, IDLoc, STI); 3061 TOut.emitRRI(Mips::SLL, ZeroReg, ZeroReg, 0, IDLoc, STI); 3062 TOut.emitII(Mips::BREAK, 0x6, 0, IDLoc, STI); 3063 } 3064 TOut.emitR(Mips::MFLO, RdReg, IDLoc, STI); 3065 return false; 3066 } 3067 3068 bool MipsAsmParser::expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU, 3069 SMLoc IDLoc, MCStreamer &Out, 3070 const MCSubtargetInfo *STI) { 3071 MipsTargetStreamer &TOut = getTargetStreamer(); 3072 3073 assert(Inst.getNumOperands() == 3 && "Invalid operand count"); 3074 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() && 3075 Inst.getOperand(2).isReg() && "Invalid instruction operand."); 3076 3077 unsigned FirstReg = Inst.getOperand(0).getReg(); 3078 unsigned SecondReg = Inst.getOperand(1).getReg(); 3079 unsigned ThirdReg = Inst.getOperand(2).getReg(); 3080 3081 if (hasMips1() && !hasMips2()) { 3082 unsigned ATReg = getATReg(IDLoc); 3083 if (!ATReg) 3084 return true; 3085 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI); 3086 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI); 3087 TOut.emitNop(IDLoc, STI); 3088 TOut.emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI); 3089 TOut.emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI); 3090 TOut.emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI); 3091 TOut.emitNop(IDLoc, STI); 3092 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32) 3093 : Mips::CVT_W_S, 3094 FirstReg, SecondReg, IDLoc, STI); 3095 TOut.emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI); 3096 TOut.emitNop(IDLoc, STI); 3097 return false; 3098 } 3099 3100 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32) 3101 : Mips::TRUNC_W_S, 3102 FirstReg, SecondReg, IDLoc, STI); 3103 3104 return false; 3105 } 3106 3107 bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc, 3108 MCStreamer &Out, const MCSubtargetInfo *STI) { 3109 MipsTargetStreamer &TOut = getTargetStreamer(); 3110 3111 if (hasMips32r6() || hasMips64r6()) { 3112 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6"); 3113 return false; 3114 } 3115 3116 warnIfNoMacro(IDLoc); 3117 3118 const MCOperand &DstRegOp = Inst.getOperand(0); 3119 assert(DstRegOp.isReg() && "expected register operand kind"); 3120 3121 const MCOperand &SrcRegOp = Inst.getOperand(1); 3122 assert(SrcRegOp.isReg() && "expected register operand kind"); 3123 3124 const MCOperand &OffsetImmOp = Inst.getOperand(2); 3125 assert(OffsetImmOp.isImm() && "expected immediate operand kind"); 3126 3127 unsigned DstReg = DstRegOp.getReg(); 3128 unsigned SrcReg = SrcRegOp.getReg(); 3129 int64_t OffsetValue = OffsetImmOp.getImm(); 3130 3131 // NOTE: We always need AT for ULHU, as it is always used as the source 3132 // register for one of the LBu's. 3133 unsigned ATReg = getATReg(IDLoc); 3134 if (!ATReg) 3135 return true; 3136 3137 // When the value of offset+1 does not fit in 16 bits, we have to load the 3138 // offset in AT, (D)ADDu the original source register (if there was one), and 3139 // then use AT as the source register for the 2 generated LBu's. 3140 bool LoadedOffsetInAT = false; 3141 if (!isInt<16>(OffsetValue + 1) || !isInt<16>(OffsetValue)) { 3142 LoadedOffsetInAT = true; 3143 3144 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(), 3145 true, IDLoc, Out, STI)) 3146 return true; 3147 3148 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate() 3149 // because it will make our output more similar to GAS'. For example, 3150 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9", 3151 // instead of just an "ori $1, $9, 32768". 3152 // NOTE: If there is no source register specified in the ULHU, the parser 3153 // will interpret it as $0. 3154 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64) 3155 TOut.emitAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), STI); 3156 } 3157 3158 unsigned FirstLbuDstReg = LoadedOffsetInAT ? DstReg : ATReg; 3159 unsigned SecondLbuDstReg = LoadedOffsetInAT ? ATReg : DstReg; 3160 unsigned LbuSrcReg = LoadedOffsetInAT ? ATReg : SrcReg; 3161 3162 int64_t FirstLbuOffset = 0, SecondLbuOffset = 0; 3163 if (isLittle()) { 3164 FirstLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1); 3165 SecondLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue; 3166 } else { 3167 FirstLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue; 3168 SecondLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1); 3169 } 3170 3171 unsigned SllReg = LoadedOffsetInAT ? DstReg : ATReg; 3172 3173 TOut.emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg, 3174 FirstLbuOffset, IDLoc, STI); 3175 3176 TOut.emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondLbuOffset, IDLoc, 3177 STI); 3178 3179 TOut.emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI); 3180 3181 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI); 3182 3183 return false; 3184 } 3185 3186 bool MipsAsmParser::expandUlw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 3187 const MCSubtargetInfo *STI) { 3188 MipsTargetStreamer &TOut = getTargetStreamer(); 3189 3190 if (hasMips32r6() || hasMips64r6()) { 3191 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6"); 3192 return false; 3193 } 3194 3195 const MCOperand &DstRegOp = Inst.getOperand(0); 3196 assert(DstRegOp.isReg() && "expected register operand kind"); 3197 3198 const MCOperand &SrcRegOp = Inst.getOperand(1); 3199 assert(SrcRegOp.isReg() && "expected register operand kind"); 3200 3201 const MCOperand &OffsetImmOp = Inst.getOperand(2); 3202 assert(OffsetImmOp.isImm() && "expected immediate operand kind"); 3203 3204 unsigned SrcReg = SrcRegOp.getReg(); 3205 int64_t OffsetValue = OffsetImmOp.getImm(); 3206 unsigned ATReg = 0; 3207 3208 // When the value of offset+3 does not fit in 16 bits, we have to load the 3209 // offset in AT, (D)ADDu the original source register (if there was one), and 3210 // then use AT as the source register for the generated LWL and LWR. 3211 bool LoadedOffsetInAT = false; 3212 if (!isInt<16>(OffsetValue + 3) || !isInt<16>(OffsetValue)) { 3213 ATReg = getATReg(IDLoc); 3214 if (!ATReg) 3215 return true; 3216 LoadedOffsetInAT = true; 3217 3218 warnIfNoMacro(IDLoc); 3219 3220 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(), 3221 true, IDLoc, Out, STI)) 3222 return true; 3223 3224 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate() 3225 // because it will make our output more similar to GAS'. For example, 3226 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9", 3227 // instead of just an "ori $1, $9, 32768". 3228 // NOTE: If there is no source register specified in the ULW, the parser 3229 // will interpret it as $0. 3230 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64) 3231 TOut.emitAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), STI); 3232 } 3233 3234 unsigned FinalSrcReg = LoadedOffsetInAT ? ATReg : SrcReg; 3235 int64_t LeftLoadOffset = 0, RightLoadOffset = 0; 3236 if (isLittle()) { 3237 LeftLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3); 3238 RightLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue; 3239 } else { 3240 LeftLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue; 3241 RightLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3); 3242 } 3243 3244 TOut.emitRRI(Mips::LWL, DstRegOp.getReg(), FinalSrcReg, LeftLoadOffset, IDLoc, 3245 STI); 3246 3247 TOut.emitRRI(Mips::LWR, DstRegOp.getReg(), FinalSrcReg, RightLoadOffset, 3248 IDLoc, STI); 3249 3250 return false; 3251 } 3252 3253 bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc, 3254 MCStreamer &Out, 3255 const MCSubtargetInfo *STI) { 3256 MipsTargetStreamer &TOut = getTargetStreamer(); 3257 3258 assert (Inst.getNumOperands() == 3 && "Invalid operand count"); 3259 assert (Inst.getOperand(0).isReg() && 3260 Inst.getOperand(1).isReg() && 3261 Inst.getOperand(2).isImm() && "Invalid instruction operand."); 3262 3263 unsigned ATReg = Mips::NoRegister; 3264 unsigned FinalDstReg = Mips::NoRegister; 3265 unsigned DstReg = Inst.getOperand(0).getReg(); 3266 unsigned SrcReg = Inst.getOperand(1).getReg(); 3267 int64_t ImmValue = Inst.getOperand(2).getImm(); 3268 3269 bool Is32Bit = isInt<32>(ImmValue) || isUInt<32>(ImmValue); 3270 3271 unsigned FinalOpcode = Inst.getOpcode(); 3272 3273 if (DstReg == SrcReg) { 3274 ATReg = getATReg(Inst.getLoc()); 3275 if (!ATReg) 3276 return true; 3277 FinalDstReg = DstReg; 3278 DstReg = ATReg; 3279 } 3280 3281 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit, false, Inst.getLoc(), Out, STI)) { 3282 switch (FinalOpcode) { 3283 default: 3284 llvm_unreachable("unimplemented expansion"); 3285 case (Mips::ADDi): 3286 FinalOpcode = Mips::ADD; 3287 break; 3288 case (Mips::ADDiu): 3289 FinalOpcode = Mips::ADDu; 3290 break; 3291 case (Mips::ANDi): 3292 FinalOpcode = Mips::AND; 3293 break; 3294 case (Mips::NORImm): 3295 FinalOpcode = Mips::NOR; 3296 break; 3297 case (Mips::ORi): 3298 FinalOpcode = Mips::OR; 3299 break; 3300 case (Mips::SLTi): 3301 FinalOpcode = Mips::SLT; 3302 break; 3303 case (Mips::SLTiu): 3304 FinalOpcode = Mips::SLTu; 3305 break; 3306 case (Mips::XORi): 3307 FinalOpcode = Mips::XOR; 3308 break; 3309 } 3310 3311 if (FinalDstReg == Mips::NoRegister) 3312 TOut.emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI); 3313 else 3314 TOut.emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI); 3315 return false; 3316 } 3317 return true; 3318 } 3319 3320 bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 3321 const MCSubtargetInfo *STI) { 3322 MipsTargetStreamer &TOut = getTargetStreamer(); 3323 unsigned ATReg = Mips::NoRegister; 3324 unsigned DReg = Inst.getOperand(0).getReg(); 3325 unsigned SReg = Inst.getOperand(1).getReg(); 3326 unsigned TReg = Inst.getOperand(2).getReg(); 3327 unsigned TmpReg = DReg; 3328 3329 unsigned FirstShift = Mips::NOP; 3330 unsigned SecondShift = Mips::NOP; 3331 3332 if (hasMips32r2()) { 3333 3334 if (DReg == SReg) { 3335 TmpReg = getATReg(Inst.getLoc()); 3336 if (!TmpReg) 3337 return true; 3338 } 3339 3340 if (Inst.getOpcode() == Mips::ROL) { 3341 TOut.emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI); 3342 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI); 3343 return false; 3344 } 3345 3346 if (Inst.getOpcode() == Mips::ROR) { 3347 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.getLoc(), STI); 3348 return false; 3349 } 3350 3351 return true; 3352 } 3353 3354 if (hasMips32()) { 3355 3356 switch (Inst.getOpcode()) { 3357 default: 3358 llvm_unreachable("unexpected instruction opcode"); 3359 case Mips::ROL: 3360 FirstShift = Mips::SRLV; 3361 SecondShift = Mips::SLLV; 3362 break; 3363 case Mips::ROR: 3364 FirstShift = Mips::SLLV; 3365 SecondShift = Mips::SRLV; 3366 break; 3367 } 3368 3369 ATReg = getATReg(Inst.getLoc()); 3370 if (!ATReg) 3371 return true; 3372 3373 TOut.emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI); 3374 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI); 3375 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI); 3376 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI); 3377 3378 return false; 3379 } 3380 3381 return true; 3382 } 3383 3384 bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc, 3385 MCStreamer &Out, 3386 const MCSubtargetInfo *STI) { 3387 MipsTargetStreamer &TOut = getTargetStreamer(); 3388 unsigned ATReg = Mips::NoRegister; 3389 unsigned DReg = Inst.getOperand(0).getReg(); 3390 unsigned SReg = Inst.getOperand(1).getReg(); 3391 int64_t ImmValue = Inst.getOperand(2).getImm(); 3392 3393 unsigned FirstShift = Mips::NOP; 3394 unsigned SecondShift = Mips::NOP; 3395 3396 if (hasMips32r2()) { 3397 3398 if (Inst.getOpcode() == Mips::ROLImm) { 3399 uint64_t MaxShift = 32; 3400 uint64_t ShiftValue = ImmValue; 3401 if (ImmValue != 0) 3402 ShiftValue = MaxShift - ImmValue; 3403 TOut.emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.getLoc(), STI); 3404 return false; 3405 } 3406 3407 if (Inst.getOpcode() == Mips::RORImm) { 3408 TOut.emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.getLoc(), STI); 3409 return false; 3410 } 3411 3412 return true; 3413 } 3414 3415 if (hasMips32()) { 3416 3417 if (ImmValue == 0) { 3418 TOut.emitRRI(Mips::SRL, DReg, SReg, 0, Inst.getLoc(), STI); 3419 return false; 3420 } 3421 3422 switch (Inst.getOpcode()) { 3423 default: 3424 llvm_unreachable("unexpected instruction opcode"); 3425 case Mips::ROLImm: 3426 FirstShift = Mips::SLL; 3427 SecondShift = Mips::SRL; 3428 break; 3429 case Mips::RORImm: 3430 FirstShift = Mips::SRL; 3431 SecondShift = Mips::SLL; 3432 break; 3433 } 3434 3435 ATReg = getATReg(Inst.getLoc()); 3436 if (!ATReg) 3437 return true; 3438 3439 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.getLoc(), STI); 3440 TOut.emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.getLoc(), STI); 3441 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI); 3442 3443 return false; 3444 } 3445 3446 return true; 3447 } 3448 3449 bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 3450 const MCSubtargetInfo *STI) { 3451 MipsTargetStreamer &TOut = getTargetStreamer(); 3452 unsigned ATReg = Mips::NoRegister; 3453 unsigned DReg = Inst.getOperand(0).getReg(); 3454 unsigned SReg = Inst.getOperand(1).getReg(); 3455 unsigned TReg = Inst.getOperand(2).getReg(); 3456 unsigned TmpReg = DReg; 3457 3458 unsigned FirstShift = Mips::NOP; 3459 unsigned SecondShift = Mips::NOP; 3460 3461 if (hasMips64r2()) { 3462 3463 if (TmpReg == SReg) { 3464 TmpReg = getATReg(Inst.getLoc()); 3465 if (!TmpReg) 3466 return true; 3467 } 3468 3469 if (Inst.getOpcode() == Mips::DROL) { 3470 TOut.emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI); 3471 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI); 3472 return false; 3473 } 3474 3475 if (Inst.getOpcode() == Mips::DROR) { 3476 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.getLoc(), STI); 3477 return false; 3478 } 3479 3480 return true; 3481 } 3482 3483 if (hasMips64()) { 3484 3485 switch (Inst.getOpcode()) { 3486 default: 3487 llvm_unreachable("unexpected instruction opcode"); 3488 case Mips::DROL: 3489 FirstShift = Mips::DSRLV; 3490 SecondShift = Mips::DSLLV; 3491 break; 3492 case Mips::DROR: 3493 FirstShift = Mips::DSLLV; 3494 SecondShift = Mips::DSRLV; 3495 break; 3496 } 3497 3498 ATReg = getATReg(Inst.getLoc()); 3499 if (!ATReg) 3500 return true; 3501 3502 TOut.emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI); 3503 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI); 3504 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI); 3505 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI); 3506 3507 return false; 3508 } 3509 3510 return true; 3511 } 3512 3513 bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc, 3514 MCStreamer &Out, 3515 const MCSubtargetInfo *STI) { 3516 MipsTargetStreamer &TOut = getTargetStreamer(); 3517 unsigned ATReg = Mips::NoRegister; 3518 unsigned DReg = Inst.getOperand(0).getReg(); 3519 unsigned SReg = Inst.getOperand(1).getReg(); 3520 int64_t ImmValue = Inst.getOperand(2).getImm() % 64; 3521 3522 unsigned FirstShift = Mips::NOP; 3523 unsigned SecondShift = Mips::NOP; 3524 3525 MCInst TmpInst; 3526 3527 if (hasMips64r2()) { 3528 3529 unsigned FinalOpcode = Mips::NOP; 3530 if (ImmValue == 0) 3531 FinalOpcode = Mips::DROTR; 3532 else if (ImmValue % 32 == 0) 3533 FinalOpcode = Mips::DROTR32; 3534 else if ((ImmValue >= 1) && (ImmValue <= 32)) { 3535 if (Inst.getOpcode() == Mips::DROLImm) 3536 FinalOpcode = Mips::DROTR32; 3537 else 3538 FinalOpcode = Mips::DROTR; 3539 } else if (ImmValue >= 33) { 3540 if (Inst.getOpcode() == Mips::DROLImm) 3541 FinalOpcode = Mips::DROTR; 3542 else 3543 FinalOpcode = Mips::DROTR32; 3544 } 3545 3546 uint64_t ShiftValue = ImmValue % 32; 3547 if (Inst.getOpcode() == Mips::DROLImm) 3548 ShiftValue = (32 - ImmValue % 32) % 32; 3549 3550 TOut.emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.getLoc(), STI); 3551 3552 return false; 3553 } 3554 3555 if (hasMips64()) { 3556 3557 if (ImmValue == 0) { 3558 TOut.emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.getLoc(), STI); 3559 return false; 3560 } 3561 3562 switch (Inst.getOpcode()) { 3563 default: 3564 llvm_unreachable("unexpected instruction opcode"); 3565 case Mips::DROLImm: 3566 if ((ImmValue >= 1) && (ImmValue <= 31)) { 3567 FirstShift = Mips::DSLL; 3568 SecondShift = Mips::DSRL32; 3569 } 3570 if (ImmValue == 32) { 3571 FirstShift = Mips::DSLL32; 3572 SecondShift = Mips::DSRL32; 3573 } 3574 if ((ImmValue >= 33) && (ImmValue <= 63)) { 3575 FirstShift = Mips::DSLL32; 3576 SecondShift = Mips::DSRL; 3577 } 3578 break; 3579 case Mips::DRORImm: 3580 if ((ImmValue >= 1) && (ImmValue <= 31)) { 3581 FirstShift = Mips::DSRL; 3582 SecondShift = Mips::DSLL32; 3583 } 3584 if (ImmValue == 32) { 3585 FirstShift = Mips::DSRL32; 3586 SecondShift = Mips::DSLL32; 3587 } 3588 if ((ImmValue >= 33) && (ImmValue <= 63)) { 3589 FirstShift = Mips::DSRL32; 3590 SecondShift = Mips::DSLL; 3591 } 3592 break; 3593 } 3594 3595 ATReg = getATReg(Inst.getLoc()); 3596 if (!ATReg) 3597 return true; 3598 3599 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.getLoc(), STI); 3600 TOut.emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32, 3601 Inst.getLoc(), STI); 3602 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI); 3603 3604 return false; 3605 } 3606 3607 return true; 3608 } 3609 3610 bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 3611 const MCSubtargetInfo *STI) { 3612 MipsTargetStreamer &TOut = getTargetStreamer(); 3613 unsigned FirstRegOp = Inst.getOperand(0).getReg(); 3614 unsigned SecondRegOp = Inst.getOperand(1).getReg(); 3615 3616 TOut.emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI); 3617 if (FirstRegOp != SecondRegOp) 3618 TOut.emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI); 3619 else 3620 TOut.emitEmptyDelaySlot(false, IDLoc, STI); 3621 TOut.emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI); 3622 3623 return false; 3624 } 3625 3626 void MipsAsmParser::createCpRestoreMemOp(bool IsLoad, int StackOffset, 3627 SMLoc IDLoc, MCStreamer &Out, 3628 const MCSubtargetInfo *STI) { 3629 MipsTargetStreamer &TOut = getTargetStreamer(); 3630 3631 if (IsLoad) { 3632 TOut.emitLoadWithImmOffset(Mips::LW, Mips::GP, Mips::SP, StackOffset, 3633 Mips::GP, IDLoc, STI); 3634 return; 3635 } 3636 3637 TOut.emitStoreWithImmOffset(Mips::SW, Mips::GP, Mips::SP, StackOffset, 3638 [&]() { return getATReg(IDLoc); }, IDLoc, STI); 3639 } 3640 3641 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) { 3642 // As described by the Mips32r2 spec, the registers Rd and Rs for 3643 // jalr.hb must be different. 3644 // It also applies for registers Rt and Rs of microMIPSr6 jalrc.hb instruction 3645 // and registers Rd and Base for microMIPS lwp instruction 3646 unsigned Opcode = Inst.getOpcode(); 3647 3648 if ((Opcode == Mips::JALR_HB || Opcode == Mips::JALRC_HB_MMR6) && 3649 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())) 3650 return Match_RequiresDifferentSrcAndDst; 3651 else if ((Opcode == Mips::LWP_MM || Opcode == Mips::LWP_MMR6) && 3652 (Inst.getOperand(0).getReg() == Inst.getOperand(2).getReg())) 3653 return Match_RequiresDifferentSrcAndDst; 3654 3655 return Match_Success; 3656 } 3657 3658 static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands, 3659 uint64_t ErrorInfo) { 3660 if (ErrorInfo != ~0ULL && ErrorInfo < Operands.size()) { 3661 SMLoc ErrorLoc = Operands[ErrorInfo]->getStartLoc(); 3662 if (ErrorLoc == SMLoc()) 3663 return Loc; 3664 return ErrorLoc; 3665 } 3666 return Loc; 3667 } 3668 3669 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 3670 OperandVector &Operands, 3671 MCStreamer &Out, 3672 uint64_t &ErrorInfo, 3673 bool MatchingInlineAsm) { 3674 3675 MCInst Inst; 3676 unsigned MatchResult = 3677 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm); 3678 3679 switch (MatchResult) { 3680 case Match_Success: { 3681 if (processInstruction(Inst, IDLoc, Out, STI)) 3682 return true; 3683 return false; 3684 } 3685 case Match_MissingFeature: 3686 Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 3687 return true; 3688 case Match_InvalidOperand: { 3689 SMLoc ErrorLoc = IDLoc; 3690 if (ErrorInfo != ~0ULL) { 3691 if (ErrorInfo >= Operands.size()) 3692 return Error(IDLoc, "too few operands for instruction"); 3693 3694 ErrorLoc = Operands[ErrorInfo]->getStartLoc(); 3695 if (ErrorLoc == SMLoc()) 3696 ErrorLoc = IDLoc; 3697 } 3698 3699 return Error(ErrorLoc, "invalid operand for instruction"); 3700 } 3701 case Match_MnemonicFail: 3702 return Error(IDLoc, "invalid instruction"); 3703 case Match_RequiresDifferentSrcAndDst: 3704 return Error(IDLoc, "source and destination must be different"); 3705 case Match_Immz: 3706 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected '0'"); 3707 case Match_UImm1_0: 3708 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3709 "expected 1-bit unsigned immediate"); 3710 case Match_UImm2_0: 3711 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3712 "expected 2-bit unsigned immediate"); 3713 case Match_UImm2_1: 3714 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3715 "expected immediate in range 1 .. 4"); 3716 case Match_UImm3_0: 3717 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3718 "expected 3-bit unsigned immediate"); 3719 case Match_UImm4_0: 3720 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3721 "expected 4-bit unsigned immediate"); 3722 case Match_SImm4_0: 3723 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3724 "expected 4-bit signed immediate"); 3725 case Match_UImm5_0: 3726 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3727 "expected 5-bit unsigned immediate"); 3728 case Match_SImm5_0: 3729 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3730 "expected 5-bit signed immediate"); 3731 case Match_UImm5_1: 3732 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3733 "expected immediate in range 1 .. 32"); 3734 case Match_UImm5_32: 3735 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3736 "expected immediate in range 32 .. 63"); 3737 case Match_UImm5_33: 3738 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3739 "expected immediate in range 33 .. 64"); 3740 case Match_UImm5_0_Report_UImm6: 3741 // This is used on UImm5 operands that have a corresponding UImm5_32 3742 // operand to avoid confusing the user. 3743 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3744 "expected 6-bit unsigned immediate"); 3745 case Match_UImm5_Lsl2: 3746 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3747 "expected both 7-bit unsigned immediate and multiple of 4"); 3748 case Match_UImmRange2_64: 3749 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3750 "expected immediate in range 2 .. 64"); 3751 case Match_UImm6_0: 3752 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3753 "expected 6-bit unsigned immediate"); 3754 case Match_UImm6_Lsl2: 3755 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3756 "expected both 8-bit unsigned immediate and multiple of 4"); 3757 case Match_SImm6_0: 3758 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3759 "expected 6-bit signed immediate"); 3760 case Match_UImm7_0: 3761 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3762 "expected 7-bit unsigned immediate"); 3763 case Match_UImm7_N1: 3764 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3765 "expected immediate in range -1 .. 126"); 3766 case Match_SImm7_Lsl2: 3767 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3768 "expected both 9-bit signed immediate and multiple of 4"); 3769 case Match_UImm8_0: 3770 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3771 "expected 8-bit unsigned immediate"); 3772 case Match_UImm10_0: 3773 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3774 "expected 10-bit unsigned immediate"); 3775 case Match_SImm10_0: 3776 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3777 "expected 10-bit signed immediate"); 3778 case Match_SImm11_0: 3779 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3780 "expected 11-bit signed immediate"); 3781 case Match_UImm16: 3782 case Match_UImm16_Relaxed: 3783 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3784 "expected 16-bit unsigned immediate"); 3785 case Match_SImm16: 3786 case Match_SImm16_Relaxed: 3787 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3788 "expected 16-bit signed immediate"); 3789 case Match_UImm20_0: 3790 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3791 "expected 20-bit unsigned immediate"); 3792 case Match_UImm26_0: 3793 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3794 "expected 26-bit unsigned immediate"); 3795 case Match_SImm32: 3796 case Match_SImm32_Relaxed: 3797 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3798 "expected 32-bit signed immediate"); 3799 case Match_MemSImm9: 3800 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3801 "expected memory with 9-bit signed offset"); 3802 case Match_MemSImm10: 3803 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3804 "expected memory with 10-bit signed offset"); 3805 case Match_MemSImm10Lsl1: 3806 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3807 "expected memory with 11-bit signed offset and multiple of 2"); 3808 case Match_MemSImm10Lsl2: 3809 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3810 "expected memory with 12-bit signed offset and multiple of 4"); 3811 case Match_MemSImm10Lsl3: 3812 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3813 "expected memory with 13-bit signed offset and multiple of 8"); 3814 case Match_MemSImm11: 3815 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3816 "expected memory with 11-bit signed offset"); 3817 case Match_MemSImm12: 3818 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3819 "expected memory with 12-bit signed offset"); 3820 case Match_MemSImm16: 3821 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3822 "expected memory with 16-bit signed offset"); 3823 } 3824 3825 llvm_unreachable("Implement any new match types added!"); 3826 } 3827 3828 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) { 3829 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex) 3830 Warning(Loc, "used $at (currently $" + Twine(RegIndex) + 3831 ") without \".set noat\""); 3832 } 3833 3834 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) { 3835 if (!AssemblerOptions.back()->isMacro()) 3836 Warning(Loc, "macro instruction expanded into multiple instructions"); 3837 } 3838 3839 void 3840 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg, 3841 SMRange Range, bool ShowColors) { 3842 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg, 3843 Range, SMFixIt(Range, FixMsg), 3844 ShowColors); 3845 } 3846 3847 int MipsAsmParser::matchCPURegisterName(StringRef Name) { 3848 int CC; 3849 3850 CC = StringSwitch<unsigned>(Name) 3851 .Case("zero", 0) 3852 .Case("at", 1) 3853 .Case("a0", 4) 3854 .Case("a1", 5) 3855 .Case("a2", 6) 3856 .Case("a3", 7) 3857 .Case("v0", 2) 3858 .Case("v1", 3) 3859 .Case("s0", 16) 3860 .Case("s1", 17) 3861 .Case("s2", 18) 3862 .Case("s3", 19) 3863 .Case("s4", 20) 3864 .Case("s5", 21) 3865 .Case("s6", 22) 3866 .Case("s7", 23) 3867 .Case("k0", 26) 3868 .Case("k1", 27) 3869 .Case("gp", 28) 3870 .Case("sp", 29) 3871 .Case("fp", 30) 3872 .Case("s8", 30) 3873 .Case("ra", 31) 3874 .Case("t0", 8) 3875 .Case("t1", 9) 3876 .Case("t2", 10) 3877 .Case("t3", 11) 3878 .Case("t4", 12) 3879 .Case("t5", 13) 3880 .Case("t6", 14) 3881 .Case("t7", 15) 3882 .Case("t8", 24) 3883 .Case("t9", 25) 3884 .Default(-1); 3885 3886 if (!(isABI_N32() || isABI_N64())) 3887 return CC; 3888 3889 if (12 <= CC && CC <= 15) { 3890 // Name is one of t4-t7 3891 AsmToken RegTok = getLexer().peekTok(); 3892 SMRange RegRange = RegTok.getLocRange(); 3893 3894 StringRef FixedName = StringSwitch<StringRef>(Name) 3895 .Case("t4", "t0") 3896 .Case("t5", "t1") 3897 .Case("t6", "t2") 3898 .Case("t7", "t3") 3899 .Default(""); 3900 assert(FixedName != "" && "Register name is not one of t4-t7."); 3901 3902 printWarningWithFixIt("register names $t4-$t7 are only available in O32.", 3903 "Did you mean $" + FixedName + "?", RegRange); 3904 } 3905 3906 // Although SGI documentation just cuts out t0-t3 for n32/n64, 3907 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7 3908 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7. 3909 if (8 <= CC && CC <= 11) 3910 CC += 4; 3911 3912 if (CC == -1) 3913 CC = StringSwitch<unsigned>(Name) 3914 .Case("a4", 8) 3915 .Case("a5", 9) 3916 .Case("a6", 10) 3917 .Case("a7", 11) 3918 .Case("kt0", 26) 3919 .Case("kt1", 27) 3920 .Default(-1); 3921 3922 return CC; 3923 } 3924 3925 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) { 3926 int CC; 3927 3928 CC = StringSwitch<unsigned>(Name) 3929 .Case("hwr_cpunum", 0) 3930 .Case("hwr_synci_step", 1) 3931 .Case("hwr_cc", 2) 3932 .Case("hwr_ccres", 3) 3933 .Case("hwr_ulr", 29) 3934 .Default(-1); 3935 3936 return CC; 3937 } 3938 3939 int MipsAsmParser::matchFPURegisterName(StringRef Name) { 3940 3941 if (Name[0] == 'f') { 3942 StringRef NumString = Name.substr(1); 3943 unsigned IntVal; 3944 if (NumString.getAsInteger(10, IntVal)) 3945 return -1; // This is not an integer. 3946 if (IntVal > 31) // Maximum index for fpu register. 3947 return -1; 3948 return IntVal; 3949 } 3950 return -1; 3951 } 3952 3953 int MipsAsmParser::matchFCCRegisterName(StringRef Name) { 3954 3955 if (Name.startswith("fcc")) { 3956 StringRef NumString = Name.substr(3); 3957 unsigned IntVal; 3958 if (NumString.getAsInteger(10, IntVal)) 3959 return -1; // This is not an integer. 3960 if (IntVal > 7) // There are only 8 fcc registers. 3961 return -1; 3962 return IntVal; 3963 } 3964 return -1; 3965 } 3966 3967 int MipsAsmParser::matchACRegisterName(StringRef Name) { 3968 3969 if (Name.startswith("ac")) { 3970 StringRef NumString = Name.substr(2); 3971 unsigned IntVal; 3972 if (NumString.getAsInteger(10, IntVal)) 3973 return -1; // This is not an integer. 3974 if (IntVal > 3) // There are only 3 acc registers. 3975 return -1; 3976 return IntVal; 3977 } 3978 return -1; 3979 } 3980 3981 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) { 3982 unsigned IntVal; 3983 3984 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal)) 3985 return -1; 3986 3987 if (IntVal > 31) 3988 return -1; 3989 3990 return IntVal; 3991 } 3992 3993 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) { 3994 int CC; 3995 3996 CC = StringSwitch<unsigned>(Name) 3997 .Case("msair", 0) 3998 .Case("msacsr", 1) 3999 .Case("msaaccess", 2) 4000 .Case("msasave", 3) 4001 .Case("msamodify", 4) 4002 .Case("msarequest", 5) 4003 .Case("msamap", 6) 4004 .Case("msaunmap", 7) 4005 .Default(-1); 4006 4007 return CC; 4008 } 4009 4010 unsigned MipsAsmParser::getATReg(SMLoc Loc) { 4011 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex(); 4012 if (ATIndex == 0) { 4013 reportParseError(Loc, 4014 "pseudo-instruction requires $at, which is not available"); 4015 return 0; 4016 } 4017 unsigned AT = getReg( 4018 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex); 4019 return AT; 4020 } 4021 4022 unsigned MipsAsmParser::getReg(int RC, int RegNo) { 4023 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo); 4024 } 4025 4026 unsigned MipsAsmParser::getGPR(int RegNo) { 4027 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, 4028 RegNo); 4029 } 4030 4031 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) { 4032 if (RegNum > 4033 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1) 4034 return -1; 4035 4036 return getReg(RegClass, RegNum); 4037 } 4038 4039 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { 4040 MCAsmParser &Parser = getParser(); 4041 DEBUG(dbgs() << "parseOperand\n"); 4042 4043 // Check if the current operand has a custom associated parser, if so, try to 4044 // custom parse the operand, or fallback to the general approach. 4045 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 4046 if (ResTy == MatchOperand_Success) 4047 return false; 4048 // If there wasn't a custom match, try the generic matcher below. Otherwise, 4049 // there was a match, but an error occurred, in which case, just return that 4050 // the operand parsing failed. 4051 if (ResTy == MatchOperand_ParseFail) 4052 return true; 4053 4054 DEBUG(dbgs() << ".. Generic Parser\n"); 4055 4056 switch (getLexer().getKind()) { 4057 default: 4058 Error(Parser.getTok().getLoc(), "unexpected token in operand"); 4059 return true; 4060 case AsmToken::Dollar: { 4061 // Parse the register. 4062 SMLoc S = Parser.getTok().getLoc(); 4063 4064 // Almost all registers have been parsed by custom parsers. There is only 4065 // one exception to this. $zero (and it's alias $0) will reach this point 4066 // for div, divu, and similar instructions because it is not an operand 4067 // to the instruction definition but an explicit register. Special case 4068 // this situation for now. 4069 if (parseAnyRegister(Operands) != MatchOperand_NoMatch) 4070 return false; 4071 4072 // Maybe it is a symbol reference. 4073 StringRef Identifier; 4074 if (Parser.parseIdentifier(Identifier)) 4075 return true; 4076 4077 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 4078 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier); 4079 // Otherwise create a symbol reference. 4080 const MCExpr *Res = 4081 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 4082 4083 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this)); 4084 return false; 4085 } 4086 // Else drop to expression parsing. 4087 case AsmToken::LParen: 4088 case AsmToken::Minus: 4089 case AsmToken::Plus: 4090 case AsmToken::Integer: 4091 case AsmToken::Tilde: 4092 case AsmToken::String: { 4093 DEBUG(dbgs() << ".. generic integer\n"); 4094 OperandMatchResultTy ResTy = parseImm(Operands); 4095 return ResTy != MatchOperand_Success; 4096 } 4097 case AsmToken::Percent: { 4098 // It is a symbol reference or constant expression. 4099 const MCExpr *IdVal; 4100 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand. 4101 if (parseRelocOperand(IdVal)) 4102 return true; 4103 4104 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 4105 4106 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this)); 4107 return false; 4108 } // case AsmToken::Percent 4109 } // switch(getLexer().getKind()) 4110 return true; 4111 } 4112 4113 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr, 4114 StringRef RelocStr) { 4115 if (RelocStr == "hi(%neg(%gp_rel") 4116 return MipsMCExpr::createGpOff(MipsMCExpr::MEK_HI, Expr, getContext()); 4117 else if (RelocStr == "lo(%neg(%gp_rel") 4118 return MipsMCExpr::createGpOff(MipsMCExpr::MEK_LO, Expr, getContext()); 4119 4120 MipsMCExpr::MipsExprKind Kind = 4121 StringSwitch<MipsMCExpr::MipsExprKind>(RelocStr) 4122 .Case("call16", MipsMCExpr::MEK_GOT_CALL) 4123 .Case("call_hi", MipsMCExpr::MEK_CALL_HI16) 4124 .Case("call_lo", MipsMCExpr::MEK_CALL_LO16) 4125 .Case("dtprel_hi", MipsMCExpr::MEK_DTPREL_HI) 4126 .Case("dtprel_lo", MipsMCExpr::MEK_DTPREL_LO) 4127 .Case("got", MipsMCExpr::MEK_GOT) 4128 .Case("got_disp", MipsMCExpr::MEK_GOT_DISP) 4129 .Case("got_hi", MipsMCExpr::MEK_GOT_HI16) 4130 .Case("got_lo", MipsMCExpr::MEK_GOT_LO16) 4131 .Case("got_ofst", MipsMCExpr::MEK_GOT_OFST) 4132 .Case("got_page", MipsMCExpr::MEK_GOT_PAGE) 4133 .Case("gottprel", MipsMCExpr::MEK_GOTTPREL) 4134 .Case("gp_rel", MipsMCExpr::MEK_GPREL) 4135 .Case("hi", MipsMCExpr::MEK_HI) 4136 .Case("higher", MipsMCExpr::MEK_HIGHER) 4137 .Case("highest", MipsMCExpr::MEK_HIGHEST) 4138 .Case("lo", MipsMCExpr::MEK_LO) 4139 .Case("neg", MipsMCExpr::MEK_NEG) 4140 .Case("pcrel_hi", MipsMCExpr::MEK_PCREL_HI16) 4141 .Case("pcrel_lo", MipsMCExpr::MEK_PCREL_LO16) 4142 .Case("tlsgd", MipsMCExpr::MEK_TLSGD) 4143 .Case("tlsldm", MipsMCExpr::MEK_TLSLDM) 4144 .Case("tprel_hi", MipsMCExpr::MEK_TPREL_HI) 4145 .Case("tprel_lo", MipsMCExpr::MEK_TPREL_LO) 4146 .Default(MipsMCExpr::MEK_None); 4147 4148 assert(Kind != MipsMCExpr::MEK_None); 4149 return MipsMCExpr::create(Kind, Expr, getContext()); 4150 } 4151 4152 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) { 4153 4154 switch (Expr->getKind()) { 4155 case MCExpr::Constant: 4156 return true; 4157 case MCExpr::SymbolRef: 4158 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None); 4159 case MCExpr::Binary: 4160 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) { 4161 if (!isEvaluated(BE->getLHS())) 4162 return false; 4163 return isEvaluated(BE->getRHS()); 4164 } 4165 case MCExpr::Unary: 4166 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr()); 4167 case MCExpr::Target: 4168 return true; 4169 } 4170 return false; 4171 } 4172 4173 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) { 4174 MCAsmParser &Parser = getParser(); 4175 Parser.Lex(); // Eat the % token. 4176 const AsmToken &Tok = Parser.getTok(); // Get next token, operation. 4177 if (Tok.isNot(AsmToken::Identifier)) 4178 return true; 4179 4180 std::string Str = Tok.getIdentifier(); 4181 4182 Parser.Lex(); // Eat the identifier. 4183 // Now make an expression from the rest of the operand. 4184 const MCExpr *IdVal; 4185 SMLoc EndLoc; 4186 4187 if (getLexer().getKind() == AsmToken::LParen) { 4188 while (1) { 4189 Parser.Lex(); // Eat the '(' token. 4190 if (getLexer().getKind() == AsmToken::Percent) { 4191 Parser.Lex(); // Eat the % token. 4192 const AsmToken &nextTok = Parser.getTok(); 4193 if (nextTok.isNot(AsmToken::Identifier)) 4194 return true; 4195 Str += "(%"; 4196 Str += nextTok.getIdentifier(); 4197 Parser.Lex(); // Eat the identifier. 4198 if (getLexer().getKind() != AsmToken::LParen) 4199 return true; 4200 } else 4201 break; 4202 } 4203 if (getParser().parseParenExpression(IdVal, EndLoc)) 4204 return true; 4205 4206 while (getLexer().getKind() == AsmToken::RParen) 4207 Parser.Lex(); // Eat the ')' token. 4208 4209 } else 4210 return true; // Parenthesis must follow the relocation operand. 4211 4212 Res = evaluateRelocExpr(IdVal, Str); 4213 return false; 4214 } 4215 4216 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 4217 SMLoc &EndLoc) { 4218 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands; 4219 OperandMatchResultTy ResTy = parseAnyRegister(Operands); 4220 if (ResTy == MatchOperand_Success) { 4221 assert(Operands.size() == 1); 4222 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front()); 4223 StartLoc = Operand.getStartLoc(); 4224 EndLoc = Operand.getEndLoc(); 4225 4226 // AFAIK, we only support numeric registers and named GPR's in CFI 4227 // directives. 4228 // Don't worry about eating tokens before failing. Using an unrecognised 4229 // register is a parse error. 4230 if (Operand.isGPRAsmReg()) { 4231 // Resolve to GPR32 or GPR64 appropriately. 4232 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg(); 4233 } 4234 4235 return (RegNo == (unsigned)-1); 4236 } 4237 4238 assert(Operands.size() == 0); 4239 return (RegNo == (unsigned)-1); 4240 } 4241 4242 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) { 4243 MCAsmParser &Parser = getParser(); 4244 SMLoc S; 4245 bool Result = true; 4246 unsigned NumOfLParen = 0; 4247 4248 while (getLexer().getKind() == AsmToken::LParen) { 4249 Parser.Lex(); 4250 ++NumOfLParen; 4251 } 4252 4253 switch (getLexer().getKind()) { 4254 default: 4255 return true; 4256 case AsmToken::Identifier: 4257 case AsmToken::LParen: 4258 case AsmToken::Integer: 4259 case AsmToken::Minus: 4260 case AsmToken::Plus: 4261 if (isParenExpr) 4262 Result = getParser().parseParenExprOfDepth(NumOfLParen, Res, S); 4263 else 4264 Result = (getParser().parseExpression(Res)); 4265 while (getLexer().getKind() == AsmToken::RParen) 4266 Parser.Lex(); 4267 break; 4268 case AsmToken::Percent: 4269 Result = parseRelocOperand(Res); 4270 } 4271 return Result; 4272 } 4273 4274 MipsAsmParser::OperandMatchResultTy 4275 MipsAsmParser::parseMemOperand(OperandVector &Operands) { 4276 MCAsmParser &Parser = getParser(); 4277 DEBUG(dbgs() << "parseMemOperand\n"); 4278 const MCExpr *IdVal = nullptr; 4279 SMLoc S; 4280 bool isParenExpr = false; 4281 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch; 4282 // First operand is the offset. 4283 S = Parser.getTok().getLoc(); 4284 4285 if (getLexer().getKind() == AsmToken::LParen) { 4286 Parser.Lex(); 4287 isParenExpr = true; 4288 } 4289 4290 if (getLexer().getKind() != AsmToken::Dollar) { 4291 if (parseMemOffset(IdVal, isParenExpr)) 4292 return MatchOperand_ParseFail; 4293 4294 const AsmToken &Tok = Parser.getTok(); // Get the next token. 4295 if (Tok.isNot(AsmToken::LParen)) { 4296 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]); 4297 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") { 4298 SMLoc E = 4299 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 4300 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this)); 4301 return MatchOperand_Success; 4302 } 4303 if (Tok.is(AsmToken::EndOfStatement)) { 4304 SMLoc E = 4305 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 4306 4307 // Zero register assumed, add a memory operand with ZERO as its base. 4308 // "Base" will be managed by k_Memory. 4309 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(), 4310 S, E, *this); 4311 Operands.push_back( 4312 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this)); 4313 return MatchOperand_Success; 4314 } 4315 Error(Parser.getTok().getLoc(), "'(' expected"); 4316 return MatchOperand_ParseFail; 4317 } 4318 4319 Parser.Lex(); // Eat the '(' token. 4320 } 4321 4322 Res = parseAnyRegister(Operands); 4323 if (Res != MatchOperand_Success) 4324 return Res; 4325 4326 if (Parser.getTok().isNot(AsmToken::RParen)) { 4327 Error(Parser.getTok().getLoc(), "')' expected"); 4328 return MatchOperand_ParseFail; 4329 } 4330 4331 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 4332 4333 Parser.Lex(); // Eat the ')' token. 4334 4335 if (!IdVal) 4336 IdVal = MCConstantExpr::create(0, getContext()); 4337 4338 // Replace the register operand with the memory operand. 4339 std::unique_ptr<MipsOperand> op( 4340 static_cast<MipsOperand *>(Operands.back().release())); 4341 // Remove the register from the operands. 4342 // "op" will be managed by k_Memory. 4343 Operands.pop_back(); 4344 // Add the memory operand. 4345 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) { 4346 int64_t Imm; 4347 if (IdVal->evaluateAsAbsolute(Imm)) 4348 IdVal = MCConstantExpr::create(Imm, getContext()); 4349 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef) 4350 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(), 4351 getContext()); 4352 } 4353 4354 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this)); 4355 return MatchOperand_Success; 4356 } 4357 4358 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) { 4359 MCAsmParser &Parser = getParser(); 4360 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier()); 4361 if (Sym) { 4362 SMLoc S = Parser.getTok().getLoc(); 4363 const MCExpr *Expr; 4364 if (Sym->isVariable()) 4365 Expr = Sym->getVariableValue(); 4366 else 4367 return false; 4368 if (Expr->getKind() == MCExpr::SymbolRef) { 4369 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr); 4370 StringRef DefSymbol = Ref->getSymbol().getName(); 4371 if (DefSymbol.startswith("$")) { 4372 OperandMatchResultTy ResTy = 4373 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S); 4374 if (ResTy == MatchOperand_Success) { 4375 Parser.Lex(); 4376 return true; 4377 } else if (ResTy == MatchOperand_ParseFail) 4378 llvm_unreachable("Should never ParseFail"); 4379 return false; 4380 } 4381 } else if (Expr->getKind() == MCExpr::Constant) { 4382 Parser.Lex(); 4383 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr); 4384 Operands.push_back( 4385 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this)); 4386 return true; 4387 } 4388 } 4389 return false; 4390 } 4391 4392 MipsAsmParser::OperandMatchResultTy 4393 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands, 4394 StringRef Identifier, 4395 SMLoc S) { 4396 int Index = matchCPURegisterName(Identifier); 4397 if (Index != -1) { 4398 Operands.push_back(MipsOperand::createGPRReg( 4399 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 4400 return MatchOperand_Success; 4401 } 4402 4403 Index = matchHWRegsRegisterName(Identifier); 4404 if (Index != -1) { 4405 Operands.push_back(MipsOperand::createHWRegsReg( 4406 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 4407 return MatchOperand_Success; 4408 } 4409 4410 Index = matchFPURegisterName(Identifier); 4411 if (Index != -1) { 4412 Operands.push_back(MipsOperand::createFGRReg( 4413 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 4414 return MatchOperand_Success; 4415 } 4416 4417 Index = matchFCCRegisterName(Identifier); 4418 if (Index != -1) { 4419 Operands.push_back(MipsOperand::createFCCReg( 4420 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 4421 return MatchOperand_Success; 4422 } 4423 4424 Index = matchACRegisterName(Identifier); 4425 if (Index != -1) { 4426 Operands.push_back(MipsOperand::createACCReg( 4427 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 4428 return MatchOperand_Success; 4429 } 4430 4431 Index = matchMSA128RegisterName(Identifier); 4432 if (Index != -1) { 4433 Operands.push_back(MipsOperand::createMSA128Reg( 4434 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 4435 return MatchOperand_Success; 4436 } 4437 4438 Index = matchMSA128CtrlRegisterName(Identifier); 4439 if (Index != -1) { 4440 Operands.push_back(MipsOperand::createMSACtrlReg( 4441 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 4442 return MatchOperand_Success; 4443 } 4444 4445 return MatchOperand_NoMatch; 4446 } 4447 4448 MipsAsmParser::OperandMatchResultTy 4449 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) { 4450 MCAsmParser &Parser = getParser(); 4451 auto Token = Parser.getLexer().peekTok(false); 4452 4453 if (Token.is(AsmToken::Identifier)) { 4454 DEBUG(dbgs() << ".. identifier\n"); 4455 StringRef Identifier = Token.getIdentifier(); 4456 OperandMatchResultTy ResTy = 4457 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S); 4458 return ResTy; 4459 } else if (Token.is(AsmToken::Integer)) { 4460 DEBUG(dbgs() << ".. integer\n"); 4461 Operands.push_back(MipsOperand::createNumericReg( 4462 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(), 4463 *this)); 4464 return MatchOperand_Success; 4465 } 4466 4467 DEBUG(dbgs() << Parser.getTok().getKind() << "\n"); 4468 4469 return MatchOperand_NoMatch; 4470 } 4471 4472 MipsAsmParser::OperandMatchResultTy 4473 MipsAsmParser::parseAnyRegister(OperandVector &Operands) { 4474 MCAsmParser &Parser = getParser(); 4475 DEBUG(dbgs() << "parseAnyRegister\n"); 4476 4477 auto Token = Parser.getTok(); 4478 4479 SMLoc S = Token.getLoc(); 4480 4481 if (Token.isNot(AsmToken::Dollar)) { 4482 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n"); 4483 if (Token.is(AsmToken::Identifier)) { 4484 if (searchSymbolAlias(Operands)) 4485 return MatchOperand_Success; 4486 } 4487 DEBUG(dbgs() << ".. !symalias -> NoMatch\n"); 4488 return MatchOperand_NoMatch; 4489 } 4490 DEBUG(dbgs() << ".. $\n"); 4491 4492 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S); 4493 if (ResTy == MatchOperand_Success) { 4494 Parser.Lex(); // $ 4495 Parser.Lex(); // identifier 4496 } 4497 return ResTy; 4498 } 4499 4500 MipsAsmParser::OperandMatchResultTy 4501 MipsAsmParser::parseImm(OperandVector &Operands) { 4502 MCAsmParser &Parser = getParser(); 4503 switch (getLexer().getKind()) { 4504 default: 4505 return MatchOperand_NoMatch; 4506 case AsmToken::LParen: 4507 case AsmToken::Minus: 4508 case AsmToken::Plus: 4509 case AsmToken::Integer: 4510 case AsmToken::Tilde: 4511 case AsmToken::String: 4512 break; 4513 } 4514 4515 const MCExpr *IdVal; 4516 SMLoc S = Parser.getTok().getLoc(); 4517 if (getParser().parseExpression(IdVal)) 4518 return MatchOperand_ParseFail; 4519 4520 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 4521 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this)); 4522 return MatchOperand_Success; 4523 } 4524 4525 MipsAsmParser::OperandMatchResultTy 4526 MipsAsmParser::parseJumpTarget(OperandVector &Operands) { 4527 MCAsmParser &Parser = getParser(); 4528 DEBUG(dbgs() << "parseJumpTarget\n"); 4529 4530 SMLoc S = getLexer().getLoc(); 4531 4532 // Integers and expressions are acceptable 4533 OperandMatchResultTy ResTy = parseImm(Operands); 4534 if (ResTy != MatchOperand_NoMatch) 4535 return ResTy; 4536 4537 // Registers are a valid target and have priority over symbols. 4538 ResTy = parseAnyRegister(Operands); 4539 if (ResTy != MatchOperand_NoMatch) 4540 return ResTy; 4541 4542 const MCExpr *Expr = nullptr; 4543 if (Parser.parseExpression(Expr)) { 4544 // We have no way of knowing if a symbol was consumed so we must ParseFail 4545 return MatchOperand_ParseFail; 4546 } 4547 Operands.push_back( 4548 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this)); 4549 return MatchOperand_Success; 4550 } 4551 4552 MipsAsmParser::OperandMatchResultTy 4553 MipsAsmParser::parseInvNum(OperandVector &Operands) { 4554 MCAsmParser &Parser = getParser(); 4555 const MCExpr *IdVal; 4556 // If the first token is '$' we may have register operand. 4557 if (Parser.getTok().is(AsmToken::Dollar)) 4558 return MatchOperand_NoMatch; 4559 SMLoc S = Parser.getTok().getLoc(); 4560 if (getParser().parseExpression(IdVal)) 4561 return MatchOperand_ParseFail; 4562 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal); 4563 assert(MCE && "Unexpected MCExpr type."); 4564 int64_t Val = MCE->getValue(); 4565 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 4566 Operands.push_back(MipsOperand::CreateImm( 4567 MCConstantExpr::create(0 - Val, getContext()), S, E, *this)); 4568 return MatchOperand_Success; 4569 } 4570 4571 MipsAsmParser::OperandMatchResultTy 4572 MipsAsmParser::parseLSAImm(OperandVector &Operands) { 4573 MCAsmParser &Parser = getParser(); 4574 switch (getLexer().getKind()) { 4575 default: 4576 return MatchOperand_NoMatch; 4577 case AsmToken::LParen: 4578 case AsmToken::Plus: 4579 case AsmToken::Minus: 4580 case AsmToken::Integer: 4581 break; 4582 } 4583 4584 const MCExpr *Expr; 4585 SMLoc S = Parser.getTok().getLoc(); 4586 4587 if (getParser().parseExpression(Expr)) 4588 return MatchOperand_ParseFail; 4589 4590 int64_t Val; 4591 if (!Expr->evaluateAsAbsolute(Val)) { 4592 Error(S, "expected immediate value"); 4593 return MatchOperand_ParseFail; 4594 } 4595 4596 // The LSA instruction allows a 2-bit unsigned immediate. For this reason 4597 // and because the CPU always adds one to the immediate field, the allowed 4598 // range becomes 1..4. We'll only check the range here and will deal 4599 // with the addition/subtraction when actually decoding/encoding 4600 // the instruction. 4601 if (Val < 1 || Val > 4) { 4602 Error(S, "immediate not in range (1..4)"); 4603 return MatchOperand_ParseFail; 4604 } 4605 4606 Operands.push_back( 4607 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this)); 4608 return MatchOperand_Success; 4609 } 4610 4611 MipsAsmParser::OperandMatchResultTy 4612 MipsAsmParser::parseRegisterList(OperandVector &Operands) { 4613 MCAsmParser &Parser = getParser(); 4614 SmallVector<unsigned, 10> Regs; 4615 unsigned RegNo; 4616 unsigned PrevReg = Mips::NoRegister; 4617 bool RegRange = false; 4618 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands; 4619 4620 if (Parser.getTok().isNot(AsmToken::Dollar)) 4621 return MatchOperand_ParseFail; 4622 4623 SMLoc S = Parser.getTok().getLoc(); 4624 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) { 4625 SMLoc E = getLexer().getLoc(); 4626 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back()); 4627 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg(); 4628 if (RegRange) { 4629 // Remove last register operand because registers from register range 4630 // should be inserted first. 4631 if ((isGP64bit() && RegNo == Mips::RA_64) || 4632 (!isGP64bit() && RegNo == Mips::RA)) { 4633 Regs.push_back(RegNo); 4634 } else { 4635 unsigned TmpReg = PrevReg + 1; 4636 while (TmpReg <= RegNo) { 4637 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) || 4638 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) && 4639 isGP64bit())) { 4640 Error(E, "invalid register operand"); 4641 return MatchOperand_ParseFail; 4642 } 4643 4644 PrevReg = TmpReg; 4645 Regs.push_back(TmpReg++); 4646 } 4647 } 4648 4649 RegRange = false; 4650 } else { 4651 if ((PrevReg == Mips::NoRegister) && 4652 ((isGP64bit() && (RegNo != Mips::S0_64) && (RegNo != Mips::RA_64)) || 4653 (!isGP64bit() && (RegNo != Mips::S0) && (RegNo != Mips::RA)))) { 4654 Error(E, "$16 or $31 expected"); 4655 return MatchOperand_ParseFail; 4656 } else if (!(((RegNo == Mips::FP || RegNo == Mips::RA || 4657 (RegNo >= Mips::S0 && RegNo <= Mips::S7)) && 4658 !isGP64bit()) || 4659 ((RegNo == Mips::FP_64 || RegNo == Mips::RA_64 || 4660 (RegNo >= Mips::S0_64 && RegNo <= Mips::S7_64)) && 4661 isGP64bit()))) { 4662 Error(E, "invalid register operand"); 4663 return MatchOperand_ParseFail; 4664 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) && 4665 ((RegNo != Mips::FP && RegNo != Mips::RA && !isGP64bit()) || 4666 (RegNo != Mips::FP_64 && RegNo != Mips::RA_64 && 4667 isGP64bit()))) { 4668 Error(E, "consecutive register numbers expected"); 4669 return MatchOperand_ParseFail; 4670 } 4671 4672 Regs.push_back(RegNo); 4673 } 4674 4675 if (Parser.getTok().is(AsmToken::Minus)) 4676 RegRange = true; 4677 4678 if (!Parser.getTok().isNot(AsmToken::Minus) && 4679 !Parser.getTok().isNot(AsmToken::Comma)) { 4680 Error(E, "',' or '-' expected"); 4681 return MatchOperand_ParseFail; 4682 } 4683 4684 Lex(); // Consume comma or minus 4685 if (Parser.getTok().isNot(AsmToken::Dollar)) 4686 break; 4687 4688 PrevReg = RegNo; 4689 } 4690 4691 SMLoc E = Parser.getTok().getLoc(); 4692 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this)); 4693 parseMemOperand(Operands); 4694 return MatchOperand_Success; 4695 } 4696 4697 MipsAsmParser::OperandMatchResultTy 4698 MipsAsmParser::parseRegisterPair(OperandVector &Operands) { 4699 MCAsmParser &Parser = getParser(); 4700 4701 SMLoc S = Parser.getTok().getLoc(); 4702 if (parseAnyRegister(Operands) != MatchOperand_Success) 4703 return MatchOperand_ParseFail; 4704 4705 SMLoc E = Parser.getTok().getLoc(); 4706 MipsOperand Op = static_cast<MipsOperand &>(*Operands.back()); 4707 4708 Operands.pop_back(); 4709 Operands.push_back(MipsOperand::CreateRegPair(Op, S, E, *this)); 4710 return MatchOperand_Success; 4711 } 4712 4713 MipsAsmParser::OperandMatchResultTy 4714 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) { 4715 MCAsmParser &Parser = getParser(); 4716 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands; 4717 SmallVector<unsigned, 10> Regs; 4718 4719 if (Parser.getTok().isNot(AsmToken::Dollar)) 4720 return MatchOperand_ParseFail; 4721 4722 SMLoc S = Parser.getTok().getLoc(); 4723 4724 if (parseAnyRegister(TmpOperands) != MatchOperand_Success) 4725 return MatchOperand_ParseFail; 4726 4727 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back()); 4728 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg(); 4729 Regs.push_back(RegNo); 4730 4731 SMLoc E = Parser.getTok().getLoc(); 4732 if (Parser.getTok().isNot(AsmToken::Comma)) { 4733 Error(E, "',' expected"); 4734 return MatchOperand_ParseFail; 4735 } 4736 4737 // Remove comma. 4738 Parser.Lex(); 4739 4740 if (parseAnyRegister(TmpOperands) != MatchOperand_Success) 4741 return MatchOperand_ParseFail; 4742 4743 Reg = &static_cast<MipsOperand &>(*TmpOperands.back()); 4744 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg(); 4745 Regs.push_back(RegNo); 4746 4747 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this)); 4748 4749 return MatchOperand_Success; 4750 } 4751 4752 /// Sometimes (i.e. load/stores) the operand may be followed immediately by 4753 /// either this. 4754 /// ::= '(', register, ')' 4755 /// handle it before we iterate so we don't get tripped up by the lack of 4756 /// a comma. 4757 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) { 4758 MCAsmParser &Parser = getParser(); 4759 if (getLexer().is(AsmToken::LParen)) { 4760 Operands.push_back( 4761 MipsOperand::CreateToken("(", getLexer().getLoc(), *this)); 4762 Parser.Lex(); 4763 if (parseOperand(Operands, Name)) { 4764 SMLoc Loc = getLexer().getLoc(); 4765 Parser.eatToEndOfStatement(); 4766 return Error(Loc, "unexpected token in argument list"); 4767 } 4768 if (Parser.getTok().isNot(AsmToken::RParen)) { 4769 SMLoc Loc = getLexer().getLoc(); 4770 Parser.eatToEndOfStatement(); 4771 return Error(Loc, "unexpected token, expected ')'"); 4772 } 4773 Operands.push_back( 4774 MipsOperand::CreateToken(")", getLexer().getLoc(), *this)); 4775 Parser.Lex(); 4776 } 4777 return false; 4778 } 4779 4780 /// Sometimes (i.e. in MSA) the operand may be followed immediately by 4781 /// either one of these. 4782 /// ::= '[', register, ']' 4783 /// ::= '[', integer, ']' 4784 /// handle it before we iterate so we don't get tripped up by the lack of 4785 /// a comma. 4786 bool MipsAsmParser::parseBracketSuffix(StringRef Name, 4787 OperandVector &Operands) { 4788 MCAsmParser &Parser = getParser(); 4789 if (getLexer().is(AsmToken::LBrac)) { 4790 Operands.push_back( 4791 MipsOperand::CreateToken("[", getLexer().getLoc(), *this)); 4792 Parser.Lex(); 4793 if (parseOperand(Operands, Name)) { 4794 SMLoc Loc = getLexer().getLoc(); 4795 Parser.eatToEndOfStatement(); 4796 return Error(Loc, "unexpected token in argument list"); 4797 } 4798 if (Parser.getTok().isNot(AsmToken::RBrac)) { 4799 SMLoc Loc = getLexer().getLoc(); 4800 Parser.eatToEndOfStatement(); 4801 return Error(Loc, "unexpected token, expected ']'"); 4802 } 4803 Operands.push_back( 4804 MipsOperand::CreateToken("]", getLexer().getLoc(), *this)); 4805 Parser.Lex(); 4806 } 4807 return false; 4808 } 4809 4810 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 4811 SMLoc NameLoc, OperandVector &Operands) { 4812 MCAsmParser &Parser = getParser(); 4813 DEBUG(dbgs() << "ParseInstruction\n"); 4814 4815 // We have reached first instruction, module directive are now forbidden. 4816 getTargetStreamer().forbidModuleDirective(); 4817 4818 // Check if we have valid mnemonic 4819 if (!mnemonicIsValid(Name, 0)) { 4820 Parser.eatToEndOfStatement(); 4821 return Error(NameLoc, "unknown instruction"); 4822 } 4823 // First operand in MCInst is instruction mnemonic. 4824 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this)); 4825 4826 // Read the remaining operands. 4827 if (getLexer().isNot(AsmToken::EndOfStatement)) { 4828 // Read the first operand. 4829 if (parseOperand(Operands, Name)) { 4830 SMLoc Loc = getLexer().getLoc(); 4831 Parser.eatToEndOfStatement(); 4832 return Error(Loc, "unexpected token in argument list"); 4833 } 4834 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands)) 4835 return true; 4836 // AFAIK, parenthesis suffixes are never on the first operand 4837 4838 while (getLexer().is(AsmToken::Comma)) { 4839 Parser.Lex(); // Eat the comma. 4840 // Parse and remember the operand. 4841 if (parseOperand(Operands, Name)) { 4842 SMLoc Loc = getLexer().getLoc(); 4843 Parser.eatToEndOfStatement(); 4844 return Error(Loc, "unexpected token in argument list"); 4845 } 4846 // Parse bracket and parenthesis suffixes before we iterate 4847 if (getLexer().is(AsmToken::LBrac)) { 4848 if (parseBracketSuffix(Name, Operands)) 4849 return true; 4850 } else if (getLexer().is(AsmToken::LParen) && 4851 parseParenSuffix(Name, Operands)) 4852 return true; 4853 } 4854 } 4855 if (getLexer().isNot(AsmToken::EndOfStatement)) { 4856 SMLoc Loc = getLexer().getLoc(); 4857 Parser.eatToEndOfStatement(); 4858 return Error(Loc, "unexpected token in argument list"); 4859 } 4860 Parser.Lex(); // Consume the EndOfStatement. 4861 return false; 4862 } 4863 4864 // FIXME: Given that these have the same name, these should both be 4865 // consistent on affecting the Parser. 4866 bool MipsAsmParser::reportParseError(Twine ErrorMsg) { 4867 MCAsmParser &Parser = getParser(); 4868 SMLoc Loc = getLexer().getLoc(); 4869 Parser.eatToEndOfStatement(); 4870 return Error(Loc, ErrorMsg); 4871 } 4872 4873 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) { 4874 return Error(Loc, ErrorMsg); 4875 } 4876 4877 bool MipsAsmParser::parseSetNoAtDirective() { 4878 MCAsmParser &Parser = getParser(); 4879 // Line should look like: ".set noat". 4880 4881 // Set the $at register to $0. 4882 AssemblerOptions.back()->setATRegIndex(0); 4883 4884 Parser.Lex(); // Eat "noat". 4885 4886 // If this is not the end of the statement, report an error. 4887 if (getLexer().isNot(AsmToken::EndOfStatement)) { 4888 reportParseError("unexpected token, expected end of statement"); 4889 return false; 4890 } 4891 4892 getTargetStreamer().emitDirectiveSetNoAt(); 4893 Parser.Lex(); // Consume the EndOfStatement. 4894 return false; 4895 } 4896 4897 bool MipsAsmParser::parseSetAtDirective() { 4898 // Line can be: ".set at", which sets $at to $1 4899 // or ".set at=$reg", which sets $at to $reg. 4900 MCAsmParser &Parser = getParser(); 4901 Parser.Lex(); // Eat "at". 4902 4903 if (getLexer().is(AsmToken::EndOfStatement)) { 4904 // No register was specified, so we set $at to $1. 4905 AssemblerOptions.back()->setATRegIndex(1); 4906 4907 getTargetStreamer().emitDirectiveSetAt(); 4908 Parser.Lex(); // Consume the EndOfStatement. 4909 return false; 4910 } 4911 4912 if (getLexer().isNot(AsmToken::Equal)) { 4913 reportParseError("unexpected token, expected equals sign"); 4914 return false; 4915 } 4916 Parser.Lex(); // Eat "=". 4917 4918 if (getLexer().isNot(AsmToken::Dollar)) { 4919 if (getLexer().is(AsmToken::EndOfStatement)) { 4920 reportParseError("no register specified"); 4921 return false; 4922 } else { 4923 reportParseError("unexpected token, expected dollar sign '$'"); 4924 return false; 4925 } 4926 } 4927 Parser.Lex(); // Eat "$". 4928 4929 // Find out what "reg" is. 4930 unsigned AtRegNo; 4931 const AsmToken &Reg = Parser.getTok(); 4932 if (Reg.is(AsmToken::Identifier)) { 4933 AtRegNo = matchCPURegisterName(Reg.getIdentifier()); 4934 } else if (Reg.is(AsmToken::Integer)) { 4935 AtRegNo = Reg.getIntVal(); 4936 } else { 4937 reportParseError("unexpected token, expected identifier or integer"); 4938 return false; 4939 } 4940 4941 // Check if $reg is a valid register. If it is, set $at to $reg. 4942 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) { 4943 reportParseError("invalid register"); 4944 return false; 4945 } 4946 Parser.Lex(); // Eat "reg". 4947 4948 // If this is not the end of the statement, report an error. 4949 if (getLexer().isNot(AsmToken::EndOfStatement)) { 4950 reportParseError("unexpected token, expected end of statement"); 4951 return false; 4952 } 4953 4954 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo); 4955 4956 Parser.Lex(); // Consume the EndOfStatement. 4957 return false; 4958 } 4959 4960 bool MipsAsmParser::parseSetReorderDirective() { 4961 MCAsmParser &Parser = getParser(); 4962 Parser.Lex(); 4963 // If this is not the end of the statement, report an error. 4964 if (getLexer().isNot(AsmToken::EndOfStatement)) { 4965 reportParseError("unexpected token, expected end of statement"); 4966 return false; 4967 } 4968 AssemblerOptions.back()->setReorder(); 4969 getTargetStreamer().emitDirectiveSetReorder(); 4970 Parser.Lex(); // Consume the EndOfStatement. 4971 return false; 4972 } 4973 4974 bool MipsAsmParser::parseSetNoReorderDirective() { 4975 MCAsmParser &Parser = getParser(); 4976 Parser.Lex(); 4977 // If this is not the end of the statement, report an error. 4978 if (getLexer().isNot(AsmToken::EndOfStatement)) { 4979 reportParseError("unexpected token, expected end of statement"); 4980 return false; 4981 } 4982 AssemblerOptions.back()->setNoReorder(); 4983 getTargetStreamer().emitDirectiveSetNoReorder(); 4984 Parser.Lex(); // Consume the EndOfStatement. 4985 return false; 4986 } 4987 4988 bool MipsAsmParser::parseSetMacroDirective() { 4989 MCAsmParser &Parser = getParser(); 4990 Parser.Lex(); 4991 // If this is not the end of the statement, report an error. 4992 if (getLexer().isNot(AsmToken::EndOfStatement)) { 4993 reportParseError("unexpected token, expected end of statement"); 4994 return false; 4995 } 4996 AssemblerOptions.back()->setMacro(); 4997 getTargetStreamer().emitDirectiveSetMacro(); 4998 Parser.Lex(); // Consume the EndOfStatement. 4999 return false; 5000 } 5001 5002 bool MipsAsmParser::parseSetNoMacroDirective() { 5003 MCAsmParser &Parser = getParser(); 5004 Parser.Lex(); 5005 // If this is not the end of the statement, report an error. 5006 if (getLexer().isNot(AsmToken::EndOfStatement)) { 5007 reportParseError("unexpected token, expected end of statement"); 5008 return false; 5009 } 5010 if (AssemblerOptions.back()->isReorder()) { 5011 reportParseError("`noreorder' must be set before `nomacro'"); 5012 return false; 5013 } 5014 AssemblerOptions.back()->setNoMacro(); 5015 getTargetStreamer().emitDirectiveSetNoMacro(); 5016 Parser.Lex(); // Consume the EndOfStatement. 5017 return false; 5018 } 5019 5020 bool MipsAsmParser::parseSetMsaDirective() { 5021 MCAsmParser &Parser = getParser(); 5022 Parser.Lex(); 5023 5024 // If this is not the end of the statement, report an error. 5025 if (getLexer().isNot(AsmToken::EndOfStatement)) 5026 return reportParseError("unexpected token, expected end of statement"); 5027 5028 setFeatureBits(Mips::FeatureMSA, "msa"); 5029 getTargetStreamer().emitDirectiveSetMsa(); 5030 return false; 5031 } 5032 5033 bool MipsAsmParser::parseSetNoMsaDirective() { 5034 MCAsmParser &Parser = getParser(); 5035 Parser.Lex(); 5036 5037 // If this is not the end of the statement, report an error. 5038 if (getLexer().isNot(AsmToken::EndOfStatement)) 5039 return reportParseError("unexpected token, expected end of statement"); 5040 5041 clearFeatureBits(Mips::FeatureMSA, "msa"); 5042 getTargetStreamer().emitDirectiveSetNoMsa(); 5043 return false; 5044 } 5045 5046 bool MipsAsmParser::parseSetNoDspDirective() { 5047 MCAsmParser &Parser = getParser(); 5048 Parser.Lex(); // Eat "nodsp". 5049 5050 // If this is not the end of the statement, report an error. 5051 if (getLexer().isNot(AsmToken::EndOfStatement)) { 5052 reportParseError("unexpected token, expected end of statement"); 5053 return false; 5054 } 5055 5056 clearFeatureBits(Mips::FeatureDSP, "dsp"); 5057 getTargetStreamer().emitDirectiveSetNoDsp(); 5058 return false; 5059 } 5060 5061 bool MipsAsmParser::parseSetMips16Directive() { 5062 MCAsmParser &Parser = getParser(); 5063 Parser.Lex(); // Eat "mips16". 5064 5065 // If this is not the end of the statement, report an error. 5066 if (getLexer().isNot(AsmToken::EndOfStatement)) { 5067 reportParseError("unexpected token, expected end of statement"); 5068 return false; 5069 } 5070 5071 setFeatureBits(Mips::FeatureMips16, "mips16"); 5072 getTargetStreamer().emitDirectiveSetMips16(); 5073 Parser.Lex(); // Consume the EndOfStatement. 5074 return false; 5075 } 5076 5077 bool MipsAsmParser::parseSetNoMips16Directive() { 5078 MCAsmParser &Parser = getParser(); 5079 Parser.Lex(); // Eat "nomips16". 5080 5081 // If this is not the end of the statement, report an error. 5082 if (getLexer().isNot(AsmToken::EndOfStatement)) { 5083 reportParseError("unexpected token, expected end of statement"); 5084 return false; 5085 } 5086 5087 clearFeatureBits(Mips::FeatureMips16, "mips16"); 5088 getTargetStreamer().emitDirectiveSetNoMips16(); 5089 Parser.Lex(); // Consume the EndOfStatement. 5090 return false; 5091 } 5092 5093 bool MipsAsmParser::parseSetFpDirective() { 5094 MCAsmParser &Parser = getParser(); 5095 MipsABIFlagsSection::FpABIKind FpAbiVal; 5096 // Line can be: .set fp=32 5097 // .set fp=xx 5098 // .set fp=64 5099 Parser.Lex(); // Eat fp token 5100 AsmToken Tok = Parser.getTok(); 5101 if (Tok.isNot(AsmToken::Equal)) { 5102 reportParseError("unexpected token, expected equals sign '='"); 5103 return false; 5104 } 5105 Parser.Lex(); // Eat '=' token. 5106 Tok = Parser.getTok(); 5107 5108 if (!parseFpABIValue(FpAbiVal, ".set")) 5109 return false; 5110 5111 if (getLexer().isNot(AsmToken::EndOfStatement)) { 5112 reportParseError("unexpected token, expected end of statement"); 5113 return false; 5114 } 5115 getTargetStreamer().emitDirectiveSetFp(FpAbiVal); 5116 Parser.Lex(); // Consume the EndOfStatement. 5117 return false; 5118 } 5119 5120 bool MipsAsmParser::parseSetOddSPRegDirective() { 5121 MCAsmParser &Parser = getParser(); 5122 5123 Parser.Lex(); // Eat "oddspreg". 5124 if (getLexer().isNot(AsmToken::EndOfStatement)) { 5125 reportParseError("unexpected token, expected end of statement"); 5126 return false; 5127 } 5128 5129 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg"); 5130 getTargetStreamer().emitDirectiveSetOddSPReg(); 5131 return false; 5132 } 5133 5134 bool MipsAsmParser::parseSetNoOddSPRegDirective() { 5135 MCAsmParser &Parser = getParser(); 5136 5137 Parser.Lex(); // Eat "nooddspreg". 5138 if (getLexer().isNot(AsmToken::EndOfStatement)) { 5139 reportParseError("unexpected token, expected end of statement"); 5140 return false; 5141 } 5142 5143 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg"); 5144 getTargetStreamer().emitDirectiveSetNoOddSPReg(); 5145 return false; 5146 } 5147 5148 bool MipsAsmParser::parseSetPopDirective() { 5149 MCAsmParser &Parser = getParser(); 5150 SMLoc Loc = getLexer().getLoc(); 5151 5152 Parser.Lex(); 5153 if (getLexer().isNot(AsmToken::EndOfStatement)) 5154 return reportParseError("unexpected token, expected end of statement"); 5155 5156 // Always keep an element on the options "stack" to prevent the user 5157 // from changing the initial options. This is how we remember them. 5158 if (AssemblerOptions.size() == 2) 5159 return reportParseError(Loc, ".set pop with no .set push"); 5160 5161 MCSubtargetInfo &STI = copySTI(); 5162 AssemblerOptions.pop_back(); 5163 setAvailableFeatures( 5164 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures())); 5165 STI.setFeatureBits(AssemblerOptions.back()->getFeatures()); 5166 5167 getTargetStreamer().emitDirectiveSetPop(); 5168 return false; 5169 } 5170 5171 bool MipsAsmParser::parseSetPushDirective() { 5172 MCAsmParser &Parser = getParser(); 5173 Parser.Lex(); 5174 if (getLexer().isNot(AsmToken::EndOfStatement)) 5175 return reportParseError("unexpected token, expected end of statement"); 5176 5177 // Create a copy of the current assembler options environment and push it. 5178 AssemblerOptions.push_back( 5179 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get())); 5180 5181 getTargetStreamer().emitDirectiveSetPush(); 5182 return false; 5183 } 5184 5185 bool MipsAsmParser::parseSetSoftFloatDirective() { 5186 MCAsmParser &Parser = getParser(); 5187 Parser.Lex(); 5188 if (getLexer().isNot(AsmToken::EndOfStatement)) 5189 return reportParseError("unexpected token, expected end of statement"); 5190 5191 setFeatureBits(Mips::FeatureSoftFloat, "soft-float"); 5192 getTargetStreamer().emitDirectiveSetSoftFloat(); 5193 return false; 5194 } 5195 5196 bool MipsAsmParser::parseSetHardFloatDirective() { 5197 MCAsmParser &Parser = getParser(); 5198 Parser.Lex(); 5199 if (getLexer().isNot(AsmToken::EndOfStatement)) 5200 return reportParseError("unexpected token, expected end of statement"); 5201 5202 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float"); 5203 getTargetStreamer().emitDirectiveSetHardFloat(); 5204 return false; 5205 } 5206 5207 bool MipsAsmParser::parseSetAssignment() { 5208 StringRef Name; 5209 const MCExpr *Value; 5210 MCAsmParser &Parser = getParser(); 5211 5212 if (Parser.parseIdentifier(Name)) 5213 reportParseError("expected identifier after .set"); 5214 5215 if (getLexer().isNot(AsmToken::Comma)) 5216 return reportParseError("unexpected token, expected comma"); 5217 Lex(); // Eat comma 5218 5219 if (Parser.parseExpression(Value)) 5220 return reportParseError("expected valid expression after comma"); 5221 5222 MCSymbol *Sym = getContext().getOrCreateSymbol(Name); 5223 Sym->setVariableValue(Value); 5224 5225 return false; 5226 } 5227 5228 bool MipsAsmParser::parseSetMips0Directive() { 5229 MCAsmParser &Parser = getParser(); 5230 Parser.Lex(); 5231 if (getLexer().isNot(AsmToken::EndOfStatement)) 5232 return reportParseError("unexpected token, expected end of statement"); 5233 5234 // Reset assembler options to their initial values. 5235 MCSubtargetInfo &STI = copySTI(); 5236 setAvailableFeatures( 5237 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures())); 5238 STI.setFeatureBits(AssemblerOptions.front()->getFeatures()); 5239 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures()); 5240 5241 getTargetStreamer().emitDirectiveSetMips0(); 5242 return false; 5243 } 5244 5245 bool MipsAsmParser::parseSetArchDirective() { 5246 MCAsmParser &Parser = getParser(); 5247 Parser.Lex(); 5248 if (getLexer().isNot(AsmToken::Equal)) 5249 return reportParseError("unexpected token, expected equals sign"); 5250 5251 Parser.Lex(); 5252 StringRef Arch; 5253 if (Parser.parseIdentifier(Arch)) 5254 return reportParseError("expected arch identifier"); 5255 5256 StringRef ArchFeatureName = 5257 StringSwitch<StringRef>(Arch) 5258 .Case("mips1", "mips1") 5259 .Case("mips2", "mips2") 5260 .Case("mips3", "mips3") 5261 .Case("mips4", "mips4") 5262 .Case("mips5", "mips5") 5263 .Case("mips32", "mips32") 5264 .Case("mips32r2", "mips32r2") 5265 .Case("mips32r3", "mips32r3") 5266 .Case("mips32r5", "mips32r5") 5267 .Case("mips32r6", "mips32r6") 5268 .Case("mips64", "mips64") 5269 .Case("mips64r2", "mips64r2") 5270 .Case("mips64r3", "mips64r3") 5271 .Case("mips64r5", "mips64r5") 5272 .Case("mips64r6", "mips64r6") 5273 .Case("octeon", "cnmips") 5274 .Case("r4000", "mips3") // This is an implementation of Mips3. 5275 .Default(""); 5276 5277 if (ArchFeatureName.empty()) 5278 return reportParseError("unsupported architecture"); 5279 5280 selectArch(ArchFeatureName); 5281 getTargetStreamer().emitDirectiveSetArch(Arch); 5282 return false; 5283 } 5284 5285 bool MipsAsmParser::parseSetFeature(uint64_t Feature) { 5286 MCAsmParser &Parser = getParser(); 5287 Parser.Lex(); 5288 if (getLexer().isNot(AsmToken::EndOfStatement)) 5289 return reportParseError("unexpected token, expected end of statement"); 5290 5291 switch (Feature) { 5292 default: 5293 llvm_unreachable("Unimplemented feature"); 5294 case Mips::FeatureDSP: 5295 setFeatureBits(Mips::FeatureDSP, "dsp"); 5296 getTargetStreamer().emitDirectiveSetDsp(); 5297 break; 5298 case Mips::FeatureMicroMips: 5299 setFeatureBits(Mips::FeatureMicroMips, "micromips"); 5300 getTargetStreamer().emitDirectiveSetMicroMips(); 5301 break; 5302 case Mips::FeatureMips1: 5303 selectArch("mips1"); 5304 getTargetStreamer().emitDirectiveSetMips1(); 5305 break; 5306 case Mips::FeatureMips2: 5307 selectArch("mips2"); 5308 getTargetStreamer().emitDirectiveSetMips2(); 5309 break; 5310 case Mips::FeatureMips3: 5311 selectArch("mips3"); 5312 getTargetStreamer().emitDirectiveSetMips3(); 5313 break; 5314 case Mips::FeatureMips4: 5315 selectArch("mips4"); 5316 getTargetStreamer().emitDirectiveSetMips4(); 5317 break; 5318 case Mips::FeatureMips5: 5319 selectArch("mips5"); 5320 getTargetStreamer().emitDirectiveSetMips5(); 5321 break; 5322 case Mips::FeatureMips32: 5323 selectArch("mips32"); 5324 getTargetStreamer().emitDirectiveSetMips32(); 5325 break; 5326 case Mips::FeatureMips32r2: 5327 selectArch("mips32r2"); 5328 getTargetStreamer().emitDirectiveSetMips32R2(); 5329 break; 5330 case Mips::FeatureMips32r3: 5331 selectArch("mips32r3"); 5332 getTargetStreamer().emitDirectiveSetMips32R3(); 5333 break; 5334 case Mips::FeatureMips32r5: 5335 selectArch("mips32r5"); 5336 getTargetStreamer().emitDirectiveSetMips32R5(); 5337 break; 5338 case Mips::FeatureMips32r6: 5339 selectArch("mips32r6"); 5340 getTargetStreamer().emitDirectiveSetMips32R6(); 5341 break; 5342 case Mips::FeatureMips64: 5343 selectArch("mips64"); 5344 getTargetStreamer().emitDirectiveSetMips64(); 5345 break; 5346 case Mips::FeatureMips64r2: 5347 selectArch("mips64r2"); 5348 getTargetStreamer().emitDirectiveSetMips64R2(); 5349 break; 5350 case Mips::FeatureMips64r3: 5351 selectArch("mips64r3"); 5352 getTargetStreamer().emitDirectiveSetMips64R3(); 5353 break; 5354 case Mips::FeatureMips64r5: 5355 selectArch("mips64r5"); 5356 getTargetStreamer().emitDirectiveSetMips64R5(); 5357 break; 5358 case Mips::FeatureMips64r6: 5359 selectArch("mips64r6"); 5360 getTargetStreamer().emitDirectiveSetMips64R6(); 5361 break; 5362 } 5363 return false; 5364 } 5365 5366 bool MipsAsmParser::eatComma(StringRef ErrorStr) { 5367 MCAsmParser &Parser = getParser(); 5368 if (getLexer().isNot(AsmToken::Comma)) { 5369 SMLoc Loc = getLexer().getLoc(); 5370 Parser.eatToEndOfStatement(); 5371 return Error(Loc, ErrorStr); 5372 } 5373 5374 Parser.Lex(); // Eat the comma. 5375 return true; 5376 } 5377 5378 // Used to determine if .cpload, .cprestore, and .cpsetup have any effect. 5379 // In this class, it is only used for .cprestore. 5380 // FIXME: Only keep track of IsPicEnabled in one place, instead of in both 5381 // MipsTargetELFStreamer and MipsAsmParser. 5382 bool MipsAsmParser::isPicAndNotNxxAbi() { 5383 return inPicMode() && !(isABI_N32() || isABI_N64()); 5384 } 5385 5386 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) { 5387 if (AssemblerOptions.back()->isReorder()) 5388 Warning(Loc, ".cpload should be inside a noreorder section"); 5389 5390 if (inMips16Mode()) { 5391 reportParseError(".cpload is not supported in Mips16 mode"); 5392 return false; 5393 } 5394 5395 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg; 5396 OperandMatchResultTy ResTy = parseAnyRegister(Reg); 5397 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) { 5398 reportParseError("expected register containing function address"); 5399 return false; 5400 } 5401 5402 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]); 5403 if (!RegOpnd.isGPRAsmReg()) { 5404 reportParseError(RegOpnd.getStartLoc(), "invalid register"); 5405 return false; 5406 } 5407 5408 // If this is not the end of the statement, report an error. 5409 if (getLexer().isNot(AsmToken::EndOfStatement)) { 5410 reportParseError("unexpected token, expected end of statement"); 5411 return false; 5412 } 5413 5414 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg()); 5415 return false; 5416 } 5417 5418 bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) { 5419 MCAsmParser &Parser = getParser(); 5420 5421 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it 5422 // is used in non-PIC mode. 5423 5424 if (inMips16Mode()) { 5425 reportParseError(".cprestore is not supported in Mips16 mode"); 5426 return false; 5427 } 5428 5429 // Get the stack offset value. 5430 const MCExpr *StackOffset; 5431 int64_t StackOffsetVal; 5432 if (Parser.parseExpression(StackOffset)) { 5433 reportParseError("expected stack offset value"); 5434 return false; 5435 } 5436 5437 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) { 5438 reportParseError("stack offset is not an absolute expression"); 5439 return false; 5440 } 5441 5442 if (StackOffsetVal < 0) { 5443 Warning(Loc, ".cprestore with negative stack offset has no effect"); 5444 IsCpRestoreSet = false; 5445 } else { 5446 IsCpRestoreSet = true; 5447 CpRestoreOffset = StackOffsetVal; 5448 } 5449 5450 // If this is not the end of the statement, report an error. 5451 if (getLexer().isNot(AsmToken::EndOfStatement)) { 5452 reportParseError("unexpected token, expected end of statement"); 5453 return false; 5454 } 5455 5456 if (!getTargetStreamer().emitDirectiveCpRestore( 5457 CpRestoreOffset, [&]() { return getATReg(Loc); }, Loc, STI)) 5458 return true; 5459 Parser.Lex(); // Consume the EndOfStatement. 5460 return false; 5461 } 5462 5463 bool MipsAsmParser::parseDirectiveCPSetup() { 5464 MCAsmParser &Parser = getParser(); 5465 unsigned FuncReg; 5466 unsigned Save; 5467 bool SaveIsReg = true; 5468 5469 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg; 5470 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg); 5471 if (ResTy == MatchOperand_NoMatch) { 5472 reportParseError("expected register containing function address"); 5473 return false; 5474 } 5475 5476 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]); 5477 if (!FuncRegOpnd.isGPRAsmReg()) { 5478 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register"); 5479 Parser.eatToEndOfStatement(); 5480 return false; 5481 } 5482 5483 FuncReg = FuncRegOpnd.getGPR32Reg(); 5484 TmpReg.clear(); 5485 5486 if (!eatComma("unexpected token, expected comma")) 5487 return true; 5488 5489 ResTy = parseAnyRegister(TmpReg); 5490 if (ResTy == MatchOperand_NoMatch) { 5491 const MCExpr *OffsetExpr; 5492 int64_t OffsetVal; 5493 SMLoc ExprLoc = getLexer().getLoc(); 5494 5495 if (Parser.parseExpression(OffsetExpr) || 5496 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) { 5497 reportParseError(ExprLoc, "expected save register or stack offset"); 5498 Parser.eatToEndOfStatement(); 5499 return false; 5500 } 5501 5502 Save = OffsetVal; 5503 SaveIsReg = false; 5504 } else { 5505 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]); 5506 if (!SaveOpnd.isGPRAsmReg()) { 5507 reportParseError(SaveOpnd.getStartLoc(), "invalid register"); 5508 Parser.eatToEndOfStatement(); 5509 return false; 5510 } 5511 Save = SaveOpnd.getGPR32Reg(); 5512 } 5513 5514 if (!eatComma("unexpected token, expected comma")) 5515 return true; 5516 5517 const MCExpr *Expr; 5518 if (Parser.parseExpression(Expr)) { 5519 reportParseError("expected expression"); 5520 return false; 5521 } 5522 5523 if (Expr->getKind() != MCExpr::SymbolRef) { 5524 reportParseError("expected symbol"); 5525 return false; 5526 } 5527 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr); 5528 5529 CpSaveLocation = Save; 5530 CpSaveLocationIsRegister = SaveIsReg; 5531 5532 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(), 5533 SaveIsReg); 5534 return false; 5535 } 5536 5537 bool MipsAsmParser::parseDirectiveCPReturn() { 5538 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation, 5539 CpSaveLocationIsRegister); 5540 return false; 5541 } 5542 5543 bool MipsAsmParser::parseDirectiveNaN() { 5544 MCAsmParser &Parser = getParser(); 5545 if (getLexer().isNot(AsmToken::EndOfStatement)) { 5546 const AsmToken &Tok = Parser.getTok(); 5547 5548 if (Tok.getString() == "2008") { 5549 Parser.Lex(); 5550 getTargetStreamer().emitDirectiveNaN2008(); 5551 return false; 5552 } else if (Tok.getString() == "legacy") { 5553 Parser.Lex(); 5554 getTargetStreamer().emitDirectiveNaNLegacy(); 5555 return false; 5556 } 5557 } 5558 // If we don't recognize the option passed to the .nan 5559 // directive (e.g. no option or unknown option), emit an error. 5560 reportParseError("invalid option in .nan directive"); 5561 return false; 5562 } 5563 5564 bool MipsAsmParser::parseDirectiveSet() { 5565 MCAsmParser &Parser = getParser(); 5566 // Get the next token. 5567 const AsmToken &Tok = Parser.getTok(); 5568 5569 if (Tok.getString() == "noat") { 5570 return parseSetNoAtDirective(); 5571 } else if (Tok.getString() == "at") { 5572 return parseSetAtDirective(); 5573 } else if (Tok.getString() == "arch") { 5574 return parseSetArchDirective(); 5575 } else if (Tok.getString() == "fp") { 5576 return parseSetFpDirective(); 5577 } else if (Tok.getString() == "oddspreg") { 5578 return parseSetOddSPRegDirective(); 5579 } else if (Tok.getString() == "nooddspreg") { 5580 return parseSetNoOddSPRegDirective(); 5581 } else if (Tok.getString() == "pop") { 5582 return parseSetPopDirective(); 5583 } else if (Tok.getString() == "push") { 5584 return parseSetPushDirective(); 5585 } else if (Tok.getString() == "reorder") { 5586 return parseSetReorderDirective(); 5587 } else if (Tok.getString() == "noreorder") { 5588 return parseSetNoReorderDirective(); 5589 } else if (Tok.getString() == "macro") { 5590 return parseSetMacroDirective(); 5591 } else if (Tok.getString() == "nomacro") { 5592 return parseSetNoMacroDirective(); 5593 } else if (Tok.getString() == "mips16") { 5594 return parseSetMips16Directive(); 5595 } else if (Tok.getString() == "nomips16") { 5596 return parseSetNoMips16Directive(); 5597 } else if (Tok.getString() == "nomicromips") { 5598 clearFeatureBits(Mips::FeatureMicroMips, "micromips"); 5599 getTargetStreamer().emitDirectiveSetNoMicroMips(); 5600 Parser.eatToEndOfStatement(); 5601 return false; 5602 } else if (Tok.getString() == "micromips") { 5603 return parseSetFeature(Mips::FeatureMicroMips); 5604 } else if (Tok.getString() == "mips0") { 5605 return parseSetMips0Directive(); 5606 } else if (Tok.getString() == "mips1") { 5607 return parseSetFeature(Mips::FeatureMips1); 5608 } else if (Tok.getString() == "mips2") { 5609 return parseSetFeature(Mips::FeatureMips2); 5610 } else if (Tok.getString() == "mips3") { 5611 return parseSetFeature(Mips::FeatureMips3); 5612 } else if (Tok.getString() == "mips4") { 5613 return parseSetFeature(Mips::FeatureMips4); 5614 } else if (Tok.getString() == "mips5") { 5615 return parseSetFeature(Mips::FeatureMips5); 5616 } else if (Tok.getString() == "mips32") { 5617 return parseSetFeature(Mips::FeatureMips32); 5618 } else if (Tok.getString() == "mips32r2") { 5619 return parseSetFeature(Mips::FeatureMips32r2); 5620 } else if (Tok.getString() == "mips32r3") { 5621 return parseSetFeature(Mips::FeatureMips32r3); 5622 } else if (Tok.getString() == "mips32r5") { 5623 return parseSetFeature(Mips::FeatureMips32r5); 5624 } else if (Tok.getString() == "mips32r6") { 5625 return parseSetFeature(Mips::FeatureMips32r6); 5626 } else if (Tok.getString() == "mips64") { 5627 return parseSetFeature(Mips::FeatureMips64); 5628 } else if (Tok.getString() == "mips64r2") { 5629 return parseSetFeature(Mips::FeatureMips64r2); 5630 } else if (Tok.getString() == "mips64r3") { 5631 return parseSetFeature(Mips::FeatureMips64r3); 5632 } else if (Tok.getString() == "mips64r5") { 5633 return parseSetFeature(Mips::FeatureMips64r5); 5634 } else if (Tok.getString() == "mips64r6") { 5635 return parseSetFeature(Mips::FeatureMips64r6); 5636 } else if (Tok.getString() == "dsp") { 5637 return parseSetFeature(Mips::FeatureDSP); 5638 } else if (Tok.getString() == "nodsp") { 5639 return parseSetNoDspDirective(); 5640 } else if (Tok.getString() == "msa") { 5641 return parseSetMsaDirective(); 5642 } else if (Tok.getString() == "nomsa") { 5643 return parseSetNoMsaDirective(); 5644 } else if (Tok.getString() == "softfloat") { 5645 return parseSetSoftFloatDirective(); 5646 } else if (Tok.getString() == "hardfloat") { 5647 return parseSetHardFloatDirective(); 5648 } else { 5649 // It is just an identifier, look for an assignment. 5650 parseSetAssignment(); 5651 return false; 5652 } 5653 5654 return true; 5655 } 5656 5657 /// parseDataDirective 5658 /// ::= .word [ expression (, expression)* ] 5659 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) { 5660 MCAsmParser &Parser = getParser(); 5661 if (getLexer().isNot(AsmToken::EndOfStatement)) { 5662 for (;;) { 5663 const MCExpr *Value; 5664 if (getParser().parseExpression(Value)) 5665 return true; 5666 5667 getParser().getStreamer().EmitValue(Value, Size); 5668 5669 if (getLexer().is(AsmToken::EndOfStatement)) 5670 break; 5671 5672 if (getLexer().isNot(AsmToken::Comma)) 5673 return Error(L, "unexpected token, expected comma"); 5674 Parser.Lex(); 5675 } 5676 } 5677 5678 Parser.Lex(); 5679 return false; 5680 } 5681 5682 /// parseDirectiveGpWord 5683 /// ::= .gpword local_sym 5684 bool MipsAsmParser::parseDirectiveGpWord() { 5685 MCAsmParser &Parser = getParser(); 5686 const MCExpr *Value; 5687 // EmitGPRel32Value requires an expression, so we are using base class 5688 // method to evaluate the expression. 5689 if (getParser().parseExpression(Value)) 5690 return true; 5691 getParser().getStreamer().EmitGPRel32Value(Value); 5692 5693 if (getLexer().isNot(AsmToken::EndOfStatement)) 5694 return Error(getLexer().getLoc(), 5695 "unexpected token, expected end of statement"); 5696 Parser.Lex(); // Eat EndOfStatement token. 5697 return false; 5698 } 5699 5700 /// parseDirectiveGpDWord 5701 /// ::= .gpdword local_sym 5702 bool MipsAsmParser::parseDirectiveGpDWord() { 5703 MCAsmParser &Parser = getParser(); 5704 const MCExpr *Value; 5705 // EmitGPRel64Value requires an expression, so we are using base class 5706 // method to evaluate the expression. 5707 if (getParser().parseExpression(Value)) 5708 return true; 5709 getParser().getStreamer().EmitGPRel64Value(Value); 5710 5711 if (getLexer().isNot(AsmToken::EndOfStatement)) 5712 return Error(getLexer().getLoc(), 5713 "unexpected token, expected end of statement"); 5714 Parser.Lex(); // Eat EndOfStatement token. 5715 return false; 5716 } 5717 5718 bool MipsAsmParser::parseDirectiveOption() { 5719 MCAsmParser &Parser = getParser(); 5720 // Get the option token. 5721 AsmToken Tok = Parser.getTok(); 5722 // At the moment only identifiers are supported. 5723 if (Tok.isNot(AsmToken::Identifier)) { 5724 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier"); 5725 Parser.eatToEndOfStatement(); 5726 return false; 5727 } 5728 5729 StringRef Option = Tok.getIdentifier(); 5730 5731 if (Option == "pic0") { 5732 // MipsAsmParser needs to know if the current PIC mode changes. 5733 IsPicEnabled = false; 5734 5735 getTargetStreamer().emitDirectiveOptionPic0(); 5736 Parser.Lex(); 5737 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) { 5738 Error(Parser.getTok().getLoc(), 5739 "unexpected token, expected end of statement"); 5740 Parser.eatToEndOfStatement(); 5741 } 5742 return false; 5743 } 5744 5745 if (Option == "pic2") { 5746 // MipsAsmParser needs to know if the current PIC mode changes. 5747 IsPicEnabled = true; 5748 5749 getTargetStreamer().emitDirectiveOptionPic2(); 5750 Parser.Lex(); 5751 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) { 5752 Error(Parser.getTok().getLoc(), 5753 "unexpected token, expected end of statement"); 5754 Parser.eatToEndOfStatement(); 5755 } 5756 return false; 5757 } 5758 5759 // Unknown option. 5760 Warning(Parser.getTok().getLoc(), 5761 "unknown option, expected 'pic0' or 'pic2'"); 5762 Parser.eatToEndOfStatement(); 5763 return false; 5764 } 5765 5766 /// parseInsnDirective 5767 /// ::= .insn 5768 bool MipsAsmParser::parseInsnDirective() { 5769 // If this is not the end of the statement, report an error. 5770 if (getLexer().isNot(AsmToken::EndOfStatement)) { 5771 reportParseError("unexpected token, expected end of statement"); 5772 return false; 5773 } 5774 5775 // The actual label marking happens in 5776 // MipsELFStreamer::createPendingLabelRelocs(). 5777 getTargetStreamer().emitDirectiveInsn(); 5778 5779 getParser().Lex(); // Eat EndOfStatement token. 5780 return false; 5781 } 5782 5783 /// parseSSectionDirective 5784 /// ::= .sbss 5785 /// ::= .sdata 5786 bool MipsAsmParser::parseSSectionDirective(StringRef Section, unsigned Type) { 5787 // If this is not the end of the statement, report an error. 5788 if (getLexer().isNot(AsmToken::EndOfStatement)) { 5789 reportParseError("unexpected token, expected end of statement"); 5790 return false; 5791 } 5792 5793 MCSection *ELFSection = getContext().getELFSection( 5794 Section, Type, ELF::SHF_WRITE | ELF::SHF_ALLOC | ELF::SHF_MIPS_GPREL); 5795 getParser().getStreamer().SwitchSection(ELFSection); 5796 5797 getParser().Lex(); // Eat EndOfStatement token. 5798 return false; 5799 } 5800 5801 /// parseDirectiveModule 5802 /// ::= .module oddspreg 5803 /// ::= .module nooddspreg 5804 /// ::= .module fp=value 5805 /// ::= .module softfloat 5806 /// ::= .module hardfloat 5807 bool MipsAsmParser::parseDirectiveModule() { 5808 MCAsmParser &Parser = getParser(); 5809 MCAsmLexer &Lexer = getLexer(); 5810 SMLoc L = Lexer.getLoc(); 5811 5812 if (!getTargetStreamer().isModuleDirectiveAllowed()) { 5813 // TODO : get a better message. 5814 reportParseError(".module directive must appear before any code"); 5815 return false; 5816 } 5817 5818 StringRef Option; 5819 if (Parser.parseIdentifier(Option)) { 5820 reportParseError("expected .module option identifier"); 5821 return false; 5822 } 5823 5824 if (Option == "oddspreg") { 5825 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg"); 5826 5827 // Synchronize the abiflags information with the FeatureBits information we 5828 // changed above. 5829 getTargetStreamer().updateABIInfo(*this); 5830 5831 // If printing assembly, use the recently updated abiflags information. 5832 // If generating ELF, don't do anything (the .MIPS.abiflags section gets 5833 // emitted at the end). 5834 getTargetStreamer().emitDirectiveModuleOddSPReg(); 5835 5836 // If this is not the end of the statement, report an error. 5837 if (getLexer().isNot(AsmToken::EndOfStatement)) { 5838 reportParseError("unexpected token, expected end of statement"); 5839 return false; 5840 } 5841 5842 return false; // parseDirectiveModule has finished successfully. 5843 } else if (Option == "nooddspreg") { 5844 if (!isABI_O32()) { 5845 Error(L, "'.module nooddspreg' requires the O32 ABI"); 5846 return false; 5847 } 5848 5849 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg"); 5850 5851 // Synchronize the abiflags information with the FeatureBits information we 5852 // changed above. 5853 getTargetStreamer().updateABIInfo(*this); 5854 5855 // If printing assembly, use the recently updated abiflags information. 5856 // If generating ELF, don't do anything (the .MIPS.abiflags section gets 5857 // emitted at the end). 5858 getTargetStreamer().emitDirectiveModuleOddSPReg(); 5859 5860 // If this is not the end of the statement, report an error. 5861 if (getLexer().isNot(AsmToken::EndOfStatement)) { 5862 reportParseError("unexpected token, expected end of statement"); 5863 return false; 5864 } 5865 5866 return false; // parseDirectiveModule has finished successfully. 5867 } else if (Option == "fp") { 5868 return parseDirectiveModuleFP(); 5869 } else if (Option == "softfloat") { 5870 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float"); 5871 5872 // Synchronize the ABI Flags information with the FeatureBits information we 5873 // updated above. 5874 getTargetStreamer().updateABIInfo(*this); 5875 5876 // If printing assembly, use the recently updated ABI Flags information. 5877 // If generating ELF, don't do anything (the .MIPS.abiflags section gets 5878 // emitted later). 5879 getTargetStreamer().emitDirectiveModuleSoftFloat(); 5880 5881 // If this is not the end of the statement, report an error. 5882 if (getLexer().isNot(AsmToken::EndOfStatement)) { 5883 reportParseError("unexpected token, expected end of statement"); 5884 return false; 5885 } 5886 5887 return false; // parseDirectiveModule has finished successfully. 5888 } else if (Option == "hardfloat") { 5889 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float"); 5890 5891 // Synchronize the ABI Flags information with the FeatureBits information we 5892 // updated above. 5893 getTargetStreamer().updateABIInfo(*this); 5894 5895 // If printing assembly, use the recently updated ABI Flags information. 5896 // If generating ELF, don't do anything (the .MIPS.abiflags section gets 5897 // emitted later). 5898 getTargetStreamer().emitDirectiveModuleHardFloat(); 5899 5900 // If this is not the end of the statement, report an error. 5901 if (getLexer().isNot(AsmToken::EndOfStatement)) { 5902 reportParseError("unexpected token, expected end of statement"); 5903 return false; 5904 } 5905 5906 return false; // parseDirectiveModule has finished successfully. 5907 } else { 5908 return Error(L, "'" + Twine(Option) + "' is not a valid .module option."); 5909 } 5910 } 5911 5912 /// parseDirectiveModuleFP 5913 /// ::= =32 5914 /// ::= =xx 5915 /// ::= =64 5916 bool MipsAsmParser::parseDirectiveModuleFP() { 5917 MCAsmParser &Parser = getParser(); 5918 MCAsmLexer &Lexer = getLexer(); 5919 5920 if (Lexer.isNot(AsmToken::Equal)) { 5921 reportParseError("unexpected token, expected equals sign '='"); 5922 return false; 5923 } 5924 Parser.Lex(); // Eat '=' token. 5925 5926 MipsABIFlagsSection::FpABIKind FpABI; 5927 if (!parseFpABIValue(FpABI, ".module")) 5928 return false; 5929 5930 if (getLexer().isNot(AsmToken::EndOfStatement)) { 5931 reportParseError("unexpected token, expected end of statement"); 5932 return false; 5933 } 5934 5935 // Synchronize the abiflags information with the FeatureBits information we 5936 // changed above. 5937 getTargetStreamer().updateABIInfo(*this); 5938 5939 // If printing assembly, use the recently updated abiflags information. 5940 // If generating ELF, don't do anything (the .MIPS.abiflags section gets 5941 // emitted at the end). 5942 getTargetStreamer().emitDirectiveModuleFP(); 5943 5944 Parser.Lex(); // Consume the EndOfStatement. 5945 return false; 5946 } 5947 5948 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI, 5949 StringRef Directive) { 5950 MCAsmParser &Parser = getParser(); 5951 MCAsmLexer &Lexer = getLexer(); 5952 bool ModuleLevelOptions = Directive == ".module"; 5953 5954 if (Lexer.is(AsmToken::Identifier)) { 5955 StringRef Value = Parser.getTok().getString(); 5956 Parser.Lex(); 5957 5958 if (Value != "xx") { 5959 reportParseError("unsupported value, expected 'xx', '32' or '64'"); 5960 return false; 5961 } 5962 5963 if (!isABI_O32()) { 5964 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI"); 5965 return false; 5966 } 5967 5968 FpABI = MipsABIFlagsSection::FpABIKind::XX; 5969 if (ModuleLevelOptions) { 5970 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx"); 5971 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64"); 5972 } else { 5973 setFeatureBits(Mips::FeatureFPXX, "fpxx"); 5974 clearFeatureBits(Mips::FeatureFP64Bit, "fp64"); 5975 } 5976 return true; 5977 } 5978 5979 if (Lexer.is(AsmToken::Integer)) { 5980 unsigned Value = Parser.getTok().getIntVal(); 5981 Parser.Lex(); 5982 5983 if (Value != 32 && Value != 64) { 5984 reportParseError("unsupported value, expected 'xx', '32' or '64'"); 5985 return false; 5986 } 5987 5988 if (Value == 32) { 5989 if (!isABI_O32()) { 5990 reportParseError("'" + Directive + " fp=32' requires the O32 ABI"); 5991 return false; 5992 } 5993 5994 FpABI = MipsABIFlagsSection::FpABIKind::S32; 5995 if (ModuleLevelOptions) { 5996 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx"); 5997 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64"); 5998 } else { 5999 clearFeatureBits(Mips::FeatureFPXX, "fpxx"); 6000 clearFeatureBits(Mips::FeatureFP64Bit, "fp64"); 6001 } 6002 } else { 6003 FpABI = MipsABIFlagsSection::FpABIKind::S64; 6004 if (ModuleLevelOptions) { 6005 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx"); 6006 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64"); 6007 } else { 6008 clearFeatureBits(Mips::FeatureFPXX, "fpxx"); 6009 setFeatureBits(Mips::FeatureFP64Bit, "fp64"); 6010 } 6011 } 6012 6013 return true; 6014 } 6015 6016 return false; 6017 } 6018 6019 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) { 6020 // This returns false if this function recognizes the directive 6021 // regardless of whether it is successfully handles or reports an 6022 // error. Otherwise it returns true to give the generic parser a 6023 // chance at recognizing it. 6024 6025 MCAsmParser &Parser = getParser(); 6026 StringRef IDVal = DirectiveID.getString(); 6027 6028 if (IDVal == ".cpload") { 6029 parseDirectiveCpLoad(DirectiveID.getLoc()); 6030 return false; 6031 } 6032 if (IDVal == ".cprestore") { 6033 parseDirectiveCpRestore(DirectiveID.getLoc()); 6034 return false; 6035 } 6036 if (IDVal == ".dword") { 6037 parseDataDirective(8, DirectiveID.getLoc()); 6038 return false; 6039 } 6040 if (IDVal == ".ent") { 6041 StringRef SymbolName; 6042 6043 if (Parser.parseIdentifier(SymbolName)) { 6044 reportParseError("expected identifier after .ent"); 6045 return false; 6046 } 6047 6048 // There's an undocumented extension that allows an integer to 6049 // follow the name of the procedure which AFAICS is ignored by GAS. 6050 // Example: .ent foo,2 6051 if (getLexer().isNot(AsmToken::EndOfStatement)) { 6052 if (getLexer().isNot(AsmToken::Comma)) { 6053 // Even though we accept this undocumented extension for compatibility 6054 // reasons, the additional integer argument does not actually change 6055 // the behaviour of the '.ent' directive, so we would like to discourage 6056 // its use. We do this by not referring to the extended version in 6057 // error messages which are not directly related to its use. 6058 reportParseError("unexpected token, expected end of statement"); 6059 return false; 6060 } 6061 Parser.Lex(); // Eat the comma. 6062 const MCExpr *DummyNumber; 6063 int64_t DummyNumberVal; 6064 // If the user was explicitly trying to use the extended version, 6065 // we still give helpful extension-related error messages. 6066 if (Parser.parseExpression(DummyNumber)) { 6067 reportParseError("expected number after comma"); 6068 return false; 6069 } 6070 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) { 6071 reportParseError("expected an absolute expression after comma"); 6072 return false; 6073 } 6074 } 6075 6076 // If this is not the end of the statement, report an error. 6077 if (getLexer().isNot(AsmToken::EndOfStatement)) { 6078 reportParseError("unexpected token, expected end of statement"); 6079 return false; 6080 } 6081 6082 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName); 6083 6084 getTargetStreamer().emitDirectiveEnt(*Sym); 6085 CurrentFn = Sym; 6086 IsCpRestoreSet = false; 6087 return false; 6088 } 6089 6090 if (IDVal == ".end") { 6091 StringRef SymbolName; 6092 6093 if (Parser.parseIdentifier(SymbolName)) { 6094 reportParseError("expected identifier after .end"); 6095 return false; 6096 } 6097 6098 if (getLexer().isNot(AsmToken::EndOfStatement)) { 6099 reportParseError("unexpected token, expected end of statement"); 6100 return false; 6101 } 6102 6103 if (CurrentFn == nullptr) { 6104 reportParseError(".end used without .ent"); 6105 return false; 6106 } 6107 6108 if ((SymbolName != CurrentFn->getName())) { 6109 reportParseError(".end symbol does not match .ent symbol"); 6110 return false; 6111 } 6112 6113 getTargetStreamer().emitDirectiveEnd(SymbolName); 6114 CurrentFn = nullptr; 6115 IsCpRestoreSet = false; 6116 return false; 6117 } 6118 6119 if (IDVal == ".frame") { 6120 // .frame $stack_reg, frame_size_in_bytes, $return_reg 6121 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg; 6122 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg); 6123 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) { 6124 reportParseError("expected stack register"); 6125 return false; 6126 } 6127 6128 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]); 6129 if (!StackRegOpnd.isGPRAsmReg()) { 6130 reportParseError(StackRegOpnd.getStartLoc(), 6131 "expected general purpose register"); 6132 return false; 6133 } 6134 unsigned StackReg = StackRegOpnd.getGPR32Reg(); 6135 6136 if (Parser.getTok().is(AsmToken::Comma)) 6137 Parser.Lex(); 6138 else { 6139 reportParseError("unexpected token, expected comma"); 6140 return false; 6141 } 6142 6143 // Parse the frame size. 6144 const MCExpr *FrameSize; 6145 int64_t FrameSizeVal; 6146 6147 if (Parser.parseExpression(FrameSize)) { 6148 reportParseError("expected frame size value"); 6149 return false; 6150 } 6151 6152 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) { 6153 reportParseError("frame size not an absolute expression"); 6154 return false; 6155 } 6156 6157 if (Parser.getTok().is(AsmToken::Comma)) 6158 Parser.Lex(); 6159 else { 6160 reportParseError("unexpected token, expected comma"); 6161 return false; 6162 } 6163 6164 // Parse the return register. 6165 TmpReg.clear(); 6166 ResTy = parseAnyRegister(TmpReg); 6167 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) { 6168 reportParseError("expected return register"); 6169 return false; 6170 } 6171 6172 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]); 6173 if (!ReturnRegOpnd.isGPRAsmReg()) { 6174 reportParseError(ReturnRegOpnd.getStartLoc(), 6175 "expected general purpose register"); 6176 return false; 6177 } 6178 6179 // If this is not the end of the statement, report an error. 6180 if (getLexer().isNot(AsmToken::EndOfStatement)) { 6181 reportParseError("unexpected token, expected end of statement"); 6182 return false; 6183 } 6184 6185 getTargetStreamer().emitFrame(StackReg, FrameSizeVal, 6186 ReturnRegOpnd.getGPR32Reg()); 6187 IsCpRestoreSet = false; 6188 return false; 6189 } 6190 6191 if (IDVal == ".set") { 6192 parseDirectiveSet(); 6193 return false; 6194 } 6195 6196 if (IDVal == ".mask" || IDVal == ".fmask") { 6197 // .mask bitmask, frame_offset 6198 // bitmask: One bit for each register used. 6199 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where 6200 // first register is expected to be saved. 6201 // Examples: 6202 // .mask 0x80000000, -4 6203 // .fmask 0x80000000, -4 6204 // 6205 6206 // Parse the bitmask 6207 const MCExpr *BitMask; 6208 int64_t BitMaskVal; 6209 6210 if (Parser.parseExpression(BitMask)) { 6211 reportParseError("expected bitmask value"); 6212 return false; 6213 } 6214 6215 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) { 6216 reportParseError("bitmask not an absolute expression"); 6217 return false; 6218 } 6219 6220 if (Parser.getTok().is(AsmToken::Comma)) 6221 Parser.Lex(); 6222 else { 6223 reportParseError("unexpected token, expected comma"); 6224 return false; 6225 } 6226 6227 // Parse the frame_offset 6228 const MCExpr *FrameOffset; 6229 int64_t FrameOffsetVal; 6230 6231 if (Parser.parseExpression(FrameOffset)) { 6232 reportParseError("expected frame offset value"); 6233 return false; 6234 } 6235 6236 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) { 6237 reportParseError("frame offset not an absolute expression"); 6238 return false; 6239 } 6240 6241 // If this is not the end of the statement, report an error. 6242 if (getLexer().isNot(AsmToken::EndOfStatement)) { 6243 reportParseError("unexpected token, expected end of statement"); 6244 return false; 6245 } 6246 6247 if (IDVal == ".mask") 6248 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal); 6249 else 6250 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal); 6251 return false; 6252 } 6253 6254 if (IDVal == ".nan") 6255 return parseDirectiveNaN(); 6256 6257 if (IDVal == ".gpword") { 6258 parseDirectiveGpWord(); 6259 return false; 6260 } 6261 6262 if (IDVal == ".gpdword") { 6263 parseDirectiveGpDWord(); 6264 return false; 6265 } 6266 6267 if (IDVal == ".word") { 6268 parseDataDirective(4, DirectiveID.getLoc()); 6269 return false; 6270 } 6271 6272 if (IDVal == ".hword") { 6273 parseDataDirective(2, DirectiveID.getLoc()); 6274 return false; 6275 } 6276 6277 if (IDVal == ".option") { 6278 parseDirectiveOption(); 6279 return false; 6280 } 6281 6282 if (IDVal == ".abicalls") { 6283 getTargetStreamer().emitDirectiveAbiCalls(); 6284 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) { 6285 Error(Parser.getTok().getLoc(), 6286 "unexpected token, expected end of statement"); 6287 // Clear line 6288 Parser.eatToEndOfStatement(); 6289 } 6290 return false; 6291 } 6292 6293 if (IDVal == ".cpsetup") { 6294 parseDirectiveCPSetup(); 6295 return false; 6296 } 6297 if (IDVal == ".cpreturn") { 6298 parseDirectiveCPReturn(); 6299 return false; 6300 } 6301 if (IDVal == ".module") { 6302 parseDirectiveModule(); 6303 return false; 6304 } 6305 if (IDVal == ".llvm_internal_mips_reallow_module_directive") { 6306 parseInternalDirectiveReallowModule(); 6307 return false; 6308 } 6309 if (IDVal == ".insn") { 6310 parseInsnDirective(); 6311 return false; 6312 } 6313 if (IDVal == ".sbss") { 6314 parseSSectionDirective(IDVal, ELF::SHT_NOBITS); 6315 return false; 6316 } 6317 if (IDVal == ".sdata") { 6318 parseSSectionDirective(IDVal, ELF::SHT_PROGBITS); 6319 return false; 6320 } 6321 6322 return true; 6323 } 6324 6325 bool MipsAsmParser::parseInternalDirectiveReallowModule() { 6326 // If this is not the end of the statement, report an error. 6327 if (getLexer().isNot(AsmToken::EndOfStatement)) { 6328 reportParseError("unexpected token, expected end of statement"); 6329 return false; 6330 } 6331 6332 getTargetStreamer().reallowModuleDirective(); 6333 6334 getParser().Lex(); // Eat EndOfStatement token. 6335 return false; 6336 } 6337 6338 extern "C" void LLVMInitializeMipsAsmParser() { 6339 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget); 6340 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget); 6341 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target); 6342 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget); 6343 } 6344 6345 #define GET_REGISTER_MATCHER 6346 #define GET_MATCHER_IMPLEMENTATION 6347 #include "MipsGenAsmMatcher.inc" 6348