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

📄 cpu.c

📁 一个MIPS虚拟机的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	//printf("reg_table[get_rd0(instruction)] %s\n",reg_table[get_rd0(instruction)]);
	//printf("reg_table[get_rs(instruction)] %s\n",reg_table[get_rs(instruction)]);
	//
	//printf("reg_table[get_rt(instruction)] %s\n",reg_table[get_rt(instruction)]);
	if ((options.debug_mode==true) && (debug.current_mode==STEP))
		printf("%s %s,%s,%s","addu",reg_table[get_rd0(instruction)] ,reg_table[get_rs(instruction)],  reg_table[get_rt(instruction)]);
	//printf("get_rd(instruction) %x\n",get_rd(instruction));
	//printf("get_rs(instruction) %x\n",get_rs(instruction));
	//printf("get_rt(instruction) %x\n",get_rt(instruction));
	
	cpu_register[get_rd0(instruction)] =(UINT32)cpu_register[get_rs(instruction)] + (UINT32)cpu_register[get_rt(instruction)] ;
	//printf("return from addu_simulate\n");
}

/* opcode=0  sub opcode = 34  sub d,s,t   */
static void sub_simulate(const UINT32 instruction)
{
	INT32 rs,rt,sub;
	if ((options.debug_mode==true) && (debug.current_mode==STEP))
		printf("%s %s,%s,%s","sub",get_rd0(instruction),get_rs(instruction), get_rt(instruction));
	rs=(INT32)cpu_register[get_rs(instruction)];
	rt=(INT32)cpu_register[get_rt(instruction)];
	sub = rs-rt;
	if (((rs<0) && (rt<0) &(sub>=0) &(rs!=rt)  ) ||((rs>0) && (rt>0) &(sub<=0) & (rs=!rt)))
		{
			//an overflow exception
			exception(OV,-1);
			
		}
	else
		{
			cpu_register[get_rd0(instruction)] = (UINT32) sub;
		}

}
/* opcode=0  sub opcode = 35  subu d,s,t   */
static void subu_simulate(const UINT32 instruction)
{
	if ((options.debug_mode==true) && (debug.current_mode==STEP))
		printf("%s %s,%s,%s","subu",reg_table[get_rd0(instruction)] ,reg_table[get_rs(instruction)],  reg_table[get_rt(instruction)]);
	cpu_register[get_rd0(instruction)] = 	cpu_register[get_rs(instruction)]  -cpu_register[get_rt(instruction)] ;
}
/* opcode=0  sub opcode = 36  and d,s,t   */
static void and_simulate(const UINT32 instruction)
{
	if ((options.debug_mode==true) && (debug.current_mode==STEP))
		printf("%s %s,%s,%s","and",reg_table[get_rd0(instruction)] ,reg_table[get_rs(instruction)],  reg_table[get_rt(instruction)]);
	cpu_register[get_rd0(instruction)] = 	cpu_register[get_rs(instruction)] &cpu_register[get_rt(instruction)] ;
}
/* opcode=0  sub opcode = 37  or d,s,t   */
static void or_simulate(const UINT32 instruction)
{
	if ((options.debug_mode==true) && (debug.current_mode==STEP))
		printf("%s %s,%s,%s","or",reg_table[get_rd0(instruction)] ,reg_table[get_rs(instruction)],  reg_table[get_rt(instruction)]);
	cpu_register[get_rd0(instruction)] = 	cpu_register[get_rs(instruction)] | cpu_register[get_rt(instruction)] ;
}
/* opcode=0  sub opcode = 38  xor d,s,t   */
static void xor_simulate(const UINT32 instruction)
{
	if ((options.debug_mode==true) && (debug.current_mode==STEP))
		printf("%s %s,%s,%s","xor",reg_table[get_rd0(instruction)] ,reg_table[get_rs(instruction)],  reg_table[get_rt(instruction)]);
	cpu_register[get_rd0(instruction)] = 	cpu_register[get_rs(instruction)] ^  cpu_register[get_rt(instruction)] ;
}
/* opcode=0  sub opcode = 39  nor d,s,t   */
static void nor_simulate(const UINT32 instruction)
{
	if ((options.debug_mode==true) && (debug.current_mode==STEP))
		printf("%s %s,%s,%s","nor",reg_table[get_rd0(instruction)] ,reg_table[get_rs(instruction)],  reg_table[get_rt(instruction)]);
	cpu_register[get_rd0(instruction)] = 	~(cpu_register[get_rs(instruction)] |  cpu_register[get_rt(instruction)]) ;
}
/* opcode=0  sub opcode = 40  madd16 s,t  Vr4100   */
/* opcode=0  sub opcode = 41  dmadd16 s,t  Vr4100   */
/* opcode=0  sub opcode = 42  slt d,s,t   */
static  void slt_simulate(const UINT32 instruction)
{
	INT32 rs,rt;
	if ((options.debug_mode==true) && (debug.current_mode==STEP))
		printf("%s %s,%s,%s","slt",reg_table[get_rd0(instruction)] ,reg_table[get_rs(instruction)],  reg_table[get_rt(instruction)]);
	rs = (INT32)cpu_register[get_rs(instruction)];
	rt = (INT32)cpu_register[get_rt(instruction)];
	cpu_register[get_rd0(instruction)]=(rs<rt)?1:0;
}

