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