📄 cpu.c
字号:
//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 + -