/* opcode=0  sub opcode = 43  sltu d,s,t   */
static void sltu_simulate(const UINT32 instruction)
{
	if ((options.debug_mode==true) && (debug.current_mode==STEP))
		printf("%s %s,%s,%s","sltu",reg_table[get_rd0(instruction)] ,reg_table[get_rs(instruction)],  reg_table[get_rt(instruction)]);
	cpu_register[get_rd0(instruction)]=(cpu_register[get_rs(instruction)]<cpu_register[get_rt(instruction)])?1:0;
	
}
/* opcode=0  sub opcode = 44-63 MIPSII OR MIPSIII   */


/* opcode=1   bltz s,p   */
static void bltz_simulate(const UINT32 instruction)
{
	INT32 br_offset;
	if ((options.debug_mode==true) && (debug.current_mode==STEP))
		printf("%s %s,0x%x","bltz",reg_table[get_rs(instruction)],  get_broffset(instruction) );
	if (((INT32)cpu_register[get_rs(instruction)])<0)
		{
			br_offset = (INT32) (get_broffset(instruction)<<2);
			delay_state = DELAYING;
			delay_pc = (PC +4) + br_offset;
		}
	
}

/* opcode=1   bgez s,p   */
static void bgez_simulate(const UINT32 instruction)
{
	INT32 br_offset;
	if ((options.debug_mode==true) && (debug.current_mode==STEP))
		printf("%s %s,0x%x","bgez",reg_table[get_rs(instruction)],  get_broffset(instruction) );
	if (((INT32)cpu_register[get_rs(instruction)])>=0)
		{
			br_offset = (INT32) (get_broffset(instruction)<<2);
			delay_state = DELAYING;
			delay_pc = (PC +4) + br_offset;
		}
}

/* opcode=1   bltzal s,p   */
static void  bltzal_simulate(const UINT32 instruction)
{
	INT32 br_offset;
	if ((options.debug_mode==true) && (debug.current_mode==STEP))
		printf("%s %s,0x%x","bltzal",reg_table[get_rs(instruction)],  get_broffset(instruction) );
	if (((INT32)cpu_register[get_rs(instruction)])<0)
		{
			br_offset = (INT32) (get_broffset(instruction)<<2);
			delay_state = DELAYING;
			delay_pc = (PC +4) + br_offset;
			cpu_register[RA] = PC + 8;
		}
}

/* opcode=1   bgezal s,p   */
static void bgezal_simulate(const UINT32 instruction)
{
	INT32 br_offset;
	if ((options.debug_mode==true) && (debug.current_mode==STEP))
		printf("%s %s,0x%x","bgezal",reg_table[get_rs(instruction)],  get_broffset(instruction) );
	if (((INT32)cpu_register[get_rs(instruction)])>=0)
		{
			br_offset = (INT32) (get_broffset(instruction)<<2);
			delay_state = DELAYING;
			delay_pc = (PC +4) + br_offset;
			cpu_register[RA] = PC + 8;
		}
}


/* opcode =2   j target*/
static void j_simulate(const UINT32 instruction)
{
	if ((options.debug_mode==true) && (debug.current_mode==STEP))
		printf("%s 0x%x","j", instruction & 0x03ffffff );
	delay_state = DELAYING;
	delay_pc = ((PC +4)&0xf0000000) | ((instruction & 0x03ffffff)<<2);
	

}
/*opcode =3  jal target*/
static void jal_simulate(const UINT32 instruction)
{
	if ((options.debug_mode==true) && (debug.current_mode==STEP))
		printf("%s 0x%x","jal", instruction & 0x03ffffff );
	delay_state = DELAYING;
	delay_pc = ((PC +4)&0xf0000000) | ((instruction & 0x03ffffff)<<2);
	cpu_register[RA] = PC + 8;
}

