📄 fpi_sigfpe.c
字号:
case FUNC_DIV: switch(fmt){ case FMT_SINGLE: dest.f = src1.f / src2.f; dest_class = fp_class_f(dest.f); break; case FMT_DOUBLE: dest.d = src1.d / src2.d; dest_class = fp_class_d(dest.d); break; default: error = 1; break; } break; case FUNC_ABS: src2_class = -1; switch(fmt){ case FMT_SINGLE: dest.f = absf_instr(src1.f); dest_class = fp_class_f(dest.f); break; case FMT_DOUBLE: dest.d = absd_instr(src1.d); dest_class = fp_class_d(dest.d); break; default: error = 1; break; } break; case FUNC_MOV: src2_class = -1; switch(fmt){ case FMT_SINGLE: dest.f = src1.f; dest_class = fp_class_f(dest.f); break; case FMT_DOUBLE: dest.d = src1.d; dest_class = fp_class_d(dest.d); break; default: error = 1; break; } if(src1_class == FP_POS_ZERO || src1_class == FP_NEG_ZERO){ fpi_counts[FPI_MOVEZERO]++; counted = 1; } break; case FUNC_NEG: src2_class = -1; switch(fmt){ case FMT_SINGLE: dest.f = -src1.f; dest_class = fp_class_f(dest.f); break; case FMT_DOUBLE: dest.d = -src1.d; dest_class = fp_class_d(dest.d); break; default: error = 1; break; } if(src1_class == FP_POS_ZERO || src1_class == FP_NEG_ZERO){ fpi_counts[FPI_NEGZERO]++; counted = 1; } break; case FUNC_SQRT: src2_class = -1; switch(fmt){ case FMT_SINGLE: dest.f = sqrtf_instr(src1.f); dest_class = fp_class_f(dest.f); break; case FMT_DOUBLE: dest.d = sqrtd_instr(src1.d); dest_class = fp_class_d(dest.d); break; default: error = 1; break; } fpi_counts[FPI_UNIMP]++; counted = 1; break; default: if(func & FUNC_FC){ dest_fmt = -1; dest_class = -1; fpc_csr.fc_word = scp->sc_fpc_csr; fpc_csr.fc_struct.condition = 0; scp->sc_fpc_csr = fpc_csr.fc_word; switch(fmt){ case FMT_SINGLE: cmpf_instr(src1.f, src2.f, (func & ~FUNC_FC) << 2); break; case FMT_DOUBLE: cmpd_instr(src1.d, src2.d, (func & ~FUNC_FC) << 2); break; default: error = 1; break; } break; }else error = 1; } source_class(src1_class); source_class(src2_class); if(!counted){ fpc_csr.fc_word = get_fpc_csr(); if(fpc_csr.fc_struct.se_invalid){ fpi_counts[FPI_INVALID]++; counted = 1; } else if(fpc_csr.fc_struct.se_divide0){ fpi_counts[FPI_DIVIDE0]++; counted = 1; } else if(fpc_csr.fc_struct.se_underflow || dest_class == FP_POS_DENORM || dest_class == FP_NEG_DENORM){ fpi_counts[FPI_UNDERFLOW]++; counted = 1; } else if(fpc_csr.fc_struct.se_overflow){ fpi_counts[FPI_OVERFLOW]++; counted = 1; } }#ifdef DEBUG if(!counted){ fprintf(stderr, "Unknown reason for interrupt\n"); error = 1; } if(error){ help(fpc_csr.fc_word, src1_fmt, src2_fmt, dest_fmt, &src1, &src2, &dest); }#endif DEBUG /* * Now if the floating point unit is the board implementation * and the floating-point destination and fpc_csr must be stored. * The next floating-point interrupt is set to cause a SIGFPE * since this one was emulated here and is not going to be re-excuted. */ if(fpc_irr.fi_struct.implementation == IMPLEMENTATION_R2360){ if(fp_sigintr(1) == -1){ fprintf(stderr, "sigfpe(): Error: system call fp_sigintr(1) failed (%s)\n", sys_errlist[errno]); exit(1); } reg = fpu_instr.rtype.rd; switch(dest_fmt){ case FMT_SINGLE: case FMT_WORD: scp->sc_fpregs[reg] = dest.v.v0; break; case FMT_DOUBLE:#ifdef MIPSEL scp->sc_fpregs[reg] = dest.v.v0; scp->sc_fpregs[reg+1] = dest.v.v1;#endif MIPSEL#ifdef MIPSEB scp->sc_fpregs[reg+1] = dest.v.v0; scp->sc_fpregs[reg] = dest.v.v1;#endif MIPSEB break; default: break; } scp->sc_fpc_csr |= get_fpc_csr(); sigreturn(scp); } /* * In the case the floating point unit is not the board implementation * and the floating-point destination is not stored. By returning the * floating-point instruction will again be executed and the next * floating-point interrupt is set to not cause a SIGFPE. */ else{ if(fp_sigintr(2) == -1){ fprintf(stderr, "sigfpe(): Error: system call fp_sigintr(2) failed (%s)\n", sys_errlist[errno]); exit(1); } }}staticvoidsource_class(class)int class;{ if(counted) return; if(class == FP_SNAN){ fpi_counts[FPI_SRCSNAN]++; counted = 1; return; } if(class == FP_QNAN){ fpi_counts[FPI_SRCQNAN]++; counted = 1; return; } if(class == FP_POS_DENORM || class == FP_NEG_DENORM){ fpi_counts[FPI_SRCDENORM]++; counted = 1; return; }} #ifdef DEBUGstatic void print_header();static long get_bytes();staticvoidhelp(fpc_csr, src1_fmt, src2_fmt, dest_fmt, src1, src2, dest)int fpc_csr, src1_fmt, src2_fmt, dest_fmt;union value *src1, *src2, *dest;{ printf("\tfpc_csr = "); print_csr(fpc_csr); printf("\tinstr = 0x%08x\n",instr); disassembler(0, 1, 0, 0, get_bytes, print_header); switch(src1_fmt){ case FMT_SINGLE: printf("\tsrc1 (single) = 0x%08x %g\n", src1->v.v0, src1->f); break; case FMT_DOUBLE: printf("\tsrc1 (double) = 0x%08x %08x %g\n", src1->v.v0, src1->v.v1, src1->d); break; case FMT_EXTENDED: printf("\tsrc1 (extended) = 0x%08x %08x %08x %08x\n", src1->v.v0, src1->v.v1, src1->v.v2, src1->v.v3); break; case FMT_QUAD: printf("\tsrc1 (quad) = 0x%08x %08x %08x %08x\n", src1->v.v0, src1->v.v1, src1->v.v2, src1->v.v3); break; case FMT_WORD: printf("\tsrc1 (word) = 0x%08x %d\n", src1->v.v0, src1->w); break; } switch(src2_fmt){ case FMT_SINGLE: printf("\tsrc2 (single) = 0x%08x %g\n", src2->v.v0, src2->f); break; case FMT_DOUBLE: printf("\tsrc2 (double) = 0x%08x %08x %g\n", src2->v.v0, src2->v.v1, src2->d); break; case FMT_EXTENDED: printf("\tsrc2 (extended) = 0x%08x %08x %08x %08x\n", src2->v.v0, src2->v.v1, src2->v.v2, src2->v.v3); break; case FMT_QUAD: printf("\tsrc2 (quad) = 0x%08x %08x %08x %08x\n", src2->v.v0, src2->v.v1, src2->v.v2, src2->v.v3); break; case FMT_WORD: printf("\tsrc2 (word) = 0x%08x %g\n", src2->v.v0, src2->d); break; } switch(dest_fmt){ case FMT_SINGLE: printf("\tdest (single) = 0x%08x %g\n", dest->v.v0, dest->f); break; case FMT_DOUBLE: printf("\tdest (double) = 0x%08x %08x %g\n", dest->v.v0, dest->v.v1, dest->d); break; case FMT_EXTENDED: printf("\tdest (extended) = 0x%08x %08x %08x %08x\n", dest->v.v0, dest->v.v1, dest->v.v2, dest->v.v3); break; case FMT_QUAD: printf("\tdest (quad) = 0x%08x %08x %08x %08x\n", dest->v.v0, dest->v.v1, dest->v.v2, dest->v.v3); break; case FMT_WORD: printf("\tdest (word) = 0x%08x %d\n", dest->v.v0, dest->w); break; }}print_csr(csr)long csr;{ printf("0x%08x ", csr); if(csr & 1<<23) printf("T "); else printf("F "); if(csr & 1<<17) printf("E"); else printf("-"); if(csr & 1<<16) printf("V"); else printf("-"); if(csr & 1<<15) printf("Z"); else printf("-"); if(csr & 1<<14) printf("O"); else printf("-"); if(csr & 1<<13) printf("U"); else printf("-"); if(csr & 1<<12) printf("I "); else printf("- "); if(csr & 1<<11) printf("V"); else printf("-"); if(csr & 1<<10) printf("Z"); else printf("-"); if(csr & 1<<9) printf("O"); else printf("-"); if(csr & 1<<8) printf("U"); else printf("-"); if(csr & 1<<7) printf("I "); else printf("- "); if(csr & 1<<6) printf("V"); else printf("-"); if(csr & 1<<5) printf("Z"); else printf("-"); if(csr & 1<<4) printf("O"); else printf("-"); if(csr & 1<<3) printf("U"); else printf("-"); if(csr & 1<<2) printf("I "); else printf("- "); switch(csr & 0x3){ case 0: printf("RN\n"); break; case 1: printf("RZ\n"); break; case 2: printf("RPI\n"); break; case 3: printf("RMI\n"); break; }}staticlongget_bytes(){ return(instr);}staticvoidprint_header(){ printf("\t");}#endif DEBUG
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -