Coverage Report

Created: 2024-09-08 06:22

/src/capstonev5/arch/TriCore/TriCoreMapping.c
Line
Count
Source (jump to first uncovered line)
1
/* Capstone Disassembly Engine */
2
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */
3
4
#ifdef CAPSTONE_HAS_TRICORE
5
6
#include <stdio.h> // debug
7
#include <string.h>
8
#include <assert.h>
9
10
#include "../../utils.h"
11
#include "../../cs_simple_types.h"
12
13
#include "TriCoreMapping.h"
14
#include "TriCoreLinkage.h"
15
16
#define GET_INSTRINFO_ENUM
17
18
#include "TriCoreGenInstrInfo.inc"
19
20
static const insn_map insns[] = {
21
  // dummy item
22
  { 0,
23
    0,
24
#ifndef CAPSTONE_DIET
25
    { 0 },
26
    { 0 },
27
    { 0 },
28
    0,
29
    0
30
#endif
31
  },
32
33
#include "TriCoreGenCSMappingInsn.inc"
34
};
35
36
void TriCore_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id)
37
0
{
38
  // Not used. Information is set after disassembly.
39
0
}
40
41
#ifndef CAPSTONE_DIET
42
static const tricore_reg flag_regs[] = { TRICORE_REG_PSW };
43
#endif // CAPSTONE_DIET
44
45
static inline void check_updates_flags(MCInst *MI)
46
0
{
47
0
#ifndef CAPSTONE_DIET
48
0
  if (!MI->flat_insn->detail)
49
0
    return;
50
0
  cs_detail *detail = MI->flat_insn->detail;
51
0
  for (int i = 0; i < detail->regs_write_count; ++i) {
52
0
    if (detail->regs_write[i] == 0)
53
0
      return;
54
0
    for (int j = 0; j < ARR_SIZE(flag_regs); ++j) {
55
0
      if (detail->regs_write[i] == flag_regs[j]) {
56
0
        detail->tricore.update_flags = true;
57
0
        return;
58
0
      }
59
0
    }
60
0
  }
61
0
#endif // CAPSTONE_DIET
62
0
}
63
64
void TriCore_set_instr_map_data(MCInst *MI)
65
0
{
66
0
  map_cs_id(MI, insns, ARR_SIZE(insns));
67
0
  map_implicit_reads(MI, insns);
68
0
  map_implicit_writes(MI, insns);
69
0
  check_updates_flags(MI);
70
0
  map_groups(MI, insns);
71
0
}
72
73
#ifndef CAPSTONE_DIET
74
75
static const char * const insn_names[] = {
76
  NULL,
77
78
#include "TriCoreGenCSMappingInsnName.inc"
79
};
80
81
// special alias insn
82
static const name_map alias_insn_names[] = { { 0, NULL } };
83
#endif
84
85
const char *TriCore_insn_name(csh handle, unsigned int id)
86
0
{
87
0
#ifndef CAPSTONE_DIET
88
0
  unsigned int i;
89
90
0
  if (id >= TRICORE_INS_ENDING)
91
0
    return NULL;
92
93
  // handle special alias first
94
0
  for (i = 0; i < ARR_SIZE(alias_insn_names); i++) {
95
0
    if (alias_insn_names[i].id == id)
96
0
      return alias_insn_names[i].name;
97
0
  }
98
99
0
  return insn_names[id];
100
#else
101
  return NULL;
102
#endif
103
0
}
104
105
#ifndef CAPSTONE_DIET
106
static const name_map group_name_maps[] = {
107
  { TRICORE_GRP_INVALID, NULL },
108
  { TRICORE_GRP_CALL, "call" },
109
  { TRICORE_GRP_JUMP, "jump" },
110
};
111
#endif
112
113
const char *TriCore_group_name(csh handle, unsigned int id)
114
0
{
115
0
#ifndef CAPSTONE_DIET
116
0
  if (id >= TRICORE_GRP_ENDING)
117
0
    return NULL;
118
119
0
  return group_name_maps[id].name;
120
#else
121
  return NULL;
122
#endif
123
0
}
124
125
#ifndef CAPSTONE_DIET
126
/// A LLVM<->CS Mapping entry of an operand.
127
typedef struct insn_op {
128
  uint8_t /* cs_op_type */ type;   ///< Operand type (e.g.: reg, imm, mem)
129
  uint8_t /* cs_ac_type */ access; ///< The access type (read, write)
130
  uint8_t        /* cs_data_type */
131
    dtypes[10]; ///< List of op types. Terminated by CS_DATA_TYPE_LAST
132
} insn_op;
133
134
///< Operands of an instruction.
135
typedef struct {
136
  insn_op ops[16]; ///< NULL terminated array of operands.
137
} insn_ops;
138
139
const insn_ops insn_operands[] = {
140
#include "TriCoreGenCSMappingInsnOp.inc"
141
};
142
#endif
143
144
void TriCore_set_access(MCInst *MI)
145
0
{
146
0
#ifndef CAPSTONE_DIET
147
0
  if (!(MI->csh->detail == CS_OPT_ON && MI->flat_insn->detail))
148
0
    return;
149
150
0
  assert(MI->Opcode < ARR_SIZE(insn_operands));
151
152
0
  cs_detail *detail = MI->flat_insn->detail;
153
0
  cs_tricore *tc = &(detail->tricore);
154
0
  for (int i = 0; i < tc->op_count; ++i) {
155
0
    cs_ac_type ac = map_get_op_access(MI, i);
156
0
    cs_tricore_op *op = &tc->operands[i];
157
0
    op->access = ac;
158
0
    cs_op_type op_type = map_get_op_type(MI, i);
159
0
    if (op_type != CS_OP_REG) {
160
0
      continue;
161
0
    }
162
0
    if (ac & CS_AC_READ) {
163
0
      detail->regs_read[detail->regs_read_count++] = op->reg;
164
0
    }
165
0
    if (ac & CS_AC_WRITE) {
166
0
      detail->regs_write[detail->regs_write_count++] =
167
0
        op->reg;
168
0
    }
169
0
  }
170
0
#endif
171
0
}
172
173
void TriCore_reg_access(const cs_insn *insn, cs_regs regs_read,
174
      uint8_t *regs_read_count, cs_regs regs_write,
175
      uint8_t *regs_write_count)
