Coverage Report

Created: 2026-06-15 06:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/capstonev5/arch/SystemZ/SystemZDisassembler.c
Line
Count
Source
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-2015 */
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 "SystemZDisassembler.h"
23
24
#include "../../MCInst.h"
25
#include "../../MCInstrDesc.h"
26
#include "../../MCFixedLenDisassembler.h"
27
#include "../../MCRegisterInfo.h"
28
#include "../../MCDisassembler.h"
29
#include "../../MathExtras.h"
30
31
#include "SystemZMCTargetDesc.h"
32
33
static uint64_t getFeatureBits(int mode)
34
103k
{
35
  // support everything
36
103k
  return (uint64_t)-1;
37
103k
}
38
39
static DecodeStatus decodeRegisterClass(MCInst *Inst, uint64_t RegNo, const unsigned *Regs)
40
186k
{
41
  //assert(RegNo < 16 && "Invalid register");
42
186k
  RegNo = Regs[RegNo];
43
186k
  if (RegNo == 0)
44
166
    return MCDisassembler_Fail;
45
46
186k
  MCOperand_CreateReg0(Inst, (unsigned)RegNo);
47
186k
  return MCDisassembler_Success;
48
186k
}
49
50
static DecodeStatus DecodeGR32BitRegisterClass(MCInst *Inst, uint64_t RegNo,
51
    uint64_t Address, const void *Decoder)
52
77.6k
{
53
77.6k
  return decodeRegisterClass(Inst, RegNo, SystemZMC_GR32Regs);
54
77.6k
}
55
56
static DecodeStatus DecodeGRH32BitRegisterClass(MCInst *Inst, uint64_t RegNo,
57
    uint64_t Address, const void *Decoder)
58
13.7k
{
59
13.7k
  return decodeRegisterClass(Inst, RegNo, SystemZMC_GRH32Regs);
60
13.7k
}
61
62
static DecodeStatus DecodeGR64BitRegisterClass(MCInst *Inst, uint64_t RegNo,
63
    uint64_t Address, const void *Decoder)
64
54.8k
{
65
54.8k
  return decodeRegisterClass(Inst, RegNo, SystemZMC_GR64Regs);
66
54.8k
}
67
68
static DecodeStatus DecodeGR128BitRegisterClass(MCInst *Inst, uint64_t RegNo,
69
    uint64_t Address, const void *Decoder)
70
23.7k
{
71
23.7k
  return decodeRegisterClass(Inst, RegNo, SystemZMC_GR128Regs);
72
23.7k
}
73
74
static DecodeStatus DecodeADDR64BitRegisterClass(MCInst *Inst, uint64_t RegNo,
75
    uint64_t Address, const void *Decoder)
76
66.3k
{
77
66.3k
  return decodeRegisterClass(Inst, RegNo, SystemZMC_GR64Regs);
78
66.3k
}
79
80
static DecodeStatus DecodeFP32BitRegisterClass(MCInst *Inst, uint64_t RegNo,
81
    uint64_t Address, const void *Decoder) 
82
33.2k
{
83
33.2k
  return decodeRegisterClass(Inst, RegNo, SystemZMC_FP32Regs);
84
33.2k
}
85
86
static DecodeStatus DecodeFP64BitRegisterClass(MCInst *Inst, uint64_t RegNo,
87
    uint64_t Address, const void *Decoder)
88
45.8k
{
89
45.8k
  return decodeRegisterClass(Inst, RegNo, SystemZMC_FP64Regs);
90
45.8k
}
91
92
static DecodeStatus DecodeFP128BitRegisterClass(MCInst *Inst, uint64_t RegNo,
93
    uint64_t Address, const void *Decoder)
94
12.3k
{
95
12.3k
  return decodeRegisterClass(Inst, RegNo, SystemZMC_FP128Regs);
96
12.3k
}
97
98
static DecodeStatus DecodeVR32BitRegisterClass(MCInst *Inst, uint64_t RegNo,
99
    uint64_t Address, const void *Decoder)
100
3.19k
{
101
3.19k
  return decodeRegisterClass(Inst, RegNo, SystemZMC_VR32Regs);
102
3.19k
}
103
104
static DecodeStatus DecodeVR64BitRegisterClass(MCInst *Inst, uint64_t RegNo,
105
    uint64_t Address, const void *Decoder)
106
6.42k
{
107
6.42k
  return decodeRegisterClass(Inst, RegNo, SystemZMC_VR64Regs);
108
6.42k
}
109
110
static DecodeStatus DecodeVR128BitRegisterClass(MCInst *Inst, uint64_t RegNo,
111
    uint64_t Address, const void *Decoder)
