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