/*opcode = 4   beq s,t,p*/
static void beq_simulate(const UINT32 instruction)
{
	INT32 br_offset;
	if ((options.debug_mode==true) && (debug.current_mode==STEP))
		printf("%s %s,%s,0x%x","beq",reg_table[get_rs(instruction)],reg_table[get_rt(instruction)],  get_broffset(instruction));
	
	if (cpu_register[get_rs(instruction)]==cpu_register[get_rt(instruction)])
		{
			br_offset = (INT32) (get_broffset(instruction)<<2);
			delay_state = DELAYING;
			delay_pc = (PC +4) + br_offset;
		}
}
/* opcode = 5 bne s,t,p*/
static void bne_simulate(const UINT32 instruction)
{
	INT32 br_offset;
	if ((options.debug_mode==true) && (debug.current_mode==STEP))
		printf("%s %s,%s,0x%x","bne",reg_table[get_rs(instruction)],reg_table[get_rt(instruction)],  get_broffset(instruction));
	
	//printf("get_rs(instruction) %x \n",get_rs(instruction));
	//printf("cpu_register[get_rs(instruction) %x \n",cpu_register[get_rs(instruction)]);
	//printf("get_rt(instruction) %x \n",get_rt(instruction));
	//
	//printf("cpu_register[get_rt(instruction)]] %x \n",cpu_register[get_rt(instruction)] );
	if (cpu_register[get_rs(instruction)]!=cpu_register[get_rt(instruction)])
		{
			br_offset = (INT32) (get_broffset(instruction)<<2);
			delay_state = DELAYING;
			delay_pc = (PC +4) + br_offset;
			//printf("delay_pc %x \n",delay_pc);
		}
}
/* opcode = 6 blez s,p*/
static void blez_simulate(const UINT32 instruction)
{
	if ((options.debug_mode==true) && (debug.current_mode==STEP))
		printf("%s %s,0x%x","blez",reg_table[get_rs(instruction)], get_broffset(instruction));
	
	INT32 signed_rs;
	INT32 br_offset;
	if (get_rt(instruction) != 0) 
		{
			//RI exception
			exception(RI,-1);
		}
	else
		{
			signed_rs = (INT32)cpu_register[get_rs(instruction)];
			if (signed_rs<=0)
				{
					br_offset = (INT32) (get_broffset(instruction)<<2);
					delay_state = DELAYING;
					delay_pc = (PC +4) + br_offset;
				}
		}
}
/* opcode = 7  bgtz s,p*/
static void bgtz_simulate(const UINT32 instruction)
{
	INT32 signed_rs;
	INT32 br_offset;
	if ((options.debug_mode==true) && (debug.current_mode==STEP))
		printf("%s %s,0x%x","bgtz",reg_table[get_rs(instruction)], get_broffset(instruction));
	if (get_rt(instruction) != 0) 
		{
			//RI exception
			exception(RI,-1);
		}
	else
		{
			signed_rs = (INT32)cpu_register[get_rs(instruction)];
			if (signed_rs>0)
				{
					br_offset = (INT32) (get_broffset(instruction)<<2);
					delay_state = DELAYING;
					delay_pc = (PC +4) + br_offset;
				}
		}
}

/* opcode =8   addi d,s,(signed)const*/
static void addi_simulate(const UINT32 instruction)
{
	INT32 sum,rs_signed,const_signed;
	rs_signed = (INT32)cpu_register[get_rs(instruction)];
	const_signed = (INT32)get_const_signed(instruction);
	sum = rs_signed + const_signed;
	if ((options.debug_mode==true) && (debug.current_mode==STEP))
		printf("%s %s,%s,0x%x","addi",reg_table[get_rd(instruction)],reg_table[get_rs(instruction)], const_signed);
	if (((rs_signed>0) && (const_signed>0) && (sum<=0)) || ((rs_signed<0) && (const_signed<0) && (sum>=0)))
		{
			//overflow exception
			exception(OV,-1);
		}
	else
		{
			cpu_register[get_rd(instruction)]=(UINT32)sum;
		}
	
	
}