112
40.4k
{
113
40.4k
  return decodeRegisterClass(Inst, RegNo, SystemZMC_VR128Regs);
114
40.4k
}
115
116
static DecodeStatus DecodeAR32BitRegisterClass(MCInst *Inst, uint64_t RegNo,
117
    uint64_t Address, const void *Decoder)
118
2.15k
{
119
2.15k
  return decodeRegisterClass(Inst, RegNo, SystemZMC_AR32Regs);
120
2.15k
}
121
122
static DecodeStatus DecodeCR64BitRegisterClass(MCInst *Inst, uint64_t RegNo,
123
    uint64_t Address, const void *Decoder)
124
2.13k
{
125
2.13k
  return decodeRegisterClass(Inst, RegNo, SystemZMC_CR64Regs);
126
2.13k
}
127
128
static DecodeStatus decodeUImmOperand(MCInst *Inst, uint64_t Imm)
129
44.0k
{
130
  //assert(isUInt<N>(Imm) && "Invalid immediate");
131
44.0k
  MCOperand_CreateImm0(Inst, Imm);
132
44.0k
  return MCDisassembler_Success;
133
44.0k
}
134
135
static DecodeStatus decodeSImmOperand(MCInst *Inst, uint64_t Imm, unsigned N)
136
6.35k
{
137
  //assert(isUInt<N>(Imm) && "Invalid immediate");
138
6.35k
  MCOperand_CreateImm0(Inst, SignExtend64(Imm, N));
139
6.35k
  return MCDisassembler_Success;
140
6.35k
}
141
142
static DecodeStatus decodeU1ImmOperand(MCInst *Inst, uint64_t Imm,
143
    uint64_t Address, const void *Decoder)
144
2.03k
{
145
2.03k
  return decodeUImmOperand(Inst, Imm);
146
2.03k
}
147
148
static DecodeStatus decodeU2ImmOperand(MCInst *Inst, uint64_t Imm,
149
    uint64_t Address, const void *Decoder)
150
1.61k
{
151
1.61k
  return decodeUImmOperand(Inst, Imm);
152
1.61k
}
153
154
static DecodeStatus decodeU3ImmOperand(MCInst *Inst, uint64_t Imm,
155
    uint64_t Address, const void *Decoder)
156
624
{
157
624
  return decodeUImmOperand(Inst, Imm);
158
624
}
159
160
static DecodeStatus decodeU4ImmOperand(MCInst *Inst, uint64_t Imm,
161
    uint64_t Address, const void *Decoder)
162
45.1k
{
163
45.1k
  return decodeUImmOperand(Inst, Imm);
164
45.1k
}
165
166
static DecodeStatus decodeU6ImmOperand(MCInst *Inst, uint64_t Imm,
167
    uint64_t Address, const void *Decoder)
168
425
{
169
425
  return decodeUImmOperand(Inst, Imm);
170
425
}
171
172
static DecodeStatus decodeU8ImmOperand(MCInst *Inst, uint64_t Imm,
173
    uint64_t Address, const void *Decoder)
174
10.0k
{
175
10.0k
  return decodeUImmOperand(Inst, Imm);
176
10.0k
}
177
178
static DecodeStatus decodeU12ImmOperand(MCInst *Inst, uint64_t Imm,
179
    uint64_t Address, const void *Decoder)
180
40.4k
{
181
40.4k
  return decodeUImmOperand(Inst, Imm);
182
40.4k
}
183
184
static DecodeStatus decodeU16ImmOperand(MCInst *Inst, uint64_t Imm,
185
    uint64_t Address, const void *Decoder)
186
3.48k
{
187
3.48k
  return decodeUImmOperand(Inst, Imm);
188
3.48k
}
189
190
static DecodeStatus decodeU32ImmOperand(MCInst *Inst, uint64_t Imm,
191
    uint64_t Address, const void *Decoder)
192
2.62k
{
193
2.62k
  return decodeUImmOperand(Inst, Imm);
194
2.62k
}
195
196
static DecodeStatus decodeS8ImmOperand(MCInst *Inst, uint64_t Imm,
197
    uint64_t Address, const void *Decoder)
198
2.87k
{
199
2.87k
  return decodeSImmOperand(Inst, Imm, 8);
200
2.87k
}
201
202
static DecodeStatus decodeS16ImmOperand(MCInst *Inst, uint64_t Imm,
203
    uint64_t Address, const void *Decoder) 
204
5.41k
{
205
5.41k
  return decodeSImmOperand(Inst, Imm, 16);
206
5.41k
}
207
208
static DecodeStatus decodeS32ImmOperand(MCInst *Inst, uint64_t Imm,
209
    uint64_t Address, const void *Decoder)
