Skip to content

Commit dfcccc7

Browse files
committedJan 6, 2014
[Sparc] Add initial implementation of disassembler for sparc
llvm-svn: 198591
1 parent a45a176 commit dfcccc7

File tree

12 files changed

+457
-61
lines changed

12 files changed

+457
-61
lines changed
 

‎llvm/lib/Target/Sparc/CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ set(LLVM_TARGET_DEFINITIONS Sparc.td)
33
tablegen(LLVM SparcGenRegisterInfo.inc -gen-register-info)
44
tablegen(LLVM SparcGenInstrInfo.inc -gen-instr-info)
55
tablegen(LLVM SparcGenCodeEmitter.inc -gen-emitter)
6+
tablegen(LLVM SparcGenDisassemblerTables.inc -gen-disassembler)
67
tablegen(LLVM SparcGenMCCodeEmitter.inc -gen-emitter -mc-emitter)
78
tablegen(LLVM SparcGenAsmWriter.inc -gen-asm-writer)
89
tablegen(LLVM SparcGenAsmMatcher.inc -gen-asm-matcher)
@@ -32,3 +33,4 @@ add_subdirectory(TargetInfo)
3233
add_subdirectory(MCTargetDesc)
3334
add_subdirectory(InstPrinter)
3435
add_subdirectory(AsmParser)
36+
add_subdirectory(Disassembler)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
add_llvm_library(LLVMSparcDisassembler
2+
SparcDisassembler.cpp
3+
)
4+
5+
# workaround for hanging compilation on MSVC9 and 10
6+
if( MSVC_VERSION EQUAL 1400 OR MSVC_VERSION EQUAL 1500
7+
OR MSVC_VERSION EQUAL 1600 )
8+
set_property(
9+
SOURCE SparcDisassembler.cpp
10+
PROPERTY COMPILE_FLAGS "/Od"
11+
)
12+
endif()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
;===- ./lib/Target/Sparc/Disassembler/LLVMBuild.txt ------------*- Conf -*--===;
2+
;
3+
; The LLVM Compiler Infrastructure
4+
;
5+
; This file is distributed under the University of Illinois Open Source
6+
; License. See LICENSE.TXT for details.
7+
;
8+
;===------------------------------------------------------------------------===;
9+
;
10+
; This is an LLVMBuild description file for the components in this subdirectory.
11+
;
12+
; For more information on the LLVMBuild system, please see:
13+
;
14+
; http://llvm.org/docs/LLVMBuild.html
15+
;
16+
;===------------------------------------------------------------------------===;
17+
18+
[component_0]
19+
type = Library
20+
name = SparcDisassembler
21+
parent = Sparc
22+
required_libraries = MC Support SparcInfo
23+
add_to_library_groups = Sparc
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
##===- lib/Target/Sparc/Disassembler/Makefile --------------*- Makefile -*-===##
2+
#
3+
# The LLVM Compiler Infrastructure
4+
#
5+
# This file is distributed under the University of Illinois Open Source
6+
# License. See LICENSE.TXT for details.
7+
#
8+
##===----------------------------------------------------------------------===##
9+
10+
LEVEL = ../../../..
11+
LIBRARYNAME = LLVMSparcDisassembler
12+
13+
# Hack: we need to include 'main' Sparc target directory to grab private headers
14+
CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
15+
16+
include $(LEVEL)/Makefile.common
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
1+
//===- SparcDisassembler.cpp - Disassembler for Sparc -----------*- C++ -*-===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
//
10+
// This file is part of the Sparc Disassembler.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
#define DEBUG_TYPE "sparc-disassembler"
15+
16+
#include "Sparc.h"
17+
#include "SparcRegisterInfo.h"
18+
#include "SparcSubtarget.h"
19+
#include "llvm/MC/MCDisassembler.h"
20+
#include "llvm/MC/MCFixedLenDisassembler.h"
21+
#include "llvm/Support/MemoryObject.h"
22+
#include "llvm/Support/TargetRegistry.h"
23+
24+
using namespace llvm;
25+
26+
typedef MCDisassembler::DecodeStatus DecodeStatus;
27+
28+
namespace {
29+
30+
/// SparcDisassembler - a disassembler class for Sparc.
31+
class SparcDisassembler : public MCDisassembler {
32+
public:
33+
/// Constructor - Initializes the disassembler.
34+
///
35+
SparcDisassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info) :
36+
MCDisassembler(STI), RegInfo(Info)
37+
{}
38+
virtual ~SparcDisassembler() {}
39+
40+
const MCRegisterInfo *getRegInfo() const { return RegInfo.get(); }
41+
42+
/// getInstruction - See MCDisassembler.
43+
virtual DecodeStatus getInstruction(MCInst &instr,
44+
uint64_t &size,
45+
const MemoryObject &region,
46+
uint64_t address,
47+
raw_ostream &vStream,
48+
raw_ostream &cStream) const;
49+
private:
50+
OwningPtr<const MCRegisterInfo> RegInfo;
51+
};
52+
53+
}
54+
55+
namespace llvm {
56+
extern Target TheSparcTarget, TheSparcV9Target;
57+
}
58+
59+
static MCDisassembler *createSparcDisassembler(
60+
const Target &T,
61+
const MCSubtargetInfo &STI) {
62+
return new SparcDisassembler(STI, T.createMCRegInfo(""));
63+
}
64+
65+
66+
extern "C" void LLVMInitializeSparcDisassembler() {
67+
// Register the disassembler.
68+
TargetRegistry::RegisterMCDisassembler(TheSparcTarget,
69+
createSparcDisassembler);
70+
TargetRegistry::RegisterMCDisassembler(TheSparcV9Target,
71+
createSparcDisassembler);
72+
}
73+
74+
75+
76+
static const unsigned IntRegDecoderTable[] = {
77+
SP::G0, SP::G1, SP::G2, SP::G3,
78+
SP::G4, SP::G5, SP::G6, SP::G7,
79+
SP::O0, SP::O1, SP::O2, SP::O3,
80+
SP::O4, SP::O5, SP::O6, SP::O7,
81+
SP::L0, SP::L1, SP::L2, SP::L3,
82+
SP::L4, SP::L5, SP::L6, SP::L7,
83+
SP::I0, SP::I1, SP::I2, SP::I3,
84+
SP::I4, SP::I5, SP::I6, SP::I7 };
85+
86+
static const unsigned FPRegDecoderTable[] = {
87+
SP::F0, SP::F1, SP::F2, SP::F3,
88+
SP::F4, SP::F5, SP::F6, SP::F7,
89+
SP::F8, SP::F9, SP::F10, SP::F11,
90+
SP::F12, SP::F13, SP::F14, SP::F15,
91+
SP::F16, SP::F17, SP::F18, SP::F19,
92+
SP::F20, SP::F21, SP::F22, SP::F23,
93+
SP::F24, SP::F25, SP::F26, SP::F27,
94+
SP::F28, SP::F29, SP::F30, SP::F31 };
95+
96+
static const unsigned DFPRegDecoderTable[] = {
97+
SP::D0, SP::D16, SP::D1, SP::D17,
98+
SP::D2, SP::D18, SP::D3, SP::D19,
99+
SP::D4, SP::D20, SP::D5, SP::D21,
100+
SP::D6, SP::D22, SP::D7, SP::D23,
101+
SP::D8, SP::D24, SP::D9, SP::D25,
102+
SP::D10, SP::D26, SP::D11, SP::D27,
103+
SP::D12, SP::D28, SP::D13, SP::D29,
104+
SP::D14, SP::D30, SP::D15, SP::D31 };
105+
106+
static const unsigned QFPRegDecoderTable[] = {
107+
SP::Q0, SP::Q8, -1, -1,
108+
SP::Q1, SP::Q9, -1, -1,
109+
SP::Q2, SP::Q10, -1, -1,
110+
SP::Q3, SP::Q11, -1, -1,
111+
SP::Q4, SP::Q12, -1, -1,
112+
SP::Q5, SP::Q13, -1, -1,
113+
SP::Q6, SP::Q14, -1, -1,
114+
SP::Q7, SP::Q15, -1, -1 } ;
115+
116+
static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst,
117+
unsigned RegNo,
118+
uint64_t Address,
119+
const void *Decoder) {
120+
if (RegNo > 31)
121+
return MCDisassembler::Fail;
122+
unsigned Reg = IntRegDecoderTable[RegNo];
123+
Inst.addOperand(MCOperand::CreateReg(Reg));
124+
return MCDisassembler::Success;
125+
}
126+
127+
static DecodeStatus DecodeI64RegsRegisterClass(MCInst &Inst,
128+
unsigned RegNo,
129+
uint64_t Address,
130+
const void *Decoder) {
131+
if (RegNo > 31)
132+
return MCDisassembler::Fail;
133+
unsigned Reg = IntRegDecoderTable[RegNo];
134+
Inst.addOperand(MCOperand::CreateReg(Reg));
135+
return MCDisassembler::Success;
136+
}
137+
138+
139+
static DecodeStatus DecodeFPRegsRegisterClass(MCInst &Inst,
140+
unsigned RegNo,
141+
uint64_t Address,
142+
const void *Decoder) {
143+
if (RegNo > 31)
144+
return MCDisassembler::Fail;
145+
unsigned Reg = FPRegDecoderTable[RegNo];
146+
Inst.addOperand(MCOperand::CreateReg(Reg));
147+
return MCDisassembler::Success;
148+
}
149+
150+
151+
static DecodeStatus DecodeDFPRegsRegisterClass(MCInst &Inst,
152+
unsigned RegNo,
153+
uint64_t Address,
154+
const void *Decoder) {
155+
if (RegNo > 31)
156+
return MCDisassembler::Fail;
157+
unsigned Reg = DFPRegDecoderTable[RegNo];
158+
Inst.addOperand(MCOperand::CreateReg(Reg));
159+
return MCDisassembler::Success;
160+
}
161+
162+
163+
static DecodeStatus DecodeQFPRegsRegisterClass(MCInst &Inst,
164+
unsigned RegNo,
165+
uint64_t Address,
166+
const void *Decoder) {
167+
if (RegNo > 31)
168+
return MCDisassembler::Fail;
169+
170+
unsigned Reg = QFPRegDecoderTable[RegNo];
171+
if (Reg == (unsigned)-1)
172+
return MCDisassembler::Fail;
173+
Inst.addOperand(MCOperand::CreateReg(Reg));
174+
return MCDisassembler::Success;
175+
}
176+
177+
178+
#include "SparcGenDisassemblerTables.inc"
179+
180+
/// readInstruction - read four bytes from the MemoryObject
181+
/// and return 32 bit word.
182+
static DecodeStatus readInstruction32(const MemoryObject &region,
183+
uint64_t address,
184+
uint64_t &size,
185+
uint32_t &insn) {
186+
uint8_t Bytes[4];
187+
188+
// We want to read exactly 4 Bytes of data.
189+
if (region.readBytes(address, 4, Bytes) == -1) {
190+
size = 0;
191+
return MCDisassembler::Fail;
192+
}
193+
194+
// Encoded as a big-endian 32-bit word in the stream.
195+
insn = (Bytes[3] << 0) |
196+
(Bytes[2] << 8) |
197+
(Bytes[1] << 16) |
198+
(Bytes[0] << 24);
199+
200+
return MCDisassembler::Success;
201+
}
202+
203+
204+
DecodeStatus
205+
SparcDisassembler::getInstruction(MCInst &instr,
206+
uint64_t &Size,
207+
const MemoryObject &Region,
208+
uint64_t Address,
209+
raw_ostream &vStream,
210+
raw_ostream &cStream) const {
211+
uint32_t Insn;
212+
213+
DecodeStatus Result = readInstruction32(Region, Address, Size, Insn);
214+
if (Result == MCDisassembler::Fail)
215+
return MCDisassembler::Fail;
216+
217+
218+
// Calling the auto-generated decoder function.
219+
Result = decodeInstruction(DecoderTableSparc32, instr, Insn, Address,
220+
this, STI);
221+
222+
if (Result != MCDisassembler::Fail) {
223+
Size = 4;
224+
return Result;
225+
}
226+
227+
return MCDisassembler::Fail;
228+
}

