Coverage Report

Created: 2025-07-01 07:03

/src/capstonenext/arch/HPPA/HPPAMapping.c
Line
Count
Source (jump to first uncovered line)
1
/* Capstone Disassembly Engine */
2
/* By Dmitry Sibirtsev  <sibirtsevdl@gmail.com>, 2023 */
3
4
#ifdef CAPSTONE_HAS_HPPA
5
6
#include <string.h>
7
#include <stdlib.h>
8
9
#include "HPPAMapping.h"
10
#include "HPPAConstants.h"
11
#include "../../Mapping.h"
12
#include "../../utils.h"
13
14
#ifndef CAPSTONE_DIET
15
static const name_map group_name_maps[] = {
16
  { HPPA_GRP_INVALID, NULL },
17
18
  { HPPA_GRP_COMPUTATION, "computation" },
19
  { HPPA_GRP_MULTIMEDIA, "multimedia" },
20
  { HPPA_GRP_MEM_REF, "memory_reference" },
21
  { HPPA_GRP_LONG_IMM, "long_imm" },
22
  { HPPA_GRP_BRANCH, "branch" },
23
  { HPPA_GRP_SYSCTRL, "system_control" },
24
  { HPPA_GRP_ASSIST, "assist" },
25
  { HPPA_GRP_FLOAT, "float" },
26
};
27
#endif
28
29
const char *HPPA_group_name(csh handle, unsigned int id)
30
0
{
31
0
#ifndef CAPSTONE_DIET
32
0
  return id2name(group_name_maps, ARR_SIZE(group_name_maps), id);
33
#else
34
  return NULL;
35
#endif
36
0
}
37
38
#ifndef CAPSTONE_DIET
39
static const name_map insn_name_maps[HPPA_INS_ENDING] = {
40
  { HPPA_INS_INVALID, NULL },
41
42
  { HPPA_INS_ADD, "add" },
43
  { HPPA_INS_ADDI, "addi" },
44
  { HPPA_INS_ADDIO, "addio" },
45
  { HPPA_INS_ADDIT, "addit" },
46
  { HPPA_INS_ADDITO, "addito" },
47
  { HPPA_INS_ADDB, "addb" },
48
  { HPPA_INS_ADDBT, "addbt" },
49
  { HPPA_INS_ADDBF, "addbf" },
50
  { HPPA_INS_ADDIB, "addib" },
51
  { HPPA_INS_ADDIBT, "addibt" },
52
  { HPPA_INS_ADDIBF, "addibf" },
53
  { HPPA_INS_ADDIL, "addil" },
54
  { HPPA_INS_ADDC, "addc" },
55
  { HPPA_INS_ADDCO, "addco" },
56
  { HPPA_INS_ADDL, "addl" },
57
  { HPPA_INS_ADDO, "addo" },
58
  { HPPA_INS_AND, "and" },
59
  { HPPA_INS_ANDCM, "andcm" },
60
  { HPPA_INS_B, "b" },
61
  { HPPA_INS_BB, "bb" },
62
  { HPPA_INS_BE, "be" },
63
  { HPPA_INS_BL, "bl" },
64
  { HPPA_INS_BLE, "ble" },
65
  { HPPA_INS_BLR, "blr" },
66
  { HPPA_INS_BREAK, "break" },
67
  { HPPA_INS_BV, "bv" },
68
  { HPPA_INS_BVB, "bvb" },
69
  { HPPA_INS_BVE, "bve" },
70
  { HPPA_INS_CALL, "call" },
71
  { HPPA_INS_CLDD, "cldd" },
72
  { HPPA_INS_CLDDS, "cldds" },
73
  { HPPA_INS_CLDDX, "clddx" },
74
  { HPPA_INS_CLDW, "cldw" },
75
  { HPPA_INS_CLDWS, "cldws" },
76
  { HPPA_INS_CLDWX, "cldwx" },
77
  { HPPA_INS_CLRBTS, "clrbts" },
78
  { HPPA_INS_CMPB, "cmpb" },
79
  { HPPA_INS_CMPCLR, "cmpclr" },
80
  { HPPA_INS_CMPIB, "cmpib" },
81
  { HPPA_INS_CMPICLR, "cmpiclr" },
82
  { HPPA_INS_COMB, "comb" },
83
  { HPPA_INS_COMBT, "combt" },
84
  { HPPA_INS_COMBF, "combf" },
85
  { HPPA_INS_COMCLR, "comclr" },
86
  { HPPA_INS_COMIB, "comib" },
87
  { HPPA_INS_COMIBT, "comibt" },
88
  { HPPA_INS_COMIBF, "comibf" },
89
  { HPPA_INS_COMICLR, "comiclr" },
90
  { HPPA_INS_COPR, "copr" },
91
  { HPPA_INS_COPY, "copy" },
92
  { HPPA_INS_CSTD, "cstd" },
93
  { HPPA_INS_CSTDS, "cstds" },
94
  { HPPA_INS_CSTDX, "cstdx" },
95
  { HPPA_INS_CSTW, "cstw" },
96
  { HPPA_INS_CSTWS, "cstws" },
97
  { HPPA_INS_CSTWX, "cstwx" },
98
  { HPPA_INS_DCOR, "dcor" },
99
  { HPPA_INS_DEP, "dep" },
100
  { HPPA_INS_DEPI, "depi" },
101
  { HPPA_INS_DEPD, "depd" },
102
  { HPPA_INS_DEPDI, "depdi" },
103
  { HPPA_INS_DEPW, "depw" },
104
  { HPPA_INS_DEPWI, "depwi" },
105
  { HPPA_INS_DIAG, "diag" },
106
  { HPPA_INS_DS, "ds" },
107
  { HPPA_INS_EXTRD, "extrd" },
108
  { HPPA_INS_EXTRS, "extrs" },
109
  { HPPA_INS_EXTRU, "extru" },
110
  { HPPA_INS_EXTRW, "extrw" },
111
  { HPPA_INS_FABS, "fabs" },
112
  { HPPA_INS_FADD, "fadd" },
113
  { HPPA_INS_FCMP, "fcmp" },
114
  { HPPA_INS_FCNV, "fcnv" },
115
  { HPPA_INS_FCNVFF, "fcnvff" },
116
  { HPPA_INS_FCNVFX, "fcnvfx" },
117
  { HPPA_INS_FCNVFXT, "fcnvfxt" },
118
  { HPPA_INS_FCNVXF, "fcnvxf" },
119
  { HPPA_INS_FCPY, "fcpy" },
120
  { HPPA_INS_FDC, "fdc" },
121
  { HPPA_INS_FDCE, "fdce" },
122
  { HPPA_INS_FDIV, "fdiv" },
123
  { HPPA_INS_FIC, "fic" },
124
  { HPPA_INS_FICE, "fice" },
125
  { HPPA_INS_FID, "fid" },
126
  { HPPA_INS_FLDD, "fldd" },
127
  { HPPA_INS_FLDDS, "fldds" },
128
  { HPPA_INS_FLDDX, "flddx" },
129
  { HPPA_INS_FLDW, "fldw" },
130
  { HPPA_INS_FLDWS, "fldws" },
131
  { HPPA_INS_FLDWX, "fldwx" },
132
  { HPPA_INS_FMPY, "fmpy" },
133
  { HPPA_INS_FMPYADD, "fmpyadd" },
134
  { HPPA_INS_FMPYFADD, "fmpyfadd" },
135
  { HPPA_INS_FMPYNFADD, "fmpynfadd" },
136
  { HPPA_INS_FMPYSUB, "fmpysub" },
137
  { HPPA_INS_FNEG, "fneg" },
138
  { HPPA_INS_FNEGABS, "fnegabs" },
139
  { HPPA_INS_FREM, "frem" },
140
  { HPPA_INS_FRND, "frnd" },
141
  { HPPA_INS_FSQRT, "fsqrt" },
142
  { HPPA_INS_FSTD, "fstd" },
143
  { HPPA_INS_FSTDS, "fstds" },
144
  { HPPA_INS_FSTDX, "fstdx" },
145
  { HPPA_INS_FSTW, "fstw" },
146
  { HPPA_INS_FSTWS, "fstws" },
147
  { HPPA_INS_FSTWX, "fstwx" },
148
  { HPPA_INS_FSTQS, "fstqs" },
149
  { HPPA_INS_FSTQX, "fstqx" },
150
  { HPPA_INS_FSUB, "fsub" },
151
  { HPPA_INS_FTEST, "ftest" },
152
  { HPPA_INS_GATE, "gate" },
153
  { HPPA_INS_GFR, "gfr" },
154
  { HPPA_INS_GFW, "gfw" },
155
  { HPPA_INS_GRSHDW, "grshdw" },
156
  { HPPA_INS_HADD, "hadd" },
157
  { HPPA_INS_HAVG, "havg" },
158
  { HPPA_INS_HSHL, "hshl" },
159
  { HPPA_INS_HSHLADD, "hshladd" },
160
  { HPPA_INS_HSHR, "hshr" },
161
  { HPPA_INS_HSHRADD, "hshradd" },
162
  { HPPA_INS_HSUB, "hsub" },
163
  { HPPA_INS_IDTLBA, "idtlba" },
164
  { HPPA_INS_IDTLBP, "idtlbp" },
165
  { HPPA_INS_IDTLBT, "idtlbt" },
166
  { HPPA_INS_IDCOR, "idcor" },
167
  { HPPA_INS_IITLBA, "iitlba" },
168
  { HPPA_INS_IITLBP, "iitlbp" },
169
  { HPPA_INS_IITLBT, "iitlbt" },
170
  { HPPA_INS_LCI, "lci" },
171
  { HPPA_INS_LDB, "ldb" },
172
  { HPPA_INS_LDBS, "ldbs" },
173
  { HPPA_INS_LDBX, "ldbx" },
174
  { HPPA_INS_LDCD, "ldcd" },
175
  { HPPA_INS_LDCW, "ldcw" },
176
  { HPPA_INS_LDCWS, "ldcws" },
177
  { HPPA_INS_LDCWX, "ldcwx" },
178
  { HPPA_INS_LDD, "ldd" },
179
  { HPPA_INS_LDDA, "ldda" },
180
  { HPPA_INS_LDH, "ldh" },
181
  { HPPA_INS_LDHS, "ldhs" },
182
  { HPPA_INS_LDHX, "ldhx" },
183
  { HPPA_INS_LDI, "ldi" },
184
  { HPPA_INS_LDIL, "ldil" },
185
  { HPPA_INS_LDO, "ldo" },
186
  { HPPA_INS_LDSID, "ldsid" },
187
  { HPPA_INS_LDW, "ldw" },
188
  { HPPA_INS_LDWA, "ldwa" },
189
  { HPPA_INS_LDWAS, "ldwas" },
190
  { HPPA_INS_LDWAX, "ldwax" },
191
  { HPPA_INS_LDWM, "ldwm" },
192
  { HPPA_INS_LDWS, "ldws" },
193
  { HPPA_INS_LDWX, "ldwx" },
194
  { HPPA_INS_LPA, "lpa" },
195
  { HPPA_INS_MFCPU, "mfcpu" },
196
  { HPPA_INS_MFCTL, "mfctl" },
197
  { HPPA_INS_MFIA, "mfia" },
198
  { HPPA_INS_MFSP, "mfsp" },
199
  { HPPA_INS_MIXH, "mixh" },
200
  { HPPA_INS_MIXW, "mixw" },
201
  { HPPA_INS_MOVB, "movb" },
202
  { HPPA_INS_MOVIB, "movib" },
203
  { HPPA_INS_MTCPU, "mtcpu" },
204
  { HPPA_INS_MTCTL, "mtctl" },
205
  { HPPA_INS_MTSAR, "mtsar" },
206
  { HPPA_INS_MTSARCM, "mtsarcm" },
207
  { HPPA_INS_MTSM, "mtsm" },
208
  { HPPA_INS_MTSP, "mtsp" },
209
  { HPPA_INS_NOP, "nop" },
210
  { HPPA_INS_OR, "or" },
211
  { HPPA_INS_PDC, "pdc" },
212
  { HPPA_INS_PDTLB, "pdtlb" },
213
  { HPPA_INS_PDTLBE, "pdtlbe" },
214
  { HPPA_INS_PERMH, "permh" },
215
  { HPPA_INS_PITLB, "pitlb" },
216
  { HPPA_INS_PITLBE, "pitlbe" },
217
  { HPPA_INS_PMDIS, "pmdis" },
218
  { HPPA_INS_PMENB, "pmenb" },
219
  { HPPA_INS_POPBTS, "popbts" },
220
  { HPPA_INS_PROBE, "probe" },
221
  { HPPA_INS_PROBEI, "probei" },
222
  { HPPA_INS_PROBER, "prober" },
223
  { HPPA_INS_PROBERI, "proberi" },
224
  { HPPA_INS_PROBEW, "probew" },
225
  { HPPA_INS_PROBEWI, "probewi" },
226
  { HPPA_INS_PUSHBTS, "pushbts" },
227
  { HPPA_INS_PUSHNOM, "pushnom" },
228
  { HPPA_INS_RET, "ret" },
229
  { HPPA_INS_RFI, "rfi" },
230
  { HPPA_INS_RFIR, "rfir" },
231
  { HPPA_INS_RSM, "rsm" },
232
  { HPPA_INS_SHDWGR, "shdwgr" },
233
  { HPPA_INS_SHLADD, "shladd" },
234
  { HPPA_INS_SH1ADD, "sh1add" },
235
  { HPPA_INS_SH1ADDL, "sh1addl" },
236
  { HPPA_INS_SH1ADDO, "sh1addo" },
237
  { HPPA_INS_SH2ADD, "sh2add" },
238
  { HPPA_INS_SH2ADDL, "sh2addl" },
239
  { HPPA_INS_SH2ADDO, "sh2addo" },
240
  { HPPA_INS_SH3ADD, "sh3add" },
241
  { HPPA_INS_SH3ADDL, "sh3addl" },
242
  { HPPA_INS_SH3ADDO, "sh3addo" },
243
  { HPPA_INS_SHD, "shd" },
244
  { HPPA_INS_SHRPD, "shrpd" },
245
  { HPPA_INS_SHRPW, "shrpw" },
246
  { HPPA_INS_SPOP0, "spop0" },
247
  { HPPA_INS_SPOP1, "spop1" },
248
  { HPPA_INS_SPOP2, "spop2" },
249
  { HPPA_INS_SPOP3, "spop3" },
250
  { HPPA_INS_SSM, "ssm" },
251
  { HPPA_INS_STB, "stb" },
252
  { HPPA_INS_STBS, "stbs" },
253
  { HPPA_INS_STBY, "stby" },
254
  { HPPA_INS_STBYS, "stbys" },
255
  { HPPA_INS_STD, "std" },
256
  { HPPA_INS_STDA, "stda" },
257
  { HPPA_INS_STDBY, "stdby" },
258
  { HPPA_INS_STH, "sth" },
259
  { HPPA_INS_STHS, "sths" },
260
  { HPPA_INS_STW, "stw" },
261
  { HPPA_INS_STWA, "stwa" },
262
  { HPPA_INS_STWAS, "stwas" },
263
  { HPPA_INS_STWS, "stws" },
264
  { HPPA_INS_STWM, "stwm" },
265
  { HPPA_INS_SUB, "sub" },
266
  { HPPA_INS_SUBB, "subb" },
267
  { HPPA_INS_SUBBO, "subbo" },
268
  { HPPA_INS_SUBI, "subi" },
269
  { HPPA_INS_SUBIO, "subio" },
270
  { HPPA_INS_SUBO, "subo" },
271
  { HPPA_INS_SUBT, "subt" },
272
  { HPPA_INS_SUBTO, "subto" },
273
  { HPPA_INS_SYNC, "sync" },
274
  { HPPA_INS_SYNCDMA, "syncdma" },
275
  { HPPA_INS_TOCDIS, "tocdis" },
276
  { HPPA_INS_TOCEN, "tocen" },
277
  { HPPA_INS_UADDCM, "uaddcm" },
278
  { HPPA_INS_UADDCMT, "uaddcmt" },
279
  { HPPA_INS_UXOR, "uxor" },
280
  { HPPA_INS_VDEP, "vdep" },
281
  { HPPA_INS_VDEPI, "vdepi" },
282
  { HPPA_INS_VEXTRS, "vextrs" },
283
  { HPPA_INS_VEXTRU, "vextru" },
284
  { HPPA_INS_VSHD, "vshd" },
285
  { HPPA_INS_XMPYU, "xmpyu" },
286
  { HPPA_INS_XOR, "xor" },
287
  { HPPA_INS_ZDEP, "zdep" },
288
  { HPPA_INS_ZDEPI, "zdepi" },
289
  { HPPA_INS_ZVDEP, "zvdep" },
290
  { HPPA_INS_ZVDEPI, "zvdepi" },
291
};
292
#endif
293
294
const char *HPPA_insn_name(csh handle, unsigned int id)
295
0
{
296
0
#ifndef CAPSTONE_DIET
297
0
  return id2name(insn_name_maps, ARR_SIZE(insn_name_maps), id);
298
#else
299
  return NULL;
300
#endif
301
0
}
302
303
#ifndef CAPSTONE_DIET
304
/* Integer register names, indexed by the numbers which appear in the
305
   opcodes.  */
