1 //===------ 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 */
11 /* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */
12
13 #ifdef CAPSTONE_HAS_SYSZ
14
15 #include <stdio.h> // DEBUG
16 #include <stdlib.h>
17 #include <string.h>
18
19 #include "../../cs_priv.h"
20 #include "../../utils.h"
21
22 #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
getFeatureBits(int mode)31 static uint64_t getFeatureBits(int mode)
32 {
33 // support everything
34 return (uint64_t)-1;
35 }
36
decodeRegisterClass(MCInst * Inst,uint64_t RegNo,const unsigned * Regs)37 static 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
44 MCOperand_CreateReg0(Inst, (unsigned)RegNo);
45 return MCDisassembler_Success;
46 }
47
DecodeGR32BitRegisterClass(MCInst * Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)48 static DecodeStatus DecodeGR32BitRegisterClass(MCInst *Inst, uint64_t RegNo,
49 uint64_t Address, const void *Decoder)
50 {
51 return decodeRegisterClass(Inst, RegNo, SystemZMC_GR32Regs);
52 }
53
DecodeGRH32BitRegisterClass(MCInst * Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)54 static DecodeStatus DecodeGRH32BitRegisterClass(MCInst *Inst, uint64_t RegNo,
55 uint64_t Address, const void *Decoder)
56 {
57 return decodeRegisterClass(Inst, RegNo, SystemZMC_GRH32Regs);
58 }
59
DecodeGR64BitRegisterClass(MCInst * Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)60 static DecodeStatus DecodeGR64BitRegisterClass(MCInst *Inst, uint64_t RegNo,
61 uint64_t Address, const void *Decoder)
62 {
63 return decodeRegisterClass(Inst, RegNo, SystemZMC_GR64Regs);
64 }
65
DecodeGR128BitRegisterClass(MCInst * Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)66 static DecodeStatus DecodeGR128BitRegisterClass(MCInst *Inst, uint64_t RegNo,
67 uint64_t Address, const void *Decoder)
68 {
69 return decodeRegisterClass(Inst, RegNo, SystemZMC_GR128Regs);
70 }
71
DecodeADDR64BitRegisterClass(MCInst * Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)72 static DecodeStatus DecodeADDR64BitRegisterClass(MCInst *Inst, uint64_t RegNo,
73 uint64_t Address, const void *Decoder)
74 {
75 return decodeRegisterClass(Inst, RegNo, SystemZMC_GR64Regs);
76 }
77
DecodeFP32BitRegisterClass(MCInst * Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)78 static DecodeStatus DecodeFP32BitRegisterClass(MCInst *Inst, uint64_t RegNo,
79 uint64_t Address, const void *Decoder)
80 {
81 return decodeRegisterClass(Inst, RegNo, SystemZMC_FP32Regs);
82 }
83
DecodeFP64BitRegisterClass(MCInst * Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)84 static DecodeStatus DecodeFP64BitRegisterClass(MCInst *Inst, uint64_t RegNo,
85 uint64_t Address, const void *Decoder)
86 {
87 return decodeRegisterClass(Inst, RegNo, SystemZMC_FP64Regs);
88 }
89
DecodeFP128BitRegisterClass(MCInst * Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)90 static DecodeStatus DecodeFP128BitRegisterClass(MCInst *Inst, uint64_t RegNo,
91 uint64_t Address, const void *Decoder)
92 {
93 return decodeRegisterClass(Inst, RegNo, SystemZMC_FP128Regs);
94 }
95
decodeUImmOperand(MCInst * Inst,uint64_t Imm)96 static DecodeStatus decodeUImmOperand(MCInst *Inst, uint64_t Imm)
97 {
98 //assert(isUInt<N>(Imm) && "Invalid immediate");
99 MCOperand_CreateImm0(Inst, Imm);
100 return MCDisassembler_Success;
101 }
102
decodeSImmOperand(MCInst * Inst,uint64_t Imm,unsigned N)103 static DecodeStatus decodeSImmOperand(MCInst *Inst, uint64_t Imm, unsigned N)
104 {
105 //assert(isUInt<N>(Imm) && "Invalid immediate");
106 MCOperand_CreateImm0(Inst, SignExtend64(Imm, N));
107 return MCDisassembler_Success;
108 }
109
decodeAccessRegOperand(MCInst * Inst,uint64_t Imm,uint64_t Address,const void * Decoder)110 static DecodeStatus decodeAccessRegOperand(MCInst *Inst, uint64_t Imm,
111 uint64_t Address, const void *Decoder)
112 {
113 return decodeUImmOperand(Inst, Imm);
114 }
115
decodeU4ImmOperand(MCInst * Inst,uint64_t Imm,uint64_t Address,const void * Decoder)116 static DecodeStatus decodeU4ImmOperand(MCInst *Inst, uint64_t Imm,
117 uint64_t Address, const void *Decoder)
118 {
119 return decodeUImmOperand(Inst, Imm);
120 }
121
decodeU6ImmOperand(MCInst * Inst,uint64_t Imm,uint64_t Address,const void * Decoder)122 static DecodeStatus decodeU6ImmOperand(MCInst *Inst, uint64_t Imm,
123 uint64_t Address, const void *Decoder)
124 {
125 return decodeUImmOperand(Inst, Imm);
126 }
127
decodeU8ImmOperand(MCInst * Inst,uint64_t Imm,uint64_t Address,const void * Decoder)128 static DecodeStatus decodeU8ImmOperand(MCInst *Inst, uint64_t Imm,
129 uint64_t Address, const void *Decoder)
130 {
131 return decodeUImmOperand(Inst, Imm);
132 }
133
decodeU16ImmOperand(MCInst * Inst,uint64_t Imm,uint64_t Address,const void * Decoder)134 static DecodeStatus decodeU16ImmOperand(MCInst *Inst, uint64_t Imm,
135 uint64_t Address, const void *Decoder)
136 {
137 return decodeUImmOperand(Inst, Imm);
138 }
139
decodeU32ImmOperand(MCInst * Inst,uint64_t Imm,uint64_t Address,const void * Decoder)140 static DecodeStatus decodeU32ImmOperand(MCInst *Inst, uint64_t Imm,
141 uint64_t Address, const void *Decoder)
142 {
143 return decodeUImmOperand(Inst, Imm);
144 }
145
decodeS8ImmOperand(MCInst * Inst,uint64_t Imm,uint64_t Address,const void * Decoder)146 static DecodeStatus decodeS8ImmOperand(MCInst *Inst, uint64_t Imm,
147 uint64_t Address, const void *Decoder)
148 {
149 return decodeSImmOperand(Inst, Imm, 8);
150 }
151
decodeS16ImmOperand(MCInst * Inst,uint64_t Imm,uint64_t Address,const void * Decoder)152 static DecodeStatus decodeS16ImmOperand(MCInst *Inst, uint64_t Imm,
153 uint64_t Address, const void *Decoder)
154 {
155 return decodeSImmOperand(Inst, Imm, 16);
156 }
157
decodeS32ImmOperand(MCInst * Inst,uint64_t Imm,uint64_t Address,const void * Decoder)158 static DecodeStatus decodeS32ImmOperand(MCInst *Inst, uint64_t Imm,
159 uint64_t Address, const void *Decoder)
160 {
161 return decodeSImmOperand(Inst, Imm, 32);
162 }
163
decodePCDBLOperand(MCInst * Inst,uint64_t Imm,uint64_t Address,unsigned N)164 static DecodeStatus decodePCDBLOperand(MCInst *Inst, uint64_t Imm,
165 uint64_t Address, unsigned N)
166 {
167 //assert(isUInt<N>(Imm) && "Invalid PC-relative offset");
168 MCOperand_CreateImm0(Inst, SignExtend64(Imm, N) * 2 + Address);
169 return MCDisassembler_Success;
170 }
171
decodePC16DBLOperand(MCInst * Inst,uint64_t Imm,uint64_t Address,const void * Decoder)172 static DecodeStatus decodePC16DBLOperand(MCInst *Inst, uint64_t Imm,
173 uint64_t Address, const void *Decoder)
174 {
175 return decodePCDBLOperand(Inst, Imm, Address, 16);
176 }
177
decodePC32DBLOperand(MCInst * Inst,uint64_t Imm,uint64_t Address,const void * Decoder)178 static 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
decodeBDAddr12Operand(MCInst * Inst,uint64_t Field,const unsigned * Regs)185 static 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
192 MCOperand_CreateReg0(Inst, Base == 0 ? 0 : Regs[Base]);
193 MCOperand_CreateImm0(Inst, Disp);
194
195 return MCDisassembler_Success;
196 }
197
decodeBDAddr20Operand(MCInst * Inst,uint64_t Field,const unsigned * Regs)198 static 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
205 MCOperand_CreateReg0(Inst, Base == 0 ? 0 : Regs[Base]);
206 MCOperand_CreateImm0(Inst, SignExtend64(Disp, 20));
207 return MCDisassembler_Success;
208 }
209
decodeBDXAddr12Operand(MCInst * Inst,uint64_t Field,const unsigned * Regs)210 static 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");
218 MCOperand_CreateReg0(Inst, Base == 0 ? 0 : Regs[Base]);
219 MCOperand_CreateImm0(Inst, Disp);
220 MCOperand_CreateReg0(Inst, Index == 0 ? 0 : Regs[Index]);
221
222 return MCDisassembler_Success;
223 }
224
decodeBDXAddr20Operand(MCInst * Inst,uint64_t Field,const unsigned * Regs)225 static 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");
233 MCOperand_CreateReg0(Inst, Base == 0 ? 0 : Regs[Base]);
234 MCOperand_CreateImm0(Inst, SignExtend64(Disp, 20));
235 MCOperand_CreateReg0(Inst, Index == 0 ? 0 : Regs[Index]);
236
237 return MCDisassembler_Success;
238 }
239
decodeBDLAddr12Len8Operand(MCInst * Inst,uint64_t Field,const unsigned * Regs)240 static 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
248 MCOperand_CreateReg0(Inst, Base == 0 ? 0 : Regs[Base]);
249 MCOperand_CreateImm0(Inst, Disp);
250 MCOperand_CreateImm0(Inst, Length + 1);
251
252 return MCDisassembler_Success;
253 }
254
decodeBDAddr32Disp12Operand(MCInst * Inst,uint64_t Field,uint64_t Address,const void * Decoder)255 static DecodeStatus decodeBDAddr32Disp12Operand(MCInst *Inst, uint64_t Field,
256 uint64_t Address, const void *Decoder)
257 {
258 return decodeBDAddr12Operand(Inst, Field, SystemZMC_GR32Regs);
259 }
260
decodeBDAddr32Disp20Operand(MCInst * Inst,uint64_t Field,uint64_t Address,const void * Decoder)261 static DecodeStatus decodeBDAddr32Disp20Operand(MCInst *Inst, uint64_t Field,
262 uint64_t Address, const void *Decoder)
263 {
264 return decodeBDAddr20Operand(Inst, Field, SystemZMC_GR32Regs);
265 }
266
decodeBDAddr64Disp12Operand(MCInst * Inst,uint64_t Field,uint64_t Address,const void * Decoder)267 static DecodeStatus decodeBDAddr64Disp12Operand(MCInst *Inst, uint64_t Field,
268 uint64_t Address, const void *Decoder)
269 {
270 return decodeBDAddr12Operand(Inst, Field, SystemZMC_GR64Regs);
271 }
272
decodeBDAddr64Disp20Operand(MCInst * Inst,uint64_t Field,uint64_t Address,const void * Decoder)273 static DecodeStatus decodeBDAddr64Disp20Operand(MCInst *Inst, uint64_t Field,
274 uint64_t Address, const void *Decoder)
275 {
276 return decodeBDAddr20Operand(Inst, Field, SystemZMC_GR64Regs);
277 }
278
decodeBDXAddr64Disp12Operand(MCInst * Inst,uint64_t Field,uint64_t Address,const void * Decoder)279 static DecodeStatus decodeBDXAddr64Disp12Operand(MCInst *Inst, uint64_t Field,
280 uint64_t Address, const void *Decoder)
281 {
282 return decodeBDXAddr12Operand(Inst, Field, SystemZMC_GR64Regs);
283 }
284
decodeBDXAddr64Disp20Operand(MCInst * Inst,uint64_t Field,uint64_t Address,const void * Decoder)285 static DecodeStatus decodeBDXAddr64Disp20Operand(MCInst *Inst, uint64_t Field,
286 uint64_t Address, const void *Decoder)
287 {
288 return decodeBDXAddr20Operand(Inst, Field, SystemZMC_GR64Regs);
289 }
290
decodeBDLAddr64Disp12Len8Operand(MCInst * Inst,uint64_t Field,uint64_t Address,const void * Decoder)291 static 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"
SystemZ_getInstruction(csh ud,const uint8_t * code,size_t code_len,MCInst * MI,uint16_t * size,uint64_t address,void * info)300 bool SystemZ_getInstruction(csh ud, const uint8_t *code, size_t code_len, MCInst *MI,
301 uint16_t *size, uint64_t address, void *info)
302 {
303 uint64_t Inst;
304 uint8_t Bytes[6];
305 uint8_t *Table;
306 uint16_t I;
307
308 // The top 2 bits of the first byte specify the size.
309 if (*code < 0x40) {
310 *size = 2;
311 Table = DecoderTable16;
312 } else if (*code < 0xc0) {
313 *size = 4;
314 Table = DecoderTable32;
315 } else {
316 *size = 6;
317 Table = DecoderTable48;
318 }
319
320 if (code_len < *size)
321 // short of input data
322 return false;
323
324 if (MI->flat_insn->detail) {
325 memset(MI->flat_insn->detail, 0, sizeof(cs_detail));
326 }
327
328 memcpy(Bytes, code, *size);
329
330 // Construct the instruction.
331 Inst = 0;
332 for (I = 0; I < *size; ++I)
333 Inst = (Inst << 8) | Bytes[I];
334
335 return decodeInstruction(Table, MI, Inst, address, info, 0);
336 }
337
338 #define GET_REGINFO_ENUM
339 #define GET_REGINFO_MC_DESC
340 #include "SystemZGenRegisterInfo.inc"
SystemZ_init(MCRegisterInfo * MRI)341 void SystemZ_init(MCRegisterInfo *MRI)
342 {
343 /*
344 InitMCRegisterInfo(SystemZRegDesc, 98, RA, PC,
345 SystemZMCRegisterClasses, 12,
346 SystemZRegUnitRoots,
347 49,
348 SystemZRegDiffLists,
349 SystemZRegStrings,
350 SystemZSubRegIdxLists,
351 7,
352 SystemZSubRegIdxRanges,
353 SystemZRegEncodingTable);
354 */
355
356 MCRegisterInfo_InitMCRegisterInfo(MRI, SystemZRegDesc, 98,
357 0, 0,
358 SystemZMCRegisterClasses, 12,
359 0, 0,
360 SystemZRegDiffLists,
361 0,
362 SystemZSubRegIdxLists, 7,
363 0);
364 }
365
366 #endif
367