‎llvm/lib/Target/Sparc/LLVMBuild.txt

+3-1
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,15 @@
1616
;===------------------------------------------------------------------------===;
1717

1818
[common]
19-
subdirectories = AsmParser InstPrinter MCTargetDesc TargetInfo
19+
subdirectories = AsmParser Disassembler InstPrinter MCTargetDesc TargetInfo
2020

2121
[component_0]
2222
type = TargetGroup
2323
name = Sparc
2424
parent = Target
25+
has_asmparser = 1
2526
has_asmprinter = 1
27+
has_disassembler = 1
2628
has_jit = 1
2729

2830
[component_1]

‎llvm/lib/Target/Sparc/Makefile

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ TARGET = Sparc
1414
# Make sure that tblgen is run, first thing.
1515
BUILT_SOURCES = SparcGenRegisterInfo.inc SparcGenInstrInfo.inc \
1616
SparcGenAsmWriter.inc SparcGenAsmMatcher.inc \
17-
SparcGenDAGISel.inc \
17+
SparcGenDAGISel.inc SparcGenDisassemblerTables.inc \
1818
SparcGenSubtargetInfo.inc SparcGenCallingConv.inc \
1919
SparcGenCodeEmitter.inc SparcGenMCCodeEmitter.inc
2020

21-
DIRS = InstPrinter AsmParser TargetInfo MCTargetDesc
21+
DIRS = InstPrinter AsmParser Disassembler TargetInfo MCTargetDesc
2222

2323
include $(LEVEL)/Makefile.common
2424

0 commit comments

Comments
 (0)
Please sign in to comment.