/* opcode =9   addiu d,s,(signed)const  .Notice: signed const too. not unsigned const.  */
static void addiu_simulate(const UINT32 instruction)
{
	INT32 sum,rs_signed,const_signed;
	//printf("get_rd(instruction) %x\n",get_rd(instruction));
	//printf("cpu_register[get_rd(instruction)] %x\n",cpu_register[get_rd(instruction)]);
	//printf("get_rs(instruction) %x\n",get_rs(instruction));
	//printf("cpu_register[get_rs(instruction)] %x\n",cpu_register[get_rs(instruction)]);
	rs_signed = (INT32)cpu_register[get_rs(instruction)];
	const_signed = (INT32)get_const_signed(instruction);
	sum = rs_signed + const_signed;
	if ((options.debug_mode==true) && (debug.current_mode==STEP))
		printf("%s %s,%s,0x%x","addiu",reg_table[get_rd(instruction)],reg_table[get_rs(instruction)], const_signed);
	
	//printf("const_signed %x\n",const_signed);
	//printf("sum is %x\n",sum);
	cpu_register[get_rd(instruction)]=(INT32)sum;
	//printf("get_rd(instruction) %x\n",get_rd(instruction));
	//printf("cpu_register[get_rd(instruction)] %x\n",cpu_register[get_rd(instruction)]);
}

/* opcode = 10 slti d,s,(signed)const*/
static void slti_simulate(const UINT32 instruction)
{
	INT32 rs_signed,const_signed;
	rs_signed = (INT32)cpu_register[get_rs(instruction)];
	const_signed = (INT32)get_const_signed(instruction);
	if ((options.debug_mode==true) && (debug.current_mode==STEP))
		printf("%s %s,%s,0x%x","slti",reg_table[get_rd(instruction)],reg_table[get_rs(instruction)], const_signed);
	
	cpu_register[get_rd(instruction)]=rs_signed<const_signed?1:0;
}
/* opcode = 11 sltiu d,s,(signed)const*/
static void sltiu_simulate(const UINT32 instruction)
{
	UINT32 rs_unsigned,const_unsigned;
	rs_unsigned = (UINT32) cpu_register[get_rs(instruction)];
	const_unsigned = (UINT32)get_const_signed(instruction);
	if ((options.debug_mode==true) && (debug.current_mode==STEP))
		printf("%s %s,%s,0x%x","sltiu",reg_table[get_rd(instruction)],reg_table[get_rs(instruction)], const_unsigned);
	
	cpu_register[get_rd(instruction)]=rs_unsigned<const_unsigned?1:0;
}
/*opcode = 12 andi d,s,const*/
static void andi_simulate(const UINT32 instruction)
{
	UINT32 const_unsigned;
	const_unsigned = (UINT32)get_const_unsigned(instruction);
	if ((options.debug_mode==true) && (debug.current_mode==STEP))
		printf("%s %s,%s,0x%x","andi",reg_table[get_rd(instruction)],reg_table[get_rs(instruction)], const_unsigned);
	
	cpu_register[get_rd(instruction)] = cpu_register[get_rs(instruction)] & const_unsigned ;
	
}
/* opcode = 13  ori d,s,const*/
static void ori_simulate(const UINT32 instruction)
{
	UINT32 const_unsigned;
	const_unsigned = (UINT32)get_const_unsigned(instruction);
	if ((options.debug_mode==true) && (debug.current_mode==STEP))
		printf("%s %s,%s,0x%x","ori",reg_table[get_rd(instruction)],reg_table[get_rs(instruction)], const_unsigned);
	
	cpu_register[get_rd(instruction)] = cpu_register[get_rs(instruction)] | const_unsigned ;
	
}

/* opcode = 14  xori d,s,const*/
static void xori_simulate(const UINT32 instruction)
{
	UINT32 const_unsigned;
	const_unsigned = (UINT32)get_const_unsigned(instruction);
	if ((options.debug_mode==true) && (debug.current_mode==STEP))
		printf("%s %s,%s,0x%x","xori",reg_table[get_rd(instruction)],reg_table[get_rs(instruction)], const_unsigned);
	
	cpu_register[get_rd(instruction)] = cpu_register[get_rs(instruction)] ^ const_unsigned ;
	
}

