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