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