diff options
author | dim <dim@FreeBSD.org> | 2014-03-26 07:42:43 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2014-03-26 07:42:43 +0000 |
commit | 45ae227ed48f53447b0000be4c2f1cb142fa5237 (patch) | |
tree | 2c3d1790f54e2af0e10eeb88cb26a0d91f029053 /contrib/llvm/patches/patch-r262261-llvm-r198591-sparc.diff | |
parent | fb422e6d310915f9e2641190198698d922f7ef58 (diff) | |
download | FreeBSD-src-45ae227ed48f53447b0000be4c2f1cb142fa5237.zip FreeBSD-src-45ae227ed48f53447b0000be4c2f1cb142fa5237.tar.gz |
MFC r263312:
Pull in r196939 from upstream llvm trunk (by Reid Kleckner):
Reland "Fix miscompile of MS inline assembly with stack realignment"
This re-lands commit r196876, which was reverted in r196879.
The tests have been fixed to pass on platforms with a stack alignment
larger than 4.
Update to clang side tests will land shortly.
Pull in r196986 from upstream llvm trunk (by Reid Kleckner):
Revert the backend fatal error from r196939
The combination of inline asm, stack realignment, and dynamic allocas
turns out to be too common to reject out of hand.
ASan inserts empy inline asm fragments and uses aligned allocas.
Compiling any trivial function containing a dynamic alloca with ASan is
enough to trigger the check.
XFAIL the test cases that would be miscompiled and add one that uses the
relevant functionality.
Pull in r202930 from upstream llvm trunk (by Hans Wennborg):
Check for dynamic allocas and inline asm that clobbers sp before building
selection dag (PR19012)
In X86SelectionDagInfo::EmitTargetCodeForMemcpy we check with MachineFrameInfo
to make sure that ESI isn't used as a base pointer register before we choose to
emit rep movs (which clobbers esi).
The problem is that MachineFrameInfo wouldn't know about dynamic allocas or
inline asm that clobbers the stack pointer until SelectionDAGBuilder has
encountered them.
This patch fixes the problem by checking for such things when building the
FunctionLoweringInfo.
Differential Revision: http://llvm-reviews.chandlerc.com/D2954
Together, these commits fix the problem encountered in the devel/emacs
port on the i386 architecture, where a combination of stack realignment,
alloca() and memcpy() could incidentally clobber the %esi register,
leading to segfaults in the temacs build-time utility.
See also: http://llvm.org/PR18171 and http://llvm.org/PR19012
Reported by: ashish
PR: ports/183064
MFC r263313:
Pull in r203311 from upstream llvm trunk (by Arnold Schwaighofer):
ISel: Make VSELECT selection terminate in cases where the condition type has to
be split and the result type widened.
When the condition of a vselect has to be split it makes no sense widening the
vselect and thereby widening the condition. We end up in an endless loop of
widening (vselect result type) and splitting (condition mask type) doing this.
Instead, split both the condition and the vselect and widen the result.
I ran this over the test suite with i686 and mattr=+sse and saw no regressions.
Fixes PR18036.
With this fix the original problem case from the graphics/rawtherapee
port (posted in http://llvm.org/PR18036 ) now compiles within ~97MB RSS.
Reported by: mandree
MFC r263320:
Add separate patch files for all the customizations we have currently
applied to our copy of llvm/clang. These can be applied in alphabetical
order to a pristine llvm/clang 3.4 release source tree, to result in the
same version used in FreeBSD.
This is intended to clearly document all the changes until now, which
mostly consist of cherry pickings from the respective upstream trunks,
plus a number of hand-written FreeBSD-specific ones. Hopefully those
can eventually be cleaned up and sent upstream too.
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..056cb34 --- /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://svn.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 |