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