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