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