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