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