Rizin
unix-like reverse engineering framework and cli tools
SystemZInstPrinter.c
Go to the documentation of this file.
1 //===-- SystemZInstPrinter.cpp - Convert SystemZ MCInst to assembly syntax --------===//
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 class prints an SystemZ MCInst to a .s file.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 /* Capstone Disassembly Engine */
15 /* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
16 
17 #ifdef CAPSTONE_HAS_SYSZ
18 
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <capstone/platform.h>
23 
24 #include "SystemZInstPrinter.h"
25 #include "../../MCInst.h"
26 #include "../../utils.h"
27 #include "../../SStream.h"
28 #include "../../MCRegisterInfo.h"
29 #include "../../MathExtras.h"
30 #include "SystemZMapping.h"
31 
32 static const char *getRegisterName(unsigned RegNo);
33 
34 void SystemZ_post_printer(csh ud, cs_insn *insn, char *insn_asm, MCInst *mci)
35 {
36  /*
37  if (((cs_struct *)ud)->detail != CS_OPT_ON)
38  return;
39  */
40 }
41 
42 static void printAddress(MCInst *MI, unsigned Base, int64_t Disp, unsigned Index, SStream *O)
43 {
44  printInt64(O, Disp);
45 
46  if (Base) {
47  SStream_concat0(O, "(");
48  if (Index)
49  SStream_concat(O, "%%%s, ", getRegisterName(Index));
50  SStream_concat(O, "%%%s)", getRegisterName(Base));
51 
52  if (MI->csh->detail) {
53  MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_MEM;
54  MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.base = (uint8_t)SystemZ_map_register(Base);
55  MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.index = (uint8_t)SystemZ_map_register(Index);
56  MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.disp = Disp;
57  MI->flat_insn->detail->sysz.op_count++;
58  }
59  } else if (!Index) {
60  if (MI->csh->detail) {
61  MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
62  MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = Disp;
63  MI->flat_insn->detail->sysz.op_count++;
64  }
65  } else {
66  SStream_concat(O, "(%%%s)", getRegisterName(Index));
67  if (MI->csh->detail) {
68  MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_MEM;
69  MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.base = (uint8_t)SystemZ_map_register(Base);
70  MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.index = (uint8_t)SystemZ_map_register(Index);
71  MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.disp = Disp;
72  MI->flat_insn->detail->sysz.op_count++;
73  }
74  }
75 }
76 
77 static void _printOperand(MCInst *MI, MCOperand *MO, SStream *O)
78 {
79  if (MCOperand_isReg(MO)) {
80  unsigned reg;
81 
82  reg = MCOperand_getReg(MO);
83  SStream_concat(O, "%%%s", getRegisterName(reg));
85 
86  if (MI->csh->detail) {
87  MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_REG;
88  MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].reg = reg;
89  MI->flat_insn->detail->sysz.op_count++;
90  }
91  } else if (MCOperand_isImm(MO)) {
92  int64_t Imm = MCOperand_getImm(MO);
93 
94  printInt64(O, Imm);
95 
96  if (MI->csh->detail) {
97  MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
98  MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = Imm;
99  MI->flat_insn->detail->sysz.op_count++;
100  }
101  }
102 }
103 
104 static void printU4ImmOperand(MCInst *MI, int OpNum, SStream *O)
105 {
106  int64_t Value = MCOperand_getImm(MCInst_getOperand(MI, OpNum));
107  // assert(isUInt<4>(Value) && "Invalid u4imm argument");
108  printInt64(O, Value);
109 
110  if (MI->csh->detail) {
111  MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
112  MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = Value;
113  MI->flat_insn->detail->sysz.op_count++;
114  }
115 }
116 
117 static void printU6ImmOperand(MCInst *MI, int OpNum, SStream *O)
118 {
120  // assert(isUInt<6>(Value) && "Invalid u6imm argument");
121 
122  printUInt32(O, Value);
123 
124  if (MI->csh->detail) {
125  MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
126  MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = (int64_t)Value;
127  MI->flat_insn->detail->sysz.op_count++;
128  }
129 }
130 
131 static void printS8ImmOperand(MCInst *MI, int OpNum, SStream *O)
132 {
133  int8_t Value = (int8_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
134  // assert(isInt<8>(Value) && "Invalid s8imm argument");
135 
136  if (Value >= 0) {
137  if (Value > HEX_THRESHOLD)
138  SStream_concat(O, "0x%x", Value);
139  else
140  SStream_concat(O, "%u", Value);
141  } else {
142  if (Value < -HEX_THRESHOLD)
143  SStream_concat(O, "-0x%x", -Value);
144  else
145  SStream_concat(O, "-%u", -Value);
146  }
147 
148  if (MI->csh->detail) {
149  MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
150  MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = (int64_t)Value;
151  MI->flat_insn->detail->sysz.op_count++;
152  }
153 }
154 
155 static void printU8ImmOperand(MCInst *MI, int OpNum, SStream *O)
156 {
157  uint8_t Value = (uint8_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
158  // assert(isUInt<8>(Value) && "Invalid u8imm argument");
159 
160  if (Value > HEX_THRESHOLD)
161  SStream_concat(O, "0x%x", Value);
162  else
163  SStream_concat(O, "%u", Value);
164 
165  if (MI->csh->detail) {
166  MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
167  MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = (int64_t)Value;
168  MI->flat_insn->detail->sysz.op_count++;
169  }
170 }
171 
172 static void printS16ImmOperand(MCInst *MI, int OpNum, SStream *O)
173 {
174  int16_t Value = (int16_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
175  // assert(isInt<16>(Value) && "Invalid s16imm argument");
176 
177  if (Value >= 0) {
178  if (Value > HEX_THRESHOLD)
179  SStream_concat(O, "0x%x", Value);
180  else
181  SStream_concat(O, "%u", Value);
182  } else {
183  if (Value < -HEX_THRESHOLD)
184  SStream_concat(O, "-0x%x", -Value);
185  else
186  SStream_concat(O, "-%u", -Value);
187  }
188 
189  if (MI->csh->detail) {
190  MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
191  MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = (int64_t)Value;
192  MI->flat_insn->detail->sysz.op_count++;
193  }
194 }
195 
196 static void printU16ImmOperand(MCInst *MI, int OpNum, SStream *O)
197 {
199  // assert(isUInt<16>(Value) && "Invalid u16imm argument");
200 
201  if (Value > HEX_THRESHOLD)
202  SStream_concat(O, "0x%x", Value);
203  else
204  SStream_concat(O, "%u", Value);
205 
206  if (MI->csh->detail) {
207  MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
208  MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = (int64_t)Value;
209  MI->flat_insn->detail->sysz.op_count++;
210  }
211 }
212 
213 static void printS32ImmOperand(MCInst *MI, int OpNum, SStream *O)
214 {
215  int32_t Value = (int32_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
216  // assert(isInt<32>(Value) && "Invalid s32imm argument");
217 
218  printInt32(O, Value);
219 
220  if (MI->csh->detail) {
221  MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
222  MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = (int64_t)Value;
223  MI->flat_insn->detail->sysz.op_count++;
224  }
225 }
226 
227 static void printU32ImmOperand(MCInst *MI, int OpNum, SStream *O)
228 {
230  // assert(isUInt<32>(Value) && "Invalid u32imm argument");
231 
232  printUInt32(O, Value);
233 
234  if (MI->csh->detail) {
235  MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
236  MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = (int64_t)Value;
237  MI->flat_insn->detail->sysz.op_count++;
238  }
239 }
240 
241 static void printAccessRegOperand(MCInst *MI, int OpNum, SStream *O)
242 {
243  int64_t Value = MCOperand_getImm(MCInst_getOperand(MI, OpNum));
244  // assert(Value < 16 && "Invalid access register number");
245  SStream_concat(O, "%%a%u", (unsigned int)Value);
246 
247  if (MI->csh->detail) {
248  MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_ACREG;
249  MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].reg = (unsigned int)Value;
250  MI->flat_insn->detail->sysz.op_count++;
251  }
252 }
253 
254 static void printPCRelOperand(MCInst *MI, int OpNum, SStream *O)
255 {
256  MCOperand *MO = MCInst_getOperand(MI, OpNum);
257 
258  if (MCOperand_isImm(MO)) {
260 
261  printInt64(O, imm);
262 
263  if (MI->csh->detail) {
264  MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
265  MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = imm;
266  MI->flat_insn->detail->sysz.op_count++;
267  }
268  }
269 }
270 
271 static void printPCRelTLSOperand(MCInst *MI, int OpNum, SStream *O)
272 {
273  // Output the PC-relative operand.
274  printPCRelOperand(MI, OpNum, O);
275 }
276 
277 static void printOperand(MCInst *MI, int OpNum, SStream *O)
278 {
279  _printOperand(MI, MCInst_getOperand(MI, OpNum), O);
280 }
281 
282 static void printBDAddrOperand(MCInst *MI, int OpNum, SStream *O)
283 {
284  printAddress(MI, MCOperand_getReg(MCInst_getOperand(MI, OpNum)),
285  MCOperand_getImm(MCInst_getOperand(MI, OpNum + 1)), 0, O);
286 }
287 
288 static void printBDXAddrOperand(MCInst *MI, int OpNum, SStream *O)
289 {
290  printAddress(MI, MCOperand_getReg(MCInst_getOperand(MI, OpNum)),
291  MCOperand_getImm(MCInst_getOperand(MI, OpNum + 1)),
292  MCOperand_getReg(MCInst_getOperand(MI, OpNum + 2)), O);
293 }
294 
295 static void printBDLAddrOperand(MCInst *MI, int OpNum, SStream *O)
296 {
297  unsigned Base = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
298  uint64_t Disp = (uint64_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum + 1));
300 
301  if (Disp > HEX_THRESHOLD)
302  SStream_concat(O, "0x%"PRIx64, Disp);
303  else
304  SStream_concat(O, "%"PRIu64, Disp);
305 
306  if (Length > HEX_THRESHOLD)
307  SStream_concat(O, "(0x%"PRIx64, Length);
308  else
309  SStream_concat(O, "(%"PRIu64, Length);
310 
311  if (Base)
312  SStream_concat(O, ", %%%s", getRegisterName(Base));
313  SStream_concat0(O, ")");
314 
315  if (MI->csh->detail) {
316  MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_MEM;
317  MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.base = (uint8_t)SystemZ_map_register(Base);
318  MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.length = Length;
319  MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.disp = (int64_t)Disp;
320  MI->flat_insn->detail->sysz.op_count++;
321  }
322 }
323 
324 static void printCond4Operand(MCInst *MI, int OpNum, SStream *O)
325 {
326  static const char *const CondNames[] = {
327  "o", "h", "nle", "l", "nhe", "lh", "ne",
328  "e", "nlh", "he", "nl", "le", "nh", "no"
329  };
330 
331  uint64_t Imm = MCOperand_getImm(MCInst_getOperand(MI, OpNum));
332  // assert(Imm > 0 && Imm < 15 && "Invalid condition");
333  SStream_concat0(O, CondNames[Imm - 1]);
334 
335  if (MI->csh->detail)
336  MI->flat_insn->detail->sysz.cc = (sysz_cc)Imm;
337 }
338 
339 #define PRINT_ALIAS_INSTR
340 #include "SystemZGenAsmWriter.inc"
341 
342 void SystemZ_printInst(MCInst *MI, SStream *O, void *Info)
343 {
344  printInstruction(MI, O, Info);
345 }
346 
347 #endif
MCOperand * MCInst_getOperand(MCInst *inst, unsigned i)
Definition: MCInst.c:78
bool MCOperand_isReg(const MCOperand *op)
Definition: MCInst.c:101
int64_t MCOperand_getImm(MCOperand *op)
Definition: MCInst.c:128
unsigned MCOperand_getReg(const MCOperand *op)
getReg - Returns the register number.
Definition: MCInst.c:117
bool MCOperand_isImm(const MCOperand *op)
Definition: MCInst.c:106
void printInt64(SStream *O, int64_t val)
Definition: SStream.c:87
void SStream_concat(SStream *ss, const char *fmt,...)
Definition: SStream.c:45
void SStream_concat0(SStream *ss, const char *s)
Definition: SStream.c:31
void printUInt32(SStream *O, uint32_t val)
Definition: SStream.c:164
void printInt32(SStream *O, int32_t val)
Definition: SStream.c:137
void SystemZ_printInst(MCInst *MI, SStream *O, void *Info)
void SystemZ_post_printer(csh ud, cs_insn *insn, char *insn_asm, MCInst *mci)
sysz_reg SystemZ_map_register(unsigned int r)
#define imm
size_t csh
Definition: capstone.h:71
@ SYSZ_OP_MEM
= CS_OP_MEM (Memory operand).
Definition: systemz.h:42
@ SYSZ_OP_IMM
= CS_OP_IMM (Immediate operand).
Definition: systemz.h:41
@ SYSZ_OP_ACREG
Access register operand.
Definition: systemz.h:43
@ SYSZ_OP_REG
= CS_OP_REG (Register operand).
Definition: systemz.h:40
sysz_cc
Enums corresponding to SystemZ condition codes.
Definition: systemz.h:18
#define reg(n)
#define PRIu64
Definition: macros.h:18
#define O
Definition: rcond.c:14
static int
Definition: sfsocketcall.h:114
unsigned short uint16_t
Definition: sftypes.h:30
long int64_t
Definition: sftypes.h:32
int int32_t
Definition: sftypes.h:33
unsigned int uint32_t
Definition: sftypes.h:29
unsigned long uint64_t
Definition: sftypes.h:28
short int16_t
Definition: sftypes.h:34
unsigned char uint8_t
Definition: sftypes.h:31
char int8_t
Definition: sftypes.h:35
Definition: length.h:9
Definition: MCInst.h:88
cs_insn * flat_insn
Definition: MCInst.h:95
cs_struct * csh
Definition: MCInst.h:97
Definition: SStream.h:9
cs_opt_value detail
Definition: cs_priv.h:68
#define HEX_THRESHOLD
Definition: utils.h:16
#define PRIx64
Definition: sysdefs.h:94