Пример #1
0
unsigned int EmulateCPRT(const unsigned int opcode)
{

    if (opcode & 0x800000) {
        /* This is some variant of a comparison (PerformComparison
           will sort out which one).  Since most of the other CPRT
           instructions are oddball cases of some sort or other it
           makes sense to pull this out into a fast path.  */
        return PerformComparison(opcode);
    }

    /* Hint to GCC that we'd like a jump table rather than a load of CMPs */
    switch ((opcode & 0x700000) >> 20) {
    case FLT_CODE >> 20:
        return PerformFLT(opcode);
        break;
    case FIX_CODE >> 20:
        return PerformFIX(opcode);
        break;

    case WFS_CODE >> 20:
        writeFPSR(readRegister(getRd(opcode)));
        break;
    case RFS_CODE >> 20:
        writeRegister(getRd(opcode), readFPSR());
        break;

    default:
        return 0;
    }

    return 1;
}
Пример #2
0
unsigned int PerformFIX(const unsigned int opcode)
{
    FPA11 *fpa11 = GET_FPA11();
    unsigned int Fn = getFm(opcode);

    SetRoundingMode(opcode);

    switch (fpa11->fType[Fn]) {
    case typeSingle:
    {
        writeRegister(getRd(opcode), float32_to_int32(fpa11->fpreg[Fn].fSingle));
    }
    break;

    case typeDouble:
    {
        writeRegister(getRd(opcode), float64_to_int32(fpa11->fpreg[Fn].fDouble));
    }
    break;

#ifdef CONFIG_FPE_NWFPE_XP
    case typeExtended:
    {
        writeRegister(getRd(opcode), floatx80_to_int32(fpa11->fpreg[Fn].fExtended));
    }
    break;
#endif

    default:
        return 0;
    }

    return 1;
}
Пример #3
0
unsigned int PerformFLT(const unsigned int opcode)
{
    FPA11 *fpa11 = GET_FPA11();
    struct roundingData roundData;

    roundData.mode = SetRoundingMode(opcode);
    roundData.precision = SetRoundingPrecision(opcode);
    roundData.exception = 0;

    switch (opcode & MASK_ROUNDING_PRECISION) {
    case ROUND_SINGLE:
        {
            fpa11->fType[getFn(opcode)] = typeSingle;
            fpa11->fpreg[getFn(opcode)].fSingle = int32_to_float32(&roundData, readRegister(getRd(opcode)));
        }
        break;

    case ROUND_DOUBLE:
        {
            fpa11->fType[getFn(opcode)] = typeDouble;
            fpa11->fpreg[getFn(opcode)].fDouble = int32_to_float64(readRegister(getRd(opcode)));
        }
        break;

#ifdef CONFIG_FPE_NWFPE_XP
    case ROUND_EXTENDED:
        {
            fpa11->fType[getFn(opcode)] = typeExtended;
            fpa11->fpreg[getFn(opcode)].fExtended = int32_to_floatx80(readRegister(getRd(opcode)));
        }
        break;
#endif

    default:
        return 0;
    }

    if (roundData.exception)
        float_raise(roundData.exception);

    return 1;
}
Пример #4
0
unsigned int PerformFIX(const unsigned int opcode)
{
    FPA11 *fpa11 = GET_FPA11();
    unsigned int Fn = getFm(opcode);
    struct roundingData roundData;

    roundData.mode = SetRoundingMode(opcode);
    roundData.precision = SetRoundingPrecision(opcode);
    roundData.exception = 0;

    switch (fpa11->fType[Fn]) {
    case typeSingle:
        {
            writeRegister(getRd(opcode), float32_to_int32(&roundData, fpa11->fpreg[Fn].fSingle));
        }
        break;

    case typeDouble:
        {
            writeRegister(getRd(opcode), float64_to_int32(&roundData, fpa11->fpreg[Fn].fDouble));
        }
        break;

#ifdef CONFIG_FPE_NWFPE_XP
    case typeExtended:
        {
            writeRegister(getRd(opcode), floatx80_to_int32(&roundData, fpa11->fpreg[Fn].fExtended));
        }
        break;
#endif

    default:
        return 0;
    }

    if (roundData.exception)
        float_raise(roundData.exception);

    return 1;
}