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; }
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); }