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