210
1.43k
{
211
1.43k
  return decodeSImmOperand(Inst, Imm, 32);
212
1.43k
}
213
214
static DecodeStatus decodePCDBLOperand(MCInst *Inst, uint64_t Imm,
215
    uint64_t Address, unsigned N)
216
5.38k
{
217
  //assert(isUInt<N>(Imm) && "Invalid PC-relative offset");
218
5.38k
  MCOperand_CreateImm0(Inst, SignExtend64(Imm, N) * 2 + Address);
219
5.38k
  return MCDisassembler_Success;
220
5.38k
}
221
222
static DecodeStatus decodePC12DBLBranchOperand(MCInst *Inst, uint64_t Imm,
223
    uint64_t Address,
224
    const void *Decoder)
225
384
{
226
384
  return decodePCDBLOperand(Inst, Imm, Address, 12);
227
384
}
228
229
static DecodeStatus decodePC16DBLBranchOperand(MCInst *Inst, uint64_t Imm,
230
    uint64_t Address,
231
    const void *Decoder)
232
5.41k
{
233
5.41k
  return decodePCDBLOperand(Inst, Imm, Address, 16);
234
5.41k
}
235
236
static DecodeStatus decodePC24DBLBranchOperand(MCInst *Inst, uint64_t Imm,
237
    uint64_t Address,
238
    const void *Decoder)
239
384
{
240
384
  return decodePCDBLOperand(Inst, Imm, Address, 24);
241
384
}
242
243
static DecodeStatus decodePC32DBLBranchOperand(MCInst *Inst, uint64_t Imm,
244
    uint64_t Address,
245
    const void *Decoder)
246
712
{
247
712
  return decodePCDBLOperand(Inst, Imm, Address, 32);
248
712
}
249
250
static DecodeStatus decodePC32DBLOperand(MCInst *Inst, uint64_t Imm,
251
    uint64_t Address,
252
    const void *Decoder)
253
1.32k
{
254
1.32k
  return decodePCDBLOperand(Inst, Imm, Address, 32);
255
1.32k
}
256
257
static DecodeStatus decodeBDAddr12Operand(MCInst *Inst, uint64_t Field,
258
    const unsigned *Regs)
259
16.7k
{
260
16.7k
  uint64_t Base = Field >> 12;
261
16.7k
  uint64_t Disp = Field & 0xfff;
262
  //assert(Base < 16 && "Invalid BDAddr12");
263
264
16.7k
  MCOperand_CreateReg0(Inst, Base == 0 ? 0 : Regs[Base]);
265
16.7k
  MCOperand_CreateImm0(Inst, Disp);
266
267
16.7k
  return MCDisassembler_Success;
268
16.7k
}
269
270
static DecodeStatus decodeBDAddr20Operand(MCInst *Inst, uint64_t Field,
271
    const unsigned *Regs)
272
5.10k
{
273
5.10k
  uint64_t Base = Field >> 20;
274
5.10k
  uint64_t Disp = ((Field << 12) & 0xff000) | ((Field >> 8) & 0xfff);
275
  //assert(Base < 16 && "Invalid BDAddr20");
276
277
5.10k
  MCOperand_CreateReg0(Inst, Base == 0 ? 0 : Regs[Base]);
278
5.10k
  MCOperand_CreateImm0(Inst, SignExtend64(Disp, 20));
279
5.10k
  return MCDisassembler_Success;
280
5.10k
}
281
282
static DecodeStatus decodeBDXAddr12Operand(MCInst *Inst, uint64_t Field,
283
    const unsigned *Regs)
284
15.1k
{
285
15.1k
  uint64_t Index = Field >> 16;
286
15.1k
  uint64_t Base = (Field >> 12) & 0xf;
287
15.1k
  uint64_t Disp = Field & 0xfff;
288
289
  //assert(Index < 16 && "Invalid BDXAddr12");
290
15.1k
  MCOperand_CreateReg0(Inst, Base == 0 ? 0 : Regs[Base]);
291
15.1k
  MCOperand_CreateImm0(Inst, Disp);
292
15.1k
  MCOperand_CreateReg0(Inst, Index == 0 ? 0 : Regs[Index]);
293
294
15.1k
  return MCDisassembler_Success;
295
15.1k
}
296
297
static DecodeStatus decodeBDXAddr20Operand(MCInst *Inst, uint64_t Field,
298
    const unsigned *Regs)
