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 bool UseSrcReg = SrcReg != Mips::NoRegister; 2380 warnIfNoMacro(IDLoc); 2381 2382 if (inPicMode() && ABI.IsO32()) { 2383 MCValue Res; 2384 if (!SymExpr->evaluateAsRelocatable(Res, nullptr, nullptr)) { 2385 Error(IDLoc, "expected relocatable expression"); 2386 return true; 2387 } 2388 if (Res.getSymB() != nullptr) { 2389 Error(IDLoc, "expected relocatable expression with only one symbol"); 2390 return true; 2391 } 2392 2393 // The case where the result register is $25 is somewhat special. If the 2394 // symbol in the final relocation is external and not modified with a 2395 // constant then we must use R_MIPS_CALL16 instead of R_MIPS_GOT16. 2396 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg && 2397 Res.getConstant() == 0 && !Res.getSymA()->getSymbol().isInSection() && 2398 !Res.getSymA()->getSymbol().isTemporary()) { 2399 const MCExpr *CallExpr = 2400 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, SymExpr, getContext()); 2401 TOut.emitRRX(Mips::LW, DstReg, ABI.GetGlobalPtr(), 2402 MCOperand::createExpr(CallExpr), IDLoc, STI); 2403 return false; 2404 } 2405 2406 // The remaining cases are: 2407 // External GOT: lw $tmp, %got(symbol+offset)($gp) 2408 // >addiu $tmp, $tmp, %lo(offset) 2409 // >addiu $rd, $tmp, $rs 2410 // Local GOT: lw $tmp, %got(symbol+offset)($gp) 2411 // addiu $tmp, $tmp, %lo(symbol+offset)($gp) 2412 // >addiu $rd, $tmp, $rs 2413 // The addiu's marked with a '>' may be omitted if they are redundant. If 2414 // this happens then the last instruction must use $rd as the result 2415 // register. 2416 const MipsMCExpr *GotExpr = 2417 MipsMCExpr::create(MipsMCExpr::MEK_GOT, SymExpr, getContext()); 2418 const MCExpr *LoExpr = nullptr; 2419 if (Res.getSymA()->getSymbol().isInSection() || 2420 Res.getSymA()->getSymbol().isTemporary()) 2421 LoExpr = MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext()); 2422 else if (Res.getConstant() != 0) { 2423 // External symbols fully resolve the symbol with just the %got(symbol) 2424 // but we must still account for any offset to the symbol for expressions 2425 // like symbol+8. 2426 LoExpr = MCConstantExpr::create(Res.getConstant(), getContext()); 2427 } 2428 2429 unsigned TmpReg = DstReg; 2430 if (UseSrcReg && 2431 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, 2432 SrcReg)) { 2433 // If $rs is the same as $rd, we need to use AT. 2434 // If it is not available we exit. 2435 unsigned ATReg = getATReg(IDLoc); 2436 if (!ATReg) 2437 return true; 2438 TmpReg = ATReg; 2439 } 2440 2441 TOut.emitRRX(Mips::LW, TmpReg, ABI.GetGlobalPtr(), 2442 MCOperand::createExpr(GotExpr), IDLoc, STI); 2443 2444 if (LoExpr) 2445 TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr), 2446 IDLoc, STI); 2447 2448 if (UseSrcReg) 2449 TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI); 2450 2451 return false; 2452 } 2453 2454 const MipsMCExpr *HiExpr = 2455 MipsMCExpr::create(MipsMCExpr::MEK_HI, SymExpr, getContext()); 2456 const MipsMCExpr *LoExpr = 2457 MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext()); 2458 2459 // This is the 64-bit symbol address expansion. 2460 if (ABI.ArePtrs64bit() && isGP64bit()) { 2461 // We always need AT for the 64-bit expansion. 2462 // If it is not available we exit. 2463 unsigned ATReg = getATReg(IDLoc); 2464 if (!ATReg) 2465 return true; 2466 2467 const MipsMCExpr *HighestExpr = 2468 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, SymExpr, getContext()); 2469 const MipsMCExpr *HigherExpr = 2470 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, SymExpr, getContext()); 2471 2472 if (UseSrcReg && 2473 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, 2474 SrcReg)) { 2475 // If $rs is the same as $rd: 2476 // (d)la $rd, sym($rd) => lui $at, %highest(sym) 2477 // daddiu $at, $at, %higher(sym) 2478 // dsll $at, $at, 16 2479 // daddiu $at, $at, %hi(sym) 2480 // dsll $at, $at, 16 2481 // daddiu $at, $at, %lo(sym) 2482 // daddu $rd, $at, $rd 2483 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc, 2484 STI); 2485 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, 2486 MCOperand::createExpr(HigherExpr), IDLoc, STI); 2487 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI); 2488 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr), 2489 IDLoc, STI); 2490 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI); 2491 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), 2492 IDLoc, STI); 2493 TOut.emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI); 2494 2495 return false; 2496 } 2497 2498 // Otherwise, if the $rs is different from $rd or if $rs isn't specified: 2499 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym) 2500 // lui $at, %hi(sym) 2501 // daddiu $rd, $rd, %higher(sym) 2502 // daddiu $at, $at, %lo(sym) 2503 // dsll32 $rd, $rd, 0 2504 // daddu $rd, $rd, $at 2505 // (daddu $rd, $rd, $rs) 2506 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc, 2507 STI); 2508 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI); 2509 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg, 2510 MCOperand::createExpr(HigherExpr), IDLoc, STI); 2511 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), 2512 IDLoc, STI); 2513 TOut.emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI); 2514 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI); 2515 if (UseSrcReg) 2516 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI); 2517 2518 return false; 2519 } 2520 2521 // And now, the 32-bit symbol address expansion: 2522 // If $rs is the same as $rd: 2523 // (d)la $rd, sym($rd) => lui $at, %hi(sym) 2524 // ori $at, $at, %lo(sym) 2525 // addu $rd, $at, $rd 2526 // Otherwise, if the $rs is different from $rd or if $rs isn't specified: 2527 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym) 2528 // ori $rd, $rd, %lo(sym) 2529 // (addu $rd, $rd, $rs) 2530 unsigned TmpReg = DstReg; 2531 if (UseSrcReg && 2532 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) { 2533 // If $rs is the same as $rd, we need to use AT. 2534 // If it is not available we exit. 2535 unsigned ATReg = getATReg(IDLoc); 2536 if (!ATReg) 2537 return true; 2538 TmpReg = ATReg; 2539 } 2540 2541 TOut.emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, STI); 2542 TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr), 2543 IDLoc, STI); 2544 2545 if (UseSrcReg) 2546 TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI); 2547 else 2548 assert( 2549 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg)); 2550 2551 return false; 2552 } 2553 2554 bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc, 2555 MCStreamer &Out, 2556 const MCSubtargetInfo *STI) { 2557 MipsTargetStreamer &TOut = getTargetStreamer(); 2558 2559 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 && 2560 "unexpected number of operands"); 2561 2562 MCOperand Offset = Inst.getOperand(0); 2563 if (Offset.isExpr()) { 2564 Inst.clear(); 2565 Inst.setOpcode(Mips::BEQ_MM); 2566 Inst.addOperand(MCOperand::createReg(Mips::ZERO)); 2567 Inst.addOperand(MCOperand::createReg(Mips::ZERO)); 2568 Inst.addOperand(MCOperand::createExpr(Offset.getExpr())); 2569 } else { 2570 assert(Offset.isImm() && "expected immediate operand kind"); 2571 if (isInt<11>(Offset.getImm())) { 2572 // If offset fits into 11 bits then this instruction becomes microMIPS 2573 // 16-bit unconditional branch instruction. 2574 if (inMicroMipsMode()) 2575 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM); 2576 } else { 2577 if (!isInt<17>(Offset.getImm())) 2578 Error(IDLoc, "branch target out of range"); 2579 if (OffsetToAlignment(Offset.getImm(), 1LL << 1)) 2580 Error(IDLoc, "branch to misaligned address"); 2581 Inst.clear(); 2582 Inst.setOpcode(Mips::BEQ_MM); 2583 Inst.addOperand(MCOperand::createReg(Mips::ZERO)); 2584 Inst.addOperand(MCOperand::createReg(Mips::ZERO)); 2585 Inst.addOperand(MCOperand::createImm(Offset.getImm())); 2586 } 2587 } 2588 Out.EmitInstruction(Inst, *STI); 2589 2590 // If .set reorder is active and branch instruction has a delay slot, 2591 // emit a NOP after it. 2592 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode()); 2593 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) 2594 TOut.emitEmptyDelaySlot(true, IDLoc, STI); 2595 2596 return false; 2597 } 2598 2599 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 2600 const MCSubtargetInfo *STI) { 2601 MipsTargetStreamer &TOut = getTargetStreamer(); 2602 const MCOperand &DstRegOp = Inst.getOperand(0); 2603 assert(DstRegOp.isReg() && "expected register operand kind"); 2604 2605 const MCOperand &ImmOp = Inst.getOperand(1); 2606 assert(ImmOp.isImm() && "expected immediate operand kind"); 2607 2608 const MCOperand &MemOffsetOp = Inst.getOperand(2); 2609 assert((MemOffsetOp.isImm() || MemOffsetOp.isExpr()) && 2610 "expected immediate or expression operand"); 2611 2612 unsigned OpCode = 0; 2613 switch(Inst.getOpcode()) { 2614 case Mips::BneImm: 2615 OpCode = Mips::BNE; 2616 break; 2617 case Mips::BeqImm: 2618 OpCode = Mips::BEQ; 2619 break; 2620 default: 2621 llvm_unreachable("Unknown immediate branch pseudo-instruction."); 2622 break; 2623 } 2624 2625 int64_t ImmValue = ImmOp.getImm(); 2626 if (ImmValue == 0) 2627 TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc, 2628 STI); 2629 else { 2630 warnIfNoMacro(IDLoc); 2631 2632 unsigned ATReg = getATReg(IDLoc); 2633 if (!ATReg) 2634 return true; 2635 2636 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true, 2637 IDLoc, Out, STI)) 2638 return true; 2639 2640 TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, STI); 2641 } 2642 return false; 2643 } 2644 2645 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 2646 const MCSubtargetInfo *STI, bool IsLoad, 2647 bool IsImmOpnd) { 2648 if (IsLoad) { 2649 expandLoadInst(Inst, IDLoc, Out, STI, IsImmOpnd); 2650 return; 2651 } 2652 expandStoreInst(Inst, IDLoc, Out, STI, IsImmOpnd); 2653 } 2654 2655 void MipsAsmParser::expandLoadInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 2656 const MCSubtargetInfo *STI, bool IsImmOpnd) { 2657 MipsTargetStreamer &TOut = getTargetStreamer(); 2658 2659 unsigned DstReg = Inst.getOperand(0).getReg(); 2660 unsigned BaseReg = Inst.getOperand(1).getReg(); 2661 2662 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode()); 2663 int16_t DstRegClass = Desc.OpInfo[0].RegClass; 2664 unsigned DstRegClassID = 2665 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID(); 2666 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) || 2667 (DstRegClassID == Mips::GPR64RegClassID); 2668 2669 if (IsImmOpnd) { 2670 // Try to use DstReg as the temporary. 2671 if (IsGPR && (BaseReg != DstReg)) { 2672 TOut.emitLoadWithImmOffset(Inst.getOpcode(), DstReg, BaseReg, 2673 Inst.getOperand(2).getImm(), DstReg, IDLoc, 2674 STI); 2675 return; 2676 } 2677 2678 // At this point we need AT to perform the expansions and we exit if it is 2679 // not available. 2680 unsigned ATReg = getATReg(IDLoc); 2681 if (!ATReg) 2682 return; 2683 2684 TOut.emitLoadWithImmOffset(Inst.getOpcode(), DstReg, BaseReg, 2685 Inst.getOperand(2).getImm(), ATReg, IDLoc, STI); 2686 return; 2687 } 2688 2689 const MCExpr *ExprOffset = Inst.getOperand(2).getExpr(); 2690 MCOperand LoOperand = MCOperand::createExpr( 2691 MipsMCExpr::create(MipsMCExpr::MEK_LO, ExprOffset, getContext())); 2692 MCOperand HiOperand = MCOperand::createExpr( 2693 MipsMCExpr::create(MipsMCExpr::MEK_HI, ExprOffset, getContext())); 2694 2695 // Try to use DstReg as the temporary. 2696 if (IsGPR && (BaseReg != DstReg)) { 2697 TOut.emitLoadWithSymOffset(Inst.getOpcode(), DstReg, BaseReg, HiOperand, 2698 LoOperand, DstReg, IDLoc, STI); 2699 return; 2700 } 2701 2702 // At this point we need AT to perform the expansions and we exit if it is 2703 // not available. 2704 unsigned ATReg = getATReg(IDLoc); 2705 if (!ATReg) 2706 return; 2707 2708 TOut.emitLoadWithSymOffset(Inst.getOpcode(), DstReg, BaseReg, HiOperand, 2709 LoOperand, ATReg, IDLoc, STI); 2710 } 2711 2712 void MipsAsmParser::expandStoreInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 2713 const MCSubtargetInfo *STI, 2714 bool IsImmOpnd) { 2715 MipsTargetStreamer &TOut = getTargetStreamer(); 2716 2717 unsigned SrcReg = Inst.getOperand(0).getReg(); 2718 unsigned BaseReg = Inst.getOperand(1).getReg(); 2719 2720 if (IsImmOpnd) { 2721 TOut.emitStoreWithImmOffset(Inst.getOpcode(), SrcReg, BaseReg, 2722 Inst.getOperand(2).getImm(), 2723 [&]() { return getATReg(IDLoc); }, IDLoc, STI); 2724 return; 2725 } 2726 2727 unsigned ATReg = getATReg(IDLoc); 2728 if (!ATReg) 2729 return; 2730 2731 const MCExpr *ExprOffset = Inst.getOperand(2).getExpr(); 2732 MCOperand LoOperand = MCOperand::createExpr( 2733 MipsMCExpr::create(MipsMCExpr::MEK_LO, ExprOffset, getContext())); 2734 MCOperand HiOperand = MCOperand::createExpr( 2735 MipsMCExpr::create(MipsMCExpr::MEK_HI, ExprOffset, getContext())); 2736 TOut.emitStoreWithSymOffset(Inst.getOpcode(), SrcReg, BaseReg, HiOperand, 2737 LoOperand, ATReg, IDLoc, STI); 2738 } 2739 2740 bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc, 2741 MCStreamer &Out, 2742 const MCSubtargetInfo *STI) { 2743 unsigned OpNum = Inst.getNumOperands(); 2744 unsigned Opcode = Inst.getOpcode(); 2745 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM; 2746 2747 assert (Inst.getOperand(OpNum - 1).isImm() && 2748 Inst.getOperand(OpNum - 2).isReg() && 2749 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand."); 2750 2751 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 && 2752 Inst.getOperand(OpNum - 1).getImm() >= 0 && 2753 (Inst.getOperand(OpNum - 2).getReg() == Mips::SP || 2754 Inst.getOperand(OpNum - 2).getReg() == Mips::SP_64) && 2755 (Inst.getOperand(OpNum - 3).getReg() == Mips::RA || 2756 Inst.getOperand(OpNum - 3).getReg() == Mips::RA_64)) { 2757 // It can be implemented as SWM16 or LWM16 instruction. 2758 if (inMicroMipsMode() && hasMips32r6()) 2759 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6; 2760 else 2761 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM; 2762 } 2763 2764 Inst.setOpcode(NewOpcode); 2765 Out.EmitInstruction(Inst, *STI); 2766 return false; 2767 } 2768 2769 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc, 2770 MCStreamer &Out, 2771 const MCSubtargetInfo *STI) { 2772 MipsTargetStreamer &TOut = getTargetStreamer(); 2773 bool EmittedNoMacroWarning = false; 2774 unsigned PseudoOpcode = Inst.getOpcode(); 2775 unsigned SrcReg = Inst.getOperand(0).getReg(); 2776 const MCOperand &TrgOp = Inst.getOperand(1); 2777 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr(); 2778 2779 unsigned ZeroSrcOpcode, ZeroTrgOpcode; 2780 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality; 2781 2782 unsigned TrgReg; 2783 if (TrgOp.isReg()) 2784 TrgReg = TrgOp.getReg(); 2785 else if (TrgOp.isImm()) { 2786 warnIfNoMacro(IDLoc); 2787 EmittedNoMacroWarning = true; 2788 2789 TrgReg = getATReg(IDLoc); 2790 if (!TrgReg) 2791 return true; 2792 2793 switch(PseudoOpcode) { 2794 default: 2795 llvm_unreachable("unknown opcode for branch pseudo-instruction"); 2796 case Mips::BLTImmMacro: 2797 PseudoOpcode = Mips::BLT; 2798 break; 2799 case Mips::BLEImmMacro: 2800 PseudoOpcode = Mips::BLE; 2801 break; 2802 case Mips::BGEImmMacro: 2803 PseudoOpcode = Mips::BGE; 2804 break; 2805 case Mips::BGTImmMacro: 2806 PseudoOpcode = Mips::BGT; 2807 break; 2808 case Mips::BLTUImmMacro: 2809 PseudoOpcode = Mips::BLTU; 2810 break; 2811 case Mips::BLEUImmMacro: 2812 PseudoOpcode = Mips::BLEU; 2813 break; 2814 case Mips::BGEUImmMacro: 2815 PseudoOpcode = Mips::BGEU; 2816 break; 2817 case Mips::BGTUImmMacro: 2818 PseudoOpcode = Mips::BGTU; 2819 break; 2820 case Mips::BLTLImmMacro: 2821 PseudoOpcode = Mips::BLTL; 2822 break; 2823 case Mips::BLELImmMacro: 2824 PseudoOpcode = Mips::BLEL; 2825 break; 2826 case Mips::BGELImmMacro: 2827 PseudoOpcode = Mips::BGEL; 2828 break; 2829 case Mips::BGTLImmMacro: 2830 PseudoOpcode = Mips::BGTL; 2831 break; 2832 case Mips::BLTULImmMacro: 2833 PseudoOpcode = Mips::BLTUL; 2834 break; 2835 case Mips::BLEULImmMacro: 2836 PseudoOpcode = Mips::BLEUL; 2837 break; 2838 case Mips::BGEULImmMacro: 2839 PseudoOpcode = Mips::BGEUL; 2840 break; 2841 case Mips::BGTULImmMacro: 2842 PseudoOpcode = Mips::BGTUL; 2843 break; 2844 } 2845 2846 if (loadImmediate(TrgOp.getImm(), TrgReg, Mips::NoRegister, !isGP64bit(), 2847 false, IDLoc, Out, STI)) 2848 return true; 2849 } 2850 2851 switch (PseudoOpcode) { 2852 case Mips::BLT: 2853 case Mips::BLTU: 2854 case Mips::BLTL: 2855 case Mips::BLTUL: 2856 AcceptsEquality = false; 2857 ReverseOrderSLT = false; 2858 IsUnsigned = ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL)); 2859 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL)); 2860 ZeroSrcOpcode = Mips::BGTZ; 2861 ZeroTrgOpcode = Mips::BLTZ; 2862 break; 2863 case Mips::BLE: 2864 case Mips::BLEU: 2865 case Mips::BLEL: 2866 case Mips::BLEUL: 2867 AcceptsEquality = true; 2868 ReverseOrderSLT = true; 2869 IsUnsigned = ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL)); 2870 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL)); 2871 ZeroSrcOpcode = Mips::BGEZ; 2872 ZeroTrgOpcode = Mips::BLEZ; 2873 break; 2874 case Mips::BGE: 2875 case Mips::BGEU: 2876 case Mips::BGEL: 2877 case Mips::BGEUL: 2878 AcceptsEquality = true; 2879 ReverseOrderSLT = false; 2880 IsUnsigned = ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL)); 2881 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL)); 2882 ZeroSrcOpcode = Mips::BLEZ; 2883 ZeroTrgOpcode = Mips::BGEZ; 2884 break; 2885 case Mips::BGT: 2886 case Mips::BGTU: 2887 case Mips::BGTL: 2888 case Mips::BGTUL: 2889 AcceptsEquality = false; 2890 ReverseOrderSLT = true; 2891 IsUnsigned = ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL)); 2892 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL)); 2893 ZeroSrcOpcode = Mips::BLTZ; 2894 ZeroTrgOpcode = Mips::BGTZ; 2895 break; 2896 default: 2897 llvm_unreachable("unknown opcode for branch pseudo-instruction"); 2898 } 2899 2900 bool IsTrgRegZero = (TrgReg == Mips::ZERO); 2901 bool IsSrcRegZero = (SrcReg == Mips::ZERO); 2902 if (IsSrcRegZero && IsTrgRegZero) { 2903 // FIXME: All of these Opcode-specific if's are needed for compatibility 2904 // with GAS' behaviour. However, they may not generate the most efficient 2905 // code in some circumstances. 2906 if (PseudoOpcode == Mips::BLT) { 2907 TOut.emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), 2908 IDLoc, STI); 2909 return false; 2910 } 2911 if (PseudoOpcode == Mips::BLE) { 2912 TOut.emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), 2913 IDLoc, STI); 2914 Warning(IDLoc, "branch is always taken"); 2915 return false; 2916 } 2917 if (PseudoOpcode == Mips::BGE) { 2918 TOut.emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), 2919 IDLoc, STI); 2920 Warning(IDLoc, "branch is always taken"); 2921 return false; 2922 } 2923 if (PseudoOpcode == Mips::BGT) { 2924 TOut.emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr), 2925 IDLoc, STI); 2926 return false; 2927 } 2928 if (PseudoOpcode == Mips::BGTU) { 2929 TOut.emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO, 2930 MCOperand::createExpr(OffsetExpr), IDLoc, STI); 2931 return false; 2932 } 2933 if (AcceptsEquality) { 2934 // If both registers are $0 and the pseudo-branch accepts equality, it 2935 // will always be taken, so we emit an unconditional branch. 2936 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO, 2937 MCOperand::createExpr(OffsetExpr), IDLoc, STI); 2938 Warning(IDLoc, "branch is always taken"); 2939 return false; 2940 } 2941 // If both registers are $0 and the pseudo-branch does not accept 2942 // equality, it will never be taken, so we don't have to emit anything. 2943 return false; 2944 } 2945 if (IsSrcRegZero || IsTrgRegZero) { 2946 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) || 2947 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) { 2948 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or 2949 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0), 2950 // the pseudo-branch will never be taken, so we don't emit anything. 2951 // This only applies to unsigned pseudo-branches. 2952 return false; 2953 } 2954 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) || 2955 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) { 2956 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or 2957 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0), 2958 // the pseudo-branch will always be taken, so we emit an unconditional 2959 // branch. 2960 // This only applies to unsigned pseudo-branches. 2961 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO, 2962 MCOperand::createExpr(OffsetExpr), IDLoc, STI); 2963 Warning(IDLoc, "branch is always taken"); 2964 return false; 2965 } 2966 if (IsUnsigned) { 2967 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or 2968 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0), 2969 // the pseudo-branch will be taken only when the non-zero register is 2970 // different from 0, so we emit a BNEZ. 2971 // 2972 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or 2973 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0), 2974 // the pseudo-branch will be taken only when the non-zero register is 2975 // equal to 0, so we emit a BEQZ. 2976 // 2977 // Because only BLEU and BGEU branch on equality, we can use the 2978 // AcceptsEquality variable to decide when to emit the BEQZ. 2979 TOut.emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE, 2980 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO, 2981 MCOperand::createExpr(OffsetExpr), IDLoc, STI); 2982 return false; 2983 } 2984 // If we have a signed pseudo-branch and one of the registers is $0, 2985 // we can use an appropriate compare-to-zero branch. We select which one 2986 // to use in the switch statement above. 2987 TOut.emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode, 2988 IsSrcRegZero ? TrgReg : SrcReg, 2989 MCOperand::createExpr(OffsetExpr), IDLoc, STI); 2990 return false; 2991 } 2992 2993 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the 2994 // expansions. If it is not available, we return. 2995 unsigned ATRegNum = getATReg(IDLoc); 2996 if (!ATRegNum) 2997 return true; 2998 2999 if (!EmittedNoMacroWarning) 3000 warnIfNoMacro(IDLoc); 3001 3002 // SLT fits well with 2 of our 4 pseudo-branches: 3003 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and 3004 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs". 3005 // If the result of the SLT is 1, we branch, and if it's 0, we don't. 3006 // This is accomplished by using a BNEZ with the result of the SLT. 3007 // 3008 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT 3009 // and BLE with BGT), so we change the BNEZ into a a BEQZ. 3010 // Because only BGE and BLE branch on equality, we can use the 3011 // AcceptsEquality variable to decide when to emit the BEQZ. 3012 // Note that the order of the SLT arguments doesn't change between 3013 // opposites. 3014 // 3015 // The same applies to the unsigned variants, except that SLTu is used 3016 // instead of SLT. 3017 TOut.emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum, 3018 ReverseOrderSLT ? TrgReg : SrcReg, 3019 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI); 3020 3021 TOut.emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL) 3022 : (AcceptsEquality ? Mips::BEQ : Mips::BNE), 3023 ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc, 3024 STI); 3025 return false; 3026 } 3027 3028 bool MipsAsmParser::expandDiv(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 3029 const MCSubtargetInfo *STI, const bool IsMips64, 3030 const bool Signed) { 3031 MipsTargetStreamer &TOut = getTargetStreamer(); 3032 3033 warnIfNoMacro(IDLoc); 3034 3035 const MCOperand &RdRegOp = Inst.getOperand(0); 3036 assert(RdRegOp.isReg() && "expected register operand kind"); 3037 unsigned RdReg = RdRegOp.getReg(); 3038 3039 const MCOperand &RsRegOp = Inst.getOperand(1); 3040 assert(RsRegOp.isReg() && "expected register operand kind"); 3041 unsigned RsReg = RsRegOp.getReg(); 3042 3043 const MCOperand &RtRegOp = Inst.getOperand(2); 3044 assert(RtRegOp.isReg() && "expected register operand kind"); 3045 unsigned RtReg = RtRegOp.getReg(); 3046 unsigned DivOp; 3047 unsigned ZeroReg; 3048 3049 if (IsMips64) { 3050 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV; 3051 ZeroReg = Mips::ZERO_64; 3052 } else { 3053 DivOp = Signed ? Mips::SDIV : Mips::UDIV; 3054 ZeroReg = Mips::ZERO; 3055 } 3056 3057 bool UseTraps = useTraps(); 3058 3059 if (RsReg == Mips::ZERO || RsReg == Mips::ZERO_64) { 3060 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) 3061 Warning(IDLoc, "dividing zero by zero"); 3062 if (IsMips64) { 3063 if (Signed && (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)) { 3064 if (UseTraps) { 3065 TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI); 3066 return false; 3067 } 3068 3069 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI); 3070 return false; 3071 } 3072 } else { 3073 TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI); 3074 return false; 3075 } 3076 } 3077 3078 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) { 3079 Warning(IDLoc, "division by zero"); 3080 if (Signed) { 3081 if (UseTraps) { 3082 TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI); 3083 return false; 3084 } 3085 3086 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI); 3087 return false; 3088 } 3089 } 3090 3091 // FIXME: The values for these two BranchTarget variables may be different in 3092 // micromips. These magic numbers need to be removed. 3093 unsigned BranchTargetNoTraps; 3094 unsigned BranchTarget; 3095 3096 if (UseTraps) { 3097 BranchTarget = IsMips64 ? 12 : 8; 3098 TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI); 3099 } else { 3100 BranchTarget = IsMips64 ? 20 : 16; 3101 BranchTargetNoTraps = 8; 3102 // Branch to the li instruction. 3103 TOut.emitRRI(Mips::BNE, RtReg, ZeroReg, BranchTargetNoTraps, IDLoc, STI); 3104 } 3105 3106 TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI); 3107 3108 if (!UseTraps) 3109 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI); 3110 3111 if (!Signed) { 3112 TOut.emitR(Mips::MFLO, RdReg, IDLoc, STI); 3113 return false; 3114 } 3115 3116 unsigned ATReg = getATReg(IDLoc); 3117 if (!ATReg) 3118 return true; 3119 3120 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, STI); 3121 if (IsMips64) { 3122 // Branch to the mflo instruction. 3123 TOut.emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, STI); 3124 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, STI); 3125 TOut.emitRRI(Mips::DSLL32, ATReg, ATReg, 0x1f, IDLoc, STI); 3126 } else { 3127 // Branch to the mflo instruction. 3128 TOut.emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, STI); 3129 TOut.emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, STI); 3130 } 3131 3132 if (UseTraps) 3133 TOut.emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, STI); 3134 else { 3135 // Branch to the mflo instruction. 3136 TOut.emitRRI(Mips::BNE, RsReg, ATReg, BranchTargetNoTraps, IDLoc, STI); 3137 TOut.emitRRI(Mips::SLL, ZeroReg, ZeroReg, 0, IDLoc, STI); 3138 TOut.emitII(Mips::BREAK, 0x6, 0, IDLoc, STI); 3139 } 3140 TOut.emitR(Mips::MFLO, RdReg, IDLoc, STI); 3141 return false; 3142 } 3143 3144 bool MipsAsmParser::expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU, 3145 SMLoc IDLoc, MCStreamer &Out, 3146 const MCSubtargetInfo *STI) { 3147 MipsTargetStreamer &TOut = getTargetStreamer(); 3148 3149 assert(Inst.getNumOperands() == 3 && "Invalid operand count"); 3150 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() && 3151 Inst.getOperand(2).isReg() && "Invalid instruction operand."); 3152 3153 unsigned FirstReg = Inst.getOperand(0).getReg(); 3154 unsigned SecondReg = Inst.getOperand(1).getReg(); 3155 unsigned ThirdReg = Inst.getOperand(2).getReg(); 3156 3157 if (hasMips1() && !hasMips2()) { 3158 unsigned ATReg = getATReg(IDLoc); 3159 if (!ATReg) 3160 return true; 3161 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI); 3162 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI); 3163 TOut.emitNop(IDLoc, STI); 3164 TOut.emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI); 3165 TOut.emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI); 3166 TOut.emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI); 3167 TOut.emitNop(IDLoc, STI); 3168 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32) 3169 : Mips::CVT_W_S, 3170 FirstReg, SecondReg, IDLoc, STI); 3171 TOut.emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI); 3172 TOut.emitNop(IDLoc, STI); 3173 return false; 3174 } 3175 3176 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32) 3177 : Mips::TRUNC_W_S, 3178 FirstReg, SecondReg, IDLoc, STI); 3179 3180 return false; 3181 } 3182 3183 bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc, 3184 MCStreamer &Out, const MCSubtargetInfo *STI) { 3185 MipsTargetStreamer &TOut = getTargetStreamer(); 3186 3187 if (hasMips32r6() || hasMips64r6()) { 3188 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6"); 3189 return false; 3190 } 3191 3192 warnIfNoMacro(IDLoc); 3193 3194 const MCOperand &DstRegOp = Inst.getOperand(0); 3195 assert(DstRegOp.isReg() && "expected register operand kind"); 3196 3197 const MCOperand &SrcRegOp = Inst.getOperand(1); 3198 assert(SrcRegOp.isReg() && "expected register operand kind"); 3199 3200 const MCOperand &OffsetImmOp = Inst.getOperand(2); 3201 assert(OffsetImmOp.isImm() && "expected immediate operand kind"); 3202 3203 unsigned DstReg = DstRegOp.getReg(); 3204 unsigned SrcReg = SrcRegOp.getReg(); 3205 int64_t OffsetValue = OffsetImmOp.getImm(); 3206 3207 // NOTE: We always need AT for ULHU, as it is always used as the source 3208 // register for one of the LBu's. 3209 unsigned ATReg = getATReg(IDLoc); 3210 if (!ATReg) 3211 return true; 3212 3213 // When the value of offset+1 does not fit in 16 bits, we have to load the 3214 // offset in AT, (D)ADDu the original source register (if there was one), and 3215 // then use AT as the source register for the 2 generated LBu's. 3216 bool LoadedOffsetInAT = false; 3217 if (!isInt<16>(OffsetValue + 1) || !isInt<16>(OffsetValue)) { 3218 LoadedOffsetInAT = true; 3219 3220 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(), 3221 true, IDLoc, Out, STI)) 3222 return true; 3223 3224 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate() 3225 // because it will make our output more similar to GAS'. For example, 3226 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9", 3227 // instead of just an "ori $1, $9, 32768". 3228 // NOTE: If there is no source register specified in the ULHU, the parser 3229 // will interpret it as $0. 3230 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64) 3231 TOut.emitAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), STI); 3232 } 3233 3234 unsigned FirstLbuDstReg = LoadedOffsetInAT ? DstReg : ATReg; 3235 unsigned SecondLbuDstReg = LoadedOffsetInAT ? ATReg : DstReg; 3236 unsigned LbuSrcReg = LoadedOffsetInAT ? ATReg : SrcReg; 3237 3238 int64_t FirstLbuOffset = 0, SecondLbuOffset = 0; 3239 if (isLittle()) { 3240 FirstLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1); 3241 SecondLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue; 3242 } else { 3243 FirstLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue; 3244 SecondLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1); 3245 } 3246 3247 unsigned SllReg = LoadedOffsetInAT ? DstReg : ATReg; 3248 3249 TOut.emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg, 3250 FirstLbuOffset, IDLoc, STI); 3251 3252 TOut.emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondLbuOffset, IDLoc, 3253 STI); 3254 3255 TOut.emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI); 3256 3257 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI); 3258 3259 return false; 3260 } 3261 3262 bool MipsAsmParser::expandUlw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 3263 const MCSubtargetInfo *STI) { 3264 MipsTargetStreamer &TOut = getTargetStreamer(); 3265 3266 if (hasMips32r6() || hasMips64r6()) { 3267 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6"); 3268 return false; 3269 } 3270 3271 const MCOperand &DstRegOp = Inst.getOperand(0); 3272 assert(DstRegOp.isReg() && "expected register operand kind"); 3273 3274 const MCOperand &SrcRegOp = Inst.getOperand(1); 3275 assert(SrcRegOp.isReg() && "expected register operand kind"); 3276 3277 const MCOperand &OffsetImmOp = Inst.getOperand(2); 3278 assert(OffsetImmOp.isImm() && "expected immediate operand kind"); 3279 3280 unsigned SrcReg = SrcRegOp.getReg(); 3281 int64_t OffsetValue = OffsetImmOp.getImm(); 3282 unsigned ATReg = 0; 3283 3284 // When the value of offset+3 does not fit in 16 bits, we have to load the 3285 // offset in AT, (D)ADDu the original source register (if there was one), and 3286 // then use AT as the source register for the generated LWL and LWR. 3287 bool LoadedOffsetInAT = false; 3288 if (!isInt<16>(OffsetValue + 3) || !isInt<16>(OffsetValue)) { 3289 ATReg = getATReg(IDLoc); 3290 if (!ATReg) 3291 return true; 3292 LoadedOffsetInAT = true; 3293 3294 warnIfNoMacro(IDLoc); 3295 3296 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(), 3297 true, IDLoc, Out, STI)) 3298 return true; 3299 3300 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate() 3301 // because it will make our output more similar to GAS'. For example, 3302 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9", 3303 // instead of just an "ori $1, $9, 32768". 3304 // NOTE: If there is no source register specified in the ULW, the parser 3305 // will interpret it as $0. 3306 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64) 3307 TOut.emitAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), STI); 3308 } 3309 3310 unsigned FinalSrcReg = LoadedOffsetInAT ? ATReg : SrcReg; 3311 int64_t LeftLoadOffset = 0, RightLoadOffset = 0; 3312 if (isLittle()) { 3313 LeftLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3); 3314 RightLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue; 3315 } else { 3316 LeftLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue; 3317 RightLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3); 3318 } 3319 3320 TOut.emitRRI(Mips::LWL, DstRegOp.getReg(), FinalSrcReg, LeftLoadOffset, IDLoc, 3321 STI); 3322 3323 TOut.emitRRI(Mips::LWR, DstRegOp.getReg(), FinalSrcReg, RightLoadOffset, 3324 IDLoc, STI); 3325 3326 return false; 3327 } 3328 3329 bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc, 3330 MCStreamer &Out, 3331 const MCSubtargetInfo *STI) { 3332 MipsTargetStreamer &TOut = getTargetStreamer(); 3333 3334 assert (Inst.getNumOperands() == 3 && "Invalid operand count"); 3335 assert (Inst.getOperand(0).isReg() && 3336 Inst.getOperand(1).isReg() && 3337 Inst.getOperand(2).isImm() && "Invalid instruction operand."); 3338 3339 unsigned ATReg = Mips::NoRegister; 3340 unsigned FinalDstReg = Mips::NoRegister; 3341 unsigned DstReg = Inst.getOperand(0).getReg(); 3342 unsigned SrcReg = Inst.getOperand(1).getReg(); 3343 int64_t ImmValue = Inst.getOperand(2).getImm(); 3344 3345 bool Is32Bit = isInt<32>(ImmValue) || isUInt<32>(ImmValue); 3346 3347 unsigned FinalOpcode = Inst.getOpcode(); 3348 3349 if (DstReg == SrcReg) { 3350 ATReg = getATReg(Inst.getLoc()); 3351 if (!ATReg) 3352 return true; 3353 FinalDstReg = DstReg; 3354 DstReg = ATReg; 3355 } 3356 3357 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit, false, Inst.getLoc(), Out, STI)) { 3358 switch (FinalOpcode) { 3359 default: 3360 llvm_unreachable("unimplemented expansion"); 3361 case (Mips::ADDi): 3362 FinalOpcode = Mips::ADD; 3363 break; 3364 case (Mips::ADDiu): 3365 FinalOpcode = Mips::ADDu; 3366 break; 3367 case (Mips::ANDi): 3368 FinalOpcode = Mips::AND; 3369 break; 3370 case (Mips::NORImm): 3371 FinalOpcode = Mips::NOR; 3372 break; 3373 case (Mips::ORi): 3374 FinalOpcode = Mips::OR; 3375 break; 3376 case (Mips::SLTi): 3377 FinalOpcode = Mips::SLT; 3378 break; 3379 case (Mips::SLTiu): 3380 FinalOpcode = Mips::SLTu; 3381 break; 3382 case (Mips::XORi): 3383 FinalOpcode = Mips::XOR; 3384 break; 3385 } 3386 3387 if (FinalDstReg == Mips::NoRegister) 3388 TOut.emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI); 3389 else 3390 TOut.emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI); 3391 return false; 3392 } 3393 return true; 3394 } 3395 3396 bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 3397 const MCSubtargetInfo *STI) { 3398 MipsTargetStreamer &TOut = getTargetStreamer(); 3399 unsigned ATReg = Mips::NoRegister; 3400 unsigned DReg = Inst.getOperand(0).getReg(); 3401 unsigned SReg = Inst.getOperand(1).getReg(); 3402 unsigned TReg = Inst.getOperand(2).getReg(); 3403 unsigned TmpReg = DReg; 3404 3405 unsigned FirstShift = Mips::NOP; 3406 unsigned SecondShift = Mips::NOP; 3407 3408 if (hasMips32r2()) { 3409 3410 if (DReg == SReg) { 3411 TmpReg = getATReg(Inst.getLoc()); 3412 if (!TmpReg) 3413 return true; 3414 } 3415 3416 if (Inst.getOpcode() == Mips::ROL) { 3417 TOut.emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI); 3418 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI); 3419 return false; 3420 } 3421 3422 if (Inst.getOpcode() == Mips::ROR) { 3423 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.getLoc(), STI); 3424 return false; 3425 } 3426 3427 return true; 3428 } 3429 3430 if (hasMips32()) { 3431 3432 switch (Inst.getOpcode()) { 3433 default: 3434 llvm_unreachable("unexpected instruction opcode"); 3435 case Mips::ROL: 3436 FirstShift = Mips::SRLV; 3437 SecondShift = Mips::SLLV; 3438 break; 3439 case Mips::ROR: 3440 FirstShift = Mips::SLLV; 3441 SecondShift = Mips::SRLV; 3442 break; 3443 } 3444 3445 ATReg = getATReg(Inst.getLoc()); 3446 if (!ATReg) 3447 return true; 3448 3449 TOut.emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI); 3450 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI); 3451 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI); 3452 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI); 3453 3454 return false; 3455 } 3456 3457 return true; 3458 } 3459 3460 bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc, 3461 MCStreamer &Out, 3462 const MCSubtargetInfo *STI) { 3463 MipsTargetStreamer &TOut = getTargetStreamer(); 3464 unsigned ATReg = Mips::NoRegister; 3465 unsigned DReg = Inst.getOperand(0).getReg(); 3466 unsigned SReg = Inst.getOperand(1).getReg(); 3467 int64_t ImmValue = Inst.getOperand(2).getImm(); 3468 3469 unsigned FirstShift = Mips::NOP; 3470 unsigned SecondShift = Mips::NOP; 3471 3472 if (hasMips32r2()) { 3473 3474 if (Inst.getOpcode() == Mips::ROLImm) { 3475 uint64_t MaxShift = 32; 3476 uint64_t ShiftValue = ImmValue; 3477 if (ImmValue != 0) 3478 ShiftValue = MaxShift - ImmValue; 3479 TOut.emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.getLoc(), STI); 3480 return false; 3481 } 3482 3483 if (Inst.getOpcode() == Mips::RORImm) { 3484 TOut.emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.getLoc(), STI); 3485 return false; 3486 } 3487 3488 return true; 3489 } 3490 3491 if (hasMips32()) { 3492 3493 if (ImmValue == 0) { 3494 TOut.emitRRI(Mips::SRL, DReg, SReg, 0, Inst.getLoc(), STI); 3495 return false; 3496 } 3497 3498 switch (Inst.getOpcode()) { 3499 default: 3500 llvm_unreachable("unexpected instruction opcode"); 3501 case Mips::ROLImm: 3502 FirstShift = Mips::SLL; 3503 SecondShift = Mips::SRL; 3504 break; 3505 case Mips::RORImm: 3506 FirstShift = Mips::SRL; 3507 SecondShift = Mips::SLL; 3508 break; 3509 } 3510 3511 ATReg = getATReg(Inst.getLoc()); 3512 if (!ATReg) 3513 return true; 3514 3515 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.getLoc(), STI); 3516 TOut.emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.getLoc(), STI); 3517 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI); 3518 3519 return false; 3520 } 3521 3522 return true; 3523 } 3524 3525 bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 3526 const MCSubtargetInfo *STI) { 3527 MipsTargetStreamer &TOut = getTargetStreamer(); 3528 unsigned ATReg = Mips::NoRegister; 3529 unsigned DReg = Inst.getOperand(0).getReg(); 3530 unsigned SReg = Inst.getOperand(1).getReg(); 3531 unsigned TReg = Inst.getOperand(2).getReg(); 3532 unsigned TmpReg = DReg; 3533 3534 unsigned FirstShift = Mips::NOP; 3535 unsigned SecondShift = Mips::NOP; 3536 3537 if (hasMips64r2()) { 3538 3539 if (TmpReg == SReg) { 3540 TmpReg = getATReg(Inst.getLoc()); 3541 if (!TmpReg) 3542 return true; 3543 } 3544 3545 if (Inst.getOpcode() == Mips::DROL) { 3546 TOut.emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI); 3547 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI); 3548 return false; 3549 } 3550 3551 if (Inst.getOpcode() == Mips::DROR) { 3552 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.getLoc(), STI); 3553 return false; 3554 } 3555 3556 return true; 3557 } 3558 3559 if (hasMips64()) { 3560 3561 switch (Inst.getOpcode()) { 3562 default: 3563 llvm_unreachable("unexpected instruction opcode"); 3564 case Mips::DROL: 3565 FirstShift = Mips::DSRLV; 3566 SecondShift = Mips::DSLLV; 3567 break; 3568 case Mips::DROR: 3569 FirstShift = Mips::DSLLV; 3570 SecondShift = Mips::DSRLV; 3571 break; 3572 } 3573 3574 ATReg = getATReg(Inst.getLoc()); 3575 if (!ATReg) 3576 return true; 3577 3578 TOut.emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI); 3579 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI); 3580 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI); 3581 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI); 3582 3583 return false; 3584 } 3585 3586 return true; 3587 } 3588 3589 bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc, 3590 MCStreamer &Out, 3591 const MCSubtargetInfo *STI) { 3592 MipsTargetStreamer &TOut = getTargetStreamer(); 3593 unsigned ATReg = Mips::NoRegister; 3594 unsigned DReg = Inst.getOperand(0).getReg(); 3595 unsigned SReg = Inst.getOperand(1).getReg(); 3596 int64_t ImmValue = Inst.getOperand(2).getImm() % 64; 3597 3598 unsigned FirstShift = Mips::NOP; 3599 unsigned SecondShift = Mips::NOP; 3600 3601 MCInst TmpInst; 3602 3603 if (hasMips64r2()) { 3604 3605 unsigned FinalOpcode = Mips::NOP; 3606 if (ImmValue == 0) 3607 FinalOpcode = Mips::DROTR; 3608 else if (ImmValue % 32 == 0) 3609 FinalOpcode = Mips::DROTR32; 3610 else if ((ImmValue >= 1) && (ImmValue <= 32)) { 3611 if (Inst.getOpcode() == Mips::DROLImm) 3612 FinalOpcode = Mips::DROTR32; 3613 else 3614 FinalOpcode = Mips::DROTR; 3615 } else if (ImmValue >= 33) { 3616 if (Inst.getOpcode() == Mips::DROLImm) 3617 FinalOpcode = Mips::DROTR; 3618 else 3619 FinalOpcode = Mips::DROTR32; 3620 } 3621 3622 uint64_t ShiftValue = ImmValue % 32; 3623 if (Inst.getOpcode() == Mips::DROLImm) 3624 ShiftValue = (32 - ImmValue % 32) % 32; 3625 3626 TOut.emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.getLoc(), STI); 3627 3628 return false; 3629 } 3630 3631 if (hasMips64()) { 3632 3633 if (ImmValue == 0) { 3634 TOut.emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.getLoc(), STI); 3635 return false; 3636 } 3637 3638 switch (Inst.getOpcode()) { 3639 default: 3640 llvm_unreachable("unexpected instruction opcode"); 3641 case Mips::DROLImm: 3642 if ((ImmValue >= 1) && (ImmValue <= 31)) { 3643 FirstShift = Mips::DSLL; 3644 SecondShift = Mips::DSRL32; 3645 } 3646 if (ImmValue == 32) { 3647 FirstShift = Mips::DSLL32; 3648 SecondShift = Mips::DSRL32; 3649 } 3650 if ((ImmValue >= 33) && (ImmValue <= 63)) { 3651 FirstShift = Mips::DSLL32; 3652 SecondShift = Mips::DSRL; 3653 } 3654 break; 3655 case Mips::DRORImm: 3656 if ((ImmValue >= 1) && (ImmValue <= 31)) { 3657 FirstShift = Mips::DSRL; 3658 SecondShift = Mips::DSLL32; 3659 } 3660 if (ImmValue == 32) { 3661 FirstShift = Mips::DSRL32; 3662 SecondShift = Mips::DSLL32; 3663 } 3664 if ((ImmValue >= 33) && (ImmValue <= 63)) { 3665 FirstShift = Mips::DSRL32; 3666 SecondShift = Mips::DSLL; 3667 } 3668 break; 3669 } 3670 3671 ATReg = getATReg(Inst.getLoc()); 3672 if (!ATReg) 3673 return true; 3674 3675 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.getLoc(), STI); 3676 TOut.emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32, 3677 Inst.getLoc(), STI); 3678 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI); 3679 3680 return false; 3681 } 3682 3683 return true; 3684 } 3685 3686 bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 3687 const MCSubtargetInfo *STI) { 3688 MipsTargetStreamer &TOut = getTargetStreamer(); 3689 unsigned FirstRegOp = Inst.getOperand(0).getReg(); 3690 unsigned SecondRegOp = Inst.getOperand(1).getReg(); 3691 3692 TOut.emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI); 3693 if (FirstRegOp != SecondRegOp) 3694 TOut.emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI); 3695 else 3696 TOut.emitEmptyDelaySlot(false, IDLoc, STI); 3697 TOut.emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI); 3698 3699 return false; 3700 } 3701 3702 void MipsAsmParser::createCpRestoreMemOp(bool IsLoad, int StackOffset, 3703 SMLoc IDLoc, MCStreamer &Out, 3704 const MCSubtargetInfo *STI) { 3705 MipsTargetStreamer &TOut = getTargetStreamer(); 3706 3707 if (IsLoad) { 3708 TOut.emitLoadWithImmOffset(Mips::LW, Mips::GP, Mips::SP, StackOffset, 3709 Mips::GP, IDLoc, STI); 3710 return; 3711 } 3712 3713 TOut.emitStoreWithImmOffset(Mips::SW, Mips::GP, Mips::SP, StackOffset, 3714 [&]() { return getATReg(IDLoc); }, IDLoc, STI); 3715 } 3716 3717 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) { 3718 switch (Inst.getOpcode()) { 3719 // As described by the Mips32r2 spec, the registers Rd and Rs for 3720 // jalr.hb must be different. 3721 // It also applies for registers Rt and Rs of microMIPSr6 jalrc.hb instruction 3722 // and registers Rd and Base for microMIPS lwp instruction 3723 case Mips::JALR_HB: 3724 case Mips::JALRC_HB_MMR6: 3725 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()) 3726 return Match_RequiresDifferentSrcAndDst; 3727 return Match_Success; 3728 case Mips::LWP_MM: 3729 case Mips::LWP_MMR6: 3730 if (Inst.getOperand(0).getReg() == Inst.getOperand(2).getReg()) 3731 return Match_RequiresDifferentSrcAndDst; 3732 return Match_Success; 3733 // As described the MIPSR6 spec, the compact branches that compare registers 3734 // must: 3735 // a) Not use the zero register. 3736 // b) Not use the same register twice. 3737 // c) rs < rt for bnec, beqc. 3738 // NB: For this case, the encoding will swap the operands as their 3739 // ordering doesn't matter. GAS performs this transformation too. 3740 // Hence, that constraint does not have to be enforced. 3741 // 3742 // The compact branches that branch iff the signed addition of two registers 3743 // would overflow must have rs >= rt. That can be handled like beqc/bnec with 3744 // operand swapping. They do not have restriction of using the zero register. 3745 case Mips::BLEZC: 3746 case Mips::BGEZC: 3747 case Mips::BGTZC: 3748 case Mips::BLTZC: 3749 case Mips::BEQZC: 3750 case Mips::BNEZC: 3751 if (Inst.getOperand(0).getReg() == Mips::ZERO) 3752 return Match_RequiresNoZeroRegister; 3753 return Match_Success; 3754 case Mips::BGEC: 3755 case Mips::BLTC: 3756 case Mips::BGEUC: 3757 case Mips::BLTUC: 3758 case Mips::BEQC: 3759 case Mips::BNEC: 3760 if (Inst.getOperand(0).getReg() == Mips::ZERO) 3761 return Match_RequiresNoZeroRegister; 3762 if (Inst.getOperand(1).getReg() == Mips::ZERO) 3763 return Match_RequiresNoZeroRegister; 3764 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()) 3765 return Match_RequiresDifferentOperands; 3766 return Match_Success; 3767 default: 3768 return Match_Success; 3769 } 3770 } 3771 3772 static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands, 3773 uint64_t ErrorInfo) { 3774 if (ErrorInfo != ~0ULL && ErrorInfo < Operands.size()) { 3775 SMLoc ErrorLoc = Operands[ErrorInfo]->getStartLoc(); 3776 if (ErrorLoc == SMLoc()) 3777 return Loc; 3778 return ErrorLoc; 3779 } 3780 return Loc; 3781 } 3782 3783 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 3784 OperandVector &Operands, 3785 MCStreamer &Out, 3786 uint64_t &ErrorInfo, 3787 bool MatchingInlineAsm) { 3788 3789 MCInst Inst; 3790 unsigned MatchResult = 3791 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm); 3792 3793 switch (MatchResult) { 3794 case Match_Success: { 3795 if (processInstruction(Inst, IDLoc, Out, STI)) 3796 return true; 3797 return false; 3798 } 3799 case Match_MissingFeature: 3800 Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 3801 return true; 3802 case Match_InvalidOperand: { 3803 SMLoc ErrorLoc = IDLoc; 3804 if (ErrorInfo != ~0ULL) { 3805 if (ErrorInfo >= Operands.size()) 3806 return Error(IDLoc, "too few operands for instruction"); 3807 3808 ErrorLoc = Operands[ErrorInfo]->getStartLoc(); 3809 if (ErrorLoc == SMLoc()) 3810 ErrorLoc = IDLoc; 3811 } 3812 3813 return Error(ErrorLoc, "invalid operand for instruction"); 3814 } 3815 case Match_MnemonicFail: 3816 return Error(IDLoc, "invalid instruction"); 3817 case Match_RequiresDifferentSrcAndDst: 3818 return Error(IDLoc, "source and destination must be different"); 3819 case Match_RequiresDifferentOperands: 3820 return Error(IDLoc, "registers must be different"); 3821 case Match_RequiresNoZeroRegister: 3822 return Error(IDLoc, "invalid operand ($zero) for instruction"); 3823 case Match_Immz: 3824 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected '0'"); 3825 case Match_UImm1_0: 3826 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3827 "expected 1-bit unsigned immediate"); 3828 case Match_UImm2_0: 3829 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3830 "expected 2-bit unsigned immediate"); 3831 case Match_UImm2_1: 3832 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3833 "expected immediate in range 1 .. 4"); 3834 case Match_UImm3_0: 3835 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3836 "expected 3-bit unsigned immediate"); 3837 case Match_UImm4_0: 3838 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3839 "expected 4-bit unsigned immediate"); 3840 case Match_SImm4_0: 3841 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3842 "expected 4-bit signed immediate"); 3843 case Match_UImm5_0: 3844 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3845 "expected 5-bit unsigned immediate"); 3846 case Match_SImm5_0: 3847 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3848 "expected 5-bit signed immediate"); 3849 case Match_UImm5_1: 3850 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3851 "expected immediate in range 1 .. 32"); 3852 case Match_UImm5_32: 3853 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3854 "expected immediate in range 32 .. 63"); 3855 case Match_UImm5_33: 3856 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3857 "expected immediate in range 33 .. 64"); 3858 case Match_UImm5_0_Report_UImm6: 3859 // This is used on UImm5 operands that have a corresponding UImm5_32 3860 // operand to avoid confusing the user. 3861 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3862 "expected 6-bit unsigned immediate"); 3863 case Match_UImm5_Lsl2: 3864 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3865 "expected both 7-bit unsigned immediate and multiple of 4"); 3866 case Match_UImmRange2_64: 3867 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3868 "expected immediate in range 2 .. 64"); 3869 case Match_UImm6_0: 3870 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3871 "expected 6-bit unsigned immediate"); 3872 case Match_UImm6_Lsl2: 3873 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3874 "expected both 8-bit unsigned immediate and multiple of 4"); 3875 case Match_SImm6_0: 3876 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3877 "expected 6-bit signed immediate"); 3878 case Match_UImm7_0: 3879 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3880 "expected 7-bit unsigned immediate"); 3881 case Match_UImm7_N1: 3882 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3883 "expected immediate in range -1 .. 126"); 3884 case Match_SImm7_Lsl2: 3885 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3886 "expected both 9-bit signed immediate and multiple of 4"); 3887 case Match_UImm8_0: 3888 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3889 "expected 8-bit unsigned immediate"); 3890 case Match_UImm10_0: 3891 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3892 "expected 10-bit unsigned immediate"); 3893 case Match_SImm10_0: 3894 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3895 "expected 10-bit signed immediate"); 3896 case Match_SImm11_0: 3897 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3898 "expected 11-bit signed immediate"); 3899 case Match_UImm16: 3900 case Match_UImm16_Relaxed: 3901 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3902 "expected 16-bit unsigned immediate"); 3903 case Match_SImm16: 3904 case Match_SImm16_Relaxed: 3905 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3906 "expected 16-bit signed immediate"); 3907 case Match_UImm20_0: 3908 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3909 "expected 20-bit unsigned immediate"); 3910 case Match_UImm26_0: 3911 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3912 "expected 26-bit unsigned immediate"); 3913 case Match_SImm32: 3914 case Match_SImm32_Relaxed: 3915 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3916 "expected 32-bit signed immediate"); 3917 case Match_MemSImm9: 3918 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3919 "expected memory with 9-bit signed offset"); 3920 case Match_MemSImm10: 3921 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3922 "expected memory with 10-bit signed offset"); 3923 case Match_MemSImm10Lsl1: 3924 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3925 "expected memory with 11-bit signed offset and multiple of 2"); 3926 case Match_MemSImm10Lsl2: 3927 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3928 "expected memory with 12-bit signed offset and multiple of 4"); 3929 case Match_MemSImm10Lsl3: 3930 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3931 "expected memory with 13-bit signed offset and multiple of 8"); 3932 case Match_MemSImm11: 3933 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3934 "expected memory with 11-bit signed offset"); 3935 case Match_MemSImm12: 3936 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3937 "expected memory with 12-bit signed offset"); 3938 case Match_MemSImm16: 3939 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), 3940 "expected memory with 16-bit signed offset"); 3941 } 3942 3943 llvm_unreachable("Implement any new match types added!"); 3944 } 3945 3946 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) { 3947 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex) 3948 Warning(Loc, "used $at (currently $" + Twine(RegIndex) + 3949 ") without \".set noat\""); 3950 } 3951 3952 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) { 3953 if (!AssemblerOptions.back()->isMacro()) 3954 Warning(Loc, "macro instruction expanded into multiple instructions"); 3955 } 3956 3957 void 3958 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg, 3959 SMRange Range, bool ShowColors) { 3960 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg, 3961 Range, SMFixIt(Range, FixMsg), 3962 ShowColors); 3963 } 3964 3965 int MipsAsmParser::matchCPURegisterName(StringRef Name) { 3966 int CC; 3967 3968 CC = StringSwitch<unsigned>(Name) 3969 .Case("zero", 0) 3970 .Case("at", 1) 3971 .Case("a0", 4) 3972 .Case("a1", 5) 3973 .Case("a2", 6) 3974 .Case("a3", 7) 3975 .Case("v0", 2) 3976 .Case("v1", 3) 3977 .Case("s0", 16) 3978 .Case("s1", 17) 3979 .Case("s2", 18) 3980 .Case("s3", 19) 3981 .Case("s4", 20) 3982 .Case("s5", 21) 3983 .Case("s6", 22) 3984 .Case("s7", 23) 3985 .Case("k0", 26) 3986 .Case("k1", 27) 3987 .Case("gp", 28) 3988 .Case("sp", 29) 3989 .Case("fp", 30) 3990 .Case("s8", 30) 3991 .Case("ra", 31) 3992 .Case("t0", 8) 3993 .Case("t1", 9) 3994 .Case("t2", 10) 3995 .Case("t3", 11) 3996 .Case("t4", 12) 3997 .Case("t5", 13) 3998 .Case("t6", 14) 3999 .Case("t7", 15) 4000 .Case("t8", 24) 4001 .Case("t9", 25) 4002 .Default(-1); 4003 4004 if (!(isABI_N32() || isABI_N64())) 4005 return CC; 4006 4007 if (12 <= CC && CC <= 15) { 4008 // Name is one of t4-t7 4009 AsmToken RegTok = getLexer().peekTok(); 4010 SMRange RegRange = RegTok.getLocRange(); 4011 4012 StringRef FixedName = StringSwitch<StringRef>(Name) 4013 .Case("t4", "t0") 4014 .Case("t5", "t1") 4015 .Case("t6", "t2") 4016 .Case("t7", "t3") 4017 .Default(""); 4018 assert(FixedName != "" && "Register name is not one of t4-t7."); 4019 4020 printWarningWithFixIt("register names $t4-$t7 are only available in O32.", 4021 "Did you mean $" + FixedName + "?", RegRange); 4022 } 4023 4024 // Although SGI documentation just cuts out t0-t3 for n32/n64, 4025 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7 4026 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7. 4027 if (8 <= CC && CC <= 11) 4028 CC += 4; 4029 4030 if (CC == -1) 4031 CC = StringSwitch<unsigned>(Name) 4032 .Case("a4", 8) 4033 .Case("a5", 9) 4034 .Case("a6", 10) 4035 .Case("a7", 11) 4036 .Case("kt0", 26) 4037 .Case("kt1", 27) 4038 .Default(-1); 4039 4040 return CC; 4041 } 4042 4043 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) { 4044 int CC; 4045 4046 CC = StringSwitch<unsigned>(Name) 4047 .Case("hwr_cpunum", 0) 4048 .Case("hwr_synci_step", 1) 4049 .Case("hwr_cc", 2) 4050 .Case("hwr_ccres", 3) 4051 .Case("hwr_ulr", 29) 4052 .Default(-1); 4053 4054 return CC; 4055 } 4056 4057 int MipsAsmParser::matchFPURegisterName(StringRef Name) { 4058 4059 if (Name[0] == 'f') { 4060 StringRef NumString = Name.substr(1); 4061 unsigned IntVal; 4062 if (NumString.getAsInteger(10, IntVal)) 4063 return -1; // This is not an integer. 4064 if (IntVal > 31) // Maximum index for fpu register. 4065 return -1; 4066 return IntVal; 4067 } 4068 return -1; 4069 } 4070 4071 int MipsAsmParser::matchFCCRegisterName(StringRef Name) { 4072 4073 if (Name.startswith("fcc")) { 4074 StringRef NumString = Name.substr(3); 4075 unsigned IntVal; 4076 if (NumString.getAsInteger(10, IntVal)) 4077 return -1; // This is not an integer. 4078 if (IntVal > 7) // There are only 8 fcc registers. 4079 return -1; 4080 return IntVal; 4081 } 4082 return -1; 4083 } 4084 4085 int MipsAsmParser::matchACRegisterName(StringRef Name) { 4086 4087 if (Name.startswith("ac")) { 4088 StringRef NumString = Name.substr(2); 4089 unsigned IntVal; 4090 if (NumString.getAsInteger(10, IntVal)) 4091 return -1; // This is not an integer. 4092 if (IntVal > 3) // There are only 3 acc registers. 4093 return -1; 4094 return IntVal; 4095 } 4096 return -1; 4097 } 4098 4099 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) { 4100 unsigned IntVal; 4101 4102 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal)) 4103 return -1; 4104 4105 if (IntVal > 31) 4106 return -1; 4107 4108 return IntVal; 4109 } 4110 4111 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) { 4112 int CC; 4113 4114 CC = StringSwitch<unsigned>(Name) 4115 .Case("msair", 0) 4116 .Case("msacsr", 1) 4117 .Case("msaaccess", 2) 4118 .Case("msasave", 3) 4119 .Case("msamodify", 4) 4120 .Case("msarequest", 5) 4121 .Case("msamap", 6) 4122 .Case("msaunmap", 7) 4123 .Default(-1); 4124 4125 return CC; 4126 } 4127 4128 unsigned MipsAsmParser::getATReg(SMLoc Loc) { 4129 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex(); 4130 if (ATIndex == 0) { 4131 reportParseError(Loc, 4132 "pseudo-instruction requires $at, which is not available"); 4133 return 0; 4134 } 4135 unsigned AT = getReg( 4136 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex); 4137 return AT; 4138 } 4139 4140 unsigned MipsAsmParser::getReg(int RC, int RegNo) { 4141 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo); 4142 } 4143 4144 unsigned MipsAsmParser::getGPR(int RegNo) { 4145 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, 4146 RegNo); 4147 } 4148 4149 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) { 4150 if (RegNum > 4151 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1) 4152 return -1; 4153 4154 return getReg(RegClass, RegNum); 4155 } 4156 4157 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { 4158 MCAsmParser &Parser = getParser(); 4159 DEBUG(dbgs() << "parseOperand\n"); 4160 4161 // Check if the current operand has a custom associated parser, if so, try to 4162 // custom parse the operand, or fallback to the general approach. 4163 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 4164 if (ResTy == MatchOperand_Success) 4165 return false; 4166 // If there wasn't a custom match, try the generic matcher below. Otherwise, 4167 // there was a match, but an error occurred, in which case, just return that 4168 // the operand parsing failed. 4169 if (ResTy == MatchOperand_ParseFail) 4170 return true; 4171 4172 DEBUG(dbgs() << ".. Generic Parser\n"); 4173 4174 switch (getLexer().getKind()) { 4175 default: 4176 Error(Parser.getTok().getLoc(), "unexpected token in operand"); 4177 return true; 4178 case AsmToken::Dollar: { 4179 // Parse the register. 4180 SMLoc S = Parser.getTok().getLoc(); 4181 4182 // Almost all registers have been parsed by custom parsers. There is only 4183 // one exception to this. $zero (and it's alias $0) will reach this point 4184 // for div, divu, and similar instructions because it is not an operand 4185 // to the instruction definition but an explicit register. Special case 4186 // this situation for now. 4187 if (parseAnyRegister(Operands) != MatchOperand_NoMatch) 4188 return false; 4189 4190 // Maybe it is a symbol reference. 4191 StringRef Identifier; 4192 if (Parser.parseIdentifier(Identifier)) 4193 return true; 4194 4195 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 4196 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier); 4197 // Otherwise create a symbol reference. 4198 const MCExpr *Res = 4199 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 4200 4201 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this)); 4202 return false; 4203 } 4204 // Else drop to expression parsing. 4205 case AsmToken::LParen: 4206 case AsmToken::Minus: 4207 case AsmToken::Plus: 4208 case AsmToken::Integer: 4209 case AsmToken::Tilde: 4210 case AsmToken::String: { 4211 DEBUG(dbgs() << ".. generic integer\n"); 4212 OperandMatchResultTy ResTy = parseImm(Operands); 4213 return ResTy != MatchOperand_Success; 4214 } 4215 case AsmToken::Percent: { 4216 // It is a symbol reference or constant expression. 4217 const MCExpr *IdVal; 4218 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand. 4219 if (parseRelocOperand(IdVal)) 4220 return true; 4221 4222 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 4223 4224 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this)); 4225 return false; 4226 } // case AsmToken::Percent 4227 } // switch(getLexer().getKind()) 4228 return true; 4229 } 4230 4231 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr, 4232 StringRef RelocStr) { 4233 if (RelocStr == "hi(%neg(%gp_rel") 4234 return MipsMCExpr::createGpOff(MipsMCExpr::MEK_HI, Expr, getContext()); 4235 else if (RelocStr == "lo(%neg(%gp_rel") 4236 return MipsMCExpr::createGpOff(MipsMCExpr::MEK_LO, Expr, getContext()); 4237 4238 MipsMCExpr::MipsExprKind Kind = 4239 StringSwitch<MipsMCExpr::MipsExprKind>(RelocStr) 4240 .Case("call16", MipsMCExpr::MEK_GOT_CALL) 4241 .Case("call_hi", MipsMCExpr::MEK_CALL_HI16) 4242 .Case("call_lo", MipsMCExpr::MEK_CALL_LO16) 4243 .Case("dtprel_hi", MipsMCExpr::MEK_DTPREL_HI) 4244 .Case("dtprel_lo", MipsMCExpr::MEK_DTPREL_LO) 4245 .Case("got", MipsMCExpr::MEK_GOT) 4246 .Case("got_disp", MipsMCExpr::MEK_GOT_DISP) 4247 .Case("got_hi", MipsMCExpr::MEK_GOT_HI16) 4248 .Case("got_lo", MipsMCExpr::MEK_GOT_LO16) 4249 .Case("got_ofst", MipsMCExpr::MEK_GOT_OFST) 4250 .Case("got_page", MipsMCExpr::MEK_GOT_PAGE) 4251 .Case("gottprel", MipsMCExpr::MEK_GOTTPREL) 4252 .Case("gp_rel", MipsMCExpr::MEK_GPREL) 4253 .Case("hi", MipsMCExpr::MEK_HI) 4254 .Case("higher", MipsMCExpr::MEK_HIGHER) 4255 .Case("highest", MipsMCExpr::MEK_HIGHEST) 4256 .Case("lo", MipsMCExpr::MEK_LO) 4257 .Case("neg", MipsMCExpr::MEK_NEG) 4258 .Case("pcrel_hi", MipsMCExpr::MEK_PCREL_HI16) 4259 .Case("pcrel_lo", MipsMCExpr::MEK_PCREL_LO16) 4260 .Case("tlsgd", MipsMCExpr::MEK_TLSGD) 4261 .Case("tlsldm", MipsMCExpr::MEK_TLSLDM) 4262 .Case("tprel_hi", MipsMCExpr::MEK_TPREL_HI) 4263 .Case("tprel_lo", MipsMCExpr::MEK_TPREL_LO) 4264 .Default(MipsMCExpr::MEK_None); 4265 4266 assert(Kind != MipsMCExpr::MEK_None); 4267 return MipsMCExpr::create(Kind, Expr, getContext()); 4268 } 4269 4270 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) { 4271 4272 switch (Expr->getKind()) { 4273 case MCExpr::Constant: 4274 return true; 4275 case MCExpr::SymbolRef: 4276 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None); 4277 case MCExpr::Binary: 4278 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) { 4279 if (!isEvaluated(BE->getLHS())) 4280 return false; 4281 return isEvaluated(BE->getRHS()); 4282 } 4283 case MCExpr::Unary: 4284 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr()); 4285 case MCExpr::Target: 4286 return true; 4287 } 4288 return false; 4289 } 4290 4291 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) { 4292 MCAsmParser &Parser = getParser(); 4293 Parser.Lex(); // Eat the % token. 4294 const AsmToken &Tok = Parser.getTok(); // Get next token, operation. 4295 if (Tok.isNot(AsmToken::Identifier)) 4296 return true; 4297 4298 std::string Str = Tok.getIdentifier(); 4299 4300 Parser.Lex(); // Eat the identifier. 4301 // Now make an expression from the rest of the operand. 4302 const MCExpr *IdVal; 4303 SMLoc EndLoc; 4304 4305 if (getLexer().getKind() == AsmToken::LParen) { 4306 while (1) { 4307 Parser.Lex(); // Eat the '(' token. 4308 if (getLexer().getKind() == AsmToken::Percent) { 4309 Parser.Lex(); // Eat the % token. 4310 const AsmToken &nextTok = Parser.getTok(); 4311 if (nextTok.isNot(AsmToken::Identifier)) 4312 return true; 4313 Str += "(%"; 4314 Str += nextTok.getIdentifier(); 4315 Parser.Lex(); // Eat the identifier. 4316 if (getLexer().getKind() != AsmToken::LParen) 4317 return true; 4318 } else 4319 break; 4320 } 4321 if (getParser().parseParenExpression(IdVal, EndLoc)) 4322 return true; 4323 4324 while (getLexer().getKind() == AsmToken::RParen) 4325 Parser.Lex(); // Eat the ')' token. 4326 4327 } else 4328 return true; // Parenthesis must follow the relocation operand. 4329 4330 Res = evaluateRelocExpr(IdVal, Str); 4331 return false; 4332 } 4333 4334 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 4335 SMLoc &EndLoc) { 4336 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands; 4337 OperandMatchResultTy ResTy = parseAnyRegister(Operands); 4338 if (ResTy == MatchOperand_Success) { 4339 assert(Operands.size() == 1); 4340 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front()); 4341 StartLoc = Operand.getStartLoc(); 4342 EndLoc = Operand.getEndLoc(); 4343 4344 // AFAIK, we only support numeric registers and named GPR's in CFI 4345 // directives. 4346 // Don't worry about eating tokens before failing. Using an unrecognised 4347 // register is a parse error. 4348 if (Operand.isGPRAsmReg()) { 4349 // Resolve to GPR32 or GPR64 appropriately. 4350 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg(); 4351 } 4352 4353 return (RegNo == (unsigned)-1); 4354 } 4355 4356 assert(Operands.size() == 0); 4357 return (RegNo == (unsigned)-1); 4358 } 4359 4360 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) { 4361 MCAsmParser &Parser = getParser(); 4362 SMLoc S; 4363 bool Result = true; 4364 unsigned NumOfLParen = 0; 4365 4366 while (getLexer().getKind() == AsmToken::LParen) { 4367 Parser.Lex(); 4368 ++NumOfLParen; 4369 } 4370 4371 switch (getLexer().getKind()) { 4372 default: 4373 return true; 4374 case AsmToken::Identifier: 4375 case AsmToken::LParen: 4376 case AsmToken::Integer: 4377 case AsmToken::Minus: 4378 case AsmToken::Plus: 4379 if (isParenExpr) 4380 Result = getParser().parseParenExprOfDepth(NumOfLParen, Res, S); 4381 else 4382 Result = (getParser().parseExpression(Res)); 4383 while (getLexer().getKind() == AsmToken::RParen) 4384 Parser.Lex(); 4385 break; 4386 case AsmToken::Percent: 4387 Result = parseRelocOperand(Res); 4388 } 4389 return Result; 4390 } 4391 4392 MipsAsmParser::OperandMatchResultTy 4393 MipsAsmParser::parseMemOperand(OperandVector &Operands) { 4394 MCAsmParser &Parser = getParser(); 4395 DEBUG(dbgs() << "parseMemOperand\n"); 4396 const MCExpr *IdVal = nullptr; 4397 SMLoc S; 4398 bool isParenExpr = false; 4399 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch; 4400 // First operand is the offset. 4401 S = Parser.getTok().getLoc(); 4402 4403 if (getLexer().getKind() == AsmToken::LParen) { 4404 Parser.Lex(); 4405 isParenExpr = true; 4406 } 4407 4408 if (getLexer().getKind() != AsmToken::Dollar) { 4409 if (parseMemOffset(IdVal, isParenExpr)) 4410 return MatchOperand_ParseFail; 4411 4412 const AsmToken &Tok = Parser.getTok(); // Get the next token. 4413 if (Tok.isNot(AsmToken::LParen)) { 4414 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]); 4415 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") { 4416 SMLoc E = 4417 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 4418 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this)); 4419 return MatchOperand_Success; 4420 } 4421 if (Tok.is(AsmToken::EndOfStatement)) { 4422 SMLoc E = 4423 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 4424 4425 // Zero register assumed, add a memory operand with ZERO as its base. 4426 // "Base" will be managed by k_Memory. 4427 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(), 4428 S, E, *this); 4429 Operands.push_back( 4430 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this)); 4431 return MatchOperand_Success; 4432 } 4433 Error(Parser.getTok().getLoc(), "'(' expected"); 4434 return MatchOperand_ParseFail; 4435 } 4436 4437 Parser.Lex(); // Eat the '(' token. 4438 } 4439 4440 Res = parseAnyRegister(Operands); 4441 if (Res != MatchOperand_Success) 4442 return Res; 4443 4444 if (Parser.getTok().isNot(AsmToken::RParen)) { 4445 Error(Parser.getTok().getLoc(), "')' expected"); 4446 return MatchOperand_ParseFail; 4447 } 4448 4449 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 4450 4451 Parser.Lex(); // Eat the ')' token. 4452 4453 if (!IdVal) 4454 IdVal = MCConstantExpr::create(0, getContext()); 4455 4456 // Replace the register operand with the memory operand. 4457 std::unique_ptr<MipsOperand> op( 4458 static_cast<MipsOperand *>(Operands.back().release())); 4459 // Remove the register from the operands. 4460 // "op" will be managed by k_Memory. 4461 Operands.pop_back(); 4462 // Add the memory operand. 4463 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) { 4464 int64_t Imm; 4465 if (IdVal->evaluateAsAbsolute(Imm)) 4466 IdVal = MCConstantExpr::create(Imm, getContext()); 4467 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef) 4468 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(), 4469 getContext()); 4470 } 4471 4472 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this)); 4473 return MatchOperand_Success; 4474 } 4475 4476 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) { 4477 MCAsmParser &Parser = getParser(); 4478 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier()); 4479 if (Sym) { 4480 SMLoc S = Parser.getTok().getLoc(); 4481 const MCExpr *Expr; 4482 if (Sym->isVariable()) 4483 Expr = Sym->getVariableValue(); 4484 else 4485 return false; 4486 if (Expr->getKind() == MCExpr::SymbolRef) { 4487 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr); 4488 StringRef DefSymbol = Ref->getSymbol().getName(); 4489 if (DefSymbol.startswith("$")) { 4490 OperandMatchResultTy ResTy = 4491 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S); 4492 if (ResTy == MatchOperand_Success) { 4493 Parser.Lex(); 4494 return true; 4495 } else if (ResTy == MatchOperand_ParseFail) 4496 llvm_unreachable("Should never ParseFail"); 4497 return false; 4498 } 4499 } else if (Expr->getKind() == MCExpr::Constant) { 4500 Parser.Lex(); 4501 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr); 4502 Operands.push_back( 4503 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this)); 4504 return true; 4505 } 4506 } 4507 return false; 4508 } 4509 4510 MipsAsmParser::OperandMatchResultTy 4511 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands, 4512 StringRef Identifier, 4513 SMLoc S) { 4514 int Index = matchCPURegisterName(Identifier); 4515 if (Index != -1) { 4516 Operands.push_back(MipsOperand::createGPRReg( 4517 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 4518 return MatchOperand_Success; 4519 } 4520 4521 Index = matchHWRegsRegisterName(Identifier); 4522 if (Index != -1) { 4523 Operands.push_back(MipsOperand::createHWRegsReg( 4524 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 4525 return MatchOperand_Success; 4526 } 4527 4528 Index = matchFPURegisterName(Identifier); 4529 if (Index != -1) { 4530 Operands.push_back(MipsOperand::createFGRReg( 4531 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 4532 return MatchOperand_Success; 4533 } 4534 4535 Index = matchFCCRegisterName(Identifier); 4536 if (Index != -1) { 4537 Operands.push_back(MipsOperand::createFCCReg( 4538 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 4539 return MatchOperand_Success; 4540 } 4541 4542 Index = matchACRegisterName(Identifier); 4543 if (Index != -1) { 4544 Operands.push_back(MipsOperand::createACCReg( 4545 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 4546 return MatchOperand_Success; 4547 } 4548 4549 Index = matchMSA128RegisterName(Identifier); 4550 if (Index != -1) { 4551 Operands.push_back(MipsOperand::createMSA128Reg( 4552 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 4553 return MatchOperand_Success; 4554 } 4555 4556 Index = matchMSA128CtrlRegisterName(Identifier); 4557 if (Index != -1) { 4558 Operands.push_back(MipsOperand::createMSACtrlReg( 4559 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 4560 return MatchOperand_Success; 4561 } 4562 4563 return MatchOperand_NoMatch; 4564 } 4565 4566 MipsAsmParser::OperandMatchResultTy 4567 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) { 4568 MCAsmParser &Parser = getParser(); 4569 auto Token = Parser.getLexer().peekTok(false); 4570 4571 if (Token.is(AsmToken::Identifier)) { 4572 DEBUG(dbgs() << ".. identifier\n"); 4573 StringRef Identifier = Token.getIdentifier(); 4574 OperandMatchResultTy ResTy = 4575 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S); 4576 return ResTy; 4577 } else if (Token.is(AsmToken::Integer)) { 4578 DEBUG(dbgs() << ".. integer\n"); 4579 Operands.push_back(MipsOperand::createNumericReg( 4580 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(), 4581 *this)); 4582 return MatchOperand_Success; 4583 } 4584 4585 DEBUG(dbgs() << Parser.getTok().getKind() << "\n"); 4586 4587 return MatchOperand_NoMatch; 4588 } 4589 4590 MipsAsmParser::OperandMatchResultTy 4591 MipsAsmParser::parseAnyRegister(OperandVector &Operands) { 4592 MCAsmParser &Parser = getParser(); 4593 DEBUG(dbgs() << "parseAnyRegister\n"); 4594 4595 auto Token = Parser.getTok(); 4596 4597 SMLoc S = Token.getLoc(); 4598 4599 if (Token.isNot(AsmToken::Dollar)) { 4600 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n"); 4601 if (Token.is(AsmToken::Identifier)) { 4602 if (searchSymbolAlias(Operands)) 4603 return MatchOperand_Success; 4604 } 4605 DEBUG(dbgs() << ".. !symalias -> NoMatch\n"); 4606 return MatchOperand_NoMatch; 4607 } 4608 DEBUG(dbgs() << ".. $\n"); 4609 4610 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S); 4611 if (ResTy == MatchOperand_Success) { 4612 Parser.Lex(); // $ 4613 Parser.Lex(); // identifier 4614 } 4615 return ResTy; 4616 } 4617 4618 MipsAsmParser::OperandMatchResultTy 4619 MipsAsmParser::parseImm(OperandVector &Operands) { 4620 MCAsmParser &Parser = getParser(); 4621 switch (getLexer().getKind()) { 4622 default: 4623 return MatchOperand_NoMatch; 4624 case AsmToken::LParen: 4625 case AsmToken::Minus: 4626 case AsmToken::Plus: 4627 case AsmToken::Integer: 4628 case AsmToken::Tilde: 4629 case AsmToken::String: 4630 break; 4631 } 4632 4633 const MCExpr *IdVal; 4634 SMLoc S = Parser.getTok().getLoc(); 4635 if (getParser().parseExpression(IdVal)) 4636 return MatchOperand_ParseFail; 4637 4638 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 4639 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this)); 4640 return MatchOperand_Success; 4641 } 4642 4643 MipsAsmParser::OperandMatchResultTy 4644 MipsAsmParser::parseJumpTarget(OperandVector &Operands) { 4645 MCAsmParser &Parser = getParser(); 4646 DEBUG(dbgs() << "parseJumpTarget\n"); 4647 4648 SMLoc S = getLexer().getLoc(); 4649 4650 // Integers and expressions are acceptable 4651 OperandMatchResultTy ResTy = parseImm(Operands); 4652 if (ResTy != MatchOperand_NoMatch) 4653 return ResTy; 4654 4655 // Registers are a valid target and have priority over symbols. 4656 ResTy = parseAnyRegister(Operands); 4657 if (ResTy != MatchOperand_NoMatch) 4658 return ResTy; 4659 4660 const MCExpr *Expr = nullptr; 4661 if (Parser.parseExpression(Expr)) { 4662 // We have no way of knowing if a symbol was consumed so we must ParseFail 4663 return MatchOperand_ParseFail; 4664 } 4665 Operands.push_back( 4666 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this)); 4667 return MatchOperand_Success; 4668 } 4669 4670 MipsAsmParser::OperandMatchResultTy 4671 MipsAsmParser::parseInvNum(OperandVector &Operands) { 4672 MCAsmParser &Parser = getParser(); 4673 const MCExpr *IdVal; 4674 // If the first token is '$' we may have register operand. 4675 if (Parser.getTok().is(AsmToken::Dollar)) 4676 return MatchOperand_NoMatch; 4677 SMLoc S = Parser.getTok().getLoc(); 4678 if (getParser().parseExpression(IdVal)) 4679 return MatchOperand_ParseFail; 4680 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal); 4681 assert(MCE && "Unexpected MCExpr type."); 4682 int64_t Val = MCE->getValue(); 4683 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 4684 Operands.push_back(MipsOperand::CreateImm( 4685 MCConstantExpr::create(0 - Val, getContext()), S, E, *this)); 4686 return MatchOperand_Success; 4687 } 4688 4689 MipsAsmParser::OperandMatchResultTy 4690 MipsAsmParser::parseLSAImm(OperandVector &Operands) { 4691 MCAsmParser &Parser = getParser(); 4692 switch (getLexer().getKind()) { 4693 default: 4694 return MatchOperand_NoMatch; 4695 case AsmToken::LParen: 4696 case AsmToken::Plus: 4697 case AsmToken::Minus: 4698 case AsmToken::Integer: 4699 break; 4700 } 4701 4702 const MCExpr *Expr; 4703 SMLoc S = Parser.getTok().getLoc(); 4704 4705 if (getParser().parseExpression(Expr)) 4706 return MatchOperand_ParseFail; 4707 4708 int64_t Val; 4709 if (!Expr->evaluateAsAbsolute(Val)) { 4710 Error(S, "expected immediate value"); 4711 return MatchOperand_ParseFail; 4712 } 4713 4714 // The LSA instruction allows a 2-bit unsigned immediate. For this reason 4715 // and because the CPU always adds one to the immediate field, the allowed 4716 // range becomes 1..4. We'll only check the range here and will deal 4717 // with the addition/subtraction when actually decoding/encoding 4718 // the instruction. 4719 if (Val < 1 || Val > 4) { 4720 Error(S, "immediate not in range (1..4)"); 4721 return MatchOperand_ParseFail; 4722 } 4723 4724 Operands.push_back( 4725 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this)); 4726 return MatchOperand_Success; 4727 } 4728 4729 MipsAsmParser::OperandMatchResultTy 4730 MipsAsmParser::parseRegisterList(OperandVector &Operands) { 4731 MCAsmParser &Parser = getParser(); 4732 SmallVector<unsigned, 10> Regs; 4733 unsigned RegNo; 4734 unsigned PrevReg = Mips::NoRegister; 4735 bool RegRange = false; 4736 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands; 4737 4738 if (Parser.getTok().isNot(AsmToken::Dollar)) 4739 return MatchOperand_ParseFail; 4740 4741 SMLoc S = Parser.getTok().getLoc(); 4742 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) { 4743 SMLoc E = getLexer().getLoc(); 4744 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back()); 4745 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg(); 4746 if (RegRange) { 4747 // Remove last register operand because registers from register range 4748 // should be inserted first. 4749 if ((isGP64bit() && RegNo == Mips::RA_64) || 4750 (!isGP64bit() && RegNo == Mips::RA)) { 4751 Regs.push_back(RegNo); 4752 } else { 4753 unsigned TmpReg = PrevReg + 1; 4754 while (TmpReg <= RegNo) { 4755 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) || 4756 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) && 4757 isGP64bit())) { 4758 Error(E, "invalid register operand"); 4759 return MatchOperand_ParseFail; 4760 } 4761 4762 PrevReg = TmpReg; 4763 Regs.push_back(TmpReg++); 4764 } 4765 } 4766 4767 RegRange = false; 4768 } else { 4769 if ((PrevReg == Mips::NoRegister) && 4770 ((isGP64bit() && (RegNo != Mips::S0_64) && (RegNo != Mips::RA_64)) || 4771 (!isGP64bit() && (RegNo != Mips::S0) && (RegNo != Mips::RA)))) { 4772 Error(E, "$16 or $31 expected"); 4773 return MatchOperand_ParseFail; 4774 } else if (!(((RegNo == Mips::FP || RegNo == Mips::RA || 4775 (RegNo >= Mips::S0 && RegNo <= Mips::S7)) && 4776 !isGP64bit()) || 4777 ((RegNo == Mips::FP_64 || RegNo == Mips::RA_64 || 4778 (RegNo >= Mips::S0_64 && RegNo <= Mips::S7_64)) && 4779 isGP64bit()))) { 4780 Error(E, "invalid register operand"); 4781 return MatchOperand_ParseFail; 4782 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) && 4783 ((RegNo != Mips::FP && RegNo != Mips::RA && !isGP64bit()) || 4784 (RegNo != Mips::FP_64 && RegNo != Mips::RA_64 && 4785 isGP64bit()))) { 4786 Error(E, "consecutive register numbers expected"); 4787 return MatchOperand_ParseFail; 4788 } 4789 4790 Regs.push_back(RegNo); 4791 } 4792 4793 if (Parser.getTok().is(AsmToken::Minus)) 4794 RegRange = true; 4795 4796 if (!Parser.getTok().isNot(AsmToken::Minus) && 4797 !Parser.getTok().isNot(AsmToken::Comma)) { 4798 Error(E, "',' or '-' expected"); 4799 return MatchOperand_ParseFail; 4800 } 4801 4802 Lex(); // Consume comma or minus 4803 if (Parser.getTok().isNot(AsmToken::Dollar)) 4804 break; 4805 4806 PrevReg = RegNo; 4807 } 4808 4809 SMLoc E = Parser.getTok().getLoc(); 4810 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this)); 4811 parseMemOperand(Operands); 4812 return MatchOperand_Success; 4813 } 4814 4815 MipsAsmParser::OperandMatchResultTy 4816 MipsAsmParser::parseRegisterPair(OperandVector &Operands) { 4817 MCAsmParser &Parser = getParser(); 4818 4819 SMLoc S = Parser.getTok().getLoc(); 4820 if (parseAnyRegister(Operands) != MatchOperand_Success) 4821 return MatchOperand_ParseFail; 4822 4823 SMLoc E = Parser.getTok().getLoc(); 4824 MipsOperand Op = static_cast<MipsOperand &>(*Operands.back()); 4825 4826 Operands.pop_back(); 4827 Operands.push_back(MipsOperand::CreateRegPair(Op, S, E, *this)); 4828 return MatchOperand_Success; 4829 } 4830 4831 MipsAsmParser::OperandMatchResultTy 4832 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) { 4833 MCAsmParser &Parser = getParser(); 4834 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands; 4835 SmallVector<unsigned, 10> Regs; 4836 4837 if (Parser.getTok().isNot(AsmToken::Dollar)) 4838 return MatchOperand_ParseFail; 4839 4840 SMLoc S = Parser.getTok().getLoc(); 4841 4842 if (parseAnyRegister(TmpOperands) != MatchOperand_Success) 4843 return MatchOperand_ParseFail; 4844 4845 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back()); 4846 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg(); 4847 Regs.push_back(RegNo); 4848 4849 SMLoc E = Parser.getTok().getLoc(); 4850 if (Parser.getTok().isNot(AsmToken::Comma)) { 4851 Error(E, "',' expected"); 4852 return MatchOperand_ParseFail; 4853 } 4854 4855 // Remove comma. 4856 Parser.Lex(); 4857 4858 if (parseAnyRegister(TmpOperands) != MatchOperand_Success) 4859 return MatchOperand_ParseFail; 4860 4861 Reg = &static_cast<MipsOperand &>(*TmpOperands.back()); 4862 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg(); 4863 Regs.push_back(RegNo); 4864 4865 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this)); 4866 4867 return MatchOperand_Success; 4868 } 4869 4870 /// Sometimes (i.e. load/stores) the operand may be followed immediately by 4871 /// either this. 4872 /// ::= '(', register, ')' 4873 /// handle it before we iterate so we don't get tripped up by the lack of 4874 /// a comma. 4875 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) { 4876 MCAsmParser &Parser = getParser(); 4877 if (getLexer().is(AsmToken::LParen)) { 4878 Operands.push_back( 4879 MipsOperand::CreateToken("(", getLexer().getLoc(), *this)); 4880 Parser.Lex(); 4881 if (parseOperand(Operands, Name)) { 4882 SMLoc Loc = getLexer().getLoc(); 4883 Parser.eatToEndOfStatement(); 4884 return Error(Loc, "unexpected token in argument list"); 4885 } 4886 if (Parser.getTok().isNot(AsmToken::RParen)) { 4887 SMLoc Loc = getLexer().getLoc(); 4888 Parser.eatToEndOfStatement(); 4889 return Error(Loc, "unexpected token, expected ')'"); 4890 } 4891 Operands.push_back( 4892 MipsOperand::CreateToken(")", getLexer().getLoc(), *this)); 4893 Parser.Lex(); 4894 } 4895 return false; 4896 } 4897 4898 /// Sometimes (i.e. in MSA) the operand may be followed immediately by 4899 /// either one of these. 4900 /// ::= '[', register, ']' 4901 /// ::= '[', integer, ']' 4902 /// handle it before we iterate so we don't get tripped up by the lack of 4903 /// a comma. 4904 bool MipsAsmParser::parseBracketSuffix(StringRef Name, 4905 OperandVector &Operands) { 4906 MCAsmParser &Parser = getParser(); 4907 if (getLexer().is(AsmToken::LBrac)) { 4908 Operands.push_back( 4909 MipsOperand::CreateToken("[", getLexer().getLoc(), *this)); 4910 Parser.Lex(); 4911 if (parseOperand(Operands, Name)) { 4912 SMLoc Loc = getLexer().getLoc(); 4913 Parser.eatToEndOfStatement(); 4914 return Error(Loc, "unexpected token in argument list"); 4915 } 4916 if (Parser.getTok().isNot(AsmToken::RBrac)) { 4917 SMLoc Loc = getLexer().getLoc(); 4918 Parser.eatToEndOfStatement(); 4919 return Error(Loc, "unexpected token, expected ']'"); 4920 } 4921 Operands.push_back( 4922 MipsOperand::CreateToken("]", getLexer().getLoc(), *this)); 4923 Parser.Lex(); 4924 } 4925 return false; 4926 } 4927 4928 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 4929 SMLoc NameLoc, OperandVector &Operands) { 4930 MCAsmParser &Parser = getParser(); 4931 DEBUG(dbgs() << "ParseInstruction\n"); 4932 4933 // We have reached first instruction, module directive are now forbidden. 4934 getTargetStreamer().forbidModuleDirective(); 4935 4936 // Check if we have valid mnemonic 4937 if (!mnemonicIsValid(Name, 0)) { 4938 Parser.eatToEndOfStatement(); 4939 return Error(NameLoc, "unknown instruction"); 4940 } 4941 // First operand in MCInst is instruction mnemonic. 4942 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this)); 4943 4944 // Read the remaining operands. 4945 if (getLexer().isNot(AsmToken::EndOfStatement)) { 4946 // Read the first operand. 4947 if (parseOperand(Operands, Name)) { 4948 SMLoc Loc = getLexer().getLoc(); 4949 Parser.eatToEndOfStatement(); 4950 return Error(Loc, "unexpected token in argument list"); 4951 } 4952 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands)) 4953 return true; 4954 // AFAIK, parenthesis suffixes are never on the first operand 4955 4956 while (getLexer().is(AsmToken::Comma)) { 4957 Parser.Lex(); // Eat the comma. 4958 // Parse and remember the operand. 4959 if (parseOperand(Operands, Name)) { 4960 SMLoc Loc = getLexer().getLoc(); 4961 Parser.eatToEndOfStatement(); 4962 return Error(Loc, "unexpected token in argument list"); 4963 } 4964 // Parse bracket and parenthesis suffixes before we iterate 4965 if (getLexer().is(AsmToken::LBrac)) { 4966 if (parseBracketSuffix(Name, Operands)) 4967 return true; 4968 } else if (getLexer().is(AsmToken::LParen) && 4969 parseParenSuffix(Name, Operands)) 4970 return true; 4971 } 4972 } 4973 if (getLexer().isNot(AsmToken::EndOfStatement)) { 4974 SMLoc Loc = getLexer().getLoc(); 4975 Parser.eatToEndOfStatement(); 4976 return Error(Loc, "unexpected token in argument list"); 4977 } 4978 Parser.Lex(); // Consume the EndOfStatement. 4979 return false; 4980 } 4981 4982 // FIXME: Given that these have the same name, these should both be 4983 // consistent on affecting the Parser. 4984 bool MipsAsmParser::reportParseError(Twine ErrorMsg) { 4985 MCAsmParser &Parser = getParser(); 4986 SMLoc Loc = getLexer().getLoc(); 4987 Parser.eatToEndOfStatement(); 4988 return Error(Loc, ErrorMsg); 4989 } 4990 4991 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) { 4992 return Error(Loc, ErrorMsg); 4993 } 4994 4995 bool MipsAsmParser::parseSetNoAtDirective() { 4996 MCAsmParser &Parser = getParser(); 4997 // Line should look like: ".set noat". 4998 4999 // Set the $at register to $0. 5000 AssemblerOptions.back()->setATRegIndex(0); 5001 5002 Parser.Lex(); // Eat "noat". 5003 5004 // If this is not the end of the statement, report an error. 5005 if (getLexer().isNot(AsmToken::EndOfStatement)) { 5006 reportParseError("unexpected token, expected end of statement"); 5007 return false; 5008 } 5009 5010 getTargetStreamer().emitDirectiveSetNoAt(); 5011 Parser.Lex(); // Consume the EndOfStatement. 5012 return false; 5013 } 5014 5015 bool MipsAsmParser::parseSetAtDirective() { 5016 // Line can be: ".set at", which sets $at to $1 5017 // or ".set at=$reg", which sets $at to $reg. 5018 MCAsmParser &Parser = getParser(); 5019 Parser.Lex(); // Eat "at". 5020 5021 if (getLexer().is(AsmToken::EndOfStatement)) { 5022 // No register was specified, so we set $at to $1. 5023 AssemblerOptions.back()->setATRegIndex(1); 5024 5025 getTargetStreamer().emitDirectiveSetAt(); 5026 Parser.Lex(); // Consume the EndOfStatement. 5027 return false; 5028 } 5029 5030 if (getLexer().isNot(AsmToken::Equal)) { 5031 reportParseError("unexpected token, expected equals sign"); 5032 return false; 5033 } 5034 Parser.Lex(); // Eat "=". 5035 5036 if (getLexer().isNot(AsmToken::Dollar)) { 5037 if (getLexer().is(AsmToken::EndOfStatement)) { 5038 reportParseError("no register specified"); 5039 return false; 5040 } else { 5041 reportParseError("unexpected token, expected dollar sign '$'"); 5042 return false; 5043 } 5044 } 5045 Parser.Lex(); // Eat "$". 5046 5047 // Find out what "reg" is. 5048 unsigned AtRegNo; 5049 const AsmToken &Reg = Parser.getTok(); 5050 if (Reg.is(AsmToken::Identifier)) { 5051 AtRegNo = matchCPURegisterName(Reg.getIdentifier()); 5052 } else if (Reg.is(AsmToken::Integer)) { 5053 AtRegNo = Reg.getIntVal(); 5054 } else { 5055 reportParseError("unexpected token, expected identifier or integer"); 5056 return false; 5057 } 5058 5059 // Check if $reg is a valid register. If it is, set $at to $reg. 5060 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) { 5061 reportParseError("invalid register"); 5062 return false; 5063 } 5064 Parser.Lex(); // Eat "reg". 5065 5066 // If this is not the end of the statement, report an error. 5067 if (getLexer().isNot(AsmToken::EndOfStatement)) { 5068 reportParseError("unexpected token, expected end of statement"); 5069 return false; 5070 } 5071 5072 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo); 5073 5074 Parser.Lex(); // Consume the EndOfStatement. 5075 return false; 5076 } 5077 5078 bool MipsAsmParser::parseSetReorderDirective() { 5079 MCAsmParser &Parser = getParser(); 5080 Parser.Lex(); 5081 // If this is not the end of the statement, report an error. 5082 if (getLexer().isNot(AsmToken::EndOfStatement)) { 5083 reportParseError("unexpected token, expected end of statement"); 5084 return false; 5085 } 5086 AssemblerOptions.back()->setReorder(); 5087 getTargetStreamer().emitDirectiveSetReorder(); 5088 Parser.Lex(); // Consume the EndOfStatement. 5089 return false; 5090 } 5091 5092 bool MipsAsmParser::parseSetNoReorderDirective() { 5093 MCAsmParser &Parser = getParser(); 5094 Parser.Lex(); 5095 // If this is not the end of the statement, report an error. 5096 if (getLexer().isNot(AsmToken::EndOfStatement)) { 5097 reportParseError("unexpected token, expected end of statement"); 5098 return false; 5099 } 5100 AssemblerOptions.back()->setNoReorder(); 5101 getTargetStreamer().emitDirectiveSetNoReorder(); 5102 Parser.Lex(); // Consume the EndOfStatement. 5103 return false; 5104 } 5105 5106 bool MipsAsmParser::parseSetMacroDirective() { 5107 MCAsmParser &Parser = getParser(); 5108 Parser.Lex(); 5109 // If this is not the end of the statement, report an error. 5110 if (getLexer().isNot(AsmToken::EndOfStatement)) { 5111 reportParseError("unexpected token, expected end of statement"); 5112 return false; 5113 } 5114 AssemblerOptions.back()->setMacro(); 5115 getTargetStreamer().emitDirectiveSetMacro(); 5116 Parser.Lex(); // Consume the EndOfStatement. 5117 return false; 5118 } 5119 5120 bool MipsAsmParser::parseSetNoMacroDirective() { 5121 MCAsmParser &Parser = getParser(); 5122 Parser.Lex(); 5123 // If this is not the end of the statement, report an error. 5124 if (getLexer().isNot(AsmToken::EndOfStatement)) { 5125 reportParseError("unexpected token, expected end of statement"); 5126 return false; 5127 } 5128 if (AssemblerOptions.back()->isReorder()) { 5129 reportParseError("`noreorder' must be set before `nomacro'"); 5130 return false; 5131 } 5132 AssemblerOptions.back()->setNoMacro(); 5133 getTargetStreamer().emitDirectiveSetNoMacro(); 5134 Parser.Lex(); // Consume the EndOfStatement. 5135 return false; 5136 } 5137 5138 bool MipsAsmParser::parseSetMsaDirective() { 5139 MCAsmParser &Parser = getParser(); 5140 Parser.Lex(); 5141 5142 // If this is not the end of the statement, report an error. 5143 if (getLexer().isNot(AsmToken::EndOfStatement)) 5144 return reportParseError("unexpected token, expected end of statement"); 5145 5146 setFeatureBits(Mips::FeatureMSA, "msa"); 5147 getTargetStreamer().emitDirectiveSetMsa(); 5148 return false; 5149 } 5150 5151 bool MipsAsmParser::parseSetNoMsaDirective() { 5152 MCAsmParser &Parser = getParser(); 5153 Parser.Lex(); 5154 5155 // If this is not the end of the statement, report an error. 5156 if (getLexer().isNot(AsmToken::EndOfStatement)) 5157 return reportParseError("unexpected token, expected end of statement"); 5158 5159 clearFeatureBits(Mips::FeatureMSA, "msa"); 5160 getTargetStreamer().emitDirectiveSetNoMsa(); 5161 return false; 5162 } 5163 5164 bool MipsAsmParser::parseSetNoDspDirective() { 5165 MCAsmParser &Parser = getParser(); 5166 Parser.Lex(); // Eat "nodsp". 5167 5168 // If this is not the end of the statement, report an error. 5169 if (getLexer().isNot(AsmToken::EndOfStatement)) { 5170 reportParseError("unexpected token, expected end of statement"); 5171 return false; 5172 } 5173 5174 clearFeatureBits(Mips::FeatureDSP, "dsp"); 5175 getTargetStreamer().emitDirectiveSetNoDsp(); 5176 return false; 5177 } 5178 5179 bool MipsAsmParser::parseSetMips16Directive() { 5180 MCAsmParser &Parser = getParser(); 5181 Parser.Lex(); // Eat "mips16". 5182 5183 // If this is not the end of the statement, report an error. 5184 if (getLexer().isNot(AsmToken::EndOfStatement)) { 5185 reportParseError("unexpected token, expected end of statement"); 5186 return false; 5187 } 5188 5189 setFeatureBits(Mips::FeatureMips16, "mips16"); 5190 getTargetStreamer().emitDirectiveSetMips16(); 5191 Parser.Lex(); // Consume the EndOfStatement. 5192 return false; 5193 } 5194 5195 bool MipsAsmParser::parseSetNoMips16Directive() { 5196 MCAsmParser &Parser = getParser(); 5197 Parser.Lex(); // Eat "nomips16". 5198 5199 // If this is not the end of the statement, report an error. 5200 if (getLexer().isNot(AsmToken::EndOfStatement)) { 5201 reportParseError("unexpected token, expected end of statement"); 5202 return false; 5203 } 5204 5205 clearFeatureBits(Mips::FeatureMips16, "mips16"); 5206 getTargetStreamer().emitDirectiveSetNoMips16(); 5207 Parser.Lex(); // Consume the EndOfStatement. 5208 return false; 5209 } 5210 5211 bool MipsAsmParser::parseSetFpDirective() { 5212 MCAsmParser &Parser = getParser(); 5213 MipsABIFlagsSection::FpABIKind FpAbiVal; 5214 // Line can be: .set fp=32 5215 // .set fp=xx 5216 // .set fp=64 5217 Parser.Lex(); // Eat fp token 5218 AsmToken Tok = Parser.getTok(); 5219 if (Tok.isNot(AsmToken::Equal)) { 5220 reportParseError("unexpected token, expected equals sign '='"); 5221 return false; 5222 } 5223 Parser.Lex(); // Eat '=' token. 5224 Tok = Parser.getTok(); 5225 5226 if (!parseFpABIValue(FpAbiVal, ".set")) 5227 return false; 5228 5229 if (getLexer().isNot(AsmToken::EndOfStatement)) { 5230 reportParseError("unexpected token, expected end of statement"); 5231 return false; 5232 } 5233 getTargetStreamer().emitDirectiveSetFp(FpAbiVal); 5234 Parser.Lex(); // Consume the EndOfStatement. 5235 return false; 5236 } 5237 5238 bool MipsAsmParser::parseSetOddSPRegDirective() { 5239 MCAsmParser &Parser = getParser(); 5240 5241 Parser.Lex(); // Eat "oddspreg". 5242 if (getLexer().isNot(AsmToken::EndOfStatement)) { 5243 reportParseError("unexpected token, expected end of statement"); 5244 return false; 5245 } 5246 5247 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg"); 5248 getTargetStreamer().emitDirectiveSetOddSPReg(); 5249 return false; 5250 } 5251 5252 bool MipsAsmParser::parseSetNoOddSPRegDirective() { 5253 MCAsmParser &Parser = getParser(); 5254 5255 Parser.Lex(); // Eat "nooddspreg". 5256 if (getLexer().isNot(AsmToken::EndOfStatement)) { 5257 reportParseError("unexpected token, expected end of statement"); 5258 return false; 5259 } 5260 5261 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg"); 5262 getTargetStreamer().emitDirectiveSetNoOddSPReg(); 5263 return false; 5264 } 5265 5266 bool MipsAsmParser::parseSetPopDirective() { 5267 MCAsmParser &Parser = getParser(); 5268 SMLoc Loc = getLexer().getLoc(); 5269 5270 Parser.Lex(); 5271 if (getLexer().isNot(AsmToken::EndOfStatement)) 5272 return reportParseError("unexpected token, expected end of statement"); 5273 5274 // Always keep an element on the options "stack" to prevent the user 5275 // from changing the initial options. This is how we remember them. 5276 if (AssemblerOptions.size() == 2) 5277 return reportParseError(Loc, ".set pop with no .set push"); 5278 5279 MCSubtargetInfo &STI = copySTI(); 5280 AssemblerOptions.pop_back(); 5281 setAvailableFeatures( 5282 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures())); 5283 STI.setFeatureBits(AssemblerOptions.back()->getFeatures()); 5284 5285 getTargetStreamer().emitDirectiveSetPop(); 5286 return false; 5287 } 5288 5289 bool MipsAsmParser::parseSetPushDirective() { 5290 MCAsmParser &Parser = getParser(); 5291 Parser.Lex(); 5292 if (getLexer().isNot(AsmToken::EndOfStatement)) 5293 return reportParseError("unexpected token, expected end of statement"); 5294 5295 // Create a copy of the current assembler options environment and push it. 5296 AssemblerOptions.push_back( 5297 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get())); 5298 5299 getTargetStreamer().emitDirectiveSetPush(); 5300 return false; 5301 } 5302 5303 bool MipsAsmParser::parseSetSoftFloatDirective() { 5304 MCAsmParser &Parser = getParser(); 5305 Parser.Lex(); 5306 if (getLexer().isNot(AsmToken::EndOfStatement)) 5307 return reportParseError("unexpected token, expected end of statement"); 5308 5309 setFeatureBits(Mips::FeatureSoftFloat, "soft-float"); 5310 getTargetStreamer().emitDirectiveSetSoftFloat(); 5311 return false; 5312 } 5313 5314 bool MipsAsmParser::parseSetHardFloatDirective() { 5315 MCAsmParser &Parser = getParser(); 5316 Parser.Lex(); 5317 if (getLexer().isNot(AsmToken::EndOfStatement)) 5318 return reportParseError("unexpected token, expected end of statement"); 5319 5320 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float"); 5321 getTargetStreamer().emitDirectiveSetHardFloat(); 5322 return false; 5323 } 5324 5325 bool MipsAsmParser::parseSetAssignment() { 5326 StringRef Name; 5327 const MCExpr *Value; 5328 MCAsmParser &Parser = getParser(); 5329 5330 if (Parser.parseIdentifier(Name)) 5331 reportParseError("expected identifier after .set"); 5332 5333 if (getLexer().isNot(AsmToken::Comma)) 5334 return reportParseError("unexpected token, expected comma"); 5335 Lex(); // Eat comma 5336 5337 if (Parser.parseExpression(Value)) 5338 return reportParseError("expected valid expression after comma"); 5339 5340 MCSymbol *Sym = getContext().getOrCreateSymbol(Name); 5341 Sym->setVariableValue(Value); 5342 5343 return false; 5344 } 5345 5346 bool MipsAsmParser::parseSetMips0Directive() { 5347 MCAsmParser &Parser = getParser(); 5348 Parser.Lex(); 5349 if (getLexer().isNot(AsmToken::EndOfStatement)) 5350 return reportParseError("unexpected token, expected end of statement"); 5351 5352 // Reset assembler options to their initial values. 5353 MCSubtargetInfo &STI = copySTI(); 5354 setAvailableFeatures( 5355 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures())); 5356 STI.setFeatureBits(AssemblerOptions.front()->getFeatures()); 5357 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures()); 5358 5359 getTargetStreamer().emitDirectiveSetMips0(); 5360 return false; 5361 } 5362 5363 bool MipsAsmParser::parseSetArchDirective() { 5364 MCAsmParser &Parser = getParser(); 5365 Parser.Lex(); 5366 if (getLexer().isNot(AsmToken::Equal)) 5367 return reportParseError("unexpected token, expected equals sign"); 5368 5369 Parser.Lex(); 5370 StringRef Arch; 5371 if (Parser.parseIdentifier(Arch)) 5372 return reportParseError("expected arch identifier"); 5373 5374 StringRef ArchFeatureName = 5375 StringSwitch<StringRef>(Arch) 5376 .Case("mips1", "mips1") 5377 .Case("mips2", "mips2") 5378 .Case("mips3", "mips3") 5379 .Case("mips4", "mips4") 5380 .Case("mips5", "mips5") 5381 .Case("mips32", "mips32") 5382 .Case("mips32r2", "mips32r2") 5383 .Case("mips32r3", "mips32r3") 5384 .Case("mips32r5", "mips32r5") 5385 .Case("mips32r6", "mips32r6") 5386 .Case("mips64", "mips64") 5387 .Case("mips64r2", "mips64r2") 5388 .Case("mips64r3", "mips64r3") 5389 .Case("mips64r5", "mips64r5") 5390 .Case("mips64r6", "mips64r6") 5391 .Case("octeon", "cnmips") 5392 .Case("r4000", "mips3") // This is an implementation of Mips3. 5393 .Default(""); 5394 5395 if (ArchFeatureName.empty()) 5396 return reportParseError("unsupported architecture"); 5397 5398 selectArch(ArchFeatureName); 5399 getTargetStreamer().emitDirectiveSetArch(Arch); 5400 return false; 5401 } 5402 5403 bool MipsAsmParser::parseSetFeature(uint64_t Feature) { 5404 MCAsmParser &Parser = getParser(); 5405 Parser.Lex(); 5406 if (getLexer().isNot(AsmToken::EndOfStatement)) 5407 return reportParseError("unexpected token, expected end of statement"); 5408 5409 switch (Feature) { 5410 default: 5411 llvm_unreachable("Unimplemented feature"); 5412 case Mips::FeatureDSP: 5413 setFeatureBits(Mips::FeatureDSP, "dsp"); 5414 getTargetStreamer().emitDirectiveSetDsp(); 5415 break; 5416 case Mips::FeatureMicroMips: 5417 setFeatureBits(Mips::FeatureMicroMips, "micromips"); 5418 getTargetStreamer().emitDirectiveSetMicroMips(); 5419 break; 5420 case Mips::FeatureMips1: 5421 selectArch("mips1"); 5422 getTargetStreamer().emitDirectiveSetMips1(); 5423 break; 5424 case Mips::FeatureMips2: 5425 selectArch("mips2"); 5426 getTargetStreamer().emitDirectiveSetMips2(); 5427 break; 5428 case Mips::FeatureMips3: 5429 selectArch("mips3"); 5430 getTargetStreamer().emitDirectiveSetMips3(); 5431 break; 5432 case Mips::FeatureMips4: 5433 selectArch("mips4"); 5434 getTargetStreamer().emitDirectiveSetMips4(); 5435 break; 5436 case Mips::FeatureMips5: 5437 selectArch("mips5"); 5438 getTargetStreamer().emitDirectiveSetMips5(); 5439 break; 5440 case Mips::FeatureMips32: 5441 selectArch("mips32"); 5442 getTargetStreamer().emitDirectiveSetMips32(); 5443 break; 5444 case Mips::FeatureMips32r2: 5445 selectArch("mips32r2"); 5446 getTargetStreamer().emitDirectiveSetMips32R2(); 5447 break; 5448 case Mips::FeatureMips32r3: 5449 selectArch("mips32r3"); 5450 getTargetStreamer().emitDirectiveSetMips32R3(); 5451 break; 5452 case Mips::FeatureMips32r5: 5453 selectArch("mips32r5"); 5454 getTargetStreamer().emitDirectiveSetMips32R5(); 5455 break; 5456 case Mips::FeatureMips32r6: 5457 selectArch("mips32r6"); 5458 getTargetStreamer().emitDirectiveSetMips32R6(); 5459 break; 5460 case Mips::FeatureMips64: 5461 selectArch("mips64"); 5462 getTargetStreamer().emitDirectiveSetMips64(); 5463 break; 5464 case Mips::FeatureMips64r2: 5465 selectArch("mips64r2"); 5466 getTargetStreamer().emitDirectiveSetMips64R2(); 5467 break; 5468 case Mips::FeatureMips64r3: 5469 selectArch("mips64r3"); 5470 getTargetStreamer().emitDirectiveSetMips64R3(); 5471 break; 5472 case Mips::FeatureMips64r5: 5473 selectArch("mips64r5"); 5474 getTargetStreamer().emitDirectiveSetMips64R5(); 5475 break; 5476 case Mips::FeatureMips64r6: 5477 selectArch("mips64r6"); 5478 getTargetStreamer().emitDirectiveSetMips64R6(); 5479 break; 5480 } 5481 return false; 5482 } 5483 5484 bool MipsAsmParser::eatComma(StringRef ErrorStr) { 5485 MCAsmParser &Parser = getParser(); 5486 if (getLexer().isNot(AsmToken::Comma)) { 5487 SMLoc Loc = getLexer().getLoc(); 5488 Parser.eatToEndOfStatement(); 5489 return Error(Loc, ErrorStr); 5490 } 5491 5492 Parser.Lex(); // Eat the comma. 5493 return true; 5494 } 5495 5496 // Used to determine if .cpload, .cprestore, and .cpsetup have any effect. 5497 // In this class, it is only used for .cprestore. 5498 // FIXME: Only keep track of IsPicEnabled in one place, instead of in both 5499 // MipsTargetELFStreamer and MipsAsmParser. 5500 bool MipsAsmParser::isPicAndNotNxxAbi() { 5501 return inPicMode() && !(isABI_N32() || isABI_N64()); 5502 } 5503 5504 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) { 5505 if (AssemblerOptions.back()->isReorder()) 5506 Warning(Loc, ".cpload should be inside a noreorder section"); 5507 5508 if (inMips16Mode()) { 5509 reportParseError(".cpload is not supported in Mips16 mode"); 5510 return false; 5511 } 5512 5513 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg; 5514 OperandMatchResultTy ResTy = parseAnyRegister(Reg); 5515 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) { 5516 reportParseError("expected register containing function address"); 5517 return false; 5518 } 5519 5520 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]); 5521 if (!RegOpnd.isGPRAsmReg()) { 5522 reportParseError(RegOpnd.getStartLoc(), "invalid register"); 5523 return false; 5524 } 5525 5526 // If this is not the end of the statement, report an error. 5527 if (getLexer().isNot(AsmToken::EndOfStatement)) { 5528 reportParseError("unexpected token, expected end of statement"); 5529 return false; 5530 } 5531 5532 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg()); 5533 return false; 5534 } 5535 5536 bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) { 5537 MCAsmParser &Parser = getParser(); 5538 5539 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it 5540 // is used in non-PIC mode. 5541 5542 if (inMips16Mode()) { 5543 reportParseError(".cprestore is not supported in Mips16 mode"); 5544 return false; 5545 } 5546 5547 // Get the stack offset value. 5548 const MCExpr *StackOffset; 5549 int64_t StackOffsetVal; 5550 if (Parser.parseExpression(StackOffset)) { 5551 reportParseError("expected stack offset value"); 5552 return false; 5553 } 5554 5555 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) { 5556 reportParseError("stack offset is not an absolute expression"); 5557 return false; 5558 } 5559 5560 if (StackOffsetVal < 0) { 5561 Warning(Loc, ".cprestore with negative stack offset has no effect"); 5562 IsCpRestoreSet = false; 5563 } else { 5564 IsCpRestoreSet = true; 5565 CpRestoreOffset = StackOffsetVal; 5566 } 5567 5568 // If this is not the end of the statement, report an error. 5569 if (getLexer().isNot(AsmToken::EndOfStatement)) { 5570 reportParseError("unexpected token, expected end of statement"); 5571 return false; 5572 } 5573 5574 if (!getTargetStreamer().emitDirectiveCpRestore( 5575 CpRestoreOffset, [&]() { return getATReg(Loc); }, Loc, STI)) 5576 return true; 5577 Parser.Lex(); // Consume the EndOfStatement. 5578 return false; 5579 } 5580 5581 bool MipsAsmParser::parseDirectiveCPSetup() { 5582 MCAsmParser &Parser = getParser(); 5583 unsigned FuncReg; 5584 unsigned Save; 5585 bool SaveIsReg = true; 5586 5587 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg; 5588 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg); 5589 if (ResTy == MatchOperand_NoMatch) { 5590 reportParseError("expected register containing function address"); 5591 return false; 5592 } 5593 5594 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]); 5595 if (!FuncRegOpnd.isGPRAsmReg()) { 5596 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register"); 5597 Parser.eatToEndOfStatement(); 5598 return false; 5599 } 5600 5601 FuncReg = FuncRegOpnd.getGPR32Reg(); 5602 TmpReg.clear(); 5603 5604 if (!eatComma("unexpected token, expected comma")) 5605 return true; 5606 5607 ResTy = parseAnyRegister(TmpReg); 5608 if (ResTy == MatchOperand_NoMatch) { 5609 const MCExpr *OffsetExpr; 5610 int64_t OffsetVal; 5611 SMLoc ExprLoc = getLexer().getLoc(); 5612 5613 if (Parser.parseExpression(OffsetExpr) || 5614 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) { 5615 reportParseError(ExprLoc, "expected save register or stack offset"); 5616 Parser.eatToEndOfStatement(); 5617 return false; 5618 } 5619 5620 Save = OffsetVal; 5621 SaveIsReg = false; 5622 } else { 5623 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]); 5624 if (!SaveOpnd.isGPRAsmReg()) { 5625 reportParseError(SaveOpnd.getStartLoc(), "invalid register"); 5626 Parser.eatToEndOfStatement(); 5627 return false; 5628 } 5629 Save = SaveOpnd.getGPR32Reg(); 5630 } 5631 5632 if (!eatComma("unexpected token, expected comma")) 5633 return true; 5634 5635 const MCExpr *Expr; 5636 if (Parser.parseExpression(Expr)) { 5637 reportParseError("expected expression"); 5638 return false; 5639 } 5640 5641 if (Expr->getKind() != MCExpr::SymbolRef) { 5642 reportParseError("expected symbol"); 5643 return false; 5644 } 5645 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr); 5646 5647 CpSaveLocation = Save; 5648 CpSaveLocationIsRegister = SaveIsReg; 5649 5650 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(), 5651 SaveIsReg); 5652 return false; 5653 } 5654 5655 bool MipsAsmParser::parseDirectiveCPReturn() { 5656 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation, 5657 CpSaveLocationIsRegister); 5658 return false; 5659 } 5660 5661 bool MipsAsmParser::parseDirectiveNaN() { 5662 MCAsmParser &Parser = getParser(); 5663 if (getLexer().isNot(AsmToken::EndOfStatement)) { 5664 const AsmToken &Tok = Parser.getTok(); 5665 5666 if (Tok.getString() == "2008") { 5667 Parser.Lex(); 5668 getTargetStreamer().emitDirectiveNaN2008(); 5669 return false; 5670 } else if (Tok.getString() == "legacy") { 5671 Parser.Lex(); 5672 getTargetStreamer().emitDirectiveNaNLegacy(); 5673 return false; 5674 } 5675 } 5676 // If we don't recognize the option passed to the .nan 5677 // directive (e.g. no option or unknown option), emit an error. 5678 reportParseError("invalid option in .nan directive"); 5679 return false; 5680 } 5681 5682 bool MipsAsmParser::parseDirectiveSet() { 5683 MCAsmParser &Parser = getParser(); 5684 // Get the next token. 5685 const AsmToken &Tok = Parser.getTok(); 5686 5687 if (Tok.getString() == "noat") { 5688 return parseSetNoAtDirective(); 5689 } else if (Tok.getString() == "at") { 5690 return parseSetAtDirective(); 5691 } else if (Tok.getString() == "arch") { 5692 return parseSetArchDirective(); 5693 } else if (Tok.getString() == "fp") { 5694 return parseSetFpDirective(); 5695 } else if (Tok.getString() == "oddspreg") { 5696 return parseSetOddSPRegDirective(); 5697 } else if (Tok.getString() == "nooddspreg") { 5698 return parseSetNoOddSPRegDirective(); 5699 } else if (Tok.getString() == "pop") { 5700 return parseSetPopDirective(); 5701 } else if (Tok.getString() == "push") { 5702 return parseSetPushDirective(); 5703 } else if (Tok.getString() == "reorder") { 5704 return parseSetReorderDirective(); 5705 } else if (Tok.getString() == "noreorder") { 5706 return parseSetNoReorderDirective(); 5707 } else if (Tok.getString() == "macro") { 5708 return parseSetMacroDirective(); 5709 } else if (Tok.getString() == "nomacro") { 5710 return parseSetNoMacroDirective(); 5711 } else if (Tok.getString() == "mips16") { 5712 return parseSetMips16Directive(); 5713 } else if (Tok.getString() == "nomips16") { 5714 return parseSetNoMips16Directive(); 5715 } else if (Tok.getString() == "nomicromips") { 5716 clearFeatureBits(Mips::FeatureMicroMips, "micromips"); 5717 getTargetStreamer().emitDirectiveSetNoMicroMips(); 5718 Parser.eatToEndOfStatement(); 5719 return false; 5720 } else if (Tok.getString() == "micromips") { 5721 return parseSetFeature(Mips::FeatureMicroMips); 5722 } else if (Tok.getString() == "mips0") { 5723 return parseSetMips0Directive(); 5724 } else if (Tok.getString() == "mips1") { 5725 return parseSetFeature(Mips::FeatureMips1); 5726 } else if (Tok.getString() == "mips2") { 5727 return parseSetFeature(Mips::FeatureMips2); 5728 } else if (Tok.getString() == "mips3") { 5729 return parseSetFeature(Mips::FeatureMips3); 5730 } else if (Tok.getString() == "mips4") { 5731 return parseSetFeature(Mips::FeatureMips4); 5732 } else if (Tok.getString() == "mips5") { 5733 return parseSetFeature(Mips::FeatureMips5); 5734 } else if (Tok.getString() == "mips32") { 5735 return parseSetFeature(Mips::FeatureMips32); 5736 } else if (Tok.getString() == "mips32r2") { 5737 return parseSetFeature(Mips::FeatureMips32r2); 5738 } else if (Tok.getString() == "mips32r3") { 5739 return parseSetFeature(Mips::FeatureMips32r3); 5740 } else if (Tok.getString() == "mips32r5") { 5741 return parseSetFeature(Mips::FeatureMips32r5); 5742 } else if (Tok.getString() == "mips32r6") { 5743 return parseSetFeature(Mips::FeatureMips32r6); 5744 } else if (Tok.getString() == "mips64") { 5745 return parseSetFeature(Mips::FeatureMips64); 5746 } else if (Tok.getString() == "mips64r2") { 5747 return parseSetFeature(Mips::FeatureMips64r2); 5748 } else if (Tok.getString() == "mips64r3") { 5749 return parseSetFeature(Mips::FeatureMips64r3); 5750 } else if (Tok.getString() == "mips64r5") { 5751 return parseSetFeature(Mips::FeatureMips64r5); 5752 } else if (Tok.getString() == "mips64r6") { 5753 return parseSetFeature(Mips::FeatureMips64r6); 5754 } else if (Tok.getString() == "dsp") { 5755 return parseSetFeature(Mips::FeatureDSP); 5756 } else if (Tok.getString() == "nodsp") { 5757 return parseSetNoDspDirective(); 5758 } else if (Tok.getString() == "msa") { 5759 return parseSetMsaDirective(); 5760 } else if (Tok.getString() == "nomsa") { 5761 return parseSetNoMsaDirective(); 5762 } else if (Tok.getString() == "softfloat") { 5763 return parseSetSoftFloatDirective(); 5764 } else if (Tok.getString() == "hardfloat") { 5765 return parseSetHardFloatDirective(); 5766 } else { 5767 // It is just an identifier, look for an assignment. 5768 parseSetAssignment(); 5769 return false; 5770 } 5771 5772 return true; 5773 } 5774 5775 /// parseDataDirective 5776 /// ::= .word [ expression (, expression)* ] 5777 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) { 5778 MCAsmParser &Parser = getParser(); 5779 if (getLexer().isNot(AsmToken::EndOfStatement)) { 5780 for (;;) { 5781 const MCExpr *Value; 5782 if (getParser().parseExpression(Value)) 5783 return true; 5784 5785 getParser().getStreamer().EmitValue(Value, Size); 5786 5787 if (getLexer().is(AsmToken::EndOfStatement)) 5788 break; 5789 5790 if (getLexer().isNot(AsmToken::Comma)) 5791 return Error(L, "unexpected token, expected comma"); 5792 Parser.Lex(); 5793 } 5794 } 5795 5796 Parser.Lex(); 5797 return false; 5798 } 5799 5800 /// parseDirectiveGpWord 5801 /// ::= .gpword local_sym 5802 bool MipsAsmParser::parseDirectiveGpWord() { 5803 MCAsmParser &Parser = getParser(); 5804 const MCExpr *Value; 5805 // EmitGPRel32Value requires an expression, so we are using base class 5806 // method to evaluate the expression. 5807 if (getParser().parseExpression(Value)) 5808 return true; 5809 getParser().getStreamer().EmitGPRel32Value(Value); 5810 5811 if (getLexer().isNot(AsmToken::EndOfStatement)) 5812 return Error(getLexer().getLoc(), 5813 "unexpected token, expected end of statement"); 5814 Parser.Lex(); // Eat EndOfStatement token. 5815 return false; 5816 } 5817 5818 /// parseDirectiveGpDWord 5819 /// ::= .gpdword local_sym 5820 bool MipsAsmParser::parseDirectiveGpDWord() { 5821 MCAsmParser &Parser = getParser(); 5822 const MCExpr *Value; 5823 // EmitGPRel64Value requires an expression, so we are using base class 5824 // method to evaluate the expression. 5825 if (getParser().parseExpression(Value)) 5826 return true; 5827 getParser().getStreamer().EmitGPRel64Value(Value); 5828 5829 if (getLexer().isNot(AsmToken::EndOfStatement)) 5830 return Error(getLexer().getLoc(), 5831 "unexpected token, expected end of statement"); 5832 Parser.Lex(); // Eat EndOfStatement token. 5833 return false; 5834 } 5835 5836 bool MipsAsmParser::parseDirectiveOption() { 5837 MCAsmParser &Parser = getParser(); 5838 // Get the option token. 5839 AsmToken Tok = Parser.getTok(); 5840 // At the moment only identifiers are supported. 5841 if (Tok.isNot(AsmToken::Identifier)) { 5842 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier"); 5843 Parser.eatToEndOfStatement(); 5844 return false; 5845 } 5846 5847 StringRef Option = Tok.getIdentifier(); 5848 5849 if (Option == "pic0") { 5850 // MipsAsmParser needs to know if the current PIC mode changes. 5851 IsPicEnabled = false; 5852 5853 getTargetStreamer().emitDirectiveOptionPic0(); 5854 Parser.Lex(); 5855 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) { 5856 Error(Parser.getTok().getLoc(), 5857 "unexpected token, expected end of statement"); 5858 Parser.eatToEndOfStatement(); 5859 } 5860 return false; 5861 } 5862 5863 if (Option == "pic2") { 5864 // MipsAsmParser needs to know if the current PIC mode changes. 5865 IsPicEnabled = true; 5866 5867 getTargetStreamer().emitDirectiveOptionPic2(); 5868 Parser.Lex(); 5869 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) { 5870 Error(Parser.getTok().getLoc(), 5871 "unexpected token, expected end of statement"); 5872 Parser.eatToEndOfStatement(); 5873 } 5874 return false; 5875 } 5876 5877 // Unknown option. 5878 Warning(Parser.getTok().getLoc(), 5879 "unknown option, expected 'pic0' or 'pic2'"); 5880 Parser.eatToEndOfStatement(); 5881 return false; 5882 } 5883 5884 /// parseInsnDirective 5885 /// ::= .insn 5886 bool MipsAsmParser::parseInsnDirective() { 5887 // If this is not the end of the statement, report an error. 5888 if (getLexer().isNot(AsmToken::EndOfStatement)) { 5889 reportParseError("unexpected token, expected end of statement"); 5890 return false; 5891 } 5892 5893 // The actual label marking happens in 5894 // MipsELFStreamer::createPendingLabelRelocs(). 5895 getTargetStreamer().emitDirectiveInsn(); 5896 5897 getParser().Lex(); // Eat EndOfStatement token. 5898 return false; 5899 } 5900 5901 /// parseSSectionDirective 5902 /// ::= .sbss 5903 /// ::= .sdata 5904 bool MipsAsmParser::parseSSectionDirective(StringRef Section, unsigned Type) { 5905 // If this is not the end of the statement, report an error. 5906 if (getLexer().isNot(AsmToken::EndOfStatement)) { 5907 reportParseError("unexpected token, expected end of statement"); 5908 return false; 5909 } 5910 5911 MCSection *ELFSection = getContext().getELFSection( 5912 Section, Type, ELF::SHF_WRITE | ELF::SHF_ALLOC | ELF::SHF_MIPS_GPREL); 5913 getParser().getStreamer().SwitchSection(ELFSection); 5914 5915 getParser().Lex(); // Eat EndOfStatement token. 5916 return false; 5917 } 5918 5919 /// parseDirectiveModule 5920 /// ::= .module oddspreg 5921 /// ::= .module nooddspreg 5922 /// ::= .module fp=value 5923 /// ::= .module softfloat 5924 /// ::= .module hardfloat 5925 bool MipsAsmParser::parseDirectiveModule() { 5926 MCAsmParser &Parser = getParser(); 5927 MCAsmLexer &Lexer = getLexer(); 5928 SMLoc L = Lexer.getLoc(); 5929 5930 if (!getTargetStreamer().isModuleDirectiveAllowed()) { 5931 // TODO : get a better message. 5932 reportParseError(".module directive must appear before any code"); 5933 return false; 5934 } 5935 5936 StringRef Option; 5937 if (Parser.parseIdentifier(Option)) { 5938 reportParseError("expected .module option identifier"); 5939 return false; 5940 } 5941 5942 if (Option == "oddspreg") { 5943 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg"); 5944 5945 // Synchronize the abiflags information with the FeatureBits information we 5946 // changed above. 5947 getTargetStreamer().updateABIInfo(*this); 5948 5949 // If printing assembly, use the recently updated abiflags information. 5950 // If generating ELF, don't do anything (the .MIPS.abiflags section gets 5951 // emitted at the end). 5952 getTargetStreamer().emitDirectiveModuleOddSPReg(); 5953 5954 // If this is not the end of the statement, report an error. 5955 if (getLexer().isNot(AsmToken::EndOfStatement)) { 5956 reportParseError("unexpected token, expected end of statement"); 5957 return false; 5958 } 5959 5960 return false; // parseDirectiveModule has finished successfully. 5961 } else if (Option == "nooddspreg") { 5962 if (!isABI_O32()) { 5963 Error(L, "'.module nooddspreg' requires the O32 ABI"); 5964 return false; 5965 } 5966 5967 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg"); 5968 5969 // Synchronize the abiflags information with the FeatureBits information we 5970 // changed above. 5971 getTargetStreamer().updateABIInfo(*this); 5972 5973 // If printing assembly, use the recently updated abiflags information. 5974 // If generating ELF, don't do anything (the .MIPS.abiflags section gets 5975 // emitted at the end). 5976 getTargetStreamer().emitDirectiveModuleOddSPReg(); 5977 5978 // If this is not the end of the statement, report an error. 5979 if (getLexer().isNot(AsmToken::EndOfStatement)) { 5980 reportParseError("unexpected token, expected end of statement"); 5981 return false; 5982 } 5983 5984 return false; // parseDirectiveModule has finished successfully. 5985 } else if (Option == "fp") { 5986 return parseDirectiveModuleFP(); 5987 } else if (Option == "softfloat") { 5988 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float"); 5989 5990 // Synchronize the ABI Flags information with the FeatureBits information we 5991 // updated above. 5992 getTargetStreamer().updateABIInfo(*this); 5993 5994 // If printing assembly, use the recently updated ABI Flags information. 5995 // If generating ELF, don't do anything (the .MIPS.abiflags section gets 5996 // emitted later). 5997 getTargetStreamer().emitDirectiveModuleSoftFloat(); 5998 5999 // If this is not the end of the statement, report an error. 6000 if (getLexer().isNot(AsmToken::EndOfStatement)) { 6001 reportParseError("unexpected token, expected end of statement"); 6002 return false; 6003 } 6004 6005 return false; // parseDirectiveModule has finished successfully. 6006 } else if (Option == "hardfloat") { 6007 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float"); 6008 6009 // Synchronize the ABI Flags information with the FeatureBits information we 6010 // updated above. 6011 getTargetStreamer().updateABIInfo(*this); 6012 6013 // If printing assembly, use the recently updated ABI Flags information. 6014 // If generating ELF, don't do anything (the .MIPS.abiflags section gets 6015 // emitted later). 6016 getTargetStreamer().emitDirectiveModuleHardFloat(); 6017 6018 // If this is not the end of the statement, report an error. 6019 if (getLexer().isNot(AsmToken::EndOfStatement)) { 6020 reportParseError("unexpected token, expected end of statement"); 6021 return false; 6022 } 6023 6024 return false; // parseDirectiveModule has finished successfully. 6025 } else { 6026 return Error(L, "'" + Twine(Option) + "' is not a valid .module option."); 6027 } 6028 } 6029 6030 /// parseDirectiveModuleFP 6031 /// ::= =32 6032 /// ::= =xx 6033 /// ::= =64 6034 bool MipsAsmParser::parseDirectiveModuleFP() { 6035 MCAsmParser &Parser = getParser(); 6036 MCAsmLexer &Lexer = getLexer(); 6037 6038 if (Lexer.isNot(AsmToken::Equal)) { 6039 reportParseError("unexpected token, expected equals sign '='"); 6040 return false; 6041 } 6042 Parser.Lex(); // Eat '=' token. 6043 6044 MipsABIFlagsSection::FpABIKind FpABI; 6045 if (!parseFpABIValue(FpABI, ".module")) 6046 return false; 6047 6048 if (getLexer().isNot(AsmToken::EndOfStatement)) { 6049 reportParseError("unexpected token, expected end of statement"); 6050 return false; 6051 } 6052 6053 // Synchronize the abiflags information with the FeatureBits information we 6054 // changed above. 6055 getTargetStreamer().updateABIInfo(*this); 6056 6057 // If printing assembly, use the recently updated abiflags information. 6058 // If generating ELF, don't do anything (the .MIPS.abiflags section gets 6059 // emitted at the end). 6060 getTargetStreamer().emitDirectiveModuleFP(); 6061 6062 Parser.Lex(); // Consume the EndOfStatement. 6063 return false; 6064 } 6065 6066 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI, 6067 StringRef Directive) { 6068 MCAsmParser &Parser = getParser(); 6069 MCAsmLexer &Lexer = getLexer(); 6070 bool ModuleLevelOptions = Directive == ".module"; 6071 6072 if (Lexer.is(AsmToken::Identifier)) { 6073 StringRef Value = Parser.getTok().getString(); 6074 Parser.Lex(); 6075 6076 if (Value != "xx") { 6077 reportParseError("unsupported value, expected 'xx', '32' or '64'"); 6078 return false; 6079 } 6080 6081 if (!isABI_O32()) { 6082 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI"); 6083 return false; 6084 } 6085 6086 FpABI = MipsABIFlagsSection::FpABIKind::XX; 6087 if (ModuleLevelOptions) { 6088 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx"); 6089 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64"); 6090 } else { 6091 setFeatureBits(Mips::FeatureFPXX, "fpxx"); 6092 clearFeatureBits(Mips::FeatureFP64Bit, "fp64"); 6093 } 6094 return true; 6095 } 6096 6097 if (Lexer.is(AsmToken::Integer)) { 6098 unsigned Value = Parser.getTok().getIntVal(); 6099 Parser.Lex(); 6100 6101 if (Value != 32 && Value != 64) { 6102 reportParseError("unsupported value, expected 'xx', '32' or '64'"); 6103 return false; 6104 } 6105 6106 if (Value == 32) { 6107 if (!isABI_O32()) { 6108 reportParseError("'" + Directive + " fp=32' requires the O32 ABI"); 6109 return false; 6110 } 6111 6112 FpABI = MipsABIFlagsSection::FpABIKind::S32; 6113 if (ModuleLevelOptions) { 6114 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx"); 6115 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64"); 6116 } else { 6117 clearFeatureBits(Mips::FeatureFPXX, "fpxx"); 6118 clearFeatureBits(Mips::FeatureFP64Bit, "fp64"); 6119 } 6120 } else { 6121 FpABI = MipsABIFlagsSection::FpABIKind::S64; 6122 if (ModuleLevelOptions) { 6123 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx"); 6124 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64"); 6125 } else { 6126 clearFeatureBits(Mips::FeatureFPXX, "fpxx"); 6127 setFeatureBits(Mips::FeatureFP64Bit, "fp64"); 6128 } 6129 } 6130 6131 return true; 6132 } 6133 6134 return false; 6135 } 6136 6137 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) { 6138 // This returns false if this function recognizes the directive 6139 // regardless of whether it is successfully handles or reports an 6140 // error. Otherwise it returns true to give the generic parser a 6141 // chance at recognizing it. 6142 6143 MCAsmParser &Parser = getParser(); 6144 StringRef IDVal = DirectiveID.getString(); 6145 6146 if (IDVal == ".cpload") { 6147 parseDirectiveCpLoad(DirectiveID.getLoc()); 6148 return false; 6149 } 6150 if (IDVal == ".cprestore") { 6151 parseDirectiveCpRestore(DirectiveID.getLoc()); 6152 return false; 6153 } 6154 if (IDVal == ".dword") { 6155 parseDataDirective(8, DirectiveID.getLoc()); 6156 return false; 6157 } 6158 if (IDVal == ".ent") { 6159 StringRef SymbolName; 6160 6161 if (Parser.parseIdentifier(SymbolName)) { 6162 reportParseError("expected identifier after .ent"); 6163 return false; 6164 } 6165 6166 // There's an undocumented extension that allows an integer to 6167 // follow the name of the procedure which AFAICS is ignored by GAS. 6168 // Example: .ent foo,2 6169 if (getLexer().isNot(AsmToken::EndOfStatement)) { 6170 if (getLexer().isNot(AsmToken::Comma)) { 6171 // Even though we accept this undocumented extension for compatibility 6172 // reasons, the additional integer argument does not actually change 6173 // the behaviour of the '.ent' directive, so we would like to discourage 6174 // its use. We do this by not referring to the extended version in 6175 // error messages which are not directly related to its use. 6176 reportParseError("unexpected token, expected end of statement"); 6177 return false; 6178 } 6179 Parser.Lex(); // Eat the comma. 6180 const MCExpr *DummyNumber; 6181 int64_t DummyNumberVal; 6182 // If the user was explicitly trying to use the extended version, 6183 // we still give helpful extension-related error messages. 6184 if (Parser.parseExpression(DummyNumber)) { 6185 reportParseError("expected number after comma"); 6186 return false; 6187 } 6188 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) { 6189 reportParseError("expected an absolute expression after comma"); 6190 return false; 6191 } 6192 } 6193 6194 // If this is not the end of the statement, report an error. 6195 if (getLexer().isNot(AsmToken::EndOfStatement)) { 6196 reportParseError("unexpected token, expected end of statement"); 6197 return false; 6198 } 6199 6200 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName); 6201 6202 getTargetStreamer().emitDirectiveEnt(*Sym); 6203 CurrentFn = Sym; 6204 IsCpRestoreSet = false; 6205 return false; 6206 } 6207 6208 if (IDVal == ".end") { 6209 StringRef SymbolName; 6210 6211 if (Parser.parseIdentifier(SymbolName)) { 6212 reportParseError("expected identifier after .end"); 6213 return false; 6214 } 6215 6216 if (getLexer().isNot(AsmToken::EndOfStatement)) { 6217 reportParseError("unexpected token, expected end of statement"); 6218 return false; 6219 } 6220 6221 if (CurrentFn == nullptr) { 6222 reportParseError(".end used without .ent"); 6223 return false; 6224 } 6225 6226 if ((SymbolName != CurrentFn->getName())) { 6227 reportParseError(".end symbol does not match .ent symbol"); 6228 return false; 6229 } 6230 6231 getTargetStreamer().emitDirectiveEnd(SymbolName); 6232 CurrentFn = nullptr; 6233 IsCpRestoreSet = false; 6234 return false; 6235 } 6236 6237 if (IDVal == ".frame") { 6238 // .frame $stack_reg, frame_size_in_bytes, $return_reg 6239 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg; 6240 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg); 6241 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) { 6242 reportParseError("expected stack register"); 6243 return false; 6244 } 6245 6246 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]); 6247 if (!StackRegOpnd.isGPRAsmReg()) { 6248 reportParseError(StackRegOpnd.getStartLoc(), 6249 "expected general purpose register"); 6250 return false; 6251 } 6252 unsigned StackReg = StackRegOpnd.getGPR32Reg(); 6253 6254 if (Parser.getTok().is(AsmToken::Comma)) 6255 Parser.Lex(); 6256 else { 6257 reportParseError("unexpected token, expected comma"); 6258 return false; 6259 } 6260 6261 // Parse the frame size. 6262 const MCExpr *FrameSize; 6263 int64_t FrameSizeVal; 6264 6265 if (Parser.parseExpression(FrameSize)) { 6266 reportParseError("expected frame size value"); 6267 return false; 6268 } 6269 6270 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) { 6271 reportParseError("frame size not an absolute expression"); 6272 return false; 6273 } 6274 6275 if (Parser.getTok().is(AsmToken::Comma)) 6276 Parser.Lex(); 6277 else { 6278 reportParseError("unexpected token, expected comma"); 6279 return false; 6280 } 6281 6282 // Parse the return register. 6283 TmpReg.clear(); 6284 ResTy = parseAnyRegister(TmpReg); 6285 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) { 6286 reportParseError("expected return register"); 6287 return false; 6288 } 6289 6290 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]); 6291 if (!ReturnRegOpnd.isGPRAsmReg()) { 6292 reportParseError(ReturnRegOpnd.getStartLoc(), 6293 "expected general purpose register"); 6294 return false; 6295 } 6296 6297 // If this is not the end of the statement, report an error. 6298 if (getLexer().isNot(AsmToken::EndOfStatement)) { 6299 reportParseError("unexpected token, expected end of statement"); 6300 return false; 6301 } 6302 6303 getTargetStreamer().emitFrame(StackReg, FrameSizeVal, 6304 ReturnRegOpnd.getGPR32Reg()); 6305 IsCpRestoreSet = false; 6306 return false; 6307 } 6308 6309 if (IDVal == ".set") { 6310 parseDirectiveSet(); 6311 return false; 6312 } 6313 6314 if (IDVal == ".mask" || IDVal == ".fmask") { 6315 // .mask bitmask, frame_offset 6316 // bitmask: One bit for each register used. 6317 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where 6318 // first register is expected to be saved. 6319 // Examples: 6320 // .mask 0x80000000, -4 6321 // .fmask 0x80000000, -4 6322 // 6323 6324 // Parse the bitmask 6325 const MCExpr *BitMask; 6326 int64_t BitMaskVal; 6327 6328 if (Parser.parseExpression(BitMask)) { 6329 reportParseError("expected bitmask value"); 6330 return false; 6331 } 6332 6333 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) { 6334 reportParseError("bitmask not an absolute expression"); 6335 return false; 6336 } 6337 6338 if (Parser.getTok().is(AsmToken::Comma)) 6339 Parser.Lex(); 6340 else { 6341 reportParseError("unexpected token, expected comma"); 6342 return false; 6343 } 6344 6345 // Parse the frame_offset 6346 const MCExpr *FrameOffset; 6347 int64_t FrameOffsetVal; 6348 6349 if (Parser.parseExpression(FrameOffset)) { 6350 reportParseError("expected frame offset value"); 6351 return false; 6352 } 6353 6354 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) { 6355 reportParseError("frame offset not an absolute expression"); 6356 return false; 6357 } 6358 6359 // If this is not the end of the statement, report an error. 6360 if (getLexer().isNot(AsmToken::EndOfStatement)) { 6361 reportParseError("unexpected token, expected end of statement"); 6362 return false; 6363 } 6364 6365 if (IDVal == ".mask") 6366 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal); 6367 else 6368 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal); 6369 return false; 6370 } 6371 6372 if (IDVal == ".nan") 6373 return parseDirectiveNaN(); 6374 6375 if (IDVal == ".gpword") { 6376 parseDirectiveGpWord(); 6377 return false; 6378 } 6379 6380 if (IDVal == ".gpdword") { 6381 parseDirectiveGpDWord(); 6382 return false; 6383 } 6384 6385 if (IDVal == ".word") { 6386 parseDataDirective(4, DirectiveID.getLoc()); 6387 return false; 6388 } 6389 6390 if (IDVal == ".hword") { 6391 parseDataDirective(2, DirectiveID.getLoc()); 6392 return false; 6393 } 6394 6395 if (IDVal == ".option") { 6396 parseDirectiveOption(); 6397 return false; 6398 } 6399 6400 if (IDVal == ".abicalls") { 6401 getTargetStreamer().emitDirectiveAbiCalls(); 6402 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) { 6403 Error(Parser.getTok().getLoc(), 6404 "unexpected token, expected end of statement"); 6405 // Clear line 6406 Parser.eatToEndOfStatement(); 6407 } 6408 return false; 6409 } 6410 6411 if (IDVal == ".cpsetup") { 6412 parseDirectiveCPSetup(); 6413 return false; 6414 } 6415 if (IDVal == ".cpreturn") { 6416 parseDirectiveCPReturn(); 6417 return false; 6418 } 6419 if (IDVal == ".module") { 6420 parseDirectiveModule(); 6421 return false; 6422 } 6423 if (IDVal == ".llvm_internal_mips_reallow_module_directive") { 6424 parseInternalDirectiveReallowModule(); 6425 return false; 6426 } 6427 if (IDVal == ".insn") { 6428 parseInsnDirective(); 6429 return false; 6430 } 6431 if (IDVal == ".sbss") { 6432 parseSSectionDirective(IDVal, ELF::SHT_NOBITS); 6433 return false; 6434 } 6435 if (IDVal == ".sdata") { 6436 parseSSectionDirective(IDVal, ELF::SHT_PROGBITS); 6437 return false; 6438 } 6439 6440 return true; 6441 } 6442 6443 bool MipsAsmParser::parseInternalDirectiveReallowModule() { 6444 // If this is not the end of the statement, report an error. 6445 if (getLexer().isNot(AsmToken::EndOfStatement)) { 6446 reportParseError("unexpected token, expected end of statement"); 6447 return false; 6448 } 6449 6450 getTargetStreamer().reallowModuleDirective(); 6451 6452 getParser().Lex(); // Eat EndOfStatement token. 6453 return false; 6454 } 6455 6456 extern "C" void LLVMInitializeMipsAsmParser() { 6457 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget); 6458 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget); 6459 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target); 6460 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget); 6461 } 6462 6463 #define GET_REGISTER_MATCHER 6464 #define GET_MATCHER_IMPLEMENTATION 6465 #include "MipsGenAsmMatcher.inc" 6466