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