1//===-- SparcAsmParser.cpp - Parse Sparc 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/SparcMCTargetDesc.h" 11#include "MCTargetDesc/SparcMCExpr.h" 12#include "llvm/ADT/STLExtras.h" 13#include "llvm/MC/MCContext.h" 14#include "llvm/MC/MCInst.h" 15#include "llvm/MC/MCObjectFileInfo.h" 16#include "llvm/MC/MCParser/MCParsedAsmOperand.h" 17#include "llvm/MC/MCStreamer.h" 18#include "llvm/MC/MCSubtargetInfo.h" 19#include "llvm/MC/MCSymbol.h" 20#include "llvm/MC/MCTargetAsmParser.h" 21#include "llvm/Support/TargetRegistry.h" 22 23using namespace llvm; 24 25// The generated AsmMatcher SparcGenAsmMatcher uses "Sparc" as the target 26// namespace. But SPARC backend uses "SP" as its namespace. 27namespace llvm { 28 namespace Sparc { 29 using namespace SP; 30 } 31} 32 33namespace { 34class SparcOperand; 35class SparcAsmParser : public MCTargetAsmParser { 36 37 MCSubtargetInfo &STI; 38 MCAsmParser &Parser; 39 40 /// @name Auto-generated Match Functions 41 /// { 42 43#define GET_ASSEMBLER_HEADER 44#include "SparcGenAsmMatcher.inc" 45 46 /// } 47 48 // public interface of the MCTargetAsmParser. 49 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 50 OperandVector &Operands, MCStreamer &Out, 51 unsigned &ErrorInfo, 52 bool MatchingInlineAsm) override; 53 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override; 54 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 55 SMLoc NameLoc, OperandVector &Operands) override; 56 bool ParseDirective(AsmToken DirectiveID) override; 57 58 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, 59 unsigned Kind) override; 60 61 // Custom parse functions for Sparc specific operands. 62 OperandMatchResultTy parseMEMOperand(OperandVector &Operands); 63 64 OperandMatchResultTy parseOperand(OperandVector &Operands, StringRef Name); 65 66 OperandMatchResultTy 67 parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Operand, 68 bool isCall = false); 69 70 OperandMatchResultTy parseBranchModifiers(OperandVector &Operands); 71 72 // returns true if Tok is matched to a register and returns register in RegNo. 73 bool matchRegisterName(const AsmToken &Tok, unsigned &RegNo, 74 unsigned &RegKind); 75 76 bool matchSparcAsmModifiers(const MCExpr *&EVal, SMLoc &EndLoc); 77 bool parseDirectiveWord(unsigned Size, SMLoc L); 78 79 bool is64Bit() const { return STI.getTargetTriple().startswith("sparcv9"); } 80public: 81 SparcAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser, 82 const MCInstrInfo &MII, 83 const MCTargetOptions &Options) 84 : MCTargetAsmParser(), STI(sti), Parser(parser) { 85 // Initialize the set of available features. 86 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 87 } 88 89}; 90 91 static unsigned IntRegs[32] = { 92 Sparc::G0, Sparc::G1, Sparc::G2, Sparc::G3, 93 Sparc::G4, Sparc::G5, Sparc::G6, Sparc::G7, 94 Sparc::O0, Sparc::O1, Sparc::O2, Sparc::O3, 95 Sparc::O4, Sparc::O5, Sparc::O6, Sparc::O7, 96 Sparc::L0, Sparc::L1, Sparc::L2, Sparc::L3, 97 Sparc::L4, Sparc::L5, Sparc::L6, Sparc::L7, 98 Sparc::I0, Sparc::I1, Sparc::I2, Sparc::I3, 99 Sparc::I4, Sparc::I5, Sparc::I6, Sparc::I7 }; 100 101 static unsigned FloatRegs[32] = { 102 Sparc::F0, Sparc::F1, Sparc::F2, Sparc::F3, 103 Sparc::F4, Sparc::F5, Sparc::F6, Sparc::F7, 104 Sparc::F8, Sparc::F9, Sparc::F10, Sparc::F11, 105 Sparc::F12, Sparc::F13, Sparc::F14, Sparc::F15, 106 Sparc::F16, Sparc::F17, Sparc::F18, Sparc::F19, 107 Sparc::F20, Sparc::F21, Sparc::F22, Sparc::F23, 108 Sparc::F24, Sparc::F25, Sparc::F26, Sparc::F27, 109 Sparc::F28, Sparc::F29, Sparc::F30, Sparc::F31 }; 110 111 static unsigned DoubleRegs[32] = { 112 Sparc::D0, Sparc::D1, Sparc::D2, Sparc::D3, 113 Sparc::D4, Sparc::D5, Sparc::D6, Sparc::D7, 114 Sparc::D8, Sparc::D7, Sparc::D8, Sparc::D9, 115 Sparc::D12, Sparc::D13, Sparc::D14, Sparc::D15, 116 Sparc::D16, Sparc::D17, Sparc::D18, Sparc::D19, 117 Sparc::D20, Sparc::D21, Sparc::D22, Sparc::D23, 118 Sparc::D24, Sparc::D25, Sparc::D26, Sparc::D27, 119 Sparc::D28, Sparc::D29, Sparc::D30, Sparc::D31 }; 120 121 static unsigned QuadFPRegs[32] = { 122 Sparc::Q0, Sparc::Q1, Sparc::Q2, Sparc::Q3, 123 Sparc::Q4, Sparc::Q5, Sparc::Q6, Sparc::Q7, 124 Sparc::Q8, Sparc::Q9, Sparc::Q10, Sparc::Q11, 125 Sparc::Q12, Sparc::Q13, Sparc::Q14, Sparc::Q15 }; 126 127 128/// SparcOperand - Instances of this class represent a parsed Sparc machine 129/// instruction. 130class SparcOperand : public MCParsedAsmOperand { 131public: 132 enum RegisterKind { 133 rk_None, 134 rk_IntReg, 135 rk_FloatReg, 136 rk_DoubleReg, 137 rk_QuadReg, 138 rk_CCReg, 139 rk_Y 140 }; 141private: 142 enum KindTy { 143 k_Token, 144 k_Register, 145 k_Immediate, 146 k_MemoryReg, 147 k_MemoryImm 148 } Kind; 149 150 SMLoc StartLoc, EndLoc; 151 152 struct Token { 153 const char *Data; 154 unsigned Length; 155 }; 156 157 struct RegOp { 158 unsigned RegNum; 159 RegisterKind Kind; 160 }; 161 162 struct ImmOp { 163 const MCExpr *Val; 164 }; 165 166 struct MemOp { 167 unsigned Base; 168 unsigned OffsetReg; 169 const MCExpr *Off; 170 }; 171 172 union { 173 struct Token Tok; 174 struct RegOp Reg; 175 struct ImmOp Imm; 176 struct MemOp Mem; 177 }; 178public: 179 SparcOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 180 181 bool isToken() const override { return Kind == k_Token; } 182 bool isReg() const override { return Kind == k_Register; } 183 bool isImm() const override { return Kind == k_Immediate; } 184 bool isMem() const override { return isMEMrr() || isMEMri(); } 185 bool isMEMrr() const { return Kind == k_MemoryReg; } 186 bool isMEMri() const { return Kind == k_MemoryImm; } 187 188 bool isFloatReg() const { 189 return (Kind == k_Register && Reg.Kind == rk_FloatReg); 190 } 191 192 bool isFloatOrDoubleReg() const { 193 return (Kind == k_Register && (Reg.Kind == rk_FloatReg 194 || Reg.Kind == rk_DoubleReg)); 195 } 196 197 198 StringRef getToken() const { 199 assert(Kind == k_Token && "Invalid access!"); 200 return StringRef(Tok.Data, Tok.Length); 201 } 202 203 unsigned getReg() const override { 204 assert((Kind == k_Register) && "Invalid access!"); 205 return Reg.RegNum; 206 } 207 208 const MCExpr *getImm() const { 209 assert((Kind == k_Immediate) && "Invalid access!"); 210 return Imm.Val; 211 } 212 213 unsigned getMemBase() const { 214 assert((Kind == k_MemoryReg || Kind == k_MemoryImm) && "Invalid access!"); 215 return Mem.Base; 216 } 217 218 unsigned getMemOffsetReg() const { 219 assert((Kind == k_MemoryReg) && "Invalid access!"); 220 return Mem.OffsetReg; 221 } 222 223 const MCExpr *getMemOff() const { 224 assert((Kind == k_MemoryImm) && "Invalid access!"); 225 return Mem.Off; 226 } 227 228 /// getStartLoc - Get the location of the first token of this operand. 229 SMLoc getStartLoc() const override { 230 return StartLoc; 231 } 232 /// getEndLoc - Get the location of the last token of this operand. 233 SMLoc getEndLoc() const override { 234 return EndLoc; 235 } 236 237 void print(raw_ostream &OS) const override { 238 switch (Kind) { 239 case k_Token: OS << "Token: " << getToken() << "\n"; break; 240 case k_Register: OS << "Reg: #" << getReg() << "\n"; break; 241 case k_Immediate: OS << "Imm: " << getImm() << "\n"; break; 242 case k_MemoryReg: OS << "Mem: " << getMemBase() << "+" 243 << getMemOffsetReg() << "\n"; break; 244 case k_MemoryImm: assert(getMemOff() != nullptr); 245 OS << "Mem: " << getMemBase() 246 << "+" << *getMemOff() 247 << "\n"; break; 248 } 249 } 250 251 void addRegOperands(MCInst &Inst, unsigned N) const { 252 assert(N == 1 && "Invalid number of operands!"); 253 Inst.addOperand(MCOperand::CreateReg(getReg())); 254 } 255 256 void addImmOperands(MCInst &Inst, unsigned N) const { 257 assert(N == 1 && "Invalid number of operands!"); 258 const MCExpr *Expr = getImm(); 259 addExpr(Inst, Expr); 260 } 261 262 void addExpr(MCInst &Inst, const MCExpr *Expr) const{ 263 // Add as immediate when possible. Null MCExpr = 0. 264 if (!Expr) 265 Inst.addOperand(MCOperand::CreateImm(0)); 266 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 267 Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 268 else 269 Inst.addOperand(MCOperand::CreateExpr(Expr)); 270 } 271 272 void addMEMrrOperands(MCInst &Inst, unsigned N) const { 273 assert(N == 2 && "Invalid number of operands!"); 274 275 Inst.addOperand(MCOperand::CreateReg(getMemBase())); 276 277 assert(getMemOffsetReg() != 0 && "Invalid offset"); 278 Inst.addOperand(MCOperand::CreateReg(getMemOffsetReg())); 279 } 280 281 void addMEMriOperands(MCInst &Inst, unsigned N) const { 282 assert(N == 2 && "Invalid number of operands!"); 283 284 Inst.addOperand(MCOperand::CreateReg(getMemBase())); 285 286 const MCExpr *Expr = getMemOff(); 287 addExpr(Inst, Expr); 288 } 289 290 static std::unique_ptr<SparcOperand> CreateToken(StringRef Str, SMLoc S) { 291 auto Op = make_unique<SparcOperand>(k_Token); 292 Op->Tok.Data = Str.data(); 293 Op->Tok.Length = Str.size(); 294 Op->StartLoc = S; 295 Op->EndLoc = S; 296 return Op; 297 } 298 299 static std::unique_ptr<SparcOperand> CreateReg(unsigned RegNum, unsigned Kind, 300 SMLoc S, SMLoc E) { 301 auto Op = make_unique<SparcOperand>(k_Register); 302 Op->Reg.RegNum = RegNum; 303 Op->Reg.Kind = (SparcOperand::RegisterKind)Kind; 304 Op->StartLoc = S; 305 Op->EndLoc = E; 306 return Op; 307 } 308 309 static std::unique_ptr<SparcOperand> CreateImm(const MCExpr *Val, SMLoc S, 310 SMLoc E) { 311 auto Op = make_unique<SparcOperand>(k_Immediate); 312 Op->Imm.Val = Val; 313 Op->StartLoc = S; 314 Op->EndLoc = E; 315 return Op; 316 } 317 318 static bool MorphToDoubleReg(SparcOperand &Op) { 319 unsigned Reg = Op.getReg(); 320 assert(Op.Reg.Kind == rk_FloatReg); 321 unsigned regIdx = Reg - Sparc::F0; 322 if (regIdx % 2 || regIdx > 31) 323 return false; 324 Op.Reg.RegNum = DoubleRegs[regIdx / 2]; 325 Op.Reg.Kind = rk_DoubleReg; 326 return true; 327 } 328 329 static bool MorphToQuadReg(SparcOperand &Op) { 330 unsigned Reg = Op.getReg(); 331 unsigned regIdx = 0; 332 switch (Op.Reg.Kind) { 333 default: llvm_unreachable("Unexpected register kind!"); 334 case rk_FloatReg: 335 regIdx = Reg - Sparc::F0; 336 if (regIdx % 4 || regIdx > 31) 337 return false; 338 Reg = QuadFPRegs[regIdx / 4]; 339 break; 340 case rk_DoubleReg: 341 regIdx = Reg - Sparc::D0; 342 if (regIdx % 2 || regIdx > 31) 343 return false; 344 Reg = QuadFPRegs[regIdx / 2]; 345 break; 346 } 347 Op.Reg.RegNum = Reg; 348 Op.Reg.Kind = rk_QuadReg; 349 return true; 350 } 351 352 static std::unique_ptr<SparcOperand> 353 MorphToMEMrr(unsigned Base, std::unique_ptr<SparcOperand> Op) { 354 unsigned offsetReg = Op->getReg(); 355 Op->Kind = k_MemoryReg; 356 Op->Mem.Base = Base; 357 Op->Mem.OffsetReg = offsetReg; 358 Op->Mem.Off = nullptr; 359 return Op; 360 } 361 362 static std::unique_ptr<SparcOperand> 363 CreateMEMri(unsigned Base, const MCExpr *Off, SMLoc S, SMLoc E) { 364 auto Op = make_unique<SparcOperand>(k_MemoryImm); 365 Op->Mem.Base = Base; 366 Op->Mem.OffsetReg = 0; 367 Op->Mem.Off = Off; 368 Op->StartLoc = S; 369 Op->EndLoc = E; 370 return Op; 371 } 372 373 static std::unique_ptr<SparcOperand> 374 MorphToMEMri(unsigned Base, std::unique_ptr<SparcOperand> Op) { 375 const MCExpr *Imm = Op->getImm(); 376 Op->Kind = k_MemoryImm; 377 Op->Mem.Base = Base; 378 Op->Mem.OffsetReg = 0; 379 Op->Mem.Off = Imm; 380 return Op; 381 } 382}; 383 384} // end namespace 385 386bool SparcAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 387 OperandVector &Operands, 388 MCStreamer &Out, 389 unsigned &ErrorInfo, 390 bool MatchingInlineAsm) { 391 MCInst Inst; 392 SmallVector<MCInst, 8> Instructions; 393 unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo, 394 MatchingInlineAsm); 395 switch (MatchResult) { 396 default: 397 break; 398 399 case Match_Success: { 400 Inst.setLoc(IDLoc); 401 Out.EmitInstruction(Inst, STI); 402 return false; 403 } 404 405 case Match_MissingFeature: 406 return Error(IDLoc, 407 "instruction requires a CPU feature not currently enabled"); 408 409 case Match_InvalidOperand: { 410 SMLoc ErrorLoc = IDLoc; 411 if (ErrorInfo != ~0U) { 412 if (ErrorInfo >= Operands.size()) 413 return Error(IDLoc, "too few operands for instruction"); 414 415 ErrorLoc = ((SparcOperand &)*Operands[ErrorInfo]).getStartLoc(); 416 if (ErrorLoc == SMLoc()) 417 ErrorLoc = IDLoc; 418 } 419 420 return Error(ErrorLoc, "invalid operand for instruction"); 421 } 422 case Match_MnemonicFail: 423 return Error(IDLoc, "invalid instruction mnemonic"); 424 } 425 return true; 426} 427 428bool SparcAsmParser:: 429ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) 430{ 431 const AsmToken &Tok = Parser.getTok(); 432 StartLoc = Tok.getLoc(); 433 EndLoc = Tok.getEndLoc(); 434 RegNo = 0; 435 if (getLexer().getKind() != AsmToken::Percent) 436 return false; 437 Parser.Lex(); 438 unsigned regKind = SparcOperand::rk_None; 439 if (matchRegisterName(Tok, RegNo, regKind)) { 440 Parser.Lex(); 441 return false; 442 } 443 444 return Error(StartLoc, "invalid register name"); 445} 446 447static void applyMnemonicAliases(StringRef &Mnemonic, unsigned Features, 448 unsigned VariantID); 449 450bool SparcAsmParser::ParseInstruction(ParseInstructionInfo &Info, 451 StringRef Name, SMLoc NameLoc, 452 OperandVector &Operands) { 453 454 // First operand in MCInst is instruction mnemonic. 455 Operands.push_back(SparcOperand::CreateToken(Name, NameLoc)); 456 457 // apply mnemonic aliases, if any, so that we can parse operands correctly. 458 applyMnemonicAliases(Name, getAvailableFeatures(), 0); 459 460 if (getLexer().isNot(AsmToken::EndOfStatement)) { 461 // Read the first operand. 462 if (getLexer().is(AsmToken::Comma)) { 463 if (parseBranchModifiers(Operands) != MatchOperand_Success) { 464 SMLoc Loc = getLexer().getLoc(); 465 Parser.eatToEndOfStatement(); 466 return Error(Loc, "unexpected token"); 467 } 468 } 469 if (parseOperand(Operands, Name) != MatchOperand_Success) { 470 SMLoc Loc = getLexer().getLoc(); 471 Parser.eatToEndOfStatement(); 472 return Error(Loc, "unexpected token"); 473 } 474 475 while (getLexer().is(AsmToken::Comma)) { 476 Parser.Lex(); // Eat the comma. 477 // Parse and remember the operand. 478 if (parseOperand(Operands, Name) != MatchOperand_Success) { 479 SMLoc Loc = getLexer().getLoc(); 480 Parser.eatToEndOfStatement(); 481 return Error(Loc, "unexpected token"); 482 } 483 } 484 } 485 if (getLexer().isNot(AsmToken::EndOfStatement)) { 486 SMLoc Loc = getLexer().getLoc(); 487 Parser.eatToEndOfStatement(); 488 return Error(Loc, "unexpected token"); 489 } 490 Parser.Lex(); // Consume the EndOfStatement. 491 return false; 492} 493 494bool SparcAsmParser:: 495ParseDirective(AsmToken DirectiveID) 496{ 497 StringRef IDVal = DirectiveID.getString(); 498 499 if (IDVal == ".byte") 500 return parseDirectiveWord(1, DirectiveID.getLoc()); 501 502 if (IDVal == ".half") 503 return parseDirectiveWord(2, DirectiveID.getLoc()); 504 505 if (IDVal == ".word") 506 return parseDirectiveWord(4, DirectiveID.getLoc()); 507 508 if (IDVal == ".nword") 509 return parseDirectiveWord(is64Bit() ? 8 : 4, DirectiveID.getLoc()); 510 511 if (is64Bit() && IDVal == ".xword") 512 return parseDirectiveWord(8, DirectiveID.getLoc()); 513 514 if (IDVal == ".register") { 515 // For now, ignore .register directive. 516 Parser.eatToEndOfStatement(); 517 return false; 518 } 519 520 // Let the MC layer to handle other directives. 521 return true; 522} 523 524bool SparcAsmParser:: parseDirectiveWord(unsigned Size, SMLoc L) { 525 if (getLexer().isNot(AsmToken::EndOfStatement)) { 526 for (;;) { 527 const MCExpr *Value; 528 if (getParser().parseExpression(Value)) 529 return true; 530 531 getParser().getStreamer().EmitValue(Value, Size); 532 533 if (getLexer().is(AsmToken::EndOfStatement)) 534 break; 535 536 // FIXME: Improve diagnostic. 537 if (getLexer().isNot(AsmToken::Comma)) 538 return Error(L, "unexpected token in directive"); 539 Parser.Lex(); 540 } 541 } 542 Parser.Lex(); 543 return false; 544} 545 546SparcAsmParser::OperandMatchResultTy 547SparcAsmParser::parseMEMOperand(OperandVector &Operands) { 548 549 SMLoc S, E; 550 unsigned BaseReg = 0; 551 552 if (ParseRegister(BaseReg, S, E)) { 553 return MatchOperand_NoMatch; 554 } 555 556 switch (getLexer().getKind()) { 557 default: return MatchOperand_NoMatch; 558 559 case AsmToken::Comma: 560 case AsmToken::RBrac: 561 case AsmToken::EndOfStatement: 562 Operands.push_back(SparcOperand::CreateMEMri(BaseReg, nullptr, S, E)); 563 return MatchOperand_Success; 564 565 case AsmToken:: Plus: 566 Parser.Lex(); // Eat the '+' 567 break; 568 case AsmToken::Minus: 569 break; 570 } 571 572 std::unique_ptr<SparcOperand> Offset; 573 OperandMatchResultTy ResTy = parseSparcAsmOperand(Offset); 574 if (ResTy != MatchOperand_Success || !Offset) 575 return MatchOperand_NoMatch; 576 577 Operands.push_back( 578 Offset->isImm() ? SparcOperand::MorphToMEMri(BaseReg, std::move(Offset)) 579 : SparcOperand::MorphToMEMrr(BaseReg, std::move(Offset))); 580 581 return MatchOperand_Success; 582} 583 584SparcAsmParser::OperandMatchResultTy 585SparcAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { 586 587 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 588 589 // If there wasn't a custom match, try the generic matcher below. Otherwise, 590 // there was a match, but an error occurred, in which case, just return that 591 // the operand parsing failed. 592 if (ResTy == MatchOperand_Success || ResTy == MatchOperand_ParseFail) 593 return ResTy; 594 595 if (getLexer().is(AsmToken::LBrac)) { 596 // Memory operand 597 Operands.push_back(SparcOperand::CreateToken("[", 598 Parser.getTok().getLoc())); 599 Parser.Lex(); // Eat the [ 600 601 if (Mnemonic == "cas" || Mnemonic == "casx") { 602 SMLoc S = Parser.getTok().getLoc(); 603 if (getLexer().getKind() != AsmToken::Percent) 604 return MatchOperand_NoMatch; 605 Parser.Lex(); // eat % 606 607 unsigned RegNo, RegKind; 608 if (!matchRegisterName(Parser.getTok(), RegNo, RegKind)) 609 return MatchOperand_NoMatch; 610 611 Parser.Lex(); // Eat the identifier token. 612 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer()-1); 613 Operands.push_back(SparcOperand::CreateReg(RegNo, RegKind, S, E)); 614 ResTy = MatchOperand_Success; 615 } else { 616 ResTy = parseMEMOperand(Operands); 617 } 618 619 if (ResTy != MatchOperand_Success) 620 return ResTy; 621 622 if (!getLexer().is(AsmToken::RBrac)) 623 return MatchOperand_ParseFail; 624 625 Operands.push_back(SparcOperand::CreateToken("]", 626 Parser.getTok().getLoc())); 627 Parser.Lex(); // Eat the ] 628 return MatchOperand_Success; 629 } 630 631 std::unique_ptr<SparcOperand> Op; 632 633 ResTy = parseSparcAsmOperand(Op, (Mnemonic == "call")); 634 if (ResTy != MatchOperand_Success || !Op) 635 return MatchOperand_ParseFail; 636 637 // Push the parsed operand into the list of operands 638 Operands.push_back(std::move(Op)); 639 640 return MatchOperand_Success; 641} 642 643SparcAsmParser::OperandMatchResultTy 644SparcAsmParser::parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Op, 645 bool isCall) { 646 647 SMLoc S = Parser.getTok().getLoc(); 648 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 649 const MCExpr *EVal; 650 651 Op = nullptr; 652 switch (getLexer().getKind()) { 653 default: break; 654 655 case AsmToken::Percent: 656 Parser.Lex(); // Eat the '%'. 657 unsigned RegNo; 658 unsigned RegKind; 659 if (matchRegisterName(Parser.getTok(), RegNo, RegKind)) { 660 StringRef name = Parser.getTok().getString(); 661 Parser.Lex(); // Eat the identifier token. 662 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 663 switch (RegNo) { 664 default: 665 Op = SparcOperand::CreateReg(RegNo, RegKind, S, E); 666 break; 667 case Sparc::Y: 668 Op = SparcOperand::CreateToken("%y", S); 669 break; 670 671 case Sparc::ICC: 672 if (name == "xcc") 673 Op = SparcOperand::CreateToken("%xcc", S); 674 else 675 Op = SparcOperand::CreateToken("%icc", S); 676 break; 677 } 678 break; 679 } 680 if (matchSparcAsmModifiers(EVal, E)) { 681 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 682 Op = SparcOperand::CreateImm(EVal, S, E); 683 } 684 break; 685 686 case AsmToken::Minus: 687 case AsmToken::Integer: 688 if (!getParser().parseExpression(EVal, E)) 689 Op = SparcOperand::CreateImm(EVal, S, E); 690 break; 691 692 case AsmToken::Identifier: { 693 StringRef Identifier; 694 if (!getParser().parseIdentifier(Identifier)) { 695 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 696 MCSymbol *Sym = getContext().GetOrCreateSymbol(Identifier); 697 698 const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, 699 getContext()); 700 if (isCall && 701 getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_) 702 Res = SparcMCExpr::Create(SparcMCExpr::VK_Sparc_WPLT30, Res, 703 getContext()); 704 Op = SparcOperand::CreateImm(Res, S, E); 705 } 706 break; 707 } 708 } 709 return (Op) ? MatchOperand_Success : MatchOperand_ParseFail; 710} 711 712SparcAsmParser::OperandMatchResultTy 713SparcAsmParser::parseBranchModifiers(OperandVector &Operands) { 714 715 // parse (,a|,pn|,pt)+ 716 717 while (getLexer().is(AsmToken::Comma)) { 718 719 Parser.Lex(); // Eat the comma 720 721 if (!getLexer().is(AsmToken::Identifier)) 722 return MatchOperand_ParseFail; 723 StringRef modName = Parser.getTok().getString(); 724 if (modName == "a" || modName == "pn" || modName == "pt") { 725 Operands.push_back(SparcOperand::CreateToken(modName, 726 Parser.getTok().getLoc())); 727 Parser.Lex(); // eat the identifier. 728 } 729 } 730 return MatchOperand_Success; 731} 732 733bool SparcAsmParser::matchRegisterName(const AsmToken &Tok, 734 unsigned &RegNo, 735 unsigned &RegKind) 736{ 737 int64_t intVal = 0; 738 RegNo = 0; 739 RegKind = SparcOperand::rk_None; 740 if (Tok.is(AsmToken::Identifier)) { 741 StringRef name = Tok.getString(); 742 743 // %fp 744 if (name.equals("fp")) { 745 RegNo = Sparc::I6; 746 RegKind = SparcOperand::rk_IntReg; 747 return true; 748 } 749 // %sp 750 if (name.equals("sp")) { 751 RegNo = Sparc::O6; 752 RegKind = SparcOperand::rk_IntReg; 753 return true; 754 } 755 756 if (name.equals("y")) { 757 RegNo = Sparc::Y; 758 RegKind = SparcOperand::rk_Y; 759 return true; 760 } 761 762 if (name.equals("icc")) { 763 RegNo = Sparc::ICC; 764 RegKind = SparcOperand::rk_CCReg; 765 return true; 766 } 767 768 if (name.equals("xcc")) { 769 // FIXME:: check 64bit. 770 RegNo = Sparc::ICC; 771 RegKind = SparcOperand::rk_CCReg; 772 return true; 773 } 774 775 // %fcc0 - %fcc3 776 if (name.substr(0, 3).equals_lower("fcc") 777 && !name.substr(3).getAsInteger(10, intVal) 778 && intVal < 4) { 779 // FIXME: check 64bit and handle %fcc1 - %fcc3 780 RegNo = Sparc::FCC0 + intVal; 781 RegKind = SparcOperand::rk_CCReg; 782 return true; 783 } 784 785 // %g0 - %g7 786 if (name.substr(0, 1).equals_lower("g") 787 && !name.substr(1).getAsInteger(10, intVal) 788 && intVal < 8) { 789 RegNo = IntRegs[intVal]; 790 RegKind = SparcOperand::rk_IntReg; 791 return true; 792 } 793 // %o0 - %o7 794 if (name.substr(0, 1).equals_lower("o") 795 && !name.substr(1).getAsInteger(10, intVal) 796 && intVal < 8) { 797 RegNo = IntRegs[8 + intVal]; 798 RegKind = SparcOperand::rk_IntReg; 799 return true; 800 } 801 if (name.substr(0, 1).equals_lower("l") 802 && !name.substr(1).getAsInteger(10, intVal) 803 && intVal < 8) { 804 RegNo = IntRegs[16 + intVal]; 805 RegKind = SparcOperand::rk_IntReg; 806 return true; 807 } 808 if (name.substr(0, 1).equals_lower("i") 809 && !name.substr(1).getAsInteger(10, intVal) 810 && intVal < 8) { 811 RegNo = IntRegs[24 + intVal]; 812 RegKind = SparcOperand::rk_IntReg; 813 return true; 814 } 815 // %f0 - %f31 816 if (name.substr(0, 1).equals_lower("f") 817 && !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 32) { 818 RegNo = FloatRegs[intVal]; 819 RegKind = SparcOperand::rk_FloatReg; 820 return true; 821 } 822 // %f32 - %f62 823 if (name.substr(0, 1).equals_lower("f") 824 && !name.substr(1, 2).getAsInteger(10, intVal) 825 && intVal >= 32 && intVal <= 62 && (intVal % 2 == 0)) { 826 // FIXME: Check V9 827 RegNo = DoubleRegs[intVal/2]; 828 RegKind = SparcOperand::rk_DoubleReg; 829 return true; 830 } 831 832 // %r0 - %r31 833 if (name.substr(0, 1).equals_lower("r") 834 && !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 31) { 835 RegNo = IntRegs[intVal]; 836 RegKind = SparcOperand::rk_IntReg; 837 return true; 838 } 839 } 840 return false; 841} 842 843static bool hasGOTReference(const MCExpr *Expr) { 844 switch (Expr->getKind()) { 845 case MCExpr::Target: 846 if (const SparcMCExpr *SE = dyn_cast<SparcMCExpr>(Expr)) 847 return hasGOTReference(SE->getSubExpr()); 848 break; 849 850 case MCExpr::Constant: 851 break; 852 853 case MCExpr::Binary: { 854 const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr); 855 return hasGOTReference(BE->getLHS()) || hasGOTReference(BE->getRHS()); 856 } 857 858 case MCExpr::SymbolRef: { 859 const MCSymbolRefExpr &SymRef = *cast<MCSymbolRefExpr>(Expr); 860 return (SymRef.getSymbol().getName() == "_GLOBAL_OFFSET_TABLE_"); 861 } 862 863 case MCExpr::Unary: 864 return hasGOTReference(cast<MCUnaryExpr>(Expr)->getSubExpr()); 865 } 866 return false; 867} 868 869bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal, 870 SMLoc &EndLoc) 871{ 872 AsmToken Tok = Parser.getTok(); 873 if (!Tok.is(AsmToken::Identifier)) 874 return false; 875 876 StringRef name = Tok.getString(); 877 878 SparcMCExpr::VariantKind VK = SparcMCExpr::parseVariantKind(name); 879 880 if (VK == SparcMCExpr::VK_Sparc_None) 881 return false; 882 883 Parser.Lex(); // Eat the identifier. 884 if (Parser.getTok().getKind() != AsmToken::LParen) 885 return false; 886 887 Parser.Lex(); // Eat the LParen token. 888 const MCExpr *subExpr; 889 if (Parser.parseParenExpression(subExpr, EndLoc)) 890 return false; 891 892 bool isPIC = getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_; 893 894 switch(VK) { 895 default: break; 896 case SparcMCExpr::VK_Sparc_LO: 897 VK = (hasGOTReference(subExpr) 898 ? SparcMCExpr::VK_Sparc_PC10 899 : (isPIC ? SparcMCExpr::VK_Sparc_GOT10 : VK)); 900 break; 901 case SparcMCExpr::VK_Sparc_HI: 902 VK = (hasGOTReference(subExpr) 903 ? SparcMCExpr::VK_Sparc_PC22 904 : (isPIC ? SparcMCExpr::VK_Sparc_GOT22 : VK)); 905 break; 906 } 907 908 EVal = SparcMCExpr::Create(VK, subExpr, getContext()); 909 return true; 910} 911 912 913extern "C" void LLVMInitializeSparcAsmParser() { 914 RegisterMCAsmParser<SparcAsmParser> A(TheSparcTarget); 915 RegisterMCAsmParser<SparcAsmParser> B(TheSparcV9Target); 916} 917 918#define GET_REGISTER_MATCHER 919#define GET_MATCHER_IMPLEMENTATION 920#include "SparcGenAsmMatcher.inc" 921 922unsigned SparcAsmParser::validateTargetOperandClass(MCParsedAsmOperand &GOp, 923 unsigned Kind) { 924 SparcOperand &Op = (SparcOperand &)GOp; 925 if (Op.isFloatOrDoubleReg()) { 926 switch (Kind) { 927 default: break; 928 case MCK_DFPRegs: 929 if (!Op.isFloatReg() || SparcOperand::MorphToDoubleReg(Op)) 930 return MCTargetAsmParser::Match_Success; 931 break; 932 case MCK_QFPRegs: 933 if (SparcOperand::MorphToQuadReg(Op)) 934 return MCTargetAsmParser::Match_Success; 935 break; 936 } 937 } 938 return Match_InvalidOperand; 939} 940