📄 fpudispatch.c
字号:
return(sgl_to_sgl_fcnvuf(&fpregs[r1],0, &fpregs[t],status)); case 1: /* sgl/dbl */ return(sgl_to_dbl_fcnvuf(&fpregs[r1],0, &fpregs[t],status)); case 2: /* dbl/sgl */ return(dbl_to_sgl_fcnvuf(&fpregs[r1],0, &fpregs[t],status)); case 3: /* dbl/dbl */ return(dbl_to_dbl_fcnvuf(&fpregs[r1],0, &fpregs[t],status)); } case 6: /* FCNVFU (PA2.0 only) */ switch(fmt) { case 0: /* sgl/sgl */ return(sgl_to_sgl_fcnvfu(&fpregs[r1],0, &fpregs[t],status)); case 1: /* sgl/dbl */ return(sgl_to_dbl_fcnvfu(&fpregs[r1],0, &fpregs[t],status)); case 2: /* dbl/sgl */ return(dbl_to_sgl_fcnvfu(&fpregs[r1],0, &fpregs[t],status)); case 3: /* dbl/dbl */ return(dbl_to_dbl_fcnvfu(&fpregs[r1],0, &fpregs[t],status)); } case 7: /* FCNVFUT (PA2.0 only) */ switch(fmt) { case 0: /* sgl/sgl */ return(sgl_to_sgl_fcnvfut(&fpregs[r1],0, &fpregs[t],status)); case 1: /* sgl/dbl */ return(sgl_to_dbl_fcnvfut(&fpregs[r1],0, &fpregs[t],status)); case 2: /* dbl/sgl */ return(dbl_to_sgl_fcnvfut(&fpregs[r1],0, &fpregs[t],status)); case 3: /* dbl/dbl */ return(dbl_to_dbl_fcnvfut(&fpregs[r1],0, &fpregs[t],status)); } case 4: /* undefined */ return(MAJOR_0C_EXCP); } /* end of switch subop */ case 2: /* class 2 */ fpu_type_flags=fpregs[FPU_TYPE_FLAG_POS]; r2 = extru(ir, fpr2pos, 5) * sizeof(double)/sizeof(u_int); if (r2 == 0) r2 = fpzeroreg; if (fpu_type_flags & PA2_0_FPU_FLAG) { /* FTEST if nullify bit set, otherwise FCMP */ if (extru(ir, fpnulpos, 1)) { /* FTEST */ switch (fmt) { case 0: /* * arg0 is not used * second param is the t field used for * ftest,acc and ftest,rej * third param is the subop (y-field) */ BUG(); /* Unsupported * return(ftest(0L,extru(ir,fptpos,5), * &fpregs[0],subop)); */ case 1: case 2: case 3: return(MAJOR_0C_EXCP); } } else { /* FCMP */ switch (fmt) { case 0: retval = sgl_fcmp(&fpregs[r1], &fpregs[r2],extru(ir,fptpos,5), &local_status); update_status_cbit(status,local_status, fpu_type_flags, subop); return(retval); case 1: retval = dbl_fcmp(&fpregs[r1], &fpregs[r2],extru(ir,fptpos,5), &local_status); update_status_cbit(status,local_status, fpu_type_flags, subop); return(retval); case 2: /* illegal */ case 3: /* quad not implemented */ return(MAJOR_0C_EXCP); } } } /* end of if for PA2.0 */ else { /* PA1.0 & PA1.1 */ switch (subop) { case 2: case 3: case 4: case 5: case 6: case 7: return(MAJOR_0C_EXCP); case 0: /* FCMP */ switch (fmt) { case 0: retval = sgl_fcmp(&fpregs[r1], &fpregs[r2],extru(ir,fptpos,5), &local_status); update_status_cbit(status,local_status, fpu_type_flags, subop); return(retval); case 1: retval = dbl_fcmp(&fpregs[r1], &fpregs[r2],extru(ir,fptpos,5), &local_status); update_status_cbit(status,local_status, fpu_type_flags, subop); return(retval); case 2: /* illegal */ case 3: /* quad not implemented */ return(MAJOR_0C_EXCP); } case 1: /* FTEST */ switch (fmt) { case 0: /* * arg0 is not used * second param is the t field used for * ftest,acc and ftest,rej * third param is the subop (y-field) */ BUG(); /* unsupported * return(ftest(0L,extru(ir,fptpos,5), * &fpregs[0],subop)); */ case 1: case 2: case 3: return(MAJOR_0C_EXCP); } } /* end of switch subop */ } /* end of else for PA1.0 & PA1.1 */ case 3: /* class 3 */ r2 = extru(ir,fpr2pos,5) * sizeof(double)/sizeof(u_int); if (r2 == 0) r2 = fpzeroreg; switch (subop) { case 5: case 6: case 7: return(MAJOR_0C_EXCP); case 0: /* FADD */ switch (fmt) { case 0: return(sgl_fadd(&fpregs[r1],&fpregs[r2], &fpregs[t],status)); case 1: return(dbl_fadd(&fpregs[r1],&fpregs[r2], &fpregs[t],status)); case 2: /* illegal */ case 3: /* quad not implemented */ return(MAJOR_0C_EXCP); } case 1: /* FSUB */ switch (fmt) { case 0: return(sgl_fsub(&fpregs[r1],&fpregs[r2], &fpregs[t],status)); case 1: return(dbl_fsub(&fpregs[r1],&fpregs[r2], &fpregs[t],status)); case 2: /* illegal */ case 3: /* quad not implemented */ return(MAJOR_0C_EXCP); } case 2: /* FMPY */ switch (fmt) { case 0: return(sgl_fmpy(&fpregs[r1],&fpregs[r2], &fpregs[t],status)); case 1: return(dbl_fmpy(&fpregs[r1],&fpregs[r2], &fpregs[t],status)); case 2: /* illegal */ case 3: /* quad not implemented */ return(MAJOR_0C_EXCP); } case 3: /* FDIV */ switch (fmt) { case 0: return(sgl_fdiv(&fpregs[r1],&fpregs[r2], &fpregs[t],status)); case 1: return(dbl_fdiv(&fpregs[r1],&fpregs[r2], &fpregs[t],status)); case 2: /* illegal */ case 3: /* quad not implemented */ return(MAJOR_0C_EXCP); } case 4: /* FREM */ switch (fmt) { case 0: return(sgl_frem(&fpregs[r1],&fpregs[r2], &fpregs[t],status)); case 1: return(dbl_frem(&fpregs[r1],&fpregs[r2], &fpregs[t],status)); case 2: /* illegal */ case 3: /* quad not implemented */ return(MAJOR_0C_EXCP); } } /* end of class 3 switch */ } /* end of switch(class) */ /* If we get here, something is really wrong! */ return(MAJOR_0C_EXCP);}static u_intdecode_0e(ir,class,subop,fpregs)u_int ir,class,subop;u_int fpregs[];{ u_int r1,r2,t; /* operand register offsets */ u_int fmt; /* also sf for class 1 conversions */ u_int df; /* dest format for class 1 conversions */ u_int *status; u_int retval, local_status; u_int fpu_type_flags; status = &fpregs[0]; local_status = fpregs[0]; r1 = ((extru(ir,fpr1pos,5)<<1)|(extru(ir,fpxr1pos,1))); if (r1 == 0) r1 = fpzeroreg; t = ((extru(ir,fptpos,5)<<1)|(extru(ir,fpxtpos,1))); if (t == 0 && class != 2) return(MAJOR_0E_EXCP); if (class < 2) /* class 0 or 1 has 2 bit fmt */ fmt = extru(ir,fpfmtpos,2); else /* class 2 and 3 have 1 bit fmt */ fmt = extru(ir,fp0efmtpos,1); /* * An undefined combination, double precision accessing the * right half of a FPR, can get us into trouble. * Let's just force proper alignment on it. */ if (fmt == DBL) { r1 &= ~1; if (class != 1) t &= ~1; } switch (class) { case 0: switch (subop) { case 0: /* unimplemented */ case 1: return(MAJOR_0E_EXCP); case 2: /* FCPY */ switch (fmt) { case 2: case 3: return(MAJOR_0E_EXCP); case 1: /* double */ fpregs[t+1] = fpregs[r1+1]; case 0: /* single */ fpregs[t] = fpregs[r1]; return(NOEXCEPTION); } case 3: /* FABS */ switch (fmt) { case 2: case 3: return(MAJOR_0E_EXCP); case 1: /* double */ fpregs[t+1] = fpregs[r1+1]; case 0: /* single */ fpregs[t] = fpregs[r1] & 0x7fffffff; return(NOEXCEPTION); } case 6: /* FNEG */ switch (fmt) { case 2: case 3: return(MAJOR_0E_EXCP); case 1: /* double */ fpregs[t+1] = fpregs[r1+1]; case 0: /* single */ fpregs[t] = fpregs[r1] ^ 0x80000000; return(NOEXCEPTION); } case 7: /* FNEGABS */ switch (fmt) { case 2: case 3: return(MAJOR_0E_EXCP); case 1: /* double */ fpregs[t+1] = fpregs[r1+1]; case 0: /* single */ fpregs[t] = fpregs[r1] | 0x80000000; return(NOEXCEPTION); } case 4: /* FSQRT */ switch (fmt) { case 0: return(sgl_fsqrt(&fpregs[r1],0, &fpregs[t], status)); case 1: return(dbl_fsqrt(&fpregs[r1],0, &fpregs[t], status)); case 2: case 3: return(MAJOR_0E_EXCP); } case 5: /* FRMD */ switch (fmt) { case 0: return(sgl_frnd(&fpregs[r1],0, &fpregs[t], status)); case 1: return(dbl_frnd(&fpregs[r1],0, &fpregs[t], status)); case 2: case 3: return(MAJOR_0E_EXCP); } } /* end of switch (subop */ case 1: /* class 1 */ df = extru(ir,fpdfpos,2); /* get dest format */ /* * Fix Crashme problem (writing to 31R in double precision) * here too. */ if (df == DBL) { t &= ~1; } if ((df & 2) || (fmt & 2)) return(MAJOR_0E_EXCP); fmt = (fmt << 1) | df; switch (subop) { case 0: /* FCNVFF */ switch(fmt) { case 0: /* sgl/sgl */ return(MAJOR_0E_EXCP); case 1: /* sgl/dbl */ return(sgl_to_dbl_fcnvff(&fpregs[r1],0, &fpregs[t],status)); case 2: /* dbl/sgl */ return(dbl_to_sgl_fcnvff(&fpregs[r1],0, &fpregs[t],status)); case 3: /* dbl/dbl */ return(MAJOR_0E_EXCP); } case 1: /* FCNVXF */ switch(fmt) { case 0: /* sgl/sgl */ return(sgl_to_sgl_fcnvxf(&fpregs[r1],0, &fpregs[t],status)); case 1: /* sgl/dbl */ return(sgl_to_dbl_fcnvxf(&fpregs[r1],0, &fpregs[t],status)); case 2: /* dbl/sgl */ return(dbl_to_sgl_fcnvxf(&fpregs[r1],0, &fpregs[t],status)); case 3: /* dbl/dbl */ return(dbl_to_dbl_fcnvxf(&fpregs[r1],0, &fpregs[t],status)); } case 2: /* FCNVFX */ switch(fmt) { case 0: /* sgl/sgl */ return(sgl_to_sgl_fcnvfx(&fpregs[r1],0, &fpregs[t],status)); case 1: /* sgl/dbl */ return(sgl_to_dbl_fcnvfx(&fpregs[r1],0, &fpregs[t],status)); case 2: /* dbl/sgl */ return(dbl_to_sgl_fcnvfx(&fpregs[r1],0, &fpregs[t],status)); case 3: /* dbl/dbl */ return(dbl_to_dbl_fcnvfx(&fpregs[r1],0, &fpregs[t],status)); } case 3: /* FCNVFXT */ switch(fmt) { case 0: /* sgl/sgl */ return(sgl_to_sgl_fcnvfxt(&fpregs[r1],0, &fpregs[t],status)); case 1: /* sgl/dbl */ return(sgl_to_dbl_fcnvfxt(&fpregs[r1],0, &fpregs[t],status)); case 2: /* dbl/sgl */ return(dbl_to_sgl_fcnvfxt(&fpregs[r1],0, &fpregs[t],status)); case 3: /* dbl/dbl */ return(dbl_to_dbl_fcnvfxt(&fpregs[r1],0, &fpregs[t],status)); } case 5: /* FCNVUF (PA2.0 only) */ switch(fmt) { case 0: /* sgl/sgl */ return(sgl_to_sgl_fcnvuf(&fpregs[r1],0, &fpregs[t],status)); case 1: /* sgl/dbl */ return(sgl_to_dbl_fcnvuf(&fpregs[r1],0, &fpregs[t],status)); case 2: /* dbl/sgl */ return(dbl_to_sgl_fcnvuf(&fpregs[r1],0, &fpregs[t],status)); case 3: /* dbl/dbl */ return(dbl_to_dbl_fcnvuf(&fpregs[r1],0, &fpregs[t],status)); } case 6: /* FCNVFU (PA2.0 only) */ switch(fmt) { case 0: /* sgl/sgl */ return(sgl_to_sgl_fcnvfu(&fpregs[r1],0, &fpregs[t],status)); case 1: /* sgl/dbl */ return(sgl_to_dbl_fcnvfu(&fpregs[r1],0, &fpregs[t],status)); case 2: /* dbl/sgl */ return(dbl_to_sgl_fcnvfu(&fpregs[r1],0, &fpregs[t],status)); case 3: /* dbl/dbl */ return(dbl_to_dbl_fcnvfu(&fpregs[r1],0, &fpregs[t],status)); } case 7: /* FCNVFUT (PA2.0 only) */ switch(fmt) { case 0: /* sgl/sgl */ return(sgl_to_sgl_fcnvfut(&fpregs[r1],0, &fpregs[t],status)); case 1: /* sgl/dbl */ return(sgl_to_dbl_fcnvfut(&fpregs[r1],0, &fpregs[t],status)); case 2: /* dbl/sgl */ return(dbl_to_sgl_fcnvfut(&fpregs[r1],0, &fpregs[t],status)); case 3: /* dbl/dbl */ return(dbl_to_dbl_fcnvfut(&fpregs[r1],0, &fpregs[t],status)); } case 4: /* undefined */ return(MAJOR_0C_EXCP); } /* end of switch subop */ case 2: /* class 2 */ /* * Be careful out there. * Crashme can generate cases where FR31R is specified * as the source or target of a double precision operation. * Since we just pass the address of the floating-point * register to the emulation routines, this can cause * corruption of fpzeroreg. */ if (fmt == DBL) r2 = (extru(ir,fpr2pos,5)<<1); else r2 = ((extru(ir,fpr2pos,5)<<1)|(extru(ir,fpxr2pos,1))); fpu_type_flags=fpregs[FPU_TYPE_FLAG_POS]; if (r2 == 0) r2 = fpzeroreg; if (fpu_type_flags & PA2_0_FPU_FLAG) { /* FTEST if nullify bit set, otherwise FCMP */ if (extru(ir, fpnulpos, 1)) { /* FTEST */ /* not legal */ return(MAJOR_0E_EXCP); } else { /* FCMP */ switch (fmt) { /* * fmt is only 1 bit long */ case 0: retval = sgl_fcmp(&fpregs[r1], &fpregs[r2],extru(ir,fptpos,5),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -