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