176
0
{
177
0
#ifndef CAPSTONE_DIET
178
0
  uint8_t read_count, write_count;
179
0
  cs_detail *detail = insn->detail;
180
0
  read_count = detail->regs_read_count;
181
0
  write_count = detail->regs_write_count;
182
183
  // implicit registers
184
0
  memcpy(regs_read, detail->regs_read,
185
0
         read_count * sizeof(detail->regs_read[0]));
186
0
  memcpy(regs_write, detail->regs_write,
187
0
         write_count * sizeof(detail->regs_write[0]));
188
189
  // explicit registers
190
0
  cs_tricore *tc = &detail->tricore;
191
0
  for (uint8_t i = 0; i < tc->op_count; i++) {
192
0
    cs_tricore_op *op = &(tc->operands[i]);
193
0
    switch ((int)op->type) {
194
0
    case TRICORE_OP_REG:
195
0
      if ((op->access & CS_AC_READ) &&
196
0
          !arr_exist(regs_read, read_count, op->reg)) {
197
0
        regs_read[read_count] = (uint16_t)op->reg;
198
0
        read_count++;
199
0
      }
200
0
      if ((op->access & CS_AC_WRITE) &&
201
0
          !arr_exist(regs_write, write_count, op->reg)) {
202
0
        regs_write[write_count] = (uint16_t)op->reg;
203
0
        write_count++;
204
0
      }
205
0
      break;
206
0
    case TRICORE_OP_MEM:
207
      // registers appeared in memory references always being read
208
0
      if ((op->mem.base != ARM_REG_INVALID) &&
209
0
          !arr_exist(regs_read, read_count, op->mem.base)) {
210
0
        regs_read[read_count] = (uint16_t)op->mem.base;
211
0
        read_count++;
212
0
      }
213
0
    default:
214
0
      break;
215
0
    }
216
0
  }
217
218
0
  *regs_read_count = read_count;
219
0
  *regs_write_count = write_count;
220
0
#endif
221
0
}
222
223
bool TriCore_getInstruction(csh handle, const uint8_t *Bytes, size_t ByteLen,
224
          MCInst *MI, uint16_t *Size, uint64_t Address,
225
          void *Info)
226
0
{
227
0
  return TriCore_LLVM_getInstruction(handle, Bytes, ByteLen, MI, Size,
228
0
             Address, Info);
229
0
}
230
231
void TriCore_printInst(MCInst *MI, SStream *O, void *Info)
232
0
{
233
0
  TriCore_LLVM_printInst(MI, MI->address, O);
234
0
}
235
236
const char *TriCore_getRegisterName(csh handle, unsigned int RegNo)
237
0
{
238
0
  return TriCore_LLVM_getRegisterName(RegNo);
239
0
}
240
241
#endif // CAPSTONE_HAS_TRICORE