306
static const char *const reg_names[] = {
307
  "flags", "r1",  "rp",  "r3",  "r4",   "r5",   "r6",  "r7",
308
  "r8",  "r9",  "r10", "r11", "r12",  "r13",  "r14", "r15",
309
  "r16",   "r17", "r18", "r19", "r20",  "r21",  "r22", "r23",
310
  "r24",   "r25", "r26", "dp",  "ret0", "ret1", "sp",  "r31"
311
};
312
313
/* Floating point register names, indexed by the numbers which appear in the
314
   opcodes.  */
315
static const char *const fp_reg_names[] = {
316
  "fpsr", "fpe2", "fpe4", "fpe6", "fr4",  "fr5",  "fr6",  "fr7",
317
  "fr8",  "fr9",  "fr10", "fr11", "fr12", "fr13", "fr14", "fr15",
318
  "fr16", "fr17", "fr18", "fr19", "fr20", "fr21", "fr22", "fr23",
319
  "fr24", "fr25", "fr26", "fr27", "fr28", "fr29", "fr30", "fr31"
320
};
321
322
static const char *const control_reg[] = {
323
  "rctr",  "cr1",   "cr2",  "cr3", "cr4",   "cr5",   "cr6",  "cr7",
324
  "pidr1", "pidr2", "ccr",  "sar", "pidr3", "pidr4", "iva",  "eiem",
325
  "itmr",  "pcsq",  "pcoq", "iir", "isr",   "ior",   "ipsw", "eirr",
326
  "tr0",   "tr1",   "tr2",  "tr3", "tr4",   "tr5",   "tr6",  "tr7"
327
};
328
329
static const char *const space_reg[] = { "sr0", "sr1", "sr2", "sr3",
330
           "sr4", "sr5", "sr6", "sr7" };
