blob: fc7fbf98f5969eb7532a36094c047c91b598fdcc [file] [log] [blame]
Richard Sandifordeb9af292013-05-14 10:17:52 +00001//===-- SystemZDisassembler.cpp - Disassembler for SystemZ ------*- 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#include "SystemZ.h"
11#include "llvm/MC/MCDisassembler.h"
12#include "llvm/MC/MCFixedLenDisassembler.h"
13#include "llvm/MC/MCInst.h"
14#include "llvm/MC/MCSubtargetInfo.h"
15#include "llvm/Support/MemoryObject.h"
16#include "llvm/Support/TargetRegistry.h"
17
18using namespace llvm;
19
20typedef MCDisassembler::DecodeStatus DecodeStatus;
21
22namespace {
23class SystemZDisassembler : public MCDisassembler {
24public:
25 SystemZDisassembler(const MCSubtargetInfo &STI)
26 : MCDisassembler(STI) {}
27 virtual ~SystemZDisassembler() {}
28
29 // Override MCDisassembler.
30 virtual DecodeStatus getInstruction(MCInst &instr,
31 uint64_t &size,
32 const MemoryObject &region,
33 uint64_t address,
34 raw_ostream &vStream,
35 raw_ostream &cStream) const LLVM_OVERRIDE;
36};
37} // end anonymous namespace
38
39static MCDisassembler *createSystemZDisassembler(const Target &T,
40 const MCSubtargetInfo &STI) {
41 return new SystemZDisassembler(STI);
42}
43
44extern "C" void LLVMInitializeSystemZDisassembler() {
45 // Register the disassembler.
46 TargetRegistry::RegisterMCDisassembler(TheSystemZTarget,
47 createSystemZDisassembler);
48}
49
50static DecodeStatus decodeRegisterClass(MCInst &Inst, uint64_t RegNo,
51 const unsigned *Regs,
52 bool isAddress = false) {
53 assert(RegNo < 16 && "Invalid register");
54 if (!isAddress || RegNo) {
55 RegNo = Regs[RegNo];
56 if (RegNo == 0)
57 return MCDisassembler::Fail;
58 }
59 Inst.addOperand(MCOperand::CreateReg(RegNo));
60 return MCDisassembler::Success;
61}
62
63static DecodeStatus DecodeGR32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
64 uint64_t Address,
65 const void *Decoder) {
66 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR32Regs);
67}
68
Richard Sandifordf9496062013-09-30 10:45:16 +000069static DecodeStatus DecodeGRH32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
70 uint64_t Address,
71 const void *Decoder) {
72 return decodeRegisterClass(Inst, RegNo, SystemZMC::GRH32Regs);
73}
74
Richard Sandifordeb9af292013-05-14 10:17:52 +000075static DecodeStatus DecodeGR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
76 uint64_t Address,
77 const void *Decoder) {
78 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs);
79}
80
81static DecodeStatus DecodeGR128BitRegisterClass(MCInst &Inst, uint64_t RegNo,
82 uint64_t Address,
83 const void *Decoder) {
84 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR128Regs);
85}
86
87static DecodeStatus DecodeADDR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
88 uint64_t Address,
89 const void *Decoder) {
90 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs, true);
91}
92
93static DecodeStatus DecodeFP32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
94 uint64_t Address,
95 const void *Decoder) {
96 return decodeRegisterClass(Inst, RegNo, SystemZMC::FP32Regs);
97}
98
99static DecodeStatus DecodeFP64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
100 uint64_t Address,
101 const void *Decoder) {
102 return decodeRegisterClass(Inst, RegNo, SystemZMC::FP64Regs);
103}
104
105static DecodeStatus DecodeFP128BitRegisterClass(MCInst &Inst, uint64_t RegNo,
106 uint64_t Address,
107 const void *Decoder) {
108 return decodeRegisterClass(Inst, RegNo, SystemZMC::FP128Regs);
109}
110
111template<unsigned N>
112static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm) {
113 assert(isUInt<N>(Imm) && "Invalid immediate");
114 Inst.addOperand(MCOperand::CreateImm(Imm));
115 return MCDisassembler::Success;
116}
117
118template<unsigned N>
119static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm) {
120 assert(isUInt<N>(Imm) && "Invalid immediate");
121 Inst.addOperand(MCOperand::CreateImm(SignExtend64<N>(Imm)));
122 return MCDisassembler::Success;
123}
124
125static DecodeStatus decodeAccessRegOperand(MCInst &Inst, uint64_t Imm,
126 uint64_t Address,
127 const void *Decoder) {
128 return decodeUImmOperand<4>(Inst, Imm);
129}
130
131static DecodeStatus decodeU4ImmOperand(MCInst &Inst, uint64_t Imm,
132 uint64_t Address, const void *Decoder) {
133 return decodeUImmOperand<4>(Inst, Imm);
134}
135
136static DecodeStatus decodeU6ImmOperand(MCInst &Inst, uint64_t Imm,
137 uint64_t Address, const void *Decoder) {
138 return decodeUImmOperand<6>(Inst, Imm);
139}
140
141static DecodeStatus decodeU8ImmOperand(MCInst &Inst, uint64_t Imm,
142 uint64_t Address, const void *Decoder) {
143 return decodeUImmOperand<8>(Inst, Imm);
144}
145
146static DecodeStatus decodeU16ImmOperand(MCInst &Inst, uint64_t Imm,
147 uint64_t Address, const void *Decoder) {
148 return decodeUImmOperand<16>(Inst, Imm);
149}
150
151static DecodeStatus decodeU32ImmOperand(MCInst &Inst, uint64_t Imm,
152 uint64_t Address, const void *Decoder) {
153 return decodeUImmOperand<32>(Inst, Imm);
154}
155
156static DecodeStatus decodeS8ImmOperand(MCInst &Inst, uint64_t Imm,
157 uint64_t Address, const void *Decoder) {
158 return decodeSImmOperand<8>(Inst, Imm);
159}
160
161static DecodeStatus decodeS16ImmOperand(MCInst &Inst, uint64_t Imm,
162 uint64_t Address, const void *Decoder) {
163 return decodeSImmOperand<16>(Inst, Imm);
164}
165
166static DecodeStatus decodeS32ImmOperand(MCInst &Inst, uint64_t Imm,
167 uint64_t Address, const void *Decoder) {
168 return decodeSImmOperand<32>(Inst, Imm);
169}
170
171template<unsigned N>
172static DecodeStatus decodePCDBLOperand(MCInst &Inst, uint64_t Imm,
173 uint64_t Address) {
174 assert(isUInt<N>(Imm) && "Invalid PC-relative offset");
175 Inst.addOperand(MCOperand::CreateImm(SignExtend64<N>(Imm) * 2 + Address));
176 return MCDisassembler::Success;
177}
178
179static DecodeStatus decodePC16DBLOperand(MCInst &Inst, uint64_t Imm,
180 uint64_t Address,
181 const void *Decoder) {
182 return decodePCDBLOperand<16>(Inst, Imm, Address);
183}
184
185static DecodeStatus decodePC32DBLOperand(MCInst &Inst, uint64_t Imm,
186 uint64_t Address,
187 const void *Decoder) {
188 return decodePCDBLOperand<32>(Inst, Imm, Address);
189}
190
191static DecodeStatus decodeBDAddr12Operand(MCInst &Inst, uint64_t Field,
192 const unsigned *Regs) {
193 uint64_t Base = Field >> 12;
194 uint64_t Disp = Field & 0xfff;
195 assert(Base < 16 && "Invalid BDAddr12");
196 Inst.addOperand(MCOperand::CreateReg(Base == 0 ? 0 : Regs[Base]));
197 Inst.addOperand(MCOperand::CreateImm(Disp));
198 return MCDisassembler::Success;
199}
200
201static DecodeStatus decodeBDAddr20Operand(MCInst &Inst, uint64_t Field,
202 const unsigned *Regs) {
203 uint64_t Base = Field >> 20;
204 uint64_t Disp = ((Field << 12) & 0xff000) | ((Field >> 8) & 0xfff);
205 assert(Base < 16 && "Invalid BDAddr20");
206 Inst.addOperand(MCOperand::CreateReg(Base == 0 ? 0 : Regs[Base]));
207 Inst.addOperand(MCOperand::CreateImm(SignExtend64<20>(Disp)));
208 return MCDisassembler::Success;
209}
210
211static DecodeStatus decodeBDXAddr12Operand(MCInst &Inst, uint64_t Field,
212 const unsigned *Regs) {
213 uint64_t Index = Field >> 16;
214 uint64_t Base = (Field >> 12) & 0xf;
215 uint64_t Disp = Field & 0xfff;
216 assert(Index < 16 && "Invalid BDXAddr12");
217 Inst.addOperand(MCOperand::CreateReg(Base == 0 ? 0 : Regs[Base]));
218 Inst.addOperand(MCOperand::CreateImm(Disp));
219 Inst.addOperand(MCOperand::CreateReg(Index == 0 ? 0 : Regs[Index]));
220 return MCDisassembler::Success;
221}
222
223static DecodeStatus decodeBDXAddr20Operand(MCInst &Inst, uint64_t Field,
224 const unsigned *Regs) {
225 uint64_t Index = Field >> 24;
226 uint64_t Base = (Field >> 20) & 0xf;
227 uint64_t Disp = ((Field & 0xfff00) >> 8) | ((Field & 0xff) << 12);
228 assert(Index < 16 && "Invalid BDXAddr20");
229 Inst.addOperand(MCOperand::CreateReg(Base == 0 ? 0 : Regs[Base]));
230 Inst.addOperand(MCOperand::CreateImm(SignExtend64<20>(Disp)));
231 Inst.addOperand(MCOperand::CreateReg(Index == 0 ? 0 : Regs[Index]));
232 return MCDisassembler::Success;
233}
234
Richard Sandiford1d959002013-07-02 14:56:45 +0000235static DecodeStatus decodeBDLAddr12Len8Operand(MCInst &Inst, uint64_t Field,
236 const unsigned *Regs) {
237 uint64_t Length = Field >> 16;
238 uint64_t Base = (Field >> 12) & 0xf;
239 uint64_t Disp = Field & 0xfff;
240 assert(Length < 256 && "Invalid BDLAddr12Len8");
241 Inst.addOperand(MCOperand::CreateReg(Base == 0 ? 0 : Regs[Base]));
242 Inst.addOperand(MCOperand::CreateImm(Disp));
243 Inst.addOperand(MCOperand::CreateImm(Length + 1));
244 return MCDisassembler::Success;
245}
246
Richard Sandifordeb9af292013-05-14 10:17:52 +0000247static DecodeStatus decodeBDAddr32Disp12Operand(MCInst &Inst, uint64_t Field,
248 uint64_t Address,
249 const void *Decoder) {
250 return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR32Regs);
251}
252
253static DecodeStatus decodeBDAddr32Disp20Operand(MCInst &Inst, uint64_t Field,
254 uint64_t Address,
255 const void *Decoder) {
256 return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR32Regs);
257}
258
259static DecodeStatus decodeBDAddr64Disp12Operand(MCInst &Inst, uint64_t Field,
260 uint64_t Address,
261 const void *Decoder) {
262 return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
263}
264
265static DecodeStatus decodeBDAddr64Disp20Operand(MCInst &Inst, uint64_t Field,
266 uint64_t Address,
267 const void *Decoder) {
268 return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR64Regs);
269}
270
271static DecodeStatus decodeBDXAddr64Disp12Operand(MCInst &Inst, uint64_t Field,
272 uint64_t Address,
273 const void *Decoder) {
274 return decodeBDXAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
275}
276
277static DecodeStatus decodeBDXAddr64Disp20Operand(MCInst &Inst, uint64_t Field,
278 uint64_t Address,
279 const void *Decoder) {
280 return decodeBDXAddr20Operand(Inst, Field, SystemZMC::GR64Regs);
281}
282
Richard Sandiford1d959002013-07-02 14:56:45 +0000283static DecodeStatus decodeBDLAddr64Disp12Len8Operand(MCInst &Inst,
284 uint64_t Field,
285 uint64_t Address,
286 const void *Decoder) {
287 return decodeBDLAddr12Len8Operand(Inst, Field, SystemZMC::GR64Regs);
288}
289
Richard Sandifordeb9af292013-05-14 10:17:52 +0000290#include "SystemZGenDisassemblerTables.inc"
291
292DecodeStatus SystemZDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
293 const MemoryObject &Region,
294 uint64_t Address,
295 raw_ostream &os,
296 raw_ostream &cs) const {
297 // Get the first two bytes of the instruction.
298 uint8_t Bytes[6];
299 Size = 0;
Benjamin Kramer534d3a42013-05-24 10:54:58 +0000300 if (Region.readBytes(Address, 2, Bytes) == -1)
Richard Sandifordeb9af292013-05-14 10:17:52 +0000301 return MCDisassembler::Fail;
302
303 // The top 2 bits of the first byte specify the size.
304 const uint8_t *Table;
305 if (Bytes[0] < 0x40) {
306 Size = 2;
307 Table = DecoderTable16;
308 } else if (Bytes[0] < 0xc0) {
309 Size = 4;
310 Table = DecoderTable32;
311 } else {
312 Size = 6;
313 Table = DecoderTable48;
314 }
315
316 // Read any remaining bytes.
Benjamin Kramer534d3a42013-05-24 10:54:58 +0000317 if (Size > 2 && Region.readBytes(Address + 2, Size - 2, Bytes + 2) == -1)
Richard Sandifordeb9af292013-05-14 10:17:52 +0000318 return MCDisassembler::Fail;
319
320 // Construct the instruction.
321 uint64_t Inst = 0;
322 for (uint64_t I = 0; I < Size; ++I)
323 Inst = (Inst << 8) | Bytes[I];
324
325 return decodeInstruction(Table, MI, Inst, Address, this, STI);
326}