1 Pull in r198484 from upstream llvm trunk (by Venkatraman Govindaraju):
3 [Sparc] Add the initial implementation of an asm parser for sparc/sparcv9.
5 Introduced here: http://svnweb.freebsd.org/changeset/base/262261
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() {
13 // Register the MC instruction info.
14 TargetRegistry::RegisterMCInstrInfo(TheSparcTarget, createSparcMCInstrInfo);
15 + TargetRegistry::RegisterMCInstrInfo(TheSparcV9Target, createSparcMCInstrInfo);
17 // Register the MC register info.
18 TargetRegistry::RegisterMCRegInfo(TheSparcTarget, createSparcMCRegisterInfo);
19 + TargetRegistry::RegisterMCRegInfo(TheSparcV9Target,
20 + createSparcMCRegisterInfo);
22 // Register the MC subtarget info.
23 TargetRegistry::RegisterMCSubtargetInfo(TheSparcTarget,
24 createSparcMCSubtargetInfo);
25 + TargetRegistry::RegisterMCSubtargetInfo(TheSparcV9Target,
26 + createSparcMCSubtargetInfo);
28 TargetRegistry::RegisterAsmStreamer(TheSparcTarget,
30 Index: lib/Target/Sparc/LLVMBuild.txt
31 ===================================================================
32 --- lib/Target/Sparc/LLVMBuild.txt
33 +++ lib/Target/Sparc/LLVMBuild.txt
35 ;===------------------------------------------------------------------------===;
38 -subdirectories = InstPrinter MCTargetDesc TargetInfo
39 +subdirectories = AsmParser InstPrinter MCTargetDesc TargetInfo
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], []>;
51 +def SparcMEMrrAsmOperand : AsmOperandClass {
53 + let ParserMethod = "parseMEMrrOperand";
56 +def SparcMEMriAsmOperand : AsmOperandClass {
58 + let ParserMethod = "parseMEMriOperand";
61 def MEMrr : Operand<iPTR> {
62 let PrintMethod = "printMemOperand";
63 let MIOperandInfo = (ops ptr_rc, ptr_rc);
64 + let ParserMatchClass = SparcMEMrrAsmOperand;
66 def MEMri : Operand<iPTR> {
67 let PrintMethod = "printMemOperand";
68 let MIOperandInfo = (ops ptr_rc, i32imm);
69 + let ParserMatchClass = SparcMEMriAsmOperand;
72 def TLSSym : Operand<iPTR>;
73 @@ -239,7 +251,10 @@ multiclass F3_12np<string OpcStr, bits<6> Op3Val>
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;
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>;
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
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
125 -DIRS = InstPrinter TargetInfo MCTargetDesc
126 +DIRS = InstPrinter AsmParser TargetInfo MCTargetDesc
128 include $(LEVEL)/Makefile.common
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"
136 def SparcInstrInfo : InstrInfo;
138 +def SparcAsmParser : AsmParser {
139 + bit ShouldEmitMatchRegisterName = 0;
142 //===----------------------------------------------------------------------===//
143 // SPARC processors supported.
144 //===----------------------------------------------------------------------===//
145 @@ -77,6 +81,7 @@ def SparcAsmWriter : AsmWriter {
147 // Pull in Instruction Info:
148 let InstructionSet = SparcInstrInfo;
149 + let AssemblyParsers = [SparcAsmParser];
151 let AssemblyWriters = [SparcAsmWriter];
153 Index: lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
154 ===================================================================
155 --- lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
156 +++ lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
158 +//===-- SparcAsmParser.cpp - Parse Sparc assembly to MCInst instructions --===//
160 +// The LLVM Compiler Infrastructure
162 +// This file is distributed under the University of Illinois Open Source
163 +// License. See LICENSE.TXT for details.
165 +//===----------------------------------------------------------------------===//
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"
177 +using namespace llvm;
179 +// The generated AsmMatcher SparcGenAsmMatcher uses "Sparc" as the target
180 +// namespace. But SPARC backend uses "SP" as its namespace.
183 + using namespace SP;
188 +class SparcAsmParser : public MCTargetAsmParser {
190 + MCSubtargetInfo &STI;
191 + MCAsmParser &Parser;
193 + /// @name Auto-generated Match Functions
196 +#define GET_ASSEMBLER_HEADER
197 +#include "SparcGenAsmMatcher.inc"
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,
209 + SmallVectorImpl<MCParsedAsmOperand*> &Operands);
210 + bool ParseDirective(AsmToken DirectiveID);
213 + // Custom parse functions for Sparc specific operands.
214 + OperandMatchResultTy
215 + parseMEMrrOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
216 + OperandMatchResultTy
217 + parseMEMriOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
219 + OperandMatchResultTy
220 + parseMEMOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
221 + int ImmOffsetOrReg);
223 + OperandMatchResultTy
224 + parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
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,
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()));
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 };
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 };
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 };
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 };
278 +/// SparcOperand - Instances of this class represent a parsed Sparc machine
280 +class SparcOperand : public MCParsedAsmOperand {
282 + enum RegisterKind {
300 + SMLoc StartLoc, EndLoc;
302 + SparcOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
320 + unsigned OffsetReg;
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; }
338 + StringRef getToken() const {
339 + assert(Kind == k_Token && "Invalid access!");
340 + return StringRef(Tok.Data, Tok.Length);
343 + unsigned getReg() const {
344 + assert((Kind == k_Register) && "Invalid access!");
348 + const MCExpr *getImm() const {
349 + assert((Kind == k_Immediate) && "Invalid access!");
353 + unsigned getMemBase() const {
354 + assert((Kind == k_MemoryReg || Kind == k_MemoryImm) && "Invalid access!");
358 + unsigned getMemOffsetReg() const {
359 + assert((Kind == k_MemoryReg) && "Invalid access!");
360 + return Mem.OffsetReg;
363 + const MCExpr *getMemOff() const {
364 + assert((Kind == k_MemoryImm) && "Invalid access!");
368 + /// getStartLoc - Get the location of the first token of this operand.
369 + SMLoc getStartLoc() const {
372 + /// getEndLoc - Get the location of the last token of this operand.
373 + SMLoc getEndLoc() const {
377 + virtual void print(raw_ostream &OS) const {
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()
391 + void addRegOperands(MCInst &Inst, unsigned N) const {
392 + assert(N == 1 && "Invalid number of operands!");
393 + Inst.addOperand(MCOperand::CreateReg(getReg()));
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);
402 + void addExpr(MCInst &Inst, const MCExpr *Expr) const{
403 + // Add as immediate when possible. Null MCExpr = 0.
405 + Inst.addOperand(MCOperand::CreateImm(0));
406 + else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
407 + Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
409 + Inst.addOperand(MCOperand::CreateExpr(Expr));
412 + void addMEMrrOperands(MCInst &Inst, unsigned N) const {
413 + assert(N == 2 && "Invalid number of operands!");
415 + Inst.addOperand(MCOperand::CreateReg(getMemBase()));
417 + assert(getMemOffsetReg() != 0 && "Invalid offset");
418 + Inst.addOperand(MCOperand::CreateReg(getMemOffsetReg()));
421 + void addMEMriOperands(MCInst &Inst, unsigned N) const {
422 + assert(N == 2 && "Invalid number of operands!");
424 + Inst.addOperand(MCOperand::CreateReg(getMemBase()));
426 + const MCExpr *Expr = getMemOff();
427 + addExpr(Inst, Expr);
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();
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;
450 + static SparcOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
451 + SparcOperand *Op = new SparcOperand(k_Immediate);
463 +bool SparcAsmParser::
464 +MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
465 + SmallVectorImpl<MCParsedAsmOperand*> &Operands,
466 + MCStreamer &Out, unsigned &ErrorInfo,
467 + bool MatchingInlineAsm) {
469 + SmallVector<MCInst, 8> Instructions;
470 + unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
471 + MatchingInlineAsm);
472 + switch (MatchResult) {
476 + case Match_Success: {
477 + Inst.setLoc(IDLoc);
478 + Out.EmitInstruction(Inst);
482 + case Match_MissingFeature:
483 + return Error(IDLoc,
484 + "instruction requires a CPU feature not currently enabled");
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");
492 + ErrorLoc = ((SparcOperand*) Operands[ErrorInfo])->getStartLoc();
493 + if (ErrorLoc == SMLoc())
497 + return Error(ErrorLoc, "invalid operand for instruction");
499 + case Match_MnemonicFail:
500 + return Error(IDLoc, "invalid instruction");
505 +bool SparcAsmParser::
506 +ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc)
508 + const AsmToken &Tok = Parser.getTok();
509 + StartLoc = Tok.getLoc();
510 + EndLoc = Tok.getEndLoc();
512 + if (getLexer().getKind() != AsmToken::Percent)
515 + if (matchRegisterName(Tok, RegNo, false, false)) {
520 + return Error(StartLoc, "invalid register name");
523 +bool SparcAsmParser::
524 +ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
526 + SmallVectorImpl<MCParsedAsmOperand*> &Operands)
528 + // Check if we have valid mnemonic.
529 + if (!mnemonicIsValid(Name, 0)) {
530 + Parser.eatToEndOfStatement();
531 + return Error(NameLoc, "Unknown instruction");
533 + // First operand in MCInst is instruction mnemonic.
534 + Operands.push_back(SparcOperand::CreateToken(Name, NameLoc));
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");
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");
554 + if (getLexer().isNot(AsmToken::EndOfStatement)) {
555 + SMLoc Loc = getLexer().getLoc();
556 + Parser.eatToEndOfStatement();
557 + return Error(Loc, "unexpected token");
559 + Parser.Lex(); // Consume the EndOfStatement.
563 +bool SparcAsmParser::
564 +ParseDirective(AsmToken DirectiveID)
566 + // Ignore all directives for now.
567 + Parser.eatToEndOfStatement();
571 +SparcAsmParser::OperandMatchResultTy SparcAsmParser::
572 +parseMEMOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
573 + int ImmOffsetOrReg)
575 + // FIXME: Implement memory operand parsing here.
576 + return MatchOperand_NoMatch;
579 +SparcAsmParser::OperandMatchResultTy SparcAsmParser::
580 +parseMEMrrOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands)
582 + return parseMEMOperand(Operands, 2);
585 +SparcAsmParser::OperandMatchResultTy SparcAsmParser::
586 +parseMEMriOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands)
588 + return parseMEMOperand(Operands, 1);
591 +SparcAsmParser::OperandMatchResultTy SparcAsmParser::
592 +parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
593 + StringRef Mnemonic)
595 + OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
596 + if (ResTy == MatchOperand_Success)
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)
604 + SMLoc S = Parser.getTok().getLoc();
605 + SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
606 + const MCExpr *EVal;
608 + switch (getLexer().getKind()) {
609 + case AsmToken::Percent:
610 + Parser.Lex(); // Eat the '%'.
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);
617 + // FIXME: Handle modifiers like %hi, %lo etc.,
618 + return MatchOperand_ParseFail;
620 + case AsmToken::Minus:
621 + case AsmToken::Integer:
622 + if (getParser().parseExpression(EVal))
623 + return MatchOperand_ParseFail;
625 + Op = SparcOperand::CreateImm(EVal, S, E);
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);
635 + // Otherwise create a symbol reference.
636 + const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
639 + Op = SparcOperand::CreateImm(Res, S, E);
643 + case AsmToken::LBrac: // handle [
644 + return parseMEMOperand(Operands, 0);
647 + return MatchOperand_ParseFail;
649 + // Push the parsed operand into the list of operands
650 + Operands.push_back(Op);
651 + return MatchOperand_Success;
654 +bool SparcAsmParser::matchRegisterName(const AsmToken &Tok,
659 + int64_t intVal = 0;
661 + if (Tok.is(AsmToken::Identifier)) {
662 + StringRef name = Tok.getString();
665 + if (name.equals("fp")) {
670 + if (name.equals("sp")) {
675 + if (name.equals("y")) {
680 + if (name.equals("icc")) {
681 + RegNo = Sparc::ICC;
685 + if (name.equals("xcc")) {
686 + // FIXME:: check 64bit.
687 + RegNo = Sparc::ICC;
692 + if (name.substr(0, 3).equals_lower("fcc")
693 + && !name.substr(3).getAsInteger(10, intVal)
695 + // FIXME: check 64bit and handle %fcc1 - %fcc3
696 + RegNo = Sparc::FCC;
701 + if (name.substr(0, 1).equals_lower("g")
702 + && !name.substr(1).getAsInteger(10, intVal)
704 + RegNo = IntRegs[intVal];
708 + if (name.substr(0, 1).equals_lower("o")
709 + && !name.substr(1).getAsInteger(10, intVal)
711 + RegNo = IntRegs[8 + intVal];
714 + if (name.substr(0, 1).equals_lower("l")
715 + && !name.substr(1).getAsInteger(10, intVal)
717 + RegNo = IntRegs[16 + intVal];
720 + if (name.substr(0, 1).equals_lower("i")
721 + && !name.substr(1).getAsInteger(10, intVal)
723 + RegNo = IntRegs[24 + intVal];
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];
734 + RegNo = FloatRegs[intVal];
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)) {
743 + RegNo = DoubleRegs[16 + intVal/2];
744 + } else if (isQFP && (intVal % 4 == 0)) {
745 + RegNo = QuadFPRegs[8 + intVal/4];
753 + if (name.substr(0, 1).equals_lower("r")
754 + && !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 31) {
755 + RegNo = IntRegs[intVal];
764 +extern "C" void LLVMInitializeSparcAsmParser() {
765 + RegisterMCAsmParser<SparcAsmParser> A(TheSparcTarget);
766 + RegisterMCAsmParser<SparcAsmParser> B(TheSparcV9Target);
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
777 +;===- ./lib/Target/Sparc/AsmParser/LLVMBuild.txt ---------------*- Conf -*--===;
779 +; The LLVM Compiler Infrastructure
781 +; This file is distributed under the University of Illinois Open Source
782 +; License. See LICENSE.TXT for details.
784 +;===------------------------------------------------------------------------===;
786 +; This is an LLVMBuild description file for the components in this subdirectory.
788 +; For more information on the LLVMBuild system, please see:
790 +; http://llvm.org/docs/LLVMBuild.html
792 +;===------------------------------------------------------------------------===;
796 +name = SparcAsmParser
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
805 +add_llvm_library(LLVMSparcAsmParser
808 Index: lib/Target/Sparc/AsmParser/Makefile
809 ===================================================================
810 --- lib/Target/Sparc/AsmParser/Makefile
811 +++ lib/Target/Sparc/AsmParser/Makefile
813 +##===- lib/Target/Sparc/AsmParser/Makefile ------------------*- Makefile-*-===##
815 +# The LLVM Compiler Infrastructure
817 +# This file is distributed under the University of Illinois Open Source
818 +# License. See LICENSE.TXT for details.
820 +##===----------------------------------------------------------------------===##
822 +LIBRARYNAME = LLVMSparcAsmParser
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)/..
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)>;
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)]>;
842 } // Predicates = [Is64Bit]