ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/mon/src/mon_ppc.cpp
Revision: 1.1
Committed: 1999-10-04T19:31:09Z (25 years, 2 months ago) by cebix
Branch: MAIN
Branch point for: cebix
Log Message:
Initial revision

File Contents

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