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

📄 mpc.c

📁 Coldfire MCF5282 DBug bootloader
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
 * File:		mpc.c
 * Purpose:		PowerPC assembly and disassembly.
 *
 * Notes:
 *
 */

#include "src/include/dbug.h"
#include "src/uif/cpu.h"
#include "src/uif/sym.h"

/********************************************************************/

#define SYMBOL_TABLE

#define REG_INT		(1)
#define REG_FLOAT	(2)

#define EA_OFFSET	(30)	/* offset before appending EA */
static const char
COMMA[] = ",";

typedef struct
{
	uint32	keepers;
	uint32	match;
	char	*instruction;
	void	(*dishandler)(unsigned int);
	int		(*asmhandler)(void);
} INSTRENTRY;

extern const
INSTRENTRY isa[];

/********************************************************************/

static char
dstr[80];

static ADDRESS
disasm_pc;

static int
valid_instruction;

static INSTRUCTION
asm_insn;

static ADDRESS
asm_pc;

/********************************************************************/

#define append_string(a,b)	strcat(a,b)

/********************************************************************/
static uint32
get_gpr(int gpr)
{
	extern REGISTERS context;

	switch (gpr)
	{
		case 0: return context.r0; break;
		case 1: return context.r1; break;
		case 2: return context.r2; break;
		case 3: return context.r3; break;
		case 4: return context.r4; break;
		case 5: return context.r5; break;
		case 6: return context.r6; break;
		case 7: return context.r7; break;
		case 8: return context.r8; break;
		case 9: return context.r9; break;
		case 10: return context.r10; break;
		case 11: return context.r11; break;
		case 12: return context.r12; break;
		case 13: return context.r13; break;
		case 14: return context.r14; break;
		case 15: return context.r15; break;
		case 16: return context.r16; break;
		case 17: return context.r17; break;
		case 18: return context.r18; break;
		case 19: return context.r19; break;
		case 20: return context.r20; break;
		case 21: return context.r21; break;
		case 22: return context.r22; break;
		case 23: return context.r23; break;
		case 24: return context.r24; break;
		case 25: return context.r25; break;
		case 26: return context.r26; break;
		case 27: return context.r27; break;
		case 28: return context.r28; break;
		case 29: return context.r29; break;
		case 30: return context.r30; break;
		case 31: return context.r31; break;
		default:
			return 0; break;
	}
}

/********************************************************************/
static void
append_eastr (char *buf, uint32 ea)
{
	char eastr[20];
	int index;

	/* Pad out to EA_OFFSET */
	for (index = strlen(buf); index < EA_OFFSET; ++index)
		append_string(buf," ");

	sprintf(eastr,"(EA: %08X)", ea);
	append_string(buf,eastr);
}

/********************************************************************/
static void
append_ea_rA_0_d (char *buf, int d, int rA)
{
	/*
	 * EA = (rA|0) + d
	 */
	uint32 ea;

	if (rA == 0)
		ea = 0;
	else
		ea = get_gpr(rA);

	if (d < 0)
		ea -= (~d+1);
	else
		ea += d;

	append_eastr(buf,ea);
}

/********************************************************************/
static void
append_ea_rA_d (char *buf, int d, int rA)
{
	/*
	 * EA = (rA) + d
	 */
	uint32 ea;

	ea = get_gpr(rA);

	if (d < 0)
		ea -= (~d+1);
	else
		ea += d;

	append_eastr(buf,ea);
}

/********************************************************************/
static void
append_ea_rA_0_rB (char *buf, int rA, int rB)
{
	/*
	 * EA = (rA|0) + (rB)
	 */
	uint32 ea;

	if (rA == 0)
		ea = 0;
	else
		ea = get_gpr(rA);

	ea += get_gpr(rB);

	append_eastr(buf,ea);
}

/********************************************************************/
static void
append_ea_rA_rB (char *buf, int rA, int rB)
{
	/*
	 * EA = (rA) + (rB)
	 */
	uint32 ea;
	
	ea = get_gpr(rA) + get_gpr(rB);

	append_eastr(buf,ea);
}

/********************************************************************/
static void
append_instruction (char *buf, char *instruction)
{
	sprintf(buf,"%-10s",instruction);
}

/********************************************************************/
static void
append_Xbit_number (char *buf, int opword, int bits, int offset)
{
	/*
	 * This field accepts `opword' and then determines according
	 * to the offsets what size 'bit' number is.
	 * The number is then concatenated to the end of the
	 * disasm_stmt.
	 *
	 * The `offset' is given by the bit number as listed in the
	 * PowerPC Microprocessor Family: Programming Environments, Ch. 8
	 * (Bit 0 is on the left, bit 31/63 is on the right)
	 */
	unsigned int i, mask;
	char regnum[15];

	/*
	 * Determine register number.  The offset is the bit number of the
	 * left-most bit of the X-bit register field.
	 */
	mask = 0x80000000;
	for (i = 0; i < bits; i++)
	{
		mask = (mask >> 1) | 0x80000000;
	}
	for (i = 0; i < offset; i++)
	{
		mask = mask >> 1;
	}
	i = (opword & mask) >> (31-(offset+bits-1));
	sprintf(regnum,"%d",i);
	strcat(buf,regnum);
}

