📄 shfloat.c
字号:
// store emulation result back to context *fpRegN1 = dp2.high; *fpRegN2 = dp2.low; } }else { fp1.i = *fpRegN1; fp2.i = *fpRegM1; switch(OpcodeExt) { case FADD_OP: function = (void*)&_adds; break; case FSUB_OP: function = (void*)&_subs; break; case FMUL_OP: function = (void*)&_muls; break; case FDIV_OP: function = (void*)&_divs; break; case FCMP_EQ: function = (void*)&_eqs; break; case FCMP_GT: function = (void*)&_gts; break; } if ((OpcodeExt == FCMP_EQ) || (OpcodeExt == FCMP_GT)) { fp1.i = ((int(*)(float,float))(function))(fp1.f, fp2.f); // // If SR-tbit is not matched retval from CRT compare, // then update SR-tbit to match retval from // CRT compare. // pctx->Psr &= (0xfffffffe & (fp1.i != 0)); }else { fp1.f = ((float(*)(float,float))(function))(fp1.f,fp2.f); *fpRegN1 = fp1.i; } } break; case 0xd: // // All these functions take one operand only. // switch(RegM) { case FLOAT_OP: if (prbit) { // float fpul,drn fp1.i = pctx->Fpul; dp1.d = _itod(fp1.i); *fpRegN1 = dp1.high; *fpRegN2 = dp1.low; }else { // float fpul, frn fp1.i = pctx->Fpul; fp1.f = _itos(fp1.i); *fpRegN1 = fp1.i; } break; case FTRC_OP: if (prbit) { // ftrc drn,fpul dp1.high = *fpRegM1; dp1.low = *fpRegM2; dp1.high = _dtoi(dp1.d); *fpRegN1 = dp1.high; }else{ // ftrc frn,fpul fp1.i = *fpRegM1; fp1.i = _stoi(fp1.f); *fpRegN1 = fp1.i; } break; case FSQRT_OP: // fsqrt drn if (prbit) { dp1.high = *fpRegN1; dp1.low = *fpRegN2; dp1.d = sqrt(dp1.d); *fpRegN1 = dp1.high; *fpRegN2 = dp1.low; }else { fp1.i = *fpRegN1; fp1.f = (float)sqrt((double)fp1.f); *fpRegN1 = fp1.i; } break; case FCNVSD_OP: //fcnvsd fpul, drn if (prbit) { fp1.i = pctx->Fpul; dp1.d = _stod(fp1.f); // copy result back to user context *fpRegN1 = dp1.high; *fpRegN2 = dp1.low; }else{ // else undefined operation // propagate exception to user retVal = 0; } break; case FCNVDS_OP: // fcnvds drn,fpul if (prbit) { dp1.high = *fpRegN1; dp1.low = *fpRegN2; fp1.f = _dtos(dp1.d); // copy result back to user context pctx->Fpul = fp1.i; }else{ // else undefined operation // propagate exception to user retVal = 0; } break; case FIPR_OP: // // Recalculated RegN and RegM for FIPR instr // fipr has opcode 1111 nnmm 1110 1101 // nn -- represent fvn // mm -- represent fvm // if (prbit) { // else undefined operation // propagate exception to user retVal = 0; }else { RegN = (RegN & 0xc); RegM = ((RegM & 0x3) << 2); if (!frbit) { pFVn = pctx->FRegs + RegN; pFVm = pctx->FRegs + RegM; } else { pFVn = pctx->xFRegs + RegN; pFVm = pctx->xFRegs + RegM; } fipr(pFVm, pFVn); } break; case FTRV_OP: if (prbit) { // else undefined operation // propagate exception to user retVal = 0; }else{ // // Recalculated RegN for ftrv instruction // ftrv has opcode 1111 nn01 1111 1101 // instruction format for ftrv xmtrx,fvn // nn -- represent fvn // if (!frbit) { pXMTRX = pctx->xFRegs; pFVn = pctx->FRegs + (RegN -1); }else { pXMTRX = pctx->FRegs; pFVn = pctx->xFRegs + (RegN -1); } ftrv(pXMTRX, pFVn); } break; } // switch(RegM) break; // end case 0xd case FMAC_OP: // // need to handle differently, // call _muls, then _adds // if (prbit) { // undefined operation // propagate exception to user retVal = 0; } else { if (!frbit) { fp1.i = pctx->FRegs[0]; }else{ fp1.i = pctx->xFRegs[0]; } fp2.i = *fpRegM1; fp2.f = _muls(fp1.f,fp2.f); fp1.i = *fpRegN1; fp2.f= _adds(fp1.f,fp2.f); *fpRegN1 = fp2.i; } break; default: NKDbgPrintfW(L"HandleHWFloatException: UNKNOWN INSTRUCTION.\r\n"); break; } // switch(opcode) }_finally{ // pr in fpscr is currently cleared // write fpscr into user thread pctx->Fpscr = get_fpscr(); // ensure that pr is set correctly in user context fpscr if (prbit) { pctx->Fpscr |= PR; } CauseField = (pctx->Fpscr & 0x0003f000)>>12; if (CauseField & 0x10) ExceptionRecord->ExceptionCode = STATUS_FLOAT_INVALID_OPERATION; else if (CauseField & 0x8) ExceptionRecord->ExceptionCode = STATUS_FLOAT_DIVIDE_BY_ZERO; else if (CauseField & 0x4) ExceptionRecord->ExceptionCode = STATUS_FLOAT_OVERFLOW; else if (CauseField & 0x2) ExceptionRecord->ExceptionCode = STATUS_FLOAT_UNDERFLOW; else if (CauseField & 0x1) ExceptionRecord->ExceptionCode = STATUS_FLOAT_INEXACT_RESULT;//#define DEBUG_STRING#ifdef DEBUG_STRING else if(_abnormal_termination()) { NKDbgPrintfW(L"An exception occur after enumlation call in HandleHWFloatException\r\n"); NKDbgPrintfW(L"fpscr status: 0x%x\r\n", get_fpscr()); }#endif } }__except(1){ // // fp emulation raised exception, // return 0 causes exception to be propagated to user. // return 0; } // // fp operation successfully emulated, return 1 causes control to // return to succeeding instruction. // return retVal;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -