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