diff options
Diffstat (limited to 'contrib/llvm/patches/patch-r262261-llvm-r198591-sparc.diff')
-rw-r--r-- | contrib/llvm/patches/patch-r262261-llvm-r198591-sparc.diff | 762 |
1 files changed, 762 insertions, 0 deletions
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r198591-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r198591-sparc.diff new file mode 100644 index 0000000..08897ed --- /dev/null +++ b/contrib/llvm/patches/patch-r262261-llvm-r198591-sparc.diff @@ -0,0 +1,762 @@ +Pull in r198591 from upstream llvm trunk (by Venkatraman Govindaraju): + + [Sparc] Add initial implementation of disassembler for sparc + +Introduced here: http://svnweb.freebsd.org/changeset/base/262261 + +Index: lib/Target/Sparc/SparcInstrFormats.td +=================================================================== +--- lib/Target/Sparc/SparcInstrFormats.td ++++ lib/Target/Sparc/SparcInstrFormats.td +@@ -12,6 +12,7 @@ class InstSP<dag outs, dag ins, string asmstr, lis + field bits<32> Inst; + + let Namespace = "SP"; ++ let Size = 4; + + bits<2> op; + let Inst{31-30} = op; // Top two bits are the 'op' field +@@ -20,6 +21,9 @@ class InstSP<dag outs, dag ins, string asmstr, lis + dag InOperandList = ins; + let AsmString = asmstr; + let Pattern = pattern; ++ ++ let DecoderNamespace = "Sparc"; ++ field bits<32> SoftFail = 0; + } + + //===----------------------------------------------------------------------===// +@@ -58,6 +62,27 @@ class F2_2<bits<3> op2Val, dag outs, dag ins, stri + let Inst{28-25} = cond; + } + ++class F2_3<bits<3> op2Val, bits<2> ccVal, dag outs, dag ins, string asmstr, ++ list<dag> pattern> ++ : InstSP<outs, ins, asmstr, pattern> { ++ bit annul; ++ bits<4> cond; ++ bit pred; ++ bits<19> imm19; ++ ++ let op = 0; // op = 0 ++ ++ bit annul = 0; // currently unused ++ let pred = 1; // default is predict taken ++ ++ let Inst{29} = annul; ++ let Inst{28-25} = cond; ++ let Inst{24-22} = op2Val; ++ let Inst{21-20} = ccVal; ++ let Inst{19} = pred; ++ let Inst{18-0} = imm19; ++} ++ + //===----------------------------------------------------------------------===// + // Format #3 instruction classes in the Sparc + //===----------------------------------------------------------------------===// +Index: lib/Target/Sparc/LLVMBuild.txt +=================================================================== +--- lib/Target/Sparc/LLVMBuild.txt ++++ lib/Target/Sparc/LLVMBuild.txt +@@ -16,13 +16,15 @@ + ;===------------------------------------------------------------------------===; + + [common] +-subdirectories = AsmParser InstPrinter MCTargetDesc TargetInfo ++subdirectories = AsmParser Disassembler InstPrinter MCTargetDesc TargetInfo + + [component_0] + type = TargetGroup + name = Sparc + parent = Target ++has_asmparser = 1 + has_asmprinter = 1 ++has_disassembler = 1 + has_jit = 1 + + [component_1] +Index: lib/Target/Sparc/SparcInstrInfo.td +=================================================================== +--- lib/Target/Sparc/SparcInstrInfo.td ++++ lib/Target/Sparc/SparcInstrInfo.td +@@ -230,13 +230,13 @@ def FCC_O : FCC_VAL<29>; // Ordered + multiclass F3_12<string OpcStr, bits<6> Op3Val, SDNode OpNode, + RegisterClass RC, ValueType Ty, Operand immOp> { + def rr : F3_1<2, Op3Val, +- (outs RC:$dst), (ins RC:$b, RC:$c), +- !strconcat(OpcStr, " $b, $c, $dst"), +- [(set Ty:$dst, (OpNode Ty:$b, Ty:$c))]>; ++ (outs RC:$rd), (ins RC:$rs1, RC:$rs2), ++ !strconcat(OpcStr, " $rs1, $rs2, $rd"), ++ [(set Ty:$rd, (OpNode Ty:$rs1, Ty:$rs2))]>; + def ri : F3_2<2, Op3Val, +- (outs RC:$dst), (ins RC:$b, immOp:$c), +- !strconcat(OpcStr, " $b, $c, $dst"), +- [(set Ty:$dst, (OpNode Ty:$b, (Ty simm13:$c)))]>; ++ (outs RC:$rd), (ins RC:$rs1, immOp:$simm13), ++ !strconcat(OpcStr, " $rs1, $simm13, $rd"), ++ [(set Ty:$rd, (OpNode Ty:$rs1, (Ty simm13:$simm13)))]>; + } + + /// F3_12np multiclass - Define a normal F3_1/F3_2 pattern in one shot, with no +@@ -243,11 +243,11 @@ multiclass F3_12<string OpcStr, bits<6> Op3Val, SD + /// pattern. + multiclass F3_12np<string OpcStr, bits<6> Op3Val> { + def rr : F3_1<2, Op3Val, +- (outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c), +- !strconcat(OpcStr, " $b, $c, $dst"), []>; ++ (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2), ++ !strconcat(OpcStr, " $rs1, $rs2, $rd"), []>; + def ri : F3_2<2, Op3Val, +- (outs IntRegs:$dst), (ins IntRegs:$b, i32imm:$c), +- !strconcat(OpcStr, " $b, $c, $dst"), []>; ++ (outs IntRegs:$rd), (ins IntRegs:$rs1, i32imm:$simm13), ++ !strconcat(OpcStr, " $rs1, $simm13, $rd"), []>; + } + + //===----------------------------------------------------------------------===// +@@ -488,31 +488,31 @@ let rd = 0, imm22 = 0 in + defm AND : F3_12<"and", 0b000001, and, IntRegs, i32, i32imm>; + + def ANDNrr : F3_1<2, 0b000101, +- (outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c), +- "andn $b, $c, $dst", +- [(set i32:$dst, (and i32:$b, (not i32:$c)))]>; ++ (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2), ++ "andn $rs1, $rs2, $rd", ++ [(set i32:$rd, (and i32:$rs1, (not i32:$rs2)))]>; + def ANDNri : F3_2<2, 0b000101, +- (outs IntRegs:$dst), (ins IntRegs:$b, i32imm:$c), +- "andn $b, $c, $dst", []>; ++ (outs IntRegs:$rd), (ins IntRegs:$rs1, i32imm:$simm13), ++ "andn $rs1, $simm13, $rd", []>; + + defm OR : F3_12<"or", 0b000010, or, IntRegs, i32, i32imm>; + + def ORNrr : F3_1<2, 0b000110, +- (outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c), +- "orn $b, $c, $dst", +- [(set i32:$dst, (or i32:$b, (not i32:$c)))]>; ++ (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2), ++ "orn $rs1, $rs2, $rd", ++ [(set i32:$rd, (or i32:$rs1, (not i32:$rs2)))]>; + def ORNri : F3_2<2, 0b000110, +- (outs IntRegs:$dst), (ins IntRegs:$b, i32imm:$c), +- "orn $b, $c, $dst", []>; ++ (outs IntRegs:$rd), (ins IntRegs:$rs1, i32imm:$simm13), ++ "orn $rs1, $simm13, $rd", []>; + defm XOR : F3_12<"xor", 0b000011, xor, IntRegs, i32, i32imm>; + + def XNORrr : F3_1<2, 0b000111, +- (outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c), +- "xnor $b, $c, $dst", +- [(set i32:$dst, (not (xor i32:$b, i32:$c)))]>; ++ (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2), ++ "xnor $rs1, $rs2, $rd", ++ [(set i32:$rd, (not (xor i32:$rs1, i32:$rs2)))]>; + def XNORri : F3_2<2, 0b000111, +- (outs IntRegs:$dst), (ins IntRegs:$b, i32imm:$c), +- "xnor $b, $c, $dst", []>; ++ (outs IntRegs:$rd), (ins IntRegs:$rs1, i32imm:$simm13), ++ "xnor $rs1, $simm13, $rd", []>; + + // Section B.12 - Shift Instructions, p. 107 + defm SLL : F3_12<"sll", 0b100101, shl, IntRegs, i32, i32imm>; +@@ -545,21 +545,15 @@ let Defs = [ICC] in + + let Defs = [ICC], rd = 0 in { + def CMPrr : F3_1<2, 0b010100, +- (outs), (ins IntRegs:$b, IntRegs:$c), +- "cmp $b, $c", +- [(SPcmpicc i32:$b, i32:$c)]>; ++ (outs), (ins IntRegs:$rs1, IntRegs:$rs2), ++ "cmp $rs1, $rs2", ++ [(SPcmpicc i32:$rs1, i32:$rs2)]>; + def CMPri : F3_2<2, 0b010100, +- (outs), (ins IntRegs:$b, i32imm:$c), +- "cmp $b, $c", +- [(SPcmpicc i32:$b, (i32 simm13:$c))]>; ++ (outs), (ins IntRegs:$rs1, i32imm:$simm13), ++ "cmp $rs1, $simm13", ++ [(SPcmpicc i32:$rs1, (i32 simm13:$simm13))]>; + } + +-let Uses = [ICC], Defs = [ICC] in +- def SUBXCCrr: F3_1<2, 0b011100, +- (outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c), +- "subxcc $b, $c, $dst", []>; +- +- + // Section B.18 - Multiply Instructions, p. 113 + let Defs = [Y] in { + defm UMUL : F3_12np<"umul", 0b001010>; +@@ -858,7 +852,7 @@ let Defs = [FCC] in { + //===----------------------------------------------------------------------===// + // Instructions for Thread Local Storage(TLS). + //===----------------------------------------------------------------------===// +- ++let isCodeGenOnly = 1, isAsmParserOnly = 1 in { + def TLS_ADDrr : F3_1<2, 0b000000, + (outs IntRegs:$rd), + (ins IntRegs:$rs1, IntRegs:$rs2, TLSSym:$sym), +@@ -882,6 +876,7 @@ let Uses = [O6], isCall = 1, hasDelaySlot = 1 in + let op = 1; + let Inst{29-0} = disp; + } ++} + + //===----------------------------------------------------------------------===// + // V9 Instructions +Index: lib/Target/Sparc/CMakeLists.txt +=================================================================== +--- lib/Target/Sparc/CMakeLists.txt ++++ lib/Target/Sparc/CMakeLists.txt +@@ -3,6 +3,7 @@ set(LLVM_TARGET_DEFINITIONS Sparc.td) + tablegen(LLVM SparcGenRegisterInfo.inc -gen-register-info) + tablegen(LLVM SparcGenInstrInfo.inc -gen-instr-info) + tablegen(LLVM SparcGenCodeEmitter.inc -gen-emitter) ++tablegen(LLVM SparcGenDisassemblerTables.inc -gen-disassembler) + tablegen(LLVM SparcGenMCCodeEmitter.inc -gen-emitter -mc-emitter) + tablegen(LLVM SparcGenAsmWriter.inc -gen-asm-writer) + tablegen(LLVM SparcGenAsmMatcher.inc -gen-asm-matcher) +@@ -34,3 +35,4 @@ add_subdirectory(TargetInfo) + add_subdirectory(MCTargetDesc) + add_subdirectory(InstPrinter) + add_subdirectory(AsmParser) ++add_subdirectory(Disassembler) +Index: lib/Target/Sparc/Disassembler/SparcDisassembler.cpp +=================================================================== +--- lib/Target/Sparc/Disassembler/SparcDisassembler.cpp ++++ lib/Target/Sparc/Disassembler/SparcDisassembler.cpp +@@ -0,0 +1,228 @@ ++//===- SparcDisassembler.cpp - Disassembler for Sparc -----------*- C++ -*-===// ++// ++// The LLVM Compiler Infrastructure ++// ++// This file is distributed under the University of Illinois Open Source ++// License. See LICENSE.TXT for details. ++// ++//===----------------------------------------------------------------------===// ++// ++// This file is part of the Sparc Disassembler. ++// ++//===----------------------------------------------------------------------===// ++ ++#define DEBUG_TYPE "sparc-disassembler" ++ ++#include "Sparc.h" ++#include "SparcRegisterInfo.h" ++#include "SparcSubtarget.h" ++#include "llvm/MC/MCDisassembler.h" ++#include "llvm/MC/MCFixedLenDisassembler.h" ++#include "llvm/Support/MemoryObject.h" ++#include "llvm/Support/TargetRegistry.h" ++ ++using namespace llvm; ++ ++typedef MCDisassembler::DecodeStatus DecodeStatus; ++ ++namespace { ++ ++/// SparcDisassembler - a disassembler class for Sparc. ++class SparcDisassembler : public MCDisassembler { ++public: ++ /// Constructor - Initializes the disassembler. ++ /// ++ SparcDisassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info) : ++ MCDisassembler(STI), RegInfo(Info) ++ {} ++ virtual ~SparcDisassembler() {} ++ ++ const MCRegisterInfo *getRegInfo() const { return RegInfo.get(); } ++ ++ /// getInstruction - See MCDisassembler. ++ virtual DecodeStatus getInstruction(MCInst &instr, ++ uint64_t &size, ++ const MemoryObject ®ion, ++ uint64_t address, ++ raw_ostream &vStream, ++ raw_ostream &cStream) const; ++private: ++ OwningPtr<const MCRegisterInfo> RegInfo; ++}; ++ ++} ++ ++namespace llvm { ++ extern Target TheSparcTarget, TheSparcV9Target; ++} ++ ++static MCDisassembler *createSparcDisassembler( ++ const Target &T, ++ const MCSubtargetInfo &STI) { ++ return new SparcDisassembler(STI, T.createMCRegInfo("")); ++} ++ ++ ++extern "C" void LLVMInitializeSparcDisassembler() { ++ // Register the disassembler. ++ TargetRegistry::RegisterMCDisassembler(TheSparcTarget, ++ createSparcDisassembler); ++ TargetRegistry::RegisterMCDisassembler(TheSparcV9Target, ++ createSparcDisassembler); ++} ++ ++ ++ ++static const unsigned IntRegDecoderTable[] = { ++ SP::G0, SP::G1, SP::G2, SP::G3, ++ SP::G4, SP::G5, SP::G6, SP::G7, ++ SP::O0, SP::O1, SP::O2, SP::O3, ++ SP::O4, SP::O5, SP::O6, SP::O7, ++ SP::L0, SP::L1, SP::L2, SP::L3, ++ SP::L4, SP::L5, SP::L6, SP::L7, ++ SP::I0, SP::I1, SP::I2, SP::I3, ++ SP::I4, SP::I5, SP::I6, SP::I7 }; ++ ++static const unsigned FPRegDecoderTable[] = { ++ SP::F0, SP::F1, SP::F2, SP::F3, ++ SP::F4, SP::F5, SP::F6, SP::F7, ++ SP::F8, SP::F9, SP::F10, SP::F11, ++ SP::F12, SP::F13, SP::F14, SP::F15, ++ SP::F16, SP::F17, SP::F18, SP::F19, ++ SP::F20, SP::F21, SP::F22, SP::F23, ++ SP::F24, SP::F25, SP::F26, SP::F27, ++ SP::F28, SP::F29, SP::F30, SP::F31 }; ++ ++static const unsigned DFPRegDecoderTable[] = { ++ SP::D0, SP::D16, SP::D1, SP::D17, ++ SP::D2, SP::D18, SP::D3, SP::D19, ++ SP::D4, SP::D20, SP::D5, SP::D21, ++ SP::D6, SP::D22, SP::D7, SP::D23, ++ SP::D8, SP::D24, SP::D9, SP::D25, ++ SP::D10, SP::D26, SP::D11, SP::D27, ++ SP::D12, SP::D28, SP::D13, SP::D29, ++ SP::D14, SP::D30, SP::D15, SP::D31 }; ++ ++static const unsigned QFPRegDecoderTable[] = { ++ SP::Q0, SP::Q8, -1, -1, ++ SP::Q1, SP::Q9, -1, -1, ++ SP::Q2, SP::Q10, -1, -1, ++ SP::Q3, SP::Q11, -1, -1, ++ SP::Q4, SP::Q12, -1, -1, ++ SP::Q5, SP::Q13, -1, -1, ++ SP::Q6, SP::Q14, -1, -1, ++ SP::Q7, SP::Q15, -1, -1 } ; ++ ++static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, ++ unsigned RegNo, ++ uint64_t Address, ++ const void *Decoder) { ++ if (RegNo > 31) ++ return MCDisassembler::Fail; ++ unsigned Reg = IntRegDecoderTable[RegNo]; ++ Inst.addOperand(MCOperand::CreateReg(Reg)); ++ return MCDisassembler::Success; ++} ++ ++static DecodeStatus DecodeI64RegsRegisterClass(MCInst &Inst, ++ unsigned RegNo, ++ uint64_t Address, ++ const void *Decoder) { ++ if (RegNo > 31) ++ return MCDisassembler::Fail; ++ unsigned Reg = IntRegDecoderTable[RegNo]; ++ Inst.addOperand(MCOperand::CreateReg(Reg)); ++ return MCDisassembler::Success; ++} ++ ++ ++static DecodeStatus DecodeFPRegsRegisterClass(MCInst &Inst, ++ unsigned RegNo, ++ uint64_t Address, ++ const void *Decoder) { ++ if (RegNo > 31) ++ return MCDisassembler::Fail; ++ unsigned Reg = FPRegDecoderTable[RegNo]; ++ Inst.addOperand(MCOperand::CreateReg(Reg)); ++ return MCDisassembler::Success; ++} ++ ++ ++static DecodeStatus DecodeDFPRegsRegisterClass(MCInst &Inst, ++ unsigned RegNo, ++ uint64_t Address, ++ const void *Decoder) { ++ if (RegNo > 31) ++ return MCDisassembler::Fail; ++ unsigned Reg = DFPRegDecoderTable[RegNo]; ++ Inst.addOperand(MCOperand::CreateReg(Reg)); ++ return MCDisassembler::Success; ++} ++ ++ ++static DecodeStatus DecodeQFPRegsRegisterClass(MCInst &Inst, ++ unsigned RegNo, ++ uint64_t Address, ++ const void *Decoder) { ++ if (RegNo > 31) ++ return MCDisassembler::Fail; ++ ++ unsigned Reg = QFPRegDecoderTable[RegNo]; ++ if (Reg == (unsigned)-1) ++ return MCDisassembler::Fail; ++ Inst.addOperand(MCOperand::CreateReg(Reg)); ++ return MCDisassembler::Success; ++} ++ ++ ++#include "SparcGenDisassemblerTables.inc" ++ ++/// readInstruction - read four bytes from the MemoryObject ++/// and return 32 bit word. ++static DecodeStatus readInstruction32(const MemoryObject ®ion, ++ uint64_t address, ++ uint64_t &size, ++ uint32_t &insn) { ++ uint8_t Bytes[4]; ++ ++ // We want to read exactly 4 Bytes of data. ++ if (region.readBytes(address, 4, Bytes) == -1) { ++ size = 0; ++ return MCDisassembler::Fail; ++ } ++ ++ // Encoded as a big-endian 32-bit word in the stream. ++ insn = (Bytes[3] << 0) | ++ (Bytes[2] << 8) | ++ (Bytes[1] << 16) | ++ (Bytes[0] << 24); ++ ++ return MCDisassembler::Success; ++} ++ ++ ++DecodeStatus ++SparcDisassembler::getInstruction(MCInst &instr, ++ uint64_t &Size, ++ const MemoryObject &Region, ++ uint64_t Address, ++ raw_ostream &vStream, ++ raw_ostream &cStream) const { ++ uint32_t Insn; ++ ++ DecodeStatus Result = readInstruction32(Region, Address, Size, Insn); ++ if (Result == MCDisassembler::Fail) ++ return MCDisassembler::Fail; ++ ++ ++ // Calling the auto-generated decoder function. ++ Result = decodeInstruction(DecoderTableSparc32, instr, Insn, Address, ++ this, STI); ++ ++ if (Result != MCDisassembler::Fail) { ++ Size = 4; ++ return Result; ++ } ++ ++ return MCDisassembler::Fail; ++} +Index: lib/Target/Sparc/Disassembler/LLVMBuild.txt +=================================================================== +--- lib/Target/Sparc/Disassembler/LLVMBuild.txt ++++ lib/Target/Sparc/Disassembler/LLVMBuild.txt +@@ -0,0 +1,23 @@ ++;===- ./lib/Target/Sparc/Disassembler/LLVMBuild.txt ------------*- Conf -*--===; ++; ++; The LLVM Compiler Infrastructure ++; ++; This file is distributed under the University of Illinois Open Source ++; License. See LICENSE.TXT for details. ++; ++;===------------------------------------------------------------------------===; ++; ++; This is an LLVMBuild description file for the components in this subdirectory. ++; ++; For more information on the LLVMBuild system, please see: ++; ++; http://llvm.org/docs/LLVMBuild.html ++; ++;===------------------------------------------------------------------------===; ++ ++[component_0] ++type = Library ++name = SparcDisassembler ++parent = Sparc ++required_libraries = MC Support SparcInfo ++add_to_library_groups = Sparc +Index: lib/Target/Sparc/Disassembler/CMakeLists.txt +=================================================================== +--- lib/Target/Sparc/Disassembler/CMakeLists.txt ++++ lib/Target/Sparc/Disassembler/CMakeLists.txt +@@ -0,0 +1,12 @@ ++add_llvm_library(LLVMSparcDisassembler ++ SparcDisassembler.cpp ++ ) ++ ++# workaround for hanging compilation on MSVC9 and 10 ++if( MSVC_VERSION EQUAL 1400 OR MSVC_VERSION EQUAL 1500 ++ OR MSVC_VERSION EQUAL 1600 ) ++set_property( ++ SOURCE SparcDisassembler.cpp ++ PROPERTY COMPILE_FLAGS "/Od" ++ ) ++endif() +Index: lib/Target/Sparc/Disassembler/Makefile +=================================================================== +--- lib/Target/Sparc/Disassembler/Makefile ++++ lib/Target/Sparc/Disassembler/Makefile +@@ -0,0 +1,16 @@ ++##===- lib/Target/Sparc/Disassembler/Makefile --------------*- Makefile -*-===## ++# ++# The LLVM Compiler Infrastructure ++# ++# This file is distributed under the University of Illinois Open Source ++# License. See LICENSE.TXT for details. ++# ++##===----------------------------------------------------------------------===## ++ ++LEVEL = ../../../.. ++LIBRARYNAME = LLVMSparcDisassembler ++ ++# Hack: we need to include 'main' Sparc target directory to grab private headers ++CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/.. ++ ++include $(LEVEL)/Makefile.common +Index: lib/Target/Sparc/Makefile +=================================================================== +--- lib/Target/Sparc/Makefile ++++ lib/Target/Sparc/Makefile +@@ -14,11 +14,11 @@ TARGET = Sparc + # Make sure that tblgen is run, first thing. + BUILT_SOURCES = SparcGenRegisterInfo.inc SparcGenInstrInfo.inc \ + SparcGenAsmWriter.inc SparcGenAsmMatcher.inc \ +- SparcGenDAGISel.inc \ ++ SparcGenDAGISel.inc SparcGenDisassemblerTables.inc \ + SparcGenSubtargetInfo.inc SparcGenCallingConv.inc \ + SparcGenCodeEmitter.inc SparcGenMCCodeEmitter.inc + +-DIRS = InstPrinter AsmParser TargetInfo MCTargetDesc ++DIRS = InstPrinter AsmParser Disassembler TargetInfo MCTargetDesc + + include $(LEVEL)/Makefile.common + +Index: lib/Target/Sparc/SparcInstr64Bit.td +=================================================================== +--- lib/Target/Sparc/SparcInstr64Bit.td ++++ lib/Target/Sparc/SparcInstr64Bit.td +@@ -141,6 +141,7 @@ def : Pat<(i64 imm:$val), + let Predicates = [Is64Bit] in { + + // Register-register instructions. ++let isCodeGenOnly = 1 in { + defm ANDX : F3_12<"and", 0b000001, and, I64Regs, i64, i64imm>; + defm ORX : F3_12<"or", 0b000010, or, I64Regs, i64, i64imm>; + defm XORX : F3_12<"xor", 0b000011, xor, I64Regs, i64, i64imm>; +@@ -161,8 +162,6 @@ def XNORXrr : F3_1<2, 0b000111, + defm ADDX : F3_12<"add", 0b000000, add, I64Regs, i64, i64imm>; + defm SUBX : F3_12<"sub", 0b000100, sub, I64Regs, i64, i64imm>; + +-def : Pat<(SPcmpicc i64:$a, i64:$b), (CMPrr $a, $b)>; +- + def TLS_ADDXrr : F3_1<2, 0b000000, (outs I64Regs:$rd), + (ins I64Regs:$rs1, I64Regs:$rs2, TLSSym:$sym), + "add $rs1, $rs2, $rd, $sym", +@@ -169,18 +168,17 @@ def TLS_ADDXrr : F3_1<2, 0b000000, (outs I64Regs:$ + [(set i64:$rd, + (tlsadd i64:$rs1, i64:$rs2, tglobaltlsaddr:$sym))]>; + +-// Register-immediate instructions. +- +-def : Pat<(SPcmpicc i64:$a, (i64 simm13:$b)), (CMPri $a, (as_i32imm $b))>; +- +-def : Pat<(ctpop i64:$src), (POPCrr $src)>; +- + // "LEA" form of add +-let isCodeGenOnly = 1 in + def LEAX_ADDri : F3_2<2, 0b000000, + (outs I64Regs:$dst), (ins MEMri:$addr), + "add ${addr:arith}, $dst", + [(set iPTR:$dst, ADDRri:$addr)]>; ++} ++ ++def : Pat<(SPcmpicc i64:$a, i64:$b), (CMPrr $a, $b)>; ++def : Pat<(SPcmpicc i64:$a, (i64 simm13:$b)), (CMPri $a, (as_i32imm $b))>; ++def : Pat<(ctpop i64:$src), (POPCrr $src)>; ++ + } // Predicates = [Is64Bit] + + +@@ -245,7 +243,7 @@ def LDXri : F3_2<3, 0b001011, + (outs I64Regs:$dst), (ins MEMri:$addr), + "ldx [$addr], $dst", + [(set i64:$dst, (load ADDRri:$addr))]>; +-let mayLoad = 1 in ++let mayLoad = 1, isCodeGenOnly = 1, isAsmParserOnly = 1 in + def TLS_LDXrr : F3_1<3, 0b001011, + (outs IntRegs:$dst), (ins MEMrr:$addr, TLSSym:$sym), + "ldx [$addr], $dst, $sym", +@@ -278,11 +276,11 @@ def : Pat<(i64 (extloadi32 ADDRrr:$addr)), (LDrr + def : Pat<(i64 (extloadi32 ADDRri:$addr)), (LDri ADDRri:$addr)>; + + // Sign-extending load of i32 into i64 is a new SPARC v9 instruction. +-def LDSWrr : F3_1<3, 0b001011, ++def LDSWrr : F3_1<3, 0b001000, + (outs I64Regs:$dst), (ins MEMrr:$addr), + "ldsw [$addr], $dst", + [(set i64:$dst, (sextloadi32 ADDRrr:$addr))]>; +-def LDSWri : F3_2<3, 0b001011, ++def LDSWri : F3_2<3, 0b001000, + (outs I64Regs:$dst), (ins MEMri:$addr), + "ldsw [$addr], $dst", + [(set i64:$dst, (sextloadi32 ADDRri:$addr))]>; +@@ -289,13 +287,13 @@ def : Pat<(i64 (extloadi32 ADDRri:$addr)), (LDri + + // 64-bit stores. + def STXrr : F3_1<3, 0b001110, +- (outs), (ins MEMrr:$addr, I64Regs:$src), +- "stx $src, [$addr]", +- [(store i64:$src, ADDRrr:$addr)]>; ++ (outs), (ins MEMrr:$addr, I64Regs:$rd), ++ "stx $rd, [$addr]", ++ [(store i64:$rd, ADDRrr:$addr)]>; + def STXri : F3_2<3, 0b001110, +- (outs), (ins MEMri:$addr, I64Regs:$src), +- "stx $src, [$addr]", +- [(store i64:$src, ADDRri:$addr)]>; ++ (outs), (ins MEMri:$addr, I64Regs:$rd), ++ "stx $rd, [$addr]", ++ [(store i64:$rd, ADDRri:$addr)]>; + + // Truncating stores from i64 are identical to the i32 stores. + def : Pat<(truncstorei8 i64:$src, ADDRrr:$addr), (STBrr ADDRrr:$addr, $src)>; +@@ -315,6 +313,15 @@ def : Pat<(store (i64 0), ADDRri:$dst), (STXri ADD + //===----------------------------------------------------------------------===// + // 64-bit Conditionals. + //===----------------------------------------------------------------------===// ++ ++// Conditional branch class on %xcc: ++class XBranchSP<dag ins, string asmstr, list<dag> pattern> ++ : F2_3<0b001, 0b10, (outs), ins, asmstr, pattern> { ++ let isBranch = 1; ++ let isTerminator = 1; ++ let hasDelaySlot = 1; ++} ++ + // + // Flag-setting instructions like subcc and addcc set both icc and xcc flags. + // The icc flags correspond to the 32-bit result, and the xcc are for the +@@ -326,7 +333,7 @@ def : Pat<(store (i64 0), ADDRri:$dst), (STXri ADD + let Predicates = [Is64Bit] in { + + let Uses = [ICC] in +-def BPXCC : BranchSP<(ins brtarget:$imm22, CCOp:$cond), ++def BPXCC : XBranchSP<(ins brtarget:$imm22, CCOp:$cond), + "b$cond %xcc, $imm22", + [(SPbrxcc bb:$imm22, imm:$cond)]>; + +@@ -409,7 +416,7 @@ def : Pat<(SPselectfcc (i64 simm11:$t), i64:$f, im + + + // 64 bit SETHI +-let Predicates = [Is64Bit] in { ++let Predicates = [Is64Bit], isCodeGenOnly = 1 in { + def SETHIXi : F2_1<0b100, + (outs IntRegs:$rd), (ins i64imm:$imm22), + "sethi $imm22, $rd", +Index: test/MC/Disassembler/Sparc/lit.local.cfg +=================================================================== +--- test/MC/Disassembler/Sparc/lit.local.cfg ++++ test/MC/Disassembler/Sparc/lit.local.cfg +@@ -0,0 +1,4 @@ ++targets = set(config.root.targets_to_build.split()) ++if not 'Sparc' in targets: ++ config.unsupported = True ++ +Index: test/MC/Disassembler/Sparc/sparc.txt +=================================================================== +--- test/MC/Disassembler/Sparc/sparc.txt ++++ test/MC/Disassembler/Sparc/sparc.txt +@@ -0,0 +1,82 @@ ++# RUN: llvm-mc --disassemble %s -triple=sparc-unknown-linux | FileCheck %s ++ ++# CHECK: add %g0, %g0, %g0 ++0x80 0x00 0x00 0x00 ++ ++# CHECK: add %g1, %g2, %g3 ++0x86 0x00 0x40 0x02 ++ ++# CHECK: add %o0, %o1, %l0 ++0xa0 0x02 0x00 0x09 ++ ++# CHECK: add %o0, 10, %l0 ++0xa0 0x02 0x20 0x0a ++ ++# CHECK: addcc %g1, %g2, %g3 ++0x86 0x80 0x40 0x02 ++ ++# CHECK: addxcc %g1, %g2, %g3 ++0x86 0xc0 0x40 0x02 ++ ++# CHECK: udiv %g1, %g2, %g3 ++0x86 0x70 0x40 0x02 ++ ++# CHECK: sdiv %g1, %g2, %g3 ++0x86 0x78 0x40 0x02 ++ ++# CHECK: and %g1, %g2, %g3 ++0x86 0x08 0x40 0x02 ++ ++# CHECK: andn %g1, %g2, %g3 ++0x86 0x28 0x40 0x02 ++ ++# CHECK: or %g1, %g2, %g3 ++0x86 0x10 0x40 0x02 ++ ++# CHECK: orn %g1, %g2, %g3 ++0x86 0x30 0x40 0x02 ++ ++# CHECK: xor %g1, %g2, %g3 ++0x86 0x18 0x40 0x02 ++ ++# CHECK: xnor %g1, %g2, %g3 ++0x86 0x38 0x40 0x02 ++ ++# CHECK: umul %g1, %g2, %g3 ++0x86 0x50 0x40 0x02 ++ ++# CHECK: smul %g1, %g2, %g3 ++0x86 0x58 0x40 0x02 ++ ++# CHECK: nop ++0x01 0x00 0x00 0x00 ++ ++# CHECK: sethi 10, %l0 ++0x21 0x00 0x00 0x0a ++ ++# CHECK: sll %g1, %g2, %g3 ++0x87 0x28 0x40 0x02 ++ ++# CHECK: sll %g1, 31, %g3 ++0x87 0x28 0x60 0x1f ++ ++# CHECK: srl %g1, %g2, %g3 ++0x87 0x30 0x40 0x02 ++ ++# CHECK: srl %g1, 31, %g3 ++0x87 0x30 0x60 0x1f ++ ++# CHECK: sra %g1, %g2, %g3 ++0x87 0x38 0x40 0x02 ++ ++# CHECK: sra %g1, 31, %g3 ++0x87 0x38 0x60 0x1f ++ ++# CHECK: sub %g1, %g2, %g3 ++0x86 0x20 0x40 0x02 ++ ++# CHECK: subcc %g1, %g2, %g3 ++0x86 0xa0 0x40 0x02 ++ ++# CHECK: subxcc %g1, %g2, %g3 ++0x86 0xe0 0x40 0x02 |