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

📄 shfloat.c

📁 wince下的源代码集合打包
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Copyright (c) 1999-2000 Microsoft Corporation.  All rights reserved. */#ifdef SH4#include "kernel.h"#include "shxinst.h"// fp instruction opcodes#define FADD_OP   0x0#define FSUB_OP   0x1#define FMUL_OP   0x2#define FDIV_OP   0x3#define FCMP_EQ   0x4#define FCMP_GT   0x5#define FMAC_OP   0xe// all these instrs have a last // common opcode is 0xd#define FLOAT_OP  0x2#define FTRC_OP   0x3#define FSQRT_OP  0x6#define FCNVSD_OP 0xa#define FCNVDS_OP 0xb#define FIPR_OP   0xe#define FTRV_OP   0xf// fpscr bit masks#define FR              0x00200000       // FR#define SZ              0x00100000       // SZ#define PR              0x00080000       // PR#define DN              0x00040000       // DN#define IMCW_ENABLE     0x00000f80       // Enable mask#define E_INVALID       0x00000800       // Invalid operation#define E_ZERODIVIDE    0x00000400       // Divide by zero#define E_OVERFLOW      0x00000200       // Overflow#define E_UNDERFLOW     0x00000100       // Underflow#define E_INEXACT       0x00000080       // Inexact result#define IMCW_CAUSE	0x0001f000	 // Cause mask#define C_INVALID       0x00010000	 // Invalid operation#define C_ZERODIVIDE    0x00008000	 // Divide by 0#define C_OVERFLOW      0x00004000	 // Overflow#define C_UNDERFLOW     0x00002000	 // Underflow#define C_INEXACT       0x00001000	 // Inexact result#define IMCW_FLAG	0x0000007c	 // Flag maskextern float _adds(float,float);extern float _subs(float,float);extern float _muls(float,float);extern float _divs(float,float);extern int _eqs(float,float);extern int _gts(float,float);extern double _addd(double, double);extern double _subd(double, double);extern double _muld(double, double);extern double _divd(double, double);extern int _eqd(double,double);extern int _gtd(double,double);extern float _itos(int);extern double _itod(int);extern int _stoi(float);extern int _dtoi(double);extern double sqrt(double);extern float  fsqrt(float);extern double _stod(float);extern float  _dtos(double);extern ULONG __asm1(const char *,...);typedef struct _FP_DOUBLE_OPERAND {    union {        struct {            ULONG low;            LONG  high;        };        double d;    };} FP_DOUBLE_OPERAND, *PFP_DOUBLE_OPERAND;typedef union _FP_SINGLE_OPERAND {    ULONG i;    float f;} FP_SINGLE_OPERAND, *PFP_SINGLE_OPERAND;void set_fpscr(ULONG mask){    __asm("sts  fpscr, r0\n"          "or   r4, r0\n"          "lds  r0, fpscr\n",          mask);}void clr_fpscr(ULONG mask){    __asm("sts fpscr, r0\n"          "not r4, r4\n"          "and r4, r0\n"          "lds r0, fpscr\n",          mask);}ULONG get_cause(){    return __asm1("sts fpscr, r0\n"                  "and r4,r0\n"                  "shlr8 r0\n"                  "shlr2 r0\n"                  "shlr2 r0\n",                  0x3f00);}ULONG get_fpscr(void){    return __asm1("sts fpscr,r0\n");}void fipr(ULONG *pFVm, ULONG *pFVn){    float result=0.0f;    FP_SINGLE_OPERAND fp1,fp2;    fp1.i = (*pFVm)++;    fp2.i = (*pFVn)++;    result = _muls(fp1.f,fp2.f);        fp1.i = (*pFVm)++;    fp2.i = (*pFVn)++;    fp2.f = _muls(fp1.f,fp2.f);    result = _adds(fp2.f,result);    fp1.i = (*pFVm)++;    fp2.i = (*pFVn)++;    fp2.f = _muls(fp1.f,fp2.f);    result = _adds(fp2.f,result);    fp1.i = (*pFVm);    fp2.i = (*pFVn);    fp2.f = _muls(fp1.f,fp2.f);    fp2.f = _adds(fp2.f,result);    *pFVn = fp2.i;}void ftrv(ULONG *pXMTRX, ULONG *pFVn){    int i;    float result=0.0f;    FP_SINGLE_OPERAND fp1,fp2;    ULONG *pResult = pFVn;    ULONG *pFV = pFVn;    for (i=0; i < 4; i++)    {        result = 0.0f;        fp1.i = (*pXMTRX)++;        fp2.i = (*pFV)++;        fp2.f =  _muls(fp1.f,fp2.f);        result = _adds(fp2.f,result);        fp1.i = (*pXMTRX)++;        fp2.i = (*pFV)++;        fp2.f = _muls(fp1.f,fp2.f);        result = _adds(fp2.f,result);        fp1.i = (*pXMTRX)++;        fp2.i = (*pFV)++;        fp2.f = _muls(fp1.f,fp2.f);        result = _adds(fp2.f,result);        fp1.i = (*pXMTRX)++;        fp2.i = (*pFV);        fp2.f = _muls(fp1.f,fp2.f);        fp2.f = _adds(fp2.f,result);        //        // store result to FV[n,n+1,n+2,n+3]        //        *pResult++ = fp2.i;        //        // reset the pFV to beginning of pFVn        //        pFV = pFVn;    }}BOOL HandleHWFloatException(EXCEPTION_RECORD *ExceptionRecord,                            PCONTEXT pctx) {    PVOID ExceptionAddress;    SH3IW Instruction;    ULONG OpcodeExt, RegM, RegN, Opcode;    ULONG prbit, frbit, CauseField;    FP_DOUBLE_OPERAND dp1,dp2;    FP_SINGLE_OPERAND fp1,fp2;    ULONG *fpRegN1, *fpRegM1, *fpRegN2, *fpRegM2;    ULONG *pFVn, *pFVm, *pXMTRX;    char f[10];    void *function = f;    int retVal = 1;    ExceptionAddress = ExceptionRecord->ExceptionAddress;    __try {        __try {            Instruction = *(PSH3IW)ExceptionRecord->ExceptionAddress;            OpcodeExt = Instruction.instr3.ext_disp;            RegM = Instruction.instr3.regM;            RegN = Instruction.instr3.regN;            Opcode = Instruction.instr3.opcode;            // check for double operation            prbit =  ((pctx->Fpscr & PR) != 0);            // check for float-point bank operation            frbit =  ((pctx->Fpscr & FR) != 0);            // reset fpscr to thread state            clr_fpscr(0xffffffff);            set_fpscr(pctx->Fpscr);            // clear PR bit            clr_fpscr(PR);            if(!frbit)            {                fpRegN1 = pctx->FRegs + RegN;                fpRegM1 = pctx->FRegs + RegM;                if (prbit)                {                    fpRegN2 = pctx->FRegs + RegN+1;                    fpRegM2 = pctx->FRegs + RegM+1;                }                            }else {                fpRegN1 = pctx->xFRegs + RegN;                fpRegM1 = pctx->xFRegs + RegM;                if (prbit)                {                    fpRegN2 = pctx->xFRegs + RegN + 1;                    fpRegM2 = pctx->xFRegs + RegM + 1;                }            }                        switch(OpcodeExt)            {            case FADD_OP:            case FSUB_OP:            case FMUL_OP:            case FDIV_OP:                if(prbit)                {                    dp1.high = *fpRegN1;                    dp1.low  = *fpRegN2;                    dp2.high = *fpRegM1;                    dp2.low  = *fpRegM2;                    switch(OpcodeExt)                    {                    case FADD_OP:                        function = (void*)&_addd;                        break;                    case FSUB_OP:                            function = (void*)&_subd;                        break;                    case FMUL_OP:                            function = (void*)&_muld;                        break;                    case FDIV_OP:                        function = (void*)&_divd;                        break;                    case FCMP_EQ:                        function = (void*)&_eqd;                        break;                    case FCMP_GT:                        function = (void*)&_gtd;                        break;                    }                    if ((OpcodeExt == FCMP_EQ) || (OpcodeExt == FCMP_GT))                    {                        dp2.low = ((int(*)(double,double))(function))(dp1.d,dp2.d);                        // set user t-bit to comparison result                        pctx->Psr &= (0xfffffffe & (dp2.low != 0));                                            }else {                                            dp2.d = ((double(*)(double,double))(function))(dp1.d,dp2.d);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -