Coverage Report

Created: 2026-02-26 07:11

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