?? ri.c
字號:
//extern onintr(int a,int *b);//#include "mips/cpu.h"#include <prid.h>#include <stdio.h> #include <sys/sys/signal.h>#ifdef R3081#include "r3081.h"#endif#ifdef R3041#include "r3041.h"#endif#include "ri.h"#ifdef GODSONEV1int global_div_num=0;#endifextern int do_ri (struct pt_regs *xcp);int __compute_return_epc(struct pt_regs *regs);static unsigned long mips_get_word_l(struct pt_regs *xcp, void *va, int *perr){ *perr = 0; return(*(unsigned long *)va);}static int mips_put_word_l(struct pt_regs *xcp, void *va, unsigned long val){ *(unsigned long *)va = val; return 0;}static int emu_lwl(struct pt_regs * regs,mips_instruction ir,vaddr_t_l emulpc){ int err = 0; /*the "ir" is the instruction causing the exception*/ /*get the real address,perhaps the address is not word aligned*/ void *va = REG_TO_VA_l (regs->regs[MIPSInst_RS(ir)])+ MIPSInst_SIMM(ir); unsigned long addr = 0; unsigned long emul_pc = (unsigned long)emulpc; unsigned long little_three_bits; unsigned long value,value_tmp;// printf("emu_lwl\r\n"); /*compute the correct position in the RT*/ /*note !!!!: we have supposed the CPU is little_Endianness and status regiester's RE bit =0 */ /*little Endianness*/ little_three_bits = (unsigned long)va&(0x7); value_tmp = regs->regs[MIPSInst_RT(ir)]; switch(little_three_bits) { case 0: case 4: /*must check lwl valid*/ addr = (unsigned long) va; check_axs(emul_pc,addr,4); value = mips_get_word_l(regs,va,&err); if(err){ return SIGBUS; } value<<=24; value_tmp &= 0xffffff; regs->regs[MIPSInst_RT(ir)] =value_tmp|value; break; case 1: case 5: addr = (unsigned long)va -1; check_axs(emul_pc,addr,4); value = mips_get_word_l(regs,(void *)((unsigned long) va-1),&err); if(err){ return SIGBUS; } value<<=16; value_tmp&=0xffff; regs->regs[MIPSInst_RT(ir)] =value_tmp|value; break; case 2: case 6: addr = (unsigned long)va - 2; check_axs(emul_pc,addr,4); value = mips_get_word_l(regs,(void *)((unsigned long)va-2),&err); if(err){ return SIGBUS; } value<<=8; value_tmp &= 0xff; regs->regs[MIPSInst_RT(ir)] =value_tmp|value; break; case 3: case 7: addr = (unsigned long)va - 3; check_axs(emul_pc,addr,4); value = mips_get_word_l(regs,(void *)((unsigned long)va-3),&err); if(err){ return SIGBUS; }; regs->regs[MIPSInst_RT(ir)] = value; break; } /*swith ended*/ return 0;}static int emu_lwr(struct pt_regs *regs,mips_instruction ir,vaddr_t_l emulpc){ int err = 0; /*the "ir" is the instruction causing the exception*/ /*get the real address,perhaps the address is not word aligned*/ void *va = REG_TO_VA_l (regs->regs[MIPSInst_RS(ir)]) + MIPSInst_SIMM(ir); unsigned long addr; unsigned long emul_pc = (unsigned long)emulpc; unsigned long little_three_bits; unsigned long value,value_tmp;// printf("emu_lwr\r\n"); /*compute the correct position in the RT*/ /*note !!!!: we have supposed the CPU is little_Endianness and status regiester's RE bit =0 */ little_three_bits = (unsigned long)va&(0x7); value_tmp = regs->regs[MIPSInst_RT(ir)]; switch(little_three_bits) { case 0: case 4: /*must check lwl valid*/ addr = (unsigned long)va ; check_axs(emul_pc,addr,4); value = mips_get_word_l(regs,va,&err); if(err){ return SIGBUS; } regs->regs[MIPSInst_RT(ir)] =value; break; case 1: case 5: addr = (unsigned long)va -1; check_axs(emul_pc,addr,4); value = mips_get_word_l(regs,(void *)((unsigned long)va-1),&err); if(err){ return SIGBUS; } value>>=8; value_tmp&=0xff000000; regs->regs[MIPSInst_RT(ir)] =value_tmp|value; break; case 2: case 6: addr = (unsigned long)va-2; check_axs(emul_pc,addr,4); value = mips_get_word_l(regs,(void *)((unsigned long)va-2),&err); if(err){ return SIGBUS; } value>>=16; value_tmp &= 0xffff0000; regs->regs[MIPSInst_RT(ir)] =value_tmp|value; break; case 3: case 7: addr = (unsigned long)va -3; check_axs(emul_pc,addr,4); value = mips_get_word_l(regs,(void *)((unsigned long)va-3),&err); if(err){ return SIGBUS; }; value>>=24; value_tmp &= 0xffffff00; regs->regs[MIPSInst_RT(ir)] = value_tmp|value; break; } /*swith ended*/ return 0;}static int emu_swl(struct pt_regs *regs,mips_instruction ir, vaddr_t_l emulpc){ int err = 0; /*the "ir" is the instruction causing the exception*/ /*get the real address,perhaps the address is not word aligned*/ void *va = REG_TO_VA_l (regs->regs[MIPSInst_RS(ir)]) + MIPSInst_SIMM(ir); unsigned long addr; unsigned long emul_pc = (unsigned long)emulpc; unsigned long little_three_bits; unsigned long value,value_tmp;// printf("emu_swl\r\n"); /*compute the correct position in the RT*/ /*note !!!!: we have supposed the CPU is little_Endianness and status re * giester's RE bit =0 */ little_three_bits = (unsigned long)va&(0x7); value_tmp = regs->regs[MIPSInst_RT(ir)]; switch(little_three_bits) { case 0: case 4: addr = (unsigned long)va; check_axs(emul_pc,addr,4); value_tmp >>= 24; value = mips_get_word_l(regs,va,&err); if(err){ return SIGBUS; } value &=0xffffff00; value |= value_tmp; if(mips_put_word_l(regs,va,value)){ return SIGBUS; } break; case 1: case 5: addr = (unsigned long)va -1; check_axs(emul_pc,addr,4); value_tmp >>= 16; value = mips_get_word_l(regs,(void *)((unsigned long)va-1),&err); if(err){ return SIGBUS; } value &=0xffff0000; value |= value_tmp; if(mips_put_word_l(regs,(void *)((unsigned long)va-1),value)){ return SIGBUS; } break; case 2: case 6: addr = (unsigned long)va - 2; check_axs(emul_pc,addr,4); value_tmp >>= 8; value = mips_get_word_l(regs,(void *)((unsigned long)va-2),&err); if(err){ return SIGBUS; } value &=0xff000000; value |= value_tmp; if(mips_put_word_l(regs,(void *)((unsigned long)va-2),value)){ return SIGBUS; } break; case 3: case 7: addr = (unsigned long)va - 3; check_axs(emul_pc,addr,4); value = value_tmp; if(mips_put_word_l(regs,(void *)((unsigned long)va-3),value)){ return SIGBUS; } break; } return 0;}static int emu_swr(struct pt_regs *regs,mips_instruction ir, vaddr_t_l emulpc){ int err = 0; /*the "ir" is the instruction causing the exception*/ /*get the real address,perhaps the address is not word aligned*/ void *va = REG_TO_VA_l (regs->regs[MIPSInst_RS(ir)]) + MIPSInst_SIMM(ir); unsigned long addr; unsigned long emul_pc = (unsigned long)emulpc; unsigned long little_three_bits; unsigned long value,value_tmp; // printf("emu_swr\r\n"); /*compute the correct position in the RT*/ /*note !!!!: we have supposed the CPU is little_Endianness and status re * giester's RE bit =0 */ little_three_bits = (unsigned long)va&(0x7); value_tmp = regs->regs[MIPSInst_RT(ir)]; switch(little_three_bits) { case 0: case 4: addr = (unsigned long) va; check_axs(emul_pc,addr,4); value = value_tmp; if(mips_put_word_l(regs,va,value)){ return SIGBUS; } break; case 1: case 5: addr = (unsigned long)va -1; check_axs(emul_pc,addr,4); value_tmp <<= 8; value = mips_get_word_l(regs,(void *)((unsigned long)va-1),&err); if(err){ return SIGBUS; } value &=0xff; value |= value_tmp; if(mips_put_word_l(regs,(void *)((unsigned long)va-1),value)){ return SIGBUS; } break; case 2: case 6: addr = (unsigned long)va - 2; check_axs(emul_pc,addr,4); value_tmp <<= 16; value = mips_get_word_l(regs,(void *)((unsigned long)va-2),&err); if(err){ return SIGBUS; } value &=0xffff; value |= value_tmp; if(mips_put_word_l(regs,(void *)((unsigned long)va-2),value)){ return SIGBUS; } break; case 3: case 7: addr = (unsigned long)va -3; check_axs(emul_pc,addr,4); value_tmp <<= 24; value = mips_get_word_l(regs,(void *)((unsigned long)va-3),&err); if(err){ return SIGBUS; } value &= 0xffffff; value |= value_tmp; if(mips_put_word_l(regs,(void *)((unsigned long)va-3),value)){ return SIGBUS; } break; } return 0;}static int emu_div(struct pt_regs *regs,mips_instruction ir){ int x,y; int flag = 0; int quotient = 0,remainder = 0; unsigned int absx,absy,absquotient = 0,absremainder = 0,bm = 1; /*the "ir" is the instruction causing the exception*/ x = regs->regs[MIPSInst_RS(ir)]; y = regs->regs[MIPSInst_RT(ir)]; #ifdef __test_ri__ //printf("now in function:emu_div().\r\n");#endif if( y == 0 ) {/*overflow*/ return SIGABRT; } /*x and y 符號是否不同*/ flag = (x&0x80000000)^(y&0x80000000); /*get the abs(x)*/ if(x<0){ absx = (unsigned int)-x; }else { absx = (unsigned int)x; } /*get the abs(y)*/ if(y<0){ absy = (unsigned int) -y; }else { absy = (unsigned int)y; } /*caculate the absx/absy*/ if(absx<absy) {/*don't need to calculate*/ absquotient = 0; absremainder = absx; goto end; } while(!(absy&0x80000000))
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -