📄 m68k-pinsn.c
字号:
/* Get register number assuming address register. */ regno = (val & 7) + 8; regname = reg_names[regno]; switch (val >> 3) { case 0: fprintf_filtered (stream, "%s", reg_names[val]); break; case 1: fprintf_filtered (stream, "%s", regname); break; case 2: fprintf_filtered (stream, "%s@", regname); break; case 3: fprintf_filtered (stream, "%s@+", regname); break; case 4: fprintf_filtered (stream, "%s@-", regname); break; case 5: val = NEXTWORD (p); fprintf_filtered (stream, "%s@(%d)", regname, val); break; case 6: p = print_indexed (regno, p, addr, stream); break; case 7: switch (val & 7) { case 0: val = NEXTWORD (p); fprintf_filtered (stream, "@#"); print_address (val, stream); break; case 1: val = NEXTLONG (p); fprintf_filtered (stream, "@#"); print_address (val, stream); break; case 2: val = NEXTWORD (p); print_address (addr + val, stream); break; case 3: p = print_indexed (-1, p, addr, stream); break; case 4: flt_p = 1; /* Assume it's a float... */ switch( place ) { case 'b': val = NEXTBYTE (p); flt_p = 0; break; case 'w': val = NEXTWORD (p); flt_p = 0; break; case 'l': val = NEXTLONG (p); flt_p = 0; break; case 'f': flval = NEXTSINGLE(p); break; case 'F': flval = NEXTDOUBLE(p); break;#ifdef HAVE_68881 case 'x': ieee_extended_to_double (&ext_format_68881, p, &flval); p += 12; break;#endif case 'p': p += 12; flval = 0; /* FIXME, handle packed decimal someday. */ break; default: error ("Invalid arg format in opcode table: \"%c%c\".", *d, place); } if ( flt_p ) /* Print a float? */ fprintf_filtered (stream, "#%g", flval); else fprintf_filtered (stream, "#%d", val); break; default: fprintf_filtered (stream, "<invalid address mode 0%o>", val); } } break; case 'L': case 'l': if (place == 'w') { char doneany; p1 = buffer + 2; val = NEXTWORD (p1); /* Move the pointer ahead if this point is farther ahead than the last. */ p = p1 > p ? p1 : p; if (val == 0) { fputs_filtered ("#0", stream); break; } if (*d == 'l') { register int newval = 0; for (regno = 0; regno < 16; ++regno) if (val & (0x8000 >> regno)) newval |= 1 << regno; val = newval; } val &= 0xffff; doneany = 0; for (regno = 0; regno < 16; ++regno) if (val & (1 << regno)) { int first_regno; if (doneany) fputs_filtered ("/", stream); doneany = 1; fprintf_filtered (stream, "%s", reg_names[regno]); first_regno = regno; while (val & (1 << (regno + 1))) ++regno; if (regno > first_regno) fprintf_filtered (stream, "-%s", reg_names[regno]); } } else if (place == '3') { /* `fmovem' insn. */ char doneany; val = fetch_arg (buffer, place, 8); if (val == 0) { fputs_filtered ("#0", stream); break; } if (*d == 'l') { register int newval = 0; for (regno = 0; regno < 8; ++regno) if (val & (0x80 >> regno)) newval |= 1 << regno; val = newval; } val &= 0xff; doneany = 0; for (regno = 0; regno < 8; ++regno) if (val & (1 << regno)) { int first_regno; if (doneany) fputs_filtered ("/", stream); doneany = 1; fprintf_filtered (stream, "fp%d", regno); first_regno = regno; while (val & (1 << (regno + 1))) ++regno; if (regno > first_regno) fprintf_filtered (stream, "-fp%d", regno); } } else goto de_fault; break; default: de_fault: error ("Invalid arg format in opcode table: \"%c\".", *d); } return (unsigned char *) p;}/* Fetch BITS bits from a position in the instruction specified by CODE. CODE is a "place to put an argument", or 'x' for a destination that is a general address (mode and register). BUFFER contains the instruction. */static intfetch_arg (buffer, code, bits) unsigned char *buffer; int code; int bits;{ register int val; switch (code) { case 's': val = buffer[1]; break; case 'd': /* Destination, for register or quick. */ val = (buffer[0] << 8) + buffer[1]; val >>= 9; break; case 'x': /* Destination, for general arg */ val = (buffer[0] << 8) + buffer[1]; val >>= 6; break; case 'k': val = (buffer[3] >> 4); break; case 'C': val = buffer[3]; break; case '1': val = (buffer[2] << 8) + buffer[3]; val >>= 12; break; case '2': val = (buffer[2] << 8) + buffer[3]; val >>= 6; break; case '3': case 'j': val = (buffer[2] << 8) + buffer[3]; break; case '4': val = (buffer[4] << 8) + buffer[5]; val >>= 12; break; case '5': val = (buffer[4] << 8) + buffer[5]; val >>= 6; break; case '6': val = (buffer[4] << 8) + buffer[5]; break; case '7': val = (buffer[2] << 8) + buffer[3]; val >>= 7; break; case '8': val = (buffer[2] << 8) + buffer[3]; val >>= 10; break; case 'e': val = (buffer[1] >> 6); break; default: abort (); } switch (bits) { case 2: return val & 3; case 3: return val & 7; case 4: return val & 017; case 5: return val & 037; case 6: return val & 077; case 7: return val & 0177; case 8: return val & 0377; case 12: return val & 07777; default: abort (); }}/* Print an indexed argument. The base register is BASEREG (-1 for pc). P points to extension word, in buffer. ADDR is the nominal core address of that extension word. */static unsigned char *print_indexed (basereg, p, addr, stream) int basereg; unsigned char *p; CORE_ADDR addr; FILE *stream;{ register int word; static char *scales[] = {"", "*2", "*4", "*8"}; register int base_disp; register int outer_disp; char buf[40]; word = NEXTWORD (p); /* Generate the text for the index register. Where this will be output is not yet determined. */ sprintf (buf, "[%s.%c%s]", reg_names[(word >> 12) & 0xf], (word & 0x800) ? 'l' : 'w', scales[(word >> 9) & 3]); /* Handle the 68000 style of indexing. */ if ((word & 0x100) == 0) { print_base (basereg, ((word & 0x80) ? word | 0xff00 : word & 0xff) + ((basereg == -1) ? addr : 0), stream); fputs_filtered (buf, stream); return p; } /* Handle the generalized kind. */ /* First, compute the displacement to add to the base register. */ if (word & 0200) basereg = -2; if (word & 0100) buf[0] = 0; base_disp = 0; switch ((word >> 4) & 3) { case 2: base_disp = NEXTWORD (p); break; case 3: base_disp = NEXTLONG (p); } if (basereg == -1) base_disp += addr; /* Handle single-level case (not indirect) */ if ((word & 7) == 0) { print_base (basereg, base_disp, stream); fputs_filtered (buf, stream); return p; } /* Two level. Compute displacement to add after indirection. */ outer_disp = 0; switch (word & 3) { case 2: outer_disp = NEXTWORD (p); break; case 3: outer_disp = NEXTLONG (p); } fprintf_filtered (stream, "%d(", outer_disp); print_base (basereg, base_disp, stream); /* If postindexed, print the closeparen before the index. */ if (word & 4) fprintf_filtered (stream, ")%s", buf); /* If preindexed, print the closeparen after the index. */ else fprintf_filtered (stream, "%s)", buf); return p;}/* Print a base register REGNO and displacement DISP, on STREAM. REGNO = -1 for pc, -2 for none (suppressed). */static voidprint_base (regno, disp, stream) int regno; int disp; FILE *stream;{ if (regno == -2) fprintf_filtered (stream, "%d", disp); else if (regno == -1) fprintf_filtered (stream, "0x%x", disp); else fprintf_filtered (stream, "%d(%s)", disp, reg_names[regno]);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -