m68k-dis.c
来自「基于4个mips核的noc设计」· C语言 代码 · 共 1,329 行 · 第 1/3 页
C
1,329 行
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) (*info->fprintf_func) (info->stream, "/"); doneany = 1; (*info->fprintf_func) (info->stream, "%s", reg_names[regno]); first_regno = regno; while (val & (1 << (regno + 1))) ++regno; if (regno > first_regno) (*info->fprintf_func) (info->stream, "-%s", reg_names[regno]); } } else if (place == '3') { /* `fmovem' insn. */ char doneany; val = fetch_arg (buffer, place, 8, info); if (val == 0) { (*info->fprintf_func) (info->stream, "#0"); 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) (*info->fprintf_func) (info->stream, "/"); doneany = 1; (*info->fprintf_func) (info->stream, "%%fp%d", regno); first_regno = regno; while (val & (1 << (regno + 1))) ++regno; if (regno > first_regno) (*info->fprintf_func) (info->stream, "-%%fp%d", regno); } } else if (place == '8') { /* fmoveml for FP status registers */ (*info->fprintf_func) (info->stream, "%s", fpcr_names[fetch_arg (buffer, place, 3, info)]); } else return -2; break; case 'X': place = '8'; case 'Y': case 'Z': case 'W': case '0': case '1': case '2': case '3': { int val = fetch_arg (buffer, place, 5, info); char *name = 0; switch (val) { case 2: name = "%tt0"; break; case 3: name = "%tt1"; break; case 0x10: name = "%tc"; break; case 0x11: name = "%drp"; break; case 0x12: name = "%srp"; break; case 0x13: name = "%crp"; break; case 0x14: name = "%cal"; break; case 0x15: name = "%val"; break; case 0x16: name = "%scc"; break; case 0x17: name = "%ac"; break; case 0x18: name = "%psr"; break; case 0x19: name = "%pcsr"; break; case 0x1c: case 0x1d: { int break_reg = ((buffer[3] >> 2) & 7); (*info->fprintf_func) (info->stream, val == 0x1c ? "%%bad%d" : "%%bac%d", break_reg); } break; default: (*info->fprintf_func) (info->stream, "<mmu register %d>", val); } if (name) (*info->fprintf_func) (info->stream, "%s", name); } break; case 'f': { int fc = fetch_arg (buffer, place, 5, info); if (fc == 1) (*info->fprintf_func) (info->stream, "%%dfc"); else if (fc == 0) (*info->fprintf_func) (info->stream, "%%sfc"); else /* xgettext:c-format */ (*info->fprintf_func) (info->stream, _("<function code %d>"), fc); } break; case 'V': (*info->fprintf_func) (info->stream, "%%val"); break; case 't': { int level = fetch_arg (buffer, place, 3, info); (*info->fprintf_func) (info->stream, "%d", level); } break; case 'u': { short is_upper = 0; int reg = fetch_arg (buffer, place, 5, info); if (reg & 0x10) { is_upper = 1; reg &= 0xf; } (*info->fprintf_func) (info->stream, "%s%s", reg_names[reg], is_upper ? "u" : "l"); } break; default: return -2; } return p - p0;}/* 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, info) unsigned char *buffer; int code; int bits; disassemble_info *info;{ register int val = 0; 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': FETCH_DATA (info, buffer + 3); val = (buffer[3] >> 4); break; case 'C': FETCH_DATA (info, buffer + 3); val = buffer[3]; break; case '1': FETCH_DATA (info, buffer + 3); val = (buffer[2] << 8) + buffer[3]; val >>= 12; break; case '2': FETCH_DATA (info, buffer + 3); val = (buffer[2] << 8) + buffer[3]; val >>= 6; break; case '3': case 'j': FETCH_DATA (info, buffer + 3); val = (buffer[2] << 8) + buffer[3]; break; case '4': FETCH_DATA (info, buffer + 5); val = (buffer[4] << 8) + buffer[5]; val >>= 12; break; case '5': FETCH_DATA (info, buffer + 5); val = (buffer[4] << 8) + buffer[5]; val >>= 6; break; case '6': FETCH_DATA (info, buffer + 5); val = (buffer[4] << 8) + buffer[5]; break; case '7': FETCH_DATA (info, buffer + 3); val = (buffer[2] << 8) + buffer[3]; val >>= 7; break; case '8': FETCH_DATA (info, buffer + 3); val = (buffer[2] << 8) + buffer[3]; val >>= 10; break; case '9': FETCH_DATA (info, buffer + 3); val = (buffer[2] << 8) + buffer[3]; val >>= 5; break; case 'e': val = (buffer[1] >> 6); break; case 'm': val = (buffer[1] & 0x40 ? 0x8 : 0) | ((buffer[0] >> 1) & 0x7) | (buffer[3] & 0x80 ? 0x10 : 0); break; case 'n': val = (buffer[1] & 0x40 ? 0x8 : 0) | ((buffer[0] >> 1) & 0x7); break; case 'o': val = (buffer[2] >> 4) | (buffer[3] & 0x80 ? 0x10 : 0); break; case 'M': val = buffer[1] | (buffer[3] & 0x40 ? 0x10 : 0); break; case 'N': val = buffer[3] | (buffer[3] & 0x40 ? 0x10 : 0); break; case 'h': val = buffer[2] >> 2; break; default: abort (); } switch (bits) { case 1: return val & 1; 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, info) int basereg; unsigned char *p; bfd_vma addr; disassemble_info *info;{ register int word; static char *const scales[] = {"", ":2", ":4", ":8"}; bfd_vma base_disp; bfd_vma outer_disp; char buf[40]; char vmabuf[50]; 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) { base_disp = word & 0xff; if ((base_disp & 0x80) != 0) base_disp -= 0x100; if (basereg == -1) base_disp += addr; print_base (basereg, base_disp, info); (*info->fprintf_func) (info->stream, ",%s)", buf); return p; } /* Handle the generalized kind. */ /* First, compute the displacement to add to the base register. */ if (word & 0200) { if (basereg == -1) basereg = -3; else 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, info); if (buf[0] != '\0') (*info->fprintf_func) (info->stream, ",%s", buf); (*info->fprintf_func) (info->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); } print_base (basereg, base_disp, info); if ((word & 4) == 0 && buf[0] != '\0') { (*info->fprintf_func) (info->stream, ",%s", buf); buf[0] = '\0'; } sprintf_vma (vmabuf, outer_disp); (*info->fprintf_func) (info->stream, ")@(%s", vmabuf); if (buf[0] != '\0') (*info->fprintf_func) (info->stream, ",%s", buf); (*info->fprintf_func) (info->stream, ")"); return p;}/* Print a base register REGNO and displacement DISP, on INFO->STREAM. REGNO = -1 for pc, -2 for none (suppressed). */static voidprint_base (regno, disp, info) int regno; bfd_vma disp; disassemble_info *info;{ if (regno == -1) { (*info->fprintf_func) (info->stream, "%%pc@("); (*info->print_address_func) (disp, info); } else { char buf[50]; if (regno == -2) (*info->fprintf_func) (info->stream, "@("); else if (regno == -3) (*info->fprintf_func) (info->stream, "%%zpc@("); else (*info->fprintf_func) (info->stream, "%s@(", reg_names[regno]); sprintf_vma (buf, disp); (*info->fprintf_func) (info->stream, "%s", buf); }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?