/*opcode =15   lui d,const*/
static void lui_simulate(const UINT32 instruction)
{
	if ((options.debug_mode==true) && (debug.current_mode==STEP))
		printf("%s %s,0x%x","lui",reg_table[get_rd(instruction)],get_const_unsigned(instruction));
	
	cpu_register[get_rd(instruction)] =  ((UINT32)(get_const_unsigned(instruction))<<16);
	
}

/*opcode = 16 mfc0 t,cs  . implemented in cp0.c */
/*opcode = 16 cfc t,cs  . implemented in cp0.c */
/*opcode = 16 mtc0 t,cd  . implemented in cp0.c */
/*opcode = 16 ctc0 t,cd  . implemented in cp0.c */
/*opcode = 16 tlbr . implemented in cp0.c */
/*opcode = 16 tlbwi  . implemented in cp0.c */
/*opcode = 16 tlbwr  . implemented in cp0.c */
/*opcode = 16 tlbp  . implemented in cp0.c */
/*opcode = 16 rfe . implemented in cp0.c */
/*opcode = 16 bc0f p . implemented in cp0.c */
/*opcode = 16 bc0t p . implemented in cp0.c */

/*opcode = 17   fp instruction. we do not implement fp in this version of dongfeng*/
/* opcode =18 CU2 instruction . MIPS R3K does not contains CU2*/
/*opcode =19  MIPS IV only*/
/*opcode = 20 21 22 23 MIPS II only */
/*opcode = 24 25 26 27  MIPS III only*/
/* opcode = 28 MIPS R4659 only*/
/* opcode = 29 30 31 not defined*/

/*opcode = 32  lb t,0(b)*/
static void lb_simulate(const UINT32 instruction)
{
	UINT32 base_addr,vaddr,phyaddr;
	INT32 offset;
	boolean cache_able;
	UINT8 data;
	INT8 return_value;
	
	offset = get_offset(instruction);
	base_addr = cpu_register[get_rb(instruction)];
	vaddr = base_addr +  offset;
	if ((options.debug_mode==true) && (debug.current_mode==STEP))
		printf("%s %s,0x%x(%s)","lb",reg_table[get_rt(instruction)],offset, reg_table[get_rb(instruction)]);
	
	phyaddr = vaddr2phyaddr(vaddr,DATA_LOAD,&cache_able);
	//printf("phyaddr %x\n",phyaddr);
	if (0xffffffff== phyaddr  )
		{
		//	printf("an exception has occured\n");
			//an exception has occured when addr->phyaddr
		}
	else
		{
			if (!load_byte(vaddr,phyaddr,cache_able,DATA_LOAD,&data))
				{
				//	printf("an exception has occured\n");
					//an exception has occured when load_halfword
					
				}
			else
				{
					/*we must convert data to signed value*/
					return_value = (INT8)data;
					//printf("return_value %x\n",return_value);
					cpu_register[get_rt(instruction)]= (INT32)return_value;
				}
		}
	
	
}

/*opcode = 33  lh t,0(b)*/
static void lh_simulate(const UINT32 instruction)
{
	UINT32 base_addr,vaddr,phyaddr;
	INT32 offset;
	boolean cache_able;
	UINT16 data;
	INT16 return_value;
	
	offset = get_offset(instruction);
	base_addr = cpu_register[get_rb(instruction)];
	vaddr = base_addr +  offset;
	if ((options.debug_mode==true) && (debug.current_mode==STEP))
		printf("%s %s,0x%x(%s)","lh",reg_table[get_rt(instruction)],offset, reg_table[get_rb(instruction)]);
	if ((vaddr % 2)!=0)
		{
			//fprintf(stderr,"vaddr % 4- !=0---------------------------------!\n");
			//bad address exctiption
			//if ((operation_mode==DATA_LOAD)||(operation_mode==INSTRUCTION_LOAD))
				exception(ADEL,-1);
			//else
			//	exception(ADES,-1);
			return ;
		}
	phyaddr = vaddr2phyaddr(vaddr,DATA_LOAD,&cache_able);
	if ((phyaddr % 2)!=0)
		{
			//fprintf(stderr,"vaddr % 4- !=0---------------------------------!\n");
			//bad address exctiption
			//if ((operation_mode==DATA_LOAD)||(operation_mode==INSTRUCTION_LOAD))
				exception(ADEL,-1);
			//else
			//	exception(ADES,-1);
			//return ;
		}
	//if (0xffffffff== phyaddr  )
	//	{
			//an exception has occured when addr->phyaddr
	//	}
	//else
	//	{

⌨️ 快捷键说明

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