• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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