1263320SdimPull in r198484 from upstream llvm trunk (by Venkatraman Govindaraju):
2263320Sdim
3263320Sdim  [Sparc] Add the initial implementation of an asm parser for sparc/sparcv9.
4263320Sdim
5269012SemasteIntroduced here: http://svnweb.freebsd.org/changeset/base/262261
6263320Sdim
7263320SdimIndex: lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp
8263320Sdim===================================================================
9263320Sdim--- lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp
10263320Sdim+++ lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp
11263320Sdim@@ -123,13 +123,18 @@ extern "C" void LLVMInitializeSparcTargetMC() {
12263320Sdim 
13263320Sdim   // Register the MC instruction info.
14263320Sdim   TargetRegistry::RegisterMCInstrInfo(TheSparcTarget, createSparcMCInstrInfo);
15263320Sdim+  TargetRegistry::RegisterMCInstrInfo(TheSparcV9Target, createSparcMCInstrInfo);
16263320Sdim 
17263320Sdim   // Register the MC register info.
18263320Sdim   TargetRegistry::RegisterMCRegInfo(TheSparcTarget, createSparcMCRegisterInfo);
19263320Sdim+  TargetRegistry::RegisterMCRegInfo(TheSparcV9Target,
20263320Sdim+                                    createSparcMCRegisterInfo);
21263320Sdim 
22263320Sdim   // Register the MC subtarget info.
23263320Sdim   TargetRegistry::RegisterMCSubtargetInfo(TheSparcTarget,
24263320Sdim                                           createSparcMCSubtargetInfo);
25263320Sdim+  TargetRegistry::RegisterMCSubtargetInfo(TheSparcV9Target,
26263320Sdim+                                          createSparcMCSubtargetInfo);
27263320Sdim 
28263320Sdim   TargetRegistry::RegisterAsmStreamer(TheSparcTarget,
29263320Sdim                                       createMCAsmStreamer);
30263320SdimIndex: lib/Target/Sparc/LLVMBuild.txt
31263320Sdim===================================================================
32263320Sdim--- lib/Target/Sparc/LLVMBuild.txt
33263320Sdim+++ lib/Target/Sparc/LLVMBuild.txt
34263320Sdim@@ -16,7 +16,7 @@
35263320Sdim ;===------------------------------------------------------------------------===;
36263320Sdim 
37263320Sdim [common]
38263320Sdim-subdirectories = InstPrinter MCTargetDesc TargetInfo
39263320Sdim+subdirectories = AsmParser InstPrinter MCTargetDesc TargetInfo
40263320Sdim 
41263320Sdim [component_0]
42263320Sdim type = TargetGroup
43263320SdimIndex: lib/Target/Sparc/SparcInstrInfo.td
44263320Sdim===================================================================
45263320Sdim--- lib/Target/Sparc/SparcInstrInfo.td
46263320Sdim+++ lib/Target/Sparc/SparcInstrInfo.td
47263320Sdim@@ -76,13 +76,25 @@ def ADDRrr : ComplexPattern<iPTR, 2, "SelectADDRrr
48263320Sdim def ADDRri : ComplexPattern<iPTR, 2, "SelectADDRri", [frameindex], []>;
49263320Sdim 
50263320Sdim // Address operands
51263320Sdim+def SparcMEMrrAsmOperand : AsmOperandClass {
52263320Sdim+  let Name = "MEMrr";
53263320Sdim+  let ParserMethod = "parseMEMrrOperand";
54263320Sdim+}
55263320Sdim+
56263320Sdim+def SparcMEMriAsmOperand : AsmOperandClass {
57263320Sdim+  let Name = "MEMri";
58263320Sdim+  let ParserMethod = "parseMEMriOperand";
59263320Sdim+}
60263320Sdim+
61263320Sdim def MEMrr : Operand<iPTR> {
62263320Sdim   let PrintMethod = "printMemOperand";
63263320Sdim   let MIOperandInfo = (ops ptr_rc, ptr_rc);
64263320Sdim+  let ParserMatchClass = SparcMEMrrAsmOperand;
65263320Sdim }
66263320Sdim def MEMri : Operand<iPTR> {
67263320Sdim   let PrintMethod = "printMemOperand";
68263320Sdim   let MIOperandInfo = (ops ptr_rc, i32imm);
69263320Sdim+  let ParserMatchClass = SparcMEMriAsmOperand;
70263320Sdim }
71263320Sdim 
72263320Sdim def TLSSym : Operand<iPTR>;
73263320Sdim@@ -239,7 +251,10 @@ multiclass F3_12np<string OpcStr, bits<6> Op3Val>
74263320Sdim 
75263320Sdim // Pseudo instructions.
76263320Sdim class Pseudo<dag outs, dag ins, string asmstr, list<dag> pattern>
77263320Sdim-   : InstSP<outs, ins, asmstr, pattern>;
78263320Sdim+   : InstSP<outs, ins, asmstr, pattern> {
79263320Sdim+  let isCodeGenOnly = 1;
80263320Sdim+  let isPseudo = 1;
81263320Sdim+}
82263320Sdim 
83263320Sdim // GETPCX for PIC
84263320Sdim let Defs = [O7] in {
85263320Sdim@@ -503,7 +518,7 @@ defm SRA : F3_12<"sra", 0b100111, sra, IntRegs, i3
86263320Sdim defm ADD   : F3_12<"add", 0b000000, add, IntRegs, i32, i32imm>;
87263320Sdim 
88263320Sdim // "LEA" forms of add (patterns to make tblgen happy)
89263320Sdim-let Predicates = [Is32Bit] in
90263320Sdim+let Predicates = [Is32Bit], isCodeGenOnly = 1 in
91263320Sdim   def LEA_ADDri   : F3_2<2, 0b000000,
92263320Sdim                      (outs IntRegs:$dst), (ins MEMri:$addr),
93263320Sdim                      "add ${addr:arith}, $dst",
94263320SdimIndex: lib/Target/Sparc/CMakeLists.txt
95263320Sdim===================================================================
96263320Sdim--- lib/Target/Sparc/CMakeLists.txt
97263320Sdim+++ lib/Target/Sparc/CMakeLists.txt
98263320Sdim@@ -4,6 +4,7 @@ tablegen(LLVM SparcGenRegisterInfo.inc -gen-regist
99263320Sdim tablegen(LLVM SparcGenInstrInfo.inc -gen-instr-info)
100263320Sdim tablegen(LLVM SparcGenCodeEmitter.inc -gen-emitter)
101263320Sdim tablegen(LLVM SparcGenAsmWriter.inc -gen-asm-writer)
102263320Sdim+tablegen(LLVM SparcGenAsmMatcher.inc -gen-asm-matcher)
103263320Sdim tablegen(LLVM SparcGenDAGISel.inc -gen-dag-isel)
104263320Sdim tablegen(LLVM SparcGenSubtargetInfo.inc -gen-subtarget)
105263320Sdim tablegen(LLVM SparcGenCallingConv.inc -gen-callingconv)
106263320Sdim@@ -31,3 +32,4 @@ add_dependencies(LLVMSparcCodeGen SparcCommonTable
107263320Sdim add_subdirectory(TargetInfo)
108263320Sdim add_subdirectory(MCTargetDesc)
109263320Sdim add_subdirectory(InstPrinter)
110263320Sdim+add_subdirectory(AsmParser)
111263320SdimIndex: lib/Target/Sparc/Makefile
112263320Sdim===================================================================
113263320Sdim--- lib/Target/Sparc/Makefile
114263320Sdim+++ lib/Target/Sparc/Makefile
115263320Sdim@@ -13,11 +13,12 @@ TARGET = Sparc
116263320Sdim 
117263320Sdim # Make sure that tblgen is run, first thing.
118263320Sdim BUILT_SOURCES = SparcGenRegisterInfo.inc SparcGenInstrInfo.inc \
119263320Sdim-		SparcGenAsmWriter.inc SparcGenDAGISel.inc \
120263320Sdim+		SparcGenAsmWriter.inc SparcGenAsmMatcher.inc \
121263320Sdim+		SparcGenDAGISel.inc \
122263320Sdim 		SparcGenSubtargetInfo.inc SparcGenCallingConv.inc \
123263320Sdim 		SparcGenCodeEmitter.inc
124263320Sdim 
125263320Sdim-DIRS = InstPrinter TargetInfo MCTargetDesc
126263320Sdim+DIRS = InstPrinter AsmParser TargetInfo MCTargetDesc
127263320Sdim 
128263320Sdim include $(LEVEL)/Makefile.common
129263320Sdim 
130263320SdimIndex: lib/Target/Sparc/Sparc.td
131263320Sdim===================================================================
132263320Sdim--- lib/Target/Sparc/Sparc.td
133263320Sdim+++ lib/Target/Sparc/Sparc.td
134263320Sdim@@ -44,6 +44,10 @@ include "SparcInstrInfo.td"
135263320Sdim 
136263320Sdim def SparcInstrInfo : InstrInfo;
137263320Sdim 
138263320Sdim+def SparcAsmParser : AsmParser {
139263320Sdim+  bit ShouldEmitMatchRegisterName = 0;
140263320Sdim+}
141263320Sdim+
142263320Sdim //===----------------------------------------------------------------------===//
143263320Sdim // SPARC processors supported.
144263320Sdim //===----------------------------------------------------------------------===//
145263320Sdim@@ -77,6 +81,7 @@ def SparcAsmWriter : AsmWriter {
146263320Sdim def Sparc : Target {
147263320Sdim   // Pull in Instruction Info:
148263320Sdim   let InstructionSet = SparcInstrInfo;
149263320Sdim+  let AssemblyParsers  = [SparcAsmParser];
150263320Sdim 
151263320Sdim   let AssemblyWriters = [SparcAsmWriter];
152263320Sdim }
153263320SdimIndex: lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
154263320Sdim===================================================================
155263320Sdim--- lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
156263320Sdim+++ lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
157263320Sdim@@ -0,0 +1,614 @@
158263320Sdim+//===-- SparcAsmParser.cpp - Parse Sparc assembly to MCInst instructions --===//
159263320Sdim+//
160263320Sdim+//                     The LLVM Compiler Infrastructure
161263320Sdim+//
162263320Sdim+// This file is distributed under the University of Illinois Open Source
163263320Sdim+// License. See LICENSE.TXT for details.
164263320Sdim+//
165263320Sdim+//===----------------------------------------------------------------------===//
166263320Sdim+
167263320Sdim+#include "MCTargetDesc/SparcMCTargetDesc.h"
168263320Sdim+#include "llvm/ADT/STLExtras.h"
169263320Sdim+#include "llvm/MC/MCContext.h"
170263320Sdim+#include "llvm/MC/MCInst.h"
171263320Sdim+#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
172263320Sdim+#include "llvm/MC/MCStreamer.h"
173263320Sdim+#include "llvm/MC/MCSubtargetInfo.h"
174263320Sdim+#include "llvm/MC/MCTargetAsmParser.h"
175263320Sdim+#include "llvm/Support/TargetRegistry.h"
176263320Sdim+
177263320Sdim+using namespace llvm;
178263320Sdim+
179263320Sdim+// The generated AsmMatcher SparcGenAsmMatcher uses "Sparc" as the target
180263320Sdim+// namespace. But SPARC backend uses "SP" as its namespace.
181263320Sdim+namespace llvm {
182263320Sdim+  namespace Sparc {
183263320Sdim+    using namespace SP;
184263320Sdim+  }
185263320Sdim+}
186263320Sdim+
187263320Sdim+namespace {
188263320Sdim+class SparcAsmParser : public MCTargetAsmParser {
189263320Sdim+
190263320Sdim+  MCSubtargetInfo &STI;
191263320Sdim+  MCAsmParser &Parser;
192263320Sdim+
193263320Sdim+  /// @name Auto-generated Match Functions
194263320Sdim+  /// {
195263320Sdim+
196263320Sdim+#define GET_ASSEMBLER_HEADER
197263320Sdim+#include "SparcGenAsmMatcher.inc"
198263320Sdim+
199263320Sdim+  /// }
200263320Sdim+
201263320Sdim+  // public interface of the MCTargetAsmParser.
202263320Sdim+  bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
203263320Sdim+                               SmallVectorImpl<MCParsedAsmOperand*> &Operands,
204263320Sdim+                               MCStreamer &Out, unsigned &ErrorInfo,
205263320Sdim+                               bool MatchingInlineAsm);
206263320Sdim+  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
207263320Sdim+  bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
208263320Sdim+                        SMLoc NameLoc,
209263320Sdim+                        SmallVectorImpl<MCParsedAsmOperand*> &Operands);
210263320Sdim+  bool ParseDirective(AsmToken DirectiveID);
211263320Sdim+
212263320Sdim+
213263320Sdim+  // Custom parse functions for Sparc specific operands.
214263320Sdim+  OperandMatchResultTy
215263320Sdim+  parseMEMrrOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
216263320Sdim+  OperandMatchResultTy
217263320Sdim+  parseMEMriOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
218263320Sdim+
219263320Sdim+  OperandMatchResultTy
220263320Sdim+  parseMEMOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
221263320Sdim+                  int ImmOffsetOrReg);
222263320Sdim+
223263320Sdim+  OperandMatchResultTy
224263320Sdim+  parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
225263320Sdim+               StringRef Name);
226263320Sdim+
227263320Sdim+  // returns true if Tok is matched to a register and returns register in RegNo.
228263320Sdim+  bool matchRegisterName(const AsmToken &Tok, unsigned &RegNo, bool isDFP,
229263320Sdim+                         bool isQFP);
230263320Sdim+
231263320Sdim+public:
232263320Sdim+  SparcAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
233263320Sdim+                const MCInstrInfo &MII)
234263320Sdim+      : MCTargetAsmParser(), STI(sti), Parser(parser) {
235263320Sdim+    // Initialize the set of available features.
236263320Sdim+    setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
237263320Sdim+  }
238263320Sdim+
239263320Sdim+};
240263320Sdim+
241263320Sdim+  static unsigned IntRegs[32] = {
242263320Sdim+    Sparc::G0, Sparc::G1, Sparc::G2, Sparc::G3,
243263320Sdim+    Sparc::G4, Sparc::G5, Sparc::G6, Sparc::G7,
244263320Sdim+    Sparc::O0, Sparc::O1, Sparc::O2, Sparc::O3,
245263320Sdim+    Sparc::O4, Sparc::O5, Sparc::O6, Sparc::O7,
246263320Sdim+    Sparc::L0, Sparc::L1, Sparc::L2, Sparc::L3,
247263320Sdim+    Sparc::L4, Sparc::L5, Sparc::L6, Sparc::L7,
248263320Sdim+    Sparc::I0, Sparc::I1, Sparc::I2, Sparc::I3,
249263320Sdim+    Sparc::I4, Sparc::I5, Sparc::I6, Sparc::I7 };
250263320Sdim+
251263320Sdim+  static unsigned FloatRegs[32] = {
252263320Sdim+    Sparc::F0,  Sparc::F1,  Sparc::F2,  Sparc::F3,
253263320Sdim+    Sparc::F4,  Sparc::F5,  Sparc::F6,  Sparc::F7,
254263320Sdim+    Sparc::F8,  Sparc::F9,  Sparc::F10, Sparc::F11,
255263320Sdim+    Sparc::F12, Sparc::F13, Sparc::F14, Sparc::F15,
256263320Sdim+    Sparc::F16, Sparc::F17, Sparc::F18, Sparc::F19,
257263320Sdim+    Sparc::F20, Sparc::F21, Sparc::F22, Sparc::F23,
258263320Sdim+    Sparc::F24, Sparc::F25, Sparc::F26, Sparc::F27,
259263320Sdim+    Sparc::F28, Sparc::F29, Sparc::F30, Sparc::F31 };
260263320Sdim+
261263320Sdim+  static unsigned DoubleRegs[32] = {
262263320Sdim+    Sparc::D0,  Sparc::D1,  Sparc::D2,  Sparc::D3,
263263320Sdim+    Sparc::D4,  Sparc::D5,  Sparc::D6,  Sparc::D7,
264263320Sdim+    Sparc::D8,  Sparc::D7,  Sparc::D8,  Sparc::D9,
265263320Sdim+    Sparc::D12, Sparc::D13, Sparc::D14, Sparc::D15,
266263320Sdim+    Sparc::D16, Sparc::D17, Sparc::D18, Sparc::D19,
267263320Sdim+    Sparc::D20, Sparc::D21, Sparc::D22, Sparc::D23,
268263320Sdim+    Sparc::D24, Sparc::D25, Sparc::D26, Sparc::D27,
269263320Sdim+    Sparc::D28, Sparc::D29, Sparc::D30, Sparc::D31 };
270263320Sdim+
271263320Sdim+  static unsigned QuadFPRegs[32] = {
272263320Sdim+    Sparc::Q0,  Sparc::Q1,  Sparc::Q2,  Sparc::Q3,
273263320Sdim+    Sparc::Q4,  Sparc::Q5,  Sparc::Q6,  Sparc::Q7,
274263320Sdim+    Sparc::Q8,  Sparc::Q7,  Sparc::Q8,  Sparc::Q9,
275263320Sdim+    Sparc::Q12, Sparc::Q13, Sparc::Q14, Sparc::Q15 };
276263320Sdim+
277263320Sdim+
278263320Sdim+/// SparcOperand - Instances of this class represent a parsed Sparc machine
279263320Sdim+/// instruction.
280263320Sdim+class SparcOperand : public MCParsedAsmOperand {
281263320Sdim+public:
282263320Sdim+  enum RegisterKind {
283263320Sdim+    rk_None,
284263320Sdim+    rk_IntReg,
285263320Sdim+    rk_FloatReg,
286263320Sdim+    rk_DoubleReg,
287263320Sdim+    rk_QuadReg,
288263320Sdim+    rk_CCReg,
289263320Sdim+    rk_Y
290263320Sdim+  };
291263320Sdim+private:
292263320Sdim+  enum KindTy {
293263320Sdim+    k_Token,
294263320Sdim+    k_Register,
295263320Sdim+    k_Immediate,
296263320Sdim+    k_MemoryReg,
297263320Sdim+    k_MemoryImm
298263320Sdim+  } Kind;
299263320Sdim+
300263320Sdim+  SMLoc StartLoc, EndLoc;
301263320Sdim+
302263320Sdim+  SparcOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
303263320Sdim+
304263320Sdim+  struct Token {
305263320Sdim+    const char *Data;
306263320Sdim+    unsigned Length;
307263320Sdim+  };
308263320Sdim+
309263320Sdim+  struct RegOp {
310263320Sdim+    unsigned RegNum;
311263320Sdim+    RegisterKind Kind;
312263320Sdim+  };
313263320Sdim+
314263320Sdim+  struct ImmOp {
315263320Sdim+    const MCExpr *Val;
316263320Sdim+  };
317263320Sdim+
318263320Sdim+  struct MemOp {
319263320Sdim+    unsigned Base;
320263320Sdim+    unsigned OffsetReg;
321263320Sdim+    const MCExpr *Off;
322263320Sdim+  };
323263320Sdim+
324263320Sdim+  union {
325263320Sdim+    struct Token Tok;
326263320Sdim+    struct RegOp Reg;
327263320Sdim+    struct ImmOp Imm;
328263320Sdim+    struct MemOp Mem;
329263320Sdim+  };
330263320Sdim+public:
331263320Sdim+  bool isToken() const { return Kind == k_Token; }
332263320Sdim+  bool isReg() const { return Kind == k_Register; }
333263320Sdim+  bool isImm() const { return Kind == k_Immediate; }
334263320Sdim+  bool isMem() const { return isMEMrr() || isMEMri(); }
335263320Sdim+  bool isMEMrr() const { return Kind == k_MemoryReg; }
336263320Sdim+  bool isMEMri() const { return Kind == k_MemoryImm; }
337263320Sdim+
338263320Sdim+  StringRef getToken() const {
339263320Sdim+    assert(Kind == k_Token && "Invalid access!");
340263320Sdim+    return StringRef(Tok.Data, Tok.Length);
341263320Sdim+  }
342263320Sdim+
343263320Sdim+  unsigned getReg() const {
344263320Sdim+    assert((Kind == k_Register) && "Invalid access!");
345263320Sdim+    return Reg.RegNum;
346263320Sdim+  }
347263320Sdim+
348263320Sdim+  const MCExpr *getImm() const {
349263320Sdim+    assert((Kind == k_Immediate) && "Invalid access!");
350263320Sdim+    return Imm.Val;
351263320Sdim+  }
352263320Sdim+
353263320Sdim+  unsigned getMemBase() const {
354263320Sdim+    assert((Kind == k_MemoryReg || Kind == k_MemoryImm) && "Invalid access!");
355263320Sdim+    return Mem.Base;
356263320Sdim+  }
357263320Sdim+
358263320Sdim+  unsigned getMemOffsetReg() const {
359263320Sdim+    assert((Kind == k_MemoryReg) && "Invalid access!");
360263320Sdim+    return Mem.OffsetReg;
361263320Sdim+  }
362263320Sdim+
363263320Sdim+  const MCExpr *getMemOff() const {
364263320Sdim+    assert((Kind == k_MemoryImm) && "Invalid access!");
365263320Sdim+    return Mem.Off;
366263320Sdim+  }
367263320Sdim+
368263320Sdim+  /// getStartLoc - Get the location of the first token of this operand.
369263320Sdim+  SMLoc getStartLoc() const {
370263320Sdim+    return StartLoc;
371263320Sdim+  }
372263320Sdim+  /// getEndLoc - Get the location of the last token of this operand.
373263320Sdim+  SMLoc getEndLoc() const {
374263320Sdim+    return EndLoc;
375263320Sdim+  }
376263320Sdim+
377263320Sdim+  virtual void print(raw_ostream &OS) const {
378263320Sdim+    switch (Kind) {
379263320Sdim+    case k_Token:     OS << "Token: " << getToken() << "\n"; break;
380263320Sdim+    case k_Register:  OS << "Reg: #" << getReg() << "\n"; break;
381263320Sdim+    case k_Immediate: OS << "Imm: " << getImm() << "\n"; break;
382263320Sdim+    case k_MemoryReg: OS << "Mem: " << getMemBase() << "+"
383263320Sdim+                         << getMemOffsetReg() << "\n"; break;
384263320Sdim+    case k_MemoryImm: assert(getMemOff() != 0);
385263320Sdim+      OS << "Mem: " << getMemBase()
386263320Sdim+         << "+" << *getMemOff()
387263320Sdim+         << "\n"; break;
388263320Sdim+    }
389263320Sdim+  }
390263320Sdim+
391263320Sdim+  void addRegOperands(MCInst &Inst, unsigned N) const {
392263320Sdim+    assert(N == 1 && "Invalid number of operands!");
393263320Sdim+    Inst.addOperand(MCOperand::CreateReg(getReg()));
394263320Sdim+  }
395263320Sdim+
396263320Sdim+  void addImmOperands(MCInst &Inst, unsigned N) const {
397263320Sdim+    assert(N == 1 && "Invalid number of operands!");
398263320Sdim+    const MCExpr *Expr = getImm();
399263320Sdim+    addExpr(Inst, Expr);
400263320Sdim+  }
401263320Sdim+
402263320Sdim+  void addExpr(MCInst &Inst, const MCExpr *Expr) const{
403263320Sdim+    // Add as immediate when possible.  Null MCExpr = 0.
404263320Sdim+    if (Expr == 0)
405263320Sdim+      Inst.addOperand(MCOperand::CreateImm(0));
406263320Sdim+    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
407263320Sdim+      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
408263320Sdim+    else
409263320Sdim+      Inst.addOperand(MCOperand::CreateExpr(Expr));
410263320Sdim+  }
411263320Sdim+
412263320Sdim+  void addMEMrrOperands(MCInst &Inst, unsigned N) const {
413263320Sdim+    assert(N == 2 && "Invalid number of operands!");
414263320Sdim+
415263320Sdim+    Inst.addOperand(MCOperand::CreateReg(getMemBase()));
416263320Sdim+
417263320Sdim+    assert(getMemOffsetReg() != 0 && "Invalid offset");
418263320Sdim+    Inst.addOperand(MCOperand::CreateReg(getMemOffsetReg()));
419263320Sdim+  }
420263320Sdim+
421263320Sdim+  void addMEMriOperands(MCInst &Inst, unsigned N) const {
422263320Sdim+    assert(N == 2 && "Invalid number of operands!");
423263320Sdim+
424263320Sdim+    Inst.addOperand(MCOperand::CreateReg(getMemBase()));
425263320Sdim+
426263320Sdim+    const MCExpr *Expr = getMemOff();
427263320Sdim+    addExpr(Inst, Expr);
428263320Sdim+  }
429263320Sdim+
430263320Sdim+  static SparcOperand *CreateToken(StringRef Str, SMLoc S) {
431263320Sdim+    SparcOperand *Op = new SparcOperand(k_Token);
432263320Sdim+    Op->Tok.Data = Str.data();
433263320Sdim+    Op->Tok.Length = Str.size();
434263320Sdim+    Op->StartLoc = S;
435263320Sdim+    Op->EndLoc = S;
436263320Sdim+    return Op;
437263320Sdim+  }
438263320Sdim+
439263320Sdim+  static SparcOperand *CreateReg(unsigned RegNum,
440263320Sdim+                                 SparcOperand::RegisterKind Kind,
441263320Sdim+                                 SMLoc S, SMLoc E) {
442263320Sdim+    SparcOperand *Op = new SparcOperand(k_Register);
443263320Sdim+    Op->Reg.RegNum = RegNum;
444263320Sdim+    Op->Reg.Kind   = Kind;
445263320Sdim+    Op->StartLoc = S;
446263320Sdim+    Op->EndLoc = E;
447263320Sdim+    return Op;
448263320Sdim+  }
449263320Sdim+
450263320Sdim+  static SparcOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
451263320Sdim+    SparcOperand *Op = new SparcOperand(k_Immediate);
452263320Sdim+    Op->Imm.Val = Val;
453263320Sdim+    Op->StartLoc = S;
454263320Sdim+    Op->EndLoc = E;
455263320Sdim+    return Op;
456263320Sdim+  }
457263320Sdim+
458263320Sdim+
459263320Sdim+};
460263320Sdim+
461263320Sdim+} // end namespace
462263320Sdim+
463263320Sdim+bool SparcAsmParser::
464263320Sdim+MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
465263320Sdim+                        SmallVectorImpl<MCParsedAsmOperand*> &Operands,
466263320Sdim+                        MCStreamer &Out, unsigned &ErrorInfo,
467263320Sdim+                        bool MatchingInlineAsm) {
468263320Sdim+  MCInst Inst;
469263320Sdim+  SmallVector<MCInst, 8> Instructions;
470263320Sdim+  unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
471263320Sdim+                                              MatchingInlineAsm);
472263320Sdim+  switch (MatchResult) {
473263320Sdim+  default:
474263320Sdim+    break;
475263320Sdim+
476263320Sdim+  case Match_Success: {
477263320Sdim+    Inst.setLoc(IDLoc);
478263320Sdim+    Out.EmitInstruction(Inst);
479263320Sdim+    return false;
480263320Sdim+  }
481263320Sdim+
482263320Sdim+  case Match_MissingFeature:
483263320Sdim+    return Error(IDLoc,
484263320Sdim+                 "instruction requires a CPU feature not currently enabled");
485263320Sdim+
486263320Sdim+  case Match_InvalidOperand: {
487263320Sdim+    SMLoc ErrorLoc = IDLoc;
488263320Sdim+    if (ErrorInfo != ~0U) {
489263320Sdim+      if (ErrorInfo >= Operands.size())
490263320Sdim+        return Error(IDLoc, "too few operands for instruction");
491263320Sdim+
492263320Sdim+      ErrorLoc = ((SparcOperand*) Operands[ErrorInfo])->getStartLoc();
493263320Sdim+      if (ErrorLoc == SMLoc())
494263320Sdim+        ErrorLoc = IDLoc;
495263320Sdim+    }
496263320Sdim+
497263320Sdim+    return Error(ErrorLoc, "invalid operand for instruction");
498263320Sdim+  }
499263320Sdim+  case Match_MnemonicFail:
500263320Sdim+    return Error(IDLoc, "invalid instruction");
501263320Sdim+  }
502263320Sdim+  return true;
503263320Sdim+}
504263320Sdim+
505263320Sdim+bool SparcAsmParser::
506263320Sdim+ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc)
507263320Sdim+{
508263320Sdim+  const AsmToken &Tok = Parser.getTok();
509263320Sdim+  StartLoc = Tok.getLoc();
510263320Sdim+  EndLoc = Tok.getEndLoc();
511263320Sdim+  RegNo = 0;
512263320Sdim+  if (getLexer().getKind() != AsmToken::Percent)
513263320Sdim+    return false;
514263320Sdim+  Parser.Lex();
515263320Sdim+  if (matchRegisterName(Tok, RegNo, false, false)) {
516263320Sdim+    Parser.Lex();
517263320Sdim+    return false;
518263320Sdim+  }
519263320Sdim+
520263320Sdim+  return Error(StartLoc, "invalid register name");
521263320Sdim+}
522263320Sdim+
523263320Sdim+bool SparcAsmParser::
524263320Sdim+ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
525263320Sdim+                 SMLoc NameLoc,
526263320Sdim+                 SmallVectorImpl<MCParsedAsmOperand*> &Operands)
527263320Sdim+{
528263320Sdim+  // Check if we have valid mnemonic.
529263320Sdim+  if (!mnemonicIsValid(Name, 0)) {
530263320Sdim+    Parser.eatToEndOfStatement();
531263320Sdim+    return Error(NameLoc, "Unknown instruction");
532263320Sdim+  }
533263320Sdim+  // First operand in MCInst is instruction mnemonic.
534263320Sdim+  Operands.push_back(SparcOperand::CreateToken(Name, NameLoc));
535263320Sdim+
536263320Sdim+  if (getLexer().isNot(AsmToken::EndOfStatement)) {
537263320Sdim+    // Read the first operand.
538263320Sdim+    if (parseOperand(Operands, Name) != MatchOperand_Success) {
539263320Sdim+      SMLoc Loc = getLexer().getLoc();
540263320Sdim+      Parser.eatToEndOfStatement();
541263320Sdim+      return Error(Loc, "unexpected token");
542263320Sdim+    }
543263320Sdim+
544263320Sdim+    while (getLexer().is(AsmToken::Comma)) {
545263320Sdim+      Parser.Lex(); // Eat the comma.
546263320Sdim+      // Parse and remember the operand.
547263320Sdim+      if (parseOperand(Operands, Name) != MatchOperand_Success) {
548263320Sdim+        SMLoc Loc = getLexer().getLoc();
549263320Sdim+        Parser.eatToEndOfStatement();
550263320Sdim+        return Error(Loc, "unexpected token");
551263320Sdim+      }
552263320Sdim+    }
553263320Sdim+  }
554263320Sdim+  if (getLexer().isNot(AsmToken::EndOfStatement)) {
555263320Sdim+    SMLoc Loc = getLexer().getLoc();
556263320Sdim+    Parser.eatToEndOfStatement();
557263320Sdim+    return Error(Loc, "unexpected token");
558263320Sdim+  }
559263320Sdim+  Parser.Lex(); // Consume the EndOfStatement.
560263320Sdim+  return false;
561263320Sdim+}
562263320Sdim+
563263320Sdim+bool SparcAsmParser::
564263320Sdim+ParseDirective(AsmToken DirectiveID)
565263320Sdim+{
566263320Sdim+  // Ignore all directives for now.
567263320Sdim+  Parser.eatToEndOfStatement();
568263320Sdim+  return false;
569263320Sdim+}
570263320Sdim+
571263320Sdim+SparcAsmParser::OperandMatchResultTy SparcAsmParser::
572263320Sdim+parseMEMOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
573263320Sdim+                int ImmOffsetOrReg)
574263320Sdim+{
575263320Sdim+  // FIXME: Implement memory operand parsing here.
576263320Sdim+  return MatchOperand_NoMatch;
577263320Sdim+}
578263320Sdim+
579263320Sdim+SparcAsmParser::OperandMatchResultTy SparcAsmParser::
580263320Sdim+parseMEMrrOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands)
581263320Sdim+{
582263320Sdim+  return parseMEMOperand(Operands, 2);
583263320Sdim+}
584263320Sdim+
585263320Sdim+SparcAsmParser::OperandMatchResultTy SparcAsmParser::
586263320Sdim+parseMEMriOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands)
587263320Sdim+{
588263320Sdim+  return parseMEMOperand(Operands, 1);
589263320Sdim+}
590263320Sdim+
591263320Sdim+SparcAsmParser::OperandMatchResultTy SparcAsmParser::
592263320Sdim+parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
593263320Sdim+             StringRef Mnemonic)
594263320Sdim+{
595263320Sdim+  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
596263320Sdim+  if (ResTy == MatchOperand_Success)
597263320Sdim+    return ResTy;
598263320Sdim+  // If there wasn't a custom match, try the generic matcher below. Otherwise,
599263320Sdim+  // there was a match, but an error occurred, in which case, just return that
600263320Sdim+  // the operand parsing failed.
601263320Sdim+  if (ResTy == MatchOperand_ParseFail)
602263320Sdim+    return ResTy;
603263320Sdim+
604263320Sdim+  SMLoc S = Parser.getTok().getLoc();
605263320Sdim+  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
606263320Sdim+  const MCExpr *EVal;
607263320Sdim+  SparcOperand *Op;
608263320Sdim+  switch (getLexer().getKind()) {
609263320Sdim+  case AsmToken::Percent:
610263320Sdim+    Parser.Lex(); // Eat the '%'.
611263320Sdim+    unsigned RegNo;
612263320Sdim+    if (matchRegisterName(Parser.getTok(), RegNo, false, false)) {
613263320Sdim+      Parser.Lex(); // Eat the identifier token.
614263320Sdim+      Op = SparcOperand::CreateReg(RegNo, SparcOperand::rk_None, S, E);
615263320Sdim+      break;
616263320Sdim+    }
617263320Sdim+    // FIXME: Handle modifiers like %hi, %lo etc.,
618263320Sdim+    return MatchOperand_ParseFail;
619263320Sdim+
620263320Sdim+  case AsmToken::Minus:
621263320Sdim+  case AsmToken::Integer:
622263320Sdim+    if (getParser().parseExpression(EVal))
623263320Sdim+      return MatchOperand_ParseFail;
624263320Sdim+
625263320Sdim+    Op = SparcOperand::CreateImm(EVal, S, E);
626263320Sdim+    break;
627263320Sdim+
628263320Sdim+  case AsmToken::Identifier: {
629263320Sdim+    StringRef Identifier;
630263320Sdim+    if (getParser().parseIdentifier(Identifier))
631263320Sdim+      return MatchOperand_ParseFail;
632263320Sdim+    SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
633263320Sdim+    MCSymbol *Sym = getContext().GetOrCreateSymbol(Identifier);
634263320Sdim+
635263320Sdim+    // Otherwise create a symbol reference.
636263320Sdim+    const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
637263320Sdim+                                                getContext());
638263320Sdim+
639263320Sdim+    Op = SparcOperand::CreateImm(Res, S, E);
640263320Sdim+    break;
641263320Sdim+  }
642263320Sdim+
643263320Sdim+  case AsmToken::LBrac:  // handle [
644263320Sdim+    return parseMEMOperand(Operands, 0);
645263320Sdim+
646263320Sdim+  default:
647263320Sdim+    return MatchOperand_ParseFail;
648263320Sdim+  }
649263320Sdim+  // Push the parsed operand into the list of operands
650263320Sdim+  Operands.push_back(Op);
651263320Sdim+  return MatchOperand_Success;
652263320Sdim+}
653263320Sdim+
654263320Sdim+bool SparcAsmParser::matchRegisterName(const AsmToken &Tok,
655263320Sdim+                                       unsigned &RegNo,
656263320Sdim+                                       bool isDFP,
657263320Sdim+                                       bool isQFP)
658263320Sdim+{
659263320Sdim+  int64_t intVal = 0;
660263320Sdim+  RegNo = 0;
661263320Sdim+  if (Tok.is(AsmToken::Identifier)) {
662263320Sdim+    StringRef name = Tok.getString();
663263320Sdim+
664263320Sdim+    // %fp
665263320Sdim+    if (name.equals("fp")) {
666263320Sdim+      RegNo = Sparc::I6;
667263320Sdim+      return true;
668263320Sdim+    }
669263320Sdim+    // %sp
670263320Sdim+    if (name.equals("sp")) {
671263320Sdim+      RegNo = Sparc::O6;
672263320Sdim+      return true;
673263320Sdim+    }
674263320Sdim+
675263320Sdim+    if (name.equals("y")) {
676263320Sdim+      RegNo = Sparc::Y;
677263320Sdim+      return true;
678263320Sdim+    }
679263320Sdim+
680263320Sdim+    if (name.equals("icc")) {
681263320Sdim+      RegNo = Sparc::ICC;
682263320Sdim+      return true;
683263320Sdim+    }
684263320Sdim+
685263320Sdim+    if (name.equals("xcc")) {
686263320Sdim+      // FIXME:: check 64bit.
687263320Sdim+      RegNo = Sparc::ICC;
688263320Sdim+      return true;
689263320Sdim+    }
690263320Sdim+
691263320Sdim+    // %fcc0 - %fcc3
692263320Sdim+    if (name.substr(0, 3).equals_lower("fcc")
693263320Sdim+        && !name.substr(3).getAsInteger(10, intVal)
694263320Sdim+        && intVal < 4) {
695263320Sdim+      // FIXME: check 64bit and  handle %fcc1 - %fcc3
696263320Sdim+      RegNo = Sparc::FCC;
697263320Sdim+      return true;
698263320Sdim+    }
699263320Sdim+
700263320Sdim+    // %g0 - %g7
701263320Sdim+    if (name.substr(0, 1).equals_lower("g")
702263320Sdim+        && !name.substr(1).getAsInteger(10, intVal)
703263320Sdim+        && intVal < 8) {
704263320Sdim+      RegNo = IntRegs[intVal];
705263320Sdim+      return true;
706263320Sdim+    }
707263320Sdim+    // %o0 - %o7
708263320Sdim+    if (name.substr(0, 1).equals_lower("o")
709263320Sdim+        && !name.substr(1).getAsInteger(10, intVal)
710263320Sdim+        && intVal < 8) {
711263320Sdim+      RegNo = IntRegs[8 + intVal];
712263320Sdim+      return true;
713263320Sdim+    }
714263320Sdim+    if (name.substr(0, 1).equals_lower("l")
715263320Sdim+        && !name.substr(1).getAsInteger(10, intVal)
716263320Sdim+        && intVal < 8) {
717263320Sdim+      RegNo = IntRegs[16 + intVal];
718263320Sdim+      return true;
719263320Sdim+    }
720263320Sdim+    if (name.substr(0, 1).equals_lower("i")
721263320Sdim+        && !name.substr(1).getAsInteger(10, intVal)
722263320Sdim+        && intVal < 8) {
723263320Sdim+      RegNo = IntRegs[24 + intVal];
724263320Sdim+      return true;
725263320Sdim+    }
726263320Sdim+    // %f0 - %f31
727263320Sdim+    if (name.substr(0, 1).equals_lower("f")
728263320Sdim+        && !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 32) {
729263320Sdim+      if (isDFP && (intVal%2 == 0)) {
730263320Sdim+        RegNo = DoubleRegs[intVal/2];
731263320Sdim+      } else if (isQFP && (intVal%4 == 0)) {
732263320Sdim+        RegNo = QuadFPRegs[intVal/4];
733263320Sdim+      } else {
734263320Sdim+        RegNo = FloatRegs[intVal];
735263320Sdim+      }
736263320Sdim+      return true;
737263320Sdim+    }
738263320Sdim+    // %f32 - %f62
739263320Sdim+    if (name.substr(0, 1).equals_lower("f")
740263320Sdim+        && !name.substr(1, 2).getAsInteger(10, intVal)
741263320Sdim+        && intVal >= 32 && intVal <= 62 && (intVal % 2 == 0)) {
742263320Sdim+      if (isDFP) {
743263320Sdim+        RegNo = DoubleRegs[16 + intVal/2];
744263320Sdim+      } else if (isQFP && (intVal % 4 == 0)) {
745263320Sdim+        RegNo = QuadFPRegs[8 + intVal/4];
746263320Sdim+      } else {
747263320Sdim+        return false;
748263320Sdim+      }
749263320Sdim+      return true;
750263320Sdim+    }
751263320Sdim+
752263320Sdim+    // %r0 - %r31
753263320Sdim+    if (name.substr(0, 1).equals_lower("r")
754263320Sdim+        && !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 31) {
755263320Sdim+      RegNo = IntRegs[intVal];
756263320Sdim+      return true;
757263320Sdim+    }
758263320Sdim+  }
759263320Sdim+  return false;
760263320Sdim+}
761263320Sdim+
762263320Sdim+
763263320Sdim+
764263320Sdim+extern "C" void LLVMInitializeSparcAsmParser() {
765263320Sdim+  RegisterMCAsmParser<SparcAsmParser> A(TheSparcTarget);
766263320Sdim+  RegisterMCAsmParser<SparcAsmParser> B(TheSparcV9Target);
767263320Sdim+}
768263320Sdim+
769263320Sdim+#define GET_REGISTER_MATCHER
770263320Sdim+#define GET_MATCHER_IMPLEMENTATION
771263320Sdim+#include "SparcGenAsmMatcher.inc"
772263320SdimIndex: lib/Target/Sparc/AsmParser/LLVMBuild.txt
773263320Sdim===================================================================
774263320Sdim--- lib/Target/Sparc/AsmParser/LLVMBuild.txt
775263320Sdim+++ lib/Target/Sparc/AsmParser/LLVMBuild.txt
776263320Sdim@@ -0,0 +1,23 @@
777263320Sdim+;===- ./lib/Target/Sparc/AsmParser/LLVMBuild.txt ---------------*- Conf -*--===;
778263320Sdim+;
779263320Sdim+;                     The LLVM Compiler Infrastructure
780263320Sdim+;
781263320Sdim+; This file is distributed under the University of Illinois Open Source
782263320Sdim+; License. See LICENSE.TXT for details.
783263320Sdim+;
784263320Sdim+;===------------------------------------------------------------------------===;
785263320Sdim+;
786263320Sdim+; This is an LLVMBuild description file for the components in this subdirectory.
787263320Sdim+;
788263320Sdim+; For more information on the LLVMBuild system, please see:
789263320Sdim+;
790263320Sdim+;   http://llvm.org/docs/LLVMBuild.html
791263320Sdim+;
792263320Sdim+;===------------------------------------------------------------------------===;
793263320Sdim+
794263320Sdim+[component_0]
795263320Sdim+type = Library
796263320Sdim+name = SparcAsmParser
797263320Sdim+parent = Sparc
798263320Sdim+required_libraries = MC MCParser Support SparcDesc SparcInfo
799263320Sdim+add_to_library_groups = Sparc
800263320SdimIndex: lib/Target/Sparc/AsmParser/CMakeLists.txt
801263320Sdim===================================================================
802263320Sdim--- lib/Target/Sparc/AsmParser/CMakeLists.txt
803263320Sdim+++ lib/Target/Sparc/AsmParser/CMakeLists.txt
804263320Sdim@@ -0,0 +1,3 @@
805263320Sdim+add_llvm_library(LLVMSparcAsmParser
806263320Sdim+  SparcAsmParser.cpp
807263320Sdim+  )
808263320SdimIndex: lib/Target/Sparc/AsmParser/Makefile
809263320Sdim===================================================================
810263320Sdim--- lib/Target/Sparc/AsmParser/Makefile
811263320Sdim+++ lib/Target/Sparc/AsmParser/Makefile
812263320Sdim@@ -0,0 +1,15 @@
813263320Sdim+##===- lib/Target/Sparc/AsmParser/Makefile ------------------*- Makefile-*-===##
814263320Sdim+#
815263320Sdim+#                     The LLVM Compiler Infrastructure
816263320Sdim+#
817263320Sdim+# This file is distributed under the University of Illinois Open Source
818263320Sdim+# License. See LICENSE.TXT for details.
819263320Sdim+#
820263320Sdim+##===----------------------------------------------------------------------===##
821263320Sdim+LEVEL = ../../../..
822263320Sdim+LIBRARYNAME = LLVMSparcAsmParser
823263320Sdim+
824263320Sdim+# Hack: we need to include 'main' Sparc target directory to grab private headers
825263320Sdim+CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
826263320Sdim+
827263320Sdim+include $(LEVEL)/Makefile.common
828263320SdimIndex: lib/Target/Sparc/SparcInstr64Bit.td
829263320Sdim===================================================================
830263320Sdim--- lib/Target/Sparc/SparcInstr64Bit.td
831263320Sdim+++ lib/Target/Sparc/SparcInstr64Bit.td
832263320Sdim@@ -176,11 +176,11 @@ def : Pat<(SPcmpicc i64:$a, (i64 simm13:$b)), (CMP
833263320Sdim def : Pat<(ctpop i64:$src), (POPCrr $src)>;
834263320Sdim 
835263320Sdim // "LEA" form of add
836263320Sdim+let isCodeGenOnly = 1 in
837263320Sdim def LEAX_ADDri : F3_2<2, 0b000000,
838263320Sdim                      (outs I64Regs:$dst), (ins MEMri:$addr),
839263320Sdim                      "add ${addr:arith}, $dst",
840263320Sdim                      [(set iPTR:$dst, ADDRri:$addr)]>;
841263320Sdim-
842263320Sdim } // Predicates = [Is64Bit]
843263320Sdim 
844263320Sdim 
845