Coverage Report

Created: 2023-12-08 06:05

/src/capstonenext/arch/SystemZ/SystemZInstPrinter.c
Line
Count
Source (jump to first uncovered line)
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
127k
{
36
  /*
37
     if (((cs_struct *)ud)->detail != CS_OPT_ON)
38
     return;
39
   */
40
127k
}
41
42
static void printAddress(MCInst *MI, unsigned Base, int64_t Disp, unsigned Index, SStream *O)
43
50.4k
{
44
50.4k
  printInt64(O, Disp);
45
46
50.4k
  if (Base) {
47
42.9k
    SStream_concat0(O, "(");
48
42.9k
    if (Index)
49
13.5k
      SStream_concat(O, "%%%s, ", getRegisterName(Index));
50
42.9k
    SStream_concat(O, "%%%s)", getRegisterName(Base));
51
52
42.9k
    if (MI->csh->detail_opt) {
53
42.9k
      MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_MEM;
54
42.9k
      MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.base = (uint8_t)SystemZ_map_register(Base);
55
42.9k
      MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.index = (uint8_t)SystemZ_map_register(Index);
56
42.9k
      MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.disp = Disp;
57
42.9k
      MI->flat_insn->detail->sysz.op_count++;
58
42.9k
    }
59
42.9k
  } else if (!Index) {
60
5.71k
    if (MI->csh->detail_opt) {
61
5.71k
      MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
62
5.71k
      MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = Disp;
63
5.71k
      MI->flat_insn->detail->sysz.op_count++;
64
5.71k
    }
65
5.71k
  } else {
66
1.74k
    SStream_concat(O, "(%%%s)", getRegisterName(Index));
67
1.74k
    if (MI->csh->detail_opt) {
68
1.74k
      MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_MEM;
69
1.74k
      MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.base = (uint8_t)SystemZ_map_register(Base);
70
1.74k
      MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.index = (uint8_t)SystemZ_map_register(Index);
71
1.74k
      MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.disp = Disp;
72
1.74k
      MI->flat_insn->detail->sysz.op_count++;
73
1.74k
    }
74
1.74k
  }
75
50.4k
}
76
77
static void _printOperand(MCInst *MI, MCOperand *MO, SStream *O)
78
183k
{
79
183k
  if (MCOperand_isReg(MO)) {
80
183k
    unsigned reg;
81
82
183k
    reg = MCOperand_getReg(MO);
83
183k
    SStream_concat(O, "%%%s", getRegisterName(reg));
84
183k
    reg = SystemZ_map_register(reg);
85
86
183k
    if (MI->csh->detail_opt) {
87
183k
      MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_REG;
88
183k
      MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].reg = reg;
89
183k
      MI->flat_insn->detail->sysz.op_count++;
90
183k
    }
91
183k
  } else if (MCOperand_isImm(MO)) {
92
0
    int64_t Imm = MCOperand_getImm(MO);
93
94
0
    printInt64(O, Imm);
95
96
0
    if (MI->csh->detail_opt) {
97
0
      MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
98
0
      MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = Imm;
99
0
      MI->flat_insn->detail->sysz.op_count++;
100
0
    }
101
0
  }
