ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/mon/src/mon_ppc.cpp
Revision: 1.1.1.1 (vendor branch)
Committed: 1999-10-04T19:31:09Z (24 years, 7 months ago) by cebix
Branch: cebix
CVS Tags: start
Changes since 1.1: +0 -0 lines
Log Message:
Imported sources

File Contents

# Content
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 }