ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/mon/src/mon_ppc.cpp
Revision: 1.11
Committed: 2010-02-21T11:58:33Z (14 years, 9 months ago) by cebix
Branch: MAIN
CVS Tags: HEAD
Changes since 1.10: +7 -7 lines
Log Message:
fixed const-correctness

File Contents

# Content
1 /*
2 * mon_ppc.cpp - PowerPC disassembler
3 *
4 * cxmon (C) Christian Bauer, Marc Hellwig
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 #include "sysdeps.h"
22
23 #include "mon.h"
24 #include "mon_disass.h"
25
26
27 // Instruction fields
28 static int primop, exop, vxop, ra, rb, rc, rd;
29 static unsigned short imm;
30
31
32 // Codes for trap instructions
33 static const char *to_code[32] = {
34 NULL, "lgt", "llt", NULL, "eq", "lge", "lle", NULL,
35 "gt", NULL, NULL, NULL, "ge", NULL, NULL, NULL,
36 "lt", NULL, NULL, NULL, "le", NULL, NULL, NULL,
37 "ne", NULL, NULL, NULL, NULL, NULL, NULL, ""
38 };
39
40
41 // Macros for instruction forms
42 #define iform(s, t) fprintf(f, "%s\t$%08x\n", s, t)
43
44 #define bform(s, t) \
45 if (rd == 0) \
46 fprintf(f, "bdnzf%s\t%d,$%08x\n", s, ra, t); \
47 else if (rd == 2) \
48 fprintf(f, "bdzf%s\t%d,$%08x\n", s, ra, t); \
49 else if (rd == 4) { \
50 if (ra == 0) \
51 fprintf(f, "bge%s\t$%08x\n", s, t); \
52 else if (ra == 1) \
53 fprintf(f, "ble%s\t$%08x\n", s, t); \
54 else if (ra == 2) \
55 fprintf(f, "bne%s\t$%08x\n", s, t); \
56 else \
57 fprintf(f, "bf%s\t%d,$%08x\n", s, ra, t); \
58 } else if (rd == 8) \
59 fprintf(f, "bdnzt%s\t%d,$%08x\n", s, ra, t); \
60 else if (rd == 10) \
61 fprintf(f, "bdzt%s\t%d,$%08x\n", s, ra, t); \
62 else if (rd == 12) { \
63 if (ra == 0) \
64 fprintf(f, "blt%s\t$%08x\n", s, t); \
65 else if (ra == 1) \
66 fprintf(f, "bgt%s\t$%08x\n", s, t); \
67 else if (ra == 2) \
68 fprintf(f, "beq%s\t$%08x\n", s, t); \
69 else \
70 fprintf(f, "bt%s\t%d,$%08x\n", s, ra, t); \
71 } else if (rd == 16) \
72 fprintf(f, "bdnz%s\t$%08x\n", s, t); \
73 else if (rd == 18) \
74 fprintf(f, "bdz%s\t$%08x\n", s, t); \
75 else \
76 fprintf(f, "bc%s\t%d,%d,$%08x\n", s, rd, ra, t)
77
78 #define scform(s) fprintf(f, s "\n")
79
80 #define dform_ls(s) \
81 if (ra == 0) \
82 fprintf(f, "%s\tr%d,$%08x\n", s, rd, short(imm)); \
83 else \
84 fprintf(f, "%s\tr%d,$%04x(r%d)\n", s, rd, short(imm), ra)
85 #define dform_fls(s) \
86 if (ra == 0) \
87 fprintf(f, "%s\tfr%d,$%08x\n", s, rd, short(imm)); \
88 else \
89 fprintf(f, "%s\tfr%d,$%04x(r%d)\n", s, rd, short(imm), ra)
90 #define dform_simm(s) fprintf(f, "%s\tr%d,r%d,$%04x\n", s, rd, ra, short(imm))
91 #define dform_simmn(s) fprintf(f, "%s\tr%d,r%d,$%04x\n", s, rd, ra, (-imm) & 0xffff)
92 #define dform_uimm(s) fprintf(f, "%s\tr%d,r%d,$%04x\n", s, ra, rd, imm)
93 #define dform_crs(s) fprintf(f, "%s\tcrf%d,r%d,$%04x\n", s, rd >> 2, ra, short(imm))
94 #define dform_cru(s) fprintf(f, "%s\tcrf%d,r%d,$%04x\n", s, rd >> 2, ra, imm)
95 #define dform_to(s) fprintf(f, "%s\t%d,r%d,$%04x\n", s, rd, ra, short(imm))
96
97 #define dsform(s) fprintf(f, "%s\tr%d,$%04x(r%d)\n", s, rd, short(imm & 0xfffc), ra)
98
99 #define xform_vls(s) \
100 if (ra == 0) \
101 fprintf(f, "%s\tv%d,r%d\n", s, rd, rb); \
102 else \
103 fprintf(f, "%s\tv%d,r%d,r%d\n", s, rd, ra, rb)
104 #define xform_ls(s) \
105 if (ra == 0) \
106 fprintf(f, "%s\tr%d,r%d\n", s, rd, rb); \
107 else \
108 fprintf(f, "%s\tr%d,r%d,r%d\n", s, rd, ra, rb)
109 #define xform_fls(s) \
110 if (ra == 0) \
111 fprintf(f, "%s\tfr%d,r%d\n", s, rd, rb); \
112 else \
113 fprintf(f, "%s\tfr%d,r%d,r%d\n", s, rd, ra, rb)
114 #define xform_lsswi(s) \
115 if (ra == 0) \
116 fprintf(f, "%s\tr%d,%d\n", s, rd, rb ? rb : 32); \
117 else \
118 fprintf(f, "%s\tr%d,r%d,%d\n", s, rd, ra, rb ? rb : 32)
119 #define xform_db(s) fprintf(f, "%s\tr%d,r%d\n", s, rd, rb)
120 #define xform_d(s) fprintf(f, "%s\tr%d\n", s, rd)
121 #define xform_fsr(s) fprintf(f, s "\tr%d,%d\n", rd, ra & 0xf)
122 #define xform_sabc(s) fprintf(f, "%s%s\tr%d,r%d,r%d\n", s, w & 1 ? "." : "", ra, rd, rb)
123 #define xform_sac(s) fprintf(f, "%s%s\tr%d,r%d\n", s, w & 1 ? "." : "", ra, rd)
124 #define xform_tsr(s) fprintf(f, s "\t%d,r%d\n", ra & 0xf, rd)
125 #define xform_sash(s) fprintf(f, s "%s\tr%d,r%d,%d\n", w & 1 ? "." : "", ra, rd, rb)
126 #define xform_crlab(s) fprintf(f, "%s\tcrf%d,r%d,r%d\n", s, rd >> 2, ra, rb)
127 #define xform_fcrab(s) fprintf(f, "%s\tcrf%d,fr%d,fr%d\n", s, rd >> 2, ra, rb)
128 #define xform_crcr(s) fprintf(f, "%s\tcrf%d,crf%d\n", s, rd >> 2, ra >> 2)
129 #define xform_cr(s) fprintf(f, "%s\tcrf%d\n", s, rd >> 2)
130 #define xform_cri(s) fprintf(f, s "%s\tcrf%d,%d\n", w & 1 ? "." : "", rd >> 2, rb >> 1)
131 #define xform_to(s) fprintf(f, "%s\t%d,r%d,r%d\n", s, rd, ra, rb)
132 #define xform_fdb(s) fprintf(f, "%s%s\tfr%d,fr%d\n", s, w & 1 ? "." : "", rd, rb)
133 #define xform_fd(s) fprintf(f, "%s%s\tfr%d\n", s, w & 1 ? "." : "", rd)
134 #define xform_crb(s) fprintf(f, "%s%s\tcrb%d\n", s, w & 1 ? "." : "", rd)
135 #define xform_ab(s) fprintf(f, "%s\tr%d,r%d\n", s, ra, rb)
136 #define xform_b(s) fprintf(f, "%s\tr%d\n", s, rb)
137 #define xform(s) fprintf(f, s "\n")
138
139 #define xlform_b(s) fprintf(f, "%s\t%d,%d\n", s, rd, ra)
140 #define xlform_cr(s) fprintf(f, "%s\tcrb%d,crb%d,crb%d\n", s, rd, ra, rb)
141 #define xlform_crcr(s) fprintf(f, "%s\tcrf%d,crf%d\n", s, rd >> 2, ra >> 2)
142 #define xlform(s) fprintf(f, s "\n")
143
144 #define xfxform_fspr(s) fprintf(f, "%s\tr%d,SPR%d\n", s, rd, ra | (rb << 5))
145 #define xfxform_crm(s) fprintf(f, s "\t$%02x,r%d\n", w >> 12 & 0xff, rd)
146 #define xfxform_tspr(s) fprintf(f, "%s\tSPR%d,r%d\n", s, ra | (rb << 5), rd)
147 #define xfxform_tb(s) fprintf(f, "%s\tr%d\n", s, rd)
148
149 #define xflform(s) fprintf(f, s "%s\t$%02x,fr%d\n", w & 1 ? "." : "", w >> 17 & 0xff, rb)
150
151 #define xsform(s) fprintf(f, s "%s\tr%d,r%d,%d\n", w & 1 ? "." : "", ra, rd, rb | (w & 2 ? 32 : 0))
152
153 #define xoform_dab(s) fprintf(f, "%s%s\tr%d,r%d,r%d\n", s, w & 1 ? "." : "", rd, ra, rb)
154 #define xoform_da(s) fprintf(f, "%s%s\tr%d,r%d\n", s, w & 1 ? "." : "", rd, ra)
155
156 #define aform_dab(s) fprintf(f, "%s%s\tfr%d,fr%d,fr%d\n", s, w & 1 ? "." : "", rd, ra, rb)
157 #define aform_db(s) fprintf(f, "%s%s\tfr%d,fr%d\n", s, w & 1 ? "." : "", rd, rb)
158 #define aform_dac(s) fprintf(f, "%s%s\tfr%d,fr%d,fr%d\n", s, w & 1 ? "." : "", rd, ra, rc)
159 #define aform_dacb(s) fprintf(f, "%s%s\tfr%d,fr%d,fr%d,fr%d\n", s, w & 1 ? "." : "", rd, ra, rc, rb)
160
161 #define mform(s) fprintf(f, "%s%s\tr%d,r%d,r%d,$%08x\n", s, w & 1 ? "." : "", ra, rd, rb, mbme2mask(w >> 6 & 31, w >>1 & 31))
162 #define mform_i(s) fprintf(f, "%s%s\tr%d,r%d,%d,$%08x\n", s, w & 1 ? "." : "", ra, rd, rb, mbme2mask(w >> 6 & 31, w >>1 & 31))
163
164 #define mdform(s) fprintf(f, "%s%s\tr%d,r%d,%d,%d\n", s, w & 1 ? "." : "", ra, rd, rb | (w & 2 ? 32 : 0), rc | (w & 32 ? 32 : 0))
165
166 #define mdsform(s) fprintf(f, "%s%s\tr%d,r%d,r%d,%d\n", s, w & 1 ? "." : "", ra, rd, rb, rc | (w & 32 ? 32 : 0))
167
168 #define va_form(s) fprintf(f, "%s\tv%d,v%d,v%d,v%d\n", s, rd, ra, rb, rc)
169 #define vx_form(s) fprintf(f, "%s\tv%d,v%d,v%d\n", s, rd, ra, rb)
170 #define vxr_form(s) fprintf(f, "%s%s\tv%d,v%d,v%d\n", s, w & (1 << 10) ? "." : "", rd, ra, rb)
171 #define vxi_ra_form(s) fprintf(f, "%s\tv%d,v%d,%d\n", s, rd, rb, ra)
172 #define vx_raz_form(s) \
173 if (ra == 0) \
174 fprintf(f, "%s\tv%d,v%d\n", s, rd, rb); \
175 else \
176 fprintf(f, "?\n")
177 #define vxi_ras_rbz_form(s) \
178 if (rb == 0) \
179 fprintf(f, "%s\tv%d,%d\n", s, rd, ra - (ra & 0x10 ? 0x20 : 0)); \
180 else \
181 fprintf(f, "?\n")
182
183 // Prototypes
184 static void disass4(FILE *f, unsigned int adr, unsigned int w);
185 static void disass19(FILE *f, unsigned int adr, unsigned int w);
186 static void disass31(FILE *f, unsigned int adr, unsigned int w);
187 static void disass59(FILE *f, unsigned int adr, unsigned int w);
188 static void disass63(FILE *f, unsigned int adr, unsigned int w);
189 static unsigned int mbme2mask(int mb, int me);
190 static const char *get_spr(int reg);
191
192
193 /*
194 * Disassemble one instruction
195 */
196
197 void disass_ppc(FILE *f, unsigned int adr, unsigned int w)
198 {
199 // Divide instruction into fields
200 primop = w >> 26;
201 rd = w >> 21 & 0x1f;
202 ra = w >> 16 & 0x1f;
203 rb = w >> 11 & 0x1f;
204 rc = w >> 6 & 0x1f;
205 exop = w >> 1 & 0x3ff;
206 vxop = w & 0x7ff;
207 imm = w & 0xffff;
208
209 // Decode primary opcode
210 switch (primop) {
211 case 2: // 64 bit
212 if (to_code[rd] != NULL)
213 fprintf(f, "td%si\tr%d,$%04x\n", to_code[rd], ra, short(imm));
214 else
215 dform_to("tdi");
216 break;
217
218 case 3:
219 if (to_code[rd] != NULL)
220 fprintf(f, "tw%si\tr%d,$%04x\n", to_code[rd], ra, short(imm));
221 else
222 dform_to("twi");
223 break;
224
225 case 4: // AltiVec
226 disass4(f, adr, w);
227 break;
228
229 case 7: dform_simm("mulli"); break;
230 case 8: dform_simm("subfic"); break;
231
232 case 10:
233 if (rd & 1)
234 dform_cru("cmpldi"); // 64 bit
235 else
236 dform_cru("cmplwi");
237 break;
238
239 case 11:
240 if (rd & 1)
241 dform_crs("cmpdi"); // 64 bit
242 else
243 dform_crs("cmpwi");
244 break;
245
246 case 12:
247 if (imm < 0x8000)
248 dform_simm("addic");
249 else
250 dform_simmn("subic");
251 break;
252
253 case 13:
254 if (imm < 0x8000)
255 dform_simm("addic.");
256 else
257 dform_simmn("subic.");
258 break;
259
260 case 14:
261 if (ra == 0)
262 fprintf(f, "li\tr%d,$%04x\n", rd, short(imm));
263 else
264 if (imm < 0x8000)
265 dform_simm("addi");
266 else
267 dform_simmn("subi");
268 break;
269
270 case 15:
271 if (ra == 0)
272 fprintf(f, "lis\tr%d,$%04x\n", rd, imm);
273 else
274 if (imm < 0x8000)
275 dform_simm("addis");
276 else
277 dform_simmn("subis");
278 break;
279
280 case 16: {
281 int target = short(imm & 0xfffc);
282 const char *form;
283 if (w & 1)
284 if (w & 2)
285 form = "la";
286 else {
287 form = "l";
288 target += adr;
289 }
290 else
291 if (w & 2)
292 form = "a";
293 else {
294 form = "";
295 target += adr;
296 }
297 bform(form, target);
298 break;
299 }
300
301 case 17:
302 if (w & 2)
303 scform("sc");
304 else
305 fprintf(f, "?\n");
306 break;
307
308 case 18: {
309 int target = w & 0x03fffffc;
310 if (target & 0x02000000)
311 target |= 0xfc000000;
312 if (w & 1)
313 if (w & 2)
314 iform("bla", target);
315 else
316 iform("bl", adr + target);
317 else
318 if (w & 2)
319 iform("ba", target);
320 else
321 iform("b", adr + target);
322 break;
323 }
324
325 case 19: disass19(f, adr, w); break;
326 case 20: mform_i("rlwimi"); break;
327 case 21: mform_i("rlwinm"); break;
328 case 23: mform("rlwnm"); break;
329
330 case 24:
331 if (rd == 0 && ra == 0 && imm == 0)
332 fprintf(f, "nop\n");
333 else
334 dform_uimm("ori");
335 break;
336
337 case 25: dform_uimm("oris"); break;
338 case 26: dform_uimm("xori"); break;
339 case 27: dform_uimm("xoris"); break;
340 case 28: dform_uimm("andi."); break;
341 case 29: dform_uimm("andis."); break;
342
343 case 30: // 64 bit
344 switch (w >> 1 & 0xf) {
345 case 0: case 1: mdform("rldicl"); break;
346 case 2: case 3: mdform("rldicr"); break;
347 case 4: case 5: mdform("rldic"); break;
348 case 6: case 7: mdform("rldimi"); break;
349 case 8: mdsform("rldcl"); break;
350 case 9: mdsform("rldcr"); break;
351 default:
352 fprintf(f, "?\n");
353 break;
354 };
355 break;
356
357 case 31: disass31(f, adr, w); break;
358 case 32: dform_ls("lwz"); break;
359 case 33: dform_ls("lwzu"); break;
360 case 34: dform_ls("lbz"); break;
361 case 35: dform_ls("lbzu"); break;
362 case 36: dform_ls("stw"); break;
363 case 37: dform_ls("stwu"); break;
364 case 38: dform_ls("stb"); break;
365 case 39: dform_ls("stbu"); break;
366 case 40: dform_ls("lhz"); break;
367 case 41: dform_ls("lhzu"); break;
368 case 42: dform_ls("lha"); break;
369 case 43: dform_ls("lhau"); break;
370 case 44: dform_ls("sth"); break;
371 case 45: dform_ls("sthu"); break;
372 case 46: dform_ls("lmw"); break;
373 case 47: dform_ls("stmw"); break;
374 case 48: dform_fls("lfs"); break;
375 case 49: dform_fls("lfsu"); break;
376 case 50: dform_fls("lfd"); break;
377 case 51: dform_fls("lfdu"); break;
378 case 52: dform_fls("stfs"); break;
379 case 53: dform_fls("stfsu"); break;
380 case 54: dform_fls("stfd"); break;
381 case 55: dform_fls("stfdu"); break;
382
383 case 58: // 64 bit
384 switch (w & 3) {
385 case 0: dsform("ld"); break;
386 case 1: dsform("ldu"); break;
387 case 2: dsform("lwa"); break;
388 default:
389 fprintf(f, "?\n");
390 break;
391 }
392 break;
393
394 case 59: disass59(f, adr, w); break;
395
396 case 62: // 64 bit
397 switch (w & 3) {
398 case 0: dsform("std"); break;
399 case 1: dsform("stdu"); break;
400 default:
401 fprintf(f, "?\n");
402 break;
403 }
404 break;
405
406 case 63: disass63(f, adr, w); break;
407
408 default:
409 if (!w)
410 fprintf(f, "illegal\n");
411 else
412 fprintf(f, "?\n");
413 break;
414 }
415 }
416
417
418 /*
419 * Disassemble instruction with primary opcode = 4 (VX-Form)
420 */
421
422 static void disass4(FILE *f, unsigned int adr, unsigned int w)
423 {
424 switch (vxop) {
425 case 1540:
426 if (ra == 0 && rb == 0)
427 fprintf(f, "mfvscr\tv%d\n", rd);
428 else
429 fprintf(f, "?\n");
430 break;
431 case 1604:
432 if (rd == 0 && ra == 0)
433 fprintf(f, "mtvscr\tv%d\n", rb);
434 else
435 fprintf(f, "?\n");
436 break;
437 case 384: vx_form("vaddcuw"); break;
438 case 10: vx_form("vaddfp"); break;
439 case 768: vx_form("vaddsbs"); break;
440 case 832: vx_form("vaddshs"); break;
441 case 896: vx_form("vaddsws"); break;
442 case 0: vx_form("vaddubm"); break;
443 case 512: vx_form("vaddubs"); break;
444 case 64: vx_form("vadduhm"); break;
445 case 576: vx_form("vadduhs"); break;
446 case 128: vx_form("vadduwm"); break;
447 case 640: vx_form("vadduws"); break;
448 case 1028: vx_form("vand"); break;
449 case 1092: vx_form("vandc"); break;
450 case 1282: vx_form("vavgsb"); break;
451 case 1346: vx_form("vavgsh"); break;
452 case 1410: vx_form("vavgsw"); break;
453 case 1026: vx_form("vavgub"); break;
454 case 1090: vx_form("vavguh"); break;
455 case 1154: vx_form("vavguw"); break;
456 case 842: vxi_ra_form("vcfsx"); break;
457 case 778: vxi_ra_form("vcfux"); break;
458 case 966: case 966+1024: vxr_form("vcmpbfp"); break;
459 case 198: case 198+1024: vxr_form("vcmpeqfp"); break;
460 case 6: case 6+1024: vxr_form("vcmpequb"); break;
461 case 70: case 70+1024: vxr_form("vcmpequh"); break;
462 case 134: case 134+1024: vxr_form("vcmpequw"); break;
463 case 454: case 454+1024: vxr_form("vcmpgefp"); break;
464 case 710: case 710+1024: vxr_form("vcmpgtfp"); break;
465 case 774: case 774+1024: vxr_form("vcmpgtsb"); break;
466 case 838: case 838+1024: vxr_form("vcmpgtsh"); break;
467 case 902: case 902+1024: vxr_form("vcmpgtsw"); break;
468 case 518: case 518+1024: vxr_form("vcmpgtub"); break;
469 case 582: case 582+1024: vxr_form("vcmpgtuh"); break;
470 case 646: case 646+1024: vxr_form("vcmpgtuw"); break;
471 case 970: vxi_ra_form("vctsxs"); break;
472 case 906: vxi_ra_form("vctuxs"); break;
473 case 394: vx_raz_form("vexptefp"); break;
474 case 458: vx_raz_form("vlogefp"); break;
475 case 1034: vx_form("vmaxfp"); break;
476 case 258: vx_form("vmaxsb"); break;
477 case 322: vx_form("vmaxsh"); break;
478 case 386: vx_form("vmaxsw"); break;
479 case 2: vx_form("vmaxub"); break;
480 case 66: vx_form("vmaxuh"); break;
481 case 130: vx_form("vmaxuw"); break;
482 case 1098: vx_form("vminfp"); break;
483 case 770: vx_form("vminsb"); break;
484 case 834: vx_form("vminsh"); break;
485 case 898: vx_form("vminsw"); break;
486 case 514: vx_form("vminub"); break;
487 case 578: vx_form("vminuh"); break;
488 case 642: vx_form("vminuw"); break;
489 case 12: vx_form("vmrghb"); break;
490 case 76: vx_form("vmrghh"); break;
491 case 140: vx_form("vmrghw"); break;
492 case 268: vx_form("vmrglb"); break;
493 case 332: vx_form("vmrglh"); break;
494 case 396: vx_form("vmrglw"); break;
495 case 776: vx_form("vmulesb"); break;
496 case 840: vx_form("vmulesh"); break;
497 case 520: vx_form("vmuleub"); break;
498 case 584: vx_form("vmuleuh"); break;
499 case 264: vx_form("vmulosb"); break;
500 case 328: vx_form("vmulosh"); break;
501 case 8: vx_form("vmuloub"); break;
502 case 72: vx_form("vmulouh"); break;
503 case 1284: vx_form("vnor"); break;
504 case 1156: vx_form("vor"); break;
505 case 782: vx_form("vpkpx"); break;
506 case 398: vx_form("vpkshss"); break;
507 case 270: vx_form("vpkshus"); break;
508 case 462: vx_form("vpkswss"); break;
509 case 334: vx_form("vpkswus"); break;
510 case 14: vx_form("vpkuhum"); break;
511 case 142: vx_form("vpkuhus"); break;
512 case 78: vx_form("vpkuwum"); break;
513 case 206: vx_form("vpkuwus"); break;
514 case 266: vx_raz_form("vrefp"); break;
515 case 714: vx_raz_form("vrfim"); break;
516 case 522: vx_raz_form("vrfin"); break;
517 case 650: vx_raz_form("vrfip"); break;
518 case 586: vx_raz_form("vrfiz"); break;
519 case 4: vx_form("vrlb"); break;
520 case 68: vx_form("vrlh"); break;
521 case 132: vx_form("vrlw"); break;
522 case 330: vx_raz_form("vrsqrtefp"); break;
523 case 452: vx_form("vsl"); break;
524 case 260: vx_form("vslb"); break;
525 case 324: vx_form("vslh"); break;
526 case 1036: vx_form("vslo"); break;
527 case 388: vx_form("vslw"); break;
528 case 524: vxi_ra_form("vspltb"); break;
529 case 588: vxi_ra_form("vsplth"); break;
530 case 780: vxi_ras_rbz_form("vspltisb"); break;
531 case 844: vxi_ras_rbz_form("vspltish"); break;
532 case 908: vxi_ras_rbz_form("vspltisw"); break;
533 case 652: vxi_ra_form("vspltw"); break;
534 case 708: vx_form("vsr"); break;
535 case 772: vx_form("vsrab"); break;
536 case 836: vx_form("vsrah"); break;
537 case 900: vx_form("vsraw"); break;
538 case 516: vx_form("vsrb"); break;
539 case 580: vx_form("vsrh"); break;
540 case 1100: vx_form("vsro"); break;
541 case 644: vx_form("vsrw"); break;
542 case 1408: vx_form("vsubcuw"); break;
543 case 74: vx_form("vsubfp"); break;
544 case 1792: vx_form("vsubsbs"); break;
545 case 1856: vx_form("vsubshs"); break;
546 case 1920: vx_form("vsubsws"); break;
547 case 1024: vx_form("vsububm"); break;
548 case 1536: vx_form("vsububs"); break;
549 case 1088: vx_form("vsubuhm"); break;
550 case 1600: vx_form("vsubuhs"); break;
551 case 1152: vx_form("vsubuwm"); break;
552 case 1664: vx_form("vsubuws"); break;
553 case 1928: vx_form("vsumsws"); break;
554 case 1672: vx_form("vsum2sws"); break;
555 case 1800: vx_form("vsum4sbs"); break;
556 case 1608: vx_form("vsum4shs"); break;
557 case 1544: vx_form("vsum4ubs"); break;
558 case 846: vx_raz_form("vupkhpx"); break;
559 case 526: vx_raz_form("vupkhsb"); break;
560 case 590: vx_raz_form("vupkhsh"); break;
561 case 974: vx_raz_form("vupklpx"); break;
562 case 654: vx_raz_form("vupklsb"); break;
563 case 718: vx_raz_form("vupklsh"); break;
564 case 1220: vx_form("vxor"); break;
565 default:
566 if ((vxop & 0x43f) == 44) { // vsldoi vD,vA,vB,SHB
567 fprintf(f, "vsldoi\tv%d,v%d,v%d,%d\n", rd, ra, rb, rc & 15);
568 break;
569 }
570 switch (vxop & 0x3f) { // VA-form, must come last
571 case 46: va_form("vmaddfp"); break;
572 case 32: va_form("vmhaddshs"); break;
573 case 33: va_form("vmhraddshs"); break;
574 case 34: va_form("vmladduhm"); break;
575 case 37: va_form("vmsummbm"); break;
576 case 40: va_form("vmsumshm"); break;
577 case 41: va_form("vmsumshs"); break;
578 case 36: va_form("vmsumubm"); break;
579 case 38: va_form("vmsumuhm"); break;
580 case 39: va_form("vmsumuhs"); break;
581 case 47: va_form("vnmsubfp"); break;
582 case 43: va_form("vperm"); break;
583 case 42: va_form("vsel"); break;
584 default: fprintf(f, "?\n"); break;
585 }
586 break;
587 }
588 }
589
590
591 /*
592 * Disassemble instruction with primary opcode = 19 (XL-Form)
593 */
594
595 static void disass19(FILE *f, unsigned int adr, unsigned int w)
596 {
597 switch (exop) {
598 case 0: xlform_crcr("mcrf"); break;
599
600 case 16:
601 if (w & 1)
602 if (rd == 20)
603 fprintf(f, "blrl\n");
604 else
605 xlform_b("bclrl");
606 else
607 if (rd == 20)
608 fprintf(f, "blr\n");
609 else
610 xlform_b("bclr");
611 break;
612
613 case 33:
614 if (ra == rb)
615 fprintf(f, "crnot\tcrb%d,crb%d\n", rd, ra);
616 else
617 xlform_cr("crnor");
618 break;
619
620 case 50: xlform("rfi"); break;
621 case 129: xlform_cr("crandc"); break;
622 case 150: xlform("isync"); break;
623
624 case 193:
625 if (ra == rd && rb == rd)
626 fprintf(f, "crclr\tcrb%d\n", rd);
627 else
628 xlform_cr("crxor");
629 break;
630
631 case 225: xlform_cr("crnand"); break;
632 case 257: xlform_cr("crand"); break;
633
634 case 289:
635 if (ra == rd && rb == rd)
636 fprintf(f, "crset\tcrb%d\n", rd);
637 else
638 xlform_cr("creqv");
639 break;
640
641 case 417: xlform_cr("crorc"); break;
642
643 case 449:
644 if (ra == rb)
645 fprintf(f, "crmove\tcrb%d,crb%d\n", rd, ra);
646 else
647 xlform_cr("cror");
648 break;
649
650 case 528:
651 if (w & 1)
652 if (rd == 20)
653 fprintf(f, "bctrl\n");
654 else
655 xlform_b("bcctrl");
656 else
657 if (rd == 20)
658 fprintf(f, "bctr\n");
659 else
660 xlform_b("bcctr");
661 break;
662
663 default:
664 fprintf(f, "?\n");
665 break;
666 }
667 }
668
669
670 /*
671 * Disassemble instruction with primary opcode = 31 (X-Form/XO-Form/XFX-Form/XS-Form)
672 */
673
674 static void disass31(FILE *f, unsigned int adr, unsigned int w)
675 {
676 switch (exop) {
677 case 0:
678 if (rd & 1)
679 xform_crlab("cmpd"); // 64 bit
680 else
681 xform_crlab("cmpw");
682 break;
683
684 case 4:
685 if (rd == 31 && ra == 0 && rb == 0)
686 xform("trap");
687 else if (to_code[rd] != NULL)
688 fprintf(f, "tw%s\tr%d,r%d\n", to_code[rd], ra, rb);
689 else
690 xform_to("tw");
691 break;
692
693 case 6: xform_vls("lvsl"); break;
694 case 7: xform_vls("lvebx"); break;
695 case 8: xoform_dab("subfc"); break;
696 case 8+512: xoform_dab("subfco"); break;
697 case 9: case 9+512: xoform_dab("mulhdu"); break; // 64 bit
698 case 10: xoform_dab("addc"); break;
699 case 10+512: xoform_dab("addco"); break;
700 case 11: case 11+512: xoform_dab("mulhwu"); break;
701 case 19: xform_d("mfcr"); break;
702 case 20: xform_ls("lwarx"); break;
703 case 21: xform_ls("ldx"); break; // 64 bit
704 case 23: xform_ls("lwzx"); break;
705 case 24: xform_sabc("slw"); break;
706 case 26: xform_sac("cntlzw"); break;
707 case 27: xform_sabc("sld"); break; // 64 bit
708 case 28: xform_sabc("and"); break;
709
710 case 32:
711 if (rd & 1)
712 xform_crlab("cmpld"); // 64 bit
713 else
714 xform_crlab("cmplw");
715 break;
716
717 case 38: xform_vls("lvsr"); break;
718 case 39: xform_vls("lvehx"); break;
719 case 40: xoform_dab("subf"); break;
720 case 40+512: xoform_dab("subfo"); break;
721 case 53: xform_ls("ldux"); break; // 64 bit
722 case 54: xform_ab("dcbst"); break;
723 case 55: xform_ls("lwzux"); break;
724 case 58: xform_sac("cntlzd"); break; // 64 bit
725 case 60: xform_sabc("andc"); break;
726
727 case 68: // 64 bit
728 if (to_code[rd] != NULL)
729 fprintf(f, "td%s\tr%d,r%d\n", to_code[rd], ra, rb);
730 else
731 xform_to("td");
732 break;
733
734 case 71: xform_vls("lvewx"); break;
735 case 73: case 73+512: xoform_dab("mulhd"); break; // 64 bit
736 case 75: case 75+512: xoform_dab("mulhw"); break;
737 case 83: xform_d("mfmsr"); break;
738 case 84: xform_ls("ldarx"); break; // 64 bit
739 case 86: xform_ab("dcbf"); break;
740 case 87: xform_ls("lbzx"); break;
741 case 103: xform_vls("lvx"); break;
742 case 104: xoform_da("neg"); break;
743 case 104+512: xoform_da("nego"); break;
744 case 119: xform_ls("lbzux"); break;
745
746 case 124:
747 if (rd == rb)
748 fprintf(f, "not%s\tr%d,r%d\n", w & 1 ? "." : "", ra, rd);
749 else
750 xform_sabc("nor");
751 break;
752
753 case 135: xform_vls("stvebx"); break;
754 case 136: xoform_dab("subfe"); break;
755 case 136+512: xoform_dab("subfeo"); break;
756 case 138: xoform_dab("adde"); break;
757 case 138+512: xoform_dab("addeo"); break;
758 case 144: xfxform_crm("mtcrf"); break;
759 case 146: xform_d("mtmsr"); break;
760 case 149: xform_ls("stdx"); break; // 64 bit
761
762 case 150:
763 if (w & 1)
764 xform_ls("stwcx.");
765 else
766 fprintf(f, "?\n");
767 break;
768
769 case 151: xform_ls("stwx"); break;
770 case 167: xform_vls("stvehx"); break;
771 case 181: xform_ls("stdux"); break; // 64 bit
772 case 183: xform_ls("stwux"); break;
773 case 199: xform_vls("stvewx"); break;
774 case 200: xoform_da("subfze"); break;
775 case 200+512: xoform_da("subfzeo"); break;
776 case 202: xoform_da("addze"); break;
777 case 202+512: xoform_da("addzeo"); break;
778 case 210: xform_tsr("mtsr"); break;
779
780 case 214: // 64 bit
781 if (w & 1)
782 xform_ls("stdcx");
783 else
784 fprintf(f, "?\n");
785 break;
786
787 case 215: xform_ls("stbx"); break;
788 case 231: xform_vls("stvx"); break;
789 case 232: xoform_da("subfme"); break;
790 case 232+512: xoform_da("subfmeo"); break;
791 case 233: xoform_dab("mulld"); break; // 64 bit
792 case 233+512: xoform_dab("mulldo"); break; // 64 bit
793 case 234: xoform_da("addme"); break;
794 case 234+512: xoform_da("addmeo"); break;
795 case 235: xoform_dab("mullw"); break;
796 case 235+512: xoform_dab("mullwo"); break;
797 case 242: xform_db("mtsrin"); break;
798 case 246: xform_ab("dcbtst"); break;
799 case 247: xform_ls("stbux"); break;
800 case 266: xoform_dab("add"); break;
801 case 266+512: xoform_dab("addo"); break;
802 case 278: xform_ab("dcbt"); break;
803 case 279: xform_ls("lhzx"); break;
804 case 284: xform_sabc("eqv"); break;
805 case 306: xform_b("tlbie"); break;
806 case 310: xform_ls("eciwx"); break;
807 case 311: xform_ls("lhzux"); break;
808 case 316: xform_sabc("xor"); break;
809
810 case 339:
811 if ((ra | (rb << 5)) == 1)
812 fprintf(f, "mfxer\tr%d\n", rd);
813 else if ((ra | (rb << 5)) == 8)
814 fprintf(f, "mflr\tr%d\n", rd);
815 else if ((ra | (rb << 5)) == 9)
816 fprintf(f, "mfctr\tr%d\n", rd);
817 else if ((ra | (rb << 5)) == 256)
818 fprintf(f, "mfvrsave\tr%d\n", rd);
819 else {
820 const char *spr = get_spr(ra | (rb << 5));
821 if (spr)
822 fprintf(f, "mfspr\tr%d,%s\n", rd, spr);
823 else
824 xfxform_fspr("mfspr");
825 }
826 break;
827
828 case 341: xform_ls("lwax"); break; // 64 bit
829 case 343: xform_ls("lhax"); break;
830 case 359: xform_vls("lvxl"); break;
831 case 370: xform("tlbia"); break;
832
833 case 822: // AltiVec
834 if ((rd & 0xc) == 0 && ra == 0 && rb == 0 && (w & 1) == 0) {
835 if (rd & 0x10)
836 fprintf(f, "dssall\n");
837 else
838 fprintf(f, "dss\t%d\n", rd & 3);
839 }
840 else
841 fprintf(f, "?\n");
842 break;
843
844 case 342: // AltiVec
845 if ((rd & 0xc) == 0 && (w & 1) == 0)
846 fprintf(f, "dst%s\tr%d,r%d,%d\n", rd & 0x10 ? "t" : "", ra, rb, rd & 3);
847 else
848 fprintf(f, "?\n");
849 break;
850
851 case 374: // AltiVec
852 if ((rd & 0xc) == 0 && (w & 1) == 0)
853 fprintf(f, "dstst%s\tr%d,r%d,%d\n", rd & 0x10 ? "t" : "", ra, rb, rd & 3);
854 else
855 fprintf(f, "?\n");
856 break;
857
858 case 371:
859 if ((ra | (rb << 5)) == 268)
860 xfxform_tb("mftb");
861 else if ((ra | (rb << 5)) == 269)
862 xfxform_tb("mftbu");
863 else
864 fprintf(f, "?\n");
865 break;
866
867 case 373: xform_ls("lwaux"); break; // 64 bit
868 case 375: xform_ls("lhaux"); break;
869 case 407: xform_ls("sthx"); break;
870 case 412: xform_sabc("orc"); break;
871 case 434: xform_b("slbie"); break; // 64 bit
872 case 438: xform_ls("ecowx"); break;
873 case 439: xform_ls("sthux"); break;
874
875 case 444:
876 if (rd == rb)
877 fprintf(f, "mr%s\tr%d,r%d\n", w & 1 ? "." : "", ra, rd);
878 else
879 xform_sabc("or");
880 break;
881
882 case 457: xoform_dab("divdu"); break; // 64 bit
883 case 457+512: xoform_dab("divduo"); break; // 64 bit
884 case 459: xoform_dab("divwu"); break;
885 case 459+512: xoform_dab("divwuo"); break;
886
887 case 467:
888 if ((ra | (rb << 5)) == 1)
889 fprintf(f, "mtxer\tr%d\n", rd);
890 else if ((ra | (rb << 5)) == 8)
891 fprintf(f, "mtlr\tr%d\n", rd);
892 else if ((ra | (rb << 5)) == 9)
893 fprintf(f, "mtctr\tr%d\n", rd);
894 else if ((ra | (rb << 5)) == 256)
895 fprintf(f, "mtvrsave\tr%d\n", rd);
896 else {
897 const char *spr = get_spr(ra | (rb << 5));
898 if (spr)
899 fprintf(f, "mtspr\t%s,r%d\n", spr, rd);
900 else
901 xfxform_tspr("mtspr");
902 }
903 break;
904
905 case 470: xform_ab("dcbi"); break;
906 case 476: xform_sabc("nand"); break;
907 case 487: xform_vls("stvxl"); break;
908 case 489: xoform_dab("divd"); break; // 64 bit
909 case 489+512: xoform_dab("divdo"); break; // 64 bit
910 case 491: xoform_dab("divw"); break;
911 case 491+512: xoform_dab("divwo"); break;
912 case 498: xform("slbia"); break; // 64 bit
913 case 512: xform_cr("mcrxr"); break;
914 case 533: xform_ls("lswx"); break;
915 case 534: xform_ls("lwbrx"); break;
916 case 535: xform_fls("lfsx"); break;
917 case 536: xform_sabc("srw"); break;
918 case 539: xform_sabc("srd"); break; // 64 bit
919 case 566: xform("tlbsync"); break;
920 case 567: xform_fls("lfsux"); break;
921 case 595: xform_fsr("mfsr"); break;
922 case 597: xform_lsswi("lswi"); break;
923 case 598: xform("sync"); break;
924 case 599: xform_fls("lfdx"); break;
925 case 631: xform_fls("lfdux"); break;
926 case 659: xform_db("mfsrin"); break;
927 case 661: xform_ls("stswx"); break;
928 case 662: xform_ls("stwbrx"); break;
929 case 663: xform_fls("stfsx"); break;
930 case 695: xform_fls("stfsux"); break;
931 case 725: xform_lsswi("stswi"); break;
932 case 727: xform_fls("stfdx"); break;
933 case 758: xform_ab("dcba"); break;
934 case 759: xform_fls("stfdux"); break;
935 case 790: xform_ls("lhbrx"); break;
936 case 792: xform_sabc("sraw"); break;
937 case 794: xform_sabc("srad"); break; // 64 bit
938 case 824: xform_sash("srawi"); break;
939 case 826: case 827: xsform("sradi"); break; // 64 bit
940 case 854: xform("eieio"); break;
941 case 918: xform_ls("sthbrx"); break;
942 case 922: xform_sac("extsh"); break;
943 case 954: xform_sac("extsb"); break;
944 case 978: fprintf(f, "tlbld\tr%d\n", rb); break; // 603
945 case 982: xform_ab("icbi"); break;
946 case 983: xform_fls("stfiwx"); break;
947 case 986: xform_sac("extsw"); break; // 64 bit
948 case 1010: fprintf(f, "tlbli\tr%d\n", rb); break; // 603
949 case 1014: xform_ab("dcbz"); break;
950
951 default:
952 fprintf(f, "?\n");
953 break;
954 }
955 }
956
957
958 /*
959 * Disassemble instruction with primary opcode = 59 (A-Form)
960 */
961
962 static void disass59(FILE *f, unsigned int adr, unsigned int w)
963 {
964 switch (exop & 0x1f) {
965 case 18: aform_dab("fdivs"); break;
966 case 20: aform_dab("fsubs"); break;
967 case 21: aform_dab("fadds"); break;
968 case 22: aform_db("fsqrts"); break;
969 case 24: aform_db("fres"); break;
970 case 25: aform_dac("fmuls"); break;
971 case 28: aform_dacb("fmsubs"); break;
972 case 29: aform_dacb("fmadds"); break;
973 case 30: aform_dacb("fnmsubs"); break;
974 case 31: aform_dacb("fnmadds"); break;
975
976 default:
977 fprintf(f, "?\n");
978 break;
979 }
980 }
981
982
983 /*
984 * Disassemble instruction with primary opcode = 63 (A-Form/X-Form/XFL-Form)
985 */
986
987 static void disass63(FILE *f, unsigned int adr, unsigned int w)
988 {
989 if (exop & 0x10)
990 switch (exop & 0x1f) {
991 case 18: aform_dab("fdiv"); break;
992 case 20: aform_dab("fsub"); break;
993 case 21: aform_dab("fadd"); break;
994 case 22: aform_db("fsqrt"); break;
995 case 23: aform_dacb("fsel"); break;
996 case 25: aform_dac("fmul"); break;
997 case 26: aform_db("frsqrte"); break;
998 case 28: aform_dacb("fmsub"); break;
999 case 29: aform_dacb("fmadd"); break;
1000 case 30: aform_dacb("fnmsub"); break;
1001 case 31: aform_dacb("fnmadd"); break;
1002
1003 default:
1004 fprintf(f, "?\n");
1005 break;
1006 }
1007 else
1008 switch (exop) {
1009 case 0: xform_fcrab("fcmpu"); break;
1010 case 12: xform_fdb("frsp"); break;
1011 case 14: xform_fdb("fctiw"); break;
1012 case 15: xform_fdb("fctiwz"); break;
1013 case 32: xform_fcrab("fcmpo"); break;
1014 case 38: xform_crb("mtfsb1"); break;
1015 case 40: xform_fdb("fneg"); break;
1016 case 64: xform_crcr("mcrfs"); break;
1017 case 70: xform_crb("mtfsb0"); break;
1018 case 72: xform_fdb("fmr"); break;
1019 case 134: xform_cri("mtfsfi"); break;
1020 case 136: xform_fdb("fnabs"); break;
1021 case 264: xform_fdb("fabs"); break;
1022 case 583: xform_fd("mffs"); break;
1023 case 711: xflform("mtfsf"); break;
1024 case 814: xform_fdb("fctid"); break; // 64 bit
1025 case 815: xform_fdb("fctidz"); break; // 64 bit
1026 case 846: xform_fdb("fcfid"); break; // 64 bit
1027
1028 default:
1029 fprintf(f, "?\n");
1030 break;
1031 }
1032 }
1033
1034
1035 /*
1036 * Convert mask begin/end to mask
1037 */
1038
1039 static unsigned int mbme2mask(int mb, int me)
1040 {
1041 unsigned int m = 0;
1042 int i;
1043
1044 if (mb <= me)
1045 for (i=mb; i<=me; i++)
1046 m |= 1 << (31-i);
1047 else {
1048 for (i=0; i<=me; i++)
1049 m |= 1 << (31-i);
1050 for (i=mb; i<=31; i++)
1051 m |= 1 << (31-i);
1052 }
1053 return m;
1054 }
1055
1056
1057 /*
1058 * Convert SPR number to register name
1059 */
1060
1061 const char *get_spr(int reg)
1062 {
1063 switch (reg) {
1064 case 1: return "xer";
1065 case 8: return "lr";
1066 case 9: return "ctr";
1067 case 18: return "dsisr";
1068 case 19: return "dar";
1069 case 22: return "dec";
1070 case 25: return "sdr1";
1071 case 26: return "srr0";
1072 case 27: return "srr1";
1073 case 272: return "sprg0";
1074 case 273: return "sprg1";
1075 case 274: return "sprg2";
1076 case 275: return "sprg3";
1077 case 280: return "asr"; // 64 bit
1078 case 282: return "ear";
1079 case 284: return "tbl";
1080 case 285: return "tbu";
1081 case 287: return "pvr";
1082 case 528: return "ibat0u";
1083 case 529: return "ibat0l";
1084 case 530: return "ibat1u";
1085 case 531: return "ibat1l";
1086 case 532: return "ibat2u";
1087 case 533: return "ibat2l";
1088 case 534: return "ibat3u";
1089 case 535: return "ibat3l";
1090 case 536: return "dbat0u";
1091 case 537: return "dbat0l";
1092 case 538: return "dbat1u";
1093 case 539: return "dbat1l";
1094 case 540: return "dbat2u";
1095 case 541: return "dbat2l";
1096 case 542: return "dbat3u";
1097 case 543: return "dbat3l";
1098 case 1013: return "dabr";
1099
1100 case 0: return "mq"; // 601
1101 case 4: return "rtcu"; // 601
1102 case 5: return "rtcl"; // 601
1103 case 20: return "rtcu"; // 601
1104 case 21: return "rtcl"; // 601
1105 case 952: return "mmcr0"; // 604
1106 case 953: return "pmc1"; // 604
1107 case 954: return "pmc2"; // 604
1108 case 955: return "sia"; // 604
1109 case 956: return "mmcr1"; // 604e
1110 case 957: return "pmc3"; // 604e
1111 case 958: return "pmc4"; // 604e
1112 case 959: return "sda"; // 604
1113 case 976: return "dmiss"; // 603
1114 case 977: return "dcmp"; // 603
1115 case 978: return "hash1"; // 603
1116 case 979: return "hash2"; // 603
1117 case 980: return "imiss"; // 603
1118 case 981: return "icmp"; // 603
1119 case 982: return "rpa"; // 603
1120 case 1008: return "hid0"; // 601/603/604
1121 case 1009: return "hid1"; // 601/603/604e
1122 case 1010: return "iabr"; // 601/603
1123 case 1023: return "pir"; // 601/604
1124
1125 case 256: return "vrsave"; // AltiVec
1126
1127 default: return NULL;
1128 }
1129 }