331
332
static const char *const fpe_reg[] = {
333
  "fpe1",  "fpe3",  "fpe5",  "fpe7",  "fr4R",  "fr5R",  "fr6R",  "fr7R",
334
  "fr8R",  "fr9R",  "fr10R", "fr11R", "fr12R", "fr13R", "fr14R", "fr15R",
335
  "fr16R", "fr17R", "fr18R", "fr19R", "fr20R", "fr21R", "fr22R", "fr23R",
336
  "fr24R", "fr25R", "fr26R", "fr27R", "fr28R", "fr29R", "fr30R", "fr31R"
337
};
338
339
static const char *const sp_fp_reg[] = {
340
  "fr16L", "fr17L", "fr18L", "fr19L", "fr20L", "fr21L", "fr22L", "fr23L",
341
  "fr24L", "fr25L", "fr26L", "fr27L", "fr28L", "fr29L", "fr30L", "fr31L",
342
  "fr16R", "fr17R", "fr18R", "fr19R", "fr20R", "fr21R", "fr22R", "fr23R",
343
  "fr24R", "fr25R", "fr26R", "fr27R", "fr28R", "fr29R", "fr30R", "fr31R"
344
};
345
#endif
346
347
const char *HPPA_reg_name(csh handle, unsigned int reg)
348
0
{
349
0
#ifndef CAPSTONE_DIET
350
0
  if (reg >= HPPA_REG_GR0 && reg <= HPPA_REG_GR31)
351
0
    return reg_names[reg - HPPA_REG_GR0];
352
0
  else if (reg >= HPPA_REG_FPR0 && reg <= HPPA_REG_FPR31)
353
0
    return fp_reg_names[reg - HPPA_REG_FPR0];
354
0
  else if (reg >= HPPA_REG_SR0 && reg <= HPPA_REG_SR7)
355
0
    return space_reg[reg - HPPA_REG_SR0];
356
0
  else if (reg >= HPPA_REG_CR0 && reg <= HPPA_REG_CR31)
357
0
    return control_reg[reg - HPPA_REG_CR0];
358
0
  else if (reg >= HPPA_REG_FPE0 && reg <= HPPA_REG_FPE31)
359
0
    return fpe_reg[reg - HPPA_REG_FPE0];
360
0
  else if (reg >= HPPA_REG_SP_FPR0 && reg <= HPPA_REG_SP_FPR31)
361
0
    return sp_fp_reg[reg - HPPA_REG_SP_FPR0];
362
0
  return NULL;
363
#else
364
  return NULL;
365
#endif
366
0
}
367
368
void HPPA_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int opcode)
369
0
{
370
0
  insn->id = opcode;
371
0
}
372
373
static void sort_and_uniq(cs_regs arr, uint8_t n, uint8_t *new_n)
374
0
{
375
  /* arr is always a tiny (usually n < 3) array,
376
   * a simple O(n^2) sort is efficient enough. */
377
0
  int i;
378
0
  int j;
379
0
  int iMin;
380
0
  int tmp;
381
382
  /* a modified selection sort for sorting and making unique */
383
0
  for (j = 0; j < n; j++) {
384
    /* arr[iMin] will be min(arr[j .. n-1]) */
385
0
    iMin = j;
386
0
    for (i = j + 1; i < n; i++) {
387
0
      if (arr[i] < arr[iMin])
388
0
        iMin = i;
389
0
    }
390
0
    if (j != 0 && arr[iMin] == arr[j - 1]) { // duplicate ele found
391
0
      arr[iMin] = arr[n - 1];
392
0
      --n;
393
0
    } else {
394
0
      tmp = arr[iMin];
395
0
      arr[iMin] = arr[j];
396
0
      arr[j] = tmp;
397
0
    }
398
0
  }
399
400
0
  *new_n = n;
401
0
}
402
403
void HPPA_reg_access(const cs_insn *insn, cs_regs regs_read,
404
         uint8_t *regs_read_count, cs_regs regs_write,
405
         uint8_t *regs_write_count)
