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

📄 reformat.c

📁 < 虚拟机设计与实现> 的source code, linux版本
💻 C
📖 第 1 页 / 共 2 页
字号:
/*************************************************************
* 由于认为bill 的reformat程序写法存在问题,按照他的写法可能存在越界问题,
* 因此我按照自己的设想在他的基础上稍为修改了一下。
* chenyong 2007.04.14

* 一个奇怪的问题:如果将 "iset.h"挪到reformat.h中就会出现奇怪的编译错误。 :-(
**************************************************************/

#include "reformat.h"
#include "iset.h"
#include "exenv.h"

void badIntReg(U1 arg, U8 currentbyte);		
void badFltReg(U1 arg, U8 currentbyte);
void badDblReg(U1 arg, U8 currentbyte);	

void checkAddress(U1 *arr, U8 cb); 

/* make sure don't have incomplete instruction*/
void checkCurrentByte(U8 cb, U8 end);

/*
	re-format bytecode numeric operands to native 
	( prevents redundant runtime work ).

	This also performs verification to make sure that:
	1) instruction opcodes are valid
	2) register arguments are actual registers of necessary type
	3) immediate address values are in range [ 0 , $TOP ]
	4) Haven't prematurely hit end of bytecode instruction
*/

U1 reformat()
{
	U8 current_byte;
	U8 stop;

	current_byte = 0;
	stop = R[$HS];

	DBG_FMT0("initiating reformat\n\n");
	DBG_FMT_PU8("starting at address->", current_byte);
	DBG_FMT_PU8("stop address->", stop);

	while (current_byte < stop)
	{
		switch (RAM[current_byte])
		{
		case LBI:	/* LBI $r1, byte_constant  BBB */
			DBG_FMT1("opcode %s\n", I_Set[RAM[current_byte]]);
				
			checkCurrentByte(current_byte + 1, stop);
			if (nErrors > 0)
				return FALSE;
			current_byte++;
			badIntReg(RAM[current_byte], current_byte);
			if (nErrors > 0)
				return FALSE;
			DBG_FMT1("operand %s\n", R_STR[RAM[current_byte]]);
				
			checkCurrentByte(current_byte + 1, stop);
			if (nErrors > 0)
				return FALSE;
			current_byte++;
            DBG_FMT1("byte %d\n\n", (S1)RAM[current_byte]);
				
			current_byte = current_byte++;
			break;
			
		case LWI:	/* LWI $r1, word_constant  BBW */
			DBG_FMT1("opcode %s\n", I_Set[RAM[current_byte]]);
				
			checkCurrentByte(current_byte + 1, stop);
			if (nErrors > 0)
				return FALSE;
			current_byte++;
			badIntReg(RAM[current_byte], current_byte);
			if (nErrors > 0)
				return FALSE;
			DBG_FMT1("operand %s\n", R_STR[RAM[current_byte]]);

			checkCurrentByte(current_byte + 2, stop);
			if (nErrors > 0)
				return FALSE;
			current_byte++;
			FORMAT_WORD(RAM, current_byte);
			DBG_FMT1("word %hd\n\n", *((S2 *)&RAM[current_byte]));

			current_byte = current_byte + 2;
			break;
			
		case LDI:	/* LDI $r1, dword_constant  BBD */
			DBG_FMT1("opcode %s\n", I_Set[RAM[current_byte]]);
				
			checkCurrentByte(current_byte + 1, stop);
			if (nErrors > 0)
				return FALSE;
			current_byte++;
			badIntReg(RAM[current_byte], current_byte);
			if (nErrors > 0)
				return FALSE;
			DBG_FMT1("operand %s\n", R_STR[RAM[current_byte]]);

			checkCurrentByte(current_byte + 4, stop);
			if (nErrors > 0)
				return FALSE;
			current_byte++;
			FORMAT_DWORD(RAM, current_byte);
			DBG_FMT1("dword %ld\n\n", *((S4 *)&RAM[current_byte]));

			current_byte = current_byte + 4;
			break;
	
		case LQI:	/* LQI $r1, qword_constant  BBQ*/
			DBG_FMT1("opcode %s\n", I_Set[RAM[current_byte]]);
				
			checkCurrentByte(current_byte + 1, stop);
			if (nErrors > 0)
				return FALSE;
			current_byte++;
			badIntReg(RAM[current_byte], current_byte);
			if (nErrors > 0)
				return FALSE;
			DBG_FMT1("operand %s\n", R_STR[RAM[current_byte]]);

			checkCurrentByte(current_byte + 8, stop);
			if (nErrors > 0)
				return FALSE;
			current_byte++;
			FORMAT_QWORD(RAM, current_byte);
			DBG_FMT_PS8("qword ", *((S8 *)&RAM[current_byte]));

			current_byte = current_byte + 8;
			break;
			
		case LF1I:	/* LF1I $f1, float_constant  BBD */
			DBG_FMT1("opcode %s\n", I_Set[RAM[current_byte]]);
				
			checkCurrentByte(current_byte + 1, stop);
			if (nErrors > 0)
				return FALSE;
			current_byte++;
			badFltReg(RAM[current_byte], current_byte);
			if (nErrors > 0)
				return FALSE;
			DBG_FMT1("operand %s\n", Rf_STR[RAM[current_byte]]);

			checkCurrentByte(current_byte + 4, stop);
			if (nErrors > 0)
				return FALSE;
			current_byte++;
			FORMAT_DWORD(RAM, current_byte);
			DBG_FMT1("float %g\n\n", *((F4 *)&RAM[current_byte]));

			current_byte = current_byte + 4;
			break;
			
		case LF2I:	/* LQI $d1, double_constant  BBQ*/
			DBG_FMT1("opcode %s\n", I_Set[RAM[current_byte]]);
				
			checkCurrentByte(current_byte + 1, stop);
			if (nErrors > 0)
				return FALSE;
			current_byte++;
			badDblReg(RAM[current_byte], current_byte);
			if (nErrors > 0)
				return FALSE;
			DBG_FMT1("operand %s\n", Rd_STR[RAM[current_byte]]);

			checkCurrentByte(current_byte + 8, stop);
			if (nErrors > 0)
				return FALSE;
			current_byte++;
			FORMAT_QWORD(RAM, current_byte);
			DBG_FMT1("float %g\n\n", *((F8 *)&RAM[current_byte]));

			current_byte = current_byte + 8;
			break;
			
		case LAD:	/* LAD $r1, address = BBQ */ 
			DBG_FMT1("opcode %s\n", I_Set[RAM[current_byte]]);
				
			checkCurrentByte(current_byte + 1, stop);
			if (nErrors > 0)
				return FALSE;
			current_byte++;
			badIntReg(RAM[current_byte], current_byte);
			if (nErrors > 0)
				return FALSE;
			DBG_FMT1("operand %s\n", R_STR[RAM[current_byte]]);

			checkCurrentByte(current_byte + 8, stop);
			if (nErrors > 0)
				return FALSE;
			current_byte++;
			FORMAT_QWORD(RAM, current_byte);
			checkAddress(RAM, current_byte);
			if (nErrors > 0)
				return FALSE;
			DBG_FMT_PU8("address ", *((U8 *)&RAM[current_byte]));

			current_byte = current_byte + 8;
			break;
			
		case LAI:   /* LAI $r1, $r2, qword     BBBQ*/
			DBG_FMT1("opcode %s\n", I_Set[RAM[current_byte]]);
				
			checkCurrentByte(current_byte + 1, stop);
			if (nErrors > 0)
				return FALSE;
			current_byte++;
			badIntReg(RAM[current_byte], current_byte);
			if (nErrors > 0)
				return FALSE;
			DBG_FMT1("operand %s\n", R_STR[RAM[current_byte]]);

			checkCurrentByte(current_byte + 1, stop);
			if (nErrors > 0)
				return FALSE;
			current_byte++;
			badIntReg(RAM[current_byte], current_byte);
			if (nErrors > 0)
				return FALSE;
			DBG_FMT1("operand %s\n", R_STR[RAM[current_byte]]);

			checkCurrentByte(current_byte + 8, stop);
			if (nErrors > 0)
				return FALSE;
			current_byte++;
			FORMAT_QWORD(RAM, current_byte);
			DBG_FMT_PS8("qword ", *((S8 *)&RAM[current_byte]));

			current_byte = current_byte + 8;
			break;
			
		case LB:	/* LB $r1,$r2	BBB */
		case LW:
		case LD:
		case LQ:
		case SB:	/* SB $r1,$r2   BBB*/ 
		case SW:
		case SD:
		case SQ:
		case MOV:	/* MOV $r1, $r2    BBB */
		case NOT:  
		case BS:
			DBG_FMT1("opcode %s\n", I_Set[RAM[current_byte]]);
				
			checkCurrentByte(current_byte + 1, stop);
			if (nErrors > 0)
				return FALSE;
			current_byte++;
			badIntReg(RAM[current_byte], current_byte);
			if (nErrors > 0)
				return FALSE;
			DBG_FMT1("operand %s\n", R_STR[RAM[current_byte]]);
				
			checkCurrentByte(current_byte + 1, stop);
			if (nErrors > 0)
				return FALSE;
			current_byte++;
			badIntReg(RAM[current_byte], current_byte);
			if (nErrors > 0)
				return FALSE;
			DBG_FMT1("operand %s\n\n", R_STR[RAM[current_byte]]);
				
			current_byte = current_byte++;
			break;
			
		case LF1:	/*  LF1  $f1, $r1   BBB */
		case SF1:
		case CAST_FI:
			DBG_FMT1("opcode %s\n", I_Set[RAM[current_byte]]);
				
			checkCurrentByte(current_byte + 1, stop);
			if (nErrors > 0)
				return FALSE;
			current_byte++;
			badFltReg(RAM[current_byte], current_byte);
			if (nErrors > 0)
				return FALSE;
			DBG_FMT1("operand %s\n", Rf_STR[RAM[current_byte]]);
				
			checkCurrentByte(current_byte + 1, stop);
			if (nErrors > 0)
				return FALSE;
			current_byte++;
			badIntReg(RAM[current_byte], current_byte);
			if (nErrors > 0)
				return FALSE;
			DBG_FMT1("operand %s\n\n", R_STR[RAM[current_byte]]);
				
			current_byte = current_byte++;
			break;
			
		case LF2:	/*  LF2  $d1, $r1   BBB */
		case SF2:
		case CAST_DI:  /* CAST_DI  $d, $r */
			DBG_FMT1("opcode %s\n", I_Set[RAM[current_byte]]);
				
			checkCurrentByte(current_byte + 1, stop);
			if (nErrors > 0)
				return FALSE;
			current_byte++;
			badDblReg(RAM[current_byte], current_byte);
			if (nErrors > 0)
				return FALSE;
			DBG_FMT1("operand %s\n", Rd_STR[RAM[current_byte]]);
				
			checkCurrentByte(current_byte + 1, stop);
			if (nErrors > 0)
				return FALSE;
			current_byte++;
			badIntReg(RAM[current_byte], current_byte);
			if (nErrors > 0)
				return FALSE;
			DBG_FMT1("operand %s\n\n", R_STR[RAM[current_byte]]);
				
			current_byte = current_byte++;
			break;
			
		case PUSHB:	/* PUSHB $r1  BB */
		case PUSHW:
		case PUSHD:
		case PUSHQ:
		case POPB:	/* POPB $r1   BB*/
		case POPW:
		case POPD:
		case POPQ:
		case JMP:	/* JMP $r1	BB*/
			DBG_FMT1("opcode %s\n", I_Set[RAM[current_byte]]);
				
			checkCurrentByte(current_byte + 1, stop);
			if (nErrors > 0)
				return FALSE;
			current_byte++;
			badIntReg(RAM[current_byte], current_byte);
			if (nErrors > 0)
				return FALSE;
			DBG_FMT1("operand %s\n\n", R_STR[RAM[current_byte]]);
				
			current_byte = current_byte++;
			break;
			
		case PUSHF1: /* PUSHF1 $f  BB*/
		case POPF1:
			DBG_FMT1("opcode %s\n", I_Set[RAM[current_byte]]);
				
			checkCurrentByte(current_byte + 1, stop);
			if (nErrors > 0)
				return FALSE;
			current_byte++;
			badFltReg(RAM[current_byte], current_byte);
			if (nErrors > 0)
				return FALSE;
			DBG_FMT1("operand %s\n\n", Rf_STR[RAM[current_byte]]);
				
			current_byte = current_byte++;
			break;
			
		case PUSHF2:  /* PUSHF2 $d  BB*/
		case POPF2:
			DBG_FMT1("opcode %s\n", I_Set[RAM[current_byte]]);
				
			checkCurrentByte(current_byte + 1, stop);
			if (nErrors > 0)
				return FALSE;
			current_byte++;
			badDblReg(RAM[current_byte], current_byte);
			if (nErrors > 0)
				return FALSE;
			DBG_FMT1("operand %s\n\n", Rd_STR[RAM[current_byte]]);
				
			current_byte = current_byte++;
			break;
			
		case MOVF:	/* MOVF $f1, $f2  BBB*/
			DBG_FMT1("opcode %s\n", I_Set[RAM[current_byte]]);
				
			checkCurrentByte(current_byte + 1, stop);
			if (nErrors > 0)
				return FALSE;
			current_byte++;
			badFltReg(RAM[current_byte], current_byte);
			if (nErrors > 0)
				return FALSE;
			DBG_FMT1("operand %s\n", Rf_STR[RAM[current_byte]]);

			checkCurrentByte(current_byte + 1, stop);
			if (nErrors > 0)
				return FALSE;
			current_byte++;
			badFltReg(RAM[current_byte], current_byte);
			if (nErrors > 0)
				return FALSE;
			DBG_FMT1("operand %s\n\n", Rf_STR[RAM[current_byte]]);
				
			current_byte = current_byte++;
			break;
			
		case MOVD:  /* MOVF $d1, $d2    BBB*/
			DBG_FMT1("opcode %s\n", I_Set[RAM[current_byte]]);
				
			checkCurrentByte(current_byte + 1, stop);
			if (nErrors > 0)
				return FALSE;
			current_byte++;

⌨️ 快捷键说明

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