ns32k-dis.c
来自「基于4个mips核的noc设计」· C语言 代码 · 共 896 行 · 第 1/2 页
C
896 行
/* Print National Semiconductor 32000 instructions. Copyright 1986, 1988, 1991, 1992, 1994, 1998 Free Software Foundation, Inc.This file is part of opcodes library.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 "bfd.h"#include "sysdep.h"#include "dis-asm.h"#if !defined(const) && !defined(__STDC__)#define const#endif#include "opcode/ns32k.h"#include "opintl.h"static disassemble_info *dis_info;/* * Hacks to get it to compile <= READ THESE AS FIXES NEEDED */#define INVALID_FLOAT(val, size) invalid_float((char *)val, size)static int print_insn_arg PARAMS ((int, int, int *, char *, bfd_vma, char *, int));static int get_displacement PARAMS ((char *, int *));static int invalid_float PARAMS ((char *, int));static long read_memory_integer(addr, nr) unsigned char *addr; int nr;{ long val; int i; for (val = 0, i = nr - 1; i >= 0; i--) { val = (val << 8); val |= (0xff & *(addr + i)); } return val;}/* 32000 instructions are never longer than this. */#define MAXLEN 62#include <setjmp.h>struct private{ /* Points to first byte not fetched. */ bfd_byte *max_fetched; bfd_byte the_buffer[MAXLEN]; bfd_vma insn_start; jmp_buf bailout;};/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive) to ADDR (exclusive) are valid. Returns 1 for success, longjmps on error. */#define FETCH_DATA(info, addr) \ ((addr) <= ((struct private *)(info->private_data))->max_fetched \ ? 1 : fetch_data ((info), (addr)))static intfetch_data (info, addr) struct disassemble_info *info; bfd_byte *addr;{ int status; struct private *priv = (struct private *)info->private_data; bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer); status = (*info->read_memory_func) (start, priv->max_fetched, addr - priv->max_fetched, info); if (status != 0) { (*info->memory_error_func) (status, start, info); longjmp (priv->bailout, 1); } else priv->max_fetched = addr; return 1;}/* Number of elements in the opcode table. */#define NOPCODES (sizeof ns32k_opcodes / sizeof ns32k_opcodes[0])#define NEXT_IS_ADDR '|'struct ns32k_option { char *pattern; /* the option itself */ unsigned long value; /* binary value of the option */ unsigned long match; /* these bits must match */};static const struct ns32k_option opt_u[]= /* restore, exit */{ { "r0", 0x80, 0x80 }, { "r1", 0x40, 0x40 }, { "r2", 0x20, 0x20 }, { "r3", 0x10, 0x10 }, { "r4", 0x08, 0x08 }, { "r5", 0x04, 0x04 }, { "r6", 0x02, 0x02 }, { "r7", 0x01, 0x01 }, { 0 , 0x00, 0x00 }};static const struct ns32k_option opt_U[]= /* save, enter */{ { "r0", 0x01, 0x01 }, { "r1", 0x02, 0x02 }, { "r2", 0x04, 0x04 }, { "r3", 0x08, 0x08 }, { "r4", 0x10, 0x10 }, { "r5", 0x20, 0x20 }, { "r6", 0x40, 0x40 }, { "r7", 0x80, 0x80 }, { 0 , 0x00, 0x00 }};static const struct ns32k_option opt_O[]= /* setcfg */{ { "c", 0x8, 0x8 }, { "m", 0x4, 0x4 }, { "f", 0x2, 0x2 }, { "i", 0x1, 0x1 }, { 0 , 0x0, 0x0 }};static const struct ns32k_option opt_C[]= /* cinv */{ { "a", 0x4, 0x4 }, { "i", 0x2, 0x2 }, { "d", 0x1, 0x1 }, { 0 , 0x0, 0x0 }};static const struct ns32k_option opt_S[]= /* string inst */{ { "b", 0x1, 0x1 }, { "u", 0x6, 0x6 }, { "w", 0x2, 0x2 }, { 0 , 0x0, 0x0 }};static const struct ns32k_option list_P532[]= /* lpr spr */{ { "us", 0x0, 0xf }, { "dcr", 0x1, 0xf }, { "bpc", 0x2, 0xf }, { "dsr", 0x3, 0xf }, { "car", 0x4, 0xf }, { "fp", 0x8, 0xf }, { "sp", 0x9, 0xf }, { "sb", 0xa, 0xf }, { "usp", 0xb, 0xf }, { "cfg", 0xc, 0xf }, { "psr", 0xd, 0xf }, { "intbase", 0xe, 0xf }, { "mod", 0xf, 0xf }, { 0 , 0x00, 0xf }};static const struct ns32k_option list_M532[]= /* lmr smr */{ { "mcr", 0x9, 0xf }, { "msr", 0xa, 0xf }, { "tear", 0xb, 0xf }, { "ptb0", 0xc, 0xf }, { "ptb1", 0xd, 0xf }, { "ivar0", 0xe, 0xf }, { "ivar1", 0xf, 0xf }, { 0 , 0x0, 0xf }};static const struct ns32k_option list_P032[]= /* lpr spr */{ { "upsr", 0x0, 0xf }, { "fp", 0x8, 0xf }, { "sp", 0x9, 0xf }, { "sb", 0xa, 0xf }, { "psr", 0xb, 0xf }, { "intbase", 0xe, 0xf }, { "mod", 0xf, 0xf }, { 0 , 0x0, 0xf }};static const struct ns32k_option list_M032[]= /* lmr smr */{ { "bpr0", 0x0, 0xf }, { "bpr1", 0x1, 0xf }, { "pf0", 0x4, 0xf }, { "pf1", 0x5, 0xf }, { "sc", 0x8, 0xf }, { "msr", 0xa, 0xf }, { "bcnt", 0xb, 0xf }, { "ptb0", 0xc, 0xf }, { "ptb1", 0xd, 0xf }, { "eia", 0xf, 0xf }, { 0 , 0x0, 0xf }};/* * figure out which options are present */static voidoptlist(options, optionP, result) int options; const struct ns32k_option *optionP; char *result;{ if (options == 0) { sprintf(result, "[]"); return; } sprintf(result, "["); for (; (options != 0) && optionP->pattern; optionP++) { if ((options & optionP->match) == optionP->value) { /* we found a match, update result and options */ strcat(result, optionP->pattern); options &= ~optionP->value; if (options != 0) /* more options to come */ strcat(result, ","); } } if (options != 0) strcat(result, "undefined"); strcat(result, "]");}static voidlist_search (reg_value, optionP, result) int reg_value; const struct ns32k_option *optionP; char *result;{ for (; optionP->pattern; optionP++) { if ((reg_value & optionP->match) == optionP->value) { sprintf(result, "%s", optionP->pattern); return; } } sprintf(result, "undefined");}/* * extract "count" bits starting "offset" bits * into buffer */static intbit_extract (buffer, offset, count) bfd_byte *buffer; int offset; int count;{ int result; int bit; buffer += offset >> 3; offset &= 7; bit = 1; result = 0; while (count--) { FETCH_DATA(dis_info, buffer + 1); if ((*buffer & (1 << offset))) result |= bit; if (++offset == 8) { offset = 0; buffer++; } bit <<= 1; } return result;}/* Like bit extract but the buffer is valid and doen't need to be * fetched */static intbit_extract_simple (buffer, offset, count) bfd_byte *buffer; int offset; int count;{ int result; int mask; int bit; buffer += offset >> 3; offset &= 7; bit = 1; result = 0; while (count--) { if ((*buffer & (1 << offset))) result |= bit; if (++offset == 8) { offset = 0; buffer++; } bit <<= 1; } return result;}static voidbit_copy (buffer, offset, count, to) char *buffer; int offset; int count; char *to;{ for(; count > 8; count -= 8, to++, offset += 8) *to = bit_extract (buffer, offset, 8); *to = bit_extract (buffer, offset, count);}static intsign_extend (value, bits) int value, bits;{ value = value & ((1 << bits) - 1); return (value & (1 << (bits-1)) ? value | (~((1 << bits) - 1)) : value);}static voidflip_bytes (ptr, count) char *ptr; int count;{ char tmp; while (count > 0) { tmp = ptr[0]; ptr[0] = ptr[count-1]; ptr[count-1] = tmp; ptr++; count -= 2; }}/* Given a character C, does it represent a general addressing mode? */#define Is_gen(c) \ ((c) == 'F' || (c) == 'L' || (c) == 'B' \ || (c) == 'W' || (c) == 'D' || (c) == 'A' || (c) == 'I' || (c) == 'Z')/* Adressing modes. */#define Adrmod_index_byte 0x1c#define Adrmod_index_word 0x1d#define Adrmod_index_doubleword 0x1e#define Adrmod_index_quadword 0x1f/* Is MODE an indexed addressing mode? */#define Adrmod_is_index(mode) \ (mode == Adrmod_index_byte \ || mode == Adrmod_index_word \ || mode == Adrmod_index_doubleword \ || mode == Adrmod_index_quadword)/* Print the 32000 instruction at address MEMADDR in debugged memory, on STREAM. Returns length of the instruction, in bytes. */intprint_insn_ns32k (memaddr, info) bfd_vma memaddr; disassemble_info *info;{ register unsigned int i; register char *d; unsigned short first_word; int ioffset; /* bits into instruction */ int aoffset; /* bits into arguments */ char arg_bufs[MAX_ARGS+1][ARG_LEN]; int argnum; int maxarg; struct private priv; bfd_byte *buffer = priv.the_buffer; dis_info = info; info->private_data = (PTR) &priv; priv.max_fetched = priv.the_buffer; priv.insn_start = memaddr; if (setjmp (priv.bailout) != 0) /* Error return. */ return -1; /* Look for 8bit opcodes first. Other wise, fetching two bytes could take * us over the end of accessible data unnecessarilly */ FETCH_DATA(info, buffer + 1); for (i = 0; i < NOPCODES; i++) if (ns32k_opcodes[i].opcode_id_size <= 8 && ((buffer[0] & (((unsigned long) 1 << ns32k_opcodes[i].opcode_id_size) - 1)) == ns32k_opcodes[i].opcode_seed)) break; if (i == NOPCODES) { /* Maybe it is 9 to 16 bits big */ FETCH_DATA(info, buffer + 2); first_word = read_memory_integer(buffer, 2); for (i = 0; i < NOPCODES; i++) if ((first_word & (((unsigned long) 1 << ns32k_opcodes[i].opcode_id_size) - 1)) == ns32k_opcodes[i].opcode_seed) break; /* Handle undefined instructions. */ if (i == NOPCODES) { (*dis_info->fprintf_func)(dis_info->stream, "0%o", buffer[0]); return 1; } } (*dis_info->fprintf_func)(dis_info->stream, "%s", ns32k_opcodes[i].name);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?