Coverage Report

Created: 2025-08-28 06:43

/src/capstonenext/arch/Alpha/AlphaMapping.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_ALPHA
5
6
#include <stdio.h> // debug
7
#include <string.h>
8
9
#include "../../Mapping.h"
10
#include "../../cs_priv.h"
11
#include "../../cs_simple_types.h"
12
#include "../../utils.h"
13
14
#include "AlphaLinkage.h"
15
#include "AlphaMapping.h"
16
#include "./AlphaDisassembler.h"
17
18
#define GET_INSTRINFO_ENUM
19
20
#include "AlphaGenInstrInfo.inc"
21
22
static const insn_map insns[] = {
23
#include "AlphaGenCSMappingInsn.inc"
24
};
25
26
static const map_insn_ops insn_operands[] = {
27
#include "AlphaGenCSMappingInsnOp.inc"
28
};
29
30
void Alpha_init_cs_detail(MCInst *MI)
31
0
{
32
0
  if (detail_is_set(MI)) {
33
0
    memset(get_detail(MI), 0,
34
0
           offsetof(cs_detail, alpha) + sizeof(cs_alpha));
35
0
  }
36
0
}
37
38
void Alpha_add_cs_detail(MCInst *MI, unsigned OpNum)
39
0
{
40
0
  if (!detail_is_set(MI))
41
0
    return;
42
43
0
  cs_op_type op_type = map_get_op_type(MI, OpNum);
44
0
  if (op_type == CS_OP_IMM)
45
0
    Alpha_set_detail_op_imm(MI, OpNum, ALPHA_OP_IMM,
46
0
          MCInst_getOpVal(MI, OpNum));
47
0
  else if (op_type == CS_OP_REG)
48
0
    Alpha_set_detail_op_reg(MI, OpNum, MCInst_getOpVal(MI, OpNum));
49
0
  else
50
0
    CS_ASSERT_RET(0 && "Op type not handled.");
51
0
}
52
53
void Alpha_set_detail_op_imm(MCInst *MI, unsigned OpNum, alpha_op_type ImmType,
54
           int64_t Imm)
55
0
{
56
0
  if (!detail_is_set(MI))
57
0
    return;
58
0
  CS_ASSERT_RET(!(map_get_op_type(MI, OpNum) & CS_OP_MEM));
59
0
  CS_ASSERT_RET(map_get_op_type(MI, OpNum) == CS_OP_IMM);
60
0
  CS_ASSERT_RET(ImmType == ALPHA_OP_IMM);
61
62
0
  Alpha_get_detail_op(MI, 0)->type = ImmType;
63
0
  Alpha_get_detail_op(MI, 0)->imm = Imm;
64
0
  Alpha_get_detail_op(MI, 0)->access = map_get_op_access(MI, OpNum);
65
0
  Alpha_inc_op_count(MI);
66
0
}
67
68
void Alpha_set_detail_op_reg(MCInst *MI, unsigned OpNum, alpha_op_type Reg)
69
0
{
70
0
  if (!detail_is_set(MI))
71
0
    return;
72
0
  CS_ASSERT_RET(!(map_get_op_type(MI, OpNum) & CS_OP_MEM));
73
0
  CS_ASSERT_RET(map_get_op_type(MI, OpNum) == CS_OP_REG);
74
75
0
  Alpha_get_detail_op(MI, 0)->type = ALPHA_OP_REG;
76
0
  Alpha_get_detail_op(MI, 0)->reg = Reg;
77
0
  Alpha_get_detail_op(MI, 0)->access = map_get_op_access(MI, OpNum);
78
0
  Alpha_inc_op_count(MI);
79
0
}
80
81
// given internal insn id, return public instruction info
82
void Alpha_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id)
83
0
{
84
0
  unsigned short i;
85
86
0
  i = insn_find(insns, ARR_SIZE(insns), id, &h->insn_cache);
87
0
  if (i == 0) {
88
0
    return;
89
0
  }
90
0
  insn->id = insns[i].mapid;
91
92
0
  if (insn->detail) {
93
0
#ifndef CAPSTONE_DIET
94
0
    memcpy(insn->detail->regs_read, insns[i].regs_use,
95
0
           sizeof(insns[i].regs_use));
96
0
    insn->detail->regs_read_count =
97
0
      (uint8_t)count_positive(insns[i].regs_use);
98
99
0
    memcpy(insn->detail->regs_write, insns[i].regs_mod,
100
0
           sizeof(insns[i].regs_mod));
101
0
    insn->detail->regs_write_count =
102
0
      (uint8_t)count_positive(insns[i].regs_mod);
103
104
0
    memcpy(insn->detail->groups, insns[i].groups,
105
0
           sizeof(insns[i].groups));
106
0
    insn->detail->groups_count =
107
0
      (uint8_t)count_positive8(insns[i].groups);
108
0
#endif
109
0
  }
110
0
}
111
112
#ifndef CAPSTONE_DIET
113
114
static const char *const insn_names[] = {
115
#include "AlphaGenCSMappingInsnName.inc"
116
};
117
118
// special alias insn
119
// static name_map alias_insn_names[] = {{0, NULL}};
120
#endif
121
122
const char *Alpha_insn_name(csh handle, unsigned int id)
123
0
{
124
0
#ifndef CAPSTONE_DIET
125
0
  if (id >= ALPHA_INS_ENDING)
126
0
    return NULL;
127
128
0
  if (id < ARR_SIZE(insn_names))
129
0
    return insn_names[id];
130
131
0
  return NULL;
132
#else
133
  return NULL;
134
#endif
135
0
}
136
137
#ifndef CAPSTONE_DIET
138
static const name_map group_name_maps[] = {
139
  { Alpha_GRP_INVALID, NULL },
140
  { Alpha_GRP_CALL, "call" },
141
  { Alpha_GRP_JUMP, "jump" },
142
  { Alpha_GRP_BRANCH_RELATIVE, "branch_relative" },
143
};
144
#endif
145
146
const char *Alpha_group_name(csh handle, unsigned int id)
147
0
{
148
0
#ifndef CAPSTONE_DIET
149
0
  return id2name(group_name_maps, ARR_SIZE(group_name_maps), id);
150
#else
151
  return NULL;
152
#endif
153
0
}
154
155
const char *Alpha_getRegisterName(csh handle, unsigned int id)
156
0
{
157
0
  return Alpha_LLVM_getRegisterName(handle, id);
158
0
}
159
160
void Alpha_printInst(MCInst *MI, SStream *O, void *Info)
161
0
{
162
0
  Alpha_LLVM_printInstruction(MI, O, Info);
163
0
}
164
165
void Alpha_set_instr_map_data(MCInst *MI)
166
0
{
167
0
  map_cs_id(MI, insns, ARR_SIZE(insns));
168
0
  map_implicit_reads(MI, insns);
169
0
  map_implicit_writes(MI, insns);
170
0
  map_groups(MI, insns);
171
0
}
172
173
bool Alpha_getInstruction(csh handle, const uint8_t *code, size_t code_len,
174
        MCInst *instr, uint16_t *size, uint64_t address,
175
        void *info)
