/src/capstonev5/arch/PowerPC/PPCMapping.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Capstone Disassembly Engine */ |
2 | | /* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */ |
3 | | |
4 | | #ifdef CAPSTONE_HAS_POWERPC |
5 | | |
6 | | #include <stdio.h> // debug |
7 | | #include <string.h> |
8 | | |
9 | | #include "../../utils.h" |
10 | | |
11 | | #include "PPCMapping.h" |
12 | | |
13 | | #define GET_INSTRINFO_ENUM |
14 | | #include "PPCGenInstrInfo.inc" |
15 | | |
16 | | // NOTE: this reg_name_maps[] reflects the order of registers in ppc_reg |
17 | | static const name_map reg_name_maps[] = { |
18 | | { PPC_REG_INVALID, NULL }, |
19 | | |
20 | | { PPC_REG_CARRY, "ca" }, |
21 | | { PPC_REG_CTR, "ctr" }, |
22 | | { PPC_REG_LR, "lr" }, |
23 | | { PPC_REG_RM, "rm" }, |
24 | | { PPC_REG_VRSAVE, "vrsave" }, |
25 | | { PPC_REG_XER, "xer" }, |
26 | | { PPC_REG_ZERO, "zero" }, |
27 | | { PPC_REG_CR0, "cr0" }, |
28 | | { PPC_REG_CR1, "cr1" }, |
29 | | { PPC_REG_CR2, "cr2" }, |
30 | | { PPC_REG_CR3, "cr3" }, |
31 | | { PPC_REG_CR4, "cr4" }, |
32 | | { PPC_REG_CR5, "cr5" }, |
33 | | { PPC_REG_CR6, "cr6" }, |
34 | | { PPC_REG_CR7, "cr7" }, |
35 | | { PPC_REG_CTR8, "ctr8" }, |
36 | | { PPC_REG_F0, "f0" }, |
37 | | { PPC_REG_F1, "f1" }, |
38 | | { PPC_REG_F2, "f2" }, |
39 | | { PPC_REG_F3, "f3" }, |
40 | | { PPC_REG_F4, "f4" }, |
41 | | { PPC_REG_F5, "f5" }, |
42 | | { PPC_REG_F6, "f6" }, |
43 | | { PPC_REG_F7, "f7" }, |
44 | | { PPC_REG_F8, "f8" }, |
45 | | { PPC_REG_F9, "f9" }, |
46 | | { PPC_REG_F10, "f10" }, |
47 | | { PPC_REG_F11, "f11" }, |
48 | | { PPC_REG_F12, "f12" }, |
49 | | { PPC_REG_F13, "f13" }, |
50 | | { PPC_REG_F14, "f14" }, |
51 | | { PPC_REG_F15, "f15" }, |
52 | | { PPC_REG_F16, "f16" }, |
53 | | { PPC_REG_F17, "f17" }, |
54 | | { PPC_REG_F18, "f18" }, |
55 | | { PPC_REG_F19, "f19" }, |
56 | | { PPC_REG_F20, "f20" }, |
57 | | { PPC_REG_F21, "f21" }, |
58 | | { PPC_REG_F22, "f22" }, |
59 | | { PPC_REG_F23, "f23" }, |
60 | | { PPC_REG_F24, "f24" }, |
61 | | { PPC_REG_F25, "f25" }, |
62 | | { PPC_REG_F26, "f26" }, |
63 | | { PPC_REG_F27, "f27" }, |
64 | | { PPC_REG_F28, "f28" }, |
65 | | { PPC_REG_F29, "f29" }, |
66 | | { PPC_REG_F30, "f30" }, |
67 | | { PPC_REG_F31, "f31" }, |
68 | | { PPC_REG_LR8, "lr8" }, |
69 | | |
70 | | { PPC_REG_Q0, "q0" }, |
71 | | { PPC_REG_Q1, "q1" }, |
72 | | { PPC_REG_Q2, "q2" }, |
73 | | { PPC_REG_Q3, "q3" }, |
74 | | { PPC_REG_Q4, "q4" }, |
75 | | { PPC_REG_Q5, "q5" }, |
76 | | { PPC_REG_Q6, "q6" }, |
77 | | { PPC_REG_Q7, "q7" }, |
78 | | { PPC_REG_Q8, "q8" }, |
79 | | { PPC_REG_Q9, "q9" }, |
80 | | { PPC_REG_Q10, "q10" }, |
81 | | { PPC_REG_Q11, "q11" }, |
82 | | { PPC_REG_Q12, "q12" }, |
83 | | { PPC_REG_Q13, "q13" }, |
84 | | { PPC_REG_Q14, "q14" }, |
85 | | { PPC_REG_Q15, "q15" }, |
86 | | { PPC_REG_Q16, "q16" }, |
87 | | { PPC_REG_Q17, "q17" }, |
88 | | { PPC_REG_Q18, "q18" }, |
89 | | { PPC_REG_Q19, "q19" }, |
90 | | { PPC_REG_Q20, "q20" }, |
91 | | { PPC_REG_Q21, "q21" }, |
92 | | { PPC_REG_Q22, "q22" }, |
93 | | { PPC_REG_Q23, "q23" }, |
94 | | { PPC_REG_Q24, "q24" }, |
95 | | { PPC_REG_Q25, "q25" }, |
96 | | { PPC_REG_Q26, "q26" }, |
97 | | { PPC_REG_Q27, "q27" }, |
98 | | { PPC_REG_Q28, "q28" }, |
99 | | { PPC_REG_Q29, "q29" }, |
100 | | { PPC_REG_Q30, "q30" }, |
101 | | { PPC_REG_Q31, "q31" }, |
102 | | { PPC_REG_R0, "r0" }, |
103 | | { PPC_REG_R1, "r1" }, |
104 | | { PPC_REG_R2, "r2" }, |
105 | | { PPC_REG_R3, "r3" }, |
106 | | { PPC_REG_R4, "r4" }, |
107 | | { PPC_REG_R5, "r5" }, |
108 | | { PPC_REG_R6, "r6" }, |
109 | | { PPC_REG_R7, "r7" }, |
110 | | { PPC_REG_R8, "r8" }, |
111 | | { PPC_REG_R9, "r9" }, |
112 | | { PPC_REG_R10, "r10" }, |
113 | | { PPC_REG_R11, "r11" }, |
114 | | { PPC_REG_R12, "r12" }, |
115 | | { PPC_REG_R13, "r13" }, |
116 | | { PPC_REG_R14, "r14" }, |
117 | | { PPC_REG_R15, "r15" }, |
118 | | { PPC_REG_R16, "r16" }, |
119 | | { PPC_REG_R17, "r17" }, |
120 | | { PPC_REG_R18, "r18" }, |
121 | | { PPC_REG_R19, "r19" }, |
122 | | { PPC_REG_R20, "r20" }, |
123 | | { PPC_REG_R21, "r21" }, |
124 | | { PPC_REG_R22, "r22" }, |
125 | | { PPC_REG_R23, "r23" }, |
126 | | { PPC_REG_R24, "r24" }, |
127 | | { PPC_REG_R25, "r25" }, |
128 | | { PPC_REG_R26, "r26" }, |
129 | | { PPC_REG_R27, "r27" }, |
130 | | { PPC_REG_R28, "r28" }, |
131 | | { PPC_REG_R29, "r29" }, |
132 | | { PPC_REG_R30, "r30" }, |
133 | | { PPC_REG_R31, "r31" }, |
134 | | { PPC_REG_V0, "v0" }, |
135 | | { PPC_REG_V1, "v1" }, |
136 | | { PPC_REG_V2, "v2" }, |
137 | | { PPC_REG_V3, "v3" }, |
138 | | { PPC_REG_V4, "v4" }, |
139 | | { PPC_REG_V5, "v5" }, |
140 | | { PPC_REG_V6, "v6" }, |
141 | | { PPC_REG_V7, "v7" }, |
142 | | { PPC_REG_V8, "v8" }, |
143 | | { PPC_REG_V9, "v9" }, |
144 | | { PPC_REG_V10, "v10" }, |
145 | | { PPC_REG_V11, "v11" }, |
146 | | { PPC_REG_V12, "v12" }, |
147 | | { PPC_REG_V13, "v13" }, |
148 | | { PPC_REG_V14, "v14" }, |
149 | | { PPC_REG_V15, "v15" }, |
150 | | { PPC_REG_V16, "v16" }, |
151 | | { PPC_REG_V17, "v17" }, |
152 | | { PPC_REG_V18, "v18" }, |
153 | | { PPC_REG_V19, "v19" }, |
154 | | { PPC_REG_V20, "v20" }, |
155 | | { PPC_REG_V21, "v21" }, |
156 | | { PPC_REG_V22, "v22" }, |
157 | | { PPC_REG_V23, "v23" }, |
158 | | { PPC_REG_V24, "v24" }, |
159 | | { PPC_REG_V25, "v25" }, |
160 | | { PPC_REG_V26, "v26" }, |
161 | | { PPC_REG_V27, "v27" }, |
162 | | { PPC_REG_V28, "v28" }, |
163 | | { PPC_REG_V29, "v29" }, |
164 | | { PPC_REG_V30, "v30" }, |
165 | | { PPC_REG_V31, "v31" }, |
166 | | { PPC_REG_VS0, "vs0" }, |
167 | | { PPC_REG_VS1, "vs1" }, |
168 | | { PPC_REG_VS2, "vs2" }, |
169 | | { PPC_REG_VS3, "vs3" }, |
170 | | { PPC_REG_VS4, "vs4" }, |
171 | | { PPC_REG_VS5, "vs5" }, |
172 | | { PPC_REG_VS6, "vs6" }, |
173 | | { PPC_REG_VS7, "vs7" }, |
174 | | { PPC_REG_VS8, "vs8" }, |
175 | | { PPC_REG_VS9, "vs9" }, |
176 | | { PPC_REG_VS10, "vs10" }, |
177 | | { PPC_REG_VS11, "vs11" }, |
178 | | { PPC_REG_VS12, "vs12" }, |
179 | | { PPC_REG_VS13, "vs13" }, |
180 | | { PPC_REG_VS14, "vs14" }, |
181 | | { PPC_REG_VS15, "vs15" }, |
182 | | { PPC_REG_VS16, "vs16" }, |
183 | | { PPC_REG_VS17, "vs17" }, |
184 | | { PPC_REG_VS18, "vs18" }, |
185 | | { PPC_REG_VS19, "vs19" }, |
186 | | { PPC_REG_VS20, "vs20" }, |
187 | | { PPC_REG_VS21, "vs21" }, |
188 | | { PPC_REG_VS22, "vs22" }, |
189 | | { PPC_REG_VS23, "vs23" }, |
190 | | { PPC_REG_VS24, "vs24" }, |
191 | | { PPC_REG_VS25, "vs25" }, |
192 | | { PPC_REG_VS26, "vs26" }, |
193 | | { PPC_REG_VS27, "vs27" }, |
194 | | { PPC_REG_VS28, "vs28" }, |
195 | | { PPC_REG_VS29, "vs29" }, |
196 | | { PPC_REG_VS30, "vs30" }, |
197 | | { PPC_REG_VS31, "vs31" }, |
198 | | |
199 | | { PPC_REG_VS32, "vs32" }, |
200 | | { PPC_REG_VS33, "vs33" }, |
201 | | { PPC_REG_VS34, "vs34" }, |
202 | | { PPC_REG_VS35, "vs35" }, |
203 | | { PPC_REG_VS36, "vs36" }, |
204 | | { PPC_REG_VS37, "vs37" }, |
205 | | { PPC_REG_VS38, "vs38" }, |
206 | | { PPC_REG_VS39, "vs39" }, |
207 | | { PPC_REG_VS40, "vs40" }, |
208 | | { PPC_REG_VS41, "vs41" }, |
209 | | { PPC_REG_VS42, "vs42" }, |
210 | | { PPC_REG_VS43, "vs43" }, |
211 | | { PPC_REG_VS44, "vs44" }, |
212 | | { PPC_REG_VS45, "vs45" }, |
213 | | { PPC_REG_VS46, "vs46" }, |
214 | | { PPC_REG_VS47, "vs47" }, |
215 | | { PPC_REG_VS48, "vs48" }, |
216 | | { PPC_REG_VS49, "vs49" }, |
217 | | { PPC_REG_VS50, "vs50" }, |
218 | | { PPC_REG_VS51, "vs51" }, |
219 | | { PPC_REG_VS52, "vs52" }, |
220 | | { PPC_REG_VS53, "vs53" }, |
221 | | { PPC_REG_VS54, "vs54" }, |
222 | | { PPC_REG_VS55, "vs55" }, |
223 | | { PPC_REG_VS56, "vs56" }, |
224 | | { PPC_REG_VS57, "vs57" }, |
225 | | { PPC_REG_VS58, "vs58" }, |
226 | | { PPC_REG_VS59, "vs59" }, |
227 | | { PPC_REG_VS60, "vs60" }, |
228 | | { PPC_REG_VS61, "vs61" }, |
229 | | { PPC_REG_VS62, "vs62" }, |
230 | | { PPC_REG_VS63, "vs63" }, |
231 | | |
232 | | { PPC_REG_CR0EQ, "cr0eq" }, |
233 | | { PPC_REG_CR1EQ, "cr1eq" }, |
234 | | { PPC_REG_CR2EQ, "cr2eq" }, |
235 | | { PPC_REG_CR3EQ, "cr3eq" }, |
236 | | { PPC_REG_CR4EQ, "cr4eq" }, |
237 | | { PPC_REG_CR5EQ, "cr5eq" }, |
238 | | { PPC_REG_CR6EQ, "cr6eq" }, |
239 | | { PPC_REG_CR7EQ, "cr7eq" }, |
240 | | { PPC_REG_CR0GT, "cr0gt" }, |
241 | | { PPC_REG_CR1GT, "cr1gt" }, |
242 | | { PPC_REG_CR2GT, "cr2gt" }, |
243 | | { PPC_REG_CR3GT, "cr3gt" }, |
244 | | { PPC_REG_CR4GT, "cr4gt" }, |
245 | | { PPC_REG_CR5GT, "cr5gt" }, |
246 | | { PPC_REG_CR6GT, "cr6gt" }, |
247 | | { PPC_REG_CR7GT, "cr7gt" }, |
248 | | { PPC_REG_CR0LT, "cr0lt" }, |
249 | | { PPC_REG_CR1LT, "cr1lt" }, |
250 | | { PPC_REG_CR2LT, "cr2lt" }, |
251 | | { PPC_REG_CR3LT, "cr3lt" }, |
252 | | { PPC_REG_CR4LT, "cr4lt" }, |
253 | | { PPC_REG_CR5LT, "cr5lt" }, |
254 | | { PPC_REG_CR6LT, "cr6lt" }, |
255 | | { PPC_REG_CR7LT, "cr7lt" }, |
256 | | { PPC_REG_CR0UN, "cr0un" }, |
257 | | { PPC_REG_CR1UN, "cr1un" }, |
258 | | { PPC_REG_CR2UN, "cr2un" }, |
259 | | { PPC_REG_CR3UN, "cr3un" }, |
260 | | { PPC_REG_CR4UN, "cr4un" }, |
261 | | { PPC_REG_CR5UN, "cr5un" }, |
262 | | { PPC_REG_CR6UN, "cr6un" }, |
263 | | { PPC_REG_CR7UN, "cr7un" }, |
264 | | }; |
265 | | |
266 | | const char *PPC_reg_name(csh handle, unsigned int reg) |
267 | 44.3k | { |
268 | | // binary searching since the IDs are sorted in order |
269 | 44.3k | unsigned int left, right, m; |
270 | 44.3k | unsigned int max = ARR_SIZE(reg_name_maps); |
271 | | |
272 | 44.3k | right = max - 1; |
273 | | |
274 | 44.3k | if (reg < reg_name_maps[0].id || reg > reg_name_maps[right].id) |
275 | | // not found |
276 | 0 | return NULL; |
277 | | |
278 | 44.3k | left = 0; |
279 | | |
280 | 302k | while(left <= right) { |
281 | 302k | m = (left + right) / 2; |
282 | 302k | if (reg == reg_name_maps[m].id) { |
283 | 44.3k | return reg_name_maps[m].name; |
284 | 44.3k | } |
285 | | |
286 | 258k | if (reg < reg_name_maps[m].id) |
287 | 229k | right = m - 1; |
288 | 29.5k | else |
289 | 29.5k | left = m + 1; |
290 | 258k | } |
291 | | |
292 | | // not found |
293 | 0 | return NULL; |
294 | 44.3k | } |
295 | | |
296 | | ppc_reg PPC_name_reg(const char *name) |
297 | 133k | { |
298 | 133k | unsigned int i; |
299 | | |
300 | 12.4M | for(i = 1; i < ARR_SIZE(reg_name_maps); i++) { |
301 | 12.4M | if (!strcmp(name, reg_name_maps[i].name)) |
302 | 131k | return reg_name_maps[i].id; |
303 | 12.4M | } |
304 | | |
305 | | // not found |
306 | 1.29k | return 0; |
307 | 133k | } |
308 | | |
309 | | static const insn_map insns[] = { |
310 | | // dummy item |
311 | | { |
312 | | 0, 0, |
313 | | #ifndef CAPSTONE_DIET |
314 | | { 0 }, { 0 }, { 0 }, 0, 0 |
315 | | #endif |
316 | | }, |
317 | | |
318 | | #include "PPCMappingInsn.inc" |
319 | | }; |
320 | | |
321 | | // given internal insn id, return public instruction info |
322 | | void PPC_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id) |
323 | 79.6k | { |
324 | 79.6k | int i; |
325 | | |
326 | 79.6k | i = insn_find(insns, ARR_SIZE(insns), id, &h->insn_cache); |
327 | 79.6k | if (i != 0) { |
328 | 79.6k | insn->id = insns[i].mapid; |
329 | | |
330 | 79.6k | if (h->detail) { |
331 | 79.6k | #ifndef CAPSTONE_DIET |
332 | 79.6k | cs_struct handle; |
333 | 79.6k | handle.detail = h->detail; |
334 | | |
335 | 79.6k | memcpy(insn->detail->regs_read, insns[i].regs_use, sizeof(insns[i].regs_use)); |
336 | 79.6k | insn->detail->regs_read_count = (uint8_t)count_positive(insns[i].regs_use); |
337 | | |
338 | 79.6k | memcpy(insn->detail->regs_write, insns[i].regs_mod, sizeof(insns[i].regs_mod)); |
339 | 79.6k | insn->detail->regs_write_count = (uint8_t)count_positive(insns[i].regs_mod); |
340 | | |
341 | 79.6k | memcpy(insn->detail->groups, insns[i].groups, sizeof(insns[i].groups)); |
342 | 79.6k | insn->detail->groups_count = (uint8_t)count_positive8(insns[i].groups); |
343 | | |
344 | 79.6k | if (insns[i].branch || insns[i].indirect_branch) { |
345 | | // this insn also belongs to JUMP group. add JUMP group |
346 | 9.09k | insn->detail->groups[insn->detail->groups_count] = PPC_GRP_JUMP; |
347 | 9.09k | insn->detail->groups_count++; |
348 | 9.09k | } |
349 | | |
350 | 79.6k | insn->detail->ppc.update_cr0 = cs_reg_write((csh)&handle, insn, PPC_REG_CR0); |
351 | 79.6k | #endif |
352 | 79.6k | } |
353 | 79.6k | } |
354 | 79.6k | } |
355 | | |
356 | | static const char * const insn_name_maps[] = { |
357 | | NULL, // PPC_INS_BCT |
358 | | #include "PPCMappingInsnName.inc" |
359 | | }; |
360 | | |
361 | | const char *PPC_insn_name(csh handle, unsigned int id) |
362 | 79.6k | { |
363 | 79.6k | #ifndef CAPSTONE_DIET |
364 | 79.6k | if (id >= PPC_INS_ENDING) |
365 | 0 | return NULL; |
366 | | |
367 | 79.6k | return insn_name_maps[id]; |
368 | | #else |
369 | | return NULL; |
370 | | #endif |
371 | 79.6k | } |
372 | | |
373 | | // map instruction name to public instruction ID |
374 | | ppc_insn PPC_map_insn(const char *name) |
375 | 29.9k | { |
376 | 29.9k | unsigned int i; |
377 | | |
378 | 20.1M | for(i = 1; i < ARR_SIZE(insn_name_maps); i++) { |
379 | 20.1M | if (!strcmp(name, insn_name_maps[i])) |
380 | 29.8k | return i; |
381 | 20.1M | } |
382 | | |
383 | | // not found |
384 | 72 | return PPC_INS_INVALID; |
385 | 29.9k | } |
386 | | |
387 | | #ifndef CAPSTONE_DIET |
388 | | static const name_map group_name_maps[] = { |
389 | | // generic groups |
390 | | { PPC_GRP_INVALID, NULL }, |
391 | | { PPC_GRP_JUMP, "jump" }, |
392 | | |
393 | | // architecture-specific groups |
394 | | { PPC_GRP_ALTIVEC, "altivec" }, |
395 | | { PPC_GRP_MODE32, "mode32" }, |
396 | | { PPC_GRP_MODE64, "mode64" }, |
397 | | { PPC_GRP_BOOKE, "booke" }, |
398 | | { PPC_GRP_NOTBOOKE, "notbooke" }, |
399 | | { PPC_GRP_SPE, "spe" }, |
400 | | { PPC_GRP_VSX, "vsx" }, |
401 | | { PPC_GRP_E500, "e500" }, |
402 | | { PPC_GRP_PPC4XX, "ppc4xx" }, |
403 | | { PPC_GRP_PPC6XX, "ppc6xx" }, |
404 | | { PPC_GRP_ICBT, "icbt" }, |
405 | | { PPC_GRP_P8ALTIVEC, "p8altivec" }, |
406 | | { PPC_GRP_P8VECTOR, "p8vector" }, |
407 | | { PPC_GRP_QPX, "qpx" }, |
408 | | { PPC_GRP_PS, "ps" }, |
409 | | }; |
410 | | #endif |
411 | | |
412 | | const char *PPC_group_name(csh handle, unsigned int id) |
413 | 20.7k | { |
414 | 20.7k | #ifndef CAPSTONE_DIET |
415 | 20.7k | return id2name(group_name_maps, ARR_SIZE(group_name_maps), id); |
416 | | #else |
417 | | return NULL; |
418 | | #endif |
419 | 20.7k | } |
420 | | |
421 | | static const struct ppc_alias alias_insn_name_maps[] = { |
422 | | //{ PPC_INS_BTA, "bta" }, |
423 | | { PPC_INS_B, PPC_BC_LT, "blt" }, |
424 | | { PPC_INS_B, PPC_BC_LE, "ble" }, |
425 | | { PPC_INS_B, PPC_BC_EQ, "beq" }, |
426 | | { PPC_INS_B, PPC_BC_GE, "bge" }, |
427 | | { PPC_INS_B, PPC_BC_GT, "bgt" }, |
428 | | { PPC_INS_B, PPC_BC_NE, "bne" }, |
429 | | { PPC_INS_B, PPC_BC_UN, "bun" }, |
430 | | { PPC_INS_B, PPC_BC_NU, "bnu" }, |
431 | | { PPC_INS_B, PPC_BC_SO, "bso" }, |
432 | | { PPC_INS_B, PPC_BC_NS, "bns" }, |
433 | | |
434 | | { PPC_INS_BA, PPC_BC_LT, "blta" }, |
435 | | { PPC_INS_BA, PPC_BC_LE, "blea" }, |
436 | | { PPC_INS_BA, PPC_BC_EQ, "beqa" }, |
437 | | { PPC_INS_BA, PPC_BC_GE, "bgea" }, |
438 | | { PPC_INS_BA, PPC_BC_GT, "bgta" }, |
439 | | { PPC_INS_BA, PPC_BC_NE, "bnea" }, |
440 | | { PPC_INS_BA, PPC_BC_UN, "buna" }, |
441 | | { PPC_INS_BA, PPC_BC_NU, "bnua" }, |
442 | | { PPC_INS_BA, PPC_BC_SO, "bsoa" }, |
443 | | { PPC_INS_BA, PPC_BC_NS, "bnsa" }, |
444 | | |
445 | | { PPC_INS_BCTR, PPC_BC_LT, "bltctr" }, |
446 | | { PPC_INS_BCTR, PPC_BC_LE, "blectr" }, |
447 | | { PPC_INS_BCTR, PPC_BC_EQ, "beqctr" }, |
448 | | { PPC_INS_BCTR, PPC_BC_GE, "bgectr" }, |
449 | | { PPC_INS_BCTR, PPC_BC_GT, "bgtctr" }, |
450 | | { PPC_INS_BCTR, PPC_BC_NE, "bnectr" }, |
451 | | { PPC_INS_BCTR, PPC_BC_UN, "bunctr" }, |
452 | | { PPC_INS_BCTR, PPC_BC_NU, "bnuctr" }, |
453 | | { PPC_INS_BCTR, PPC_BC_SO, "bsoctr" }, |
454 | | { PPC_INS_BCTR, PPC_BC_NS, "bnsctr" }, |
455 | | |
456 | | { PPC_INS_BCTRL, PPC_BC_LT, "bltctrl" }, |
457 | | { PPC_INS_BCTRL, PPC_BC_LE, "blectrl" }, |
458 | | { PPC_INS_BCTRL, PPC_BC_EQ, "beqctrl" }, |
459 | | { PPC_INS_BCTRL, PPC_BC_GE, "bgectrl" }, |
460 | | { PPC_INS_BCTRL, PPC_BC_GT, "bgtctrl" }, |
461 | | { PPC_INS_BCTRL, PPC_BC_NE, "bnectrl" }, |
462 | | { PPC_INS_BCTRL, PPC_BC_UN, "bunctrl" }, |
463 | | { PPC_INS_BCTRL, PPC_BC_NU, "bnuctrl" }, |
464 | | { PPC_INS_BCTRL, PPC_BC_SO, "bsoctrl" }, |
465 | | { PPC_INS_BCTRL, PPC_BC_NS, "bnsctrl" }, |
466 | | |
467 | | { PPC_INS_BL, PPC_BC_LT, "bltl" }, |
468 | | { PPC_INS_BL, PPC_BC_LE, "blel" }, |
469 | | { PPC_INS_BL, PPC_BC_EQ, "beql" }, |
470 | | { PPC_INS_BL, PPC_BC_GE, "bgel" }, |
471 | | { PPC_INS_BL, PPC_BC_GT, "bgtl" }, |
472 | | { PPC_INS_BL, PPC_BC_NE, "bnel" }, |
473 | | { PPC_INS_BL, PPC_BC_UN, "bunl" }, |
474 | | { PPC_INS_BL, PPC_BC_NU, "bnul" }, |
475 | | { PPC_INS_BL, PPC_BC_SO, "bsol" }, |
476 | | { PPC_INS_BL, PPC_BC_NS, "bnsl" }, |
477 | | |
478 | | { PPC_INS_BLA, PPC_BC_LT, "bltla" }, |
479 | | { PPC_INS_BLA, PPC_BC_LE, "blela" }, |
480 | | { PPC_INS_BLA, PPC_BC_EQ, "beqla" }, |
481 | | { PPC_INS_BLA, PPC_BC_GE, "bgela" }, |
482 | | { PPC_INS_BLA, PPC_BC_GT, "bgtla" }, |
483 | | { PPC_INS_BLA, PPC_BC_NE, "bnela" }, |
484 | | { PPC_INS_BLA, PPC_BC_UN, "bunla" }, |
485 | | { PPC_INS_BLA, PPC_BC_NU, "bnula" }, |
486 | | { PPC_INS_BLA, PPC_BC_SO, "bsola" }, |
487 | | { PPC_INS_BLA, PPC_BC_NS, "bnsla" }, |
488 | | |
489 | | { PPC_INS_BLR, PPC_BC_LT, "bltlr" }, |
490 | | { PPC_INS_BLR, PPC_BC_LE, "blelr" }, |
491 | | { PPC_INS_BLR, PPC_BC_EQ, "beqlr" }, |
492 | | { PPC_INS_BLR, PPC_BC_GE, "bgelr" }, |
493 | | { PPC_INS_BLR, PPC_BC_GT, "bgtlr" }, |
494 | | { PPC_INS_BLR, PPC_BC_NE, "bnelr" }, |
495 | | { PPC_INS_BLR, PPC_BC_UN, "bunlr" }, |
496 | | { PPC_INS_BLR, PPC_BC_NU, "bnulr" }, |
497 | | { PPC_INS_BLR, PPC_BC_SO, "bsolr" }, |
498 | | { PPC_INS_BLR, PPC_BC_NS, "bnslr" }, |
499 | | |
500 | | { PPC_INS_BLRL, PPC_BC_LT, "bltlrl" }, |
501 | | { PPC_INS_BLRL, PPC_BC_LE, "blelrl" }, |
502 | | { PPC_INS_BLRL, PPC_BC_EQ, "beqlrl" }, |
503 | | { PPC_INS_BLRL, PPC_BC_GE, "bgelrl" }, |
504 | | { PPC_INS_BLRL, PPC_BC_GT, "bgtlrl" }, |
505 | | { PPC_INS_BLRL, PPC_BC_NE, "bnelrl" }, |
506 | | { PPC_INS_BLRL, PPC_BC_UN, "bunlrl" }, |
507 | | { PPC_INS_BLRL, PPC_BC_NU, "bnulrl" }, |
508 | | { PPC_INS_BLRL, PPC_BC_SO, "bsolrl" }, |
509 | | { PPC_INS_BLRL, PPC_BC_NS, "bnslrl" }, |
510 | | }; |
511 | | |
512 | | // given alias mnemonic, return instruction ID & CC |
513 | | bool PPC_alias_insn(const char *name, struct ppc_alias *alias) |
514 | 29.9k | { |
515 | 29.9k | size_t i; |
516 | | |
517 | 29.9k | alias->cc = PPC_BC_INVALID; |
518 | | |
519 | 2.35M | for(i = 0; i < ARR_SIZE(alias_insn_name_maps); i++) { |
520 | 2.33M | if (!strcmp(name, alias_insn_name_maps[i].mnem)) { |
521 | | // alias->id = alias_insn_name_maps[i].id; |
522 | 1.50k | alias->cc = alias_insn_name_maps[i].cc; |
523 | 1.50k | return true; |
524 | 1.50k | } |
525 | 2.33M | } |
526 | | |
527 | | // not found |
528 | 28.4k | return false; |
529 | 29.9k | } |
530 | | |
531 | | // check if this insn is relative branch |
532 | | bool PPC_abs_branch(cs_struct *h, unsigned int id) |
533 | 8.76k | { |
534 | 8.76k | unsigned int i; |
535 | | // list all absolute branch instructions |
536 | 8.76k | static const unsigned int insn_abs[] = { |
537 | 8.76k | PPC_BA, |
538 | 8.76k | PPC_BCCA, |
539 | 8.76k | PPC_BCCLA, |
540 | 8.76k | PPC_BDNZA, |
541 | 8.76k | PPC_BDNZAm, |
542 | 8.76k | PPC_BDNZAp, |
543 | 8.76k | PPC_BDNZLA, |
544 | 8.76k | PPC_BDNZLAm, |
545 | 8.76k | PPC_BDNZLAp, |
546 | 8.76k | PPC_BDZA, |
547 | 8.76k | PPC_BDZAm, |
548 | 8.76k | PPC_BDZAp, |
549 | 8.76k | PPC_BDZLAm, |
550 | 8.76k | PPC_BDZLAp, |
551 | 8.76k | PPC_BLA, |
552 | 8.76k | PPC_gBCA, |
553 | 8.76k | PPC_gBCLA, |
554 | 8.76k | PPC_BDZLA, |
555 | 8.76k | 0 |
556 | 8.76k | }; |
557 | | |
558 | | // printf("opcode: %u\n", id); |
559 | | |
560 | 150k | for (i = 0; insn_abs[i]; i++) { |
561 | 145k | if (id == insn_abs[i]) { |
562 | 3.60k | return true; |
563 | 3.60k | } |
564 | 145k | } |
565 | | |
566 | | // not found |
567 | 5.16k | return false; |
568 | 8.76k | } |
569 | | |
570 | | #endif |