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