]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/llvm/patches/patch-r262261-llvm-r198484-sparc.diff
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / llvm / patches / patch-r262261-llvm-r198484-sparc.diff
1 Pull in r198484 from upstream llvm trunk (by Venkatraman Govindaraju):
2
3   [Sparc] Add the initial implementation of an asm parser for sparc/sparcv9.
4
5 Introduced here: http://svnweb.freebsd.org/changeset/base/262261
6
7 Index: 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);
30 Index: 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
43 Index: 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",
94 Index: 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)
111 Index: 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  
130 Index: 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  }
153 Index: 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"
772 Index: 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
800 Index: 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 +  )
808 Index: 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
828 Index: 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