m68k-dis.c
来自「基于4个mips核的noc设计」· C语言 代码 · 共 1,329 行 · 第 1/3 页
C
1,329 行
if (*d) (*info->fprintf_func) (info->stream, " "); while (*d) { p += print_insn_arg (d, buffer, p, memaddr + (p - buffer), info); d += 2; if (*d && *(d - 2) != 'I' && *d != 'k') (*info->fprintf_func) (info->stream, ","); } return p - buffer; invalid: /* Handle undefined instructions. */ info->fprintf_func = save_printer; info->print_address_func = save_print_address; (*info->fprintf_func) (info->stream, "0%o", (buffer[0] << 8) + buffer[1]); return 2;}/* Returns number of bytes "eaten" by the operand, or return -1 if an invalid operand was found, or -2 if an opcode tabe error was found. */static intprint_insn_arg (d, buffer, p0, addr, info) const char *d; unsigned char *buffer; unsigned char *p0; bfd_vma addr; /* PC for this arg to be relative to */ disassemble_info *info;{ register int val = 0; register int place = d[1]; register unsigned char *p = p0; int regno; register CONST char *regname; register unsigned char *p1; double flval; int flt_p; bfd_signed_vma disp; unsigned int uval; switch (*d) { case 'c': /* cache identifier */ { static char *const cacheFieldName[] = { "nc", "dc", "ic", "bc" }; val = fetch_arg (buffer, place, 2, info); (*info->fprintf_func) (info->stream, cacheFieldName[val]); break; } case 'a': /* address register indirect only. Cf. case '+'. */ { (*info->fprintf_func) (info->stream, "%s@", reg_names [fetch_arg (buffer, place, 3, info) + 8]); break; } case '_': /* 32-bit absolute address for move16. */ { uval = NEXTULONG (p); (*info->print_address_func) (uval, info); break; } case 'C': (*info->fprintf_func) (info->stream, "%%ccr"); break; case 'S': (*info->fprintf_func) (info->stream, "%%sr"); break; case 'U': (*info->fprintf_func) (info->stream, "%%usp"); break; case 'E': (*info->fprintf_func) (info->stream, "%%acc"); break; case 'G': (*info->fprintf_func) (info->stream, "%%macsr"); break; case 'H': (*info->fprintf_func) (info->stream, "%%mask"); break; case 'J': { static const struct { char *name; int value; } names[] = {{"%sfc", 0x000}, {"%dfc", 0x001}, {"%cacr", 0x002}, {"%tc", 0x003}, {"%itt0",0x004}, {"%itt1", 0x005}, {"%dtt0",0x006}, {"%dtt1",0x007}, {"%buscr",0x008}, {"%usp", 0x800}, {"%vbr", 0x801}, {"%caar", 0x802}, {"%msp", 0x803}, {"%isp", 0x804}, /* Should we be calling this psr like we do in case 'Y'? */ {"%mmusr",0x805}, {"%urp", 0x806}, {"%srp", 0x807}, {"%pcr", 0x808}}; val = fetch_arg (buffer, place, 12, info); for (regno = sizeof names / sizeof names[0] - 1; regno >= 0; regno--) if (names[regno].value == val) { (*info->fprintf_func) (info->stream, "%s", names[regno].name); break; } if (regno < 0) (*info->fprintf_func) (info->stream, "%d", val); } break; case 'Q': val = fetch_arg (buffer, place, 3, info); /* 0 means 8, except for the bkpt instruction... */ if (val == 0 && d[1] != 's') val = 8; (*info->fprintf_func) (info->stream, "#%d", val); break; case 'M': if (place == 'h') { static char *const scalefactor_name[] = { "<<", ">>" }; val = fetch_arg (buffer, place, 1, info); (*info->fprintf_func) (info->stream, scalefactor_name[val]); } else { val = fetch_arg (buffer, place, 8, info); if (val & 0x80) val = val - 0x100; (*info->fprintf_func) (info->stream, "#%d", val); } break; case 'T': val = fetch_arg (buffer, place, 4, info); (*info->fprintf_func) (info->stream, "#%d", val); break; case 'D': (*info->fprintf_func) (info->stream, "%s", reg_names[fetch_arg (buffer, place, 3, info)]); break; case 'A': (*info->fprintf_func) (info->stream, "%s", reg_names[fetch_arg (buffer, place, 3, info) + 010]); break; case 'R': (*info->fprintf_func) (info->stream, "%s", reg_names[fetch_arg (buffer, place, 4, info)]); break; case 'r': regno = fetch_arg (buffer, place, 4, info); if (regno > 7) (*info->fprintf_func) (info->stream, "%s@", reg_names[regno]); else (*info->fprintf_func) (info->stream, "@(%s)", reg_names[regno]); break; case 'F': (*info->fprintf_func) (info->stream, "%%fp%d", fetch_arg (buffer, place, 3, info)); break; case 'O': val = fetch_arg (buffer, place, 6, info); if (val & 0x20) (*info->fprintf_func) (info->stream, "%s", reg_names [val & 7]); else (*info->fprintf_func) (info->stream, "%d", val); break; case '+': (*info->fprintf_func) (info->stream, "%s@+", reg_names[fetch_arg (buffer, place, 3, info) + 8]); break; case '-': (*info->fprintf_func) (info->stream, "%s@-", reg_names[fetch_arg (buffer, place, 3, info) + 8]); break; case 'k': if (place == 'k') (*info->fprintf_func) (info->stream, "{%s}", reg_names[fetch_arg (buffer, place, 3, info)]); else if (place == 'C') { val = fetch_arg (buffer, place, 7, info); if ( val > 63 ) /* This is a signed constant. */ val -= 128; (*info->fprintf_func) (info->stream, "{#%d}", val); } else return -2; break; case '#': case '^': p1 = buffer + (*d == '#' ? 2 : 4); if (place == 's') val = fetch_arg (buffer, place, 4, info); else if (place == 'C') val = fetch_arg (buffer, place, 7, info); else if (place == '8') val = fetch_arg (buffer, place, 3, info); else if (place == '3') val = fetch_arg (buffer, place, 8, info); else if (place == 'b') val = NEXTBYTE (p1); else if (place == 'w' || place == 'W') val = NEXTWORD (p1); else if (place == 'l') val = NEXTLONG (p1); else return -2; (*info->fprintf_func) (info->stream, "#%d", val); break; case 'B': if (place == 'b') disp = NEXTBYTE (p); else if (place == 'B') disp = COERCE_SIGNED_CHAR(buffer[1]); else if (place == 'w' || place == 'W') disp = NEXTWORD (p); else if (place == 'l' || place == 'L' || place == 'C') disp = NEXTLONG (p); else if (place == 'g') { disp = NEXTBYTE (buffer); if (disp == 0) disp = NEXTWORD (p); else if (disp == -1) disp = NEXTLONG (p); } else if (place == 'c') { if (buffer[1] & 0x40) /* If bit six is one, long offset */ disp = NEXTLONG (p); else disp = NEXTWORD (p); } else return -2; (*info->print_address_func) (addr + disp, info); break; case 'd': val = NEXTWORD (p); (*info->fprintf_func) (info->stream, "%s@(%d)", reg_names[fetch_arg (buffer, place, 3, info) + 8], val); break; case 's': (*info->fprintf_func) (info->stream, "%s", fpcr_names[fetch_arg (buffer, place, 3, info)]); break; case 'I': /* Get coprocessor ID... */ val = fetch_arg (buffer, 'd', 3, info); if (val != 1) /* Unusual coprocessor ID? */ (*info->fprintf_func) (info->stream, "(cpid=%d) ", val); break; case '*': case '~': case '%': case ';': case '@': case '!': case '$': case '?': case '/': case '&': case '|': case '<': case '>': case 'm': case 'n': case 'o': case 'p': case 'q': case 'v': if (place == 'd') { val = fetch_arg (buffer, 'x', 6, info); val = ((val & 7) << 3) + ((val >> 3) & 7); } else val = fetch_arg (buffer, 's', 6, info); /* Get register number assuming address register. */ regno = (val & 7) + 8; regname = reg_names[regno]; switch (val >> 3) { case 0: (*info->fprintf_func) (info->stream, "%s", reg_names[val]); break; case 1: (*info->fprintf_func) (info->stream, "%s", regname); break; case 2: (*info->fprintf_func) (info->stream, "%s@", regname); break; case 3: (*info->fprintf_func) (info->stream, "%s@+", regname); break; case 4: (*info->fprintf_func) (info->stream, "%s@-", regname); break; case 5: val = NEXTWORD (p); (*info->fprintf_func) (info->stream, "%s@(%d)", regname, val); break; case 6: p = print_indexed (regno, p, addr, info); break; case 7: switch (val & 7) { case 0: val = NEXTWORD (p); (*info->print_address_func) (val, info); break; case 1: uval = NEXTULONG (p); (*info->print_address_func) (uval, info); break; case 2: val = NEXTWORD (p); (*info->fprintf_func) (info->stream, "%%pc@("); (*info->print_address_func) (addr + val, info); (*info->fprintf_func) (info->stream, ")"); break; case 3: p = print_indexed (-1, p, addr, info); 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': NEXTSINGLE(flval, p); break; case 'F': NEXTDOUBLE(flval, p); break; case 'x': NEXTEXTEND(flval, p); break; case 'p': flval = NEXTPACKED(p); break; default: return -1; } if ( flt_p ) /* Print a float? */ (*info->fprintf_func) (info->stream, "#%g", flval); else (*info->fprintf_func) (info->stream, "#%d", val); break; default: return -1; } } 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) { (*info->fprintf_func) (info->stream, "#0"); break; } if (*d == 'l') { register int newval = 0;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?