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/MipsMCExpr.h" 11 #include "MCTargetDesc/MipsMCTargetDesc.h" 12 #include "MipsRegisterInfo.h" 13 #include "MipsTargetStreamer.h" 14 #include "llvm/ADT/APInt.h" 15 #include "llvm/ADT/StringSwitch.h" 16 #include "llvm/ADT/SmallVector.h" 17 #include "llvm/MC/MCContext.h" 18 #include "llvm/MC/MCExpr.h" 19 #include "llvm/MC/MCInst.h" 20 #include "llvm/MC/MCInstBuilder.h" 21 #include "llvm/MC/MCParser/MCAsmLexer.h" 22 #include "llvm/MC/MCParser/MCParsedAsmOperand.h" 23 #include "llvm/MC/MCStreamer.h" 24 #include "llvm/MC/MCSubtargetInfo.h" 25 #include "llvm/MC/MCSymbol.h" 26 #include "llvm/MC/MCTargetAsmParser.h" 27 #include "llvm/Support/Debug.h" 28 #include "llvm/Support/MathExtras.h" 29 #include "llvm/Support/TargetRegistry.h" 30 #include <memory> 31 32 using namespace llvm; 33 34 #define DEBUG_TYPE "mips-asm-parser" 35 36 namespace llvm { 37 class MCInstrInfo; 38 } 39 40 namespace { 41 class MipsAssemblerOptions { 42 public: 43 MipsAssemblerOptions(uint64_t Features_) : 44 ATReg(1), Reorder(true), Macro(true), Features(Features_) {} 45 46 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) { 47 ATReg = Opts->getATRegNum(); 48 Reorder = Opts->isReorder(); 49 Macro = Opts->isMacro(); 50 Features = Opts->getFeatures(); 51 } 52 53 unsigned getATRegNum() const { return ATReg; } 54 bool setATReg(unsigned Reg); 55 56 bool isReorder() const { return Reorder; } 57 void setReorder() { Reorder = true; } 58 void setNoReorder() { Reorder = false; } 59 60 bool isMacro() const { return Macro; } 61 void setMacro() { Macro = true; } 62 void setNoMacro() { Macro = false; } 63 64 uint64_t getFeatures() const { return Features; } 65 void setFeatures(uint64_t Features_) { Features = Features_; } 66 67 // Set of features that are either architecture features or referenced 68 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6). 69 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]). 70 // The reason we need this mask is explained in the selectArch function. 71 // FIXME: Ideally we would like TableGen to generate this information. 72 static const uint64_t AllArchRelatedMask = 73 Mips::FeatureMips1 | Mips::FeatureMips2 | Mips::FeatureMips3 | 74 Mips::FeatureMips3_32 | Mips::FeatureMips3_32r2 | Mips::FeatureMips4 | 75 Mips::FeatureMips4_32 | Mips::FeatureMips4_32r2 | Mips::FeatureMips5 | 76 Mips::FeatureMips5_32r2 | Mips::FeatureMips32 | Mips::FeatureMips32r2 | 77 Mips::FeatureMips32r6 | Mips::FeatureMips64 | Mips::FeatureMips64r2 | 78 Mips::FeatureMips64r6 | Mips::FeatureCnMips | Mips::FeatureFP64Bit | 79 Mips::FeatureGP64Bit | Mips::FeatureNaN2008; 80 81 private: 82 unsigned ATReg; 83 bool Reorder; 84 bool Macro; 85 uint64_t Features; 86 }; 87 } 88 89 namespace { 90 class MipsAsmParser : public MCTargetAsmParser { 91 MipsTargetStreamer &getTargetStreamer() { 92 MCTargetStreamer &TS = *Parser.getStreamer().getTargetStreamer(); 93 return static_cast<MipsTargetStreamer &>(TS); 94 } 95 96 MCSubtargetInfo &STI; 97 MCAsmParser &Parser; 98 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions; 99 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a 100 // nullptr, which indicates that no function is currently 101 // selected. This usually happens after an '.end func' 102 // directive. 103 104 #define GET_ASSEMBLER_HEADER 105 #include "MipsGenAsmMatcher.inc" 106 107 unsigned checkTargetMatchPredicate(MCInst &Inst) override; 108 109 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 110 OperandVector &Operands, MCStreamer &Out, 111 uint64_t &ErrorInfo, 112 bool MatchingInlineAsm) override; 113 114 /// Parse a register as used in CFI directives 115 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override; 116 117 bool parseParenSuffix(StringRef Name, OperandVector &Operands); 118 119 bool parseBracketSuffix(StringRef Name, OperandVector &Operands); 120 121 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 122 SMLoc NameLoc, OperandVector &Operands) override; 123 124 bool ParseDirective(AsmToken DirectiveID) override; 125 126 MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands); 127 128 MipsAsmParser::OperandMatchResultTy 129 matchAnyRegisterNameWithoutDollar(OperandVector &Operands, 130 StringRef Identifier, SMLoc S); 131 132 MipsAsmParser::OperandMatchResultTy 133 matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S); 134 135 MipsAsmParser::OperandMatchResultTy parseAnyRegister(OperandVector &Operands); 136 137 MipsAsmParser::OperandMatchResultTy parseImm(OperandVector &Operands); 138 139 MipsAsmParser::OperandMatchResultTy parseJumpTarget(OperandVector &Operands); 140 141 MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands); 142 143 MipsAsmParser::OperandMatchResultTy parseLSAImm(OperandVector &Operands); 144 145 bool searchSymbolAlias(OperandVector &Operands); 146 147 bool parseOperand(OperandVector &, StringRef Mnemonic); 148 149 bool needsExpansion(MCInst &Inst); 150 151 // Expands assembly pseudo instructions. 152 // Returns false on success, true otherwise. 153 bool expandInstruction(MCInst &Inst, SMLoc IDLoc, 154 SmallVectorImpl<MCInst> &Instructions); 155 156 bool expandLoadImm(MCInst &Inst, SMLoc IDLoc, 157 SmallVectorImpl<MCInst> &Instructions); 158 159 bool expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc, 160 SmallVectorImpl<MCInst> &Instructions); 161 162 bool expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc, 163 SmallVectorImpl<MCInst> &Instructions); 164 165 void expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc, 166 SmallVectorImpl<MCInst> &Instructions); 167 168 void expandMemInst(MCInst &Inst, SMLoc IDLoc, 169 SmallVectorImpl<MCInst> &Instructions, bool isLoad, 170 bool isImmOpnd); 171 bool reportParseError(Twine ErrorMsg); 172 bool reportParseError(SMLoc Loc, Twine ErrorMsg); 173 174 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr); 175 bool parseRelocOperand(const MCExpr *&Res); 176 177 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr); 178 179 bool isEvaluated(const MCExpr *Expr); 180 bool parseSetMips0Directive(); 181 bool parseSetArchDirective(); 182 bool parseSetFeature(uint64_t Feature); 183 bool parseDirectiveCpLoad(SMLoc Loc); 184 bool parseDirectiveCPSetup(); 185 bool parseDirectiveNaN(); 186 bool parseDirectiveSet(); 187 bool parseDirectiveOption(); 188 189 bool parseSetAtDirective(); 190 bool parseSetNoAtDirective(); 191 bool parseSetMacroDirective(); 192 bool parseSetNoMacroDirective(); 193 bool parseSetMsaDirective(); 194 bool parseSetNoMsaDirective(); 195 bool parseSetNoDspDirective(); 196 bool parseSetReorderDirective(); 197 bool parseSetNoReorderDirective(); 198 bool parseSetNoMips16Directive(); 199 bool parseSetFpDirective(); 200 bool parseSetPopDirective(); 201 bool parseSetPushDirective(); 202 203 bool parseSetAssignment(); 204 205 bool parseDataDirective(unsigned Size, SMLoc L); 206 bool parseDirectiveGpWord(); 207 bool parseDirectiveGpDWord(); 208 bool parseDirectiveModule(); 209 bool parseDirectiveModuleFP(); 210 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI, 211 StringRef Directive); 212 213 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol); 214 215 bool eatComma(StringRef ErrorStr); 216 217 int matchCPURegisterName(StringRef Symbol); 218 219 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass); 220 221 int matchFPURegisterName(StringRef Name); 222 223 int matchFCCRegisterName(StringRef Name); 224 225 int matchACRegisterName(StringRef Name); 226 227 int matchMSA128RegisterName(StringRef Name); 228 229 int matchMSA128CtrlRegisterName(StringRef Name); 230 231 unsigned getReg(int RC, int RegNo); 232 233 unsigned getGPR(int RegNo); 234 235 int getATReg(SMLoc Loc); 236 237 bool processInstruction(MCInst &Inst, SMLoc IDLoc, 238 SmallVectorImpl<MCInst> &Instructions); 239 240 // Helper function that checks if the value of a vector index is within the 241 // boundaries of accepted values for each RegisterKind 242 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0 243 bool validateMSAIndex(int Val, int RegKind); 244 245 // Selects a new architecture by updating the FeatureBits with the necessary 246 // info including implied dependencies. 247 // Internally, it clears all the feature bits related to *any* architecture 248 // and selects the new one using the ToggleFeature functionality of the 249 // MCSubtargetInfo object that handles implied dependencies. The reason we 250 // clear all the arch related bits manually is because ToggleFeature only 251 // clears the features that imply the feature being cleared and not the 252 // features implied by the feature being cleared. This is easier to see 253 // with an example: 254 // -------------------------------------------------- 255 // | Feature | Implies | 256 // | -------------------------------------------------| 257 // | FeatureMips1 | None | 258 // | FeatureMips2 | FeatureMips1 | 259 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 | 260 // | FeatureMips4 | FeatureMips3 | 261 // | ... | | 262 // -------------------------------------------------- 263 // 264 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 | 265 // FeatureMipsGP64 | FeatureMips1) 266 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4). 267 void selectArch(StringRef ArchFeature) { 268 uint64_t FeatureBits = STI.getFeatureBits(); 269 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask; 270 STI.setFeatureBits(FeatureBits); 271 setAvailableFeatures( 272 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature))); 273 AssemblerOptions.back()->setFeatures(getAvailableFeatures()); 274 } 275 276 void setFeatureBits(uint64_t Feature, StringRef FeatureString) { 277 if (!(STI.getFeatureBits() & Feature)) { 278 setAvailableFeatures( 279 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString))); 280 } 281 AssemblerOptions.back()->setFeatures(getAvailableFeatures()); 282 } 283 284 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) { 285 if (STI.getFeatureBits() & Feature) { 286 setAvailableFeatures( 287 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString))); 288 } 289 AssemblerOptions.back()->setFeatures(getAvailableFeatures()); 290 } 291 292 public: 293 enum MipsMatchResultTy { 294 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY 295 #define GET_OPERAND_DIAGNOSTIC_TYPES 296 #include "MipsGenAsmMatcher.inc" 297 #undef GET_OPERAND_DIAGNOSTIC_TYPES 298 299 }; 300 301 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser, 302 const MCInstrInfo &MII, const MCTargetOptions &Options) 303 : MCTargetAsmParser(), STI(sti), Parser(parser) { 304 // Initialize the set of available features. 305 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 306 307 // Remember the initial assembler options. The user can not modify these. 308 AssemblerOptions.push_back( 309 make_unique<MipsAssemblerOptions>(getAvailableFeatures())); 310 311 // Create an assembler options environment for the user to modify. 312 AssemblerOptions.push_back( 313 make_unique<MipsAssemblerOptions>(getAvailableFeatures())); 314 315 getTargetStreamer().updateABIInfo(*this); 316 317 // Assert exactly one ABI was chosen. 318 assert((((STI.getFeatureBits() & Mips::FeatureO32) != 0) + 319 ((STI.getFeatureBits() & Mips::FeatureEABI) != 0) + 320 ((STI.getFeatureBits() & Mips::FeatureN32) != 0) + 321 ((STI.getFeatureBits() & Mips::FeatureN64) != 0)) == 1); 322 323 if (!isABI_O32() && !useOddSPReg() != 0) 324 report_fatal_error("-mno-odd-spreg requires the O32 ABI"); 325 326 CurrentFn = nullptr; 327 } 328 329 MCAsmParser &getParser() const { return Parser; } 330 MCAsmLexer &getLexer() const { return Parser.getLexer(); } 331 332 /// True if all of $fcc0 - $fcc7 exist for the current ISA. 333 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); } 334 335 bool isGP64bit() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; } 336 bool isFP64bit() const { return STI.getFeatureBits() & Mips::FeatureFP64Bit; } 337 bool isABI_N32() const { return STI.getFeatureBits() & Mips::FeatureN32; } 338 bool isABI_N64() const { return STI.getFeatureBits() & Mips::FeatureN64; } 339 bool isABI_O32() const { return STI.getFeatureBits() & Mips::FeatureO32; } 340 bool isABI_FPXX() const { return STI.getFeatureBits() & Mips::FeatureFPXX; } 341 342 bool useOddSPReg() const { 343 return !(STI.getFeatureBits() & Mips::FeatureNoOddSPReg); 344 } 345 346 bool inMicroMipsMode() const { 347 return STI.getFeatureBits() & Mips::FeatureMicroMips; 348 } 349 bool hasMips1() const { return STI.getFeatureBits() & Mips::FeatureMips1; } 350 bool hasMips2() const { return STI.getFeatureBits() & Mips::FeatureMips2; } 351 bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; } 352 bool hasMips4() const { return STI.getFeatureBits() & Mips::FeatureMips4; } 353 bool hasMips5() const { return STI.getFeatureBits() & Mips::FeatureMips5; } 354 bool hasMips32() const { 355 return (STI.getFeatureBits() & Mips::FeatureMips32); 356 } 357 bool hasMips64() const { 358 return (STI.getFeatureBits() & Mips::FeatureMips64); 359 } 360 bool hasMips32r2() const { 361 return (STI.getFeatureBits() & Mips::FeatureMips32r2); 362 } 363 bool hasMips64r2() const { 364 return (STI.getFeatureBits() & Mips::FeatureMips64r2); 365 } 366 bool hasMips32r6() const { 367 return (STI.getFeatureBits() & Mips::FeatureMips32r6); 368 } 369 bool hasMips64r6() const { 370 return (STI.getFeatureBits() & Mips::FeatureMips64r6); 371 } 372 bool hasDSP() const { return (STI.getFeatureBits() & Mips::FeatureDSP); } 373 bool hasDSPR2() const { return (STI.getFeatureBits() & Mips::FeatureDSPR2); } 374 bool hasMSA() const { return (STI.getFeatureBits() & Mips::FeatureMSA); } 375 376 bool inMips16Mode() const { 377 return STI.getFeatureBits() & Mips::FeatureMips16; 378 } 379 // TODO: see how can we get this info. 380 bool abiUsesSoftFloat() const { return false; } 381 382 /// Warn if RegNo is the current assembler temporary. 383 void warnIfAssemblerTemporary(int RegNo, SMLoc Loc); 384 }; 385 } 386 387 namespace { 388 389 /// MipsOperand - Instances of this class represent a parsed Mips machine 390 /// instruction. 391 class MipsOperand : public MCParsedAsmOperand { 392 public: 393 /// Broad categories of register classes 394 /// The exact class is finalized by the render method. 395 enum RegKind { 396 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit()) 397 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and 398 /// isFP64bit()) 399 RegKind_FCC = 4, /// FCC 400 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which) 401 RegKind_MSACtrl = 16, /// MSA control registers 402 RegKind_COP2 = 32, /// COP2 403 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on 404 /// context). 405 RegKind_CCR = 128, /// CCR 406 RegKind_HWRegs = 256, /// HWRegs 407 RegKind_COP3 = 512, /// COP3 408 409 /// Potentially any (e.g. $1) 410 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 | 411 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC | 412 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 413 }; 414 415 private: 416 enum KindTy { 417 k_Immediate, /// An immediate (possibly involving symbol references) 418 k_Memory, /// Base + Offset Memory Address 419 k_PhysRegister, /// A physical register from the Mips namespace 420 k_RegisterIndex, /// A register index in one or more RegKind. 421 k_Token /// A simple token 422 } Kind; 423 424 public: 425 MipsOperand(KindTy K, MipsAsmParser &Parser) 426 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {} 427 428 private: 429 /// For diagnostics, and checking the assembler temporary 430 MipsAsmParser &AsmParser; 431 432 struct Token { 433 const char *Data; 434 unsigned Length; 435 }; 436 437 struct PhysRegOp { 438 unsigned Num; /// Register Number 439 }; 440 441 struct RegIdxOp { 442 unsigned Index; /// Index into the register class 443 RegKind Kind; /// Bitfield of the kinds it could possibly be 444 const MCRegisterInfo *RegInfo; 445 }; 446 447 struct ImmOp { 448 const MCExpr *Val; 449 }; 450 451 struct MemOp { 452 MipsOperand *Base; 453 const MCExpr *Off; 454 }; 455 456 union { 457 struct Token Tok; 458 struct PhysRegOp PhysReg; 459 struct RegIdxOp RegIdx; 460 struct ImmOp Imm; 461 struct MemOp Mem; 462 }; 463 464 SMLoc StartLoc, EndLoc; 465 466 /// Internal constructor for register kinds 467 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind, 468 const MCRegisterInfo *RegInfo, 469 SMLoc S, SMLoc E, 470 MipsAsmParser &Parser) { 471 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser); 472 Op->RegIdx.Index = Index; 473 Op->RegIdx.RegInfo = RegInfo; 474 Op->RegIdx.Kind = RegKind; 475 Op->StartLoc = S; 476 Op->EndLoc = E; 477 return Op; 478 } 479 480 public: 481 /// Coerce the register to GPR32 and return the real register for the current 482 /// target. 483 unsigned getGPR32Reg() const { 484 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!"); 485 AsmParser.warnIfAssemblerTemporary(RegIdx.Index, StartLoc); 486 unsigned ClassID = Mips::GPR32RegClassID; 487 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 488 } 489 490 /// Coerce the register to GPR64 and return the real register for the current 491 /// target. 492 unsigned getGPR64Reg() const { 493 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!"); 494 unsigned ClassID = Mips::GPR64RegClassID; 495 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 496 } 497 498 private: 499 /// Coerce the register to AFGR64 and return the real register for the current 500 /// target. 501 unsigned getAFGR64Reg() const { 502 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!"); 503 if (RegIdx.Index % 2 != 0) 504 AsmParser.Warning(StartLoc, "Float register should be even."); 505 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID) 506 .getRegister(RegIdx.Index / 2); 507 } 508 509 /// Coerce the register to FGR64 and return the real register for the current 510 /// target. 511 unsigned getFGR64Reg() const { 512 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!"); 513 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID) 514 .getRegister(RegIdx.Index); 515 } 516 517 /// Coerce the register to FGR32 and return the real register for the current 518 /// target. 519 unsigned getFGR32Reg() const { 520 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!"); 521 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID) 522 .getRegister(RegIdx.Index); 523 } 524 525 /// Coerce the register to FGRH32 and return the real register for the current 526 /// target. 527 unsigned getFGRH32Reg() const { 528 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!"); 529 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID) 530 .getRegister(RegIdx.Index); 531 } 532 533 /// Coerce the register to FCC and return the real register for the current 534 /// target. 535 unsigned getFCCReg() const { 536 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!"); 537 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID) 538 .getRegister(RegIdx.Index); 539 } 540 541 /// Coerce the register to MSA128 and return the real register for the current 542 /// target. 543 unsigned getMSA128Reg() const { 544 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!"); 545 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all 546 // identical 547 unsigned ClassID = Mips::MSA128BRegClassID; 548 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 549 } 550 551 /// Coerce the register to MSACtrl and return the real register for the 552 /// current target. 553 unsigned getMSACtrlReg() const { 554 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!"); 555 unsigned ClassID = Mips::MSACtrlRegClassID; 556 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 557 } 558 559 /// Coerce the register to COP2 and return the real register for the 560 /// current target. 561 unsigned getCOP2Reg() const { 562 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!"); 563 unsigned ClassID = Mips::COP2RegClassID; 564 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 565 } 566 567 /// Coerce the register to COP3 and return the real register for the 568 /// current target. 569 unsigned getCOP3Reg() const { 570 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!"); 571 unsigned ClassID = Mips::COP3RegClassID; 572 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 573 } 574 575 /// Coerce the register to ACC64DSP and return the real register for the 576 /// current target. 577 unsigned getACC64DSPReg() const { 578 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!"); 579 unsigned ClassID = Mips::ACC64DSPRegClassID; 580 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 581 } 582 583 /// Coerce the register to HI32DSP and return the real register for the 584 /// current target. 585 unsigned getHI32DSPReg() const { 586 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!"); 587 unsigned ClassID = Mips::HI32DSPRegClassID; 588 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 589 } 590 591 /// Coerce the register to LO32DSP and return the real register for the 592 /// current target. 593 unsigned getLO32DSPReg() const { 594 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!"); 595 unsigned ClassID = Mips::LO32DSPRegClassID; 596 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 597 } 598 599 /// Coerce the register to CCR and return the real register for the 600 /// current target. 601 unsigned getCCRReg() const { 602 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!"); 603 unsigned ClassID = Mips::CCRRegClassID; 604 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 605 } 606 607 /// Coerce the register to HWRegs and return the real register for the 608 /// current target. 609 unsigned getHWRegsReg() const { 610 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!"); 611 unsigned ClassID = Mips::HWRegsRegClassID; 612 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index); 613 } 614 615 public: 616 void addExpr(MCInst &Inst, const MCExpr *Expr) const { 617 // Add as immediate when possible. Null MCExpr = 0. 618 if (!Expr) 619 Inst.addOperand(MCOperand::CreateImm(0)); 620 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 621 Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 622 else 623 Inst.addOperand(MCOperand::CreateExpr(Expr)); 624 } 625 626 void addRegOperands(MCInst &Inst, unsigned N) const { 627 llvm_unreachable("Use a custom parser instead"); 628 } 629 630 /// Render the operand to an MCInst as a GPR32 631 /// Asserts if the wrong number of operands are requested, or the operand 632 /// is not a k_RegisterIndex compatible with RegKind_GPR 633 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const { 634 assert(N == 1 && "Invalid number of operands!"); 635 Inst.addOperand(MCOperand::CreateReg(getGPR32Reg())); 636 } 637 638 /// Render the operand to an MCInst as a GPR64 639 /// Asserts if the wrong number of operands are requested, or the operand 640 /// is not a k_RegisterIndex compatible with RegKind_GPR 641 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const { 642 assert(N == 1 && "Invalid number of operands!"); 643 Inst.addOperand(MCOperand::CreateReg(getGPR64Reg())); 644 } 645 646 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const { 647 assert(N == 1 && "Invalid number of operands!"); 648 Inst.addOperand(MCOperand::CreateReg(getAFGR64Reg())); 649 } 650 651 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const { 652 assert(N == 1 && "Invalid number of operands!"); 653 Inst.addOperand(MCOperand::CreateReg(getFGR64Reg())); 654 } 655 656 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const { 657 assert(N == 1 && "Invalid number of operands!"); 658 Inst.addOperand(MCOperand::CreateReg(getFGR32Reg())); 659 // FIXME: We ought to do this for -integrated-as without -via-file-asm too. 660 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1) 661 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU " 662 "registers"); 663 } 664 665 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const { 666 assert(N == 1 && "Invalid number of operands!"); 667 Inst.addOperand(MCOperand::CreateReg(getFGRH32Reg())); 668 } 669 670 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const { 671 assert(N == 1 && "Invalid number of operands!"); 672 Inst.addOperand(MCOperand::CreateReg(getFCCReg())); 673 } 674 675 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const { 676 assert(N == 1 && "Invalid number of operands!"); 677 Inst.addOperand(MCOperand::CreateReg(getMSA128Reg())); 678 } 679 680 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const { 681 assert(N == 1 && "Invalid number of operands!"); 682 Inst.addOperand(MCOperand::CreateReg(getMSACtrlReg())); 683 } 684 685 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const { 686 assert(N == 1 && "Invalid number of operands!"); 687 Inst.addOperand(MCOperand::CreateReg(getCOP2Reg())); 688 } 689 690 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const { 691 assert(N == 1 && "Invalid number of operands!"); 692 Inst.addOperand(MCOperand::CreateReg(getCOP3Reg())); 693 } 694 695 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const { 696 assert(N == 1 && "Invalid number of operands!"); 697 Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg())); 698 } 699 700 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const { 701 assert(N == 1 && "Invalid number of operands!"); 702 Inst.addOperand(MCOperand::CreateReg(getHI32DSPReg())); 703 } 704 705 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const { 706 assert(N == 1 && "Invalid number of operands!"); 707 Inst.addOperand(MCOperand::CreateReg(getLO32DSPReg())); 708 } 709 710 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const { 711 assert(N == 1 && "Invalid number of operands!"); 712 Inst.addOperand(MCOperand::CreateReg(getCCRReg())); 713 } 714 715 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const { 716 assert(N == 1 && "Invalid number of operands!"); 717 Inst.addOperand(MCOperand::CreateReg(getHWRegsReg())); 718 } 719 720 void addImmOperands(MCInst &Inst, unsigned N) const { 721 assert(N == 1 && "Invalid number of operands!"); 722 const MCExpr *Expr = getImm(); 723 addExpr(Inst, Expr); 724 } 725 726 void addMemOperands(MCInst &Inst, unsigned N) const { 727 assert(N == 2 && "Invalid number of operands!"); 728 729 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPR32Reg())); 730 731 const MCExpr *Expr = getMemOff(); 732 addExpr(Inst, Expr); 733 } 734 735 bool isReg() const override { 736 // As a special case until we sort out the definition of div/divu, pretend 737 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly. 738 if (isGPRAsmReg() && RegIdx.Index == 0) 739 return true; 740 741 return Kind == k_PhysRegister; 742 } 743 bool isRegIdx() const { return Kind == k_RegisterIndex; } 744 bool isImm() const override { return Kind == k_Immediate; } 745 bool isConstantImm() const { 746 return isImm() && dyn_cast<MCConstantExpr>(getImm()); 747 } 748 bool isToken() const override { 749 // Note: It's not possible to pretend that other operand kinds are tokens. 750 // The matcher emitter checks tokens first. 751 return Kind == k_Token; 752 } 753 bool isMem() const override { return Kind == k_Memory; } 754 bool isConstantMemOff() const { 755 return isMem() && dyn_cast<MCConstantExpr>(getMemOff()); 756 } 757 template <unsigned Bits> bool isMemWithSimmOffset() const { 758 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff()); 759 } 760 bool isInvNum() const { return Kind == k_Immediate; } 761 bool isLSAImm() const { 762 if (!isConstantImm()) 763 return false; 764 int64_t Val = getConstantImm(); 765 return 1 <= Val && Val <= 4; 766 } 767 768 StringRef getToken() const { 769 assert(Kind == k_Token && "Invalid access!"); 770 return StringRef(Tok.Data, Tok.Length); 771 } 772 773 unsigned getReg() const override { 774 // As a special case until we sort out the definition of div/divu, pretend 775 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly. 776 if (Kind == k_RegisterIndex && RegIdx.Index == 0 && 777 RegIdx.Kind & RegKind_GPR) 778 return getGPR32Reg(); // FIXME: GPR64 too 779 780 assert(Kind == k_PhysRegister && "Invalid access!"); 781 return PhysReg.Num; 782 } 783 784 const MCExpr *getImm() const { 785 assert((Kind == k_Immediate) && "Invalid access!"); 786 return Imm.Val; 787 } 788 789 int64_t getConstantImm() const { 790 const MCExpr *Val = getImm(); 791 return static_cast<const MCConstantExpr *>(Val)->getValue(); 792 } 793 794 MipsOperand *getMemBase() const { 795 assert((Kind == k_Memory) && "Invalid access!"); 796 return Mem.Base; 797 } 798 799 const MCExpr *getMemOff() const { 800 assert((Kind == k_Memory) && "Invalid access!"); 801 return Mem.Off; 802 } 803 804 int64_t getConstantMemOff() const { 805 return static_cast<const MCConstantExpr *>(getMemOff())->getValue(); 806 } 807 808 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S, 809 MipsAsmParser &Parser) { 810 auto Op = make_unique<MipsOperand>(k_Token, Parser); 811 Op->Tok.Data = Str.data(); 812 Op->Tok.Length = Str.size(); 813 Op->StartLoc = S; 814 Op->EndLoc = S; 815 return Op; 816 } 817 818 /// Create a numeric register (e.g. $1). The exact register remains 819 /// unresolved until an instruction successfully matches 820 static std::unique_ptr<MipsOperand> 821 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, 822 SMLoc E, MipsAsmParser &Parser) { 823 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n"); 824 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser); 825 } 826 827 /// Create a register that is definitely a GPR. 828 /// This is typically only used for named registers such as $gp. 829 static std::unique_ptr<MipsOperand> 830 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E, 831 MipsAsmParser &Parser) { 832 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser); 833 } 834 835 /// Create a register that is definitely a FGR. 836 /// This is typically only used for named registers such as $f0. 837 static std::unique_ptr<MipsOperand> 838 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E, 839 MipsAsmParser &Parser) { 840 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser); 841 } 842 843 /// Create a register that is definitely an FCC. 844 /// This is typically only used for named registers such as $fcc0. 845 static std::unique_ptr<MipsOperand> 846 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E, 847 MipsAsmParser &Parser) { 848 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser); 849 } 850 851 /// Create a register that is definitely an ACC. 852 /// This is typically only used for named registers such as $ac0. 853 static std::unique_ptr<MipsOperand> 854 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E, 855 MipsAsmParser &Parser) { 856 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser); 857 } 858 859 /// Create a register that is definitely an MSA128. 860 /// This is typically only used for named registers such as $w0. 861 static std::unique_ptr<MipsOperand> 862 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, 863 SMLoc E, MipsAsmParser &Parser) { 864 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser); 865 } 866 867 /// Create a register that is definitely an MSACtrl. 868 /// This is typically only used for named registers such as $msaaccess. 869 static std::unique_ptr<MipsOperand> 870 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, 871 SMLoc E, MipsAsmParser &Parser) { 872 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser); 873 } 874 875 static std::unique_ptr<MipsOperand> 876 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) { 877 auto Op = make_unique<MipsOperand>(k_Immediate, Parser); 878 Op->Imm.Val = Val; 879 Op->StartLoc = S; 880 Op->EndLoc = E; 881 return Op; 882 } 883 884 static std::unique_ptr<MipsOperand> 885 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S, 886 SMLoc E, MipsAsmParser &Parser) { 887 auto Op = make_unique<MipsOperand>(k_Memory, Parser); 888 Op->Mem.Base = Base.release(); 889 Op->Mem.Off = Off; 890 Op->StartLoc = S; 891 Op->EndLoc = E; 892 return Op; 893 } 894 895 bool isGPRAsmReg() const { 896 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31; 897 } 898 bool isFGRAsmReg() const { 899 // AFGR64 is $0-$15 but we handle this in getAFGR64() 900 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31; 901 } 902 bool isHWRegsAsmReg() const { 903 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31; 904 } 905 bool isCCRAsmReg() const { 906 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31; 907 } 908 bool isFCCAsmReg() const { 909 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC)) 910 return false; 911 if (!AsmParser.hasEightFccRegisters()) 912 return RegIdx.Index == 0; 913 return RegIdx.Index <= 7; 914 } 915 bool isACCAsmReg() const { 916 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3; 917 } 918 bool isCOP2AsmReg() const { 919 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31; 920 } 921 bool isCOP3AsmReg() const { 922 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31; 923 } 924 bool isMSA128AsmReg() const { 925 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31; 926 } 927 bool isMSACtrlAsmReg() const { 928 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7; 929 } 930 931 /// getStartLoc - Get the location of the first token of this operand. 932 SMLoc getStartLoc() const override { return StartLoc; } 933 /// getEndLoc - Get the location of the last token of this operand. 934 SMLoc getEndLoc() const override { return EndLoc; } 935 936 virtual ~MipsOperand() { 937 switch (Kind) { 938 case k_Immediate: 939 break; 940 case k_Memory: 941 delete Mem.Base; 942 break; 943 case k_PhysRegister: 944 case k_RegisterIndex: 945 case k_Token: 946 break; 947 } 948 } 949 950 void print(raw_ostream &OS) const override { 951 switch (Kind) { 952 case k_Immediate: 953 OS << "Imm<"; 954 Imm.Val->print(OS); 955 OS << ">"; 956 break; 957 case k_Memory: 958 OS << "Mem<"; 959 Mem.Base->print(OS); 960 OS << ", "; 961 Mem.Off->print(OS); 962 OS << ">"; 963 break; 964 case k_PhysRegister: 965 OS << "PhysReg<" << PhysReg.Num << ">"; 966 break; 967 case k_RegisterIndex: 968 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">"; 969 break; 970 case k_Token: 971 OS << Tok.Data; 972 break; 973 } 974 } 975 }; // class MipsOperand 976 } // namespace 977 978 namespace llvm { 979 extern const MCInstrDesc MipsInsts[]; 980 } 981 static const MCInstrDesc &getInstDesc(unsigned Opcode) { 982 return MipsInsts[Opcode]; 983 } 984 985 static bool hasShortDelaySlot(unsigned Opcode) { 986 switch (Opcode) { 987 case Mips::JALS_MM: 988 case Mips::JALRS_MM: 989 case Mips::BGEZALS_MM: 990 case Mips::BLTZALS_MM: 991 return true; 992 default: 993 return false; 994 } 995 } 996 997 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, 998 SmallVectorImpl<MCInst> &Instructions) { 999 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode()); 1000 1001 Inst.setLoc(IDLoc); 1002 1003 if (MCID.isBranch() || MCID.isCall()) { 1004 const unsigned Opcode = Inst.getOpcode(); 1005 MCOperand Offset; 1006 1007 switch (Opcode) { 1008 default: 1009 break; 1010 case Mips::BEQ: 1011 case Mips::BNE: 1012 case Mips::BEQ_MM: 1013 case Mips::BNE_MM: 1014 assert(MCID.getNumOperands() == 3 && "unexpected number of operands"); 1015 Offset = Inst.getOperand(2); 1016 if (!Offset.isImm()) 1017 break; // We'll deal with this situation later on when applying fixups. 1018 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm())) 1019 return Error(IDLoc, "branch target out of range"); 1020 if (OffsetToAlignment(Offset.getImm(), 1021 1LL << (inMicroMipsMode() ? 1 : 2))) 1022 return Error(IDLoc, "branch to misaligned address"); 1023 break; 1024 case Mips::BGEZ: 1025 case Mips::BGTZ: 1026 case Mips::BLEZ: 1027 case Mips::BLTZ: 1028 case Mips::BGEZAL: 1029 case Mips::BLTZAL: 1030 case Mips::BC1F: 1031 case Mips::BC1T: 1032 case Mips::BGEZ_MM: 1033 case Mips::BGTZ_MM: 1034 case Mips::BLEZ_MM: 1035 case Mips::BLTZ_MM: 1036 case Mips::BGEZAL_MM: 1037 case Mips::BLTZAL_MM: 1038 case Mips::BC1F_MM: 1039 case Mips::BC1T_MM: 1040 assert(MCID.getNumOperands() == 2 && "unexpected number of operands"); 1041 Offset = Inst.getOperand(1); 1042 if (!Offset.isImm()) 1043 break; // We'll deal with this situation later on when applying fixups. 1044 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm())) 1045 return Error(IDLoc, "branch target out of range"); 1046 if (OffsetToAlignment(Offset.getImm(), 1047 1LL << (inMicroMipsMode() ? 1 : 2))) 1048 return Error(IDLoc, "branch to misaligned address"); 1049 break; 1050 } 1051 } 1052 1053 // SSNOP is deprecated on MIPS32r6/MIPS64r6 1054 // We still accept it but it is a normal nop. 1055 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) { 1056 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6"; 1057 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a " 1058 "nop instruction"); 1059 } 1060 1061 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) { 1062 // If this instruction has a delay slot and .set reorder is active, 1063 // emit a NOP after it. 1064 Instructions.push_back(Inst); 1065 MCInst NopInst; 1066 if (hasShortDelaySlot(Inst.getOpcode())) { 1067 NopInst.setOpcode(Mips::MOVE16_MM); 1068 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 1069 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 1070 } else { 1071 NopInst.setOpcode(Mips::SLL); 1072 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 1073 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 1074 NopInst.addOperand(MCOperand::CreateImm(0)); 1075 } 1076 Instructions.push_back(NopInst); 1077 return false; 1078 } 1079 1080 if (MCID.mayLoad() || MCID.mayStore()) { 1081 // Check the offset of memory operand, if it is a symbol 1082 // reference or immediate we may have to expand instructions. 1083 for (unsigned i = 0; i < MCID.getNumOperands(); i++) { 1084 const MCOperandInfo &OpInfo = MCID.OpInfo[i]; 1085 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) || 1086 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) { 1087 MCOperand &Op = Inst.getOperand(i); 1088 if (Op.isImm()) { 1089 int MemOffset = Op.getImm(); 1090 if (MemOffset < -32768 || MemOffset > 32767) { 1091 // Offset can't exceed 16bit value. 1092 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true); 1093 return false; 1094 } 1095 } else if (Op.isExpr()) { 1096 const MCExpr *Expr = Op.getExpr(); 1097 if (Expr->getKind() == MCExpr::SymbolRef) { 1098 const MCSymbolRefExpr *SR = 1099 static_cast<const MCSymbolRefExpr *>(Expr); 1100 if (SR->getKind() == MCSymbolRefExpr::VK_None) { 1101 // Expand symbol. 1102 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false); 1103 return false; 1104 } 1105 } else if (!isEvaluated(Expr)) { 1106 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false); 1107 return false; 1108 } 1109 } 1110 } 1111 } // for 1112 } // if load/store 1113 1114 if (needsExpansion(Inst)) 1115 return expandInstruction(Inst, IDLoc, Instructions); 1116 else 1117 Instructions.push_back(Inst); 1118 1119 return false; 1120 } 1121 1122 bool MipsAsmParser::needsExpansion(MCInst &Inst) { 1123 1124 switch (Inst.getOpcode()) { 1125 case Mips::LoadImm32Reg: 1126 case Mips::LoadAddr32Imm: 1127 case Mips::LoadAddr32Reg: 1128 case Mips::LoadImm64Reg: 1129 return true; 1130 default: 1131 return false; 1132 } 1133 } 1134 1135 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc, 1136 SmallVectorImpl<MCInst> &Instructions) { 1137 switch (Inst.getOpcode()) { 1138 default: 1139 assert(0 && "unimplemented expansion"); 1140 return true; 1141 case Mips::LoadImm32Reg: 1142 return expandLoadImm(Inst, IDLoc, Instructions); 1143 case Mips::LoadImm64Reg: 1144 if (!isGP64bit()) { 1145 Error(IDLoc, "instruction requires a 64-bit architecture"); 1146 return true; 1147 } 1148 return expandLoadImm(Inst, IDLoc, Instructions); 1149 case Mips::LoadAddr32Imm: 1150 return expandLoadAddressImm(Inst, IDLoc, Instructions); 1151 case Mips::LoadAddr32Reg: 1152 return expandLoadAddressReg(Inst, IDLoc, Instructions); 1153 } 1154 } 1155 1156 namespace { 1157 template <bool PerformShift> 1158 void createShiftOr(MCOperand Operand, unsigned RegNo, SMLoc IDLoc, 1159 SmallVectorImpl<MCInst> &Instructions) { 1160 MCInst tmpInst; 1161 if (PerformShift) { 1162 tmpInst.setOpcode(Mips::DSLL); 1163 tmpInst.addOperand(MCOperand::CreateReg(RegNo)); 1164 tmpInst.addOperand(MCOperand::CreateReg(RegNo)); 1165 tmpInst.addOperand(MCOperand::CreateImm(16)); 1166 tmpInst.setLoc(IDLoc); 1167 Instructions.push_back(tmpInst); 1168 tmpInst.clear(); 1169 } 1170 tmpInst.setOpcode(Mips::ORi); 1171 tmpInst.addOperand(MCOperand::CreateReg(RegNo)); 1172 tmpInst.addOperand(MCOperand::CreateReg(RegNo)); 1173 tmpInst.addOperand(Operand); 1174 tmpInst.setLoc(IDLoc); 1175 Instructions.push_back(tmpInst); 1176 } 1177 1178 template <int Shift, bool PerformShift> 1179 void createShiftOr(int64_t Value, unsigned RegNo, SMLoc IDLoc, 1180 SmallVectorImpl<MCInst> &Instructions) { 1181 createShiftOr<PerformShift>( 1182 MCOperand::CreateImm(((Value & (0xffffLL << Shift)) >> Shift)), RegNo, 1183 IDLoc, Instructions); 1184 } 1185 } 1186 1187 bool MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc, 1188 SmallVectorImpl<MCInst> &Instructions) { 1189 MCInst tmpInst; 1190 const MCOperand &ImmOp = Inst.getOperand(1); 1191 assert(ImmOp.isImm() && "expected immediate operand kind"); 1192 const MCOperand &RegOp = Inst.getOperand(0); 1193 assert(RegOp.isReg() && "expected register operand kind"); 1194 1195 int64_t ImmValue = ImmOp.getImm(); 1196 tmpInst.setLoc(IDLoc); 1197 // FIXME: gas has a special case for values that are 000...1111, which 1198 // becomes a li -1 and then a dsrl 1199 if (0 <= ImmValue && ImmValue <= 65535) { 1200 // For 0 <= j <= 65535. 1201 // li d,j => ori d,$zero,j 1202 tmpInst.setOpcode(Mips::ORi); 1203 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 1204 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 1205 tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 1206 Instructions.push_back(tmpInst); 1207 } else if (ImmValue < 0 && ImmValue >= -32768) { 1208 // For -32768 <= j < 0. 1209 // li d,j => addiu d,$zero,j 1210 tmpInst.setOpcode(Mips::ADDiu); 1211 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 1212 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 1213 tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 1214 Instructions.push_back(tmpInst); 1215 } else if ((ImmValue & 0xffffffff) == ImmValue) { 1216 // For any value of j that is representable as a 32-bit integer, create 1217 // a sequence of: 1218 // li d,j => lui d,hi16(j) 1219 // ori d,d,lo16(j) 1220 tmpInst.setOpcode(Mips::LUi); 1221 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 1222 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); 1223 Instructions.push_back(tmpInst); 1224 createShiftOr<0, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions); 1225 } else if ((ImmValue & (0xffffLL << 48)) == 0) { 1226 if (!isGP64bit()) { 1227 Error(IDLoc, "instruction requires a 64-bit architecture"); 1228 return true; 1229 } 1230 1231 // <------- lo32 ------> 1232 // <------- hi32 ------> 1233 // <- hi16 -> <- lo16 -> 1234 // _________________________________ 1235 // | | | | 1236 // | 16-bytes | 16-bytes | 16-bytes | 1237 // |__________|__________|__________| 1238 // 1239 // For any value of j that is representable as a 48-bit integer, create 1240 // a sequence of: 1241 // li d,j => lui d,hi16(j) 1242 // ori d,d,hi16(lo32(j)) 1243 // dsll d,d,16 1244 // ori d,d,lo16(lo32(j)) 1245 tmpInst.setOpcode(Mips::LUi); 1246 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 1247 tmpInst.addOperand( 1248 MCOperand::CreateImm((ImmValue & (0xffffLL << 32)) >> 32)); 1249 Instructions.push_back(tmpInst); 1250 createShiftOr<16, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions); 1251 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions); 1252 } else { 1253 if (!isGP64bit()) { 1254 Error(IDLoc, "instruction requires a 64-bit architecture"); 1255 return true; 1256 } 1257 1258 // <------- hi32 ------> <------- lo32 ------> 1259 // <- hi16 -> <- lo16 -> 1260 // ___________________________________________ 1261 // | | | | | 1262 // | 16-bytes | 16-bytes | 16-bytes | 16-bytes | 1263 // |__________|__________|__________|__________| 1264 // 1265 // For any value of j that isn't representable as a 48-bit integer. 1266 // li d,j => lui d,hi16(j) 1267 // ori d,d,lo16(hi32(j)) 1268 // dsll d,d,16 1269 // ori d,d,hi16(lo32(j)) 1270 // dsll d,d,16 1271 // ori d,d,lo16(lo32(j)) 1272 tmpInst.setOpcode(Mips::LUi); 1273 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 1274 tmpInst.addOperand( 1275 MCOperand::CreateImm((ImmValue & (0xffffLL << 48)) >> 48)); 1276 Instructions.push_back(tmpInst); 1277 createShiftOr<32, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions); 1278 createShiftOr<16, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions); 1279 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions); 1280 } 1281 return false; 1282 } 1283 1284 bool 1285 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc, 1286 SmallVectorImpl<MCInst> &Instructions) { 1287 MCInst tmpInst; 1288 const MCOperand &ImmOp = Inst.getOperand(2); 1289 assert((ImmOp.isImm() || ImmOp.isExpr()) && 1290 "expected immediate operand kind"); 1291 if (!ImmOp.isImm()) { 1292 expandLoadAddressSym(Inst, IDLoc, Instructions); 1293 return false; 1294 } 1295 const MCOperand &SrcRegOp = Inst.getOperand(1); 1296 assert(SrcRegOp.isReg() && "expected register operand kind"); 1297 const MCOperand &DstRegOp = Inst.getOperand(0); 1298 assert(DstRegOp.isReg() && "expected register operand kind"); 1299 int ImmValue = ImmOp.getImm(); 1300 if (-32768 <= ImmValue && ImmValue <= 65535) { 1301 // For -32768 <= j <= 65535. 1302 // la d,j(s) => addiu d,s,j 1303 tmpInst.setOpcode(Mips::ADDiu); 1304 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 1305 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg())); 1306 tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 1307 Instructions.push_back(tmpInst); 1308 } else { 1309 // For any other value of j that is representable as a 32-bit integer. 1310 // la d,j(s) => lui d,hi16(j) 1311 // ori d,d,lo16(j) 1312 // addu d,d,s 1313 tmpInst.setOpcode(Mips::LUi); 1314 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 1315 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); 1316 Instructions.push_back(tmpInst); 1317 tmpInst.clear(); 1318 tmpInst.setOpcode(Mips::ORi); 1319 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 1320 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 1321 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff)); 1322 Instructions.push_back(tmpInst); 1323 tmpInst.clear(); 1324 tmpInst.setOpcode(Mips::ADDu); 1325 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 1326 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 1327 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg())); 1328 Instructions.push_back(tmpInst); 1329 } 1330 return false; 1331 } 1332 1333 bool 1334 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc, 1335 SmallVectorImpl<MCInst> &Instructions) { 1336 MCInst tmpInst; 1337 const MCOperand &ImmOp = Inst.getOperand(1); 1338 assert((ImmOp.isImm() || ImmOp.isExpr()) && 1339 "expected immediate operand kind"); 1340 if (!ImmOp.isImm()) { 1341 expandLoadAddressSym(Inst, IDLoc, Instructions); 1342 return false; 1343 } 1344 const MCOperand &RegOp = Inst.getOperand(0); 1345 assert(RegOp.isReg() && "expected register operand kind"); 1346 int ImmValue = ImmOp.getImm(); 1347 if (-32768 <= ImmValue && ImmValue <= 65535) { 1348 // For -32768 <= j <= 65535. 1349 // la d,j => addiu d,$zero,j 1350 tmpInst.setOpcode(Mips::ADDiu); 1351 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 1352 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 1353 tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 1354 Instructions.push_back(tmpInst); 1355 } else { 1356 // For any other value of j that is representable as a 32-bit integer. 1357 // la d,j => lui d,hi16(j) 1358 // ori d,d,lo16(j) 1359 tmpInst.setOpcode(Mips::LUi); 1360 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 1361 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); 1362 Instructions.push_back(tmpInst); 1363 tmpInst.clear(); 1364 tmpInst.setOpcode(Mips::ORi); 1365 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 1366 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 1367 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff)); 1368 Instructions.push_back(tmpInst); 1369 } 1370 return false; 1371 } 1372 1373 void 1374 MipsAsmParser::expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc, 1375 SmallVectorImpl<MCInst> &Instructions) { 1376 // FIXME: If we do have a valid at register to use, we should generate a 1377 // slightly shorter sequence here. 1378 MCInst tmpInst; 1379 int ExprOperandNo = 1; 1380 // Sometimes the assembly parser will get the immediate expression as 1381 // a $zero + an immediate. 1382 if (Inst.getNumOperands() == 3) { 1383 assert(Inst.getOperand(1).getReg() == 1384 (isGP64bit() ? Mips::ZERO_64 : Mips::ZERO)); 1385 ExprOperandNo = 2; 1386 } 1387 const MCOperand &SymOp = Inst.getOperand(ExprOperandNo); 1388 assert(SymOp.isExpr() && "expected symbol operand kind"); 1389 const MCOperand &RegOp = Inst.getOperand(0); 1390 unsigned RegNo = RegOp.getReg(); 1391 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymOp.getExpr()); 1392 const MCSymbolRefExpr *HiExpr = 1393 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(), 1394 MCSymbolRefExpr::VK_Mips_ABS_HI, getContext()); 1395 const MCSymbolRefExpr *LoExpr = 1396 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(), 1397 MCSymbolRefExpr::VK_Mips_ABS_LO, getContext()); 1398 if (isGP64bit()) { 1399 // If it's a 64-bit architecture, expand to: 1400 // la d,sym => lui d,highest(sym) 1401 // ori d,d,higher(sym) 1402 // dsll d,d,16 1403 // ori d,d,hi16(sym) 1404 // dsll d,d,16 1405 // ori d,d,lo16(sym) 1406 const MCSymbolRefExpr *HighestExpr = 1407 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(), 1408 MCSymbolRefExpr::VK_Mips_HIGHEST, getContext()); 1409 const MCSymbolRefExpr *HigherExpr = 1410 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(), 1411 MCSymbolRefExpr::VK_Mips_HIGHER, getContext()); 1412 1413 tmpInst.setOpcode(Mips::LUi); 1414 tmpInst.addOperand(MCOperand::CreateReg(RegNo)); 1415 tmpInst.addOperand(MCOperand::CreateExpr(HighestExpr)); 1416 Instructions.push_back(tmpInst); 1417 1418 createShiftOr<false>(MCOperand::CreateExpr(HigherExpr), RegNo, SMLoc(), 1419 Instructions); 1420 createShiftOr<true>(MCOperand::CreateExpr(HiExpr), RegNo, SMLoc(), 1421 Instructions); 1422 createShiftOr<true>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(), 1423 Instructions); 1424 } else { 1425 // Otherwise, expand to: 1426 // la d,sym => lui d,hi16(sym) 1427 // ori d,d,lo16(sym) 1428 tmpInst.setOpcode(Mips::LUi); 1429 tmpInst.addOperand(MCOperand::CreateReg(RegNo)); 1430 tmpInst.addOperand(MCOperand::CreateExpr(HiExpr)); 1431 Instructions.push_back(tmpInst); 1432 1433 createShiftOr<false>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(), 1434 Instructions); 1435 } 1436 } 1437 1438 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, 1439 SmallVectorImpl<MCInst> &Instructions, 1440 bool isLoad, bool isImmOpnd) { 1441 const MCSymbolRefExpr *SR; 1442 MCInst TempInst; 1443 unsigned ImmOffset, HiOffset, LoOffset; 1444 const MCExpr *ExprOffset; 1445 unsigned TmpRegNum; 1446 // 1st operand is either the source or destination register. 1447 assert(Inst.getOperand(0).isReg() && "expected register operand kind"); 1448 unsigned RegOpNum = Inst.getOperand(0).getReg(); 1449 // 2nd operand is the base register. 1450 assert(Inst.getOperand(1).isReg() && "expected register operand kind"); 1451 unsigned BaseRegNum = Inst.getOperand(1).getReg(); 1452 // 3rd operand is either an immediate or expression. 1453 if (isImmOpnd) { 1454 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind"); 1455 ImmOffset = Inst.getOperand(2).getImm(); 1456 LoOffset = ImmOffset & 0x0000ffff; 1457 HiOffset = (ImmOffset & 0xffff0000) >> 16; 1458 // If msb of LoOffset is 1(negative number) we must increment HiOffset. 1459 if (LoOffset & 0x8000) 1460 HiOffset++; 1461 } else 1462 ExprOffset = Inst.getOperand(2).getExpr(); 1463 // All instructions will have the same location. 1464 TempInst.setLoc(IDLoc); 1465 // These are some of the types of expansions we perform here: 1466 // 1) lw $8, sym => lui $8, %hi(sym) 1467 // lw $8, %lo(sym)($8) 1468 // 2) lw $8, offset($9) => lui $8, %hi(offset) 1469 // add $8, $8, $9 1470 // lw $8, %lo(offset)($9) 1471 // 3) lw $8, offset($8) => lui $at, %hi(offset) 1472 // add $at, $at, $8 1473 // lw $8, %lo(offset)($at) 1474 // 4) sw $8, sym => lui $at, %hi(sym) 1475 // sw $8, %lo(sym)($at) 1476 // 5) sw $8, offset($8) => lui $at, %hi(offset) 1477 // add $at, $at, $8 1478 // sw $8, %lo(offset)($at) 1479 // 6) ldc1 $f0, sym => lui $at, %hi(sym) 1480 // ldc1 $f0, %lo(sym)($at) 1481 // 1482 // For load instructions we can use the destination register as a temporary 1483 // if base and dst are different (examples 1 and 2) and if the base register 1484 // is general purpose otherwise we must use $at (example 6) and error if it's 1485 // not available. For stores we must use $at (examples 4 and 5) because we 1486 // must not clobber the source register setting up the offset. 1487 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode()); 1488 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass; 1489 unsigned RegClassIDOp0 = 1490 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID(); 1491 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) || 1492 (RegClassIDOp0 == Mips::GPR64RegClassID); 1493 if (isLoad && IsGPR && (BaseRegNum != RegOpNum)) 1494 TmpRegNum = RegOpNum; 1495 else { 1496 int AT = getATReg(IDLoc); 1497 // At this point we need AT to perform the expansions and we exit if it is 1498 // not available. 1499 if (!AT) 1500 return; 1501 TmpRegNum = getReg( 1502 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, AT); 1503 } 1504 1505 TempInst.setOpcode(Mips::LUi); 1506 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 1507 if (isImmOpnd) 1508 TempInst.addOperand(MCOperand::CreateImm(HiOffset)); 1509 else { 1510 if (ExprOffset->getKind() == MCExpr::SymbolRef) { 1511 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset); 1512 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create( 1513 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI, 1514 getContext()); 1515 TempInst.addOperand(MCOperand::CreateExpr(HiExpr)); 1516 } else { 1517 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi"); 1518 TempInst.addOperand(MCOperand::CreateExpr(HiExpr)); 1519 } 1520 } 1521 // Add the instruction to the list. 1522 Instructions.push_back(TempInst); 1523 // Prepare TempInst for next instruction. 1524 TempInst.clear(); 1525 // Add temp register to base. 1526 TempInst.setOpcode(Mips::ADDu); 1527 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 1528 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 1529 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum)); 1530 Instructions.push_back(TempInst); 1531 TempInst.clear(); 1532 // And finally, create original instruction with low part 1533 // of offset and new base. 1534 TempInst.setOpcode(Inst.getOpcode()); 1535 TempInst.addOperand(MCOperand::CreateReg(RegOpNum)); 1536 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 1537 if (isImmOpnd) 1538 TempInst.addOperand(MCOperand::CreateImm(LoOffset)); 1539 else { 1540 if (ExprOffset->getKind() == MCExpr::SymbolRef) { 1541 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create( 1542 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO, 1543 getContext()); 1544 TempInst.addOperand(MCOperand::CreateExpr(LoExpr)); 1545 } else { 1546 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo"); 1547 TempInst.addOperand(MCOperand::CreateExpr(LoExpr)); 1548 } 1549 } 1550 Instructions.push_back(TempInst); 1551 TempInst.clear(); 1552 } 1553 1554 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) { 1555 // As described by the Mips32r2 spec, the registers Rd and Rs for 1556 // jalr.hb must be different. 1557 unsigned Opcode = Inst.getOpcode(); 1558 1559 if (Opcode == Mips::JALR_HB && 1560 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())) 1561 return Match_RequiresDifferentSrcAndDst; 1562 1563 return Match_Success; 1564 } 1565 1566 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 1567 OperandVector &Operands, 1568 MCStreamer &Out, 1569 uint64_t &ErrorInfo, 1570 bool MatchingInlineAsm) { 1571 1572 MCInst Inst; 1573 SmallVector<MCInst, 8> Instructions; 1574 unsigned MatchResult = 1575 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm); 1576 1577 switch (MatchResult) { 1578 default: 1579 break; 1580 case Match_Success: { 1581 if (processInstruction(Inst, IDLoc, Instructions)) 1582 return true; 1583 for (unsigned i = 0; i < Instructions.size(); i++) 1584 Out.EmitInstruction(Instructions[i], STI); 1585 return false; 1586 } 1587 case Match_MissingFeature: 1588 Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 1589 return true; 1590 case Match_InvalidOperand: { 1591 SMLoc ErrorLoc = IDLoc; 1592 if (ErrorInfo != ~0ULL) { 1593 if (ErrorInfo >= Operands.size()) 1594 return Error(IDLoc, "too few operands for instruction"); 1595 1596 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc(); 1597 if (ErrorLoc == SMLoc()) 1598 ErrorLoc = IDLoc; 1599 } 1600 1601 return Error(ErrorLoc, "invalid operand for instruction"); 1602 } 1603 case Match_MnemonicFail: 1604 return Error(IDLoc, "invalid instruction"); 1605 case Match_RequiresDifferentSrcAndDst: 1606 return Error(IDLoc, "source and destination must be different"); 1607 } 1608 return true; 1609 } 1610 1611 void MipsAsmParser::warnIfAssemblerTemporary(int RegIndex, SMLoc Loc) { 1612 if ((RegIndex != 0) && 1613 ((int)AssemblerOptions.back()->getATRegNum() == RegIndex)) { 1614 if (RegIndex == 1) 1615 Warning(Loc, "used $at without \".set noat\""); 1616 else 1617 Warning(Loc, Twine("used $") + Twine(RegIndex) + " with \".set at=$" + 1618 Twine(RegIndex) + "\""); 1619 } 1620 } 1621 1622 int MipsAsmParser::matchCPURegisterName(StringRef Name) { 1623 int CC; 1624 1625 CC = StringSwitch<unsigned>(Name) 1626 .Case("zero", 0) 1627 .Case("at", 1) 1628 .Case("a0", 4) 1629 .Case("a1", 5) 1630 .Case("a2", 6) 1631 .Case("a3", 7) 1632 .Case("v0", 2) 1633 .Case("v1", 3) 1634 .Case("s0", 16) 1635 .Case("s1", 17) 1636 .Case("s2", 18) 1637 .Case("s3", 19) 1638 .Case("s4", 20) 1639 .Case("s5", 21) 1640 .Case("s6", 22) 1641 .Case("s7", 23) 1642 .Case("k0", 26) 1643 .Case("k1", 27) 1644 .Case("gp", 28) 1645 .Case("sp", 29) 1646 .Case("fp", 30) 1647 .Case("s8", 30) 1648 .Case("ra", 31) 1649 .Case("t0", 8) 1650 .Case("t1", 9) 1651 .Case("t2", 10) 1652 .Case("t3", 11) 1653 .Case("t4", 12) 1654 .Case("t5", 13) 1655 .Case("t6", 14) 1656 .Case("t7", 15) 1657 .Case("t8", 24) 1658 .Case("t9", 25) 1659 .Default(-1); 1660 1661 if (!(isABI_N32() || isABI_N64())) 1662 return CC; 1663 1664 // Although SGI documentation just cuts out t0-t3 for n32/n64, 1665 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7 1666 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7. 1667 if (8 <= CC && CC <= 11) 1668 CC += 4; 1669 1670 if (CC == -1) 1671 CC = StringSwitch<unsigned>(Name) 1672 .Case("a4", 8) 1673 .Case("a5", 9) 1674 .Case("a6", 10) 1675 .Case("a7", 11) 1676 .Case("kt0", 26) 1677 .Case("kt1", 27) 1678 .Default(-1); 1679 1680 return CC; 1681 } 1682 1683 int MipsAsmParser::matchFPURegisterName(StringRef Name) { 1684 1685 if (Name[0] == 'f') { 1686 StringRef NumString = Name.substr(1); 1687 unsigned IntVal; 1688 if (NumString.getAsInteger(10, IntVal)) 1689 return -1; // This is not an integer. 1690 if (IntVal > 31) // Maximum index for fpu register. 1691 return -1; 1692 return IntVal; 1693 } 1694 return -1; 1695 } 1696 1697 int MipsAsmParser::matchFCCRegisterName(StringRef Name) { 1698 1699 if (Name.startswith("fcc")) { 1700 StringRef NumString = Name.substr(3); 1701 unsigned IntVal; 1702 if (NumString.getAsInteger(10, IntVal)) 1703 return -1; // This is not an integer. 1704 if (IntVal > 7) // There are only 8 fcc registers. 1705 return -1; 1706 return IntVal; 1707 } 1708 return -1; 1709 } 1710 1711 int MipsAsmParser::matchACRegisterName(StringRef Name) { 1712 1713 if (Name.startswith("ac")) { 1714 StringRef NumString = Name.substr(2); 1715 unsigned IntVal; 1716 if (NumString.getAsInteger(10, IntVal)) 1717 return -1; // This is not an integer. 1718 if (IntVal > 3) // There are only 3 acc registers. 1719 return -1; 1720 return IntVal; 1721 } 1722 return -1; 1723 } 1724 1725 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) { 1726 unsigned IntVal; 1727 1728 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal)) 1729 return -1; 1730 1731 if (IntVal > 31) 1732 return -1; 1733 1734 return IntVal; 1735 } 1736 1737 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) { 1738 int CC; 1739 1740 CC = StringSwitch<unsigned>(Name) 1741 .Case("msair", 0) 1742 .Case("msacsr", 1) 1743 .Case("msaaccess", 2) 1744 .Case("msasave", 3) 1745 .Case("msamodify", 4) 1746 .Case("msarequest", 5) 1747 .Case("msamap", 6) 1748 .Case("msaunmap", 7) 1749 .Default(-1); 1750 1751 return CC; 1752 } 1753 1754 bool MipsAssemblerOptions::setATReg(unsigned Reg) { 1755 if (Reg > 31) 1756 return false; 1757 1758 ATReg = Reg; 1759 return true; 1760 } 1761 1762 int MipsAsmParser::getATReg(SMLoc Loc) { 1763 int AT = AssemblerOptions.back()->getATRegNum(); 1764 if (AT == 0) 1765 reportParseError(Loc, 1766 "pseudo-instruction requires $at, which is not available"); 1767 return AT; 1768 } 1769 1770 unsigned MipsAsmParser::getReg(int RC, int RegNo) { 1771 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo); 1772 } 1773 1774 unsigned MipsAsmParser::getGPR(int RegNo) { 1775 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, 1776 RegNo); 1777 } 1778 1779 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) { 1780 if (RegNum > 1781 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1) 1782 return -1; 1783 1784 return getReg(RegClass, RegNum); 1785 } 1786 1787 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { 1788 DEBUG(dbgs() << "parseOperand\n"); 1789 1790 // Check if the current operand has a custom associated parser, if so, try to 1791 // custom parse the operand, or fallback to the general approach. 1792 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 1793 if (ResTy == MatchOperand_Success) 1794 return false; 1795 // If there wasn't a custom match, try the generic matcher below. Otherwise, 1796 // there was a match, but an error occurred, in which case, just return that 1797 // the operand parsing failed. 1798 if (ResTy == MatchOperand_ParseFail) 1799 return true; 1800 1801 DEBUG(dbgs() << ".. Generic Parser\n"); 1802 1803 switch (getLexer().getKind()) { 1804 default: 1805 Error(Parser.getTok().getLoc(), "unexpected token in operand"); 1806 return true; 1807 case AsmToken::Dollar: { 1808 // Parse the register. 1809 SMLoc S = Parser.getTok().getLoc(); 1810 1811 // Almost all registers have been parsed by custom parsers. There is only 1812 // one exception to this. $zero (and it's alias $0) will reach this point 1813 // for div, divu, and similar instructions because it is not an operand 1814 // to the instruction definition but an explicit register. Special case 1815 // this situation for now. 1816 if (parseAnyRegister(Operands) != MatchOperand_NoMatch) 1817 return false; 1818 1819 // Maybe it is a symbol reference. 1820 StringRef Identifier; 1821 if (Parser.parseIdentifier(Identifier)) 1822 return true; 1823 1824 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1825 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier); 1826 // Otherwise create a symbol reference. 1827 const MCExpr *Res = 1828 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext()); 1829 1830 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this)); 1831 return false; 1832 } 1833 // Else drop to expression parsing. 1834 case AsmToken::LParen: 1835 case AsmToken::Minus: 1836 case AsmToken::Plus: 1837 case AsmToken::Integer: 1838 case AsmToken::Tilde: 1839 case AsmToken::String: { 1840 DEBUG(dbgs() << ".. generic integer\n"); 1841 OperandMatchResultTy ResTy = parseImm(Operands); 1842 return ResTy != MatchOperand_Success; 1843 } 1844 case AsmToken::Percent: { 1845 // It is a symbol reference or constant expression. 1846 const MCExpr *IdVal; 1847 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand. 1848 if (parseRelocOperand(IdVal)) 1849 return true; 1850 1851 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1852 1853 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this)); 1854 return false; 1855 } // case AsmToken::Percent 1856 } // switch(getLexer().getKind()) 1857 return true; 1858 } 1859 1860 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr, 1861 StringRef RelocStr) { 1862 const MCExpr *Res; 1863 // Check the type of the expression. 1864 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) { 1865 // It's a constant, evaluate reloc value. 1866 int16_t Val; 1867 switch (getVariantKind(RelocStr)) { 1868 case MCSymbolRefExpr::VK_Mips_ABS_LO: 1869 // Get the 1st 16-bits. 1870 Val = MCE->getValue() & 0xffff; 1871 break; 1872 case MCSymbolRefExpr::VK_Mips_ABS_HI: 1873 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low 1874 // 16 bits being negative. 1875 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff; 1876 break; 1877 case MCSymbolRefExpr::VK_Mips_HIGHER: 1878 // Get the 3rd 16-bits. 1879 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff; 1880 break; 1881 case MCSymbolRefExpr::VK_Mips_HIGHEST: 1882 // Get the 4th 16-bits. 1883 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff; 1884 break; 1885 default: 1886 report_fatal_error("unsupported reloc value"); 1887 } 1888 return MCConstantExpr::Create(Val, getContext()); 1889 } 1890 1891 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) { 1892 // It's a symbol, create a symbolic expression from the symbol. 1893 StringRef Symbol = MSRE->getSymbol().getName(); 1894 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr); 1895 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext()); 1896 return Res; 1897 } 1898 1899 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) { 1900 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr); 1901 1902 // Try to create target expression. 1903 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE)) 1904 return MipsMCExpr::Create(VK, Expr, getContext()); 1905 1906 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr); 1907 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr); 1908 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext()); 1909 return Res; 1910 } 1911 1912 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) { 1913 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr); 1914 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext()); 1915 return Res; 1916 } 1917 // Just return the original expression. 1918 return Expr; 1919 } 1920 1921 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) { 1922 1923 switch (Expr->getKind()) { 1924 case MCExpr::Constant: 1925 return true; 1926 case MCExpr::SymbolRef: 1927 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None); 1928 case MCExpr::Binary: 1929 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) { 1930 if (!isEvaluated(BE->getLHS())) 1931 return false; 1932 return isEvaluated(BE->getRHS()); 1933 } 1934 case MCExpr::Unary: 1935 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr()); 1936 case MCExpr::Target: 1937 return true; 1938 } 1939 return false; 1940 } 1941 1942 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) { 1943 Parser.Lex(); // Eat the % token. 1944 const AsmToken &Tok = Parser.getTok(); // Get next token, operation. 1945 if (Tok.isNot(AsmToken::Identifier)) 1946 return true; 1947 1948 std::string Str = Tok.getIdentifier().str(); 1949 1950 Parser.Lex(); // Eat the identifier. 1951 // Now make an expression from the rest of the operand. 1952 const MCExpr *IdVal; 1953 SMLoc EndLoc; 1954 1955 if (getLexer().getKind() == AsmToken::LParen) { 1956 while (1) { 1957 Parser.Lex(); // Eat the '(' token. 1958 if (getLexer().getKind() == AsmToken::Percent) { 1959 Parser.Lex(); // Eat the % token. 1960 const AsmToken &nextTok = Parser.getTok(); 1961 if (nextTok.isNot(AsmToken::Identifier)) 1962 return true; 1963 Str += "(%"; 1964 Str += nextTok.getIdentifier(); 1965 Parser.Lex(); // Eat the identifier. 1966 if (getLexer().getKind() != AsmToken::LParen) 1967 return true; 1968 } else 1969 break; 1970 } 1971 if (getParser().parseParenExpression(IdVal, EndLoc)) 1972 return true; 1973 1974 while (getLexer().getKind() == AsmToken::RParen) 1975 Parser.Lex(); // Eat the ')' token. 1976 1977 } else 1978 return true; // Parenthesis must follow the relocation operand. 1979 1980 Res = evaluateRelocExpr(IdVal, Str); 1981 return false; 1982 } 1983 1984 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 1985 SMLoc &EndLoc) { 1986 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands; 1987 OperandMatchResultTy ResTy = parseAnyRegister(Operands); 1988 if (ResTy == MatchOperand_Success) { 1989 assert(Operands.size() == 1); 1990 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front()); 1991 StartLoc = Operand.getStartLoc(); 1992 EndLoc = Operand.getEndLoc(); 1993 1994 // AFAIK, we only support numeric registers and named GPR's in CFI 1995 // directives. 1996 // Don't worry about eating tokens before failing. Using an unrecognised 1997 // register is a parse error. 1998 if (Operand.isGPRAsmReg()) { 1999 // Resolve to GPR32 or GPR64 appropriately. 2000 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg(); 2001 } 2002 2003 return (RegNo == (unsigned)-1); 2004 } 2005 2006 assert(Operands.size() == 0); 2007 return (RegNo == (unsigned)-1); 2008 } 2009 2010 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) { 2011 SMLoc S; 2012 bool Result = true; 2013 2014 while (getLexer().getKind() == AsmToken::LParen) 2015 Parser.Lex(); 2016 2017 switch (getLexer().getKind()) { 2018 default: 2019 return true; 2020 case AsmToken::Identifier: 2021 case AsmToken::LParen: 2022 case AsmToken::Integer: 2023 case AsmToken::Minus: 2024 case AsmToken::Plus: 2025 if (isParenExpr) 2026 Result = getParser().parseParenExpression(Res, S); 2027 else 2028 Result = (getParser().parseExpression(Res)); 2029 while (getLexer().getKind() == AsmToken::RParen) 2030 Parser.Lex(); 2031 break; 2032 case AsmToken::Percent: 2033 Result = parseRelocOperand(Res); 2034 } 2035 return Result; 2036 } 2037 2038 MipsAsmParser::OperandMatchResultTy 2039 MipsAsmParser::parseMemOperand(OperandVector &Operands) { 2040 DEBUG(dbgs() << "parseMemOperand\n"); 2041 const MCExpr *IdVal = nullptr; 2042 SMLoc S; 2043 bool isParenExpr = false; 2044 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch; 2045 // First operand is the offset. 2046 S = Parser.getTok().getLoc(); 2047 2048 if (getLexer().getKind() == AsmToken::LParen) { 2049 Parser.Lex(); 2050 isParenExpr = true; 2051 } 2052 2053 if (getLexer().getKind() != AsmToken::Dollar) { 2054 if (parseMemOffset(IdVal, isParenExpr)) 2055 return MatchOperand_ParseFail; 2056 2057 const AsmToken &Tok = Parser.getTok(); // Get the next token. 2058 if (Tok.isNot(AsmToken::LParen)) { 2059 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]); 2060 if (Mnemonic.getToken() == "la") { 2061 SMLoc E = 2062 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 2063 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this)); 2064 return MatchOperand_Success; 2065 } 2066 if (Tok.is(AsmToken::EndOfStatement)) { 2067 SMLoc E = 2068 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 2069 2070 // Zero register assumed, add a memory operand with ZERO as its base. 2071 // "Base" will be managed by k_Memory. 2072 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(), 2073 S, E, *this); 2074 Operands.push_back( 2075 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this)); 2076 return MatchOperand_Success; 2077 } 2078 Error(Parser.getTok().getLoc(), "'(' expected"); 2079 return MatchOperand_ParseFail; 2080 } 2081 2082 Parser.Lex(); // Eat the '(' token. 2083 } 2084 2085 Res = parseAnyRegister(Operands); 2086 if (Res != MatchOperand_Success) 2087 return Res; 2088 2089 if (Parser.getTok().isNot(AsmToken::RParen)) { 2090 Error(Parser.getTok().getLoc(), "')' expected"); 2091 return MatchOperand_ParseFail; 2092 } 2093 2094 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 2095 2096 Parser.Lex(); // Eat the ')' token. 2097 2098 if (!IdVal) 2099 IdVal = MCConstantExpr::Create(0, getContext()); 2100 2101 // Replace the register operand with the memory operand. 2102 std::unique_ptr<MipsOperand> op( 2103 static_cast<MipsOperand *>(Operands.back().release())); 2104 // Remove the register from the operands. 2105 // "op" will be managed by k_Memory. 2106 Operands.pop_back(); 2107 // Add the memory operand. 2108 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) { 2109 int64_t Imm; 2110 if (IdVal->EvaluateAsAbsolute(Imm)) 2111 IdVal = MCConstantExpr::Create(Imm, getContext()); 2112 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef) 2113 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(), 2114 getContext()); 2115 } 2116 2117 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this)); 2118 return MatchOperand_Success; 2119 } 2120 2121 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) { 2122 2123 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier()); 2124 if (Sym) { 2125 SMLoc S = Parser.getTok().getLoc(); 2126 const MCExpr *Expr; 2127 if (Sym->isVariable()) 2128 Expr = Sym->getVariableValue(); 2129 else 2130 return false; 2131 if (Expr->getKind() == MCExpr::SymbolRef) { 2132 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr); 2133 StringRef DefSymbol = Ref->getSymbol().getName(); 2134 if (DefSymbol.startswith("$")) { 2135 OperandMatchResultTy ResTy = 2136 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S); 2137 if (ResTy == MatchOperand_Success) { 2138 Parser.Lex(); 2139 return true; 2140 } else if (ResTy == MatchOperand_ParseFail) 2141 llvm_unreachable("Should never ParseFail"); 2142 return false; 2143 } 2144 } else if (Expr->getKind() == MCExpr::Constant) { 2145 Parser.Lex(); 2146 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr); 2147 Operands.push_back( 2148 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this)); 2149 return true; 2150 } 2151 } 2152 return false; 2153 } 2154 2155 MipsAsmParser::OperandMatchResultTy 2156 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands, 2157 StringRef Identifier, 2158 SMLoc S) { 2159 int Index = matchCPURegisterName(Identifier); 2160 if (Index != -1) { 2161 Operands.push_back(MipsOperand::createGPRReg( 2162 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 2163 return MatchOperand_Success; 2164 } 2165 2166 Index = matchFPURegisterName(Identifier); 2167 if (Index != -1) { 2168 Operands.push_back(MipsOperand::createFGRReg( 2169 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 2170 return MatchOperand_Success; 2171 } 2172 2173 Index = matchFCCRegisterName(Identifier); 2174 if (Index != -1) { 2175 Operands.push_back(MipsOperand::createFCCReg( 2176 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 2177 return MatchOperand_Success; 2178 } 2179 2180 Index = matchACRegisterName(Identifier); 2181 if (Index != -1) { 2182 Operands.push_back(MipsOperand::createACCReg( 2183 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 2184 return MatchOperand_Success; 2185 } 2186 2187 Index = matchMSA128RegisterName(Identifier); 2188 if (Index != -1) { 2189 Operands.push_back(MipsOperand::createMSA128Reg( 2190 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 2191 return MatchOperand_Success; 2192 } 2193 2194 Index = matchMSA128CtrlRegisterName(Identifier); 2195 if (Index != -1) { 2196 Operands.push_back(MipsOperand::createMSACtrlReg( 2197 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this)); 2198 return MatchOperand_Success; 2199 } 2200 2201 return MatchOperand_NoMatch; 2202 } 2203 2204 MipsAsmParser::OperandMatchResultTy 2205 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) { 2206 auto Token = Parser.getLexer().peekTok(false); 2207 2208 if (Token.is(AsmToken::Identifier)) { 2209 DEBUG(dbgs() << ".. identifier\n"); 2210 StringRef Identifier = Token.getIdentifier(); 2211 OperandMatchResultTy ResTy = 2212 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S); 2213 return ResTy; 2214 } else if (Token.is(AsmToken::Integer)) { 2215 DEBUG(dbgs() << ".. integer\n"); 2216 Operands.push_back(MipsOperand::createNumericReg( 2217 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(), 2218 *this)); 2219 return MatchOperand_Success; 2220 } 2221 2222 DEBUG(dbgs() << Parser.getTok().getKind() << "\n"); 2223 2224 return MatchOperand_NoMatch; 2225 } 2226 2227 MipsAsmParser::OperandMatchResultTy 2228 MipsAsmParser::parseAnyRegister(OperandVector &Operands) { 2229 DEBUG(dbgs() << "parseAnyRegister\n"); 2230 2231 auto Token = Parser.getTok(); 2232 2233 SMLoc S = Token.getLoc(); 2234 2235 if (Token.isNot(AsmToken::Dollar)) { 2236 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n"); 2237 if (Token.is(AsmToken::Identifier)) { 2238 if (searchSymbolAlias(Operands)) 2239 return MatchOperand_Success; 2240 } 2241 DEBUG(dbgs() << ".. !symalias -> NoMatch\n"); 2242 return MatchOperand_NoMatch; 2243 } 2244 DEBUG(dbgs() << ".. $\n"); 2245 2246 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S); 2247 if (ResTy == MatchOperand_Success) { 2248 Parser.Lex(); // $ 2249 Parser.Lex(); // identifier 2250 } 2251 return ResTy; 2252 } 2253 2254 MipsAsmParser::OperandMatchResultTy 2255 MipsAsmParser::parseImm(OperandVector &Operands) { 2256 switch (getLexer().getKind()) { 2257 default: 2258 return MatchOperand_NoMatch; 2259 case AsmToken::LParen: 2260 case AsmToken::Minus: 2261 case AsmToken::Plus: 2262 case AsmToken::Integer: 2263 case AsmToken::Tilde: 2264 case AsmToken::String: 2265 break; 2266 } 2267 2268 const MCExpr *IdVal; 2269 SMLoc S = Parser.getTok().getLoc(); 2270 if (getParser().parseExpression(IdVal)) 2271 return MatchOperand_ParseFail; 2272 2273 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 2274 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this)); 2275 return MatchOperand_Success; 2276 } 2277 2278 MipsAsmParser::OperandMatchResultTy 2279 MipsAsmParser::parseJumpTarget(OperandVector &Operands) { 2280 DEBUG(dbgs() << "parseJumpTarget\n"); 2281 2282 SMLoc S = getLexer().getLoc(); 2283 2284 // Integers and expressions are acceptable 2285 OperandMatchResultTy ResTy = parseImm(Operands); 2286 if (ResTy != MatchOperand_NoMatch) 2287 return ResTy; 2288 2289 // Registers are a valid target and have priority over symbols. 2290 ResTy = parseAnyRegister(Operands); 2291 if (ResTy != MatchOperand_NoMatch) 2292 return ResTy; 2293 2294 const MCExpr *Expr = nullptr; 2295 if (Parser.parseExpression(Expr)) { 2296 // We have no way of knowing if a symbol was consumed so we must ParseFail 2297 return MatchOperand_ParseFail; 2298 } 2299 Operands.push_back( 2300 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this)); 2301 return MatchOperand_Success; 2302 } 2303 2304 MipsAsmParser::OperandMatchResultTy 2305 MipsAsmParser::parseInvNum(OperandVector &Operands) { 2306 const MCExpr *IdVal; 2307 // If the first token is '$' we may have register operand. 2308 if (Parser.getTok().is(AsmToken::Dollar)) 2309 return MatchOperand_NoMatch; 2310 SMLoc S = Parser.getTok().getLoc(); 2311 if (getParser().parseExpression(IdVal)) 2312 return MatchOperand_ParseFail; 2313 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal); 2314 assert(MCE && "Unexpected MCExpr type."); 2315 int64_t Val = MCE->getValue(); 2316 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 2317 Operands.push_back(MipsOperand::CreateImm( 2318 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this)); 2319 return MatchOperand_Success; 2320 } 2321 2322 MipsAsmParser::OperandMatchResultTy 2323 MipsAsmParser::parseLSAImm(OperandVector &Operands) { 2324 switch (getLexer().getKind()) { 2325 default: 2326 return MatchOperand_NoMatch; 2327 case AsmToken::LParen: 2328 case AsmToken::Plus: 2329 case AsmToken::Minus: 2330 case AsmToken::Integer: 2331 break; 2332 } 2333 2334 const MCExpr *Expr; 2335 SMLoc S = Parser.getTok().getLoc(); 2336 2337 if (getParser().parseExpression(Expr)) 2338 return MatchOperand_ParseFail; 2339 2340 int64_t Val; 2341 if (!Expr->EvaluateAsAbsolute(Val)) { 2342 Error(S, "expected immediate value"); 2343 return MatchOperand_ParseFail; 2344 } 2345 2346 // The LSA instruction allows a 2-bit unsigned immediate. For this reason 2347 // and because the CPU always adds one to the immediate field, the allowed 2348 // range becomes 1..4. We'll only check the range here and will deal 2349 // with the addition/subtraction when actually decoding/encoding 2350 // the instruction. 2351 if (Val < 1 || Val > 4) { 2352 Error(S, "immediate not in range (1..4)"); 2353 return MatchOperand_ParseFail; 2354 } 2355 2356 Operands.push_back( 2357 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this)); 2358 return MatchOperand_Success; 2359 } 2360 2361 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) { 2362 2363 MCSymbolRefExpr::VariantKind VK = 2364 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol) 2365 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI) 2366 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO) 2367 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL) 2368 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL) 2369 .Case("got", MCSymbolRefExpr::VK_Mips_GOT) 2370 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD) 2371 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM) 2372 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI) 2373 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO) 2374 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL) 2375 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI) 2376 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO) 2377 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP) 2378 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE) 2379 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST) 2380 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI) 2381 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO) 2382 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16) 2383 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16) 2384 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16) 2385 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16) 2386 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER) 2387 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST) 2388 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16) 2389 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16) 2390 .Default(MCSymbolRefExpr::VK_None); 2391 2392 assert(VK != MCSymbolRefExpr::VK_None); 2393 2394 return VK; 2395 } 2396 2397 /// Sometimes (i.e. load/stores) the operand may be followed immediately by 2398 /// either this. 2399 /// ::= '(', register, ')' 2400 /// handle it before we iterate so we don't get tripped up by the lack of 2401 /// a comma. 2402 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) { 2403 if (getLexer().is(AsmToken::LParen)) { 2404 Operands.push_back( 2405 MipsOperand::CreateToken("(", getLexer().getLoc(), *this)); 2406 Parser.Lex(); 2407 if (parseOperand(Operands, Name)) { 2408 SMLoc Loc = getLexer().getLoc(); 2409 Parser.eatToEndOfStatement(); 2410 return Error(Loc, "unexpected token in argument list"); 2411 } 2412 if (Parser.getTok().isNot(AsmToken::RParen)) { 2413 SMLoc Loc = getLexer().getLoc(); 2414 Parser.eatToEndOfStatement(); 2415 return Error(Loc, "unexpected token, expected ')'"); 2416 } 2417 Operands.push_back( 2418 MipsOperand::CreateToken(")", getLexer().getLoc(), *this)); 2419 Parser.Lex(); 2420 } 2421 return false; 2422 } 2423 2424 /// Sometimes (i.e. in MSA) the operand may be followed immediately by 2425 /// either one of these. 2426 /// ::= '[', register, ']' 2427 /// ::= '[', integer, ']' 2428 /// handle it before we iterate so we don't get tripped up by the lack of 2429 /// a comma. 2430 bool MipsAsmParser::parseBracketSuffix(StringRef Name, 2431 OperandVector &Operands) { 2432 if (getLexer().is(AsmToken::LBrac)) { 2433 Operands.push_back( 2434 MipsOperand::CreateToken("[", getLexer().getLoc(), *this)); 2435 Parser.Lex(); 2436 if (parseOperand(Operands, Name)) { 2437 SMLoc Loc = getLexer().getLoc(); 2438 Parser.eatToEndOfStatement(); 2439 return Error(Loc, "unexpected token in argument list"); 2440 } 2441 if (Parser.getTok().isNot(AsmToken::RBrac)) { 2442 SMLoc Loc = getLexer().getLoc(); 2443 Parser.eatToEndOfStatement(); 2444 return Error(Loc, "unexpected token, expected ']'"); 2445 } 2446 Operands.push_back( 2447 MipsOperand::CreateToken("]", getLexer().getLoc(), *this)); 2448 Parser.Lex(); 2449 } 2450 return false; 2451 } 2452 2453 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 2454 SMLoc NameLoc, OperandVector &Operands) { 2455 DEBUG(dbgs() << "ParseInstruction\n"); 2456 2457 // We have reached first instruction, module directive are now forbidden. 2458 getTargetStreamer().forbidModuleDirective(); 2459 2460 // Check if we have valid mnemonic 2461 if (!mnemonicIsValid(Name, 0)) { 2462 Parser.eatToEndOfStatement(); 2463 return Error(NameLoc, "unknown instruction"); 2464 } 2465 // First operand in MCInst is instruction mnemonic. 2466 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this)); 2467 2468 // Read the remaining operands. 2469 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2470 // Read the first operand. 2471 if (parseOperand(Operands, Name)) { 2472 SMLoc Loc = getLexer().getLoc(); 2473 Parser.eatToEndOfStatement(); 2474 return Error(Loc, "unexpected token in argument list"); 2475 } 2476 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands)) 2477 return true; 2478 // AFAIK, parenthesis suffixes are never on the first operand 2479 2480 while (getLexer().is(AsmToken::Comma)) { 2481 Parser.Lex(); // Eat the comma. 2482 // Parse and remember the operand. 2483 if (parseOperand(Operands, Name)) { 2484 SMLoc Loc = getLexer().getLoc(); 2485 Parser.eatToEndOfStatement(); 2486 return Error(Loc, "unexpected token in argument list"); 2487 } 2488 // Parse bracket and parenthesis suffixes before we iterate 2489 if (getLexer().is(AsmToken::LBrac)) { 2490 if (parseBracketSuffix(Name, Operands)) 2491 return true; 2492 } else if (getLexer().is(AsmToken::LParen) && 2493 parseParenSuffix(Name, Operands)) 2494 return true; 2495 } 2496 } 2497 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2498 SMLoc Loc = getLexer().getLoc(); 2499 Parser.eatToEndOfStatement(); 2500 return Error(Loc, "unexpected token in argument list"); 2501 } 2502 Parser.Lex(); // Consume the EndOfStatement. 2503 return false; 2504 } 2505 2506 bool MipsAsmParser::reportParseError(Twine ErrorMsg) { 2507 SMLoc Loc = getLexer().getLoc(); 2508 Parser.eatToEndOfStatement(); 2509 return Error(Loc, ErrorMsg); 2510 } 2511 2512 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) { 2513 return Error(Loc, ErrorMsg); 2514 } 2515 2516 bool MipsAsmParser::parseSetNoAtDirective() { 2517 // Line should look like: ".set noat". 2518 // set at reg to 0. 2519 AssemblerOptions.back()->setATReg(0); 2520 // eat noat 2521 Parser.Lex(); 2522 // If this is not the end of the statement, report an error. 2523 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2524 reportParseError("unexpected token, expected end of statement"); 2525 return false; 2526 } 2527 Parser.Lex(); // Consume the EndOfStatement. 2528 return false; 2529 } 2530 2531 bool MipsAsmParser::parseSetAtDirective() { 2532 // Line can be .set at - defaults to $1 2533 // or .set at=$reg 2534 int AtRegNo; 2535 getParser().Lex(); 2536 if (getLexer().is(AsmToken::EndOfStatement)) { 2537 AssemblerOptions.back()->setATReg(1); 2538 Parser.Lex(); // Consume the EndOfStatement. 2539 return false; 2540 } else if (getLexer().is(AsmToken::Equal)) { 2541 getParser().Lex(); // Eat the '='. 2542 if (getLexer().isNot(AsmToken::Dollar)) { 2543 reportParseError("unexpected token, expected dollar sign '$'"); 2544 return false; 2545 } 2546 Parser.Lex(); // Eat the '$'. 2547 const AsmToken &Reg = Parser.getTok(); 2548 if (Reg.is(AsmToken::Identifier)) { 2549 AtRegNo = matchCPURegisterName(Reg.getIdentifier()); 2550 } else if (Reg.is(AsmToken::Integer)) { 2551 AtRegNo = Reg.getIntVal(); 2552 } else { 2553 reportParseError("unexpected token, expected identifier or integer"); 2554 return false; 2555 } 2556 2557 if (AtRegNo < 0 || AtRegNo > 31) { 2558 reportParseError("unexpected token in statement"); 2559 return false; 2560 } 2561 2562 if (!AssemblerOptions.back()->setATReg(AtRegNo)) { 2563 reportParseError("invalid register"); 2564 return false; 2565 } 2566 getParser().Lex(); // Eat the register. 2567 2568 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2569 reportParseError("unexpected token, expected end of statement"); 2570 return false; 2571 } 2572 Parser.Lex(); // Consume the EndOfStatement. 2573 return false; 2574 } else { 2575 reportParseError("unexpected token in statement"); 2576 return false; 2577 } 2578 } 2579 2580 bool MipsAsmParser::parseSetReorderDirective() { 2581 Parser.Lex(); 2582 // If this is not the end of the statement, report an error. 2583 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2584 reportParseError("unexpected token, expected end of statement"); 2585 return false; 2586 } 2587 AssemblerOptions.back()->setReorder(); 2588 getTargetStreamer().emitDirectiveSetReorder(); 2589 Parser.Lex(); // Consume the EndOfStatement. 2590 return false; 2591 } 2592 2593 bool MipsAsmParser::parseSetNoReorderDirective() { 2594 Parser.Lex(); 2595 // If this is not the end of the statement, report an error. 2596 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2597 reportParseError("unexpected token, expected end of statement"); 2598 return false; 2599 } 2600 AssemblerOptions.back()->setNoReorder(); 2601 getTargetStreamer().emitDirectiveSetNoReorder(); 2602 Parser.Lex(); // Consume the EndOfStatement. 2603 return false; 2604 } 2605 2606 bool MipsAsmParser::parseSetMacroDirective() { 2607 Parser.Lex(); 2608 // If this is not the end of the statement, report an error. 2609 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2610 reportParseError("unexpected token, expected end of statement"); 2611 return false; 2612 } 2613 AssemblerOptions.back()->setMacro(); 2614 Parser.Lex(); // Consume the EndOfStatement. 2615 return false; 2616 } 2617 2618 bool MipsAsmParser::parseSetNoMacroDirective() { 2619 Parser.Lex(); 2620 // If this is not the end of the statement, report an error. 2621 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2622 reportParseError("unexpected token, expected end of statement"); 2623 return false; 2624 } 2625 if (AssemblerOptions.back()->isReorder()) { 2626 reportParseError("`noreorder' must be set before `nomacro'"); 2627 return false; 2628 } 2629 AssemblerOptions.back()->setNoMacro(); 2630 Parser.Lex(); // Consume the EndOfStatement. 2631 return false; 2632 } 2633 2634 bool MipsAsmParser::parseSetMsaDirective() { 2635 Parser.Lex(); 2636 2637 // If this is not the end of the statement, report an error. 2638 if (getLexer().isNot(AsmToken::EndOfStatement)) 2639 return reportParseError("unexpected token, expected end of statement"); 2640 2641 setFeatureBits(Mips::FeatureMSA, "msa"); 2642 getTargetStreamer().emitDirectiveSetMsa(); 2643 return false; 2644 } 2645 2646 bool MipsAsmParser::parseSetNoMsaDirective() { 2647 Parser.Lex(); 2648 2649 // If this is not the end of the statement, report an error. 2650 if (getLexer().isNot(AsmToken::EndOfStatement)) 2651 return reportParseError("unexpected token, expected end of statement"); 2652 2653 clearFeatureBits(Mips::FeatureMSA, "msa"); 2654 getTargetStreamer().emitDirectiveSetNoMsa(); 2655 return false; 2656 } 2657 2658 bool MipsAsmParser::parseSetNoDspDirective() { 2659 Parser.Lex(); // Eat "nodsp". 2660 2661 // If this is not the end of the statement, report an error. 2662 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2663 reportParseError("unexpected token, expected end of statement"); 2664 return false; 2665 } 2666 2667 clearFeatureBits(Mips::FeatureDSP, "dsp"); 2668 getTargetStreamer().emitDirectiveSetNoDsp(); 2669 return false; 2670 } 2671 2672 bool MipsAsmParser::parseSetNoMips16Directive() { 2673 Parser.Lex(); 2674 // If this is not the end of the statement, report an error. 2675 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2676 reportParseError("unexpected token, expected end of statement"); 2677 return false; 2678 } 2679 // For now do nothing. 2680 Parser.Lex(); // Consume the EndOfStatement. 2681 return false; 2682 } 2683 2684 bool MipsAsmParser::parseSetFpDirective() { 2685 MipsABIFlagsSection::FpABIKind FpAbiVal; 2686 // Line can be: .set fp=32 2687 // .set fp=xx 2688 // .set fp=64 2689 Parser.Lex(); // Eat fp token 2690 AsmToken Tok = Parser.getTok(); 2691 if (Tok.isNot(AsmToken::Equal)) { 2692 reportParseError("unexpected token, expected equals sign '='"); 2693 return false; 2694 } 2695 Parser.Lex(); // Eat '=' token. 2696 Tok = Parser.getTok(); 2697 2698 if (!parseFpABIValue(FpAbiVal, ".set")) 2699 return false; 2700 2701 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2702 reportParseError("unexpected token, expected end of statement"); 2703 return false; 2704 } 2705 getTargetStreamer().emitDirectiveSetFp(FpAbiVal); 2706 Parser.Lex(); // Consume the EndOfStatement. 2707 return false; 2708 } 2709 2710 bool MipsAsmParser::parseSetPopDirective() { 2711 SMLoc Loc = getLexer().getLoc(); 2712 2713 Parser.Lex(); 2714 if (getLexer().isNot(AsmToken::EndOfStatement)) 2715 return reportParseError("unexpected token, expected end of statement"); 2716 2717 // Always keep an element on the options "stack" to prevent the user 2718 // from changing the initial options. This is how we remember them. 2719 if (AssemblerOptions.size() == 2) 2720 return reportParseError(Loc, ".set pop with no .set push"); 2721 2722 AssemblerOptions.pop_back(); 2723 setAvailableFeatures(AssemblerOptions.back()->getFeatures()); 2724 2725 getTargetStreamer().emitDirectiveSetPop(); 2726 return false; 2727 } 2728 2729 bool MipsAsmParser::parseSetPushDirective() { 2730 Parser.Lex(); 2731 if (getLexer().isNot(AsmToken::EndOfStatement)) 2732 return reportParseError("unexpected token, expected end of statement"); 2733 2734 // Create a copy of the current assembler options environment and push it. 2735 AssemblerOptions.push_back( 2736 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get())); 2737 2738 getTargetStreamer().emitDirectiveSetPush(); 2739 return false; 2740 } 2741 2742 bool MipsAsmParser::parseSetAssignment() { 2743 StringRef Name; 2744 const MCExpr *Value; 2745 2746 if (Parser.parseIdentifier(Name)) 2747 reportParseError("expected identifier after .set"); 2748 2749 if (getLexer().isNot(AsmToken::Comma)) 2750 return reportParseError("unexpected token, expected comma"); 2751 Lex(); // Eat comma 2752 2753 if (Parser.parseExpression(Value)) 2754 return reportParseError("expected valid expression after comma"); 2755 2756 // Check if the Name already exists as a symbol. 2757 MCSymbol *Sym = getContext().LookupSymbol(Name); 2758 if (Sym) 2759 return reportParseError("symbol already defined"); 2760 Sym = getContext().GetOrCreateSymbol(Name); 2761 Sym->setVariableValue(Value); 2762 2763 return false; 2764 } 2765 2766 bool MipsAsmParser::parseSetMips0Directive() { 2767 Parser.Lex(); 2768 if (getLexer().isNot(AsmToken::EndOfStatement)) 2769 return reportParseError("unexpected token, expected end of statement"); 2770 2771 // Reset assembler options to their initial values. 2772 setAvailableFeatures(AssemblerOptions.front()->getFeatures()); 2773 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures()); 2774 2775 getTargetStreamer().emitDirectiveSetMips0(); 2776 return false; 2777 } 2778 2779 bool MipsAsmParser::parseSetArchDirective() { 2780 Parser.Lex(); 2781 if (getLexer().isNot(AsmToken::Equal)) 2782 return reportParseError("unexpected token, expected equals sign"); 2783 2784 Parser.Lex(); 2785 StringRef Arch; 2786 if (Parser.parseIdentifier(Arch)) 2787 return reportParseError("expected arch identifier"); 2788 2789 StringRef ArchFeatureName = 2790 StringSwitch<StringRef>(Arch) 2791 .Case("mips1", "mips1") 2792 .Case("mips2", "mips2") 2793 .Case("mips3", "mips3") 2794 .Case("mips4", "mips4") 2795 .Case("mips5", "mips5") 2796 .Case("mips32", "mips32") 2797 .Case("mips32r2", "mips32r2") 2798 .Case("mips32r6", "mips32r6") 2799 .Case("mips64", "mips64") 2800 .Case("mips64r2", "mips64r2") 2801 .Case("mips64r6", "mips64r6") 2802 .Case("cnmips", "cnmips") 2803 .Case("r4000", "mips3") // This is an implementation of Mips3. 2804 .Default(""); 2805 2806 if (ArchFeatureName.empty()) 2807 return reportParseError("unsupported architecture"); 2808 2809 selectArch(ArchFeatureName); 2810 getTargetStreamer().emitDirectiveSetArch(Arch); 2811 return false; 2812 } 2813 2814 bool MipsAsmParser::parseSetFeature(uint64_t Feature) { 2815 Parser.Lex(); 2816 if (getLexer().isNot(AsmToken::EndOfStatement)) 2817 return reportParseError("unexpected token, expected end of statement"); 2818 2819 switch (Feature) { 2820 default: 2821 llvm_unreachable("Unimplemented feature"); 2822 case Mips::FeatureDSP: 2823 setFeatureBits(Mips::FeatureDSP, "dsp"); 2824 getTargetStreamer().emitDirectiveSetDsp(); 2825 break; 2826 case Mips::FeatureMicroMips: 2827 getTargetStreamer().emitDirectiveSetMicroMips(); 2828 break; 2829 case Mips::FeatureMips16: 2830 getTargetStreamer().emitDirectiveSetMips16(); 2831 break; 2832 case Mips::FeatureMips1: 2833 selectArch("mips1"); 2834 getTargetStreamer().emitDirectiveSetMips1(); 2835 break; 2836 case Mips::FeatureMips2: 2837 selectArch("mips2"); 2838 getTargetStreamer().emitDirectiveSetMips2(); 2839 break; 2840 case Mips::FeatureMips3: 2841 selectArch("mips3"); 2842 getTargetStreamer().emitDirectiveSetMips3(); 2843 break; 2844 case Mips::FeatureMips4: 2845 selectArch("mips4"); 2846 getTargetStreamer().emitDirectiveSetMips4(); 2847 break; 2848 case Mips::FeatureMips5: 2849 selectArch("mips5"); 2850 getTargetStreamer().emitDirectiveSetMips5(); 2851 break; 2852 case Mips::FeatureMips32: 2853 selectArch("mips32"); 2854 getTargetStreamer().emitDirectiveSetMips32(); 2855 break; 2856 case Mips::FeatureMips32r2: 2857 selectArch("mips32r2"); 2858 getTargetStreamer().emitDirectiveSetMips32R2(); 2859 break; 2860 case Mips::FeatureMips32r6: 2861 selectArch("mips32r6"); 2862 getTargetStreamer().emitDirectiveSetMips32R6(); 2863 break; 2864 case Mips::FeatureMips64: 2865 selectArch("mips64"); 2866 getTargetStreamer().emitDirectiveSetMips64(); 2867 break; 2868 case Mips::FeatureMips64r2: 2869 selectArch("mips64r2"); 2870 getTargetStreamer().emitDirectiveSetMips64R2(); 2871 break; 2872 case Mips::FeatureMips64r6: 2873 selectArch("mips64r6"); 2874 getTargetStreamer().emitDirectiveSetMips64R6(); 2875 break; 2876 } 2877 return false; 2878 } 2879 2880 bool MipsAsmParser::eatComma(StringRef ErrorStr) { 2881 if (getLexer().isNot(AsmToken::Comma)) { 2882 SMLoc Loc = getLexer().getLoc(); 2883 Parser.eatToEndOfStatement(); 2884 return Error(Loc, ErrorStr); 2885 } 2886 2887 Parser.Lex(); // Eat the comma. 2888 return true; 2889 } 2890 2891 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) { 2892 if (AssemblerOptions.back()->isReorder()) 2893 Warning(Loc, ".cpload in reorder section"); 2894 2895 // FIXME: Warn if cpload is used in Mips16 mode. 2896 2897 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg; 2898 OperandMatchResultTy ResTy = parseAnyRegister(Reg); 2899 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) { 2900 reportParseError("expected register containing function address"); 2901 return false; 2902 } 2903 2904 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]); 2905 if (!RegOpnd.isGPRAsmReg()) { 2906 reportParseError(RegOpnd.getStartLoc(), "invalid register"); 2907 return false; 2908 } 2909 2910 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg()); 2911 return false; 2912 } 2913 2914 bool MipsAsmParser::parseDirectiveCPSetup() { 2915 unsigned FuncReg; 2916 unsigned Save; 2917 bool SaveIsReg = true; 2918 2919 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg; 2920 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg); 2921 if (ResTy == MatchOperand_NoMatch) { 2922 reportParseError("expected register containing function address"); 2923 Parser.eatToEndOfStatement(); 2924 return false; 2925 } 2926 2927 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]); 2928 if (!FuncRegOpnd.isGPRAsmReg()) { 2929 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register"); 2930 Parser.eatToEndOfStatement(); 2931 return false; 2932 } 2933 2934 FuncReg = FuncRegOpnd.getGPR32Reg(); 2935 TmpReg.clear(); 2936 2937 if (!eatComma("unexpected token, expected comma")) 2938 return true; 2939 2940 ResTy = parseAnyRegister(TmpReg); 2941 if (ResTy == MatchOperand_NoMatch) { 2942 const AsmToken &Tok = Parser.getTok(); 2943 if (Tok.is(AsmToken::Integer)) { 2944 Save = Tok.getIntVal(); 2945 SaveIsReg = false; 2946 Parser.Lex(); 2947 } else { 2948 reportParseError("expected save register or stack offset"); 2949 Parser.eatToEndOfStatement(); 2950 return false; 2951 } 2952 } else { 2953 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]); 2954 if (!SaveOpnd.isGPRAsmReg()) { 2955 reportParseError(SaveOpnd.getStartLoc(), "invalid register"); 2956 Parser.eatToEndOfStatement(); 2957 return false; 2958 } 2959 Save = SaveOpnd.getGPR32Reg(); 2960 } 2961 2962 if (!eatComma("unexpected token, expected comma")) 2963 return true; 2964 2965 StringRef Name; 2966 if (Parser.parseIdentifier(Name)) 2967 reportParseError("expected identifier"); 2968 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 2969 2970 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, *Sym, SaveIsReg); 2971 return false; 2972 } 2973 2974 bool MipsAsmParser::parseDirectiveNaN() { 2975 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2976 const AsmToken &Tok = Parser.getTok(); 2977 2978 if (Tok.getString() == "2008") { 2979 Parser.Lex(); 2980 getTargetStreamer().emitDirectiveNaN2008(); 2981 return false; 2982 } else if (Tok.getString() == "legacy") { 2983 Parser.Lex(); 2984 getTargetStreamer().emitDirectiveNaNLegacy(); 2985 return false; 2986 } 2987 } 2988 // If we don't recognize the option passed to the .nan 2989 // directive (e.g. no option or unknown option), emit an error. 2990 reportParseError("invalid option in .nan directive"); 2991 return false; 2992 } 2993 2994 bool MipsAsmParser::parseDirectiveSet() { 2995 2996 // Get the next token. 2997 const AsmToken &Tok = Parser.getTok(); 2998 2999 if (Tok.getString() == "noat") { 3000 return parseSetNoAtDirective(); 3001 } else if (Tok.getString() == "at") { 3002 return parseSetAtDirective(); 3003 } else if (Tok.getString() == "arch") { 3004 return parseSetArchDirective(); 3005 } else if (Tok.getString() == "fp") { 3006 return parseSetFpDirective(); 3007 } else if (Tok.getString() == "pop") { 3008 return parseSetPopDirective(); 3009 } else if (Tok.getString() == "push") { 3010 return parseSetPushDirective(); 3011 } else if (Tok.getString() == "reorder") { 3012 return parseSetReorderDirective(); 3013 } else if (Tok.getString() == "noreorder") { 3014 return parseSetNoReorderDirective(); 3015 } else if (Tok.getString() == "macro") { 3016 return parseSetMacroDirective(); 3017 } else if (Tok.getString() == "nomacro") { 3018 return parseSetNoMacroDirective(); 3019 } else if (Tok.getString() == "mips16") { 3020 return parseSetFeature(Mips::FeatureMips16); 3021 } else if (Tok.getString() == "nomips16") { 3022 return parseSetNoMips16Directive(); 3023 } else if (Tok.getString() == "nomicromips") { 3024 getTargetStreamer().emitDirectiveSetNoMicroMips(); 3025 Parser.eatToEndOfStatement(); 3026 return false; 3027 } else if (Tok.getString() == "micromips") { 3028 return parseSetFeature(Mips::FeatureMicroMips); 3029 } else if (Tok.getString() == "mips0") { 3030 return parseSetMips0Directive(); 3031 } else if (Tok.getString() == "mips1") { 3032 return parseSetFeature(Mips::FeatureMips1); 3033 } else if (Tok.getString() == "mips2") { 3034 return parseSetFeature(Mips::FeatureMips2); 3035 } else if (Tok.getString() == "mips3") { 3036 return parseSetFeature(Mips::FeatureMips3); 3037 } else if (Tok.getString() == "mips4") { 3038 return parseSetFeature(Mips::FeatureMips4); 3039 } else if (Tok.getString() == "mips5") { 3040 return parseSetFeature(Mips::FeatureMips5); 3041 } else if (Tok.getString() == "mips32") { 3042 return parseSetFeature(Mips::FeatureMips32); 3043 } else if (Tok.getString() == "mips32r2") { 3044 return parseSetFeature(Mips::FeatureMips32r2); 3045 } else if (Tok.getString() == "mips32r6") { 3046 return parseSetFeature(Mips::FeatureMips32r6); 3047 } else if (Tok.getString() == "mips64") { 3048 return parseSetFeature(Mips::FeatureMips64); 3049 } else if (Tok.getString() == "mips64r2") { 3050 return parseSetFeature(Mips::FeatureMips64r2); 3051 } else if (Tok.getString() == "mips64r6") { 3052 return parseSetFeature(Mips::FeatureMips64r6); 3053 } else if (Tok.getString() == "dsp") { 3054 return parseSetFeature(Mips::FeatureDSP); 3055 } else if (Tok.getString() == "nodsp") { 3056 return parseSetNoDspDirective(); 3057 } else if (Tok.getString() == "msa") { 3058 return parseSetMsaDirective(); 3059 } else if (Tok.getString() == "nomsa") { 3060 return parseSetNoMsaDirective(); 3061 } else { 3062 // It is just an identifier, look for an assignment. 3063 parseSetAssignment(); 3064 return false; 3065 } 3066 3067 return true; 3068 } 3069 3070 /// parseDataDirective 3071 /// ::= .word [ expression (, expression)* ] 3072 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) { 3073 if (getLexer().isNot(AsmToken::EndOfStatement)) { 3074 for (;;) { 3075 const MCExpr *Value; 3076 if (getParser().parseExpression(Value)) 3077 return true; 3078 3079 getParser().getStreamer().EmitValue(Value, Size); 3080 3081 if (getLexer().is(AsmToken::EndOfStatement)) 3082 break; 3083 3084 if (getLexer().isNot(AsmToken::Comma)) 3085 return Error(L, "unexpected token, expected comma"); 3086 Parser.Lex(); 3087 } 3088 } 3089 3090 Parser.Lex(); 3091 return false; 3092 } 3093 3094 /// parseDirectiveGpWord 3095 /// ::= .gpword local_sym 3096 bool MipsAsmParser::parseDirectiveGpWord() { 3097 const MCExpr *Value; 3098 // EmitGPRel32Value requires an expression, so we are using base class 3099 // method to evaluate the expression. 3100 if (getParser().parseExpression(Value)) 3101 return true; 3102 getParser().getStreamer().EmitGPRel32Value(Value); 3103 3104 if (getLexer().isNot(AsmToken::EndOfStatement)) 3105 return Error(getLexer().getLoc(), 3106 "unexpected token, expected end of statement"); 3107 Parser.Lex(); // Eat EndOfStatement token. 3108 return false; 3109 } 3110 3111 /// parseDirectiveGpDWord 3112 /// ::= .gpdword local_sym 3113 bool MipsAsmParser::parseDirectiveGpDWord() { 3114 const MCExpr *Value; 3115 // EmitGPRel64Value requires an expression, so we are using base class 3116 // method to evaluate the expression. 3117 if (getParser().parseExpression(Value)) 3118 return true; 3119 getParser().getStreamer().EmitGPRel64Value(Value); 3120 3121 if (getLexer().isNot(AsmToken::EndOfStatement)) 3122 return Error(getLexer().getLoc(), 3123 "unexpected token, expected end of statement"); 3124 Parser.Lex(); // Eat EndOfStatement token. 3125 return false; 3126 } 3127 3128 bool MipsAsmParser::parseDirectiveOption() { 3129 // Get the option token. 3130 AsmToken Tok = Parser.getTok(); 3131 // At the moment only identifiers are supported. 3132 if (Tok.isNot(AsmToken::Identifier)) { 3133 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier"); 3134 Parser.eatToEndOfStatement(); 3135 return false; 3136 } 3137 3138 StringRef Option = Tok.getIdentifier(); 3139 3140 if (Option == "pic0") { 3141 getTargetStreamer().emitDirectiveOptionPic0(); 3142 Parser.Lex(); 3143 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) { 3144 Error(Parser.getTok().getLoc(), 3145 "unexpected token, expected end of statement"); 3146 Parser.eatToEndOfStatement(); 3147 } 3148 return false; 3149 } 3150 3151 if (Option == "pic2") { 3152 getTargetStreamer().emitDirectiveOptionPic2(); 3153 Parser.Lex(); 3154 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) { 3155 Error(Parser.getTok().getLoc(), 3156 "unexpected token, expected end of statement"); 3157 Parser.eatToEndOfStatement(); 3158 } 3159 return false; 3160 } 3161 3162 // Unknown option. 3163 Warning(Parser.getTok().getLoc(), 3164 "unknown option, expected 'pic0' or 'pic2'"); 3165 Parser.eatToEndOfStatement(); 3166 return false; 3167 } 3168 3169 /// parseDirectiveModule 3170 /// ::= .module oddspreg 3171 /// ::= .module nooddspreg 3172 /// ::= .module fp=value 3173 bool MipsAsmParser::parseDirectiveModule() { 3174 MCAsmLexer &Lexer = getLexer(); 3175 SMLoc L = Lexer.getLoc(); 3176 3177 if (!getTargetStreamer().isModuleDirectiveAllowed()) { 3178 // TODO : get a better message. 3179 reportParseError(".module directive must appear before any code"); 3180 return false; 3181 } 3182 3183 if (Lexer.is(AsmToken::Identifier)) { 3184 StringRef Option = Parser.getTok().getString(); 3185 Parser.Lex(); 3186 3187 if (Option == "oddspreg") { 3188 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32()); 3189 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg"); 3190 3191 if (getLexer().isNot(AsmToken::EndOfStatement)) { 3192 reportParseError("unexpected token, expected end of statement"); 3193 return false; 3194 } 3195 3196 return false; 3197 } else if (Option == "nooddspreg") { 3198 if (!isABI_O32()) { 3199 Error(L, "'.module nooddspreg' requires the O32 ABI"); 3200 return false; 3201 } 3202 3203 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32()); 3204 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg"); 3205 3206 if (getLexer().isNot(AsmToken::EndOfStatement)) { 3207 reportParseError("unexpected token, expected end of statement"); 3208 return false; 3209 } 3210 3211 return false; 3212 } else if (Option == "fp") { 3213 return parseDirectiveModuleFP(); 3214 } 3215 3216 return Error(L, "'" + Twine(Option) + "' is not a valid .module option."); 3217 } 3218 3219 return false; 3220 } 3221 3222 /// parseDirectiveModuleFP 3223 /// ::= =32 3224 /// ::= =xx 3225 /// ::= =64 3226 bool MipsAsmParser::parseDirectiveModuleFP() { 3227 MCAsmLexer &Lexer = getLexer(); 3228 3229 if (Lexer.isNot(AsmToken::Equal)) { 3230 reportParseError("unexpected token, expected equals sign '='"); 3231 return false; 3232 } 3233 Parser.Lex(); // Eat '=' token. 3234 3235 MipsABIFlagsSection::FpABIKind FpABI; 3236 if (!parseFpABIValue(FpABI, ".module")) 3237 return false; 3238 3239 if (getLexer().isNot(AsmToken::EndOfStatement)) { 3240 reportParseError("unexpected token, expected end of statement"); 3241 return false; 3242 } 3243 3244 // Emit appropriate flags. 3245 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32()); 3246 Parser.Lex(); // Consume the EndOfStatement. 3247 return false; 3248 } 3249 3250 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI, 3251 StringRef Directive) { 3252 MCAsmLexer &Lexer = getLexer(); 3253 3254 if (Lexer.is(AsmToken::Identifier)) { 3255 StringRef Value = Parser.getTok().getString(); 3256 Parser.Lex(); 3257 3258 if (Value != "xx") { 3259 reportParseError("unsupported value, expected 'xx', '32' or '64'"); 3260 return false; 3261 } 3262 3263 if (!isABI_O32()) { 3264 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI"); 3265 return false; 3266 } 3267 3268 FpABI = MipsABIFlagsSection::FpABIKind::XX; 3269 return true; 3270 } 3271 3272 if (Lexer.is(AsmToken::Integer)) { 3273 unsigned Value = Parser.getTok().getIntVal(); 3274 Parser.Lex(); 3275 3276 if (Value != 32 && Value != 64) { 3277 reportParseError("unsupported value, expected 'xx', '32' or '64'"); 3278 return false; 3279 } 3280 3281 if (Value == 32) { 3282 if (!isABI_O32()) { 3283 reportParseError("'" + Directive + " fp=32' requires the O32 ABI"); 3284 return false; 3285 } 3286 3287 FpABI = MipsABIFlagsSection::FpABIKind::S32; 3288 } else 3289 FpABI = MipsABIFlagsSection::FpABIKind::S64; 3290 3291 return true; 3292 } 3293 3294 return false; 3295 } 3296 3297 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) { 3298 StringRef IDVal = DirectiveID.getString(); 3299 3300 if (IDVal == ".cpload") 3301 return parseDirectiveCpLoad(DirectiveID.getLoc()); 3302 if (IDVal == ".dword") { 3303 parseDataDirective(8, DirectiveID.getLoc()); 3304 return false; 3305 } 3306 if (IDVal == ".ent") { 3307 StringRef SymbolName; 3308 3309 if (Parser.parseIdentifier(SymbolName)) { 3310 reportParseError("expected identifier after .ent"); 3311 return false; 3312 } 3313 3314 // There's an undocumented extension that allows an integer to 3315 // follow the name of the procedure which AFAICS is ignored by GAS. 3316 // Example: .ent foo,2 3317 if (getLexer().isNot(AsmToken::EndOfStatement)) { 3318 if (getLexer().isNot(AsmToken::Comma)) { 3319 // Even though we accept this undocumented extension for compatibility 3320 // reasons, the additional integer argument does not actually change 3321 // the behaviour of the '.ent' directive, so we would like to discourage 3322 // its use. We do this by not referring to the extended version in 3323 // error messages which are not directly related to its use. 3324 reportParseError("unexpected token, expected end of statement"); 3325 return false; 3326 } 3327 Parser.Lex(); // Eat the comma. 3328 const MCExpr *DummyNumber; 3329 int64_t DummyNumberVal; 3330 // If the user was explicitly trying to use the extended version, 3331 // we still give helpful extension-related error messages. 3332 if (Parser.parseExpression(DummyNumber)) { 3333 reportParseError("expected number after comma"); 3334 return false; 3335 } 3336 if (!DummyNumber->EvaluateAsAbsolute(DummyNumberVal)) { 3337 reportParseError("expected an absolute expression after comma"); 3338 return false; 3339 } 3340 } 3341 3342 // If this is not the end of the statement, report an error. 3343 if (getLexer().isNot(AsmToken::EndOfStatement)) { 3344 reportParseError("unexpected token, expected end of statement"); 3345 return false; 3346 } 3347 3348 MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName); 3349 3350 getTargetStreamer().emitDirectiveEnt(*Sym); 3351 CurrentFn = Sym; 3352 return false; 3353 } 3354 3355 if (IDVal == ".end") { 3356 StringRef SymbolName; 3357 3358 if (Parser.parseIdentifier(SymbolName)) { 3359 reportParseError("expected identifier after .end"); 3360 return false; 3361 } 3362 3363 if (getLexer().isNot(AsmToken::EndOfStatement)) { 3364 reportParseError("unexpected token, expected end of statement"); 3365 return false; 3366 } 3367 3368 if (CurrentFn == nullptr) { 3369 reportParseError(".end used without .ent"); 3370 return false; 3371 } 3372 3373 if ((SymbolName != CurrentFn->getName())) { 3374 reportParseError(".end symbol does not match .ent symbol"); 3375 return false; 3376 } 3377 3378 getTargetStreamer().emitDirectiveEnd(SymbolName); 3379 CurrentFn = nullptr; 3380 return false; 3381 } 3382 3383 if (IDVal == ".frame") { 3384 // .frame $stack_reg, frame_size_in_bytes, $return_reg 3385 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg; 3386 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg); 3387 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) { 3388 reportParseError("expected stack register"); 3389 return false; 3390 } 3391 3392 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]); 3393 if (!StackRegOpnd.isGPRAsmReg()) { 3394 reportParseError(StackRegOpnd.getStartLoc(), 3395 "expected general purpose register"); 3396 return false; 3397 } 3398 unsigned StackReg = StackRegOpnd.getGPR32Reg(); 3399 3400 if (Parser.getTok().is(AsmToken::Comma)) 3401 Parser.Lex(); 3402 else { 3403 reportParseError("unexpected token, expected comma"); 3404 return false; 3405 } 3406 3407 // Parse the frame size. 3408 const MCExpr *FrameSize; 3409 int64_t FrameSizeVal; 3410 3411 if (Parser.parseExpression(FrameSize)) { 3412 reportParseError("expected frame size value"); 3413 return false; 3414 } 3415 3416 if (!FrameSize->EvaluateAsAbsolute(FrameSizeVal)) { 3417 reportParseError("frame size not an absolute expression"); 3418 return false; 3419 } 3420 3421 if (Parser.getTok().is(AsmToken::Comma)) 3422 Parser.Lex(); 3423 else { 3424 reportParseError("unexpected token, expected comma"); 3425 return false; 3426 } 3427 3428 // Parse the return register. 3429 TmpReg.clear(); 3430 ResTy = parseAnyRegister(TmpReg); 3431 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) { 3432 reportParseError("expected return register"); 3433 return false; 3434 } 3435 3436 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]); 3437 if (!ReturnRegOpnd.isGPRAsmReg()) { 3438 reportParseError(ReturnRegOpnd.getStartLoc(), 3439 "expected general purpose register"); 3440 return false; 3441 } 3442 3443 // If this is not the end of the statement, report an error. 3444 if (getLexer().isNot(AsmToken::EndOfStatement)) { 3445 reportParseError("unexpected token, expected end of statement"); 3446 return false; 3447 } 3448 3449 getTargetStreamer().emitFrame(StackReg, FrameSizeVal, 3450 ReturnRegOpnd.getGPR32Reg()); 3451 return false; 3452 } 3453 3454 if (IDVal == ".set") { 3455 return parseDirectiveSet(); 3456 } 3457 3458 if (IDVal == ".mask" || IDVal == ".fmask") { 3459 // .mask bitmask, frame_offset 3460 // bitmask: One bit for each register used. 3461 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where 3462 // first register is expected to be saved. 3463 // Examples: 3464 // .mask 0x80000000, -4 3465 // .fmask 0x80000000, -4 3466 // 3467 3468 // Parse the bitmask 3469 const MCExpr *BitMask; 3470 int64_t BitMaskVal; 3471 3472 if (Parser.parseExpression(BitMask)) { 3473 reportParseError("expected bitmask value"); 3474 return false; 3475 } 3476 3477 if (!BitMask->EvaluateAsAbsolute(BitMaskVal)) { 3478 reportParseError("bitmask not an absolute expression"); 3479 return false; 3480 } 3481 3482 if (Parser.getTok().is(AsmToken::Comma)) 3483 Parser.Lex(); 3484 else { 3485 reportParseError("unexpected token, expected comma"); 3486 return false; 3487 } 3488 3489 // Parse the frame_offset 3490 const MCExpr *FrameOffset; 3491 int64_t FrameOffsetVal; 3492 3493 if (Parser.parseExpression(FrameOffset)) { 3494 reportParseError("expected frame offset value"); 3495 return false; 3496 } 3497 3498 if (!FrameOffset->EvaluateAsAbsolute(FrameOffsetVal)) { 3499 reportParseError("frame offset not an absolute expression"); 3500 return false; 3501 } 3502 3503 // If this is not the end of the statement, report an error. 3504 if (getLexer().isNot(AsmToken::EndOfStatement)) { 3505 reportParseError("unexpected token, expected end of statement"); 3506 return false; 3507 } 3508 3509 if (IDVal == ".mask") 3510 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal); 3511 else 3512 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal); 3513 return false; 3514 } 3515 3516 if (IDVal == ".nan") 3517 return parseDirectiveNaN(); 3518 3519 if (IDVal == ".gpword") { 3520 parseDirectiveGpWord(); 3521 return false; 3522 } 3523 3524 if (IDVal == ".gpdword") { 3525 parseDirectiveGpDWord(); 3526 return false; 3527 } 3528 3529 if (IDVal == ".word") { 3530 parseDataDirective(4, DirectiveID.getLoc()); 3531 return false; 3532 } 3533 3534 if (IDVal == ".option") 3535 return parseDirectiveOption(); 3536 3537 if (IDVal == ".abicalls") { 3538 getTargetStreamer().emitDirectiveAbiCalls(); 3539 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) { 3540 Error(Parser.getTok().getLoc(), 3541 "unexpected token, expected end of statement"); 3542 // Clear line 3543 Parser.eatToEndOfStatement(); 3544 } 3545 return false; 3546 } 3547 3548 if (IDVal == ".cpsetup") 3549 return parseDirectiveCPSetup(); 3550 3551 if (IDVal == ".module") 3552 return parseDirectiveModule(); 3553 3554 return true; 3555 } 3556 3557 extern "C" void LLVMInitializeMipsAsmParser() { 3558 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget); 3559 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget); 3560 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target); 3561 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget); 3562 } 3563 3564 #define GET_REGISTER_MATCHER 3565 #define GET_MATCHER_IMPLEMENTATION 3566 #include "MipsGenAsmMatcher.inc" 3567