Annotation of sys/arch/m68k/m68k/db_disasm.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: db_disasm.c,v 1.9 2002/03/14 01:26:34 millert Exp $ */
2: /* $NetBSD: db_disasm.c,v 1.19 1996/10/30 08:22:39 is Exp $ */
3:
4: /*
5: * Copyright (c) 1994 Christian E. Hopps
6: * All rights reserved.
7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions
10: * are met:
11: * 1. Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer.
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
16: * 3. All advertising materials mentioning features or use of this software
17: * must display the following acknowledgement:
18: * This product includes software developed by Christian E. Hopps.
19: * 4. The name of the author may not be used to endorse or promote products
20: * derived from this software without specific prior written permission
21: *
22: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32: */
33: /*
34: * Notes:
35: *
36: * Much can be done with this format, with a lot of hacking even
37: * a moto emul. could be built. However things like symbol lookup
38: * and reference are needed right away.
39: *
40: * the only functions that use the "get_xxx()" notation should be
41: * ones that modify things in a dis_buffer_t besides the buffers.
42: * (namely the used field)
43: *
44: * An attempt has been made to *always* increment dbuf->used++ immediately
45: * after referencing a value beyond the current "short *" address.
46: * this meant either only referencing the value once or placing it in
47: * a local var. If you play with this keep this style. Its very useful
48: * in eliminating a very easy to make hard to find logic error.
49: *
50: * I broke style in 2 ways with one macro ``addchar()''
51: * However it makes sense, consider that it is called *a lot* and
52: * commonly with things like ","'s
53: *
54: * *dbuf->casm++ = ','; || ADDCHAR(dbuf,','); || addchar(dbuf,',');
55: * I chose:
56: * addchar(',');
57: *
58: * If this is not enough to convince you, please load up you emacs or
59: * vi and do a fancy regex-replace, and compare for yourself.
60: * (The 2 rules of style I broke if you failed to notice are:
61: * 1: lower case macro name 2: implicit reference to local var name.)
62: *
63: * (chopps - March 1, 1994)
64: */
65:
66: #include <sys/param.h>
67:
68: #include <machine/db_machdep.h>
69:
70: #include <ddb/db_sym.h>
71: #include <ddb/db_output.h>
72: #include <m68k/m68k/db_disasm.h>
73:
74: void get_modregstr(dis_buffer_t *, int, int, int, int);
75: void get_immed(dis_buffer_t *, int);
76: void get_fpustdGEN(dis_buffer_t *, u_short, const char *);
77: void addstr(dis_buffer_t *, const char *s);
78: void prints(dis_buffer_t *, int, int);
79: void printu(dis_buffer_t *, u_int, int);
80: void prints_wb(dis_buffer_t *, int, int, int);
81: void printu_wb(dis_buffer_t *, u_int, int, int);
82: void prints_bf(dis_buffer_t *, int, int, int);
83: void printu_bf(dis_buffer_t *, u_int, int, int);
84: void iaddstr(dis_buffer_t *, const char *s);
85: void iprints(dis_buffer_t *, int, int);
86: void iprintu(dis_buffer_t *, u_int, int);
87: void iprints_wb(dis_buffer_t *, int, int, int);
88: void iprintu_wb(dis_buffer_t *, u_int, int, int);
89: void make_cond(dis_buffer_t *, int , char *);
90: void print_fcond(dis_buffer_t *, char);
91: void print_mcond(dis_buffer_t *, char);
92: void print_disp(dis_buffer_t *, int, int, int);
93: void print_addr(dis_buffer_t *, u_long);
94: void print_reglist(dis_buffer_t *, int, u_short);
95: void print_freglist(dis_buffer_t *, int, u_short, int);
96: void print_fcode(dis_buffer_t *, u_short);
97:
98: /* groups */
99: void opcode_bitmanip(dis_buffer_t *, u_short);
100: void opcode_move(dis_buffer_t *, u_short);
101: void opcode_misc(dis_buffer_t *, u_short);
102: void opcode_branch(dis_buffer_t *, u_short);
103: void opcode_coproc(dis_buffer_t *, u_short);
104: void opcode_0101(dis_buffer_t *, u_short);
105: void opcode_1000(dis_buffer_t *, u_short);
106: void opcode_addsub(dis_buffer_t *, u_short);
107: void opcode_1010(dis_buffer_t *, u_short);
108: void opcode_1011(dis_buffer_t *, u_short);
109: void opcode_1100(dis_buffer_t *, u_short);
110: void opcode_1110(dis_buffer_t *, u_short);
111: void opcode_fpu(dis_buffer_t *, u_short);
112: void opcode_mmu(dis_buffer_t *, u_short);
113: void opcode_mmu040(dis_buffer_t *, u_short);
114: void opcode_move16(dis_buffer_t *, u_short);
115:
116: /* subs of groups */
117: void opcode_movec(dis_buffer_t *, u_short);
118: void opcode_divmul(dis_buffer_t *, u_short);
119: void opcode_movem(dis_buffer_t *, u_short);
120: void opcode_fmove_ext(dis_buffer_t *, u_short, u_short);
121: void opcode_pmove(dis_buffer_t *, u_short, u_short);
122: void opcode_pflush(dis_buffer_t *, u_short, u_short);
123:
124: #define addchar(ch) (*dbuf->casm++ = ch)
125: #define iaddchar(ch) (*dbuf->cinfo++ = ch)
126:
127: typedef void dis_func_t(dis_buffer_t *, u_short);
128:
129: dis_func_t *const opcode_map[16] = {
130: opcode_bitmanip, opcode_move, opcode_move, opcode_move,
131: opcode_misc, opcode_0101, opcode_branch, opcode_move,
132: opcode_1000, opcode_addsub, opcode_1010, opcode_1011,
133: opcode_1100, opcode_addsub, opcode_1110, opcode_coproc
134: };
135:
136: const char *const cc_table[16] = {
137: "t", "f", "hi", "ls",
138: "cc", "cs", "ne", "eq",
139: "vc", "vs", "pl", "mi",
140: "ge", "lt", "gt", "le"
141: };
142:
143: const char *const fpcc_table[32] = {
144: "f", "eq", "ogt", "oge", "olt", "ole", "ogl", "or",
145: "un", "ueq", "ugt", "uge", "ult", "ule", "ne", "t",
146: "sf", "seq", "gt", "ge", "lt", "le", "gl", "gle",
147: "ngle", "ngl", "nle", "nlt", "nge", "ngt", "sne", "st" };
148:
149: const char *const mmcc_table[16] = {
150: "bs", "bc", "ls", "lc", "ss", "sc", "as", "sc",
151: "ws", "wc", "is", "ic", "gs", "gc", "cs", "cc" };
152:
153:
154: const char *const aregs[8] = {"a0","a1","a2","a3","a4","a5","a6","sp"};
155: const char *const dregs[8] = {"d0","d1","d2","d3","d4","d5","d6","d7"};
156: const char *const fpregs[8] = {
157: "fp0","fp1","fp2","fp3","fp4","fp5","fp6","fp7" };
158: const char *const fpcregs[3] = { "fpiar", "fpsr", "fpcr" };
159:
160: /*
161: * Disassemble intruction at location ``loc''.
162: * Returns location of next instruction.
163: */
164:
165: static char asm_buffer[256];
166: static char info_buffer[256];
167:
168: db_addr_t
169: db_disasm(loc, moto_syntax)
170: db_addr_t loc;
171: boolean_t moto_syntax;
172: {
173: u_short opc;
174: dis_func_t *func;
175: dis_buffer_t dbuf;
176:
177: dbuf.casm = dbuf.dasm = asm_buffer;
178: dbuf.cinfo = dbuf.info = info_buffer;
179: dbuf.used = 0;
180: dbuf.val = (short *)loc;
181: dbuf.mit = moto_syntax ? 0 : 1;
182:
183: dbuf.dasm[0] = 0;
184: dbuf.info[0] = 0;
185:
186: opc = *dbuf.val;
187: dbuf.used++;
188:
189: func = opcode_map[OPCODE_MAP(opc)];
190: func(&dbuf, opc);
191:
192: db_printf("%s",asm_buffer);
193: if (info_buffer[0])
194: db_printf("\t[%s]\n",info_buffer);
195: else
196: db_printf("\n");
197: return (loc + sizeof(short)*dbuf.used);
198: }
199: /*
200: * Bit manipulation/MOVEP/Immediate.
201: */
202: void
203: opcode_bitmanip(dbuf, opc)
204: dis_buffer_t *dbuf;
205: u_short opc;
206: {
207: char *tmp;
208: u_short ext;
209: int sz;
210:
211: tmp = NULL;
212:
213: switch (opc) {
214: case ANDITOCCR_INST:
215: tmp = "andib\t";
216: break;
217: case ANDIROSR_INST:
218: tmp = "andiw\t";
219: break;
220: case EORITOCCR_INST:
221: tmp = "eorib\t";
222: break;
223: case EORITOSR_INST:
224: tmp = "eoriw\t";
225: break;
226: case ORITOCCR_INST:
227: tmp = "orib\t";
228: break;
229: case ORITOSR_INST:
230: tmp = "oriw\t";
231: break;
232: }
233: if (tmp) {
234: addstr(dbuf, tmp);
235: if (ISBITSET(opc,6)) {
236: get_immed(dbuf, SIZE_WORD);
237: addstr(dbuf, ",sr");
238: } else {
239: get_immed(dbuf, SIZE_BYTE);
240: addstr(dbuf, ",ccr");
241: }
242: return;
243: }
244:
245: if (IS_INST(RTM,opc)) {
246: addstr(dbuf, "rtm\t");
247: if (ISBITSET(opc,3))
248: PRINT_AREG(dbuf, BITFIELD(opc,2,0));
249: else
250: PRINT_DREG(dbuf, BITFIELD(opc,2,0));
251: return;
252: }
253:
254: if (IS_INST(MOVEP,opc)) {
255: addstr(dbuf, "movp");
256: if (ISBITSET(opc,6))
257: addchar('l');
258: else
259: addchar('w');
260: addchar('\t');
261: if (ISBITSET(opc,7)) {
262: PRINT_DREG(dbuf, BITFIELD(opc, 11, 9));
263: addchar(',');
264: }
265: PRINT_AREG(dbuf, BITFIELD(opc, 2, 0));
266: addchar('@');
267: addchar('(');
268: print_disp(dbuf, *(dbuf->val + 1), SIZE_WORD,
269: BITFIELD(opc, 2, 0));
270: dbuf->used++;
271: addchar(')');
272: if (!ISBITSET(opc,7)) {
273: addchar(',');
274: PRINT_DREG(dbuf, BITFIELD(opc, 11, 9));
275: }
276: return;
277: }
278:
279: switch (opc & BCHGD_MASK) {
280: case BCHGD_INST:
281: tmp = "bchg\t";
282: break;
283: case BCLRD_INST:
284: tmp = "bclr\t";
285: break;
286: case BSETD_INST:
287: tmp = "bset\t";
288: break;
289: case BTSTD_INST:
290: tmp = "btst\t";
291: break;
292: }
293: if (tmp) {
294: addstr(dbuf, tmp);
295: PRINT_DREG(dbuf, BITFIELD(opc,11,9));
296: addchar(',');
297: get_modregstr(dbuf,5,GETMOD_BEFORE,0,0);
298: return;
299: }
300:
301: switch (opc & BCHGS_MASK) {
302: case BCHGS_INST:
303: tmp = "bchg\t";
304: break;
305: case BCLRS_INST:
306: tmp = "bclr\t";
307: break;
308: case BSETS_INST:
309: tmp = "bset\t";
310: break;
311: case BTSTS_INST:
312: tmp = "btst\t";
313: break;
314: }
315: if (tmp) {
316: addstr(dbuf, tmp);
317: get_immed(dbuf, SIZE_BYTE);
318: addchar(',');
319: get_modregstr(dbuf, 5, GETMOD_BEFORE, 0, 1);
320: return;
321: }
322:
323: if (IS_INST(CAS2,opc)) {
324: u_short ext2;
325:
326: ext = *(dbuf->val + 1);
327: ext2 = *(dbuf->val + 2);
328: dbuf->used += 2;
329:
330: if (ISBITSET(opc,9))
331: addstr(dbuf, "cas2l\t");
332: else
333: addstr(dbuf, "cas2w\t");
334:
335: PRINT_DREG(dbuf, BITFIELD(ext,2,0));
336: addchar(':');
337: PRINT_DREG(dbuf, BITFIELD(ext2,2,0));
338: addchar(',');
339:
340: PRINT_DREG(dbuf, BITFIELD(ext,8,6));
341: addchar(':');
342: PRINT_DREG(dbuf, BITFIELD(ext2,8,6));
343: addchar(',');
344:
345: if (ISBITSET(ext,15))
346: PRINT_AREG(dbuf, BITFIELD(ext,14,12));
347: else
348: PRINT_DREG(dbuf, BITFIELD(ext,14,12));
349: addchar('@');
350: addchar(':');
351: if (ISBITSET(ext2,15))
352: PRINT_AREG(dbuf, BITFIELD(ext2,14,12));
353: else
354: PRINT_DREG(dbuf, BITFIELD(ext2,14,12));
355: addchar('@');
356: return;
357: }
358:
359: switch (opc & CAS_MASK) {
360: case CAS_INST:
361: ext = *(dbuf->val + 1);
362: dbuf->used++;
363:
364: addstr(dbuf,"cas");
365: sz = BITFIELD(opc,10,9);
366: if (sz == 0) {
367: sz = SIZE_BYTE;
368: addchar('b');
369: } else if (sz == 1) {
370: sz = SIZE_WORD;
371: addchar('w');
372: } else {
373: sz = SIZE_LONG;
374: addchar('l');
375: }
376: addchar('\t');
377: PRINT_DREG(dbuf, BITFIELD(ext, 2, 0));
378: addchar(',');
379: PRINT_DREG(dbuf, BITFIELD(ext, 8, 6));
380: addchar(',');
381: get_modregstr(dbuf, 5, GETMOD_BEFORE, sz, 1);
382: return;
383: case CHK2_INST:
384: /* case CMP2_INST: */
385: ext = *(dbuf->val + 1);
386: dbuf->used++;
387:
388: if (ISBITSET(ext,11))
389: addstr(dbuf,"chk2");
390: else
391: addstr(dbuf,"cmp2");
392:
393: sz = BITFIELD(opc,10,9);
394: if (sz == 0) {
395: sz = SIZE_BYTE;
396: addchar('b');
397: } else if (sz == 1) {
398: sz = SIZE_WORD;
399: addchar('w');
400: } else {
401: sz = SIZE_LONG;
402: addchar('l');
403: }
404: addchar('\t');
405: get_modregstr(dbuf, 5, GETMOD_BEFORE, sz, 1);
406:
407: addchar(',');
408: if(ISBITSET(ext,15))
409: PRINT_AREG(dbuf, BITFIELD(ext, 14, 12));
410: else
411: PRINT_DREG(dbuf, BITFIELD(ext, 14, 12));
412: return;
413: }
414:
415: switch (ADDI_MASK & opc) {
416: case MOVES_INST:
417: addstr(dbuf, "movs");
418: sz = BITFIELD(opc,7,6);
419: if (sz == 0) {
420: addchar('b');
421: sz = SIZE_BYTE;
422: } else if (sz == 1) {
423: addchar('w');
424: sz = SIZE_WORD;
425: } else {
426: addchar ('l');
427: sz = SIZE_LONG;
428: }
429: addchar('\t');
430:
431: ext = *(dbuf->val + 1);
432: dbuf->used++;
433:
434: if (ISBITSET(ext,11)) {
435: if (ISBITSET(ext,15))
436: PRINT_AREG(dbuf,BITFIELD(ext,14,12));
437: else
438: PRINT_DREG(dbuf,BITFIELD(ext,14,12));
439: addchar(',');
440: get_modregstr(dbuf, 5, GETMOD_BEFORE, sz, 1);
441: } else {
442: get_modregstr(dbuf, 5, GETMOD_BEFORE, sz, 1);
443: addchar(',');
444: if (ISBITSET(ext,15))
445: PRINT_AREG(dbuf,BITFIELD(ext,14,12));
446: else
447: PRINT_DREG(dbuf,BITFIELD(ext,14,12));
448: }
449: return;
450: case ADDI_INST:
451: tmp = "addi";
452: break;
453: case ANDI_INST:
454: tmp = "andi";
455: break;
456: case CMPI_INST:
457: tmp = "cmpi";
458: break;
459: case EORI_INST:
460: tmp = "eori";
461: break;
462: case ORI_INST:
463: tmp = "ori";
464: break;
465: case SUBI_INST:
466: tmp = "subi";
467: break;
468: }
469: if (tmp) {
470: addstr(dbuf, tmp);
471: sz = BITFIELD(opc,7,6);
472: switch (sz) {
473: case 0:
474: addchar('b');
475: addchar('\t');
476: sz = SIZE_BYTE;
477: break;
478: case 1:
479: addchar('w');
480: addchar('\t');
481: sz = SIZE_WORD;
482: break;
483: case 2:
484: addchar ('l');
485: addchar('\t');
486: get_immed(dbuf,SIZE_LONG);
487: addchar(',');
488: get_modregstr(dbuf,5,GETMOD_BEFORE,SIZE_LONG,2);
489: return;
490: }
491: get_immed(dbuf,sz);
492: addchar(',');
493: get_modregstr(dbuf,5,GETMOD_BEFORE,sz,1);
494: return;
495: }
496: }
497:
498: /*
499: * move byte/word/long and q
500: * 00xx (01==.b 10==.l 11==.w) and 0111(Q)
501: */
502: void
503: opcode_move(dbuf, opc)
504: dis_buffer_t *dbuf;
505: u_short opc;
506: {
507: int sz, lused;
508:
509: sz = 0;
510: switch (OPCODE_MAP(opc)) {
511: case 0x1: /* move.b */
512: sz = SIZE_BYTE;
513: break;
514: case 0x3: /* move.w */
515: sz = SIZE_WORD;
516: break;
517: case 0x2: /* move.l */
518: sz = SIZE_LONG;
519: break;
520: case 0x7: /* moveq */
521: addstr(dbuf, "movq\t#");
522: prints_bf(dbuf, opc, 7, 0);
523: addchar(',');
524: PRINT_DREG(dbuf,BITFIELD(opc,11,9));
525: return;
526: }
527: addstr(dbuf, "mov");
528:
529: if (BITFIELD(opc,8,6) == AR_DIR)
530: addchar('a');
531:
532: if (sz == SIZE_BYTE)
533: addchar('b');
534: else if (sz == SIZE_WORD)
535: addchar('w');
536: else
537: addchar('l');
538:
539: addchar('\t');
540: lused = dbuf->used;
541: get_modregstr(dbuf, 5, GETMOD_BEFORE, sz, 0);
542: addchar(',');
543: get_modregstr(dbuf, 11, GETMOD_AFTER, sz, dbuf->used - lused);
544: }
545:
546: /*
547: * misc opcodes.
548: */
549: void
550: opcode_misc(dbuf, opc)
551: dis_buffer_t *dbuf;
552: u_short opc;
553: {
554: char *tmp;
555: int sz;
556:
557: tmp = NULL;
558:
559: /* Check against no option instructions */
560: switch (opc) {
561: case BGND_INST:
562: tmp = "bgnd";
563: break;
564: case ILLEGAL_INST:
565: tmp = "illegal";
566: break;
567: case MOVEFRC_INST:
568: case MOVETOC_INST:
569: opcode_movec(dbuf, opc);
570: return;
571: case NOP_INST:
572: tmp = "nop";
573: break;
574: case RESET_INST:
575: tmp = "reset";
576: break;
577: case RTD_INST:
578: addstr(dbuf, "rtd\t");
579: get_immed(dbuf, SIZE_WORD);
580: return;
581: case RTE_INST:
582: tmp = "rte";
583: break;
584: case RTR_INST:
585: tmp = "rtr";
586: break;
587: case RTS_INST:
588: tmp = "rts";
589: break;
590: case STOP_INST:
591: addstr(dbuf, "stop\t");
592: get_immed(dbuf, SIZE_WORD);
593: return;
594: case TRAPV_INST:
595: tmp = "trapv";
596: break;
597: default:
598: break;
599: }
600: if (tmp) {
601: addstr(dbuf, tmp);
602: return;
603: }
604:
605: switch (opc & BKPT_MASK) {
606: case BKPT_INST:
607: addstr(dbuf, "bkpt\t#");
608: printu_bf(dbuf, opc, 2, 0);
609: return;
610: case EXTBW_INST:
611: addstr(dbuf, "extw\t");
612: get_modregstr(dbuf,2,DR_DIR,0,0);
613: return;
614: case EXTWL_INST:
615: addstr(dbuf, "extl\t");
616: get_modregstr(dbuf,2,DR_DIR,0,0);
617: return;
618: case EXTBL_INST:
619: addstr(dbuf, "extbl\t");
620: get_modregstr(dbuf,2,DR_DIR,0,0);
621: return;
622: case LINKW_INST:
623: case LINKL_INST:
624: if ((LINKW_MASK & opc) == LINKW_INST) {
625: addstr(dbuf, "linkw\t");
626: get_modregstr(dbuf, 2, AR_DIR, 0, 1);
627: } else {
628: addstr(dbuf, "linkl\t");
629: get_modregstr(dbuf, 2, AR_DIR, 0, 2);
630: }
631: addchar(',');
632: if ((LINKW_MASK & opc) == LINKW_INST)
633: get_immed(dbuf, SIZE_WORD);
634: else
635: get_immed(dbuf,SIZE_LONG);
636: return;
637: case MOVETOUSP_INST:
638: case MOVEFRUSP_INST:
639: addstr(dbuf, "movl\t");
640: if (!ISBITSET(opc,3)) {
641: get_modregstr(dbuf, 2, AR_DIR, 0, 0);
642: addchar(',');
643: }
644: addstr(dbuf, "usp");
645: if (ISBITSET(opc,3)) {
646: addchar(',');
647: get_modregstr(dbuf, 2, AR_DIR, 0, 0);
648: }
649: return;
650: case SWAP_INST:
651: addstr(dbuf, "swap\t");
652: get_modregstr(dbuf, 2, DR_DIR, 0, 0);
653: return;
654: case UNLK_INST:
655: addstr(dbuf, "unlk\t");
656: get_modregstr(dbuf, 2, AR_DIR, 0, 0);
657: return;
658: }
659:
660: if ((opc & TRAP_MASK) == TRAP_INST) {
661: addstr(dbuf, "trap\t#");
662: printu_bf(dbuf, opc, 3, 0);
663: return;
664: }
665:
666: sz = 0;
667: switch (DIVSL_MASK & opc) {
668: case DIVSL_INST:
669: case MULSL_INST:
670: opcode_divmul(dbuf, opc);
671: return;
672: case JMP_INST:
673: tmp = "jmp\t";
674: break;
675: case JSR_INST:
676: tmp = "jsr\t";
677: break;
678: case MOVEFRCCR_INST:
679: tmp = "mov\tccr,";
680: break;
681: case MOVEFRSR_INST:
682: tmp = "mov\tsr,";
683: break;
684: case NBCD_INST:
685: tmp = "nbcd\t";
686: break;
687: case PEA_INST:
688: tmp = "pea\t";
689: break;
690: case TAS_INST:
691: tmp = "tas\t";
692: break;
693: case MOVETOCCR_INST:
694: case MOVETOSR_INST:
695: tmp = "mov\t";
696: sz = SIZE_WORD;
697: break;
698: }
699: if (tmp) {
700: addstr(dbuf, tmp);
701: get_modregstr(dbuf,5, GETMOD_BEFORE, sz, 0);
702: if(IS_INST(MOVETOSR,opc))
703: addstr(dbuf, ",sr");
704: else if(IS_INST(MOVETOCCR,opc))
705: addstr(dbuf, ",ccr");
706: return;
707: }
708:
709: if ((opc & MOVEM_MASK) == MOVEM_INST) {
710: opcode_movem(dbuf, opc);
711: return;
712: }
713:
714: switch (opc & CLR_MASK) {
715: case CLR_INST:
716: tmp = "clr";
717: break;
718: case NEG_INST:
719: tmp = "neg";
720: break;
721: case NEGX_INST:
722: tmp = "negx";
723: break;
724: case NOT_INST:
725: tmp = "not";
726: break;
727: case TST_INST:
728: tmp = "tst";
729: break;
730: }
731: if (tmp) {
732: int sz, msz;
733:
734: addstr(dbuf, tmp);
735:
736: msz = BITFIELD(opc,7,6);
737: if (msz == 0) {
738: tmp = "b\t";
739: sz = SIZE_BYTE;
740: } else if (msz == 1) {
741: tmp = "w\t";
742: sz = SIZE_WORD;
743: } else {
744: tmp = "l\t";
745: sz = SIZE_LONG;
746: }
747: addstr(dbuf, tmp);
748: get_modregstr(dbuf, 5, GETMOD_BEFORE, sz, 0);
749: return;
750: }
751:
752: if ((opc & LEA_MASK) == LEA_INST) {
753: addstr(dbuf, "lea\t");
754: get_modregstr(dbuf, 5, GETMOD_BEFORE, SIZE_LONG, 0);
755: addchar(',');
756: get_modregstr(dbuf, 11, AR_DIR, 0, 0);
757: return;
758: } else if ((opc & CHK_MASK) == CHK_INST) {
759: if (BITFIELD(opc,8,7) == 0x3) {
760: addstr(dbuf, "chkw\t");
761: get_modregstr(dbuf, 5, GETMOD_BEFORE, SIZE_WORD, 0);
762: } else {
763: addstr(dbuf, "chkl\t");
764: get_modregstr(dbuf, 5, GETMOD_BEFORE, SIZE_LONG, 0);
765: }
766: addchar(',');
767: get_modregstr(dbuf, 11, DR_DIR, 0, 0);
768: return;
769: }
770: }
771:
772: /*
773: * ADDQ/SUBQ/Scc/DBcc/TRAPcc
774: */
775: void
776: opcode_0101(dbuf, opc)
777: dis_buffer_t *dbuf;
778: u_short opc;
779: {
780: int data;
781:
782: if (IS_INST(TRAPcc, opc) && BITFIELD(opc,2,0) > 1) {
783: int opmode;
784:
785: opmode = BITFIELD(opc,2,0);
786: make_cond(dbuf,11,"trap");
787:
788: if (opmode == 0x2) {
789: addchar('w');
790: addchar('\t');
791: get_immed(dbuf, SIZE_WORD);
792: } else if (opmode == 0x3) {
793: addchar('l');
794: addchar('\t');
795: get_immed(dbuf, SIZE_LONG);
796: }
797: return;
798: } else if (IS_INST(DBcc, opc)) {
799: make_cond(dbuf,11,"db");
800: addchar('\t');
801: PRINT_DREG(dbuf, BITFIELD(opc,2,0));
802: addchar(',');
803: print_disp(dbuf, *(dbuf->val + 1), SIZE_WORD, -1);
804: dbuf->used++;
805: return;
806: } else if (IS_INST(Scc,opc)) {
807: make_cond(dbuf,11,"s");
808: addchar('\t');
809: get_modregstr(dbuf, 5, GETMOD_BEFORE, SIZE_BYTE, 0);
810: return;
811: } else if (IS_INST(ADDQ, opc) || IS_INST(SUBQ, opc)) {
812: int size = BITFIELD(opc,7,6);
813:
814: if (IS_INST(SUBQ, opc))
815: addstr(dbuf, "subq");
816: else
817: addstr(dbuf, "addq");
818:
819: if (size == 0x1)
820: addchar('w');
821: else if (size == 0x2)
822: addchar('l');
823: else
824: addchar('b');
825:
826: addchar('\t');
827: addchar('#');
828: data = BITFIELD(opc,11,9);
829: if (data == 0)
830: data = 8;
831: printu(dbuf, data, SIZE_BYTE);
832: addchar(',');
833: get_modregstr(dbuf, 5, GETMOD_BEFORE, 0, 0);
834:
835: return;
836: }
837: }
838:
839: /*
840: * Bcc/BSR/BRA
841: */
842: void
843: opcode_branch(dbuf, opc)
844: dis_buffer_t *dbuf;
845: u_short opc;
846: {
847: int disp, sz;
848:
849: if (IS_INST(BRA,opc))
850: addstr(dbuf, "bra");
851: else if (IS_INST(BSR,opc))
852: addstr(dbuf, "bsr");
853: else
854: make_cond(dbuf,11,"b");
855:
856: disp = BITFIELD(opc,7,0);
857: if (disp == 0) {
858: /* 16-bit signed displacement */
859: disp = *(dbuf->val + 1);
860: dbuf->used++;
861: sz = SIZE_WORD;
862: addchar('w');
863: } else if (disp == 0xff) {
864: /* 32-bit signed displacement */
865: disp = *(long *)(dbuf->val + 1);
866: dbuf->used += 2;
867: sz = SIZE_LONG;
868: addchar('l');
869: } else {
870: /* 8-bit signed displacement in opcode. */
871: /* Needs to be sign-extended... */
872: if (ISBITSET(disp,7))
873: disp -= 256;
874: sz = SIZE_BYTE;
875: addchar('b');
876: }
877: addchar('\t');
878: print_addr(dbuf, disp + (u_long)dbuf->val + 2);
879: }
880:
881: /*
882: * ADD/ADDA/ADDX/SUB/SUBA/SUBX
883: */
884: void
885: opcode_addsub(dbuf, opc)
886: dis_buffer_t *dbuf;
887: u_short opc;
888: {
889: int sz, ch, amode;
890:
891: sz = BITFIELD(opc,7,6);
892: amode = 0;
893:
894: if (sz == 0) {
895: ch = 'b';
896: sz = SIZE_BYTE;
897: } else if (sz == 1) {
898: ch = 'w';
899: sz = SIZE_WORD;
900: } else if (sz == 2) {
901: ch = 'l';
902: sz = SIZE_LONG;
903: } else {
904: amode = 1;
905: if (!ISBITSET(opc,8)) {
906: sz = SIZE_WORD;
907: ch = 'w';
908: } else {
909: sz = SIZE_LONG;
910: ch = 'l';
911: }
912: }
913:
914: if (!amode && (IS_INST(ADDX,opc) || IS_INST(SUBX,opc))) {
915: if (IS_INST(ADDX,opc))
916: addstr(dbuf,"addx");
917: else
918: addstr(dbuf,"subx");
919:
920: addchar(ch);
921: addchar('\t');
922:
923: if (ISBITSET(opc,3)) {
924: PRINT_AREG(dbuf,BITFIELD(opc,2,0));
925: addchar('@');
926: addchar('-');
927: addchar(',');
928: PRINT_AREG(dbuf,BITFIELD(opc,11,9));
929: addchar('@');
930: addchar('-');
931: } else {
932: PRINT_DREG(dbuf,BITFIELD(opc,2,0));
933: addchar(',');
934: PRINT_DREG(dbuf,BITFIELD(opc,11,9));
935: }
936: } else {
937: if (IS_INST(ADD,opc))
938: addstr(dbuf, "add");
939: else
940: addstr(dbuf, "sub");
941:
942: if (amode)
943: addchar('a');
944: addchar(ch);
945: addchar('\t');
946:
947: if (ISBITSET(opc,8) && amode == 0) {
948: PRINT_DREG(dbuf,BITFIELD(opc,11,9));
949: addchar(',');
950: get_modregstr(dbuf, 5, GETMOD_BEFORE, sz, 0);
951: } else {
952: get_modregstr(dbuf, 5, GETMOD_BEFORE, sz, 0);
953: addchar(',');
954: if (amode)
955: PRINT_AREG(dbuf,BITFIELD(opc,11,9));
956: else
957: PRINT_DREG(dbuf,BITFIELD(opc,11,9));
958: }
959: }
960: return;
961: }
962:
963: /*
964: * Shift/Rotate/Bit Field
965: */
966: void
967: opcode_1110(dbuf, opc)
968: dis_buffer_t *dbuf;
969: u_short opc;
970: {
971: char *tmp;
972: u_short ext;
973: int type, sz;
974:
975: tmp = NULL;
976:
977: switch (opc & BFCHG_MASK) {
978: case BFCHG_INST:
979: tmp = "bfchg";
980: break;
981: case BFCLR_INST:
982: tmp = "bfclr";
983: break;
984: case BFEXTS_INST:
985: tmp = "bfexts";
986: break;
987: case BFEXTU_INST:
988: tmp = "bfextu";
989: break;
990: case BFFFO_INST:
991: tmp = "bfffo";
992: break;
993: case BFINS_INST:
994: tmp = "bfins";
995: break;
996: case BFSET_INST:
997: tmp = "bfset";
998: break;
999: case BFTST_INST:
1000: tmp = "bftst";
1001: break;
1002: }
1003: if (tmp) {
1004: short bf;
1005:
1006: addstr(dbuf, tmp);
1007: addchar('\t');
1008:
1009: ext = *(dbuf->val + 1);
1010: dbuf->used++;
1011:
1012: if (IS_INST(BFINS,opc)) {
1013: PRINT_DREG(dbuf, BITFIELD(ext,14,12));
1014: addchar(',');
1015: }
1016: get_modregstr(dbuf, 5, GETMOD_BEFORE, 0, 1);
1017: addchar('{');
1018:
1019: bf = BITFIELD(ext,10,6);
1020: if (ISBITSET(ext, 11))
1021: PRINT_DREG(dbuf, bf);
1022: else
1023: printu_wb(dbuf, bf, SIZE_BYTE, 10);
1024:
1025: addchar(':');
1026:
1027: bf = BITFIELD(ext, 4, 0);
1028: if (ISBITSET(ext, 5))
1029: PRINT_DREG(dbuf, bf);
1030: else {
1031: if (bf == 0)
1032: bf = 32;
1033: printu_wb(dbuf, bf, SIZE_BYTE, 10);
1034: }
1035: addchar('}');
1036: if (ISBITSET(opc,8) && !IS_INST(BFINS,opc)) {
1037: addchar(',');
1038: PRINT_DREG(dbuf, BITFIELD(ext,14,12));
1039: } else
1040: *dbuf->casm = 0;
1041: return;
1042: }
1043: sz = BITFIELD(opc,7,6);
1044: if (sz == 0x3)
1045: type = BITFIELD(opc, 10, 9);
1046: else
1047: type = BITFIELD(opc, 4, 3);
1048:
1049: switch (type) {
1050: case AS_TYPE:
1051: addchar('a');
1052: addchar('s');
1053: break;
1054: case LS_TYPE:
1055: addchar('l');
1056: addchar('s');
1057: break;
1058: case RO_TYPE:
1059: addchar('r');
1060: addchar('o');
1061: break;
1062: case ROX_TYPE:
1063: addchar('r');
1064: addchar('o');
1065: addchar('x');
1066: break;
1067: }
1068:
1069: if (ISBITSET(opc,8))
1070: addchar('l');
1071: else
1072: addchar('r');
1073:
1074: switch (sz) {
1075: case 0:
1076: sz = SIZE_BYTE;
1077: addchar('b');
1078: break;
1079: case 3:
1080: case 1:
1081: sz = SIZE_WORD;
1082: addchar('w');
1083: break;
1084: case 2:
1085: sz = SIZE_LONG;
1086: addchar('l');
1087: break;
1088:
1089: }
1090: addchar('\t');
1091: if(BITFIELD(opc,7,6) == 0x3) {
1092: get_modregstr(dbuf, 5, GETMOD_BEFORE, sz, 0);
1093: return;
1094: } else if (ISBITSET(opc,5))
1095: PRINT_DREG(dbuf, BITFIELD(opc,11,9));
1096: else {
1097: addchar('#');
1098: sz = BITFIELD(opc,11,9);
1099: if (sz == 0)
1100: sz = 8;
1101: printu_wb(dbuf, sz, SIZE_BYTE, 10);
1102: }
1103: addchar(',');
1104: PRINT_DREG(dbuf, BITFIELD(opc,2,0));
1105: return;
1106: }
1107:
1108: /*
1109: * CMP/CMPA/EOR
1110: */
1111: void
1112: opcode_1011(dbuf, opc)
1113: dis_buffer_t *dbuf;
1114: u_short opc;
1115: {
1116: int sz;
1117:
1118: if (IS_INST(CMPA,opc)) {
1119: addstr(dbuf, "cmpa");
1120:
1121: if (ISBITSET(opc, 8)) {
1122: addchar('l');
1123: sz = SIZE_LONG;
1124: } else {
1125: addchar('w');
1126: sz = SIZE_WORD;
1127: }
1128: addchar('\t');
1129: } else {
1130: if (IS_INST(CMP, opc))
1131: addstr(dbuf, "cmp");
1132: else
1133: addstr(dbuf, "eor");
1134:
1135: sz = BITFIELD(opc,7,6);
1136: switch (sz) {
1137: case 0:
1138: addchar('b');
1139: sz = SIZE_BYTE;
1140: break;
1141: case 1:
1142: addchar('w');
1143: sz = SIZE_WORD;
1144: break;
1145: case 2:
1146: addchar('l');
1147: sz = SIZE_LONG;
1148: break;
1149: }
1150: addchar('\t');
1151: if (IS_INST(EOR,opc)) {
1152: PRINT_DREG(dbuf, BITFIELD(opc,11,9));
1153: addchar(',');
1154: }
1155: }
1156: get_modregstr(dbuf, 5, GETMOD_BEFORE, sz, 0);
1157:
1158: if (IS_INST(CMPA,opc)) {
1159: addchar(',');
1160: PRINT_AREG(dbuf, BITFIELD(opc,11,9));
1161: } else if (IS_INST(CMP,opc)) {
1162: addchar(',');
1163: PRINT_DREG(dbuf, BITFIELD(opc,11,9));
1164: }
1165: return;
1166: }
1167:
1168: /*
1169: * OR/DIV/SBCD
1170: */
1171: void
1172: opcode_1000(dbuf, opc)
1173: dis_buffer_t *dbuf;
1174: u_short opc;
1175: {
1176: int sz;
1177:
1178: if (IS_INST(UNPKA,opc)) {
1179: addstr(dbuf, "unpk\t");
1180: PRINT_AREG(dbuf,BITFIELD(opc,2,0));
1181: addstr(dbuf, "@-,");
1182: PRINT_AREG(dbuf,BITFIELD(opc,11,9));
1183: addstr(dbuf, "@-,");
1184: get_immed(dbuf,SIZE_WORD);
1185: } else if (IS_INST(UNPKD,opc)) {
1186: addstr(dbuf, "unpk\t");
1187: PRINT_DREG(dbuf,BITFIELD(opc,2,0));
1188: addchar(',');
1189: PRINT_DREG(dbuf,BITFIELD(opc,11,9));
1190: addchar(',');
1191: get_immed(dbuf,SIZE_WORD);
1192: } else if (IS_INST(SBCDA,opc)) {
1193: addstr(dbuf, "sbcd\t");
1194: PRINT_AREG(dbuf,BITFIELD(opc,2,0));
1195: addstr(dbuf, "@-,");
1196: PRINT_AREG(dbuf,BITFIELD(opc,11,9));
1197: addstr(dbuf, "@-");
1198: } else if (IS_INST(SBCDA,opc)) {
1199: addstr(dbuf, "sbcd\t");
1200: PRINT_DREG(dbuf,BITFIELD(opc,2,0));
1201: addchar(',');
1202: PRINT_DREG(dbuf,BITFIELD(opc,11,9));
1203: } else if (IS_INST(DIVSW,opc) || IS_INST(DIVUW,opc)) {
1204: if (IS_INST(DIVSW,opc))
1205: addstr(dbuf, "divsw\t");
1206: else
1207: addstr(dbuf, "divuw\t");
1208: get_modregstr(dbuf, 5, GETMOD_BEFORE, SIZE_WORD, 0);
1209: addchar(',');
1210: PRINT_DREG(dbuf, BITFIELD(opc,11,9));
1211: } else {
1212: addstr(dbuf, "or");
1213:
1214: sz = BITFIELD(opc,7,6);
1215: switch (sz) {
1216: case 0:
1217: addchar('b');
1218: sz = SIZE_BYTE;
1219: break;
1220: case 1:
1221: addchar('w');
1222: sz = SIZE_WORD;
1223: break;
1224: case 2:
1225: addchar('l');
1226: sz = SIZE_LONG;
1227: break;
1228: }
1229: addchar('\t');
1230: if (ISBITSET(opc,8)) {
1231: PRINT_DREG(dbuf, BITFIELD(opc,11,9));
1232: addchar(',');
1233: }
1234: get_modregstr(dbuf, 5, GETMOD_BEFORE, sz, 0);
1235: if (!ISBITSET(opc,8)) {
1236: addchar(',');
1237: PRINT_DREG(dbuf, BITFIELD(opc,11,9));
1238: }
1239: }
1240: }
1241:
1242: /*
1243: * AND/MUL/ABCD/EXG (1100)
1244: */
1245: void
1246: opcode_1100(dbuf, opc)
1247: dis_buffer_t *dbuf;
1248: u_short opc;
1249: {
1250: int sz;
1251:
1252: if (IS_INST(ABCDA,opc)) {
1253: addstr(dbuf, "abcd\t");
1254: PRINT_AREG(dbuf,BITFIELD(opc,2,0));
1255: addstr(dbuf, "@-,");
1256: PRINT_AREG(dbuf,BITFIELD(opc,11,9));
1257: addstr(dbuf, "@-");
1258: } else if (IS_INST(ABCDA,opc)) {
1259: addstr(dbuf, "abcd\t");
1260: PRINT_DREG(dbuf,BITFIELD(opc,2,0));
1261: addchar(',');
1262: PRINT_DREG(dbuf,BITFIELD(opc,11,9));
1263: } else if (IS_INST(MULSW,opc) || IS_INST(MULUW,opc)) {
1264: if (IS_INST(MULSW,opc))
1265: addstr(dbuf, "mulsw\t");
1266: else
1267: addstr(dbuf, "muluw\t");
1268: get_modregstr(dbuf, 5, GETMOD_BEFORE, SIZE_WORD, 0);
1269: addchar(',');
1270: PRINT_DREG(dbuf, BITFIELD(opc,11,9));
1271: } else if (IS_INST(EXG,opc)) {
1272: addstr(dbuf, "exg\t");
1273: if (ISBITSET(opc,7)) {
1274: PRINT_DREG(dbuf,BITFIELD(opc,11,9));
1275: addchar(',');
1276: PRINT_AREG(dbuf,BITFIELD(opc,2,0));
1277: } else if (ISBITSET(opc,3)) {
1278: PRINT_AREG(dbuf,BITFIELD(opc,11,9));
1279: addchar(',');
1280: PRINT_AREG(dbuf,BITFIELD(opc,2,0));
1281: } else {
1282: PRINT_DREG(dbuf,BITFIELD(opc,11,9));
1283: addchar(',');
1284: PRINT_DREG(dbuf,BITFIELD(opc,2,0));
1285: }
1286: } else {
1287: addstr(dbuf, "and");
1288:
1289: sz = BITFIELD(opc,7,6);
1290: switch (sz) {
1291: case 0:
1292: addchar('b');
1293: sz = SIZE_BYTE;
1294: break;
1295: case 1:
1296: addchar('w');
1297: sz = SIZE_WORD;
1298: break;
1299: case 2:
1300: addchar('l');
1301: sz = SIZE_LONG;
1302: break;
1303: }
1304: addchar('\t');
1305:
1306: if (ISBITSET(opc,8)) {
1307: PRINT_DREG(dbuf, BITFIELD(opc,11,9));
1308: addchar(',');
1309: }
1310: get_modregstr(dbuf, 5, GETMOD_BEFORE, sz, 0);
1311: if (!ISBITSET(opc,8)) {
1312: addchar(',');
1313: PRINT_DREG(dbuf, BITFIELD(opc,11,9));
1314: }
1315: }
1316: }
1317:
1318: /*
1319: * Coprocessor instruction
1320: */
1321: void
1322: opcode_coproc(dbuf, opc)
1323: dis_buffer_t *dbuf;
1324: u_short opc;
1325: {
1326: switch (BITFIELD(*dbuf->val,11,9)) {
1327: case 1:
1328: opcode_fpu(dbuf, opc);
1329: return;
1330: case 0:
1331: opcode_mmu(dbuf, opc);
1332: return;
1333: case 2:
1334: opcode_mmu040(dbuf, opc);
1335: return;
1336: case 3:
1337: opcode_move16(dbuf, opc);
1338: return;
1339: }
1340: switch (BITFIELD(opc,8,6)) {
1341: case 0:
1342: dbuf->used++;
1343: break;
1344: case 3:
1345: dbuf->used++;
1346: /*FALLTHROUGH*/
1347: case 2:
1348: dbuf->used++;
1349: break;
1350: case 1:
1351: dbuf->used++;
1352: case 4:
1353: case 5:
1354: default:
1355: }
1356: addstr(dbuf, "UNKNOWN COPROC OPCODE");
1357: return;
1358: }
1359:
1360: /*
1361: * Resvd
1362: */
1363: void
1364: opcode_1010(dbuf, opc)
1365: dis_buffer_t *dbuf;
1366: u_short opc;
1367: {
1368: addstr(dbuf, "RSVD");
1369: dbuf->used++;
1370: }
1371:
1372: void
1373: opcode_fpu(dbuf, opc)
1374: dis_buffer_t *dbuf;
1375: u_short opc;
1376: {
1377: u_short ext;
1378: int type, opmode;
1379:
1380: type = BITFIELD(opc,8,6);
1381: switch (type) {
1382: /* cpGEN */
1383: case 0:
1384: ext = *(dbuf->val + 1);
1385: dbuf->used++;
1386: opmode = BITFIELD(ext,5,0);
1387:
1388: if (BITFIELD(opc,5,0) == 0 && BITFIELD(ext,15,10) == 0x17) {
1389: addstr(dbuf,"fmovcrx #");
1390: printu(dbuf,BITFIELD(ext,6,0),SIZE_BYTE);
1391: return;
1392: }
1393: if (ISBITSET(ext,15) || ISBITSET(ext,13)) {
1394: opcode_fmove_ext(dbuf, opc, ext);
1395: return;
1396: }
1397:
1398: switch(opmode) {
1399: case FMOVE:
1400: get_fpustdGEN(dbuf,ext,"fmov");
1401: return;
1402: case FABS:
1403: get_fpustdGEN(dbuf,ext,"fabs");
1404: return;
1405: case FACOS:
1406: get_fpustdGEN(dbuf,ext,"facos");
1407: return;
1408: case FADD:
1409: get_fpustdGEN(dbuf,ext,"fadd");
1410: return;
1411: case FASIN:
1412: get_fpustdGEN(dbuf,ext,"fasin");
1413: return;
1414: case FATAN:
1415: get_fpustdGEN(dbuf,ext,"fatan");
1416: return;
1417: case FATANH:
1418: get_fpustdGEN(dbuf,ext,"fatanh");
1419: return;
1420: case FCMP:
1421: get_fpustdGEN(dbuf,ext,"fcmp");
1422: return;
1423: case FCOS:
1424: get_fpustdGEN(dbuf,ext,"fcos");
1425: return;
1426: case FCOSH:
1427: get_fpustdGEN(dbuf,ext,"fcosh");
1428: return;
1429: case FDIV:
1430: get_fpustdGEN(dbuf,ext,"fdiv");
1431: return;
1432: case FETOX:
1433: get_fpustdGEN(dbuf,ext,"fetox");
1434: return;
1435: case FGETEXP:
1436: get_fpustdGEN(dbuf,ext,"fgetexp");
1437: return;
1438: case FGETMAN:
1439: get_fpustdGEN(dbuf,ext,"fgetman");
1440: return;
1441: case FINT:
1442: get_fpustdGEN(dbuf,ext,"fint");
1443: return;
1444: case FINTRZ:
1445: get_fpustdGEN(dbuf,ext,"fintrz");
1446: return;
1447: case FLOG10:
1448: get_fpustdGEN(dbuf,ext,"flog10");
1449: return;
1450: case FLOG2:
1451: get_fpustdGEN(dbuf,ext,"flog2");
1452: return;
1453: case FLOGN:
1454: get_fpustdGEN(dbuf,ext,"flogn");
1455: return;
1456: case FLOGNP1:
1457: get_fpustdGEN(dbuf,ext,"flognp1");
1458: return;
1459: case FMOD:
1460: get_fpustdGEN(dbuf,ext,"fmod");
1461: return;
1462: case FMUL:
1463: get_fpustdGEN(dbuf,ext,"fmul");
1464: return;
1465: case FNEG:
1466: get_fpustdGEN(dbuf,ext,"fneg");
1467: return;
1468: case FREM:
1469: get_fpustdGEN(dbuf,ext,"frem");
1470: return;
1471: case FSCALE:
1472: get_fpustdGEN(dbuf,ext,"fscale");
1473: return;
1474: case FSGLDIV:
1475: get_fpustdGEN(dbuf,ext,"fsgldiv");
1476: return;
1477: case FSGLMUL:
1478: get_fpustdGEN(dbuf,ext,"fsglmul");
1479: return;
1480: case FSIN:
1481: get_fpustdGEN(dbuf,ext,"fsin");
1482: return;
1483: case FSINH:
1484: get_fpustdGEN(dbuf,ext,"fsinh");
1485: return;
1486: case FSQRT:
1487: get_fpustdGEN(dbuf,ext,"fsqrt");
1488: return;
1489: case FSUB:
1490: get_fpustdGEN(dbuf,ext,"fsub");
1491: return;
1492: case FTAN:
1493: get_fpustdGEN(dbuf,ext,"ftan");
1494: return;
1495: case FTANH:
1496: get_fpustdGEN(dbuf,ext,"ftanh");
1497: return;
1498: case FTENTOX:
1499: get_fpustdGEN(dbuf,ext,"ftentox");
1500: return;
1501: case FTST:
1502: get_fpustdGEN(dbuf,ext,"ftst");
1503: return;
1504: case FTWOTOX:
1505: get_fpustdGEN(dbuf,ext,"ftwotox");
1506: return;
1507:
1508: }
1509: /* cpBcc */
1510: case 2:
1511: if (BITFIELD(opc,5,0) == 0 && *(dbuf->val + 1) == 0) {
1512: dbuf->used++;
1513: addstr (dbuf, "fnop");
1514: return;
1515: }
1516: case 3:
1517: addstr(dbuf, "fb");
1518: print_fcond(dbuf, BITFIELD(opc,5,0));
1519: if (type == 2) {
1520: addchar('w');
1521: addchar('\t');
1522: print_disp(dbuf,*(dbuf->val + 1), SIZE_WORD, -1);
1523: dbuf->used++;
1524: } else {
1525: addchar('l');
1526: addchar('\t');
1527: print_disp(dbuf,*(long *)(dbuf->val + 1), SIZE_LONG,
1528: -1);
1529: dbuf->used += 2;
1530: }
1531: return;
1532: /* cpDBcc/cpScc/cpTrap */
1533: case 1:
1534: ext = *(dbuf->val + 1);
1535: dbuf->used++;
1536:
1537: if (BITFIELD(opc,5,3) == 0x1) {
1538: /* fdbcc */
1539: addstr(dbuf,"fdb");
1540: print_fcond(dbuf,BITFIELD(ext,5,0));
1541: addchar('\t');
1542: PRINT_DREG(dbuf, BITFIELD(opc,2,0));
1543: addchar(',');
1544: print_disp(dbuf, *(dbuf->val + 2), SIZE_WORD, -1);
1545: dbuf->used++;
1546: } else if (BITFIELD(opc,5,3) == 0x7 &&
1547: BITFIELD(opc,2,0) > 1) {
1548: addstr(dbuf,"ftrap");
1549: print_fcond(dbuf,BITFIELD(ext,5,0));
1550:
1551: if (BITFIELD(opc,2,0) == 0x2) {
1552: addchar('w');
1553: addchar('\t');
1554: dbuf->val++;
1555: get_immed(dbuf, SIZE_WORD);
1556: dbuf->val--;
1557: } else if (BITFIELD(opc,2,0) == 0x3) {
1558: addchar('l');
1559: addchar('\t');
1560: dbuf->val++;
1561: get_immed(dbuf, SIZE_LONG);
1562: dbuf->val--;
1563: }
1564: } else {
1565: addstr(dbuf,"fs");
1566: print_fcond(dbuf,BITFIELD(ext,5,0));
1567: addchar('\t');
1568: get_modregstr(dbuf, 5, GETMOD_BEFORE, SIZE_BYTE, 1);
1569: }
1570: return;
1571: case 4:
1572: addstr(dbuf,"fsave\t");
1573: get_modregstr(dbuf, 5, GETMOD_BEFORE, 0, 0);
1574: return;
1575: case 5:
1576: addstr(dbuf,"frestor\t");
1577: get_modregstr(dbuf, 5, GETMOD_BEFORE, 0, 0);
1578: return;
1579: }
1580: }
1581:
1582: /*
1583: * XXX - This screws up on: fmovem a0@(312),fpcr/fpsr/fpi
1584: */
1585: void
1586: opcode_fmove_ext(dbuf, opc, ext)
1587: dis_buffer_t *dbuf;
1588: u_short opc, ext;
1589: {
1590: int sz;
1591:
1592: sz = 0;
1593: if (BITFIELD(ext,15,13) == 3) {
1594: /* fmove r ==> m */
1595: addstr(dbuf, "fmov");
1596: switch (BITFIELD(ext,12,10)) {
1597: case 0:
1598: addchar('l');
1599: sz = SIZE_LONG;
1600: break;
1601: case 1:
1602: addchar('s');
1603: sz = SIZE_SINGLE;
1604: break;
1605: case 2:
1606: addchar('x');
1607: sz = SIZE_EXTENDED;
1608: break;
1609: case 7:
1610: case 3:
1611: addchar('p');
1612: sz = SIZE_PACKED;
1613: break;
1614: case 4:
1615: addchar('w');
1616: sz = SIZE_WORD;
1617: break;
1618: case 5:
1619: addchar('d');
1620: sz = SIZE_DOUBLE;
1621: break;
1622: case 6:
1623: addchar('b');
1624: sz = SIZE_BYTE;
1625: break;
1626: }
1627: addchar('\t');
1628: PRINT_FPREG(dbuf, BITFIELD(ext,9,7));
1629: addchar(',');
1630: get_modregstr(dbuf, 5, GETMOD_BEFORE, sz, 1);
1631: if (sz == SIZE_PACKED) {
1632: addchar('{');
1633: if (ISBITSET(ext,12)) {
1634: PRINT_DREG(dbuf,BITFIELD(ext,6,4));
1635: } else {
1636: addchar('#');
1637: prints_bf(dbuf, ext, 6, 4);
1638: }
1639: addchar('}');
1640: }
1641: return;
1642: }
1643: addstr(dbuf,"fmovm");
1644:
1645: if (!ISBITSET(ext,14)) {
1646: /* fmove[m] control reg */
1647: addchar('l');
1648: addchar('\t');
1649:
1650: if (ISBITSET(ext,13)) {
1651: print_freglist(dbuf, AR_DEC, BITFIELD(ext,12,10), 1);
1652: addchar(',');
1653: }
1654: get_modregstr(dbuf, 5, GETMOD_BEFORE, SIZE_LONG, 1);
1655: if (!ISBITSET(ext,13)) {
1656: addchar(',');
1657: print_freglist(dbuf, AR_DEC, BITFIELD(ext,12,10), 1);
1658: }
1659: return;
1660: }
1661: addchar('x');
1662: addchar('\t');
1663:
1664: if (ISBITSET(ext,11)) {
1665: if (ISBITSET(ext,13)) {
1666: PRINT_DREG(dbuf,BITFIELD(ext,6,4));
1667: addchar(',');
1668: }
1669: get_modregstr(dbuf, 5, GETMOD_BEFORE, SIZE_EXTENDED, 1);
1670: if (!ISBITSET(ext,13)) {
1671: addchar(',');
1672: PRINT_DREG(dbuf,BITFIELD(ext,6,4));
1673: }
1674: } else {
1675: if (ISBITSET(ext,13)) {
1676: print_freglist(dbuf, BITFIELD(opc,5,3),
1677: BITFIELD(ext,7,0), 0);
1678: addchar(',');
1679: }
1680: get_modregstr(dbuf, 5, GETMOD_BEFORE, SIZE_EXTENDED, 1);
1681: if (!ISBITSET(ext,13)) {
1682: addchar(',');
1683: print_freglist(dbuf, BITFIELD(opc,5,3),
1684: BITFIELD(ext,7,0), 0);
1685: }
1686: }
1687: }
1688:
1689: void
1690: opcode_mmu(dbuf, opc)
1691: dis_buffer_t *dbuf;
1692: u_short opc;
1693: {
1694: u_short ext;
1695: int type;
1696:
1697: type = BITFIELD(opc,8,6);
1698: switch (type) {
1699: /* cpGEN? */
1700: case 0:
1701: ext = *(dbuf->val + 1);
1702: dbuf->used++;
1703:
1704: switch(BITFIELD(ext,15,13)) {
1705: case 5:
1706: case 1:
1707: opcode_pflush(dbuf, opc, ext);
1708: return;
1709: case 0:
1710: case 3:
1711: case 2:
1712: opcode_pmove(dbuf, opc, ext);
1713: return;
1714: case 4:
1715: addstr(dbuf, "ptest");
1716: if (ISBITSET(ext,9))
1717: addchar('r');
1718: else
1719: addchar('w');
1720: addchar('\t');
1721: print_fcode(dbuf, BITFIELD(ext, 5, 0));
1722: addchar(',');
1723: get_modregstr(dbuf, 5, GETMOD_BEFORE, 0, 1);
1724: addchar(',');
1725: addchar('#');
1726: printu_bf(dbuf, ext, 12, 10);
1727: if (ISBITSET(ext, 8)) {
1728: addchar(',');
1729: PRINT_AREG(dbuf, BITFIELD(ext, 7, 5));
1730: }
1731: }
1732: return;
1733: case 2:
1734: case 3:
1735: addstr(dbuf, "pb");
1736: print_mcond(dbuf, BITFIELD(opc,5,0));
1737: if (type == 2) {
1738: addchar('w');
1739: addchar('\t');
1740: print_disp(dbuf,*(dbuf->val + 1), SIZE_WORD, -1);
1741: dbuf->used++;
1742: } else {
1743: addchar('l');
1744: addchar('\t');
1745: print_disp(dbuf,*(long *)(dbuf->val + 1), SIZE_LONG,
1746: -1);
1747: dbuf->used += 2;
1748: }
1749: return;
1750: case 1:
1751: ext = *(dbuf->val + 1);
1752: dbuf->used++;
1753:
1754: if (BITFIELD(opc,5,3) == 0x1) {
1755: /* fdbcc */
1756: addstr(dbuf,"pdb");
1757: print_fcond(dbuf,BITFIELD(ext,5,0));
1758: addchar('\t');
1759: PRINT_DREG(dbuf, BITFIELD(opc,2,0));
1760: addchar(',');
1761: print_disp(dbuf, *(dbuf->val + 2), SIZE_WORD, -1);
1762: dbuf->used++;
1763: } else if (BITFIELD(opc,5,3) == 0x7 &&
1764: BITFIELD(opc,2,0) > 1) {
1765: addstr(dbuf,"ptrap");
1766: print_fcond(dbuf,BITFIELD(ext,5,0));
1767:
1768: if (BITFIELD(opc,2,0) == 0x2) {
1769: addchar('w');
1770: addchar('\t');
1771: dbuf->val++;
1772: get_immed(dbuf, SIZE_WORD);
1773: dbuf->val--;
1774: } else if (BITFIELD(opc,2,0) == 0x3) {
1775: addchar('l');
1776: addchar('\t');
1777: dbuf->val++;
1778: get_immed(dbuf, SIZE_LONG);
1779: dbuf->val--;
1780: }
1781: } else {
1782: addstr(dbuf,"ps");
1783: print_fcond(dbuf,BITFIELD(ext,5,0));
1784: addchar('\t');
1785: get_modregstr(dbuf, 5, GETMOD_BEFORE, SIZE_BYTE, 1);
1786: }
1787: return;
1788: case 4:
1789: addstr(dbuf,"psave\t");
1790: get_modregstr(dbuf, 5, GETMOD_BEFORE, 0, 0);
1791: return;
1792: case 5:
1793: addstr(dbuf,"prestore\t");
1794: get_modregstr(dbuf, 5, GETMOD_BEFORE, 0, 0);
1795: return;
1796: }
1797: }
1798:
1799: void
1800: opcode_pflush(dbuf, opc, ext)
1801: dis_buffer_t *dbuf;
1802: u_short opc, ext;
1803: {
1804: u_short mode, mask, fc;
1805:
1806: mode = BITFIELD(ext,12,10);
1807: mask = BITFIELD(ext,8,5);
1808: fc = BITFIELD(ext, 5, 0);
1809:
1810: if (ext == 0xa000) {
1811: addstr(dbuf,"pflushr\t");
1812: get_modregstr(dbuf, 5, GETMOD_BEFORE, SIZE_LONG, 1);
1813: return;
1814: }
1815:
1816: if (mode == 0) {
1817: addstr(dbuf,"pload");
1818: if (ISBITSET(ext,9))
1819: addchar('r');
1820: else
1821: addchar('w');
1822: addchar(' ');
1823: print_fcode(dbuf, fc);
1824: }
1825:
1826: addstr(dbuf,"pflush");
1827: switch (mode) {
1828: case 1:
1829: addchar('a');
1830: *dbuf->casm = 0;
1831: break;
1832: case 7:
1833: case 5:
1834: addchar('s');
1835: /*FALLTHROUGH*/
1836: case 6:
1837: case 4:
1838: addchar('\t');
1839: print_fcode(dbuf, fc);
1840: addchar(',');
1841: addchar('#');
1842: printu(dbuf, mask, SIZE_BYTE);
1843: if (!ISBITSET(mode,1))
1844: break;
1845: addchar(',');
1846: get_modregstr(dbuf, 5, GETMOD_BEFORE, SIZE_LONG, 1);
1847: }
1848: }
1849:
1850: void
1851: opcode_pmove(dbuf, opc, ext)
1852: dis_buffer_t *dbuf;
1853: u_short opc, ext;
1854: {
1855: const char *reg;
1856: int rtom, sz, preg;
1857:
1858: reg = "???";
1859: sz = 0;
1860: rtom = ISBITSET(ext, 9);
1861: preg = BITFIELD(ext, 12, 10);
1862:
1863: addstr(dbuf,"pmov");
1864: if (ISBITSET(ext,8)) {
1865: addchar('f');
1866: addchar('d');
1867: }
1868: switch (BITFIELD(ext, 15, 13)) {
1869: case 0: /* tt regs 030o */
1870: switch (preg) {
1871: case 2:
1872: reg = "tt0";
1873: break;
1874: case 3:
1875: reg = "tt1";
1876: break;
1877: }
1878: sz = SIZE_LONG;
1879: break;
1880: case 2:
1881: switch (preg) {
1882: case 0:
1883: reg = "tc";
1884: sz = SIZE_LONG;
1885: break;
1886: case 1:
1887: reg = "drp";
1888: sz = SIZE_QUAD;
1889: break;
1890: case 2:
1891: reg = "srp";
1892: sz = SIZE_QUAD;
1893: break;
1894: case 3:
1895: reg = "crp";
1896: sz = SIZE_QUAD;
1897: break;
1898: case 4:
1899: reg = "cal";
1900: sz = SIZE_BYTE;
1901: break;
1902: case 5:
1903: reg = "val";
1904: sz = SIZE_BYTE;
1905: break;
1906: case 6:
1907: reg = "scc";
1908: sz = SIZE_BYTE;
1909: break;
1910: case 7:
1911: reg = "ac";
1912: sz = SIZE_WORD;
1913: }
1914: break;
1915: case 3:
1916: switch (preg) {
1917: case 0:
1918: reg = "mmusr";
1919: break;
1920: case 1:
1921: reg = "pcsr";
1922: break;
1923: case 4:
1924: reg = "bad";
1925: break;
1926: case 5:
1927: reg = "bac";
1928: break;
1929: }
1930: sz = SIZE_WORD;
1931: break;
1932: }
1933: switch (sz) {
1934: case SIZE_BYTE:
1935: addchar ('b');
1936: break;
1937: case SIZE_WORD:
1938: addchar ('w');
1939: break;
1940: case SIZE_LONG:
1941: addchar ('l');
1942: break;
1943: case SIZE_QUAD:
1944: addchar ('d');
1945: break;
1946: }
1947: addchar('\t');
1948:
1949: if (!rtom) {
1950: get_modregstr(dbuf, 5, GETMOD_BEFORE, sz, 1);
1951: addchar(',');
1952: }
1953: addstr(dbuf, reg);
1954: if (BITFIELD(ext, 15, 13) == 3 && preg > 1)
1955: printu_bf(dbuf, ext, 4, 2);
1956: if (rtom) {
1957: addchar(',');
1958: get_modregstr(dbuf, 5, GETMOD_BEFORE, sz, 1);
1959: }
1960: return;
1961: }
1962:
1963: void
1964: print_fcode(dbuf, fc)
1965: dis_buffer_t *dbuf;
1966: u_short fc;
1967: {
1968: if (ISBITSET(fc, 4))
1969: printu_bf(dbuf, fc, 3, 0);
1970: else if (ISBITSET(fc, 3))
1971: PRINT_DREG(dbuf, BITFIELD(fc, 2, 0));
1972: else if (fc == 1)
1973: addstr(dbuf, "sfc");
1974: else
1975: addstr(dbuf, "dfc");
1976: }
1977: void
1978: opcode_mmu040(dbuf, opc)
1979: dis_buffer_t *dbuf;
1980: u_short opc;
1981: {
1982: if (ISBITSET(opc, 6)) {
1983: addstr(dbuf, "ptest");
1984: if (ISBITSET(opc, 5))
1985: addchar('r');
1986: else
1987: addchar('w');
1988: addchar('\t');
1989: PRINT_AREG(dbuf, BITFIELD(opc,2,0));
1990: addchar('@');
1991: } else {
1992: addstr(dbuf, "pflush");
1993: switch (BITFIELD(opc, 4, 3)) {
1994: case 3:
1995: addchar('a');
1996: break;
1997: case 2:
1998: addchar('a');
1999: addchar('n');
2000: break;
2001: case 0:
2002: addchar('n');
2003: /*FALLTHROUGH*/
2004: case 1:
2005: addchar('\t');
2006: PRINT_AREG(dbuf, BITFIELD(opc,2,0));
2007: addchar('@');
2008: break;
2009: }
2010: }
2011: *dbuf->casm = 0;
2012: }
2013:
2014:
2015: /*
2016: * disassemble long format (64b) divs/muls divu/mulu opcode.
2017: * Note: opcode's dbuf->used already accounted for.
2018: */
2019: void
2020: opcode_divmul(dbuf, opc)
2021: dis_buffer_t *dbuf;
2022: u_short opc;
2023: {
2024: u_short ext;
2025: int iq, hr;
2026:
2027: ext = *(dbuf->val + 1);
2028: dbuf->used++;
2029:
2030: iq = BITFIELD(ext,14,12);
2031: hr = BITFIELD(ext,2,0);
2032:
2033: if (IS_INST(DIVSL,opc))
2034: addstr(dbuf, "div");
2035: else
2036: addstr(dbuf, "mul");
2037: if (ISBITSET(ext,11))
2038: addchar('s');
2039: else
2040: addchar('u');
2041: addchar('l');
2042: if (IS_INST(DIVSL,opc) && !ISBITSET(ext,10) && iq != hr)
2043: addchar('l');
2044: addchar('\t');
2045:
2046: get_modregstr(dbuf,5,GETMOD_BEFORE,SIZE_LONG,1);
2047: addchar(',');
2048:
2049: if (ISBITSET(ext,10) ||
2050: (iq != hr && IS_INST(DIVSL,opc))) {
2051: /* 64 bit version */
2052: PRINT_DREG(dbuf, hr);
2053: if (dbuf->mit)
2054: addchar(',');
2055: else
2056: addchar(':');
2057: }
2058: PRINT_DREG(dbuf, iq);
2059: }
2060:
2061: void
2062: print_reglist(dbuf, mod, rl)
2063: dis_buffer_t *dbuf;
2064: int mod;
2065: u_short rl;
2066: {
2067: const char *const regs[16] = {
2068: "d0","d1","d2","d3","d4","d5","d6","d7",
2069: "a0","a1","a2","a3","a4","a5","a6","a7" };
2070: int bit, list;
2071:
2072: if (mod == AR_DEC) {
2073: list = rl;
2074: rl = 0;
2075: /* I am sure there is some trick... */
2076: for (bit = 0; bit < 16; bit++)
2077: if (list & (1 << bit))
2078: rl |= (0x8000 >> bit);
2079: }
2080: for (bit = 0, list = 0; bit < 16; bit++) {
2081: if (ISBITSET(rl,bit) && bit != 8) {
2082: if (list == 0) {
2083: list = 1;
2084: addstr(dbuf, regs[bit]);
2085: } else if (list == 1) {
2086: list++;
2087: addchar('-');
2088: }
2089: } else {
2090: if (list) {
2091: if (list > 1)
2092: addstr(dbuf, regs[bit-1]);
2093: addchar('/');
2094: list = 0;
2095: }
2096: if (ISBITSET(rl,bit)) {
2097: addstr(dbuf, regs[bit]);
2098: list = 1;
2099: }
2100: }
2101: }
2102: if (list > 1)
2103: addstr(dbuf, regs[15]);
2104:
2105: if (dbuf->casm[-1] == '/' || dbuf->casm[-1] == '-')
2106: dbuf->casm--;
2107: *dbuf->casm = 0;
2108: }
2109:
2110: void
2111: print_freglist(dbuf, mod, rl, cntl)
2112: dis_buffer_t *dbuf;
2113: int mod, cntl;
2114: u_short rl;
2115: {
2116: const char *const * regs;
2117: int bit, list, upper;
2118:
2119: regs = cntl ? fpcregs : fpregs;
2120: upper = cntl ? 3 : 8;
2121:
2122: if (!cntl && mod != AR_DEC) {
2123: list = rl;
2124: rl = 0;
2125: /* I am sure there is some trick... */
2126: for (bit = 0; bit < upper; bit++)
2127: if (list & (1 << bit))
2128: rl |= (0x80 >> bit);
2129: }
2130: for (bit = 0, list = 0; bit < upper; bit++) {
2131: if (ISBITSET(rl,bit)) {
2132: if (list == 0) {
2133: addstr(dbuf, regs[bit]);
2134: if (cntl)
2135: addchar('/');
2136: else
2137: list = 1;
2138: } else if (list == 1) {
2139: list++;
2140: addchar('-');
2141: }
2142: } else {
2143: if (list) {
2144: if (list > 1)
2145: addstr(dbuf, regs[bit-1]);
2146: addchar('/');
2147: list = 0;
2148: }
2149: }
2150: }
2151: if (list > 1)
2152: addstr(dbuf, regs[upper-1]);
2153:
2154: if (dbuf->casm[-1] == '/' || dbuf->casm[-1] == '-')
2155: dbuf->casm--;
2156: *dbuf->casm = 0;
2157: }
2158:
2159: /*
2160: * disassemble movem opcode.
2161: */
2162: void
2163: opcode_movem(dbuf, opc)
2164: dis_buffer_t *dbuf;
2165: u_short opc;
2166: {
2167: u_short rl;
2168:
2169: rl = *(dbuf->val + 1);
2170: dbuf->used++;
2171:
2172: if (ISBITSET(opc,6))
2173: addstr(dbuf, "movml\t");
2174: else
2175: addstr(dbuf, "movmw\t");
2176: if (ISBITSET(opc,10)) {
2177: get_modregstr(dbuf, 5, GETMOD_BEFORE, 0, 1);
2178: addchar(',');
2179: print_reglist(dbuf, BITFIELD(opc,5,3), rl);
2180: } else {
2181: print_reglist(dbuf, BITFIELD(opc,5,3), rl);
2182: addchar(',');
2183: get_modregstr(dbuf, 5, GETMOD_BEFORE, 0, 1);
2184: }
2185: }
2186:
2187: /*
2188: * disassemble movec opcode.
2189: */
2190: void
2191: opcode_movec(dbuf, opc)
2192: dis_buffer_t *dbuf;
2193: u_short opc;
2194: {
2195: char *tmp;
2196: u_short ext;
2197:
2198: ext = *(dbuf->val + 1);
2199: dbuf->used++;
2200:
2201: addstr(dbuf, "movc\t");
2202: if (ISBITSET(opc,0)) {
2203: dbuf->val++;
2204: if (ISBITSET(ext,15))
2205: get_modregstr(dbuf,14,AR_DIR,0,0);
2206: else
2207: get_modregstr(dbuf,14,DR_DIR,0,0);
2208: dbuf->val--;
2209: addchar(',');
2210: }
2211: switch (BITFIELD(ext,11,0)) {
2212: /* 010/020/030/040/CPU32/060 */
2213: case 0x000:
2214: tmp = "sfc";
2215: break;
2216: case 0x001:
2217: tmp = "dfc";
2218: break;
2219: case 0x800:
2220: tmp = "usp";
2221: break;
2222: case 0x801:
2223: tmp = "vbr";
2224: break;
2225: /* 020/030 */
2226: case 0x802:
2227: tmp = "caar";
2228: break;
2229: /* 020/030/040/060 */
2230: case 0x002:
2231: tmp = "cacr";
2232: break;
2233: /* 020/030/040 */
2234: case 0x803:
2235: tmp = "msp";
2236: break;
2237: case 0x804:
2238: tmp = "isp";
2239: break;
2240: /* 040/060 */
2241: case 0x003:
2242: tmp = "tc";
2243: break;
2244: case 0x004:
2245: tmp = "itt0";
2246: break;
2247: case 0x005:
2248: tmp = "itt1";
2249: break;
2250: case 0x006:
2251: tmp = "dtt0";
2252: break;
2253: case 0x007:
2254: tmp = "dtt1";
2255: break;
2256: /* 040 */
2257: case 0x805:
2258: tmp = "mmusr";
2259: break;
2260: /* 040/060 */
2261: case 0x806:
2262: tmp = "urp";
2263: break;
2264: case 0x807:
2265: tmp = "srp";
2266: break;
2267: /* 060 */
2268: case 0x008:
2269: tmp = "buscr";
2270: break;
2271: case 0x808:
2272: tmp = "pcr";
2273: break;
2274: default:
2275: tmp = "INVALID";
2276: break;
2277: }
2278: addstr(dbuf, tmp);
2279: if (!ISBITSET(opc,0)) {
2280: dbuf->val++;
2281: addchar(',');
2282: if (ISBITSET(ext,15))
2283: get_modregstr(dbuf,14,AR_DIR,0,0);
2284: else
2285: get_modregstr(dbuf,14,DR_DIR,0,0);
2286: dbuf->val--;
2287: }
2288: }
2289:
2290: void
2291: opcode_move16(dbuf, opc)
2292: dis_buffer_t *dbuf;
2293: u_short opc;
2294: {
2295: u_short ext;
2296:
2297: addstr(dbuf, "move16\t");
2298:
2299: if (ISBITSET(opc, 5)) {
2300: PRINT_AREG(dbuf, BITFIELD(opc,2,0));
2301: addstr(dbuf, "@+,");
2302: ext = *(dbuf->val + 1);
2303: PRINT_AREG(dbuf, BITFIELD(ext,14,12));
2304: addstr(dbuf, "@+");
2305: dbuf->used++;
2306: } else {
2307: switch (BITFIELD(opc,4,3)) {
2308: case 0:
2309: PRINT_AREG(dbuf, BITFIELD(opc,2,0));
2310: addstr(dbuf, "@+,");
2311: get_immed(dbuf, SIZE_LONG);
2312: break;
2313: case 1:
2314: get_immed(dbuf, SIZE_LONG);
2315: addchar(',');
2316: PRINT_AREG(dbuf, BITFIELD(opc,2,0));
2317: addstr(dbuf, "@+");
2318: break;
2319: case 2:
2320: PRINT_AREG(dbuf, BITFIELD(opc,2,0));
2321: addstr(dbuf, "@,");
2322: get_immed(dbuf, SIZE_LONG);
2323: break;
2324: case 3:
2325: get_immed(dbuf, SIZE_LONG);
2326: addchar(',');
2327: PRINT_AREG(dbuf, BITFIELD(opc,2,0));
2328: addchar('@');
2329: break;
2330: }
2331: }
2332: }
2333:
2334: /*
2335: * copy const string 's' into ``dbuf''->casm
2336: */
2337: void
2338: addstr(dbuf, s)
2339: dis_buffer_t *dbuf;
2340: const char *s;
2341: {
2342: while ((*dbuf->casm++ = *s++))
2343: ;
2344: dbuf->casm--;
2345: }
2346:
2347: /*
2348: * copy const string 's' into ``dbuf''->cinfo
2349: */
2350: void
2351: iaddstr(dbuf, s)
2352: dis_buffer_t *dbuf;
2353: const char *s;
2354: {
2355: while ((*dbuf->cinfo++ = *s++))
2356: ;
2357: dbuf->cinfo--;
2358: }
2359:
2360: void
2361: get_modregstr_moto(dbuf, bit, mod, sz, dd)
2362: dis_buffer_t *dbuf;
2363: int bit, mod, sz, dd;
2364: {
2365: u_char scale, idx;
2366: const short *nval;
2367: u_short ext;
2368: int disp, odisp, bd, od, reg;
2369:
2370: odisp = 0;
2371:
2372: /* check to see if we have been given the mod */
2373: if (mod != GETMOD_BEFORE && mod != GETMOD_AFTER)
2374: reg = BITFIELD(*dbuf->val, bit, bit-2);
2375: else if (mod == GETMOD_BEFORE) {
2376: mod = BITFIELD(*dbuf->val, bit, bit-2);
2377: reg = BITFIELD(*dbuf->val, bit-3, bit-5);
2378: } else {
2379: reg = BITFIELD(*dbuf->val, bit, bit-2);
2380: mod = BITFIELD(*dbuf->val, bit-3, bit-5);
2381: }
2382: switch (mod) {
2383: case DR_DIR:
2384: case AR_DIR:
2385: if (mod == DR_DIR)
2386: PRINT_DREG(dbuf, reg);
2387: else
2388: PRINT_AREG(dbuf, reg);
2389: break;
2390: case AR_DIS:
2391: print_disp(dbuf, *(dbuf->val + 1 + dd), SIZE_WORD,reg);
2392: dbuf->used++;
2393: /*FALLTHROUGH*/
2394: case AR_IND:
2395: case AR_INC:
2396: case AR_DEC:
2397: if (mod == AR_DEC)
2398: addchar('-');
2399: addchar('(');
2400: PRINT_AREG(dbuf, reg);
2401: addchar(')');
2402: if (mod == AR_INC)
2403: addchar('+');
2404: break;
2405: /* mod 6 & 7 are the biggies. */
2406: case MOD_SPECIAL:
2407: if (reg == 0) {
2408: /* abs short addr */
2409: print_addr(dbuf, *(dbuf->val + 1 + dd));
2410: dbuf->used++;
2411: addchar('.');
2412: addchar('w');
2413: break;
2414: } else if (reg == 1) {
2415: /* abs long addr */
2416: print_addr(dbuf, *(u_long *)(dbuf->val + 1 + dd));
2417: dbuf->used += 2;
2418: addchar('.');
2419: addchar('l');
2420: break;
2421: } else if (reg == 2) {
2422: /* pc ind displ. xxx(PC) */
2423: dbuf->used++;
2424: print_disp(dbuf, *(dbuf->val + 1 + dd), SIZE_WORD,
2425: -1);
2426: addstr(dbuf,"(pc)");
2427: break;
2428: } else if (reg == 4) {
2429: /* uses ``sz'' to figure imediate data. */
2430: if (sz == SIZE_BYTE) {
2431: addchar('#');
2432: prints(dbuf,
2433: *((char *)dbuf->val + 3+ (dd * 2)), sz);
2434: dbuf->used++;
2435: } else if (sz == SIZE_WORD) {
2436: addchar('#');
2437: prints(dbuf, *(dbuf->val + 1 + dd), sz);
2438: dbuf->used++;
2439: } else if (sz == SIZE_LONG) {
2440: addchar('#');
2441: prints(dbuf, *(long *)(dbuf->val + 1 + dd),
2442: sz);
2443: dbuf->used += 2;
2444: } else if (sz == SIZE_QUAD) {
2445: dbuf->used += 4;
2446: addstr(dbuf,"#<quad>");
2447: } else if (sz == SIZE_SINGLE) {
2448: dbuf->used += 2;
2449: addstr(dbuf,"#<single>");
2450: } else if (sz == SIZE_DOUBLE) {
2451: dbuf->used += 4;
2452: addstr(dbuf,"#<double>");
2453: } else if (sz == SIZE_PACKED) {
2454: dbuf->used += 6;
2455: addstr(dbuf,"#<packed>");
2456: } else if (sz == SIZE_EXTENDED) {
2457: dbuf->used += 6;
2458: addstr(dbuf,"#<extended>");
2459: }
2460: break;
2461: }
2462: /* standrd PC stuff. */
2463: /*FALLTHROUGH*/
2464: case AR_IDX:
2465: ext = *(dbuf->val + 1 + dd);
2466: dbuf->used++;
2467: nval = dbuf->val + 2 + dd; /* set to possible displacements */
2468: scale = BITFIELD(ext,10,9);
2469: idx = BITFIELD(ext,14,12);
2470:
2471: if (ISBITSET(ext,8)) {
2472: /* either base disp, or memory indirect */
2473: bd = BITFIELD(ext,5,4);
2474: od = BITFIELD(ext,1,0);
2475: if (bd == 1)
2476: disp = 0;
2477: else if (bd == 2) {
2478: dbuf->used++;
2479: disp = *nval++;
2480: } else {
2481: dbuf->used += 2;
2482: disp = *(long *)nval;
2483: nval += 2;
2484: }
2485:
2486: if (od == 1)
2487: odisp = 0;
2488: else if (od == 2) {
2489: dbuf->used++;
2490: odisp = *nval++;
2491: } else if (od == 3) {
2492: dbuf->used += 2;
2493: odisp = *(long *)nval;
2494: nval += 2;
2495: }
2496: } else {
2497: /*
2498: * We set od and bd to zero, these values are
2499: * not allowed in opcodes that use base and
2500: * outer displacement, e.g. we can tell if we
2501: * are using on of those modes by checking
2502: * `bd' and `od'.
2503: */
2504: od = 0;
2505: bd = 0;
2506: disp = (char)BITFIELD(ext,7,0);
2507: }
2508: /*
2509: * write everything into buf
2510: */
2511: addchar('(');
2512: if (od)
2513: addchar('['); /* begin memory indirect xxx-indexed */
2514: prints(dbuf, disp,
2515: bd == 2 ? SIZE_WORD :
2516: bd == 3 ? SIZE_LONG :
2517: SIZE_BYTE);
2518: addchar(',');
2519: if (bd && ISBITSET(ext,7)) {
2520: addchar('z');
2521: if (mod != MOD_SPECIAL)
2522: PRINT_AREG(dbuf,reg);
2523: else {
2524: addchar('p');
2525: addchar('c');
2526: }
2527: } else if (mod == AR_IDX)
2528: PRINT_AREG(dbuf, reg);
2529: else {
2530: addchar('p');
2531: addchar('c');
2532: }
2533:
2534: if (od && ISBITSET(ext,2))
2535: addchar(']'); /* post-indexed. */
2536: addchar(',');
2537: if (bd && ISBITSET(ext,6))
2538: addchar('0');
2539: else {
2540: if (0x8000 & ext)
2541: PRINT_AREG(dbuf, idx);
2542: else
2543: PRINT_DREG(dbuf, idx);
2544: addchar('.');
2545: addchar(0x800 & ext ? 'l' : 'w');
2546: if (scale) {
2547: addchar('*');
2548: addchar('0' + (1 << scale));
2549: }
2550: }
2551: if (od) {
2552: if (!ISBITSET(ext,2))
2553: addchar(']'); /* pre-indexed */
2554: addchar(',');
2555: prints(dbuf, odisp,
2556: od == 2 ? SIZE_WORD :
2557: od == 3 ? SIZE_LONG :
2558: SIZE_BYTE);
2559: }
2560: addchar(')');
2561: break;
2562: }
2563: *dbuf->casm = 0;
2564: }
2565:
2566: /* mit syntax makes for spaghetti parses */
2567: void
2568: get_modregstr_mit(dbuf, bit, mod, sz, dd)
2569: dis_buffer_t *dbuf;
2570: int bit, mod, sz, dd;
2571: {
2572: u_char scale, idx;
2573: const short *nval;
2574: u_short ext;
2575: int disp, odisp, bd, od, reg;
2576:
2577: disp = odisp = 0;
2578: /* check to see if we have been given the mod */
2579: if (mod != GETMOD_BEFORE && mod != GETMOD_AFTER)
2580: reg = BITFIELD(*dbuf->val, bit, bit-2);
2581: else if (mod == GETMOD_BEFORE) {
2582: mod = BITFIELD(*dbuf->val, bit, bit-2);
2583: reg = BITFIELD(*dbuf->val, bit-3, bit-5);
2584: } else {
2585: reg = BITFIELD(*dbuf->val, bit, bit-2);
2586: mod = BITFIELD(*dbuf->val, bit-3, bit-5);
2587: }
2588: switch (mod) {
2589: case DR_DIR:
2590: case AR_DIR:
2591: if (mod == DR_DIR)
2592: PRINT_DREG(dbuf, reg);
2593: else
2594: PRINT_AREG(dbuf, reg);
2595: break;
2596: case AR_DIS:
2597: dbuf->used++; /* tell caller we used an ext word. */
2598: disp = *(dbuf->val + 1 + dd);
2599: /*FALLTHROUGH*/
2600: case AR_IND:
2601: case AR_INC:
2602: case AR_DEC:
2603: PRINT_AREG(dbuf, reg);
2604: addchar('@' );
2605: if (mod == AR_DEC)
2606: addchar('-');
2607: else if (mod == AR_INC)
2608: addchar('+');
2609: else if (mod == AR_DIS) {
2610: addchar('(');
2611: print_disp(dbuf, disp, SIZE_WORD, reg);
2612: addchar(')');
2613: }
2614: break;
2615: /* mod 6 & 7 are the biggies. */
2616: case MOD_SPECIAL:
2617: if (reg == 0) {
2618: /* abs short addr */
2619: print_addr(dbuf, *(dbuf->val + 1 + dd));
2620: dbuf->used++;
2621: break;
2622: } else if (reg == 1) {
2623: /* abs long addr */
2624: print_addr(dbuf, *(u_long *)(dbuf->val + 1 + dd));
2625: dbuf->used += 2;
2626: break;
2627: } else if (reg == 2) {
2628: /* pc ind displ. pc@(xxx) */
2629: addstr(dbuf,"pc@(");
2630: print_disp(dbuf, *(dbuf->val + 1 + dd), SIZE_WORD, -1);
2631: dbuf->used++;
2632: addchar(')');
2633: break;
2634: } else if (reg == 4) {
2635: /* uses ``sz'' to figure imediate data. */
2636: if (sz == SIZE_BYTE) {
2637: addchar('#');
2638: prints(dbuf,
2639: *((char *)dbuf->val + 3 + (dd * 2)), sz);
2640: dbuf->used++;
2641: } else if (sz == SIZE_WORD) {
2642: addchar('#');
2643: prints(dbuf, *(dbuf->val + 1 + dd), sz);
2644: dbuf->used++;
2645: } else if (sz == SIZE_LONG) {
2646: addchar('#');
2647: prints(dbuf, *(long *)(dbuf->val + 1 + dd),
2648: sz);
2649: dbuf->used += 2;
2650: } else if (sz == SIZE_QUAD) {
2651: dbuf->used += 4;
2652: addstr(dbuf,"#<quad>");
2653: } else if (sz == SIZE_SINGLE) {
2654: dbuf->used += 2;
2655: addstr(dbuf,"#<single>");
2656: } else if (sz == SIZE_DOUBLE) {
2657: dbuf->used += 4;
2658: addstr(dbuf,"#<double>");
2659: } else if (sz == SIZE_PACKED) {
2660: dbuf->used += 6;
2661: addstr(dbuf,"#<packed>");
2662: } else if (sz == SIZE_EXTENDED) {
2663: dbuf->used += 6;
2664: addstr(dbuf,"#<extended>");
2665: }
2666: break;
2667: }
2668: /* standrd PC stuff. */
2669: /*FALLTHROUGH*/
2670: case AR_IDX:
2671: dbuf->used++; /* indicate use of ext word. */
2672: ext = *(dbuf->val + 1 + dd);
2673: nval = dbuf->val + 2 + dd; /* set to possible displacements */
2674: scale = BITFIELD(ext,10,9);
2675: idx = BITFIELD(ext,14,12);
2676:
2677: if (ISBITSET(ext,8)) {
2678: /* either base disp, or memory indirect */
2679: bd = BITFIELD(ext,5,4);
2680: od = BITFIELD(ext,1,0);
2681: if (bd == 1)
2682: disp = 0;
2683: else if (bd == 2) {
2684: dbuf->used++;
2685: disp = *nval++;
2686: } else {
2687: dbuf->used += 2;
2688: disp = *(long *)nval;
2689: nval += 2;
2690: }
2691:
2692: if (od == 1)
2693: odisp = 0;
2694: else if (od == 2) {
2695: dbuf->used++;
2696: odisp = *nval++;
2697: } else if (od == 3) {
2698: dbuf->used += 2;
2699: odisp = *(long *)nval;
2700: nval += 2;
2701: }
2702: } else {
2703: /*
2704: * We set od and bd to zero, these values are
2705: * not allowed in opcodes that use base and
2706: * outer displacement, e.g. we can tell if we
2707: * are using on of those modes by checking
2708: * `bd' and `od'.
2709: */
2710: od = 0;
2711: bd = 0;
2712: disp = (char)BITFIELD(ext,7,0);
2713: }
2714: /*
2715: * write everything into buf
2716: */
2717: /* if base register not suppresed */
2718: if (mod == AR_IDX && (!bd || !ISBITSET(ext,7)))
2719: PRINT_AREG(dbuf, reg);
2720: else if (mod == MOD_SPECIAL && ISBITSET(ext,7)) {
2721: addchar('z');
2722: addchar('p');
2723: addchar('c');
2724: } else if (mod == MOD_SPECIAL) {
2725: addchar('p');
2726: addchar('c');
2727: }
2728: addchar('@');
2729: addchar('(');
2730:
2731: if (bd && bd != 1) {
2732: prints(dbuf, disp,
2733: bd == 2 ? SIZE_WORD :
2734: bd == 3 ? SIZE_LONG :
2735: SIZE_BYTE);
2736: if (od && !ISBITSET(ext,6) && !ISBITSET(ext,2))
2737: /* Pre-indexed and not supressing index */
2738: addchar(',');
2739: else if (od && ISBITSET(ext,2)) {
2740: /* Post-indexed */
2741: addchar(')');
2742: addchar('@');
2743: addchar('(');
2744: } else if (!od)
2745: addchar(',');
2746: } else if (!bd) {
2747: /* don't forget simple 8 bit displacement. */
2748: prints(dbuf, disp,
2749: bd == 2 ? SIZE_WORD :
2750: bd == 3 ? SIZE_LONG :
2751: SIZE_BYTE);
2752: addchar(',');
2753: }
2754:
2755: /* Post-indexed? */
2756: if (od && ISBITSET(ext,2)) {
2757: /* have displacement? */
2758: if (od != 1) {
2759: prints(dbuf, odisp,
2760: od == 2 ? SIZE_WORD :
2761: od == 3 ? SIZE_LONG :
2762: SIZE_BYTE);
2763: addchar(',');
2764: }
2765: }
2766:
2767: if (!bd || !ISBITSET(ext,6)) {
2768: if (ISBITSET(ext,15))
2769: PRINT_AREG(dbuf,idx);
2770: else
2771: PRINT_DREG(dbuf,idx);
2772: addchar(':');
2773: addchar(ISBITSET(ext,11) ? 'l' : 'w');
2774: if (scale) {
2775: addchar(':');
2776: addchar('0' + (1 << scale));
2777: }
2778: }
2779: /* pre-indexed? */
2780: if (od && !ISBITSET(ext,2)) {
2781: if (od != 1) {
2782: addchar(')');
2783: addchar('@');
2784: addchar('(');
2785: prints(dbuf, odisp,
2786: od == 2 ? SIZE_WORD :
2787: od == 3 ? SIZE_LONG :
2788: SIZE_BYTE);
2789: }
2790: }
2791: addchar(')');
2792: break;
2793: }
2794: *dbuf->casm = 0;
2795: }
2796:
2797: /*
2798: * Given a disassembly buffer ``dbuf'' and a starting bit of the
2799: * mod|reg field ``bit'' (or just a reg field if ``mod'' is not
2800: * GETMOD_BEFORE or GETMOD_AFTER), disassemble and write into ``dbuf''
2801: * the mod|reg pair.
2802: */
2803: void get_modregstr(dbuf, bit, mod, sz, dispdisp)
2804: dis_buffer_t *dbuf;
2805: int bit, mod, sz, dispdisp;
2806: {
2807: if (dbuf->mit)
2808: get_modregstr_mit(dbuf,bit,mod,sz,dispdisp);
2809: else
2810: get_modregstr_moto(dbuf,bit,mod,sz,dispdisp);
2811: }
2812:
2813: /*
2814: * given a bit position ``bit'' in the current ``dbuf''->val
2815: * and the ``base'' string of the opcode, append the full
2816: * opcode name including condition found at ``bit''.
2817: */
2818: void
2819: make_cond(dbuf, bit, base)
2820: dis_buffer_t *dbuf;
2821: int bit;
2822: char *base;
2823: {
2824: int cc;
2825: const char *ccs;
2826:
2827: cc = BITFIELD(*dbuf->val,bit,bit-3);
2828: ccs = cc_table[cc&15];
2829:
2830: addstr(dbuf, base);
2831: addstr(dbuf, ccs);
2832: }
2833:
2834: void
2835: print_fcond(dbuf, cp)
2836: dis_buffer_t *dbuf;
2837: char cp;
2838: {
2839: addstr(dbuf,fpcc_table[cp&31]); /* XXX - not 63 ?*/
2840: }
2841:
2842: void
2843: print_mcond(dbuf, cp)
2844: dis_buffer_t *dbuf;
2845: char cp;
2846: {
2847: addstr(dbuf,mmcc_table[cp&15]);
2848: }
2849:
2850: /*
2851: * given dis_buffer_t ``dbuf'' get the immediate value from the
2852: * extension words following current instruction, output a
2853: * hash (``#'') sign and the value. Increment the ``dbuf''->used
2854: * field accordingly.
2855: */
2856: void
2857: get_immed(dbuf,sz)
2858: dis_buffer_t *dbuf;
2859: int sz;
2860: {
2861: addchar('#');
2862: switch (sz) {
2863: case SIZE_BYTE:
2864: prints(dbuf, BITFIELD(*(dbuf->val + 1),7,0), SIZE_BYTE);
2865: dbuf->used++;
2866: break;
2867: case SIZE_WORD:
2868: prints(dbuf, *(dbuf->val + 1), SIZE_WORD);
2869: dbuf->used++;
2870: break;
2871: case SIZE_LONG:
2872: prints(dbuf, *(long *)(dbuf->val + 1), SIZE_LONG);
2873: dbuf->used += 2;
2874: break;
2875: }
2876: return;
2877: }
2878:
2879: void
2880: get_fpustdGEN(dbuf,ext,name)
2881: dis_buffer_t *dbuf;
2882: u_short ext;
2883: const char *name;
2884: {
2885: int sz;
2886:
2887: /*
2888: * If bit seven is set, its a 040 s/d opcode, then if bit 2 is
2889: * set its "d". This is not documented, however thats the way
2890: * it is.
2891: */
2892:
2893: sz = 0;
2894: addchar(*name++);
2895: if (ISBITSET(ext,7)) {
2896: if(ISBITSET(ext,2))
2897: addchar('d');
2898: else
2899: addchar('s');
2900: }
2901: addstr(dbuf,name);
2902:
2903: if (ISBITSET(ext,14)) {
2904: switch (BITFIELD(ext,12,10)) {
2905: case 0:
2906: addchar('l');
2907: sz = SIZE_LONG;
2908: break;
2909: case 1:
2910: addchar('s');
2911: sz = SIZE_SINGLE;
2912: break;
2913: case 2:
2914: addchar('x');
2915: sz = SIZE_EXTENDED;
2916: break;
2917: case 3:
2918: addchar('p');
2919: sz = SIZE_PACKED;
2920: break;
2921: case 4:
2922: addchar('w');
2923: sz = SIZE_WORD;
2924: break;
2925: case 5:
2926: addchar('d');
2927: sz = SIZE_DOUBLE;
2928: break;
2929: case 6:
2930: addchar('b');
2931: sz = SIZE_BYTE;
2932: break;
2933: }
2934: addchar('\t');
2935: get_modregstr(dbuf, 5, GETMOD_BEFORE, sz, 1);
2936: if (BITFIELD(ext,6,3) == 6) {
2937: addchar(',');
2938: PRINT_FPREG(dbuf, BITFIELD(ext,2,0));
2939: addchar(':');
2940: PRINT_FPREG(dbuf, BITFIELD(ext,9,7));
2941: } else if (BITFIELD(ext,5,0) != FTST) {
2942: addchar(',');
2943: PRINT_FPREG(dbuf, BITFIELD(ext,9,7));
2944: }
2945: } else {
2946: addchar('x');
2947: addchar('\t');
2948: PRINT_FPREG(dbuf, BITFIELD(ext,12,10));
2949: if (BITFIELD(ext,6,3) == 6) {
2950: addchar(',');
2951: PRINT_FPREG(dbuf, BITFIELD(ext,2,0));
2952: addchar(':');
2953: PRINT_FPREG(dbuf, BITFIELD(ext,9,7));
2954: } else if (BITFIELD(ext,5,0) != FTST) {
2955: addchar(',');
2956: PRINT_FPREG(dbuf, BITFIELD(ext,9,7));
2957: }
2958: }
2959: }
2960:
2961: u_long
2962: get_areg_val(reg)
2963: int reg;
2964: {
2965: return (0);
2966: }
2967:
2968: /*
2969: * given value ``disp'' print it to ``dbuf''->buf. ``rel'' is a
2970: * register number 0-7 (a0-a7), or -1 (pc). Thus possible extra info
2971: * could be output to the ``dbuf''->info buffer.
2972: */
2973: void
2974: print_disp(dbuf, disp, sz, rel)
2975: dis_buffer_t *dbuf;
2976: int disp, sz, rel;
2977: {
2978: db_expr_t diff;
2979: db_sym_t sym;
2980: char *symname;
2981: u_long nv;
2982:
2983: prints(dbuf, disp, sz);
2984:
2985: if (rel == -1)
2986: /* XXX This may be wrong for a couple inst. */
2987: nv = disp + (u_int)dbuf->val + 2;
2988: else
2989: return; /* nv = get_areg_val(rel); */
2990:
2991: diff = INT_MAX;
2992: symname = NULL;
2993: sym = db_search_symbol(nv, DB_STGY_PROC, &diff);
2994: db_symbol_values(sym, &symname, 0);
2995:
2996: if (symname) {
2997: iaddstr(dbuf, "disp:");
2998: iaddstr(dbuf, symname);
2999: iaddchar('+');
3000: iprintu(dbuf, diff, SIZE_LONG);
3001: iaddchar(' ');
3002: *dbuf->cinfo = 0;
3003: }
3004: }
3005:
3006: void
3007: print_addr(dbuf, addr)
3008: dis_buffer_t *dbuf;
3009: u_long addr;
3010: {
3011: db_expr_t diff;
3012: db_sym_t sym;
3013: char *symname;
3014:
3015: diff = INT_MAX;
3016: symname = NULL;
3017: sym = db_search_symbol(addr, DB_STGY_ANY, &diff);
3018: db_symbol_values(sym, &symname, 0);
3019:
3020: if (symname) {
3021: if (diff == 0)
3022: addstr(dbuf,symname);
3023: else {
3024: addchar('<');
3025: addstr(dbuf,symname);
3026: addchar('+');
3027: printu(dbuf, diff, SIZE_LONG);
3028: addchar('>');
3029: *dbuf->casm = 0;
3030: }
3031: iaddstr(dbuf,"addr:");
3032: iprintu(dbuf, addr, SIZE_LONG);
3033: iaddchar(' ');
3034: *dbuf->cinfo = 0;
3035: } else {
3036: printu(dbuf, addr, SIZE_LONG);
3037: }
3038: }
3039:
3040: void
3041: prints(dbuf, val, sz)
3042: dis_buffer_t *dbuf;
3043: int val;
3044: int sz;
3045: {
3046: extern int db_radix;
3047:
3048: if (val == 0) {
3049: dbuf->casm[0] = '0';
3050: dbuf->casm[1] = 0;
3051: } else if (sz == SIZE_BYTE)
3052: prints_wb(dbuf, (char)val, sz, db_radix);
3053: else if (sz == SIZE_WORD)
3054: prints_wb(dbuf, (short)val, sz, db_radix);
3055: else
3056: prints_wb(dbuf, (long)val, sz, db_radix);
3057:
3058: dbuf->casm = &dbuf->casm[strlen(dbuf->casm)];
3059: }
3060:
3061: void
3062: iprints(dbuf, val, sz)
3063: dis_buffer_t *dbuf;
3064: int val;
3065: int sz;
3066: {
3067: extern int db_radix;
3068:
3069: if (val == 0) {
3070: dbuf->cinfo[0] = '0';
3071: dbuf->cinfo[1] = 0;
3072: } else if (sz == SIZE_BYTE)
3073: iprints_wb(dbuf, (char)val, sz, db_radix);
3074: else if (sz == SIZE_WORD)
3075: iprints_wb(dbuf, (short)val, sz, db_radix);
3076: else
3077: iprints_wb(dbuf, (long)val, sz, db_radix);
3078:
3079: dbuf->cinfo = &dbuf->cinfo[strlen(dbuf->cinfo)];
3080: }
3081:
3082: void
3083: printu(dbuf, val, sz)
3084: dis_buffer_t *dbuf;
3085: u_int val;
3086: int sz;
3087: {
3088: extern int db_radix;
3089:
3090: if (val == 0) {
3091: dbuf->casm[0] = '0';
3092: dbuf->casm[1] = 0;
3093: } else if (sz == SIZE_BYTE)
3094: printu_wb(dbuf, (u_char)val, sz, db_radix);
3095: else if (sz == SIZE_WORD)
3096: printu_wb(dbuf, (u_short)val, sz, db_radix);
3097: else
3098: printu_wb(dbuf, (u_long)val, sz, db_radix);
3099: dbuf->casm = &dbuf->casm[strlen(dbuf->casm)];
3100: }
3101:
3102: void
3103: iprintu(dbuf, val, sz)
3104: dis_buffer_t *dbuf;
3105: u_int val;
3106: int sz;
3107: {
3108: extern int db_radix;
3109:
3110: if (val == 0) {
3111: dbuf->cinfo[0] = '0';
3112: dbuf->cinfo[1] = 0;
3113: } else if (sz == SIZE_BYTE)
3114: iprintu_wb(dbuf, (u_char)val, sz, db_radix);
3115: else if (sz == SIZE_WORD)
3116: iprintu_wb(dbuf, (u_short)val, sz, db_radix);
3117: else
3118: iprintu_wb(dbuf, (u_long)val, sz, db_radix);
3119: dbuf->cinfo = &dbuf->cinfo[strlen(dbuf->cinfo)];
3120: }
3121:
3122: void
3123: printu_wb(dbuf, val, sz, base)
3124: dis_buffer_t *dbuf;
3125: u_int val;
3126: int sz, base;
3127: {
3128: static char buf[sizeof(long) * NBBY / 3 + 2];
3129: char *p, ch;
3130:
3131: if (base != 10) {
3132: addchar('0');
3133: if (base != 8) {
3134: base = 16;
3135: addchar('x');
3136: }
3137: }
3138:
3139: p = buf;
3140: do {
3141: *++p = "0123456789abcdef"[val % base];
3142: } while (val /= base);
3143:
3144: while ((ch = *p--))
3145: addchar(ch);
3146:
3147: *dbuf->casm = 0;
3148: }
3149:
3150: void
3151: prints_wb(dbuf, val, sz, base)
3152: dis_buffer_t *dbuf;
3153: int val;
3154: int sz, base;
3155: {
3156: if (val < 0) {
3157: addchar('-');
3158: val = -val;
3159: }
3160: printu_wb(dbuf, val, sz, base);
3161: }
3162:
3163: void
3164: iprintu_wb(dbuf, val, sz, base)
3165: dis_buffer_t *dbuf;
3166: u_int val;
3167: int sz, base;
3168: {
3169: static char buf[sizeof(long) * NBBY / 3 + 2];
3170: char *p, ch;
3171:
3172: if (base != 10) {
3173: iaddchar('0');
3174: if (base != 8) {
3175: base = 16;
3176: iaddchar('x');
3177: }
3178: }
3179:
3180: p = buf;
3181: do {
3182: *++p = "0123456789abcdef"[val % base];
3183: } while (val /= base);
3184:
3185: while ((ch = *p--))
3186: iaddchar(ch);
3187:
3188: *dbuf->cinfo = 0;
3189: }
3190:
3191: void
3192: iprints_wb(dbuf, val, sz, base)
3193: dis_buffer_t *dbuf;
3194: int val;
3195: int sz, base;
3196: {
3197: if (val < 0) {
3198: iaddchar('-');
3199: val = -val;
3200: }
3201: iprintu_wb(dbuf, val, sz, base);
3202: }
3203:
3204:
3205: void
3206: prints_bf(dbuf, val, sb, eb)
3207: dis_buffer_t *dbuf;
3208: int val, sb, eb;
3209: {
3210: if (ISBITSET(val,sb))
3211: val = (~0 & ~BITFIELD(~0, sb, eb)) | BITFIELD(val, sb, eb);
3212: else
3213: val = BITFIELD(val,sb,eb);
3214:
3215: prints(dbuf, val, SIZE_LONG);
3216: }
3217:
3218: void
3219: printu_bf(dbuf, val, sb, eb)
3220: dis_buffer_t *dbuf;
3221: u_int val;
3222: int sb, eb;
3223: {
3224: printu(dbuf,BITFIELD(val,sb,eb),SIZE_LONG);
3225: }
CVSweb