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