mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-22 18:35:45 +00:00
[Sparc] Add initial implementation of disassembler for sparc
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@198591 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
ba7548302b
commit
9429f47d83
@ -3,6 +3,7 @@ set(LLVM_TARGET_DEFINITIONS Sparc.td)
|
|||||||
tablegen(LLVM SparcGenRegisterInfo.inc -gen-register-info)
|
tablegen(LLVM SparcGenRegisterInfo.inc -gen-register-info)
|
||||||
tablegen(LLVM SparcGenInstrInfo.inc -gen-instr-info)
|
tablegen(LLVM SparcGenInstrInfo.inc -gen-instr-info)
|
||||||
tablegen(LLVM SparcGenCodeEmitter.inc -gen-emitter)
|
tablegen(LLVM SparcGenCodeEmitter.inc -gen-emitter)
|
||||||
|
tablegen(LLVM SparcGenDisassemblerTables.inc -gen-disassembler)
|
||||||
tablegen(LLVM SparcGenMCCodeEmitter.inc -gen-emitter -mc-emitter)
|
tablegen(LLVM SparcGenMCCodeEmitter.inc -gen-emitter -mc-emitter)
|
||||||
tablegen(LLVM SparcGenAsmWriter.inc -gen-asm-writer)
|
tablegen(LLVM SparcGenAsmWriter.inc -gen-asm-writer)
|
||||||
tablegen(LLVM SparcGenAsmMatcher.inc -gen-asm-matcher)
|
tablegen(LLVM SparcGenAsmMatcher.inc -gen-asm-matcher)
|
||||||
@ -32,3 +33,4 @@ add_subdirectory(TargetInfo)
|
|||||||
add_subdirectory(MCTargetDesc)
|
add_subdirectory(MCTargetDesc)
|
||||||
add_subdirectory(InstPrinter)
|
add_subdirectory(InstPrinter)
|
||||||
add_subdirectory(AsmParser)
|
add_subdirectory(AsmParser)
|
||||||
|
add_subdirectory(Disassembler)
|
||||||
|
12
lib/Target/Sparc/Disassembler/CMakeLists.txt
Normal file
12
lib/Target/Sparc/Disassembler/CMakeLists.txt
Normal file
@ -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()
|
23
lib/Target/Sparc/Disassembler/LLVMBuild.txt
Normal file
23
lib/Target/Sparc/Disassembler/LLVMBuild.txt
Normal file
@ -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
|
16
lib/Target/Sparc/Disassembler/Makefile
Normal file
16
lib/Target/Sparc/Disassembler/Makefile
Normal file
@ -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
|
228
lib/Target/Sparc/Disassembler/SparcDisassembler.cpp
Normal file
228
lib/Target/Sparc/Disassembler/SparcDisassembler.cpp
Normal file
@ -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;
|
||||||
|
}
|
@ -16,13 +16,15 @@
|
|||||||
;===------------------------------------------------------------------------===;
|
;===------------------------------------------------------------------------===;
|
||||||
|
|
||||||
[common]
|
[common]
|
||||||
subdirectories = AsmParser InstPrinter MCTargetDesc TargetInfo
|
subdirectories = AsmParser Disassembler InstPrinter MCTargetDesc TargetInfo
|
||||||
|
|
||||||
[component_0]
|
[component_0]
|
||||||
type = TargetGroup
|
type = TargetGroup
|
||||||
name = Sparc
|
name = Sparc
|
||||||
parent = Target
|
parent = Target
|
||||||
|
has_asmparser = 1
|
||||||
has_asmprinter = 1
|
has_asmprinter = 1
|
||||||
|
has_disassembler = 1
|
||||||
has_jit = 1
|
has_jit = 1
|
||||||
|
|
||||||
[component_1]
|
[component_1]
|
||||||
|
@ -14,11 +14,11 @@ TARGET = Sparc
|
|||||||
# Make sure that tblgen is run, first thing.
|
# Make sure that tblgen is run, first thing.
|
||||||
BUILT_SOURCES = SparcGenRegisterInfo.inc SparcGenInstrInfo.inc \
|
BUILT_SOURCES = SparcGenRegisterInfo.inc SparcGenInstrInfo.inc \
|
||||||
SparcGenAsmWriter.inc SparcGenAsmMatcher.inc \
|
SparcGenAsmWriter.inc SparcGenAsmMatcher.inc \
|
||||||
SparcGenDAGISel.inc \
|
SparcGenDAGISel.inc SparcGenDisassemblerTables.inc \
|
||||||
SparcGenSubtargetInfo.inc SparcGenCallingConv.inc \
|
SparcGenSubtargetInfo.inc SparcGenCallingConv.inc \
|
||||||
SparcGenCodeEmitter.inc SparcGenMCCodeEmitter.inc
|
SparcGenCodeEmitter.inc SparcGenMCCodeEmitter.inc
|
||||||
|
|
||||||
DIRS = InstPrinter AsmParser TargetInfo MCTargetDesc
|
DIRS = InstPrinter AsmParser Disassembler TargetInfo MCTargetDesc
|
||||||
|
|
||||||
include $(LEVEL)/Makefile.common
|
include $(LEVEL)/Makefile.common
|
||||||
|
|
||||||
|
@ -141,6 +141,7 @@ def : Pat<(i64 imm:$val),
|
|||||||
let Predicates = [Is64Bit] in {
|
let Predicates = [Is64Bit] in {
|
||||||
|
|
||||||
// Register-register instructions.
|
// Register-register instructions.
|
||||||
|
let isCodeGenOnly = 1 in {
|
||||||
defm ANDX : F3_12<"and", 0b000001, and, I64Regs, i64, i64imm>;
|
defm ANDX : F3_12<"and", 0b000001, and, I64Regs, i64, i64imm>;
|
||||||
defm ORX : F3_12<"or", 0b000010, or, I64Regs, i64, i64imm>;
|
defm ORX : F3_12<"or", 0b000010, or, I64Regs, i64, i64imm>;
|
||||||
defm XORX : F3_12<"xor", 0b000011, xor, I64Regs, i64, i64imm>;
|
defm XORX : F3_12<"xor", 0b000011, xor, I64Regs, i64, i64imm>;
|
||||||
@ -161,26 +162,23 @@ def XNORXrr : F3_1<2, 0b000111,
|
|||||||
defm ADDX : F3_12<"add", 0b000000, add, I64Regs, i64, i64imm>;
|
defm ADDX : F3_12<"add", 0b000000, add, I64Regs, i64, i64imm>;
|
||||||
defm SUBX : F3_12<"sub", 0b000100, sub, 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),
|
def TLS_ADDXrr : F3_1<2, 0b000000, (outs I64Regs:$rd),
|
||||||
(ins I64Regs:$rs1, I64Regs:$rs2, TLSSym:$sym),
|
(ins I64Regs:$rs1, I64Regs:$rs2, TLSSym:$sym),
|
||||||
"add $rs1, $rs2, $rd, $sym",
|
"add $rs1, $rs2, $rd, $sym",
|
||||||
[(set i64:$rd,
|
[(set i64:$rd,
|
||||||
(tlsadd i64:$rs1, i64:$rs2, tglobaltlsaddr:$sym))]>;
|
(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
|
// "LEA" form of add
|
||||||
let isCodeGenOnly = 1 in
|
|
||||||
def LEAX_ADDri : F3_2<2, 0b000000,
|
def LEAX_ADDri : F3_2<2, 0b000000,
|
||||||
(outs I64Regs:$dst), (ins MEMri:$addr),
|
(outs I64Regs:$dst), (ins MEMri:$addr),
|
||||||
"add ${addr:arith}, $dst",
|
"add ${addr:arith}, $dst",
|
||||||
[(set iPTR:$dst, ADDRri:$addr)]>;
|
[(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]
|
} // Predicates = [Is64Bit]
|
||||||
|
|
||||||
|
|
||||||
@ -245,7 +243,7 @@ def LDXri : F3_2<3, 0b001011,
|
|||||||
(outs I64Regs:$dst), (ins MEMri:$addr),
|
(outs I64Regs:$dst), (ins MEMri:$addr),
|
||||||
"ldx [$addr], $dst",
|
"ldx [$addr], $dst",
|
||||||
[(set i64:$dst, (load ADDRri:$addr))]>;
|
[(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,
|
def TLS_LDXrr : F3_1<3, 0b001011,
|
||||||
(outs IntRegs:$dst), (ins MEMrr:$addr, TLSSym:$sym),
|
(outs IntRegs:$dst), (ins MEMrr:$addr, TLSSym:$sym),
|
||||||
"ldx [$addr], $dst, $sym",
|
"ldx [$addr], $dst, $sym",
|
||||||
@ -278,24 +276,24 @@ def : Pat<(i64 (extloadi32 ADDRrr:$addr)), (LDrr ADDRrr:$addr)>;
|
|||||||
def : Pat<(i64 (extloadi32 ADDRri:$addr)), (LDri ADDRri:$addr)>;
|
def : Pat<(i64 (extloadi32 ADDRri:$addr)), (LDri ADDRri:$addr)>;
|
||||||
|
|
||||||
// Sign-extending load of i32 into i64 is a new SPARC v9 instruction.
|
// 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),
|
(outs I64Regs:$dst), (ins MEMrr:$addr),
|
||||||
"ldsw [$addr], $dst",
|
"ldsw [$addr], $dst",
|
||||||
[(set i64:$dst, (sextloadi32 ADDRrr:$addr))]>;
|
[(set i64:$dst, (sextloadi32 ADDRrr:$addr))]>;
|
||||||
def LDSWri : F3_2<3, 0b001011,
|
def LDSWri : F3_2<3, 0b001000,
|
||||||
(outs I64Regs:$dst), (ins MEMri:$addr),
|
(outs I64Regs:$dst), (ins MEMri:$addr),
|
||||||
"ldsw [$addr], $dst",
|
"ldsw [$addr], $dst",
|
||||||
[(set i64:$dst, (sextloadi32 ADDRri:$addr))]>;
|
[(set i64:$dst, (sextloadi32 ADDRri:$addr))]>;
|
||||||
|
|
||||||
// 64-bit stores.
|
// 64-bit stores.
|
||||||
def STXrr : F3_1<3, 0b001110,
|
def STXrr : F3_1<3, 0b001110,
|
||||||
(outs), (ins MEMrr:$addr, I64Regs:$src),
|
(outs), (ins MEMrr:$addr, I64Regs:$rd),
|
||||||
"stx $src, [$addr]",
|
"stx $rd, [$addr]",
|
||||||
[(store i64:$src, ADDRrr:$addr)]>;
|
[(store i64:$rd, ADDRrr:$addr)]>;
|
||||||
def STXri : F3_2<3, 0b001110,
|
def STXri : F3_2<3, 0b001110,
|
||||||
(outs), (ins MEMri:$addr, I64Regs:$src),
|
(outs), (ins MEMri:$addr, I64Regs:$rd),
|
||||||
"stx $src, [$addr]",
|
"stx $rd, [$addr]",
|
||||||
[(store i64:$src, ADDRri:$addr)]>;
|
[(store i64:$rd, ADDRri:$addr)]>;
|
||||||
|
|
||||||
// Truncating stores from i64 are identical to the i32 stores.
|
// Truncating stores from i64 are identical to the i32 stores.
|
||||||
def : Pat<(truncstorei8 i64:$src, ADDRrr:$addr), (STBrr ADDRrr:$addr, $src)>;
|
def : Pat<(truncstorei8 i64:$src, ADDRrr:$addr), (STBrr ADDRrr:$addr, $src)>;
|
||||||
@ -315,6 +313,15 @@ def : Pat<(store (i64 0), ADDRri:$dst), (STXri ADDRri:$dst, (i64 G0))>;
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// 64-bit Conditionals.
|
// 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.
|
// 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
|
// 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 ADDRri:$dst, (i64 G0))>;
|
|||||||
let Predicates = [Is64Bit] in {
|
let Predicates = [Is64Bit] in {
|
||||||
|
|
||||||
let Uses = [ICC] 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",
|
"b$cond %xcc, $imm22",
|
||||||
[(SPbrxcc bb:$imm22, imm:$cond)]>;
|
[(SPbrxcc bb:$imm22, imm:$cond)]>;
|
||||||
|
|
||||||
@ -409,7 +416,7 @@ def : Pat<(SPselectfcc (i64 simm11:$t), i64:$f, imm:$cond),
|
|||||||
|
|
||||||
|
|
||||||
// 64 bit SETHI
|
// 64 bit SETHI
|
||||||
let Predicates = [Is64Bit] in {
|
let Predicates = [Is64Bit], isCodeGenOnly = 1 in {
|
||||||
def SETHIXi : F2_1<0b100,
|
def SETHIXi : F2_1<0b100,
|
||||||
(outs IntRegs:$rd), (ins i64imm:$imm22),
|
(outs IntRegs:$rd), (ins i64imm:$imm22),
|
||||||
"sethi $imm22, $rd",
|
"sethi $imm22, $rd",
|
||||||
|
@ -12,6 +12,7 @@ class InstSP<dag outs, dag ins, string asmstr, list<dag> pattern>
|
|||||||
field bits<32> Inst;
|
field bits<32> Inst;
|
||||||
|
|
||||||
let Namespace = "SP";
|
let Namespace = "SP";
|
||||||
|
let Size = 4;
|
||||||
|
|
||||||
bits<2> op;
|
bits<2> op;
|
||||||
let Inst{31-30} = op; // Top two bits are the 'op' field
|
let Inst{31-30} = op; // Top two bits are the 'op' field
|
||||||
@ -20,6 +21,9 @@ class InstSP<dag outs, dag ins, string asmstr, list<dag> pattern>
|
|||||||
dag InOperandList = ins;
|
dag InOperandList = ins;
|
||||||
let AsmString = asmstr;
|
let AsmString = asmstr;
|
||||||
let Pattern = pattern;
|
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, string asmstr,
|
|||||||
let Inst{28-25} = cond;
|
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
|
// Format #3 instruction classes in the Sparc
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -230,24 +230,24 @@ def FCC_O : FCC_VAL<29>; // Ordered
|
|||||||
multiclass F3_12<string OpcStr, bits<6> Op3Val, SDNode OpNode,
|
multiclass F3_12<string OpcStr, bits<6> Op3Val, SDNode OpNode,
|
||||||
RegisterClass RC, ValueType Ty, Operand immOp> {
|
RegisterClass RC, ValueType Ty, Operand immOp> {
|
||||||
def rr : F3_1<2, Op3Val,
|
def rr : F3_1<2, Op3Val,
|
||||||
(outs RC:$dst), (ins RC:$b, RC:$c),
|
(outs RC:$rd), (ins RC:$rs1, RC:$rs2),
|
||||||
!strconcat(OpcStr, " $b, $c, $dst"),
|
!strconcat(OpcStr, " $rs1, $rs2, $rd"),
|
||||||
[(set Ty:$dst, (OpNode Ty:$b, Ty:$c))]>;
|
[(set Ty:$rd, (OpNode Ty:$rs1, Ty:$rs2))]>;
|
||||||
def ri : F3_2<2, Op3Val,
|
def ri : F3_2<2, Op3Val,
|
||||||
(outs RC:$dst), (ins RC:$b, immOp:$c),
|
(outs RC:$rd), (ins RC:$rs1, immOp:$simm13),
|
||||||
!strconcat(OpcStr, " $b, $c, $dst"),
|
!strconcat(OpcStr, " $rs1, $simm13, $rd"),
|
||||||
[(set Ty:$dst, (OpNode Ty:$b, (Ty simm13:$c)))]>;
|
[(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
|
/// F3_12np multiclass - Define a normal F3_1/F3_2 pattern in one shot, with no
|
||||||
/// pattern.
|
/// pattern.
|
||||||
multiclass F3_12np<string OpcStr, bits<6> Op3Val> {
|
multiclass F3_12np<string OpcStr, bits<6> Op3Val> {
|
||||||
def rr : F3_1<2, Op3Val,
|
def rr : F3_1<2, Op3Val,
|
||||||
(outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c),
|
(outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2),
|
||||||
!strconcat(OpcStr, " $b, $c, $dst"), []>;
|
!strconcat(OpcStr, " $rs1, $rs2, $rd"), []>;
|
||||||
def ri : F3_2<2, Op3Val,
|
def ri : F3_2<2, Op3Val,
|
||||||
(outs IntRegs:$dst), (ins IntRegs:$b, i32imm:$c),
|
(outs IntRegs:$rd), (ins IntRegs:$rs1, i32imm:$simm13),
|
||||||
!strconcat(OpcStr, " $b, $c, $dst"), []>;
|
!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>;
|
defm AND : F3_12<"and", 0b000001, and, IntRegs, i32, i32imm>;
|
||||||
|
|
||||||
def ANDNrr : F3_1<2, 0b000101,
|
def ANDNrr : F3_1<2, 0b000101,
|
||||||
(outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c),
|
(outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2),
|
||||||
"andn $b, $c, $dst",
|
"andn $rs1, $rs2, $rd",
|
||||||
[(set i32:$dst, (and i32:$b, (not i32:$c)))]>;
|
[(set i32:$rd, (and i32:$rs1, (not i32:$rs2)))]>;
|
||||||
def ANDNri : F3_2<2, 0b000101,
|
def ANDNri : F3_2<2, 0b000101,
|
||||||
(outs IntRegs:$dst), (ins IntRegs:$b, i32imm:$c),
|
(outs IntRegs:$rd), (ins IntRegs:$rs1, i32imm:$simm13),
|
||||||
"andn $b, $c, $dst", []>;
|
"andn $rs1, $simm13, $rd", []>;
|
||||||
|
|
||||||
defm OR : F3_12<"or", 0b000010, or, IntRegs, i32, i32imm>;
|
defm OR : F3_12<"or", 0b000010, or, IntRegs, i32, i32imm>;
|
||||||
|
|
||||||
def ORNrr : F3_1<2, 0b000110,
|
def ORNrr : F3_1<2, 0b000110,
|
||||||
(outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c),
|
(outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2),
|
||||||
"orn $b, $c, $dst",
|
"orn $rs1, $rs2, $rd",
|
||||||
[(set i32:$dst, (or i32:$b, (not i32:$c)))]>;
|
[(set i32:$rd, (or i32:$rs1, (not i32:$rs2)))]>;
|
||||||
def ORNri : F3_2<2, 0b000110,
|
def ORNri : F3_2<2, 0b000110,
|
||||||
(outs IntRegs:$dst), (ins IntRegs:$b, i32imm:$c),
|
(outs IntRegs:$rd), (ins IntRegs:$rs1, i32imm:$simm13),
|
||||||
"orn $b, $c, $dst", []>;
|
"orn $rs1, $simm13, $rd", []>;
|
||||||
defm XOR : F3_12<"xor", 0b000011, xor, IntRegs, i32, i32imm>;
|
defm XOR : F3_12<"xor", 0b000011, xor, IntRegs, i32, i32imm>;
|
||||||
|
|
||||||
def XNORrr : F3_1<2, 0b000111,
|
def XNORrr : F3_1<2, 0b000111,
|
||||||
(outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c),
|
(outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2),
|
||||||
"xnor $b, $c, $dst",
|
"xnor $rs1, $rs2, $rd",
|
||||||
[(set i32:$dst, (not (xor i32:$b, i32:$c)))]>;
|
[(set i32:$rd, (not (xor i32:$rs1, i32:$rs2)))]>;
|
||||||
def XNORri : F3_2<2, 0b000111,
|
def XNORri : F3_2<2, 0b000111,
|
||||||
(outs IntRegs:$dst), (ins IntRegs:$b, i32imm:$c),
|
(outs IntRegs:$rd), (ins IntRegs:$rs1, i32imm:$simm13),
|
||||||
"xnor $b, $c, $dst", []>;
|
"xnor $rs1, $simm13, $rd", []>;
|
||||||
|
|
||||||
// Section B.12 - Shift Instructions, p. 107
|
// Section B.12 - Shift Instructions, p. 107
|
||||||
defm SLL : F3_12<"sll", 0b100101, shl, IntRegs, i32, i32imm>;
|
defm SLL : F3_12<"sll", 0b100101, shl, IntRegs, i32, i32imm>;
|
||||||
@ -545,21 +545,15 @@ let Defs = [ICC] in
|
|||||||
|
|
||||||
let Defs = [ICC], rd = 0 in {
|
let Defs = [ICC], rd = 0 in {
|
||||||
def CMPrr : F3_1<2, 0b010100,
|
def CMPrr : F3_1<2, 0b010100,
|
||||||
(outs), (ins IntRegs:$b, IntRegs:$c),
|
(outs), (ins IntRegs:$rs1, IntRegs:$rs2),
|
||||||
"cmp $b, $c",
|
"cmp $rs1, $rs2",
|
||||||
[(SPcmpicc i32:$b, i32:$c)]>;
|
[(SPcmpicc i32:$rs1, i32:$rs2)]>;
|
||||||
def CMPri : F3_2<2, 0b010100,
|
def CMPri : F3_2<2, 0b010100,
|
||||||
(outs), (ins IntRegs:$b, i32imm:$c),
|
(outs), (ins IntRegs:$rs1, i32imm:$simm13),
|
||||||
"cmp $b, $c",
|
"cmp $rs1, $simm13",
|
||||||
[(SPcmpicc i32:$b, (i32 simm13:$c))]>;
|
[(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
|
// Section B.18 - Multiply Instructions, p. 113
|
||||||
let Defs = [Y] in {
|
let Defs = [Y] in {
|
||||||
defm UMUL : F3_12np<"umul", 0b001010>;
|
defm UMUL : F3_12np<"umul", 0b001010>;
|
||||||
@ -858,7 +852,7 @@ let Defs = [FCC] in {
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Instructions for Thread Local Storage(TLS).
|
// Instructions for Thread Local Storage(TLS).
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
let isCodeGenOnly = 1, isAsmParserOnly = 1 in {
|
||||||
def TLS_ADDrr : F3_1<2, 0b000000,
|
def TLS_ADDrr : F3_1<2, 0b000000,
|
||||||
(outs IntRegs:$rd),
|
(outs IntRegs:$rd),
|
||||||
(ins IntRegs:$rs1, IntRegs:$rs2, TLSSym:$sym),
|
(ins IntRegs:$rs1, IntRegs:$rs2, TLSSym:$sym),
|
||||||
@ -882,6 +876,7 @@ let Uses = [O6], isCall = 1, hasDelaySlot = 1 in
|
|||||||
let op = 1;
|
let op = 1;
|
||||||
let Inst{29-0} = disp;
|
let Inst{29-0} = disp;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// V9 Instructions
|
// V9 Instructions
|
||||||
|
4
test/MC/Disassembler/Sparc/lit.local.cfg
Normal file
4
test/MC/Disassembler/Sparc/lit.local.cfg
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
targets = set(config.root.targets_to_build.split())
|
||||||
|
if not 'Sparc' in targets:
|
||||||
|
config.unsupported = True
|
||||||
|
|
82
test/MC/Disassembler/Sparc/sparc.txt
Normal file
82
test/MC/Disassembler/Sparc/sparc.txt
Normal file
@ -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
|
Loading…
x
Reference in New Issue
Block a user