⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i960-pinsn.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* i80960 instruction disassembler for GDB.   Copyright 1990, 1991, 1992 Free Software Foundation, Inc.This file is part of GDB.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., 675 Mass Ave, Cambridge, MA 02139, USA.  */#include "defs.h"#include "frame.h"#include "inferior.h"static FILE *stream;		/* Output goes here */static void print_addr();static void ctrl();static void cobr();static void reg();static int mem();static void ea();static void dstop();static void regop();static void invalid();static int pinsn();static void put_abs();/* Print the i960 instruction at address 'memaddr' in debugged memory,   on stream 's'.  Returns length of the instruction, in bytes.  */intprint_insn( memaddr, s )    CORE_ADDR memaddr;    FILE *s;{	unsigned int word1, word2;	stream = s;	word1 = read_memory_integer( memaddr, 4 );	word2 = read_memory_integer( memaddr+4, 4 );	return pinsn( memaddr, word1, word2 );}/* Read the i960 instruction at 'memaddr' and return the address of    the next instruction after that, or 0 if 'memaddr' is not the   address of a valid instruction.  The first word of the instruction   is stored at 'pword1', and the second word, if any, is stored at   'pword2'.  */CORE_ADDRnext_insn (memaddr, pword1, pword2)     unsigned long *pword1, *pword2;     CORE_ADDR memaddr;{  int len;  unsigned long buf[2];  /* Read the two (potential) words of the instruction at once,     to eliminate the overhead of two calls to read_memory ().     TODO: read more instructions at once and cache them.  */  read_memory (memaddr, buf, sizeof (buf));  *pword1 = buf[0];  SWAP_TARGET_AND_HOST (pword1, sizeof (long));  *pword2 = buf[1];  SWAP_TARGET_AND_HOST (pword2, sizeof (long));  /* Divide instruction set into classes based on high 4 bits of opcode*/  switch ((*pword1 >> 28) & 0xf)    {    case 0x0:    case 0x1:	/* ctrl */    case 0x2:    case 0x3:	/* cobr */    case 0x5:    case 0x6:    case 0x7:	/* reg */      len = 4;      break;    case 0x8:    case 0x9:    case 0xa:    case 0xb:    case 0xc:      len = mem (memaddr, *pword1, *pword2, 1);      break;    default:	/* invalid instruction */      len = 0;      break;    }  if (len)    return memaddr + len;  else    return 0;}#define IN_GDB/***************************************************************************** *	All code below this point should be identical with that of *	the disassembler in gdmp960. *****************************************************************************/struct tabent {	char	*name;	char	numops;};static intpinsn( memaddr, word1, word2 )    unsigned long memaddr;    unsigned long word1, word2;{	int instr_len;	instr_len = 4;	put_abs( word1, word2 );	/* Divide instruction set into classes based on high 4 bits of opcode*/	switch ( (word1 >> 28) & 0xf ){	case 0x0:	case 0x1:		ctrl( memaddr, word1, word2 );		break;	case 0x2:	case 0x3:		cobr( memaddr, word1, word2 );		break;	case 0x5:	case 0x6:	case 0x7:		reg( word1 );		break;	case 0x8:	case 0x9:	case 0xa:	case 0xb:	case 0xc:		instr_len = mem( memaddr, word1, word2, 0 );		break;	default:		/* invalid instruction, print as data word */ 		invalid( word1 );		break;	}	return instr_len;}/****************************************//* CTRL format				*//****************************************/static voidctrl( memaddr, word1, word2 )    unsigned long memaddr;    unsigned long word1, word2;{	int i;	static struct tabent ctrl_tab[] = {		NULL,		0,	/* 0x00 */		NULL,		0,	/* 0x01 */		NULL,		0,	/* 0x02 */		NULL,		0,	/* 0x03 */		NULL,		0,	/* 0x04 */		NULL,		0,	/* 0x05 */		NULL,		0,	/* 0x06 */		NULL,		0,	/* 0x07 */		"b",		1,	/* 0x08 */		"call",		1,	/* 0x09 */		"ret",		0,	/* 0x0a */		"bal",		1,	/* 0x0b */		NULL,		0,	/* 0x0c */		NULL,		0,	/* 0x0d */		NULL,		0,	/* 0x0e */		NULL,		0,	/* 0x0f */		"bno",		1,	/* 0x10 */		"bg",		1,	/* 0x11 */		"be",		1,	/* 0x12 */		"bge",		1,	/* 0x13 */		"bl",		1,	/* 0x14 */		"bne",		1,	/* 0x15 */		"ble",		1,	/* 0x16 */		"bo",		1,	/* 0x17 */		"faultno",	0,	/* 0x18 */		"faultg",	0,	/* 0x19 */		"faulte",	0,	/* 0x1a */		"faultge",	0,	/* 0x1b */		"faultl",	0,	/* 0x1c */		"faultne",	0,	/* 0x1d */		"faultle",	0,	/* 0x1e */		"faulto",	0,	/* 0x1f */	};	i = (word1 >> 24) & 0xff;	if ( (ctrl_tab[i].name == NULL) || ((word1 & 1) != 0) ){		invalid( word1 );		return;	}	fputs_filtered( ctrl_tab[i].name, stream );	if ( word1 & 2 ){		/* Predicts branch not taken */		fputs_filtered ( ".f", stream );	}	if ( ctrl_tab[i].numops == 1 ){		/* EXTRACT DISPLACEMENT AND CONVERT TO ADDRESS */		word1 &= 0x00ffffff;		if ( word1 & 0x00800000 ){		/* Sign bit is set */			word1 |= (-1 & ~0xffffff);	/* Sign extend */		}		fputs_filtered ( "\t", stream );		print_addr( word1 + memaddr );	}}/****************************************//* COBR format				*//****************************************/static voidcobr( memaddr, word1, word2 )    unsigned long memaddr;    unsigned long word1, word2;{	int src1;	int src2;	int i;	static struct tabent cobr_tab[] = {		"testno",	1,	/* 0x20 */		"testg",	1,	/* 0x21 */		"teste",	1,	/* 0x22 */		"testge",	1,	/* 0x23 */		"testl",	1,	/* 0x24 */		"testne",	1,	/* 0x25 */		"testle",	1,	/* 0x26 */		"testo",	1,	/* 0x27 */		NULL,		0,	/* 0x28 */		NULL,		0,	/* 0x29 */		NULL,		0,	/* 0x2a */		NULL,		0,	/* 0x2b */		NULL,		0,	/* 0x2c */		NULL,		0,	/* 0x2d */		NULL,		0,	/* 0x2e */		NULL,		0,	/* 0x2f */		"bbc",		3,	/* 0x30 */		"cmpobg",	3,	/* 0x31 */		"cmpobe",	3,	/* 0x32 */		"cmpobge",	3,	/* 0x33 */		"cmpobl",	3,	/* 0x34 */		"cmpobne",	3,	/* 0x35 */		"cmpoble",	3,	/* 0x36 */		"bbs",		3,	/* 0x37 */		"cmpibno",	3,	/* 0x38 */		"cmpibg",	3,	/* 0x39 */		"cmpibe",	3,	/* 0x3a */		"cmpibge",	3,	/* 0x3b */		"cmpibl",	3,	/* 0x3c */		"cmpibne",	3,	/* 0x3d */		"cmpible",	3,	/* 0x3e */		"cmpibo",	3,	/* 0x3f */	};	i = ((word1 >> 24) & 0xff) - 0x20;	if ( cobr_tab[i].name == NULL ){		invalid( word1 );		return;	}	fputs( cobr_tab[i].name, stream );	if ( word1 & 2 ){		/* Predicts branch not taken */		fputs_filtered ( ".f", stream );	}	fputs_filtered ( "\t", stream, 0 );	src1 = (word1 >> 19) & 0x1f;	src2 = (word1 >> 14) & 0x1f;	if ( word1 & 0x02000 ){		/* M1 is 1 */		fprintf_filtered ( stream, "%d", src1 );	} else {			/* M1 is 0 */		fputs_filtered ( reg_names[src1], stream );	}	if ( cobr_tab[i].numops > 1 ){		if ( word1 & 1 ){		/* S2 is 1 */			fprintf_filtered ( stream, ",sf%d,", src2 );		} else {			/* S1 is 0 */			fprintf_filtered ( stream, ",%s,", reg_names[src2] );		}		/* Extract displacement and convert to address		 */		word1 &= 0x00001ffc;		if ( word1 & 0x00001000 ){	/* Negative displacement */			word1 |= (-1 & ~0x1fff);	/* Sign extend */		}		print_addr( memaddr + word1 );	}}/****************************************//* MEM format				*//****************************************/static int				/* returns instruction length: 4 or 8 */mem( memaddr, word1, word2, noprint )    unsigned long memaddr;    unsigned long word1, word2;    int noprint;		/* If TRUE, return instruction length, but				   don't output any text.  */{	int i, j;	int len;	int mode;	int offset;	const char *reg1, *reg2, *reg3;	/* This lookup table is too sparse to make it worth typing in, but not	 * so large as to make a sparse array necessary.  We allocate the	 * table at runtime, initialize all entries to empty, and copy the	 * real ones in from an initialization table.	 *	 * NOTE: In this table, the meaning of 'numops' is:	 *	 1: single operand	 *	 2: 2 operands, load instruction	 *	-2: 2 operands, store instruction	 */	static struct tabent *mem_tab = NULL;	static struct { int opcode; char *name; char numops; } mem_init[] = {#define MEM_MIN	0x80		0x80,	"ldob",	 2,		0x82,	"stob",	-2,		0x84,	"bx",	 1,		0x85,	"balx",	 2,		0x86,	"callx", 1,		0x88,	"ldos",	 2,		0x8a,	"stos",	-2,		0x8c,	"lda",	 2,		0x90,	"ld",	 2,		0x92,	"st",	-2,		0x98,	"ldl",	 2,		0x9a,	"stl",	-2,		0xa0,	"ldt",	 2,		0xa2,	"stt",	-2,		0xb0,	"ldq",	 2,		0xb2,	"stq",	-2,		0xc0,	"ldib",	 2,		0xc2,	"stib",	-2,		0xc8,	"ldis",	 2,		0xca,	"stis",	-2,#define MEM_MAX	0xca#define MEM_SIZ	((MEM_MAX-MEM_MIN+1) * sizeof(struct tabent))		0,	NULL,	0	};	if ( mem_tab == NULL ){		mem_tab = (struct tabent *) xmalloc( MEM_SIZ );		bzero( mem_tab, MEM_SIZ );		for ( i = 0; mem_init[i].opcode != 0; i++ ){			j = mem_init[i].opcode - MEM_MIN;			mem_tab[j].name = mem_init[i].name;			mem_tab[j].numops = mem_init[i].numops;		}	}	i = ((word1 >> 24) & 0xff) - MEM_MIN;	mode = (word1 >> 10) & 0xf;	if ( (mem_tab[i].name != NULL)		/* Valid instruction */	&&   ((mode == 5) || (mode >=12)) ){	/* With 32-bit displacement */		len = 8;	} else {		len = 4;	}	if ( noprint ){		return len;	}	if ( (mem_tab[i].name == NULL) || (mode == 6) ){		invalid( word1 );		return len;	}	fprintf_filtered ( stream, "%s\t", mem_tab[i].name );	reg1 = reg_names[ (word1 >> 19) & 0x1f ];	/* MEMB only */	reg2 = reg_names[ (word1 >> 14) & 0x1f ];	reg3 = reg_names[ word1 & 0x1f ];		/* MEMB only */	offset = word1 & 0xfff;				/* MEMA only  */	switch ( mem_tab[i].numops ){	case 2: /* LOAD INSTRUCTION */		if ( mode & 4 ){			/* MEMB FORMAT */			ea( memaddr, mode, reg2, reg3, word1, word2 );			fprintf_filtered ( stream, ",%s", reg1 );		} else {				/* MEMA FORMAT */			fprintf( stream, "0x%x", offset );			if (mode & 8) {				fprintf_filtered ( stream, "(%s)", reg2 );			}			fprintf_filtered ( stream, ",%s", reg1 );		}		break;	case -2: /* STORE INSTRUCTION */		if ( mode & 4 ){			/* MEMB FORMAT */			fprintf_filtered ( stream, "%s,", reg1 );			ea( memaddr, mode, reg2, reg3, word1, word2 );		} else {				/* MEMA FORMAT */			fprintf_filtered ( stream, "%s,0x%x", reg1, offset );			if (mode & 8) {				fprintf_filtered ( stream, "(%s)", reg2 );			}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -