/src/capstonev5/arch/Sparc/SparcMapping.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_SPARC |
5 | | |
6 | | #include <stdio.h> // debug |
7 | | #include <string.h> |
8 | | |
9 | | #include "../../utils.h" |
10 | | |
11 | | #include "SparcMapping.h" |
12 | | |
13 | | #define GET_INSTRINFO_ENUM |
14 | | #include "SparcGenInstrInfo.inc" |
15 | | |
16 | | #ifndef CAPSTONE_DIET |
17 | | static const name_map reg_name_maps[] = { |
18 | | { SPARC_REG_INVALID, NULL }, |
19 | | |
20 | | { SPARC_REG_F0, "f0"}, |
21 | | { SPARC_REG_F1, "f1"}, |
22 | | { SPARC_REG_F2, "f2"}, |
23 | | { SPARC_REG_F3, "f3"}, |
24 | | { SPARC_REG_F4, "f4"}, |
25 | | { SPARC_REG_F5, "f5"}, |
26 | | { SPARC_REG_F6, "f6"}, |
27 | | { SPARC_REG_F7, "f7"}, |
28 | | { SPARC_REG_F8, "f8"}, |
29 | | { SPARC_REG_F9, "f9"}, |
30 | | { SPARC_REG_F10, "f10"}, |
31 | | { SPARC_REG_F11, "f11"}, |
32 | | { SPARC_REG_F12, "f12"}, |
33 | | { SPARC_REG_F13, "f13"}, |
34 | | { SPARC_REG_F14, "f14"}, |
35 | | { SPARC_REG_F15, "f15"}, |
36 | | { SPARC_REG_F16, "f16"}, |
37 | | { SPARC_REG_F17, "f17"}, |
38 | | { SPARC_REG_F18, "f18"}, |
39 | | { SPARC_REG_F19, "f19"}, |
40 | | { SPARC_REG_F20, "f20"}, |
41 | | { SPARC_REG_F21, "f21"}, |
42 | | { SPARC_REG_F22, "f22"}, |
43 | | { SPARC_REG_F23, "f23"}, |
44 | | { SPARC_REG_F24, "f24"}, |
45 | | { SPARC_REG_F25, "f25"}, |
46 | | { SPARC_REG_F26, "f26"}, |
47 | | { SPARC_REG_F27, "f27"}, |
48 | | { SPARC_REG_F28, "f28"}, |
49 | | { SPARC_REG_F29, "f29"}, |
50 | | { SPARC_REG_F30, "f30"}, |
51 | | { SPARC_REG_F31, "f31"}, |
52 | | { SPARC_REG_F32, "f32"}, |
53 | | { SPARC_REG_F34, "f34"}, |
54 | | { SPARC_REG_F36, "f36"}, |
55 | | { SPARC_REG_F38, "f38"}, |
56 | | { SPARC_REG_F40, "f40"}, |
57 | | { SPARC_REG_F42, "f42"}, |
58 | | { SPARC_REG_F44, "f44"}, |
59 | | { SPARC_REG_F46, "f46"}, |
60 | | { SPARC_REG_F48, "f48"}, |
61 | | { SPARC_REG_F50, "f50"}, |
62 | | { SPARC_REG_F52, "f52"}, |
63 | | { SPARC_REG_F54, "f54"}, |
64 | | { SPARC_REG_F56, "f56"}, |
65 | | { SPARC_REG_F58, "f58"}, |
66 | | { SPARC_REG_F60, "f60"}, |
67 | | { SPARC_REG_F62, "f62"}, |
68 | | { SPARC_REG_FCC0, "fcc0"}, |
69 | | { SPARC_REG_FCC1, "fcc1"}, |
70 | | { SPARC_REG_FCC2, "fcc2"}, |
71 | | { SPARC_REG_FCC3, "fcc3"}, |
72 | | { SPARC_REG_FP, "fp"}, |
73 | | { SPARC_REG_G0, "g0"}, |
74 | | { SPARC_REG_G1, "g1"}, |
75 | | { SPARC_REG_G2, "g2"}, |
76 | | { SPARC_REG_G3, "g3"}, |
77 | | { SPARC_REG_G4, "g4"}, |
78 | | { SPARC_REG_G5, "g5"}, |
79 | | { SPARC_REG_G6, "g6"}, |
80 | | { SPARC_REG_G7, "g7"}, |
81 | | { SPARC_REG_I0, "i0"}, |
82 | | { SPARC_REG_I1, "i1"}, |
83 | | { SPARC_REG_I2, "i2"}, |
84 | | { SPARC_REG_I3, "i3"}, |
85 | | { SPARC_REG_I4, "i4"}, |
86 | | { SPARC_REG_I5, "i5"}, |
87 | | { SPARC_REG_I7, "i7"}, |
88 | | { SPARC_REG_ICC, "icc"}, |
89 | | { SPARC_REG_L0, "l0"}, |
90 | | { SPARC_REG_L1, "l1"}, |
91 | | { SPARC_REG_L2, "l2"}, |
92 | | { SPARC_REG_L3, "l3"}, |
93 | | { SPARC_REG_L4, "l4"}, |
94 | | { SPARC_REG_L5, "l5"}, |
95 | | { SPARC_REG_L6, "l6"}, |
96 | | { SPARC_REG_L7, "l7"}, |
97 | | { SPARC_REG_O0, "o0"}, |
98 | | { SPARC_REG_O1, "o1"}, |
99 | | { SPARC_REG_O2, "o2"}, |
100 | | { SPARC_REG_O3, "o3"}, |
101 | | { SPARC_REG_O4, "o4"}, |
102 | | { SPARC_REG_O5, "o5"}, |
103 | | { SPARC_REG_O7, "o7"}, |
104 | | { SPARC_REG_SP, "sp"}, |
105 | | { SPARC_REG_Y, "y"}, |
106 | | |
107 | | // special registers |
108 | | { SPARC_REG_XCC, "xcc"}, |
109 | | }; |
110 | | #endif |
111 | | |
112 | | const char *Sparc_reg_name(csh handle, unsigned int reg) |
113 | 75.5k | { |
114 | 75.5k | #ifndef CAPSTONE_DIET |
115 | 75.5k | if (reg >= ARR_SIZE(reg_name_maps)) |
116 | 0 | return NULL; |
117 | | |
118 | 75.5k | return reg_name_maps[reg].name; |
119 | | #else |
120 | | return NULL; |
121 | | #endif |
122 | 75.5k | } |
123 | | |
124 | | static const insn_map insns[] = { |
125 | | // dummy item |
126 | | { |
127 | | 0, 0, |
128 | | #ifndef CAPSTONE_DIET |
129 | | { 0 }, { 0 }, { 0 }, 0, 0 |
130 | | #endif |
131 | | }, |
132 | | |
133 | | #include "SparcMappingInsn.inc" |
134 | | }; |
135 | | |
136 | | static struct hint_map { |
137 | | unsigned int id; |
138 | | uint8_t hints; |
139 | | } const insn_hints[] = { |
140 | | { SP_BPGEZapn, SPARC_HINT_A | SPARC_HINT_PN }, |
141 | | { SP_BPGEZapt, SPARC_HINT_A | SPARC_HINT_PT }, |
142 | | { SP_BPGEZnapn, SPARC_HINT_PN }, |
143 | | { SP_BPGZapn, SPARC_HINT_A | SPARC_HINT_PN }, |
144 | | { SP_BPGZapt, SPARC_HINT_A | SPARC_HINT_PT }, |
145 | | { SP_BPGZnapn, SPARC_HINT_PN }, |
146 | | { SP_BPLEZapn, SPARC_HINT_A | SPARC_HINT_PN }, |
147 | | { SP_BPLEZapt, SPARC_HINT_A | SPARC_HINT_PT }, |
148 | | { SP_BPLEZnapn, SPARC_HINT_PN }, |
149 | | { SP_BPLZapn, SPARC_HINT_A | SPARC_HINT_PN }, |
150 | | { SP_BPLZapt, SPARC_HINT_A | SPARC_HINT_PT }, |
151 | | { SP_BPLZnapn, SPARC_HINT_PN }, |
152 | | { SP_BPNZapn, SPARC_HINT_A | SPARC_HINT_PN }, |
153 | | { SP_BPNZapt, SPARC_HINT_A | SPARC_HINT_PT }, |
154 | | { SP_BPNZnapn, SPARC_HINT_PN }, |
155 | | { SP_BPZapn, SPARC_HINT_A | SPARC_HINT_PN }, |
156 | | { SP_BPZapt, SPARC_HINT_A | SPARC_HINT_PT }, |
157 | | { SP_BPZnapn, SPARC_HINT_PN }, |
158 | | }; |
159 | | |
160 | | // given internal insn id, return public instruction info |
161 | | void Sparc_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id) |
162 | 121k | { |
163 | 121k | unsigned short i; |
164 | | |
165 | 121k | i = insn_find(insns, ARR_SIZE(insns), id, &h->insn_cache); |
166 | 121k | if (i != 0) { |
167 | 121k | insn->id = insns[i].mapid; |
168 | | |
169 | 121k | if (h->detail) { |
170 | 121k | #ifndef CAPSTONE_DIET |
171 | 121k | memcpy(insn->detail->regs_read, insns[i].regs_use, sizeof(insns[i].regs_use)); |
172 | 121k | insn->detail->regs_read_count = (uint8_t)count_positive(insns[i].regs_use); |
173 | | |
174 | 121k | memcpy(insn->detail->regs_write, insns[i].regs_mod, sizeof(insns[i].regs_mod)); |
175 | 121k | insn->detail->regs_write_count = (uint8_t)count_positive(insns[i].regs_mod); |
176 | | |
177 | 121k | memcpy(insn->detail->groups, insns[i].groups, sizeof(insns[i].groups)); |
178 | 121k | insn->detail->groups_count = (uint8_t)count_positive8(insns[i].groups); |
179 | | |
180 | 121k | if (insns[i].branch || insns[i].indirect_branch) { |
181 | | // this insn also belongs to JUMP group. add JUMP group |
182 | 40.0k | insn->detail->groups[insn->detail->groups_count] = SPARC_GRP_JUMP; |
183 | 40.0k | insn->detail->groups_count++; |
184 | 40.0k | } |
185 | 121k | #endif |
186 | | // hint code |
187 | 2.27M | for (i = 0; i < ARR_SIZE(insn_hints); i++) { |
188 | 2.15M | if (id == insn_hints[i].id) { |
189 | 2.62k | insn->detail->sparc.hint = insn_hints[i].hints; |
190 | 2.62k | break; |
191 | 2.62k | } |
192 | 2.15M | } |
193 | 121k | } |
194 | 121k | } |
195 | 121k | } |
196 | | |
197 | | static const name_map insn_name_maps[] = { |
198 | | { SPARC_INS_INVALID, NULL }, |
199 | | |
200 | | { SPARC_INS_ADDCC, "addcc" }, |
201 | | { SPARC_INS_ADDX, "addx" }, |
202 | | { SPARC_INS_ADDXCC, "addxcc" }, |
203 | | { SPARC_INS_ADDXC, "addxc" }, |
204 | | { SPARC_INS_ADDXCCC, "addxccc" }, |
205 | | { SPARC_INS_ADD, "add" }, |
206 | | { SPARC_INS_ALIGNADDR, "alignaddr" }, |
207 | | { SPARC_INS_ALIGNADDRL, "alignaddrl" }, |
208 | | { SPARC_INS_ANDCC, "andcc" }, |
209 | | { SPARC_INS_ANDNCC, "andncc" }, |
210 | | { SPARC_INS_ANDN, "andn" }, |
211 | | { SPARC_INS_AND, "and" }, |
212 | | { SPARC_INS_ARRAY16, "array16" }, |
213 | | { SPARC_INS_ARRAY32, "array32" }, |
214 | | { SPARC_INS_ARRAY8, "array8" }, |
215 | | { SPARC_INS_B, "b" }, |
216 | | { SPARC_INS_JMP, "jmp" }, |
217 | | { SPARC_INS_BMASK, "bmask" }, |
218 | | { SPARC_INS_FB, "fb" }, |
219 | | { SPARC_INS_BRGEZ, "brgez" }, |
220 | | { SPARC_INS_BRGZ, "brgz" }, |
221 | | { SPARC_INS_BRLEZ, "brlez" }, |
222 | | { SPARC_INS_BRLZ, "brlz" }, |
223 | | { SPARC_INS_BRNZ, "brnz" }, |
224 | | { SPARC_INS_BRZ, "brz" }, |
225 | | { SPARC_INS_BSHUFFLE, "bshuffle" }, |
226 | | { SPARC_INS_CALL, "call" }, |
227 | | { SPARC_INS_CASX, "casx" }, |
228 | | { SPARC_INS_CAS, "cas" }, |
229 | | { SPARC_INS_CMASK16, "cmask16" }, |
230 | | { SPARC_INS_CMASK32, "cmask32" }, |
231 | | { SPARC_INS_CMASK8, "cmask8" }, |
232 | | { SPARC_INS_CMP, "cmp" }, |
233 | | { SPARC_INS_EDGE16, "edge16" }, |
234 | | { SPARC_INS_EDGE16L, "edge16l" }, |
235 | | { SPARC_INS_EDGE16LN, "edge16ln" }, |
236 | | { SPARC_INS_EDGE16N, "edge16n" }, |
237 | | { SPARC_INS_EDGE32, "edge32" }, |
238 | | { SPARC_INS_EDGE32L, "edge32l" }, |
239 | | { SPARC_INS_EDGE32LN, "edge32ln" }, |
240 | | { SPARC_INS_EDGE32N, "edge32n" }, |
241 | | { SPARC_INS_EDGE8, "edge8" }, |
242 | | { SPARC_INS_EDGE8L, "edge8l" }, |
243 | | { SPARC_INS_EDGE8LN, "edge8ln" }, |
244 | | { SPARC_INS_EDGE8N, "edge8n" }, |
245 | | { SPARC_INS_FABSD, "fabsd" }, |
246 | | { SPARC_INS_FABSQ, "fabsq" }, |
247 | | { SPARC_INS_FABSS, "fabss" }, |
248 | | { SPARC_INS_FADDD, "faddd" }, |
249 | | { SPARC_INS_FADDQ, "faddq" }, |
250 | | { SPARC_INS_FADDS, "fadds" }, |
251 | | { SPARC_INS_FALIGNDATA, "faligndata" }, |
252 | | { SPARC_INS_FAND, "fand" }, |
253 | | { SPARC_INS_FANDNOT1, "fandnot1" }, |
254 | | { SPARC_INS_FANDNOT1S, "fandnot1s" }, |
255 | | { SPARC_INS_FANDNOT2, "fandnot2" }, |
256 | | { SPARC_INS_FANDNOT2S, "fandnot2s" }, |
257 | | { SPARC_INS_FANDS, "fands" }, |
258 | | { SPARC_INS_FCHKSM16, "fchksm16" }, |
259 | | { SPARC_INS_FCMPD, "fcmpd" }, |
260 | | { SPARC_INS_FCMPEQ16, "fcmpeq16" }, |
261 | | { SPARC_INS_FCMPEQ32, "fcmpeq32" }, |
262 | | { SPARC_INS_FCMPGT16, "fcmpgt16" }, |
263 | | { SPARC_INS_FCMPGT32, "fcmpgt32" }, |
264 | | { SPARC_INS_FCMPLE16, "fcmple16" }, |
265 | | { SPARC_INS_FCMPLE32, "fcmple32" }, |
266 | | { SPARC_INS_FCMPNE16, "fcmpne16" }, |
267 | | { SPARC_INS_FCMPNE32, "fcmpne32" }, |
268 | | { SPARC_INS_FCMPQ, "fcmpq" }, |
269 | | { SPARC_INS_FCMPS, "fcmps" }, |
270 | | { SPARC_INS_FDIVD, "fdivd" }, |
271 | | { SPARC_INS_FDIVQ, "fdivq" }, |
272 | | { SPARC_INS_FDIVS, "fdivs" }, |
273 | | { SPARC_INS_FDMULQ, "fdmulq" }, |
274 | | { SPARC_INS_FDTOI, "fdtoi" }, |
275 | | { SPARC_INS_FDTOQ, "fdtoq" }, |
276 | | { SPARC_INS_FDTOS, "fdtos" }, |
277 | | { SPARC_INS_FDTOX, "fdtox" }, |
278 | | { SPARC_INS_FEXPAND, "fexpand" }, |
279 | | { SPARC_INS_FHADDD, "fhaddd" }, |
280 | | { SPARC_INS_FHADDS, "fhadds" }, |
281 | | { SPARC_INS_FHSUBD, "fhsubd" }, |
282 | | { SPARC_INS_FHSUBS, "fhsubs" }, |
283 | | { SPARC_INS_FITOD, "fitod" }, |
284 | | { SPARC_INS_FITOQ, "fitoq" }, |
285 | | { SPARC_INS_FITOS, "fitos" }, |
286 | | { SPARC_INS_FLCMPD, "flcmpd" }, |
287 | | { SPARC_INS_FLCMPS, "flcmps" }, |
288 | | { SPARC_INS_FLUSHW, "flushw" }, |
289 | | { SPARC_INS_FMEAN16, "fmean16" }, |
290 | | { SPARC_INS_FMOVD, "fmovd" }, |
291 | | { SPARC_INS_FMOVQ, "fmovq" }, |
292 | | { SPARC_INS_FMOVRDGEZ, "fmovrdgez" }, |
293 | | { SPARC_INS_FMOVRQGEZ, "fmovrqgez" }, |
294 | | { SPARC_INS_FMOVRSGEZ, "fmovrsgez" }, |
295 | | { SPARC_INS_FMOVRDGZ, "fmovrdgz" }, |
296 | | { SPARC_INS_FMOVRQGZ, "fmovrqgz" }, |
297 | | { SPARC_INS_FMOVRSGZ, "fmovrsgz" }, |
298 | | { SPARC_INS_FMOVRDLEZ, "fmovrdlez" }, |
299 | | { SPARC_INS_FMOVRQLEZ, "fmovrqlez" }, |
300 | | { SPARC_INS_FMOVRSLEZ, "fmovrslez" }, |
301 | | { SPARC_INS_FMOVRDLZ, "fmovrdlz" }, |
302 | | { SPARC_INS_FMOVRQLZ, "fmovrqlz" }, |
303 | | { SPARC_INS_FMOVRSLZ, "fmovrslz" }, |
304 | | { SPARC_INS_FMOVRDNZ, "fmovrdnz" }, |
305 | | { SPARC_INS_FMOVRQNZ, "fmovrqnz" }, |
306 | | { SPARC_INS_FMOVRSNZ, "fmovrsnz" }, |
307 | | { SPARC_INS_FMOVRDZ, "fmovrdz" }, |
308 | | { SPARC_INS_FMOVRQZ, "fmovrqz" }, |
309 | | { SPARC_INS_FMOVRSZ, "fmovrsz" }, |
310 | | { SPARC_INS_FMOVS, "fmovs" }, |
311 | | { SPARC_INS_FMUL8SUX16, "fmul8sux16" }, |
312 | | { SPARC_INS_FMUL8ULX16, "fmul8ulx16" }, |
313 | | { SPARC_INS_FMUL8X16, "fmul8x16" }, |
314 | | { SPARC_INS_FMUL8X16AL, "fmul8x16al" }, |
315 | | { SPARC_INS_FMUL8X16AU, "fmul8x16au" }, |
316 | | { SPARC_INS_FMULD, "fmuld" }, |
317 | | { SPARC_INS_FMULD8SUX16, "fmuld8sux16" }, |
318 | | { SPARC_INS_FMULD8ULX16, "fmuld8ulx16" }, |
319 | | { SPARC_INS_FMULQ, "fmulq" }, |
320 | | { SPARC_INS_FMULS, "fmuls" }, |
321 | | { SPARC_INS_FNADDD, "fnaddd" }, |
322 | | { SPARC_INS_FNADDS, "fnadds" }, |
323 | | { SPARC_INS_FNAND, "fnand" }, |
324 | | { SPARC_INS_FNANDS, "fnands" }, |
325 | | { SPARC_INS_FNEGD, "fnegd" }, |
326 | | { SPARC_INS_FNEGQ, "fnegq" }, |
327 | | { SPARC_INS_FNEGS, "fnegs" }, |
328 | | { SPARC_INS_FNHADDD, "fnhaddd" }, |
329 | | { SPARC_INS_FNHADDS, "fnhadds" }, |
330 | | { SPARC_INS_FNOR, "fnor" }, |
331 | | { SPARC_INS_FNORS, "fnors" }, |
332 | | { SPARC_INS_FNOT1, "fnot1" }, |
333 | | { SPARC_INS_FNOT1S, "fnot1s" }, |
334 | | { SPARC_INS_FNOT2, "fnot2" }, |
335 | | { SPARC_INS_FNOT2S, "fnot2s" }, |
336 | | { SPARC_INS_FONE, "fone" }, |
337 | | { SPARC_INS_FONES, "fones" }, |
338 | | { SPARC_INS_FOR, "for" }, |
339 | | { SPARC_INS_FORNOT1, "fornot1" }, |
340 | | { SPARC_INS_FORNOT1S, "fornot1s" }, |
341 | | { SPARC_INS_FORNOT2, "fornot2" }, |
342 | | { SPARC_INS_FORNOT2S, "fornot2s" }, |
343 | | { SPARC_INS_FORS, "fors" }, |
344 | | { SPARC_INS_FPACK16, "fpack16" }, |
345 | | { SPARC_INS_FPACK32, "fpack32" }, |
346 | | { SPARC_INS_FPACKFIX, "fpackfix" }, |
347 | | { SPARC_INS_FPADD16, "fpadd16" }, |
348 | | { SPARC_INS_FPADD16S, "fpadd16s" }, |
349 | | { SPARC_INS_FPADD32, "fpadd32" }, |
350 | | { SPARC_INS_FPADD32S, "fpadd32s" }, |
351 | | { SPARC_INS_FPADD64, "fpadd64" }, |
352 | | { SPARC_INS_FPMERGE, "fpmerge" }, |
353 | | { SPARC_INS_FPSUB16, "fpsub16" }, |
354 | | { SPARC_INS_FPSUB16S, "fpsub16s" }, |
355 | | { SPARC_INS_FPSUB32, "fpsub32" }, |
356 | | { SPARC_INS_FPSUB32S, "fpsub32s" }, |
357 | | { SPARC_INS_FQTOD, "fqtod" }, |
358 | | { SPARC_INS_FQTOI, "fqtoi" }, |
359 | | { SPARC_INS_FQTOS, "fqtos" }, |
360 | | { SPARC_INS_FQTOX, "fqtox" }, |
361 | | { SPARC_INS_FSLAS16, "fslas16" }, |
362 | | { SPARC_INS_FSLAS32, "fslas32" }, |
363 | | { SPARC_INS_FSLL16, "fsll16" }, |
364 | | { SPARC_INS_FSLL32, "fsll32" }, |
365 | | { SPARC_INS_FSMULD, "fsmuld" }, |
366 | | { SPARC_INS_FSQRTD, "fsqrtd" }, |
367 | | { SPARC_INS_FSQRTQ, "fsqrtq" }, |
368 | | { SPARC_INS_FSQRTS, "fsqrts" }, |
369 | | { SPARC_INS_FSRA16, "fsra16" }, |
370 | | { SPARC_INS_FSRA32, "fsra32" }, |
371 | | { SPARC_INS_FSRC1, "fsrc1" }, |
372 | | { SPARC_INS_FSRC1S, "fsrc1s" }, |
373 | | { SPARC_INS_FSRC2, "fsrc2" }, |
374 | | { SPARC_INS_FSRC2S, "fsrc2s" }, |
375 | | { SPARC_INS_FSRL16, "fsrl16" }, |
376 | | { SPARC_INS_FSRL32, "fsrl32" }, |
377 | | { SPARC_INS_FSTOD, "fstod" }, |
378 | | { SPARC_INS_FSTOI, "fstoi" }, |
379 | | { SPARC_INS_FSTOQ, "fstoq" }, |
380 | | { SPARC_INS_FSTOX, "fstox" }, |
381 | | { SPARC_INS_FSUBD, "fsubd" }, |
382 | | { SPARC_INS_FSUBQ, "fsubq" }, |
383 | | { SPARC_INS_FSUBS, "fsubs" }, |
384 | | { SPARC_INS_FXNOR, "fxnor" }, |
385 | | { SPARC_INS_FXNORS, "fxnors" }, |
386 | | { SPARC_INS_FXOR, "fxor" }, |
387 | | { SPARC_INS_FXORS, "fxors" }, |
388 | | { SPARC_INS_FXTOD, "fxtod" }, |
389 | | { SPARC_INS_FXTOQ, "fxtoq" }, |
390 | | { SPARC_INS_FXTOS, "fxtos" }, |
391 | | { SPARC_INS_FZERO, "fzero" }, |
392 | | { SPARC_INS_FZEROS, "fzeros" }, |
393 | | { SPARC_INS_JMPL, "jmpl" }, |
394 | | { SPARC_INS_LDD, "ldd" }, |
395 | | { SPARC_INS_LD, "ld" }, |
396 | | { SPARC_INS_LDQ, "ldq" }, |
397 | | { SPARC_INS_LDSB, "ldsb" }, |
398 | | { SPARC_INS_LDSH, "ldsh" }, |
399 | | { SPARC_INS_LDSW, "ldsw" }, |
400 | | { SPARC_INS_LDUB, "ldub" }, |
401 | | { SPARC_INS_LDUH, "lduh" }, |
402 | | { SPARC_INS_LDX, "ldx" }, |
403 | | { SPARC_INS_LZCNT, "lzcnt" }, |
404 | | { SPARC_INS_MEMBAR, "membar" }, |
405 | | { SPARC_INS_MOVDTOX, "movdtox" }, |
406 | | { SPARC_INS_MOV, "mov" }, |
407 | | { SPARC_INS_MOVRGEZ, "movrgez" }, |
408 | | { SPARC_INS_MOVRGZ, "movrgz" }, |
409 | | { SPARC_INS_MOVRLEZ, "movrlez" }, |
410 | | { SPARC_INS_MOVRLZ, "movrlz" }, |
411 | | { SPARC_INS_MOVRNZ, "movrnz" }, |
412 | | { SPARC_INS_MOVRZ, "movrz" }, |
413 | | { SPARC_INS_MOVSTOSW, "movstosw" }, |
414 | | { SPARC_INS_MOVSTOUW, "movstouw" }, |
415 | | { SPARC_INS_MULX, "mulx" }, |
416 | | { SPARC_INS_NOP, "nop" }, |
417 | | { SPARC_INS_ORCC, "orcc" }, |
418 | | { SPARC_INS_ORNCC, "orncc" }, |
419 | | { SPARC_INS_ORN, "orn" }, |
420 | | { SPARC_INS_OR, "or" }, |
421 | | { SPARC_INS_PDIST, "pdist" }, |
422 | | { SPARC_INS_PDISTN, "pdistn" }, |
423 | | { SPARC_INS_POPC, "popc" }, |
424 | | { SPARC_INS_RD, "rd" }, |
425 | | { SPARC_INS_RESTORE, "restore" }, |
426 | | { SPARC_INS_RETT, "rett" }, |
427 | | { SPARC_INS_SAVE, "save" }, |
428 | | { SPARC_INS_SDIVCC, "sdivcc" }, |
429 | | { SPARC_INS_SDIVX, "sdivx" }, |
430 | | { SPARC_INS_SDIV, "sdiv" }, |
431 | | { SPARC_INS_SETHI, "sethi" }, |
432 | | { SPARC_INS_SHUTDOWN, "shutdown" }, |
433 | | { SPARC_INS_SIAM, "siam" }, |
434 | | { SPARC_INS_SLLX, "sllx" }, |
435 | | { SPARC_INS_SLL, "sll" }, |
436 | | { SPARC_INS_SMULCC, "smulcc" }, |
437 | | { SPARC_INS_SMUL, "smul" }, |
438 | | { SPARC_INS_SRAX, "srax" }, |
439 | | { SPARC_INS_SRA, "sra" }, |
440 | | { SPARC_INS_SRLX, "srlx" }, |
441 | | { SPARC_INS_SRL, "srl" }, |
442 | | { SPARC_INS_STBAR, "stbar" }, |
443 | | { SPARC_INS_STB, "stb" }, |
444 | | { SPARC_INS_STD, "std" }, |
445 | | { SPARC_INS_ST, "st" }, |
446 | | { SPARC_INS_STH, "sth" }, |
447 | | { SPARC_INS_STQ, "stq" }, |
448 | | { SPARC_INS_STX, "stx" }, |
449 | | { SPARC_INS_SUBCC, "subcc" }, |
450 | | { SPARC_INS_SUBX, "subx" }, |
451 | | { SPARC_INS_SUBXCC, "subxcc" }, |
452 | | { SPARC_INS_SUB, "sub" }, |
453 | | { SPARC_INS_SWAP, "swap" }, |
454 | | { SPARC_INS_TADDCCTV, "taddcctv" }, |
455 | | { SPARC_INS_TADDCC, "taddcc" }, |
456 | | { SPARC_INS_T, "t" }, |
457 | | { SPARC_INS_TSUBCCTV, "tsubcctv" }, |
458 | | { SPARC_INS_TSUBCC, "tsubcc" }, |
459 | | { SPARC_INS_UDIVCC, "udivcc" }, |
460 | | { SPARC_INS_UDIVX, "udivx" }, |
461 | | { SPARC_INS_UDIV, "udiv" }, |
462 | | { SPARC_INS_UMULCC, "umulcc" }, |
463 | | { SPARC_INS_UMULXHI, "umulxhi" }, |
464 | | { SPARC_INS_UMUL, "umul" }, |
465 | | { SPARC_INS_UNIMP, "unimp" }, |
466 | | { SPARC_INS_FCMPED, "fcmped" }, |
467 | | { SPARC_INS_FCMPEQ, "fcmpeq" }, |
468 | | { SPARC_INS_FCMPES, "fcmpes" }, |
469 | | { SPARC_INS_WR, "wr" }, |
470 | | { SPARC_INS_XMULX, "xmulx" }, |
471 | | { SPARC_INS_XMULXHI, "xmulxhi" }, |
472 | | { SPARC_INS_XNORCC, "xnorcc" }, |
473 | | { SPARC_INS_XNOR, "xnor" }, |
474 | | { SPARC_INS_XORCC, "xorcc" }, |
475 | | { SPARC_INS_XOR, "xor" }, |
476 | | |
477 | | // alias instructions |
478 | | { SPARC_INS_RET, "ret" }, |
479 | | { SPARC_INS_RETL, "retl" }, |
480 | | }; |
481 | | |
482 | | #ifndef CAPSTONE_DIET |
483 | | // special alias insn |
484 | | static const name_map alias_insn_names[] = { |
485 | | { 0, NULL } |
486 | | }; |
487 | | #endif |
488 | | |
489 | | const char *Sparc_insn_name(csh handle, unsigned int id) |
490 | 121k | { |
491 | 121k | #ifndef CAPSTONE_DIET |
492 | 121k | unsigned int i; |
493 | | |
494 | 121k | if (id >= SPARC_INS_ENDING) |
495 | 0 | return NULL; |
496 | | |
497 | | // handle special alias first |
498 | 242k | for (i = 0; i < ARR_SIZE(alias_insn_names); i++) { |
499 | 121k | if (alias_insn_names[i].id == id) |
500 | 0 | return alias_insn_names[i].name; |
501 | 121k | } |
502 | | |
503 | 121k | return insn_name_maps[id].name; |
504 | | #else |
505 | | return NULL; |
506 | | #endif |
507 | 121k | } |
508 | | |
509 | | #ifndef CAPSTONE_DIET |
510 | | static const name_map group_name_maps[] = { |
511 | | // generic groups |
512 | | { SPARC_GRP_INVALID, NULL }, |
513 | | { SPARC_GRP_JUMP, "jump" }, |
514 | | |
515 | | // architecture-specific groups |
516 | | { SPARC_GRP_HARDQUAD, "hardquad" }, |
517 | | { SPARC_GRP_V9, "v9" }, |
518 | | { SPARC_GRP_VIS, "vis" }, |
519 | | { SPARC_GRP_VIS2, "vis2" }, |
520 | | { SPARC_GRP_VIS3, "vis3" }, |
521 | | { SPARC_GRP_32BIT, "32bit" }, |
522 | | { SPARC_GRP_64BIT, "64bit" }, |
523 | | }; |
524 | | #endif |
525 | | |
526 | | const char *Sparc_group_name(csh handle, unsigned int id) |
527 | 87.0k | { |
528 | 87.0k | #ifndef CAPSTONE_DIET |
529 | 87.0k | return id2name(group_name_maps, ARR_SIZE(group_name_maps), id); |
530 | | #else |
531 | | return NULL; |
532 | | #endif |
533 | 87.0k | } |
534 | | |
535 | | // map internal raw register to 'public' register |
536 | | sparc_reg Sparc_map_register(unsigned int r) |
537 | 79.8k | { |
538 | 79.8k | static const unsigned int map[] = { 0, |
539 | 79.8k | SPARC_REG_ICC, SPARC_REG_Y, SPARC_REG_F0, SPARC_REG_F2, SPARC_REG_F4, |
540 | 79.8k | SPARC_REG_F6, SPARC_REG_F8, SPARC_REG_F10, SPARC_REG_F12, SPARC_REG_F14, |
541 | 79.8k | SPARC_REG_F16, SPARC_REG_F18, SPARC_REG_F20, SPARC_REG_F22, SPARC_REG_F24, |
542 | 79.8k | SPARC_REG_F26, SPARC_REG_F28, SPARC_REG_F30, SPARC_REG_F32, SPARC_REG_F34, |
543 | 79.8k | SPARC_REG_F36, SPARC_REG_F38, SPARC_REG_F40, SPARC_REG_F42, SPARC_REG_F44, |
544 | 79.8k | SPARC_REG_F46, SPARC_REG_F48, SPARC_REG_F50, SPARC_REG_F52, SPARC_REG_F54, |
545 | 79.8k | SPARC_REG_F56, SPARC_REG_F58, SPARC_REG_F60, SPARC_REG_F62, SPARC_REG_F0, |
546 | 79.8k | SPARC_REG_F1, SPARC_REG_F2, SPARC_REG_F3, SPARC_REG_F4, SPARC_REG_F5, |
547 | 79.8k | SPARC_REG_F6, SPARC_REG_F7, SPARC_REG_F8, SPARC_REG_F9, SPARC_REG_F10, |
548 | 79.8k | SPARC_REG_F11, SPARC_REG_F12, SPARC_REG_F13, SPARC_REG_F14, SPARC_REG_F15, |
549 | 79.8k | SPARC_REG_F16, SPARC_REG_F17, SPARC_REG_F18, SPARC_REG_F19, SPARC_REG_F20, |
550 | 79.8k | SPARC_REG_F21, SPARC_REG_F22, SPARC_REG_F23, SPARC_REG_F24, SPARC_REG_F25, |
551 | 79.8k | SPARC_REG_F26, SPARC_REG_F27, SPARC_REG_F28, SPARC_REG_F29, SPARC_REG_F30, |
552 | 79.8k | SPARC_REG_F31, SPARC_REG_FCC0, SPARC_REG_FCC1, SPARC_REG_FCC2, SPARC_REG_FCC3, |
553 | 79.8k | SPARC_REG_G0, SPARC_REG_G1, SPARC_REG_G2, SPARC_REG_G3, SPARC_REG_G4, |
554 | 79.8k | SPARC_REG_G5, SPARC_REG_G6, SPARC_REG_G7, SPARC_REG_I0, SPARC_REG_I1, |
555 | 79.8k | SPARC_REG_I2, SPARC_REG_I3, SPARC_REG_I4, SPARC_REG_I5, SPARC_REG_FP, |
556 | 79.8k | SPARC_REG_I7, SPARC_REG_L0, SPARC_REG_L1, SPARC_REG_L2, SPARC_REG_L3, |
557 | 79.8k | SPARC_REG_L4, SPARC_REG_L5, SPARC_REG_L6, SPARC_REG_L7, SPARC_REG_O0, |
558 | 79.8k | SPARC_REG_O1, SPARC_REG_O2, SPARC_REG_O3, SPARC_REG_O4, SPARC_REG_O5, |
559 | 79.8k | SPARC_REG_SP, SPARC_REG_O7, SPARC_REG_F0, SPARC_REG_F4, SPARC_REG_F8, |
560 | 79.8k | SPARC_REG_F12, SPARC_REG_F16, SPARC_REG_F20, SPARC_REG_F24, SPARC_REG_F28, |
561 | 79.8k | SPARC_REG_F32, SPARC_REG_F36, SPARC_REG_F40, SPARC_REG_F44, SPARC_REG_F48, |
562 | 79.8k | SPARC_REG_F52, SPARC_REG_F56, SPARC_REG_F60, |
563 | 79.8k | }; |
564 | | |
565 | 79.8k | if (r < ARR_SIZE(map)) |
566 | 79.8k | return map[r]; |
567 | | |
568 | | // cannot find this register |
569 | 0 | return 0; |
570 | 79.8k | } |
571 | | |
572 | | // map instruction name to instruction ID (public) |
573 | | sparc_reg Sparc_map_insn(const char *name) |
574 | 37.0k | { |
575 | 37.0k | unsigned int i; |
576 | | |
577 | | // NOTE: skip first NULL name in insn_name_maps |
578 | 37.0k | i = name2id(&insn_name_maps[1], ARR_SIZE(insn_name_maps) - 1, name); |
579 | | |
580 | 37.0k | return (i != -1)? i : SPARC_REG_INVALID; |
581 | 37.0k | } |
582 | | |
583 | | // NOTE: put strings in the order of string length since |
584 | | // we are going to compare with mnemonic to find out CC |
585 | | static const name_map alias_icc_maps[] = { |
586 | | { SPARC_CC_ICC_LEU, "leu" }, |
587 | | { SPARC_CC_ICC_POS, "pos" }, |
588 | | { SPARC_CC_ICC_NEG, "neg" }, |
589 | | { SPARC_CC_ICC_NE, "ne" }, |
590 | | { SPARC_CC_ICC_LE, "le" }, |
591 | | { SPARC_CC_ICC_GE, "ge" }, |
592 | | { SPARC_CC_ICC_GU, "gu" }, |
593 | | { SPARC_CC_ICC_CC, "cc" }, |
594 | | { SPARC_CC_ICC_CS, "cs" }, |
595 | | { SPARC_CC_ICC_VC, "vc" }, |
596 | | { SPARC_CC_ICC_VS, "vs" }, |
597 | | { SPARC_CC_ICC_A, "a" }, |
598 | | { SPARC_CC_ICC_N, "n" }, |
599 | | { SPARC_CC_ICC_E, "e" }, |
600 | | { SPARC_CC_ICC_G, "g" }, |
601 | | { SPARC_CC_ICC_L, "l" }, |
602 | | }; |
603 | | |
604 | | static const name_map alias_fcc_maps[] = { |
605 | | { SPARC_CC_FCC_UGE, "uge" }, |
606 | | { SPARC_CC_FCC_ULE, "ule" }, |
607 | | { SPARC_CC_FCC_UG, "ug" }, |
608 | | { SPARC_CC_FCC_UL, "ul" }, |
609 | | { SPARC_CC_FCC_LG, "lg" }, |
610 | | { SPARC_CC_FCC_NE, "ne" }, |
611 | | { SPARC_CC_FCC_UE, "ue" }, |
612 | | { SPARC_CC_FCC_GE, "ge" }, |
613 | | { SPARC_CC_FCC_LE, "le" }, |
614 | | { SPARC_CC_FCC_A, "a" }, |
615 | | { SPARC_CC_FCC_N, "n" }, |
616 | | { SPARC_CC_FCC_U, "u" }, |
617 | | { SPARC_CC_FCC_G, "g" }, |
618 | | { SPARC_CC_FCC_L, "l" }, |
619 | | { SPARC_CC_FCC_E, "e" }, |
620 | | { SPARC_CC_FCC_O, "o" }, |
621 | | }; |
622 | | |
623 | | // map CC string to CC id |
624 | | sparc_cc Sparc_map_ICC(const char *name) |
625 | 28.8k | { |
626 | 28.8k | unsigned int i; |
627 | | |
628 | 28.8k | i = name2id(alias_icc_maps, ARR_SIZE(alias_icc_maps), name); |
629 | | |
630 | 28.8k | return (i != -1)? i : SPARC_CC_INVALID; |
631 | 28.8k | } |
632 | | |
633 | | sparc_cc Sparc_map_FCC(const char *name) |
634 | 7.51k | { |
635 | 7.51k | unsigned int i; |
636 | | |
637 | 7.51k | i = name2id(alias_fcc_maps, ARR_SIZE(alias_fcc_maps), name); |
638 | | |
639 | 7.51k | return (i != -1)? i : SPARC_CC_INVALID; |
640 | 7.51k | } |
641 | | |
642 | | static const name_map hint_maps[] = { |
643 | | { SPARC_HINT_A, ",a" }, |
644 | | { SPARC_HINT_A | SPARC_HINT_PN, ",a,pn" }, |
645 | | { SPARC_HINT_PN, ",pn" }, |
646 | | }; |
647 | | |
648 | | sparc_hint Sparc_map_hint(const char *name) |
649 | 36.3k | { |
650 | 36.3k | size_t i, l1, l2; |
651 | | |
652 | 36.3k | l1 = strlen(name); |
653 | 103k | for(i = 0; i < ARR_SIZE(hint_maps); i++) { |
654 | 92.3k | l2 = strlen(hint_maps[i].name); |
655 | 92.3k | if (l1 > l2) { |
656 | | // compare the last part of @name with this hint string |
657 | 65.4k | if (!strcmp(hint_maps[i].name, name + (l1 - l2))) |
658 | 24.8k | return hint_maps[i].id; |
659 | 65.4k | } |
660 | 92.3k | } |
661 | | |
662 | 11.5k | return SPARC_HINT_INVALID; |
663 | 36.3k | } |
664 | | |
665 | | #endif |