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