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