102
183k
}
103
104
static void printU1ImmOperand(MCInst *MI, int OpNum, SStream *O)
105
320
{
106
320
  int64_t Value = MCOperand_getImm(MCInst_getOperand(MI, OpNum));
107
  // assert(isUInt<1>(Value) && "Invalid u1imm argument");
108
320
  printInt64(O, Value);
109
110
320
  if (MI->csh->detail_opt) {
111
320
    MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
112
320
    MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = Value;
113
320
    MI->flat_insn->detail->sysz.op_count++;
114
320
  }
115
320
}
116
117
static void printU2ImmOperand(MCInst *MI, int OpNum, SStream *O)
118
253
{
119
253
  int64_t Value = MCOperand_getImm(MCInst_getOperand(MI, OpNum));
120
  // assert(isUInt<2>(Value) && "Invalid u2imm argument");
121
253
  printInt64(O, Value);
122
123
253
  if (MI->csh->detail_opt) {
124
253
    MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
125
253
    MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = Value;
126
253
    MI->flat_insn->detail->sysz.op_count++;
127
253
  }
128
253
}
129
130
static void printU3ImmOperand(MCInst *MI, int OpNum, SStream *O)
131
279
{
132
279
  int64_t Value = MCOperand_getImm(MCInst_getOperand(MI, OpNum));
133
  // assert(isUInt<3>(Value) && "Invalid u4imm argument");
134
279
  printInt64(O, Value);
135
136
279
  if (MI->csh->detail_opt) {
137
279
    MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
138
279
    MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = Value;
139
279
    MI->flat_insn->detail->sysz.op_count++;
140
279
  }
141
279
}
142
143
static void printU4ImmOperand(MCInst *MI, int OpNum, SStream *O)
144
26.1k
{
145
26.1k
  int64_t Value = MCOperand_getImm(MCInst_getOperand(MI, OpNum));
146
  // assert(isUInt<4>(Value) && "Invalid u4imm argument");
147
26.1k
  printInt64(O, Value);
148
149
26.1k
  if (MI->csh->detail_opt) {
150
26.1k
    MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
151
26.1k
    MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = Value;
152
26.1k
    MI->flat_insn->detail->sysz.op_count++;
153
26.1k
  }
154
26.1k
}
155
156
static void printU6ImmOperand(MCInst *MI, int OpNum, SStream *O)
157
530
{
158
530
  uint32_t Value = (uint32_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
159
  // assert(isUInt<6>(Value) && "Invalid u6imm argument");
160
161
530
  printUInt32(O, Value);
162
163
530
  if (MI->csh->detail_opt) {
164
530
    MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
165
530
    MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = (int64_t)Value;
166
530
    MI->flat_insn->detail->sysz.op_count++;
167
530
  }
168
530
}
169
170
static void printS8ImmOperand(MCInst *MI, int OpNum, SStream *O)
171
1.61k
{
172
1.61k
  int8_t Value = (int8_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
173
  // assert(isInt<8>(Value) && "Invalid s8imm argument");
174
175
1.61k
  if (Value >= 0) {
176
408
    if (Value > HEX_THRESHOLD)
177
274
      SStream_concat(O, "0x%x", Value);
178
134
    else
179
134
      SStream_concat(O, "%u", Value);
180
1.20k
  } else {
181
1.20k
    if (Value < -HEX_THRESHOLD)
182
744
      SStream_concat(O, "-0x%x", -Value);
183
465
    else
184
465
      SStream_concat(O, "-%u", -Value);
185
1.20k
  }
186
187
1.61k
  if (MI->csh->detail_opt) {
188
1.61k
    MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
189
1.61k
    MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = (int64_t)Value;
190
1.61k
    MI->flat_insn->detail->sysz.op_count++;
191
1.61k
  }
192
1.61k
}
193
194
static void printU8ImmOperand(MCInst *MI, int OpNum, SStream *O)
195
7.53k
{
196
7.53k
  uint8_t Value = (uint8_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
197
  // assert(isUInt<8>(Value) && "Invalid u8imm argument");
198
199
7.53k
  if (Value > HEX_THRESHOLD)
200
5.35k
    SStream_concat(O, "0x%x", Value);
201
2.17k
  else
202
2.17k
    SStream_concat(O, "%u", Value);
203
204
7.53k
  if (MI->csh->detail_opt) {
205
7.53k
    MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
206
7.53k
    MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = (int64_t)Value;
207
7.53k
    MI->flat_insn->detail->sysz.op_count++;
208
7.53k
  }
209
7.53k
}
210
211
static void printU12ImmOperand(MCInst *MI, int OpNum, SStream *O)
212
1.53k
{
213
1.53k
  int64_t Value = MCOperand_getImm(MCInst_getOperand(MI, OpNum));
214
  // assert(isUInt<12>(Value) && "Invalid u12imm argument");
215
1.53k
  printInt64(O, Value);
216
217
1.53k
  if (MI->csh->detail_opt) {
218
1.53k
    MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
219
1.53k
    MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = Value;
220
1.53k
    MI->flat_insn->detail->sysz.op_count++;
221
1.53k
  }
222
1.53k
}
223
224
static void printS16ImmOperand(MCInst *MI, int OpNum, SStream *O)
225
3.28k
{
226
3.28k
  int16_t Value = (int16_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
227
  // assert(isInt<16>(Value) && "Invalid s16imm argument");
228
229
3.28k
  if (Value >= 0) {
230
1.49k
    if (Value > HEX_THRESHOLD)
231
1.30k
      SStream_concat(O, "0x%x", Value);
232
191
    else
233
191
      SStream_concat(O, "%u", Value);
234
1.78k
  } else {
235
1.78k
    if (Value < -HEX_THRESHOLD)
236
1.54k
      SStream_concat(O, "-0x%x", -Value);
237
244
    else
238
244
      SStream_concat(O, "-%u", -Value);
239
1.78k
  }
240
241
3.28k
  if (MI->csh->detail_opt) {
242
3.28k
    MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
243
3.28k
    MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = (int64_t)Value;
244
3.28k
    MI->flat_insn->detail->sysz.op_count++;
245
3.28k
  }
246
3.28k
}
247
248
static void printU16ImmOperand(MCInst *MI, int OpNum, SStream *O)
249
3.76k
{
250
3.76k
  uint16_t Value = (uint16_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
251
  // assert(isUInt<16>(Value) && "Invalid u16imm argument");
252
253
3.76k
  if (Value > HEX_THRESHOLD)
254
3.18k
    SStream_concat(O, "0x%x", Value);
255
587
  else
256
587
    SStream_concat(O, "%u", Value);
257
258
3.76k
  if (MI->csh->detail_opt) {
259
3.76k
    MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
260
3.76k
    MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = (int64_t)Value;
261
3.76k
    MI->flat_insn->detail->sysz.op_count++;
262
3.76k
  }
263
3.76k
}
264
265
static void printS32ImmOperand(MCInst *MI, int OpNum, SStream *O)
266
1.26k
{
267
1.26k
  int32_t Value = (int32_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
268
  // assert(isInt<32>(Value) && "Invalid s32imm argument");
269
270
1.26k
  printInt32(O, Value);
271
272
1.26k
  if (MI->csh->detail_opt) {
273
1.26k
    MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
274
1.26k
    MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = (int64_t)Value;
275
1.26k
    MI->flat_insn->detail->sysz.op_count++;
276
1.26k
  }
277
1.26k
}
278
279
static void printU32ImmOperand(MCInst *MI, int OpNum, SStream *O)
280
2.01k
{
281
2.01k
  uint32_t Value = (uint32_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
282
  // assert(isUInt<32>(Value) && "Invalid u32imm argument");
283
284
2.01k
  printUInt32(O, Value);
285
286
2.01k
  if (MI->csh->detail_opt) {
287
2.01k
    MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
288
2.01k
    MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = (int64_t)Value;
289
2.01k
    MI->flat_insn->detail->sysz.op_count++;
290
2.01k
  }
291
2.01k
}
292
293
static void printU48ImmOperand(MCInst *MI, int OpNum, SStream *O)
294
0
{
295
0
  int64_t Value = MCOperand_getImm(MCInst_getOperand(MI, OpNum));
296
  // assert(isUInt<48>(Value) && "Invalid u48imm argument");
297
0
  printInt64(O, Value);
298
299
0
  if (MI->csh->detail_opt) {
300
0
    MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
301
0
    MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = Value;
302
0
    MI->flat_insn->detail->sysz.op_count++;
303
0
  }
304
0
}
305
306
static void printPCRelOperand(MCInst *MI, int OpNum, SStream *O)
307
6.16k
{
308
6.16k
  MCOperand *MO = MCInst_getOperand(MI, OpNum);
309
310
6.16k
  if (MCOperand_isImm(MO)) {
311
6.16k
    int64_t imm = (int64_t)MCOperand_getImm(MO);
312
313
6.16k
    printInt64(O, imm);
314
315
6.16k
    if (MI->csh->detail_opt) {
316
6.16k
      MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM;
317
6.16k
      MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = imm;
318
6.16k
      MI->flat_insn->detail->sysz.op_count++;
319
6.16k
    }
320
6.16k
  }
321
6.16k
}
322
323
static void printPCRelTLSOperand(MCInst *MI, int OpNum, SStream *O)
324
327
{
325
  // Output the PC-relative operand.
326
327
  printPCRelOperand(MI, OpNum, O);
327
327
}
328
329
static void printOperand(MCInst *MI, int OpNum, SStream *O)
330
183k
{
331
183k
  _printOperand(MI, MCInst_getOperand(MI, OpNum), O);
332
183k
}
333
334
static void printBDAddrOperand(MCInst *MI, int OpNum, SStream *O)
335
30.9k
{
336
30.9k
  printAddress(MI, MCOperand_getReg(MCInst_getOperand(MI, OpNum)),
337
30.9k
      MCOperand_getImm(MCInst_getOperand(MI, OpNum + 1)), 0, O);
338
30.9k
}
339
340
static void printBDXAddrOperand(MCInst *MI, int OpNum, SStream *O)
341
19.1k
{
342
19.1k
  printAddress(MI, MCOperand_getReg(MCInst_getOperand(MI, OpNum)),
343
19.1k
      MCOperand_getImm(MCInst_getOperand(MI, OpNum + 1)),
344
19.1k
      MCOperand_getReg(MCInst_getOperand(MI, OpNum + 2)), O);
345
19.1k
}
346
347
static void printBDLAddrOperand(MCInst *MI, int OpNum, SStream *O)
348
11.8k
{
349
11.8k
  unsigned Base = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
350
11.8k
  uint64_t Disp = (uint64_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum + 1));
351
11.8k
  uint64_t Length = (uint64_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum + 2));
352
353
11.8k
  if (Disp > HEX_THRESHOLD)
354
11.5k
    SStream_concat(O, "0x%"PRIx64, Disp);
355
341
  else
356
341
    SStream_concat(O, "%"PRIu64, Disp);
357
358
11.8k
  if (Length > HEX_THRESHOLD)
359
9.06k
    SStream_concat(O, "(0x%"PRIx64, Length);
360
2.82k
  else
361
2.82k
    SStream_concat(O, "(%"PRIu64, Length);
362
363
11.8k
  if (Base)
364
9.75k
    SStream_concat(O, ", %%%s", getRegisterName(Base));
365
11.8k
  SStream_concat0(O, ")");
366
367
11.8k
  if (MI->csh->detail_opt) {
368
11.8k
    MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_MEM;
369
11.8k
    MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.base = (uint8_t)SystemZ_map_register(Base);
370
11.8k
    MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.length = Length;
371
11.8k
    MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.disp = (int64_t)Disp;
372
11.8k
    MI->flat_insn->detail->sysz.op_count++;
373
11.8k
  }
374
11.8k
}
375
376
static void printBDRAddrOperand(MCInst *MI, int OpNum, SStream *O)
377
1.06k
{
378
1.06k
  unsigned Base = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
379
1.06k
  uint64_t Disp = (uint64_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum + 1));
380
1.06k
  uint64_t Length = MCOperand_getReg(MCInst_getOperand(MI, OpNum + 2));
381
382
1.06k
  if (Disp > HEX_THRESHOLD)
383
768
    SStream_concat(O, "0x%"PRIx64, Disp);
384
301
  else
385
301
    SStream_concat(O, "%"PRIu64, Disp);
386
387
1.06k
  SStream_concat0(O, "(");
388
1.06k
  SStream_concat(O, "%%%s", getRegisterName(Length));
389
390
1.06k
  if (Base)
391
673
    SStream_concat(O, ", %%%s", getRegisterName(Base));
392
1.06k
  SStream_concat0(O, ")");
393
394
1.06k
  if (MI->csh->detail_opt) {
395
1.06k
    MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_MEM;
396
1.06k
    MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.base = (uint8_t)SystemZ_map_register(Base);
397
1.06k
    MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.length = (uint8_t)SystemZ_map_register(Length);
398
1.06k
    MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.disp = (int64_t)Disp;
399
1.06k
    MI->flat_insn->detail->sysz.op_count++;
400
1.06k
  }
401
1.06k
}
402
403
static void printBDVAddrOperand(MCInst *MI, int OpNum, SStream *O)
404
273
{
405
273
  printAddress(MI, MCOperand_getReg(MCInst_getOperand(MI, OpNum)),
406
273
      MCOperand_getImm(MCInst_getOperand(MI, OpNum + 1)),
407
273
      MCOperand_getReg(MCInst_getOperand(MI, OpNum + 2)), O);
408
273
}
409
410
static void printCond4Operand(MCInst *MI, int OpNum, SStream *O)
411
0
{
412
0
  static const char *const CondNames[] = {
413
0
    "o", "h", "nle", "l", "nhe", "lh", "ne",
414
0
    "e", "nlh", "he", "nl", "le", "nh", "no"
415
0
  };
416
417
0
  uint64_t Imm = MCOperand_getImm(MCInst_getOperand(MI, OpNum));
418
  // assert(Imm > 0 && Imm < 15 && "Invalid condition");
419
0
  SStream_concat0(O, CondNames[Imm - 1]);
420
421
0
  if (MI->csh->detail_opt)
422
0
    MI->flat_insn->detail->sysz.cc = (sysz_cc)Imm;
423
0
}
424
425
#define PRINT_ALIAS_INSTR
426
#include "SystemZGenAsmWriter.inc"
427
428
void SystemZ_printInst(MCInst *MI, SStream *O, void *Info)
429
127k
{
430
127k
  printInstruction(MI, O, Info);
431
127k
}
432
433
#endif