ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/mon/src/mon_ppc.cpp
Revision: 1.9
Committed: 2005-03-13T17:09:19Z (19 years, 8 months ago) by gbeauche
Branch: MAIN
Changes since 1.8: +139 -2 lines
Log Message:
initial altivec disassembler

File Contents

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