/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 | assert(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 | assert(!(map_get_op_type(MI, OpNum) & CS_OP_MEM)); |
59 | 0 | assert(map_get_op_type(MI, OpNum) == CS_OP_IMM); |
60 | 0 | assert(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 | assert(!(map_get_op_type(MI, OpNum) & CS_OP_MEM)); |
73 | 0 | assert(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) { return; } |
88 | 0 | insn->id = insns[i].mapid; |
89 | |
|
90 | 0 | if (insn->detail) { |
91 | 0 | #ifndef CAPSTONE_DIET |
92 | 0 | memcpy(insn->detail->regs_read, insns[i].regs_use, |
93 | 0 | sizeof(insns[i].regs_use)); |
94 | 0 | insn->detail->regs_read_count = |
95 | 0 | (uint8_t)count_positive(insns[i].regs_use); |
96 | |
|
97 | 0 | memcpy(insn->detail->regs_write, insns[i].regs_mod, |
98 | 0 | sizeof(insns[i].regs_mod)); |
99 | 0 | insn->detail->regs_write_count = |
100 | 0 | (uint8_t)count_positive(insns[i].regs_mod); |
101 | |
|
102 | 0 | memcpy(insn->detail->groups, insns[i].groups, |
103 | 0 | sizeof(insns[i].groups)); |
104 | 0 | insn->detail->groups_count = |
105 | 0 | (uint8_t)count_positive8(insns[i].groups); |
106 | 0 | #endif |
107 | 0 | } |
108 | 0 | } |
109 | | |
110 | | #ifndef CAPSTONE_DIET |
111 | | |
112 | | static const char * const insn_names[] = { |
113 | | #include "AlphaGenCSMappingInsnName.inc" |
114 | | }; |
115 | | |
116 | | // special alias insn |
117 | | // static name_map alias_insn_names[] = {{0, NULL}}; |
118 | | #endif |
119 | | |
120 | | const char *Alpha_insn_name(csh handle, unsigned int id) |
121 | 0 | { |
122 | 0 | #ifndef CAPSTONE_DIET |
123 | 0 | if (id >= ALPHA_INS_ENDING) |
124 | 0 | return NULL; |
125 | | |
126 | 0 | if (id < ARR_SIZE(insn_names)) |
127 | 0 | return insn_names[id]; |
128 | | |
129 | 0 | return NULL; |
130 | | #else |
131 | | return NULL; |
132 | | #endif |
133 | 0 | } |
134 | | |
135 | | #ifndef CAPSTONE_DIET |
136 | | static const name_map group_name_maps[] = { |
137 | | {Alpha_GRP_INVALID, NULL}, |
138 | | {Alpha_GRP_CALL, "call"}, |
139 | | {Alpha_GRP_JUMP, "jump"}, |
140 | | {Alpha_GRP_BRANCH_RELATIVE, "branch_relative"}, |
141 | | }; |
142 | | #endif |
143 | | |
144 | | const char *Alpha_group_name(csh handle, unsigned int id) |
145 | 0 | { |
146 | 0 | #ifndef CAPSTONE_DIET |
147 | 0 | return id2name(group_name_maps, ARR_SIZE(group_name_maps), id); |
148 | | #else |
149 | | return NULL; |
150 | | #endif |
151 | 0 | } |
152 | | |
153 | | const char *Alpha_getRegisterName(csh handle, unsigned int id) |
154 | 0 | { |
155 | 0 | return Alpha_LLVM_getRegisterName(handle, id); |
156 | 0 | } |
157 | | |
158 | | void Alpha_printInst(MCInst *MI, SStream *O, void *Info) |
159 | 0 | { |
160 | 0 | Alpha_LLVM_printInstruction(MI, O, Info); |
161 | 0 | } |
162 | | |
163 | | void Alpha_set_instr_map_data(MCInst *MI) |
164 | 0 | { |
165 | 0 | map_cs_id(MI, insns, ARR_SIZE(insns)); |
166 | 0 | map_implicit_reads(MI, insns); |
167 | 0 | map_implicit_writes(MI, insns); |
168 | 0 | map_groups(MI, insns); |
169 | 0 | } |
170 | | |
171 | | bool Alpha_getInstruction(csh handle, const uint8_t *code, |
172 | | size_t code_len, MCInst *instr, |
173 | | uint16_t *size, uint64_t address, void *info) |
174 | 0 | { |
175 | 0 | Alpha_init_cs_detail(instr); |
176 | 0 | bool Result = Alpha_LLVM_getInstruction(handle, code, code_len, instr, size, |
177 | 0 | address, info); |
178 | 0 | Alpha_set_instr_map_data(instr); |
179 | 0 | return Result; |
180 | 0 | } |
181 | | |
182 | | #endif |