ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/mon/src/mon_ppc.cpp
Revision: 1.5
Committed: 2000-10-15T15:07:15Z (24 years, 1 month ago) by cebix
Branch: MAIN
Changes since 1.4: +1 -1 lines
Log Message:
- extended to 8080 disassembler to a Z80 disassembler
- program renamed to "cxmon"

File Contents

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