Esempio n. 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;
}
Esempio n. 2
0
void float_raise(signed char flags)
{
	register unsigned int fpsr, cumulativeTraps;

#ifdef CONFIG_DEBUG_USER
	printk(KERN_DEBUG
	       "NWFPE: %s[%d] takes exception %08x at %p from %08lx\n",
	       current->comm, current->pid, flags,
	       __builtin_return_address(0), GET_USERREG()[15]);
#endif

	/* Keep SoftFloat exception flags up to date.  */
	float_exception_flags |= flags;

	/* Read fpsr and initialize the cumulativeTraps.  */
	fpsr = readFPSR();
	cumulativeTraps = 0;

	/* For each type of exception, the cumulative trap exception bit is only
	   set if the corresponding trap enable bit is not set.  */
	if ((!(fpsr & BIT_IXE)) && (flags & BIT_IXC))
		cumulativeTraps |= BIT_IXC;
	if ((!(fpsr & BIT_UFE)) && (flags & BIT_UFC))
		cumulativeTraps |= BIT_UFC;
	if ((!(fpsr & BIT_OFE)) && (flags & BIT_OFC))
		cumulativeTraps |= BIT_OFC;
	if ((!(fpsr & BIT_DZE)) && (flags & BIT_DZC))
		cumulativeTraps |= BIT_DZC;
	if ((!(fpsr & BIT_IOE)) && (flags & BIT_IOC))
		cumulativeTraps |= BIT_IOC;

	/* Set the cumulative exceptions flags.  */
	if (cumulativeTraps)
		writeFPSR(fpsr | cumulativeTraps);

	/* Raise an exception if necessary.  */
	if (fpsr & (flags << 16))
		fp_send_sig(SIGFPE, current, 1);
}