blob: e9db9ec3c18afd549d66cae2939dd46d4817bedd [file] [log] [blame]
Nguyen Anh Quynh48a14ca2014-03-23 08:35:45 +08001//===------ SystemZDisassembler.cpp - Disassembler for PowerPC ------*- 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/* Capstone Disassembly Engine */
Nguyen Anh Quynhbfcaba52015-03-04 17:45:23 +080011/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
Nguyen Anh Quynh48a14ca2014-03-23 08:35:45 +080012
Nguyen Anh Quynh8598a212014-05-14 11:26:41 +080013#ifdef CAPSTONE_HAS_SYSZ
14
Nguyen Anh Quynh48a14ca2014-03-23 08:35:45 +080015#include <stdio.h> // DEBUG
16#include <stdlib.h>
17#include <string.h>
18
19#include "../../cs_priv.h"
Nguyen Anh Quynh69582d72014-06-09 17:50:01 +070020#include "../../utils.h"
Nguyen Anh Quynh48a14ca2014-03-23 08:35:45 +080021
Nguyen Anh Quynh48a14ca2014-03-23 08:35:45 +080022#include "../../MCInst.h"
23#include "../../MCInstrDesc.h"
24#include "../../MCFixedLenDisassembler.h"
25#include "../../MCRegisterInfo.h"
26#include "../../MCDisassembler.h"
27#include "../../MathExtras.h"
28
29#include "SystemZMCTargetDesc.h"
30
31static uint64_t getFeatureBits(int mode)
32{
33 // support everything
34 return (uint64_t)-1;
35}
36
37static DecodeStatus decodeRegisterClass(MCInst *Inst, uint64_t RegNo, const unsigned *Regs)
38{
39 //assert(RegNo < 16 && "Invalid register");
40 RegNo = Regs[RegNo];
41 if (RegNo == 0)
42 return MCDisassembler_Fail;
43
Nguyen Anh Quynh70629882014-06-16 13:09:15 +080044 MCOperand_CreateReg0(Inst, (unsigned)RegNo);
Nguyen Anh Quynh48a14ca2014-03-23 08:35:45 +080045 return MCDisassembler_Success;
46}
47
48static DecodeStatus DecodeGR32BitRegisterClass(MCInst *Inst, uint64_t RegNo,
49 uint64_t Address, const void *Decoder)
50{
51 return decodeRegisterClass(Inst, RegNo, SystemZMC_GR32Regs);
52}
53
54static DecodeStatus DecodeGRH32BitRegisterClass(MCInst *Inst, uint64_t RegNo,
55 uint64_t Address, const void *Decoder)
56{
57 return decodeRegisterClass(Inst, RegNo, SystemZMC_GRH32Regs);
58}
59
60static DecodeStatus DecodeGR64BitRegisterClass(MCInst *Inst, uint64_t RegNo,
61 uint64_t Address, const void *Decoder)
62{
63 return decodeRegisterClass(Inst, RegNo, SystemZMC_GR64Regs);
64}
65
66static DecodeStatus DecodeGR128BitRegisterClass(MCInst *Inst, uint64_t RegNo,
67 uint64_t Address, const void *Decoder)
68{
69 return decodeRegisterClass(Inst, RegNo, SystemZMC_GR128Regs);
70}
71
72static DecodeStatus DecodeADDR64BitRegisterClass(MCInst *Inst, uint64_t RegNo,
73 uint64_t Address, const void *Decoder)
74{
75 return decodeRegisterClass(Inst, RegNo, SystemZMC_GR64Regs);
76}
77
78static DecodeStatus DecodeFP32BitRegisterClass(MCInst *Inst, uint64_t RegNo,
79 uint64_t Address, const void *Decoder)
80{
81 return decodeRegisterClass(Inst, RegNo, SystemZMC_FP32Regs);
82}
83
84static DecodeStatus DecodeFP64BitRegisterClass(MCInst *Inst, uint64_t RegNo,
85 uint64_t Address, const void *Decoder)
86{
87 return decodeRegisterClass(Inst, RegNo, SystemZMC_FP64Regs);
88}
89
90static DecodeStatus DecodeFP128BitRegisterClass(MCInst *Inst, uint64_t RegNo,
91 uint64_t Address, const void *Decoder)
92{
93 return decodeRegisterClass(Inst, RegNo, SystemZMC_FP128Regs);
94}
95
96static DecodeStatus decodeUImmOperand(MCInst *Inst, uint64_t Imm)
97{
98 //assert(isUInt<N>(Imm) && "Invalid immediate");
Nguyen Anh Quynh70629882014-06-16 13:09:15 +080099 MCOperand_CreateImm0(Inst, Imm);
Nguyen Anh Quynh48a14ca2014-03-23 08:35:45 +0800100 return MCDisassembler_Success;
101}
102
103static DecodeStatus decodeSImmOperand(MCInst *Inst, uint64_t Imm, unsigned N)
104{
105 //assert(isUInt<N>(Imm) && "Invalid immediate");
Nguyen Anh Quynh70629882014-06-16 13:09:15 +0800106 MCOperand_CreateImm0(Inst, SignExtend64(Imm, N));
Nguyen Anh Quynh48a14ca2014-03-23 08:35:45 +0800107 return MCDisassembler_Success;
108}
109
110static DecodeStatus decodeAccessRegOperand(MCInst *Inst, uint64_t Imm,
111 uint64_t Address, const void *Decoder)
112{
113 return decodeUImmOperand(Inst, Imm);
114}
115
116static DecodeStatus decodeU4ImmOperand(MCInst *Inst, uint64_t Imm,
117 uint64_t Address, const void *Decoder)
118{
119 return decodeUImmOperand(Inst, Imm);
120}
121
122static DecodeStatus decodeU6ImmOperand(MCInst *Inst, uint64_t Imm,
123 uint64_t Address, const void *Decoder)
124{
125 return decodeUImmOperand(Inst, Imm);
126}
127
128static DecodeStatus decodeU8ImmOperand(MCInst *Inst, uint64_t Imm,
129 uint64_t Address, const void *Decoder)
130{
131 return decodeUImmOperand(Inst, Imm);
132}
133
134static DecodeStatus decodeU16ImmOperand(MCInst *Inst, uint64_t Imm,
135 uint64_t Address, const void *Decoder)
136{
137 return decodeUImmOperand(Inst, Imm);
138}
139
140static DecodeStatus decodeU32ImmOperand(MCInst *Inst, uint64_t Imm,
141 uint64_t Address, const void *Decoder)
142{
143 return decodeUImmOperand(Inst, Imm);
144}
145
146static DecodeStatus decodeS8ImmOperand(MCInst *Inst, uint64_t Imm,
147 uint64_t Address, const void *Decoder)
148{
149 return decodeSImmOperand(Inst, Imm, 8);
150}
151
152static DecodeStatus decodeS16ImmOperand(MCInst *Inst, uint64_t Imm,
153 uint64_t Address, const void *Decoder)
154{
155 return decodeSImmOperand(Inst, Imm, 16);
156}
157
158static DecodeStatus decodeS32ImmOperand(MCInst *Inst, uint64_t Imm,
159 uint64_t Address, const void *Decoder)
160{
161 return decodeSImmOperand(Inst, Imm, 32);
162}
163
164static DecodeStatus decodePCDBLOperand(MCInst *Inst, uint64_t Imm,
165 uint64_t Address, unsigned N)
166{
167 //assert(isUInt<N>(Imm) && "Invalid PC-relative offset");
Nguyen Anh Quynh70629882014-06-16 13:09:15 +0800168 MCOperand_CreateImm0(Inst, SignExtend64(Imm, N) * 2 + Address);
Nguyen Anh Quynh48a14ca2014-03-23 08:35:45 +0800169 return MCDisassembler_Success;
170}
171
172static DecodeStatus decodePC16DBLOperand(MCInst *Inst, uint64_t Imm,
173 uint64_t Address, const void *Decoder)
174{
175 return decodePCDBLOperand(Inst, Imm, Address, 16);
176}
177
178static DecodeStatus decodePC32DBLOperand(MCInst *Inst, uint64_t Imm,
179 uint64_t Address,
180 const void *Decoder)
181{
182 return decodePCDBLOperand(Inst, Imm, Address, 32);
183}
184
185static DecodeStatus decodeBDAddr12Operand(MCInst *Inst, uint64_t Field,
186 const unsigned *Regs)
187{
188 uint64_t Base = Field >> 12;
189 uint64_t Disp = Field & 0xfff;
190 //assert(Base < 16 && "Invalid BDAddr12");
191
Nguyen Anh Quynh70629882014-06-16 13:09:15 +0800192 MCOperand_CreateReg0(Inst, Base == 0 ? 0 : Regs[Base]);
193 MCOperand_CreateImm0(Inst, Disp);
Nguyen Anh Quynh48a14ca2014-03-23 08:35:45 +0800194
195 return MCDisassembler_Success;
196}
197
198static DecodeStatus decodeBDAddr20Operand(MCInst *Inst, uint64_t Field,
199 const unsigned *Regs)
200{
201 uint64_t Base = Field >> 20;
202 uint64_t Disp = ((Field << 12) & 0xff000) | ((Field >> 8) & 0xfff);
203 //assert(Base < 16 && "Invalid BDAddr20");
204
Nguyen Anh Quynh70629882014-06-16 13:09:15 +0800205 MCOperand_CreateReg0(Inst, Base == 0 ? 0 : Regs[Base]);
206 MCOperand_CreateImm0(Inst, SignExtend64(Disp, 20));
Nguyen Anh Quynh48a14ca2014-03-23 08:35:45 +0800207 return MCDisassembler_Success;
208}
209
210static DecodeStatus decodeBDXAddr12Operand(MCInst *Inst, uint64_t Field,
211 const unsigned *Regs)
212{
213 uint64_t Index = Field >> 16;
214 uint64_t Base = (Field >> 12) & 0xf;
215 uint64_t Disp = Field & 0xfff;
216
217 //assert(Index < 16 && "Invalid BDXAddr12");
Nguyen Anh Quynh70629882014-06-16 13:09:15 +0800218 MCOperand_CreateReg0(Inst, Base == 0 ? 0 : Regs[Base]);
219 MCOperand_CreateImm0(Inst, Disp);
220 MCOperand_CreateReg0(Inst, Index == 0 ? 0 : Regs[Index]);
Nguyen Anh Quynh48a14ca2014-03-23 08:35:45 +0800221
222 return MCDisassembler_Success;
223}
224
225static DecodeStatus decodeBDXAddr20Operand(MCInst *Inst, uint64_t Field,
226 const unsigned *Regs)
227{
228 uint64_t Index = Field >> 24;
229 uint64_t Base = (Field >> 20) & 0xf;
230 uint64_t Disp = ((Field & 0xfff00) >> 8) | ((Field & 0xff) << 12);
231
232 //assert(Index < 16 && "Invalid BDXAddr20");
Nguyen Anh Quynh70629882014-06-16 13:09:15 +0800233 MCOperand_CreateReg0(Inst, Base == 0 ? 0 : Regs[Base]);
234 MCOperand_CreateImm0(Inst, SignExtend64(Disp, 20));
235 MCOperand_CreateReg0(Inst, Index == 0 ? 0 : Regs[Index]);
Nguyen Anh Quynh48a14ca2014-03-23 08:35:45 +0800236
237 return MCDisassembler_Success;
238}
239
240static DecodeStatus decodeBDLAddr12Len8Operand(MCInst *Inst, uint64_t Field,
241 const unsigned *Regs)
242{
243 uint64_t Length = Field >> 16;
244 uint64_t Base = (Field >> 12) & 0xf;
245 uint64_t Disp = Field & 0xfff;
246 //assert(Length < 256 && "Invalid BDLAddr12Len8");
247
Nguyen Anh Quynh70629882014-06-16 13:09:15 +0800248 MCOperand_CreateReg0(Inst, Base == 0 ? 0 : Regs[Base]);
249 MCOperand_CreateImm0(Inst, Disp);
250 MCOperand_CreateImm0(Inst, Length + 1);
Nguyen Anh Quynh48a14ca2014-03-23 08:35:45 +0800251
252 return MCDisassembler_Success;
253}
254
255static DecodeStatus decodeBDAddr32Disp12Operand(MCInst *Inst, uint64_t Field,
256 uint64_t Address, const void *Decoder)
257{
258 return decodeBDAddr12Operand(Inst, Field, SystemZMC_GR32Regs);
259}
260
261static DecodeStatus decodeBDAddr32Disp20Operand(MCInst *Inst, uint64_t Field,
262 uint64_t Address, const void *Decoder)
263{
264 return decodeBDAddr20Operand(Inst, Field, SystemZMC_GR32Regs);
265}
266
267static DecodeStatus decodeBDAddr64Disp12Operand(MCInst *Inst, uint64_t Field,
268 uint64_t Address, const void *Decoder)
269{
270 return decodeBDAddr12Operand(Inst, Field, SystemZMC_GR64Regs);
271}
272
273static DecodeStatus decodeBDAddr64Disp20Operand(MCInst *Inst, uint64_t Field,
274 uint64_t Address, const void *Decoder)
275{
276 return decodeBDAddr20Operand(Inst, Field, SystemZMC_GR64Regs);
277}
278
279static DecodeStatus decodeBDXAddr64Disp12Operand(MCInst *Inst, uint64_t Field,
280 uint64_t Address, const void *Decoder)
281{
282 return decodeBDXAddr12Operand(Inst, Field, SystemZMC_GR64Regs);
283}
284
285static DecodeStatus decodeBDXAddr64Disp20Operand(MCInst *Inst, uint64_t Field,
286 uint64_t Address, const void *Decoder)
287{
288 return decodeBDXAddr20Operand(Inst, Field, SystemZMC_GR64Regs);
289}
290
291static DecodeStatus decodeBDLAddr64Disp12Len8Operand(MCInst *Inst, uint64_t Field,
292 uint64_t Address, const void *Decoder)
293{
294 return decodeBDLAddr12Len8Operand(Inst, Field, SystemZMC_GR64Regs);
295}
296
297#define GET_SUBTARGETINFO_ENUM
298#include "SystemZGenSubtargetInfo.inc"
299#include "SystemZGenDisassemblerTables.inc"
Nguyen Anh Quynha5ffdc32014-05-07 08:25:24 +0800300bool SystemZ_getInstruction(csh ud, const uint8_t *code, size_t code_len, MCInst *MI,
Nguyen Anh Quynh48a14ca2014-03-23 08:35:45 +0800301 uint16_t *size, uint64_t address, void *info)
302{
303 uint64_t Inst;
Nguyen Anh Quynh48a14ca2014-03-23 08:35:45 +0800304 uint8_t *Table;
305 uint16_t I;
306
307 // The top 2 bits of the first byte specify the size.
308 if (*code < 0x40) {
309 *size = 2;
310 Table = DecoderTable16;
311 } else if (*code < 0xc0) {
312 *size = 4;
313 Table = DecoderTable32;
314 } else {
315 *size = 6;
316 Table = DecoderTable48;
317 }
318
319 if (code_len < *size)
320 // short of input data
Nguyen Anh Quynha7837a42015-03-10 14:57:21 +0800321 return false;
Nguyen Anh Quynh48a14ca2014-03-23 08:35:45 +0800322
Nguyen Anh Quynh69582d72014-06-09 17:50:01 +0700323 if (MI->flat_insn->detail) {
clslgrnc9b9844d2018-07-12 06:01:34 +0200324 memset(MI->flat_insn->detail, 0, offsetof(cs_detail, sysz)+sizeof(cs_sysz));
Nguyen Anh Quynh69582d72014-06-09 17:50:01 +0700325 }
326
Nguyen Anh Quynh48a14ca2014-03-23 08:35:45 +0800327 // Construct the instruction.
328 Inst = 0;
329 for (I = 0; I < *size; ++I)
Nguyen Anh Quynh603a32e2015-03-04 13:58:07 +0800330 Inst = (Inst << 8) | code[I];
Nguyen Anh Quynh48a14ca2014-03-23 08:35:45 +0800331
332 return decodeInstruction(Table, MI, Inst, address, info, 0);
333}
334
335#define GET_REGINFO_ENUM
336#define GET_REGINFO_MC_DESC
337#include "SystemZGenRegisterInfo.inc"
338void SystemZ_init(MCRegisterInfo *MRI)
339{
340 /*
341 InitMCRegisterInfo(SystemZRegDesc, 98, RA, PC,
342 SystemZMCRegisterClasses, 12,
343 SystemZRegUnitRoots,
344 49,
345 SystemZRegDiffLists,
346 SystemZRegStrings,
347 SystemZSubRegIdxLists,
348 7,
349 SystemZSubRegIdxRanges,
350 SystemZRegEncodingTable);
351 */
352
353 MCRegisterInfo_InitMCRegisterInfo(MRI, SystemZRegDesc, 98,
354 0, 0,
355 SystemZMCRegisterClasses, 12,
356 0, 0,
357 SystemZRegDiffLists,
358 0,
359 SystemZSubRegIdxLists, 7,
360 0);
361}
362
Nguyen Anh Quynh8598a212014-05-14 11:26:41 +0800363#endif