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