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