⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shfloat.c

📁 windows ce 3.00 嵌入式操作系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:

                        // 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 + -