406
0
{
407
0
  uint8_t read_count = 0;
408
0
  uint8_t write_count = 0;
409
0
  const cs_hppa *hppa = &(insn->detail->hppa);
410
411
0
  for (unsigned i = 0; i < hppa->op_count; ++i) {
412
0
    const cs_hppa_op *op = &(hppa->operands[i]);
413
0
    switch (op->type) {
414
0
    case HPPA_OP_REG:
415
0
    case HPPA_OP_IDX_REG:
416
0
      if (op->access & CS_AC_READ) {
417
0
        regs_read[read_count++] = op->reg;
418
0
      }
419
0
      if (op->access & CS_AC_WRITE) {
420
0
        regs_write[write_count++] = op->reg;
421
0
      }
422
0
      break;
423
0
    case HPPA_OP_MEM:
424
0
      if (op->mem.space != HPPA_REG_INVALID)
425
0
        regs_read[read_count++] = op->mem.space;
426
0
      if (op->mem.base_access & CS_AC_READ) {
427
0
        regs_read[read_count++] = op->mem.base;
428
0
      }
429
0
      if (op->mem.base_access & CS_AC_WRITE) {
430
0
        regs_write[write_count++] = op->mem.base;
431
0
      }
432
0
      break;
433
0
    default:
434
0
      break;
435
0
    }
436
0
  }
437
438
0
  sort_and_uniq(regs_read, read_count, regs_read_count);
439
0
  sort_and_uniq(regs_write, write_count, regs_write_count);
440
0
}
441
442
#endif