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

📄 decoder.c

📁 skyeye for pxa270
💻 C
📖 第 1 页 / 共 3 页
字号:
#include "instr.h"#include "emul.h"#include <stdio.h>/* Anthony Lee: 2006-09-18 */#ifdef __MINGW32__#define sync()	_flushall()#else#include <unistd.h> /* for sync() */#endifextern FILE *skyeye_logfd;/* This monster of a switch statement decodes all CPU instructions. I've * decided against an explicit jump table, as such implementation both * increases the code size and introduced additional overhead to the inner * decoder loop. *//*  WARNING: The below code currently does not simulate any slips. * This should be fixed soon (it's fairly easy to simulate, too.) */const char* regname[32] = {    "$0", "at", "v0", "v1", "a0", "a1", "a2", "a3",    "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",    "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",    "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"};int decode(MIPS_State* mstate, Instr instr){    	switch (opcode(instr)) {    		case SPECIAL:    		{			/* Special instructions, decoded using the (function) field */			switch (function(instr)) {				case SLL:				{	    				// Shift Left Logical	    				if (rd(instr)) {						UInt32 x = mstate->gpr[rt(instr)];						int s = shamt(instr);						x <<= s;						mstate->gpr[rd(instr)] = x;					}    					return nothing_special;				}				case SRL:				{	    				// Shift Right Logical					UInt32 x = mstate->gpr[rt(instr)];	    				int s = shamt(instr);					x >>= s;	   				mstate->gpr[rd(instr)] = x;				  	return nothing_special;				}				case SRA:				{				    	// Shift Right Arithmetic					UInt32 x = mstate->gpr[rt(instr)];	    				int s = shamt(instr);					x >>= s;	    				mstate->gpr[rd(instr)] = sign_extend_UInt32(x, 32 - s);			    				return nothing_special;				}				case SLLV:				{				    	UInt32 x = mstate->gpr[rt(instr)];				    	int s = bits(mstate->gpr[rs(instr)], 4, 0);					x <<= s;					//mstate->gpr[rd(instr)] = sign_extend_UInt32(x, 32 - s);					mstate->gpr[rd(instr)] = x;					return nothing_special;				}				case SRLV:				{	    				// Shift Right Logical Variable					UInt32 x = mstate->gpr[rt(instr)];				        int s = bits(mstate->gpr[rs(instr)], 4, 0);					x >>= s;	   				//mstate->gpr[rd(instr)] = sign_extend_UInt32(x, 32 - s);					mstate->gpr[rd(instr)] = x;					return nothing_special;				}				case SRAV:				{					// Shift Right Arithmetic Variable 					UInt32 x = mstate->gpr[rt(instr)];				        int s = bits(mstate->gpr[rs(instr)], 4, 0);					x >>= s;				        mstate->gpr[rd(instr)] = sign_extend_UInt32(x, 32 - s);					return nothing_special;				}				case MOVZ:				{					if(!mstate->gpr[rt(instr)])                                        	mstate->gpr[rd(instr)] = mstate->gpr[rs(instr)];                                        return nothing_special;                                }				case MOVN:                                {                                        if(mstate->gpr[rt(instr)])                                                mstate->gpr[rd(instr)] = mstate->gpr[rs(instr)];                                        return nothing_special;                                }				case JR:				{				    	// Jump Register					mstate->branch_target = mstate->gpr[rs(instr)];	    				if (mstate->pipeline == branch_delay)						printf("Can't handle branch in branch delay slot\n");	   					return bits(mstate->branch_target, 1, 0) ? instr_addr_error : branch_delay;				}				case JALR:				{					// Jump And Link Register					mstate->branch_target = mstate->gpr[rs(instr)];					if(rd(instr) != 31)						mstate->gpr[rd(instr)] = mstate->pc + 8;					else						mstate->gpr[31] = mstate->pc + 8;	    				if (mstate->pipeline == branch_delay)						printf("Can't handle branch in branch delay slot\n");							return bits(mstate->branch_target, 1, 0) ? instr_addr_error : branch_delay;				}				case SYSCALL:				{				        // System Call					process_syscall(mstate);		    				return nothing_special;				}				case BREAK:				{					//process_breakpoint(mstate);					fprintf(stderr,"workaround for break instruction, pc=0x%x\n ", mstate->pc);				    	return nothing_special;				}				case SYNC:				{					// Synchronize					//Fix me Shi yang 2006-08-08					//process_reserved_instruction(mstate);					return nothing_special;				}				case MFHI:				{				    	// Move From HI	    				mstate->gpr[rd(instr)] = mstate->hi;					return nothing_special;				}				case MTHI:				{					// Move To HI				    	mstate->hi = mstate->gpr[rs(instr)];					return nothing_special;				}				case MFLO:				{				    	// Move From LO	    				mstate->gpr[rd(instr)] = mstate->lo;						        return nothing_special;				}				case MTLO:				{	    				// Move To LO		    			mstate->lo = mstate->gpr[rs(instr)];				        return nothing_special;				}				case DSLLV:				{			    		// Doubleword Shift Left Logical Variable					process_reserved_instruction(mstate);					return nothing_special;				}				case DSRLV:				{				    	// Doubleword Shift Right Logical Variable					process_reserved_instruction(mstate);					return nothing_special;				}					case DSRAV:				{		    			// Doubleword Shift Right Arithmetic Variable					process_reserved_instruction(mstate);					return nothing_special;				}				case MULT:				{			    		// Multiply				        Int64 x = mstate->gpr[rs(instr)];	    				Int64 y = mstate->gpr[rt(instr)];	    				//multiply(x, y);					long long z = x * y;					mstate->hi = (z >> 32) & 0xFFFFFFFF;                                        mstate->lo = z & 0xFFFFFFFF;					return nothing_special;				}				case MULTU:				{	    				// Multiply Unsigned				    	UInt64 x = mstate->gpr[rs(instr)];		    			UInt64 y = mstate->gpr[rt(instr)];					unsigned long long z = x * y;	   	 			//multiply(x, y);					mstate->hi = (z >> 32) & 0xFFFFFFFF;				        mstate->lo = z & 0xFFFFFFFF;				    	return nothing_special;				}				case DIV:				{	    				// Divide					Int32 y = (Int32) mstate->gpr[rt(instr)];					Int32 x = (Int32) mstate->gpr[rs(instr)];					divide_Int32(x, y);									    	return nothing_special;				}				case DIVU:				{				    	UInt32 y = (UInt32) mstate->gpr[rt(instr)];					UInt32 x = (UInt32) mstate->gpr[rs(instr)];					divide_UInt32(x, y);				    	return nothing_special;				}				case DMULT:				{	    				// Doubleword Multiply					process_reserved_instruction(mstate);					return nothing_special;				}				case DMULTU:				{	    				// Doubleword Multiply Unsigned					process_reserved_instruction(mstate);					return nothing_special;				}				case DDIV:				{			   		 // Doubleword Divide					process_reserved_instruction(mstate);					return nothing_special;				}				case DDIVU:				{	    				// Doubleword Divide Unsigned					process_reserved_instruction(mstate);					return nothing_special;				}				case ADD:	    			{	    				// Add	    				UInt32 x = mstate->gpr[rs(instr)];	    				UInt32 y = mstate->gpr[rt(instr)];	    				UInt32 z = x + y;				    	// Overflow occurs is sign(x) == sign(y) != sign(z).				    	if (bit(x ^ y, 31) == 0 && bit(x ^ z, 31) != 0)						process_integer_overflow(mstate);					mstate->gpr[rd(instr)] = z;				    	return nothing_special;				}				case ADDU:				{	    				// Add Unsigned					UInt32 x = mstate->gpr[rs(instr)];				    	UInt32 y = mstate->gpr[rt(instr)];					UInt32 z = x + y;	    				mstate->gpr[rd(instr)] = z;				    	return nothing_special;				}				case SUB:				{	    				// Subtract					Int32 x = mstate->gpr[rs(instr)];					Int32 y = mstate->gpr[rt(instr)];	    				Int32 z = (UInt32)x - (UInt32)y;				    	if ((y < 0 && z < x) || (y > 0 && z > x))						process_integer_overflow();				    	mstate->gpr[rd(instr)] = z;					return nothing_special;				}				case SUBU:				{	    				// Subtract Unsigned	    				UInt32 x = mstate->gpr[rs(instr)];	    				UInt32 y = mstate->gpr[rt(instr)];				    	mstate->gpr[rd(instr)] = x - y;					return nothing_special;				}				case AND:				{	    				// And					mstate->gpr[rd(instr)] = mstate->gpr[rs(instr)] & mstate->gpr[rt(instr)];				    	return nothing_special;				}				case OR:				{				    	// Or				    	mstate->gpr[rd(instr)] = mstate->gpr[rs(instr)] | mstate->gpr[rt(instr)];				   	return nothing_special;				}				case XOR:				{			    		// Exclusive Or				        mstate->gpr[rd(instr)] = mstate->gpr[rs(instr)] ^ mstate->gpr[rt(instr)];				    	return nothing_special;				}				case NOR:				{	    				// Nor				        mstate->gpr[rd(instr)] = ~((mstate->gpr[rs(instr)] | mstate->gpr[rt(instr)]));					    	return nothing_special;				}				case SLT:				{	    				// Set On Less Than				    	Int32 x = mstate->gpr[rs(instr)];				    	Int32 y = mstate->gpr[rt(instr)];				    	mstate->gpr[rd(instr)] = (x < y);					    	return nothing_special;				}				case SLTU:				{				    	mstate->gpr[rd(instr)] = (mstate->gpr[rs(instr)] < mstate->gpr[rt(instr)]);				    	return nothing_special;				}				case DADD:				{				    	// Doubleword Add						process_reserved_instruction(mstate);					return nothing_special;				}				case DADDU:				{	    				// Doubleword Add Unsigned					process_reserved_instruction(mstate);					return nothing_special;				}				case DSUB:				{		    			// Doubleword Subtract					process_reserved_instruction(mstate);					return nothing_special;				}				case DSUBU:				{	    				// Doubleword Subtract Unsigned					process_reserved_instruction(mstate);					return nothing_special;				}				case TGE:				{			    		// Trap If Greater Than Or Equal					process_reserved_instruction(mstate);					return nothing_special;				}				case TGEU:				{			    		// Trap If Greater Than Or Equal Unsigned					process_reserved_instruction(mstate);					return nothing_special;				}				case TLT:				{				    	// Trap If Less Than					process_reserved_instruction(mstate);					return nothing_special;				}				case TLTU:				{				    	// Trap If Less Than Unsigned					process_reserved_instruction(mstate);					return nothing_special;				}				case TEQ:				{				    	// Trap If Equal					process_reserved_instruction(mstate);					return nothing_special;				}

⌨️ 快捷键说明

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