| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 | 
							- /*
 
-     NetWinder Floating Point Emulator
 
-     (c) Rebel.COM, 1998,1999
 
-     (c) Philip Blundell, 1999, 2001
 
-     Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
 
-     This program is free software; you can redistribute it and/or modify
 
-     it under the terms of the GNU General Public License as published by
 
-     the Free Software Foundation; either version 2 of the License, or
 
-     (at your option) any later version.
 
-     This program is distributed in the hope that it will be useful,
 
-     but WITHOUT ANY WARRANTY; without even the implied warranty of
 
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
-     GNU General Public License for more details.
 
-     You should have received a copy of the GNU General Public License
 
-     along with this program; if not, write to the Free Software
 
-     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
- */
 
- #include "fpa11.h"
 
- #include "fpopcode.h"
 
- #include "fpa11.inl"
 
- #include "fpmodule.h"
 
- #include "fpmodule.inl"
 
- #include "softfloat.h"
 
- unsigned int PerformFLT(const unsigned int opcode);
 
- unsigned int PerformFIX(const unsigned int opcode);
 
- static unsigned int PerformComparison(const unsigned int opcode);
 
- 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;
 
- }
 
- 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);
 
 
  |