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

📄 utils.c

📁 m68k系列反汇编的C语言源码,供学习编译原理的同学使用。实用!
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *                 Author:  Christopher G. Phillips *              Copyright (C) 1994 All Rights Reserved * *                              NOTICE * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby granted * provided that the above copyright notice appear in all copies and * that both the copyright notice and this permission notice appear in * supporting documentation. * * The author makes no representations about the suitability of this * software for any purpose.  This software is provided ``as is'' * without express or implied warranty. *//* * Various utility functions including formatting effective addresses, * reading input (correctly!), and printing are here. */#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <string.h>#include <ctype.h>#include <math.h>#include <float.h>#include <limits.h>#include "dis.h"/* * Format immediate constant ``value'' into ``s''. */intimmsprintf(char *s, long value){	long	absvalue;	char	*sign;	if (pass == FIRSTPASS)		return 0;	if (value < 0) {		absvalue = -value;		sign = "-$";	} else {		absvalue = value;		sign = "$";	}	if (absvalue > 9 || value == LONG_MIN)		return sprintf(s, "%ld!%s%lx", value, sign, absvalue);	else		return sprintf(s, "%ld", value);}/* * Sign-extend ``value'' from a ``bits''-bit value to a long. */longsignextend(long value, int bits){	switch (bits) {	case 8:		value &= 0xff;		if (value & 0x80)			value |= ~0xffL;		break;	case 16:		value &= 0xffff;		if (value & 0x8000)			value |= ~0xffffL;		break;	case 32:		value &= 0xffffffff;		if (value & 0x80000000)			value |= ~0xffffffffL;		break;	}	return value;}char	instbuf[512];size_t	leninstbuf = 0;/* * Read a word from the input file.  Put its numerical value in *wp. */intnextword(m68kword *wp){	unsigned char	c[WORDSIZE];	size_t		i;	if (fread(c, 1, WORDSIZE, infp) == WORDSIZE) {		for (*wp = 0, i = 0; i < WORDSIZE; i++)			*wp += c[i] << (CHAR_BIT * (WORDSIZE - 1 - i));		pc += WORDSIZE;		curoffset += WORDSIZE;		for (i = 0; i < WORDSIZE; i++) {			sprintf(&instbuf[leninstbuf], "%0*x", WORDSIZE, c[i]);			leninstbuf += WORDSIZE;		}		return 0;	} else		return -1;}/* * Get a sign-extended value of type ``size'' from the input file. */longgetval(int size, int *failure){	m68kword	extra[2];	long		value;	if (nextword(&extra[0]) == -1) {		*failure = -1;		return 0;	}	switch (size) {	case BYTE:#if 0		if (extra[0] & 0xff00) {			*failure = -1;			return 0;		} else#endif		value = signextend(extra[0], 8);		break;	case WORD:		value = signextend(extra[0], 16);		break;	case LONGWORD:		if (nextword(&extra[1]) == -1) {			*failure = -1;			return 0;		}		value = signextend(((long)extra[0] << 16) | extra[1], 32);		break;	default:		*failure = -1;		return 0;		break;	}	*failure = 0;	return value;}/* * Translate scale bits to a scaling factor. */static intscale(int s){	switch (s) {	case 0:	return 1;	break;	case 1:	return 2;	break;	case 2:	return 4;	break;	case 3:	return 8;	break;	}	/* NOTREACHED */}/* * Format address register ``reg'' taking ``sp'' into account. */char *Areg(int reg){	static char	s[2] = "A0";	if (sp && reg == 7)		return "SP";	else {		s[1] = reg + '0';		return s;	}}/* * Format register ``reg''. */voidAreg2(char *s, char c, int reg){	if (c == 'A')		sprintf(s, "%2.2s", Areg(reg));	else		sprintf(s, "D%d", reg);}/* * Extended mode for extension words. * * The formatted text goes in ``s''. * Return 0 for success, negative for failure. */static intextended(char *s, const char *reg, int size){	m68kword	extra;	m68kaddr	bd;	m68kaddr	od;	m68kaddr	savedpc;	int		comma;	int		n = 0;	int		failure;	char		reg2[2];	savedpc = pc;	if (nextword(&extra) == -1)		return -1;	if (CPU(chip) < MC68020 || (extra & 0x0100) == 0) {		/* Brief format */		long	value;		/*		 * Format is as follows:		 *		 * Bits		Name		 * 15		Index register type (D/A, 0 if D)		 * 12-14	Index register number		 * 11		Index size (W/L, 0 if sign-extended word)		 * 9-10		Scale (00 = 1, 01 = 2, 10 = 4, 11 = 8)		 * 8		Must be 0		 * 0-7		Displacement		 */		if (CPU(chip) >= MC68020)			n += sprintf(s, "(");		value = (long)signextend(extra, 8);		if (strcmp(reg, "PC") == 0)			value += WORDSIZE;		n += immsprintf(s + n, value);		n += sprintf(s + n, "%s", (CPU(chip) < MC68020) ? "(" : ",");		Areg2(reg2, (extra & 0x8000) ? 'A' : 'D', (extra >> 12) & 7);		n += sprintf(s + n, "%s,%2.2s.%c", reg, reg2,		  (extra & 0x0800) ? 'L' : 'W');		if (CPU(chip) >= MC68020 && ((extra >> 9) & 3))			n += sprintf(s + n, "*%d", scale((extra >> 9) & 3));		n += sprintf(s + n, ")");	} else {		/* Full format */		/*		 * Format is as follows:		 *		 * Bits		Name		 * 15		Index register type (D/A, 0 if D)		 * 12-14	Index register number		 * 11		Index size (W/L, 0 if sign-extended word)		 * 9-10		Scale (00 = 1, 01 = 2, 10 = 4, 11 = 8)		 * 8		Must be 1		 * 7		Base suppress (1 if base register suppressed)		 * 6		Index suppress (1 if index register suppressed)		 * 4-5		Base displacement size (00 = reserved,				  01 = null, 10 = word, 11 = long)		 * 3		Must be 0		 * 0-2		Index/Indirect selection		 * I/IS combinations:		 *		 * IS	I/IS	Operation		 * 0	000	No memory indirection		 * 0	001	Indirect preindexed with null outer displacement		 * 0	010	Indirect preindexed with word od		 * 0	011	Indirect preindexed with long od		 * 0	101	Indirect postindexed with null od		 * 0	110	Indirect postindexed with word od		 * 0	111	Indirect postindexed with long od		 * 1	000	No memory indirection		 * 1	001	Memory indirect with null od		 * 1	010	Memory indirect with word od		 * 1	011	Memory indirect with long od		 */		/*		 * Get base displacement		 */		switch ((extra >> 4) & 3) {		case 0:			return -1;			break;		case 1:			bd = 0;			break;		case 2:			bd = getval(WORD, &failure);			if (failure)				return failure;			break;		case 3:			bd = getval(LONGWORD, &failure);			if (failure)				return failure;			break;		}		/*		 * Check if collapses to PC-relative		 */		if ((extra & 0x01cf) == 0x0140) {			if (pass == DCLABELSPASS) {				if (bd + savedpc >= initialpc				  && bd + savedpc <= initialpc + maxoffset) {					insts[bd + savedpc - initialpc].flags					  |= ISLABEL;					if (!insts[ppc - initialpc].size &&					  insts[ppc - initialpc].flags & ISFPU)						insts[bd + savedpc						  - initialpc].flags						  |= ftype2lis(size);				}			} else if (pass == FIRSTPASS && pcrelative) {				required[flags & 3] = bd + savedpc;				flags++;			} else if (pass == LASTPASS			  && bd + savedpc >= initialpc			  && bd + savedpc <= initialpc + maxoffset			  && insts[bd + savedpc - initialpc].labelnum)				sprintf(s, "L%d",				 insts[bd + savedpc - initialpc].labelnum);			else /* if ((pass == FIRSTPASS || pass == LASTPASS)			  && !pcrelative			  || pass == DEBUGPASS			  || pass == LASTPASS && pcrelative			  && bd + savedpc > initialpc + maxoffset) */ {				if (bd)					sprintf(s, "(%ld,PC)!$%lx", bd,					  bd + savedpc);				else					sprintf(s, "(PC)!$%lx", savedpc);			}			return 0;		}		switch (extra & 3) {		case 0: /* FALLTHROUGH */		case 1:			od = 0;			break;		case 2:			od = getval(WORD, &failure);			if (failure)				return failure;			break;		case 3:			od = getval(LONGWORD, &failure);			if (failure)				return failure;			break;		}		n += sprintf(s + n, "(");		if (extra & 3)			n += sprintf(s + n, "[");		if (comma = bd)			n += immsprintf(s + n, (long)bd);		if ((extra & 0x0080) == 0) {			/*			 * Base suppress is 0.			 */			if (comma)				n += sprintf(s + n, ",");			n += sprintf(s + n, "%s", reg);			comma = 1;		} else if (strcmp(reg, "PC") == 0) {			if (comma)				n += sprintf(s + n, ",");			n += sprintf(s + n, "ZPC");			comma = 1;		}		if (extra & 4) {			n += sprintf(s + n, "]");			comma = 1;		}		if ((extra & 0x0040) == 0) {			/*			 * Index suppress is 0.			 */			if ((extra & 7) == 4)				return -1;			if (comma)				n += sprintf(s + n, ",");			Areg2(reg2, (extra & 0x8000) ? 'A' : 'D',			  (extra >> 12) & 7);			n += sprintf(s + n, "%2.2s.%c", reg2,			  (extra & 0x0800) ? 'L' : 'W');			if ((extra >> 9) & 3)				n += sprintf(s + n, "*%d",				  scale((extra >> 9) & 3));		} else if (extra & 4)			return -1;		if ((extra & 3) && (extra & 4) == 0) {			n += sprintf(s + n, "]");			comma = 1;		}		if (od) {			if (comma)				n += sprintf(s + n, ",");			n += immsprintf(s + n, (long)od);		}		if (n) {			if (s[n - 1] != '(')				n += sprintf(s + n, ")");			else {				s[n - 1] = '\0';				if (--n == 0)					sprintf(s, "0");			}		} else			sprintf(s, "0");	}	return 0;}/* * The next few functions convert hexadecimal nibble values * to a floating-point value (and format it). */#define BIT(p,n)        ((p)[(n) / 32] & (1UL << (32 - (n) % 32 - 1)))/* * Is the mantissa zero? */static intzeromantissa(u32bit_t *p, size_t firstbit, size_t lastbit){	size_t	bit;	for (bit = firstbit; bit <= lastbit; bit++)		if (BIT(p, bit))			return 0;	return 1;}/* * Convert the input data in *lwp from bits ``firstbit'' to ``lastbit'' * into a mantissa.  Note that the *highest* bit is considered bit 0 here. */static doublestod(u32bit_t *lwp, size_t firstbit, size_t lastbit){	double		result = 1.0;	double		value = 0.5;	size_t		bit;	for (bit = firstbit; bit <= lastbit && value; bit++) {		if (BIT(lwp, bit))			result += value;		value /= 2.0;	}	return result;}/* * Convert the input data in *longwords into a floating-point value * of floating-point type ``type'' and place a human-readable version in ``s''. * Return -1 if NaN or Denormalized, else 0. */intfpoint(u32bit_t *longwords, int type, char *s){	short	exponent;	short	sign;	short	zero;	short	maxexp;	short	minexp;	size_t	firstbit;	size_t	lastbit;	int	rval = 0;	/* return -1 if NaN or Denormalized */	/* These are for PACKED */	short	mantissa[17];	short	lastnonzero;	short	firstnonzero;	size_t	i;	sign = (longwords[0] & 0x80000000) != 0;	switch (type) {	case SINGLE:		/*		 * Format:		 *		 * 1 bit	sign		 * 8 bits	exponent (biased by 0x7f)		 * 23 bits	mantissa (implicit leading bit		 *			  left of implied binary point)		 */		exponent = ((longwords[0] >> (32 - (8+1))) & 0xff) - 0x7f;		firstbit = 31 - 22;		lastbit = 31;		zero = zeromantissa(longwords, firstbit, lastbit);		maxexp = 0x80;		minexp = -0x7f;		break;	case DOUBLE:		/*		 * Format:		 *		 * 1 bit	sign		 * 11 bits	exponent (biased by 0x3ff)		 * 52 bits	mantissa (implicit leading bit		 *			  left of implied binary point)		 */		exponent = ((longwords[0] >> (32 - (11+1))) & 0x7ff) - 0x3ff;		firstbit = 63 - 51;

⌨️ 快捷键说明

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