/********************************************************************/
static int
append_register (char *buf, int opword, int reg, int offset)
{
	/*
	 * This field accepts `opword' and then determines according
	 * to the offsets which register (r0 .. r31) is specified.
	 * The register name is then concatenated to the end of the
	 * disasm_stmt.
	 *
	 * The `offset' is given by the bit number as listed in the
	 * PowerPC Microprocessor Family: Programming Environments, Ch. 8
	 * (Bit 0 is on the left, bit 31/63 is on the right)
	 *
	 * This routine also returns the register number.
	 */
	unsigned int i, mask;
	char regnum[5];

	/*
	 * Determine register number.  The offset is the bit number of the
	 * left-most bit of the 5-bit register field.
	 */
#if 0
	mask = 0xF8000000;	/* 5 bits */
	for (i = 0; i < offset; i++)
	{
		mask = mask >> 1;
	}
#else
	mask = (0xF8000000 >> offset);
#endif
	i = (opword & mask) >> (31-(offset+5-1));

	if (buf != NULL)
	{
		switch (reg)
		{
			case REG_FLOAT:
				sprintf(regnum,"f%d",i);
				break;
			case REG_INT:
			default:
				sprintf(regnum,"r%d",i);
				break;
		}
		strcat(buf,regnum);
	}

	return i;
}

/********************************************************************/
static void
append_value (char *buf, unsigned int value, int size)
{
	char vbuf[10];
	switch (size)
	{
		case 16:
			sprintf(vbuf,"0x%04X",value & 0x0000FFFF);
			break;
		case 32:
		default:
			sprintf(vbuf,"0x%08X",value);
			break;
	}
	append_string(buf,vbuf);
}

/********************************************************************/
static void
func (unsigned int opword)
{
	/* The instruction name has already been printed. */

	(void)opword;
}

/********************************************************************/
static void
func1 (unsigned int opword)
{
	append_register(dstr,opword,REG_INT,6);
	append_string(dstr,COMMA);
	append_register(dstr,opword,REG_INT,11);
	append_string(dstr,COMMA);
	append_register(dstr,opword,REG_INT,16);
}

/********************************************************************/
static void
func2 (unsigned int opword)
{
	append_register(dstr,opword,REG_INT,6);
	append_string(dstr,COMMA);
	append_register(dstr,opword,REG_INT,11);
	append_string(dstr,COMMA);
	append_value(dstr,opword & 0x0000FFFF,16);
}

/********************************************************************/
static void
func3 (unsigned int opword)
{
	append_register(dstr,opword,REG_INT,6);
	append_string(dstr,COMMA);
	append_register(dstr,opword,REG_INT,11);
}

/********************************************************************/
static void
func4 (unsigned int opword)
{
	append_register(dstr,opword,REG_INT,11);
	append_string(dstr,COMMA);
	append_register(dstr,opword,REG_INT,6);
	append_string(dstr,COMMA);
	append_register(dstr,opword,REG_INT,16);
}

/********************************************************************/
static void
func5 (unsigned int opword)
{
	append_register(dstr,opword,REG_INT,11);
	append_string(dstr,COMMA);
	append_register(dstr,opword,REG_INT,6);
	append_string(dstr,COMMA);
	append_value(dstr,opword & 0x0000FFFF,16);
}

/********************************************************************/
static void
func6 (unsigned int opword)
{
	uint32 li;
	uint32 target;
	char sstr[40];

	li = opword & 0x03FFFFFC;
	if (li & 0x02000000)
	{
		/* sign extend */
		li = li | 0xFC000000;
	}

	if (0x00000002 & opword)
	{
		/* AA = 1 */
		target = li;
	}
	else
	{
		/* AA = 0 */
		target = (uint32)disasm_pc + li;
	}

#ifdef SYMBOL_TABLE
	if (symtab_convert_address(target,sstr))
	{
		append_string(dstr,sstr);
	}
	else
	{
		append_value(dstr,target,32);
	}
#else
	append_value(dstr,target,32);
#endif
}

/********************************************************************/
static void
func7 (unsigned int opword)
{
	int bd;
	unsigned int target;

	append_Xbit_number(dstr,opword,5,6);
	append_string(dstr,COMMA);
	append_Xbit_number(dstr,opword,5,11);
	append_string(dstr,COMMA);

	bd = opword & 0x0000FFFC;
	if (bd & 0x00008000)
	{
		/* sign extend */
		bd = bd | 0xFFFF0000;
	}

	if (0x00000002 & opword)
	{
		/* AA = 1 */
		target = (unsigned int)bd;
	}
	else
	{
		/* AA = 0 */
		target = (unsigned int)((int)disasm_pc + (int)bd);
	}
	append_value(dstr,target,32);
}

/********************************************************************/
static void
func8 (unsigned int opword)
{
	append_Xbit_number(dstr,opword,5,6);
	append_string(dstr,COMMA);
	append_Xbit_number(dstr,opword,5,11);
}