176
0
{
177
0
  Alpha_init_cs_detail(instr);
178
0
  DecodeStatus Result = Alpha_LLVM_getInstruction(
179
0
    handle, code, code_len, instr, size, address, info);
180
0
  Alpha_set_instr_map_data(instr);
181
0
  if (Result == MCDisassembler_SoftFail) {
182
0
    MCInst_setSoftFail(instr);
183
0
  }
184
0
  return Result != MCDisassembler_Fail;
185
0
}
186
187
#ifndef CAPSTONE_DIET
188
void Alpha_reg_access(const cs_insn *insn, cs_regs regs_read,
189
          uint8_t *regs_read_count, cs_regs regs_write,
190
          uint8_t *regs_write_count)
191
0
{
192
0
  uint8_t i;
193
0
  uint8_t read_count, write_count;
194
0
  cs_alpha *alpha = &(insn->detail->alpha);
195
196
0
  read_count = insn->detail->regs_read_count;
197
0
  write_count = insn->detail->regs_write_count;
198
199
  // implicit registers
200
0
  memcpy(regs_read, insn->detail->regs_read,
201
0
         read_count * sizeof(insn->detail->regs_read[0]));
202
0
  memcpy(regs_write, insn->detail->regs_write,
203
0
         write_count * sizeof(insn->detail->regs_write[0]));
204
205
  // explicit registers
206
0
  for (i = 0; i < alpha->op_count; i++) {
207
0
    cs_alpha_op *op = &(alpha->operands[i]);
208
0
    switch ((int)op->type) {
209
0
    case ALPHA_OP_REG:
210
0
      if ((op->access & CS_AC_READ) &&
211
0
          !arr_exist(regs_read, read_count, op->reg)) {
212
0
        regs_read[read_count] = (uint16_t)op->reg;
213
0
        read_count++;
214
0
      }
215
0
      if ((op->access & CS_AC_WRITE) &&
216
0
          !arr_exist(regs_write, write_count, op->reg)) {
217
0
        regs_write[write_count] = (uint16_t)op->reg;
218
0
        write_count++;
219
0
      }
220
0
      break;
221
0
    default:
222
0
      break;
223
0
    }
224
0
  }
225
226
0
  *regs_read_count = read_count;
227
0
  *regs_write_count = write_count;
228
0
}
229
#endif
230
231
#endif