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