299
1.92k
{
300
1.92k
  uint64_t Index = Field >> 24;
301
1.92k
  uint64_t Base = (Field >> 20) & 0xf;
302
1.92k
  uint64_t Disp = ((Field & 0xfff00) >> 8) | ((Field & 0xff) << 12);
303
304
  //assert(Index < 16 && "Invalid BDXAddr20");
305
1.92k
  MCOperand_CreateReg0(Inst, Base == 0 ? 0 : Regs[Base]);
306
1.92k
  MCOperand_CreateImm0(Inst, SignExtend64(Disp, 20));
307
1.92k
  MCOperand_CreateReg0(Inst, Index == 0 ? 0 : Regs[Index]);
308
309
1.92k
  return MCDisassembler_Success;
310
1.92k
}
311
312
static DecodeStatus decodeBDLAddr12Len8Operand(MCInst *Inst, uint64_t Field,
313
    const unsigned *Regs)
314
6.46k
{
315
6.46k
  uint64_t Length = Field >> 16;
316
6.46k
  uint64_t Base = (Field >> 12) & 0xf;
317
6.46k
  uint64_t Disp = Field & 0xfff;
318
  //assert(Length < 256 && "Invalid BDLAddr12Len8");
319
320
6.46k
  MCOperand_CreateReg0(Inst, Base == 0 ? 0 : Regs[Base]);
321
6.46k
  MCOperand_CreateImm0(Inst, Disp);
322
6.46k
  MCOperand_CreateImm0(Inst, Length + 1);
323
324
6.46k
  return MCDisassembler_Success;
325
6.46k
}
326
327
static DecodeStatus decodeBDRAddr12Operand(MCInst *Inst, uint64_t Field,
328
    const unsigned *Regs)
329
1.17k
{
330
1.17k
  uint64_t Length = Field >> 16;
331
1.17k
  uint64_t Base = (Field >> 12) & 0xf;
332
1.17k
  uint64_t Disp = Field & 0xfff;
333
  //assert(Length < 16 && "Invalid BDRAddr12");
334
335
1.17k
  MCOperand_CreateReg0(Inst, Base == 0 ? 0 : Regs[Base]);
336
1.17k
  MCOperand_CreateImm0(Inst, Disp);
337
1.17k
  MCOperand_CreateReg0(Inst, Regs[Length]);
338
339
1.17k
  return MCDisassembler_Success;
340
1.17k
}
341
342
static DecodeStatus decodeBDVAddr12Operand(MCInst *Inst, uint64_t Field,
343
    const unsigned *Regs)
344
1.17k
{
345
1.17k
  uint64_t Index = Field >> 16;
346
1.17k
  uint64_t Base = (Field >> 12) & 0xf;
347
1.17k
  uint64_t Disp = Field & 0xfff;
348
  //assert(Index < 32 && "Invalid BDVAddr12");
349
350
1.17k
  MCOperand_CreateReg0(Inst, Base == 0 ? 0 : Regs[Base]);
351
1.17k
  MCOperand_CreateImm0(Inst, Disp);
352
1.17k
  MCOperand_CreateReg0(Inst, SystemZMC_VR128Regs[Index]);
353
354
1.17k
  return MCDisassembler_Success;
355
1.17k
}
356
357
static DecodeStatus decodeBDAddr32Disp12Operand(MCInst *Inst, uint64_t Field,
358
    uint64_t Address, const void *Decoder)
359
2.74k
{
360
2.74k
  return decodeBDAddr12Operand(Inst, Field, SystemZMC_GR32Regs);
361
2.74k
}
362
363
static DecodeStatus decodeBDAddr32Disp20Operand(MCInst *Inst, uint64_t Field,
364
    uint64_t Address, const void *Decoder)
365
554
{
366
554
  return decodeBDAddr20Operand(Inst, Field, SystemZMC_GR32Regs);
367
554
}
368
369
static DecodeStatus decodeBDAddr64Disp12Operand(MCInst *Inst, uint64_t Field,
370
    uint64_t Address, const void *Decoder)
371
13.9k
{
372
13.9k
  return decodeBDAddr12Operand(Inst, Field, SystemZMC_GR64Regs);
373
13.9k
}
374
375
static DecodeStatus decodeBDAddr64Disp20Operand(MCInst *Inst, uint64_t Field,
376
    uint64_t Address, const void *Decoder)
377
4.55k
{
378
4.55k
  return decodeBDAddr20Operand(Inst, Field, SystemZMC_GR64Regs);
379
4.55k
}
380
381
static DecodeStatus decodeBDXAddr64Disp12Operand(MCInst *Inst, uint64_t Field,
382
    uint64_t Address, const void *Decoder)
