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 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 SoftFail = 0; } //===----------------------------------------------------------------------===// @@ -58,6 +62,27 @@ class F2_2 op2Val, dag outs, dag ins, stri let Inst{28-25} = cond; } +class F2_3 op2Val, bits<2> ccVal, dag outs, dag ins, string asmstr, + list pattern> + : InstSP { + 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 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 Op3Val, SD /// pattern. multiclass F3_12np 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 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 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