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