383
15.1k
{
384
15.1k
  return decodeBDXAddr12Operand(Inst, Field, SystemZMC_GR64Regs);
385
15.1k
}
386
387
static DecodeStatus decodeBDXAddr64Disp20Operand(MCInst *Inst, uint64_t Field,
388
    uint64_t Address, const void *Decoder)
389
1.92k
{
390
1.92k
  return decodeBDXAddr20Operand(Inst, Field, SystemZMC_GR64Regs);
391
1.92k
}
392
393
static DecodeStatus decodeBDLAddr64Disp12Len4Operand(MCInst *Inst, uint64_t Field,
394
    uint64_t Address, const void *Decoder)
395
3.61k
{
396
3.61k
  return decodeBDLAddr12Len8Operand(Inst, Field, SystemZMC_GR64Regs);
397
3.61k
}
398
399
static DecodeStatus decodeBDLAddr64Disp12Len8Operand(MCInst *Inst, uint64_t Field,
400
    uint64_t Address, const void *Decoder)
401
2.84k
{
402
2.84k
  return decodeBDLAddr12Len8Operand(Inst, Field, SystemZMC_GR64Regs);
403
2.84k
}
404
405
static DecodeStatus decodeBDRAddr64Disp12Operand(MCInst *Inst, uint64_t Field,
406
    uint64_t Address, const void *Decoder)
407
1.17k
{
408
1.17k
  return decodeBDRAddr12Operand(Inst, Field, SystemZMC_GR64Regs);
409
1.17k
}
410
411
static DecodeStatus decodeBDVAddr64Disp12Operand(MCInst *Inst, uint64_t Field,
412
    uint64_t Address, const void *Decoder)
413
1.17k
{
414
1.17k
  return decodeBDVAddr12Operand(Inst, Field, SystemZMC_GR64Regs);
415
1.17k
}
416
417
418
#define GET_SUBTARGETINFO_ENUM
419
#include "SystemZGenSubtargetInfo.inc"
420
#include "SystemZGenDisassemblerTables.inc"
421
bool SystemZ_getInstruction(csh ud, const uint8_t *code, size_t code_len, MCInst *MI,
422
    uint16_t *size, uint64_t address, void *info)
423
104k
{
424
104k
  uint64_t Inst;
425
104k
  const uint8_t *Table;
426
104k
  uint16_t I; 
427
428
  // The top 2 bits of the first byte specify the size.
429
104k
  if (*code < 0x40) {
430
22.9k
    *size = 2;
431
22.9k
    Table = DecoderTable16;
432
82.0k
  } else if (*code < 0xc0) {
433
38.8k
    *size = 4;
434
38.8k
    Table = DecoderTable32;
435
43.1k
  } else {
436
43.1k
    *size = 6;
437
43.1k
    Table = DecoderTable48;
438
43.1k
  }
439
440
104k
  if (code_len < *size)
441
    // short of input data
442
979
    return false;
443
444
103k
  if (MI->flat_insn->detail) {
445
103k
    memset(MI->flat_insn->detail, 0, offsetof(cs_detail, sysz)+sizeof(cs_sysz));
446
103k
  }
447
448
  // Construct the instruction.
449
103k
  Inst = 0;
450
559k
  for (I = 0; I < *size; ++I)
451
455k
    Inst = (Inst << 8) | code[I];
452
453
103k
  return decodeInstruction(Table, MI, Inst, address, info, 0);
454
104k
}
455
456
#define GET_REGINFO_ENUM
457
#define GET_REGINFO_MC_DESC
458
#include "SystemZGenRegisterInfo.inc"
459
void SystemZ_init(MCRegisterInfo *MRI)
460
3.06k
{
461
  /*
462
  InitMCRegisterInfo(SystemZRegDesc, 98, RA, PC,
463
      SystemZMCRegisterClasses, 12,
464
      SystemZRegUnitRoots,
465
      49,
466
      SystemZRegDiffLists,
467
      SystemZRegStrings,
468
      SystemZSubRegIdxLists,
469
      7,
470
      SystemZSubRegIdxRanges,
471
      SystemZRegEncodingTable);
472
  */
473
474
3.06k
  MCRegisterInfo_InitMCRegisterInfo(MRI, SystemZRegDesc, 194,
475
3.06k
      0, 0,
476
3.06k
      SystemZMCRegisterClasses, 21,
477
3.06k
      0, 0,
478
3.06k
      SystemZRegDiffLists,
479
3.06k
      0,
480
3.06k
      SystemZSubRegIdxLists, 7,
481
3.06k
      0);
482
3.06k
}
483
484
#endif