m10300-dis.c
来自「基于4个mips核的noc设计」· C语言 代码 · 共 688 行 · 第 1/2 页
C
688 行
/* Disassemble MN10300 instructions. Copyright 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, or(at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include <stdio.h>#include "sysdep.h"#include "opcode/mn10300.h" #include "dis-asm.h"#include "opintl.h"static void disassemble PARAMS ((bfd_vma, struct disassemble_info *, unsigned long insn, unsigned int));#define HAVE_AM33 (info->mach == AM33)#define HAVE_AM30 (info->mach == AM30)int print_insn_mn10300 (memaddr, info) bfd_vma memaddr; struct disassemble_info *info;{ int status; bfd_byte buffer[4]; unsigned long insn; unsigned int consume; /* First figure out how big the opcode is. */ status = (*info->read_memory_func) (memaddr, buffer, 1, info); if (status != 0) { (*info->memory_error_func) (status, memaddr, info); return -1; } insn = *(unsigned char *) buffer; /* These are one byte insns. */ if ((insn & 0xf3) == 0x00 || (insn & 0xf0) == 0x10 || (insn & 0xfc) == 0x3c || (insn & 0xf3) == 0x41 || (insn & 0xf3) == 0x40 || (insn & 0xfc) == 0x50 || (insn & 0xfc) == 0x54 || (insn & 0xf0) == 0x60 || (insn & 0xf0) == 0x70 || ((insn & 0xf0) == 0x80 && (insn & 0x0c) >> 2 != (insn & 0x03)) || ((insn & 0xf0) == 0x90 && (insn & 0x0c) >> 2 != (insn & 0x03)) || ((insn & 0xf0) == 0xa0 && (insn & 0x0c) >> 2 != (insn & 0x03)) || ((insn & 0xf0) == 0xb0 && (insn & 0x0c) >> 2 != (insn & 0x03)) || (insn & 0xff) == 0xcb || (insn & 0xfc) == 0xd0 || (insn & 0xfc) == 0xd4 || (insn & 0xfc) == 0xd8 || (insn & 0xf0) == 0xe0 || (insn & 0xff) == 0xff) { consume = 1; } /* These are two byte insns. */ else if ((insn & 0xf0) == 0x80 || (insn & 0xf0) == 0x90 || (insn & 0xf0) == 0xa0 || (insn & 0xf0) == 0xb0 || (insn & 0xfc) == 0x20 || (insn & 0xfc) == 0x28 || (insn & 0xf3) == 0x43 || (insn & 0xf3) == 0x42 || (insn & 0xfc) == 0x58 || (insn & 0xfc) == 0x5c || ((insn & 0xf0) == 0xc0 && (insn & 0xff) != 0xcb && (insn & 0xff) != 0xcc && (insn & 0xff) != 0xcd) || (insn & 0xff) == 0xf0 || (insn & 0xff) == 0xf1 || (insn & 0xff) == 0xf2 || (insn & 0xff) == 0xf3 || (insn & 0xff) == 0xf4 || (insn & 0xff) == 0xf5 || (insn & 0xff) == 0xf6) { status = (*info->read_memory_func) (memaddr, buffer, 2, info); if (status != 0) { (*info->memory_error_func) (status, memaddr, info); return -1; } insn = bfd_getb16 (buffer); consume = 2; } /* These are three byte insns. */ else if ((insn & 0xff) == 0xf8 || (insn & 0xff) == 0xcc || (insn & 0xff) == 0xf9 || (insn & 0xf3) == 0x01 || (insn & 0xf3) == 0x02 || (insn & 0xf3) == 0x03 || (insn & 0xfc) == 0x24 || (insn & 0xfc) == 0x2c || (insn & 0xfc) == 0x30 || (insn & 0xfc) == 0x34 || (insn & 0xfc) == 0x38 || (insn & 0xff) == 0xde || (insn & 0xff) == 0xdf || (insn & 0xff) == 0xf9 || (insn & 0xff) == 0xcc) { status = (*info->read_memory_func) (memaddr, buffer, 2, info); if (status != 0) { (*info->memory_error_func) (status, memaddr, info); return -1; } insn = bfd_getb16 (buffer); insn <<= 8; status = (*info->read_memory_func) (memaddr + 2, buffer, 1, info); if (status != 0) { (*info->memory_error_func) (status, memaddr, info); return -1; } insn |= *(unsigned char *)buffer; consume = 3; } /* These are four byte insns. */ else if ((insn & 0xff) == 0xfa || (insn & 0xff) == 0xf7 || (insn & 0xff) == 0xfb) { status = (*info->read_memory_func) (memaddr, buffer, 4, info); if (status != 0) { (*info->memory_error_func) (status, memaddr, info); return -1; } insn = bfd_getb32 (buffer); consume = 4; } /* These are five byte insns. */ else if ((insn & 0xff) == 0xcd || (insn & 0xff) == 0xdc) { status = (*info->read_memory_func) (memaddr, buffer, 4, info); if (status != 0) { (*info->memory_error_func) (status, memaddr, info); return -1; } insn = bfd_getb32 (buffer); consume = 5; } /* These are six byte insns. */ else if ((insn & 0xff) == 0xfd || (insn & 0xff) == 0xfc) { status = (*info->read_memory_func) (memaddr, buffer, 4, info); if (status != 0) { (*info->memory_error_func) (status, memaddr, info); return -1; } insn = bfd_getb32 (buffer); consume = 6; } /* Else its a seven byte insns (in theory). */ else { status = (*info->read_memory_func) (memaddr, buffer, 4, info); if (status != 0) { (*info->memory_error_func) (status, memaddr, info); return -1; } insn = bfd_getb32 (buffer); consume = 7; } disassemble (memaddr, info, insn, consume); return consume;}static voiddisassemble (memaddr, info, insn, size) bfd_vma memaddr; struct disassemble_info *info; unsigned long insn; unsigned int size;{ struct mn10300_opcode *op = (struct mn10300_opcode *)mn10300_opcodes; const struct mn10300_operand *operand; bfd_byte buffer[4]; unsigned long extension = 0; int status, match = 0; /* Find the opcode. */ while (op->name) { int mysize, extra_shift; if (op->format == FMT_S0) mysize = 1; else if (op->format == FMT_S1 || op->format == FMT_D0) mysize = 2; else if (op->format == FMT_S2 || op->format == FMT_D1) mysize = 3; else if (op->format == FMT_S4) mysize = 5; else if (op->format == FMT_D2) mysize = 4; else if (op->format == FMT_D4) mysize = 6; else if (op->format == FMT_D6) mysize = 3; else if (op->format == FMT_D7 || op->format == FMT_D10) mysize = 4; else if (op->format == FMT_D8) mysize = 6; else if (op->format == FMT_D9) mysize = 7; else mysize = 7; if ((op->mask & insn) == op->opcode && size == (unsigned int) mysize && (op->machine == 0 || (op->machine == AM33 && HAVE_AM33) || (op->machine == AM30 && HAVE_AM30))) { const unsigned char *opindex_ptr; unsigned int nocomma; int paren = 0; if (op->format == FMT_D1 || op->format == FMT_S1) extra_shift = 8; else if (op->format == FMT_D2 || op->format == FMT_D4 || op->format == FMT_S2 || op->format == FMT_S4 || op->format == FMT_S6 || op->format == FMT_D5) extra_shift = 16; else if (op->format == FMT_D7 || op->format == FMT_D8 || op->format == FMT_D9) extra_shift = 8; else extra_shift = 0; if (size == 1 || size == 2) { extension = 0; } else if (size == 3 && (op->format == FMT_D1 || op->opcode == 0xdf0000 || op->opcode == 0xde0000)) { extension = 0; } else if (size == 3 && op->format == FMT_D6) { extension = 0; } else if (size == 3) { insn &= 0xff0000; status = (*info->read_memory_func) (memaddr + 1, buffer, 2, info); if (status != 0) { (*info->memory_error_func) (status, memaddr, info); return; } insn |= bfd_getl16 (buffer); extension = 0; } else if (size == 4 && (op->opcode == 0xfaf80000 || op->opcode == 0xfaf00000 || op->opcode == 0xfaf40000)) { extension = 0; } else if (size == 4 && (op->format == FMT_D7 || op->format == FMT_D10)) { extension = 0; } else if (size == 4) { insn &= 0xffff0000; status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info); if (status != 0) { (*info->memory_error_func) (status, memaddr, info); return; } insn |= bfd_getl16 (buffer); extension = 0; } else if (size == 5 && op->opcode == 0xdc000000) { unsigned long temp = 0; status = (*info->read_memory_func) (memaddr + 1, buffer, 4, info); if (status != 0) { (*info->memory_error_func) (status, memaddr, info); return; } temp |= bfd_getl32 (buffer); insn &= 0xff000000; insn |= (temp & 0xffffff00) >> 8; extension = temp & 0xff;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?