/********************************************************************/
static void
func9 (unsigned int opword)
{
	append_Xbit_number(dstr,opword,3,6);
	append_string(dstr,COMMA);
	if (opword & 0x00200000)
	{
		append_string(dstr,"1");
	}
	else
	{
		append_string(dstr,"0");
	}
	append_string(dstr,COMMA);
	append_register(dstr,opword,REG_INT,11);
	append_string(dstr,COMMA);
	append_register(dstr,opword,REG_INT,16);
}

/********************************************************************/
static void
func10 (unsigned int opword)
{
	append_Xbit_number(dstr,opword,3,6);
	append_string(dstr,COMMA);
	if (opword & 0x00200000)
	{
		append_string(dstr,"1");
	}
	else
	{
		append_string(dstr,"0");
	}
	append_string(dstr,COMMA);
	append_register(dstr,opword,REG_INT,11);
	append_string(dstr,COMMA);
	append_value(dstr,opword & 0x0000FFFF,16);
}

/********************************************************************/
static void
func11 (unsigned int opword)
{
	append_register(dstr,opword,REG_INT,11);
	append_string(dstr,COMMA);
	append_register(dstr,opword,REG_INT,6);
}

/********************************************************************/
static void
func12 (unsigned int opword)
{
	append_Xbit_number(dstr,opword,5,6);
	append_string(dstr,COMMA);
	append_Xbit_number(dstr,opword,5,11);
	append_string(dstr,COMMA);
	append_Xbit_number(dstr,opword,5,16);
}

/********************************************************************/
static void
func13 (unsigned int opword)
{
	int rA, rB;
	rA = append_register(dstr,opword,REG_INT,11);
	append_string(dstr,COMMA);
	rB = append_register(dstr,opword,REG_INT,16);
	append_ea_rA_rB(dstr, rA, rB);
}

/********************************************************************/
static void
func14 (unsigned int opword)
{
	append_register(dstr,opword,REG_FLOAT,6);
	append_string(dstr,COMMA);
	append_register(dstr,opword,REG_FLOAT,16);
}

/********************************************************************/
static void
func15 (unsigned int opword)
{
	append_register(dstr,opword,REG_FLOAT,6);
	append_string(dstr,COMMA);
	append_register(dstr,opword,REG_FLOAT,11);
	append_string(dstr,COMMA);
	append_register(dstr,opword,REG_FLOAT,16);
}

/********************************************************************/
static void
func16 (unsigned int opword)
{
	append_Xbit_number(dstr,opword,3,6);
	append_string(dstr,COMMA);
	append_register(dstr,opword,REG_FLOAT,11);
	append_string(dstr,COMMA);
	append_register(dstr,opword,REG_FLOAT,16);
}

/********************************************************************/
static void
func17 (unsigned int opword)
{
	append_register(dstr,opword,REG_FLOAT,6);
	append_string(dstr,COMMA);
	append_register(dstr,opword,REG_FLOAT,16);
}

/********************************************************************/
static void
func18 (unsigned int opword)
{
	append_register(dstr,opword,REG_FLOAT,6);
	append_string(dstr,COMMA);
	append_register(dstr,opword,REG_FLOAT,11);
	append_string(dstr,COMMA);
	append_register(dstr,opword,REG_FLOAT,21);
	append_string(dstr,COMMA);
	append_register(dstr,opword,REG_FLOAT,16);
}

/********************************************************************/
static void
func19 (unsigned int opword)
{
	append_register(dstr,opword,REG_FLOAT,6);
	append_string(dstr,COMMA);
	append_register(dstr,opword,REG_FLOAT,11);
	append_string(dstr,COMMA);
	append_register(dstr,opword,REG_FLOAT,21);
}

/********************************************************************/
static void
insn_rD_d_rA (unsigned int opword, int *d, int *rA)
{
	/*
	 * Ex: lbz  rD,d(rA)
	 */
	char valstr[10];
	int disp;

	disp = opword & 0x0000FFFF;
	if (disp & 0x00008000)
	{
		disp = disp | 0xFFFF0000;
	}
	sprintf(valstr,"%d",disp);
	*d = disp;

	append_register(dstr,opword,REG_INT,6);
	append_string(dstr,COMMA);
	append_string(dstr,valstr);
	append_string(dstr,"(");
	*rA = append_register(dstr,opword,REG_INT,11);
	append_string(dstr,")");
}

/********************************************************************/
static void
insn_rD_rA_rB (unsigned int opword, int *rA, int *rB)
{
	/*
	 * Ex: lbzx  rD,rA,rB
	 */
	append_register(dstr,opword,REG_INT,6);
	append_string(dstr,COMMA);
	*rA = append_register(dstr,opword,REG_INT,11);
	append_string(dstr,COMMA);
	*rB = append_register(dstr,opword,REG_INT,16);
}

/********************************************************************/
static void
func20a (unsigned int opword)
{
	/*
	 * Ex: lbz  rD,d(rA), where EA = (rA|0) + d
	 */
	int d, rA;

	insn_rD_d_rA(opword, &d, &rA);
	append_ea_rA_0_d(dstr, d, rA);
}

⌨️ 快捷键说明

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