diff options
author | aurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-04-09 06:53:01 +0000 |
---|---|---|
committer | aurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-04-09 06:53:01 +0000 |
commit | 3ebdd11939b83b9fd2f27029cd86c1153e51e3a3 (patch) | |
tree | 5070ab4c1cc2324d79b441824b078f54ed612821 /target-arm | |
parent | e771edab0d9aaa7925dc26aec3e0c6eac27f19c3 (diff) | |
download | qemu-3ebdd11939b83b9fd2f27029cd86c1153e51e3a3.zip qemu-3ebdd11939b83b9fd2f27029cd86c1153e51e3a3.tar.gz qemu-3ebdd11939b83b9fd2f27029cd86c1153e51e3a3.tar.bz2 |
Move target-arm/nwfpe into linux-user/arm/nwfpe
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4185 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-arm')
-rw-r--r-- | target-arm/nwfpe/double_cpdo.c | 296 | ||||
-rw-r--r-- | target-arm/nwfpe/extended_cpdo.c | 273 | ||||
-rw-r--r-- | target-arm/nwfpe/fpa11.c | 244 | ||||
-rw-r--r-- | target-arm/nwfpe/fpa11.h | 122 | ||||
-rw-r--r-- | target-arm/nwfpe/fpa11.inl | 51 | ||||
-rw-r--r-- | target-arm/nwfpe/fpa11_cpdo.c | 117 | ||||
-rw-r--r-- | target-arm/nwfpe/fpa11_cpdt.c | 386 | ||||
-rw-r--r-- | target-arm/nwfpe/fpa11_cprt.c | 286 | ||||
-rw-r--r-- | target-arm/nwfpe/fpopcode.c | 148 | ||||
-rw-r--r-- | target-arm/nwfpe/fpopcode.h | 390 | ||||
-rw-r--r-- | target-arm/nwfpe/fpsr.h | 108 | ||||
-rw-r--r-- | target-arm/nwfpe/single_cpdo.c | 253 |
12 files changed, 0 insertions, 2674 deletions
diff --git a/target-arm/nwfpe/double_cpdo.c b/target-arm/nwfpe/double_cpdo.c deleted file mode 100644 index b5320c8..0000000 --- a/target-arm/nwfpe/double_cpdo.c +++ /dev/null @@ -1,296 +0,0 @@ -/* - NetWinder Floating Point Emulator - (c) Rebel.COM, 1998,1999 - - 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 "softfloat.h" -#include "fpopcode.h" - -float64 float64_exp(float64 Fm); -float64 float64_ln(float64 Fm); -float64 float64_sin(float64 rFm); -float64 float64_cos(float64 rFm); -float64 float64_arcsin(float64 rFm); -float64 float64_arctan(float64 rFm); -float64 float64_log(float64 rFm); -float64 float64_tan(float64 rFm); -float64 float64_arccos(float64 rFm); -float64 float64_pow(float64 rFn,float64 rFm); -float64 float64_pol(float64 rFn,float64 rFm); - -unsigned int DoubleCPDO(const unsigned int opcode) -{ - FPA11 *fpa11 = GET_FPA11(); - float64 rFm, rFn = float64_zero; - unsigned int Fd, Fm, Fn, nRc = 1; - - //printk("DoubleCPDO(0x%08x)\n",opcode); - - Fm = getFm(opcode); - if (CONSTANT_FM(opcode)) - { - rFm = getDoubleConstant(Fm); - } - else - { - switch (fpa11->fType[Fm]) - { - case typeSingle: - rFm = float32_to_float64(fpa11->fpreg[Fm].fSingle, &fpa11->fp_status); - break; - - case typeDouble: - rFm = fpa11->fpreg[Fm].fDouble; - break; - - case typeExtended: - // !! patb - //printk("not implemented! why not?\n"); - //!! ScottB - // should never get here, if extended involved - // then other operand should be promoted then - // ExtendedCPDO called. - break; - - default: return 0; - } - } - - if (!MONADIC_INSTRUCTION(opcode)) - { - Fn = getFn(opcode); - switch (fpa11->fType[Fn]) - { - case typeSingle: - rFn = float32_to_float64(fpa11->fpreg[Fn].fSingle, &fpa11->fp_status); - break; - - case typeDouble: - rFn = fpa11->fpreg[Fn].fDouble; - break; - - default: return 0; - } - } - - Fd = getFd(opcode); - /* !! this switch isn't optimized; better (opcode & MASK_ARITHMETIC_OPCODE)>>24, sort of */ - switch (opcode & MASK_ARITHMETIC_OPCODE) - { - /* dyadic opcodes */ - case ADF_CODE: - fpa11->fpreg[Fd].fDouble = float64_add(rFn,rFm, &fpa11->fp_status); - break; - - case MUF_CODE: - case FML_CODE: - fpa11->fpreg[Fd].fDouble = float64_mul(rFn,rFm, &fpa11->fp_status); - break; - - case SUF_CODE: - fpa11->fpreg[Fd].fDouble = float64_sub(rFn,rFm, &fpa11->fp_status); - break; - - case RSF_CODE: - fpa11->fpreg[Fd].fDouble = float64_sub(rFm,rFn, &fpa11->fp_status); - break; - - case DVF_CODE: - case FDV_CODE: - fpa11->fpreg[Fd].fDouble = float64_div(rFn,rFm, &fpa11->fp_status); - break; - - case RDF_CODE: - case FRD_CODE: - fpa11->fpreg[Fd].fDouble = float64_div(rFm,rFn, &fpa11->fp_status); - break; - -#if 0 - case POW_CODE: - fpa11->fpreg[Fd].fDouble = float64_pow(rFn,rFm); - break; - - case RPW_CODE: - fpa11->fpreg[Fd].fDouble = float64_pow(rFm,rFn); - break; -#endif - - case RMF_CODE: - fpa11->fpreg[Fd].fDouble = float64_rem(rFn,rFm, &fpa11->fp_status); - break; - -#if 0 - case POL_CODE: - fpa11->fpreg[Fd].fDouble = float64_pol(rFn,rFm); - break; -#endif - - /* monadic opcodes */ - case MVF_CODE: - fpa11->fpreg[Fd].fDouble = rFm; - break; - - case MNF_CODE: - { - unsigned int *p = (unsigned int*)&rFm; -#ifdef WORDS_BIGENDIAN - p[0] ^= 0x80000000; -#else - p[1] ^= 0x80000000; -#endif - fpa11->fpreg[Fd].fDouble = rFm; - } - break; - - case ABS_CODE: - { - unsigned int *p = (unsigned int*)&rFm; -#ifdef WORDS_BIGENDIAN - p[0] &= 0x7fffffff; -#else - p[1] &= 0x7fffffff; -#endif - fpa11->fpreg[Fd].fDouble = rFm; - } - break; - - case RND_CODE: - case URD_CODE: - fpa11->fpreg[Fd].fDouble = float64_round_to_int(rFm, &fpa11->fp_status); - break; - - case SQT_CODE: - fpa11->fpreg[Fd].fDouble = float64_sqrt(rFm, &fpa11->fp_status); - break; - -#if 0 - case LOG_CODE: - fpa11->fpreg[Fd].fDouble = float64_log(rFm); - break; - - case LGN_CODE: - fpa11->fpreg[Fd].fDouble = float64_ln(rFm); - break; - - case EXP_CODE: - fpa11->fpreg[Fd].fDouble = float64_exp(rFm); - break; - - case SIN_CODE: - fpa11->fpreg[Fd].fDouble = float64_sin(rFm); - break; - - case COS_CODE: - fpa11->fpreg[Fd].fDouble = float64_cos(rFm); - break; - - case TAN_CODE: - fpa11->fpreg[Fd].fDouble = float64_tan(rFm); - break; - - case ASN_CODE: - fpa11->fpreg[Fd].fDouble = float64_arcsin(rFm); - break; - - case ACS_CODE: - fpa11->fpreg[Fd].fDouble = float64_arccos(rFm); - break; - - case ATN_CODE: - fpa11->fpreg[Fd].fDouble = float64_arctan(rFm); - break; -#endif - - case NRM_CODE: - break; - - default: - { - nRc = 0; - } - } - - if (0 != nRc) fpa11->fType[Fd] = typeDouble; - return nRc; -} - -#if 0 -float64 float64_exp(float64 rFm) -{ - return rFm; -//series -} - -float64 float64_ln(float64 rFm) -{ - return rFm; -//series -} - -float64 float64_sin(float64 rFm) -{ - return rFm; -//series -} - -float64 float64_cos(float64 rFm) -{ - return rFm; - //series -} - -#if 0 -float64 float64_arcsin(float64 rFm) -{ -//series -} - -float64 float64_arctan(float64 rFm) -{ - //series -} -#endif - -float64 float64_log(float64 rFm) -{ - return float64_div(float64_ln(rFm),getDoubleConstant(7)); -} - -float64 float64_tan(float64 rFm) -{ - return float64_div(float64_sin(rFm),float64_cos(rFm)); -} - -float64 float64_arccos(float64 rFm) -{ -return rFm; - //return float64_sub(halfPi,float64_arcsin(rFm)); -} - -float64 float64_pow(float64 rFn,float64 rFm) -{ - return float64_exp(float64_mul(rFm,float64_ln(rFn))); -} - -float64 float64_pol(float64 rFn,float64 rFm) -{ - return float64_arctan(float64_div(rFn,rFm)); -} -#endif diff --git a/target-arm/nwfpe/extended_cpdo.c b/target-arm/nwfpe/extended_cpdo.c deleted file mode 100644 index 05e32b0..0000000 --- a/target-arm/nwfpe/extended_cpdo.c +++ /dev/null @@ -1,273 +0,0 @@ -/* - NetWinder Floating Point Emulator - (c) Rebel.COM, 1998,1999 - - 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 "softfloat.h" -#include "fpopcode.h" - -floatx80 floatx80_exp(floatx80 Fm); -floatx80 floatx80_ln(floatx80 Fm); -floatx80 floatx80_sin(floatx80 rFm); -floatx80 floatx80_cos(floatx80 rFm); -floatx80 floatx80_arcsin(floatx80 rFm); -floatx80 floatx80_arctan(floatx80 rFm); -floatx80 floatx80_log(floatx80 rFm); -floatx80 floatx80_tan(floatx80 rFm); -floatx80 floatx80_arccos(floatx80 rFm); -floatx80 floatx80_pow(floatx80 rFn,floatx80 rFm); -floatx80 floatx80_pol(floatx80 rFn,floatx80 rFm); - -unsigned int ExtendedCPDO(const unsigned int opcode) -{ - FPA11 *fpa11 = GET_FPA11(); - floatx80 rFm, rFn; - unsigned int Fd, Fm, Fn, nRc = 1; - - //printk("ExtendedCPDO(0x%08x)\n",opcode); - - Fm = getFm(opcode); - if (CONSTANT_FM(opcode)) - { - rFm = getExtendedConstant(Fm); - } - else - { - switch (fpa11->fType[Fm]) - { - case typeSingle: - rFm = float32_to_floatx80(fpa11->fpreg[Fm].fSingle, &fpa11->fp_status); - break; - - case typeDouble: - rFm = float64_to_floatx80(fpa11->fpreg[Fm].fDouble, &fpa11->fp_status); - break; - - case typeExtended: - rFm = fpa11->fpreg[Fm].fExtended; - break; - - default: return 0; - } - } - - if (!MONADIC_INSTRUCTION(opcode)) - { - Fn = getFn(opcode); - switch (fpa11->fType[Fn]) - { - case typeSingle: - rFn = float32_to_floatx80(fpa11->fpreg[Fn].fSingle, &fpa11->fp_status); - break; - - case typeDouble: - rFn = float64_to_floatx80(fpa11->fpreg[Fn].fDouble, &fpa11->fp_status); - break; - - case typeExtended: - rFn = fpa11->fpreg[Fn].fExtended; - break; - - default: return 0; - } - } - - Fd = getFd(opcode); - switch (opcode & MASK_ARITHMETIC_OPCODE) - { - /* dyadic opcodes */ - case ADF_CODE: - fpa11->fpreg[Fd].fExtended = floatx80_add(rFn,rFm, &fpa11->fp_status); - break; - - case MUF_CODE: - case FML_CODE: - fpa11->fpreg[Fd].fExtended = floatx80_mul(rFn,rFm, &fpa11->fp_status); - break; - - case SUF_CODE: - fpa11->fpreg[Fd].fExtended = floatx80_sub(rFn,rFm, &fpa11->fp_status); - break; - - case RSF_CODE: - fpa11->fpreg[Fd].fExtended = floatx80_sub(rFm,rFn, &fpa11->fp_status); - break; - - case DVF_CODE: - case FDV_CODE: - fpa11->fpreg[Fd].fExtended = floatx80_div(rFn,rFm, &fpa11->fp_status); - break; - - case RDF_CODE: - case FRD_CODE: - fpa11->fpreg[Fd].fExtended = floatx80_div(rFm,rFn, &fpa11->fp_status); - break; - -#if 0 - case POW_CODE: - fpa11->fpreg[Fd].fExtended = floatx80_pow(rFn,rFm); - break; - - case RPW_CODE: - fpa11->fpreg[Fd].fExtended = floatx80_pow(rFm,rFn); - break; -#endif - - case RMF_CODE: - fpa11->fpreg[Fd].fExtended = floatx80_rem(rFn,rFm, &fpa11->fp_status); - break; - -#if 0 - case POL_CODE: - fpa11->fpreg[Fd].fExtended = floatx80_pol(rFn,rFm); - break; -#endif - - /* monadic opcodes */ - case MVF_CODE: - fpa11->fpreg[Fd].fExtended = rFm; - break; - - case MNF_CODE: - rFm.high ^= 0x8000; - fpa11->fpreg[Fd].fExtended = rFm; - break; - - case ABS_CODE: - rFm.high &= 0x7fff; - fpa11->fpreg[Fd].fExtended = rFm; - break; - - case RND_CODE: - case URD_CODE: - fpa11->fpreg[Fd].fExtended = floatx80_round_to_int(rFm, &fpa11->fp_status); - break; - - case SQT_CODE: - fpa11->fpreg[Fd].fExtended = floatx80_sqrt(rFm, &fpa11->fp_status); - break; - -#if 0 - case LOG_CODE: - fpa11->fpreg[Fd].fExtended = floatx80_log(rFm); - break; - - case LGN_CODE: - fpa11->fpreg[Fd].fExtended = floatx80_ln(rFm); - break; - - case EXP_CODE: - fpa11->fpreg[Fd].fExtended = floatx80_exp(rFm); - break; - - case SIN_CODE: - fpa11->fpreg[Fd].fExtended = floatx80_sin(rFm); - break; - - case COS_CODE: - fpa11->fpreg[Fd].fExtended = floatx80_cos(rFm); - break; - - case TAN_CODE: - fpa11->fpreg[Fd].fExtended = floatx80_tan(rFm); - break; - - case ASN_CODE: - fpa11->fpreg[Fd].fExtended = floatx80_arcsin(rFm); - break; - - case ACS_CODE: - fpa11->fpreg[Fd].fExtended = floatx80_arccos(rFm); - break; - - case ATN_CODE: - fpa11->fpreg[Fd].fExtended = floatx80_arctan(rFm); - break; -#endif - - case NRM_CODE: - break; - - default: - { - nRc = 0; - } - } - - if (0 != nRc) fpa11->fType[Fd] = typeExtended; - return nRc; -} - -#if 0 -floatx80 floatx80_exp(floatx80 Fm) -{ -//series -} - -floatx80 floatx80_ln(floatx80 Fm) -{ -//series -} - -floatx80 floatx80_sin(floatx80 rFm) -{ -//series -} - -floatx80 floatx80_cos(floatx80 rFm) -{ -//series -} - -floatx80 floatx80_arcsin(floatx80 rFm) -{ -//series -} - -floatx80 floatx80_arctan(floatx80 rFm) -{ - //series -} - -floatx80 floatx80_log(floatx80 rFm) -{ - return floatx80_div(floatx80_ln(rFm),getExtendedConstant(7)); -} - -floatx80 floatx80_tan(floatx80 rFm) -{ - return floatx80_div(floatx80_sin(rFm),floatx80_cos(rFm)); -} - -floatx80 floatx80_arccos(floatx80 rFm) -{ - //return floatx80_sub(halfPi,floatx80_arcsin(rFm)); -} - -floatx80 floatx80_pow(floatx80 rFn,floatx80 rFm) -{ - return floatx80_exp(floatx80_mul(rFm,floatx80_ln(rFn))); -} - -floatx80 floatx80_pol(floatx80 rFn,floatx80 rFm) -{ - return floatx80_arctan(floatx80_div(rFn,rFm)); -} -#endif diff --git a/target-arm/nwfpe/fpa11.c b/target-arm/nwfpe/fpa11.c deleted file mode 100644 index 626a87a..0000000 --- a/target-arm/nwfpe/fpa11.c +++ /dev/null @@ -1,244 +0,0 @@ -/* - NetWinder Floating Point Emulator - (c) Rebel.COM, 1998,1999 - - 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 "fpmodule.h" -//#include "fpmodule.inl" - -//#include <asm/system.h> - -#include <stdio.h> - -/* forward declarations */ -unsigned int EmulateCPDO(const unsigned int); -unsigned int EmulateCPDT(const unsigned int); -unsigned int EmulateCPRT(const unsigned int); - -FPA11* qemufpa=0; -CPUARMState* user_registers; - -/* Reset the FPA11 chip. Called to initialize and reset the emulator. */ -void resetFPA11(void) -{ - int i; - FPA11 *fpa11 = GET_FPA11(); - - /* initialize the register type array */ - for (i=0;i<=7;i++) - { - fpa11->fType[i] = typeNone; - } - - /* FPSR: set system id to FP_EMULATOR, set AC, clear all other bits */ - fpa11->fpsr = FP_EMULATOR | BIT_AC; - - /* FPCR: set SB, AB and DA bits, clear all others */ -#if MAINTAIN_FPCR - fpa11->fpcr = MASK_RESET; -#endif -} - -void SetRoundingMode(const unsigned int opcode) -{ - int rounding_mode; - FPA11 *fpa11 = GET_FPA11(); - -#if MAINTAIN_FPCR - fpa11->fpcr &= ~MASK_ROUNDING_MODE; -#endif - switch (opcode & MASK_ROUNDING_MODE) - { - default: - case ROUND_TO_NEAREST: - rounding_mode = float_round_nearest_even; -#if MAINTAIN_FPCR - fpa11->fpcr |= ROUND_TO_NEAREST; -#endif - break; - - case ROUND_TO_PLUS_INFINITY: - rounding_mode = float_round_up; -#if MAINTAIN_FPCR - fpa11->fpcr |= ROUND_TO_PLUS_INFINITY; -#endif - break; - - case ROUND_TO_MINUS_INFINITY: - rounding_mode = float_round_down; -#if MAINTAIN_FPCR - fpa11->fpcr |= ROUND_TO_MINUS_INFINITY; -#endif - break; - - case ROUND_TO_ZERO: - rounding_mode = float_round_to_zero; -#if MAINTAIN_FPCR - fpa11->fpcr |= ROUND_TO_ZERO; -#endif - break; - } - set_float_rounding_mode(rounding_mode, &fpa11->fp_status); -} - -void SetRoundingPrecision(const unsigned int opcode) -{ - int rounding_precision; - FPA11 *fpa11 = GET_FPA11(); -#if MAINTAIN_FPCR - fpa11->fpcr &= ~MASK_ROUNDING_PRECISION; -#endif - switch (opcode & MASK_ROUNDING_PRECISION) - { - case ROUND_SINGLE: - rounding_precision = 32; -#if MAINTAIN_FPCR - fpa11->fpcr |= ROUND_SINGLE; -#endif - break; - - case ROUND_DOUBLE: - rounding_precision = 64; -#if MAINTAIN_FPCR - fpa11->fpcr |= ROUND_DOUBLE; -#endif - break; - - case ROUND_EXTENDED: - rounding_precision = 80; -#if MAINTAIN_FPCR - fpa11->fpcr |= ROUND_EXTENDED; -#endif - break; - - default: rounding_precision = 80; - } - set_floatx80_rounding_precision(rounding_precision, &fpa11->fp_status); -} - -/* Emulate the instruction in the opcode. */ -/* ??? This is not thread safe. */ -unsigned int EmulateAll(unsigned int opcode, FPA11* qfpa, CPUARMState* qregs) -{ - unsigned int nRc = 0; -// unsigned long flags; - FPA11 *fpa11; -// save_flags(flags); sti(); - - qemufpa=qfpa; - user_registers=qregs; - -#if 0 - fprintf(stderr,"emulating FP insn 0x%08x, PC=0x%08x\n", - opcode, qregs[REG_PC]); -#endif - fpa11 = GET_FPA11(); - - if (fpa11->initflag == 0) /* good place for __builtin_expect */ - { - resetFPA11(); - SetRoundingMode(ROUND_TO_NEAREST); - SetRoundingPrecision(ROUND_EXTENDED); - fpa11->initflag = 1; - } - - set_float_exception_flags(0, &fpa11->fp_status); - - if (TEST_OPCODE(opcode,MASK_CPRT)) - { - //fprintf(stderr,"emulating CPRT\n"); - /* Emulate conversion opcodes. */ - /* Emulate register transfer opcodes. */ - /* Emulate comparison opcodes. */ - nRc = EmulateCPRT(opcode); - } - else if (TEST_OPCODE(opcode,MASK_CPDO)) - { - //fprintf(stderr,"emulating CPDO\n"); - /* Emulate monadic arithmetic opcodes. */ - /* Emulate dyadic arithmetic opcodes. */ - nRc = EmulateCPDO(opcode); - } - else if (TEST_OPCODE(opcode,MASK_CPDT)) - { - //fprintf(stderr,"emulating CPDT\n"); - /* Emulate load/store opcodes. */ - /* Emulate load/store multiple opcodes. */ - nRc = EmulateCPDT(opcode); - } - else - { - /* Invalid instruction detected. Return FALSE. */ - nRc = 0; - } - -// restore_flags(flags); - if(nRc == 1 && get_float_exception_flags(&fpa11->fp_status)) - { - //printf("fef 0x%x\n",float_exception_flags); - nRc=-get_float_exception_flags(&fpa11->fp_status); - } - - //printf("returning %d\n",nRc); - return(nRc); -} - -#if 0 -unsigned int EmulateAll1(unsigned int opcode) -{ - switch ((opcode >> 24) & 0xf) - { - case 0xc: - case 0xd: - if ((opcode >> 20) & 0x1) - { - switch ((opcode >> 8) & 0xf) - { - case 0x1: return PerformLDF(opcode); break; - case 0x2: return PerformLFM(opcode); break; - default: return 0; - } - } - else - { - switch ((opcode >> 8) & 0xf) - { - case 0x1: return PerformSTF(opcode); break; - case 0x2: return PerformSFM(opcode); break; - default: return 0; - } - } - break; - - case 0xe: - if (opcode & 0x10) - return EmulateCPDO(opcode); - else - return EmulateCPRT(opcode); - break; - - default: return 0; - } -} -#endif - diff --git a/target-arm/nwfpe/fpa11.h b/target-arm/nwfpe/fpa11.h deleted file mode 100644 index 4fc0b3b..0000000 --- a/target-arm/nwfpe/fpa11.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - NetWinder Floating Point Emulator - (c) Rebel.com, 1998-1999 - - 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. -*/ - -#ifndef __FPA11_H__ -#define __FPA11_H__ - -#include <stdlib.h> -#include <stdio.h> -#include <errno.h> - -#include <cpu.h> - -#define GET_FPA11() (qemufpa) - -/* - * The processes registers are always at the very top of the 8K - * stack+task struct. Use the same method as 'current' uses to - * reach them. - */ -extern CPUARMState *user_registers; - -#define GET_USERREG() (user_registers) - -/* Need task_struct */ -//#include <linux/sched.h> - -/* includes */ -#include "fpsr.h" /* FP control and status register definitions */ -#include "softfloat.h" - -#define typeNone 0x00 -#define typeSingle 0x01 -#define typeDouble 0x02 -#define typeExtended 0x03 - -/* - * This must be no more and no less than 12 bytes. - */ -typedef union tagFPREG { - floatx80 fExtended; - float64 fDouble; - float32 fSingle; -} FPREG; - -/* - * FPA11 device model. - * - * This structure is exported to user space. Do not re-order. - * Only add new stuff to the end, and do not change the size of - * any element. Elements of this structure are used by user - * space, and must match struct user_fp in include/asm-arm/user.h. - * We include the byte offsets below for documentation purposes. - * - * The size of this structure and FPREG are checked by fpmodule.c - * on initialisation. If the rules have been broken, NWFPE will - * not initialise. - */ -typedef struct tagFPA11 { -/* 0 */ FPREG fpreg[8]; /* 8 floating point registers */ -/* 96 */ FPSR fpsr; /* floating point status register */ -/* 100 */ FPCR fpcr; /* floating point control register */ -/* 104 */ unsigned char fType[8]; /* type of floating point value held in - floating point registers. One of none - single, double or extended. */ -/* 112 */ int initflag; /* this is special. The kernel guarantees - to set it to 0 when a thread is launched, - so we can use it to detect whether this - instance of the emulator needs to be - initialised. */ - float_status fp_status; /* QEMU float emulator status */ -} FPA11; - -extern FPA11* qemufpa; - -extern void resetFPA11(void); -extern void SetRoundingMode(const unsigned int); -extern void SetRoundingPrecision(const unsigned int); - -static inline unsigned int readRegister(unsigned int reg) -{ - return (user_registers->regs[(reg)]); -} - -static inline void writeRegister(unsigned int x, unsigned int y) -{ -#if 0 - printf("writing %d to r%d\n",y,x); -#endif - user_registers->regs[(x)]=(y); -} - -static inline void writeConditionCodes(unsigned int x) -{ - cpsr_write(user_registers,x,CPSR_NZCV); -} - -#define REG_PC 15 - -unsigned int EmulateAll(unsigned int opcode, FPA11* qfpa, CPUARMState* qregs); - -/* included only for get_user/put_user macros */ -#include "qemu.h" - -#endif diff --git a/target-arm/nwfpe/fpa11.inl b/target-arm/nwfpe/fpa11.inl deleted file mode 100644 index 7183ec9..0000000 --- a/target-arm/nwfpe/fpa11.inl +++ /dev/null @@ -1,51 +0,0 @@ -/* - NetWinder Floating Point Emulator - (c) Rebel.COM, 1998,1999 - - 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" - -/* Read and write floating point status register */ -static inline unsigned int readFPSR(void) -{ - FPA11 *fpa11 = GET_FPA11(); - return(fpa11->fpsr); -} - -static inline void writeFPSR(FPSR reg) -{ - FPA11 *fpa11 = GET_FPA11(); - /* the sysid byte in the status register is readonly */ - fpa11->fpsr = (fpa11->fpsr & MASK_SYSID) | (reg & ~MASK_SYSID); -} - -/* Read and write floating point control register */ -static inline FPCR readFPCR(void) -{ - FPA11 *fpa11 = GET_FPA11(); - /* clear SB, AB and DA bits before returning FPCR */ - return(fpa11->fpcr & ~MASK_RFC); -} - -static inline void writeFPCR(FPCR reg) -{ - FPA11 *fpa11 = GET_FPA11(); - fpa11->fpcr &= ~MASK_WFC; /* clear SB, AB and DA bits */ - fpa11->fpcr |= (reg & MASK_WFC); /* write SB, AB and DA bits */ -} diff --git a/target-arm/nwfpe/fpa11_cpdo.c b/target-arm/nwfpe/fpa11_cpdo.c deleted file mode 100644 index 7779637..0000000 --- a/target-arm/nwfpe/fpa11_cpdo.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - NetWinder Floating Point Emulator - (c) Rebel.COM, 1998,1999 - - 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" - -unsigned int SingleCPDO(const unsigned int opcode); -unsigned int DoubleCPDO(const unsigned int opcode); -unsigned int ExtendedCPDO(const unsigned int opcode); - -unsigned int EmulateCPDO(const unsigned int opcode) -{ - FPA11 *fpa11 = GET_FPA11(); - unsigned int Fd, nType, nDest, nRc = 1; - - //printk("EmulateCPDO(0x%08x)\n",opcode); - - /* Get the destination size. If not valid let Linux perform - an invalid instruction trap. */ - nDest = getDestinationSize(opcode); - if (typeNone == nDest) return 0; - - SetRoundingMode(opcode); - - /* Compare the size of the operands in Fn and Fm. - Choose the largest size and perform operations in that size, - in order to make use of all the precision of the operands. - If Fm is a constant, we just grab a constant of a size - matching the size of the operand in Fn. */ - if (MONADIC_INSTRUCTION(opcode)) - nType = nDest; - else - nType = fpa11->fType[getFn(opcode)]; - - if (!CONSTANT_FM(opcode)) - { - register unsigned int Fm = getFm(opcode); - if (nType < fpa11->fType[Fm]) - { - nType = fpa11->fType[Fm]; - } - } - - switch (nType) - { - case typeSingle : nRc = SingleCPDO(opcode); break; - case typeDouble : nRc = DoubleCPDO(opcode); break; - case typeExtended : nRc = ExtendedCPDO(opcode); break; - default : nRc = 0; - } - - /* If the operation succeeded, check to see if the result in the - destination register is the correct size. If not force it - to be. */ - Fd = getFd(opcode); - nType = fpa11->fType[Fd]; - if ((0 != nRc) && (nDest != nType)) - { - switch (nDest) - { - case typeSingle: - { - if (typeDouble == nType) - fpa11->fpreg[Fd].fSingle = - float64_to_float32(fpa11->fpreg[Fd].fDouble, &fpa11->fp_status); - else - fpa11->fpreg[Fd].fSingle = - floatx80_to_float32(fpa11->fpreg[Fd].fExtended, &fpa11->fp_status); - } - break; - - case typeDouble: - { - if (typeSingle == nType) - fpa11->fpreg[Fd].fDouble = - float32_to_float64(fpa11->fpreg[Fd].fSingle, &fpa11->fp_status); - else - fpa11->fpreg[Fd].fDouble = - floatx80_to_float64(fpa11->fpreg[Fd].fExtended, &fpa11->fp_status); - } - break; - - case typeExtended: - { - if (typeSingle == nType) - fpa11->fpreg[Fd].fExtended = - float32_to_floatx80(fpa11->fpreg[Fd].fSingle, &fpa11->fp_status); - else - fpa11->fpreg[Fd].fExtended = - float64_to_floatx80(fpa11->fpreg[Fd].fDouble, &fpa11->fp_status); - } - break; - } - - fpa11->fType[Fd] = nDest; - } - - return nRc; -} diff --git a/target-arm/nwfpe/fpa11_cpdt.c b/target-arm/nwfpe/fpa11_cpdt.c deleted file mode 100644 index 41877df..0000000 --- a/target-arm/nwfpe/fpa11_cpdt.c +++ /dev/null @@ -1,386 +0,0 @@ -/* - NetWinder Floating Point Emulator - (c) Rebel.com, 1998-1999 - (c) Philip Blundell, 1998 - - 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 "softfloat.h" -#include "fpopcode.h" -//#include "fpmodule.h" -//#include "fpmodule.inl" - -//#include <asm/uaccess.h> - -static inline -void loadSingle(const unsigned int Fn,const unsigned int *pMem) -{ - target_ulong addr = (target_ulong)(long)pMem; - FPA11 *fpa11 = GET_FPA11(); - fpa11->fType[Fn] = typeSingle; - /* FIXME - handle failure of get_user() */ - get_user_u32(fpa11->fpreg[Fn].fSingle, addr); -} - -static inline -void loadDouble(const unsigned int Fn,const unsigned int *pMem) -{ - target_ulong addr = (target_ulong)(long)pMem; - FPA11 *fpa11 = GET_FPA11(); - unsigned int *p; - p = (unsigned int*)&fpa11->fpreg[Fn].fDouble; - fpa11->fType[Fn] = typeDouble; -#ifdef WORDS_BIGENDIAN - /* FIXME - handle failure of get_user() */ - get_user_u32(p[0], addr); /* sign & exponent */ - get_user_u32(p[1], addr + 4); -#else - /* FIXME - handle failure of get_user() */ - get_user_u32(p[0], addr + 4); - get_user_u32(p[1], addr); /* sign & exponent */ -#endif -} - -static inline -void loadExtended(const unsigned int Fn,const unsigned int *pMem) -{ - target_ulong addr = (target_ulong)(long)pMem; - FPA11 *fpa11 = GET_FPA11(); - unsigned int *p; - p = (unsigned int*)&fpa11->fpreg[Fn].fExtended; - fpa11->fType[Fn] = typeExtended; - /* FIXME - handle failure of get_user() */ - get_user_u32(p[0], addr); /* sign & exponent */ - get_user_u32(p[1], addr + 8); /* ls bits */ - get_user_u32(p[2], addr + 4); /* ms bits */ -} - -static inline -void loadMultiple(const unsigned int Fn,const unsigned int *pMem) -{ - target_ulong addr = (target_ulong)(long)pMem; - FPA11 *fpa11 = GET_FPA11(); - register unsigned int *p; - unsigned long x; - - p = (unsigned int*)&(fpa11->fpreg[Fn]); - /* FIXME - handle failure of get_user() */ - get_user_u32(x, addr); - fpa11->fType[Fn] = (x >> 14) & 0x00000003; - - switch (fpa11->fType[Fn]) - { - case typeSingle: - case typeDouble: - { - /* FIXME - handle failure of get_user() */ - get_user_u32(p[0], addr + 8); /* Single */ - get_user_u32(p[1], addr + 4); /* double msw */ - p[2] = 0; /* empty */ - } - break; - - case typeExtended: - { - /* FIXME - handle failure of get_user() */ - get_user_u32(p[1], addr + 8); - get_user_u32(p[2], addr + 4); /* msw */ - p[0] = (x & 0x80003fff); - } - break; - } -} - -static inline -void storeSingle(const unsigned int Fn,unsigned int *pMem) -{ - target_ulong addr = (target_ulong)(long)pMem; - FPA11 *fpa11 = GET_FPA11(); - float32 val; - register unsigned int *p = (unsigned int*)&val; - - switch (fpa11->fType[Fn]) - { - case typeDouble: - val = float64_to_float32(fpa11->fpreg[Fn].fDouble, &fpa11->fp_status); - break; - - case typeExtended: - val = floatx80_to_float32(fpa11->fpreg[Fn].fExtended, &fpa11->fp_status); - break; - - default: val = fpa11->fpreg[Fn].fSingle; - } - - /* FIXME - handle put_user() failures */ - put_user_u32(p[0], addr); -} - -static inline -void storeDouble(const unsigned int Fn,unsigned int *pMem) -{ - target_ulong addr = (target_ulong)(long)pMem; - FPA11 *fpa11 = GET_FPA11(); - float64 val; - register unsigned int *p = (unsigned int*)&val; - - switch (fpa11->fType[Fn]) - { - case typeSingle: - val = float32_to_float64(fpa11->fpreg[Fn].fSingle, &fpa11->fp_status); - break; - - case typeExtended: - val = floatx80_to_float64(fpa11->fpreg[Fn].fExtended, &fpa11->fp_status); - break; - - default: val = fpa11->fpreg[Fn].fDouble; - } - /* FIXME - handle put_user() failures */ -#ifdef WORDS_BIGENDIAN - put_user_u32(p[0], addr); /* msw */ - put_user_u32(p[1], addr + 4); /* lsw */ -#else - put_user_u32(p[1], addr); /* msw */ - put_user_u32(p[0], addr + 4); /* lsw */ -#endif -} - -static inline -void storeExtended(const unsigned int Fn,unsigned int *pMem) -{ - target_ulong addr = (target_ulong)(long)pMem; - FPA11 *fpa11 = GET_FPA11(); - floatx80 val; - register unsigned int *p = (unsigned int*)&val; - - switch (fpa11->fType[Fn]) - { - case typeSingle: - val = float32_to_floatx80(fpa11->fpreg[Fn].fSingle, &fpa11->fp_status); - break; - - case typeDouble: - val = float64_to_floatx80(fpa11->fpreg[Fn].fDouble, &fpa11->fp_status); - break; - - default: val = fpa11->fpreg[Fn].fExtended; - } - - /* FIXME - handle put_user() failures */ - put_user_u32(p[0], addr); /* sign & exp */ - put_user_u32(p[1], addr + 8); - put_user_u32(p[2], addr + 4); /* msw */ -} - -static inline -void storeMultiple(const unsigned int Fn,unsigned int *pMem) -{ - target_ulong addr = (target_ulong)(long)pMem; - FPA11 *fpa11 = GET_FPA11(); - register unsigned int nType, *p; - - p = (unsigned int*)&(fpa11->fpreg[Fn]); - nType = fpa11->fType[Fn]; - - switch (nType) - { - case typeSingle: - case typeDouble: - { - put_user_u32(p[0], addr + 8); /* single */ - put_user_u32(p[1], addr + 4); /* double msw */ - put_user_u32(nType << 14, addr); - } - break; - - case typeExtended: - { - put_user_u32(p[2], addr + 4); /* msw */ - put_user_u32(p[1], addr + 8); - put_user_u32((p[0] & 0x80003fff) | (nType << 14), addr); - } - break; - } -} - -unsigned int PerformLDF(const unsigned int opcode) -{ - unsigned int *pBase, *pAddress, *pFinal, nRc = 1, - write_back = WRITE_BACK(opcode); - - //printk("PerformLDF(0x%08x), Fd = 0x%08x\n",opcode,getFd(opcode)); - - pBase = (unsigned int*)readRegister(getRn(opcode)); - if (REG_PC == getRn(opcode)) - { - pBase += 2; - write_back = 0; - } - - pFinal = pBase; - if (BIT_UP_SET(opcode)) - pFinal += getOffset(opcode); - else - pFinal -= getOffset(opcode); - - if (PREINDEXED(opcode)) pAddress = pFinal; else pAddress = pBase; - - switch (opcode & MASK_TRANSFER_LENGTH) - { - case TRANSFER_SINGLE : loadSingle(getFd(opcode),pAddress); break; - case TRANSFER_DOUBLE : loadDouble(getFd(opcode),pAddress); break; - case TRANSFER_EXTENDED: loadExtended(getFd(opcode),pAddress); break; - default: nRc = 0; - } - - if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal); - return nRc; -} - -unsigned int PerformSTF(const unsigned int opcode) -{ - unsigned int *pBase, *pAddress, *pFinal, nRc = 1, - write_back = WRITE_BACK(opcode); - - //printk("PerformSTF(0x%08x), Fd = 0x%08x\n",opcode,getFd(opcode)); - SetRoundingMode(ROUND_TO_NEAREST); - - pBase = (unsigned int*)readRegister(getRn(opcode)); - if (REG_PC == getRn(opcode)) - { - pBase += 2; - write_back = 0; - } - - pFinal = pBase; - if (BIT_UP_SET(opcode)) - pFinal += getOffset(opcode); - else - pFinal -= getOffset(opcode); - - if (PREINDEXED(opcode)) pAddress = pFinal; else pAddress = pBase; - - switch (opcode & MASK_TRANSFER_LENGTH) - { - case TRANSFER_SINGLE : storeSingle(getFd(opcode),pAddress); break; - case TRANSFER_DOUBLE : storeDouble(getFd(opcode),pAddress); break; - case TRANSFER_EXTENDED: storeExtended(getFd(opcode),pAddress); break; - default: nRc = 0; - } - - if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal); - return nRc; -} - -unsigned int PerformLFM(const unsigned int opcode) -{ - unsigned int i, Fd, *pBase, *pAddress, *pFinal, - write_back = WRITE_BACK(opcode); - - pBase = (unsigned int*)readRegister(getRn(opcode)); - if (REG_PC == getRn(opcode)) - { - pBase += 2; - write_back = 0; - } - - pFinal = pBase; - if (BIT_UP_SET(opcode)) - pFinal += getOffset(opcode); - else - pFinal -= getOffset(opcode); - - if (PREINDEXED(opcode)) pAddress = pFinal; else pAddress = pBase; - - Fd = getFd(opcode); - for (i=getRegisterCount(opcode);i>0;i--) - { - loadMultiple(Fd,pAddress); - pAddress += 3; Fd++; - if (Fd == 8) Fd = 0; - } - - if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal); - return 1; -} - -unsigned int PerformSFM(const unsigned int opcode) -{ - unsigned int i, Fd, *pBase, *pAddress, *pFinal, - write_back = WRITE_BACK(opcode); - - pBase = (unsigned int*)readRegister(getRn(opcode)); - if (REG_PC == getRn(opcode)) - { - pBase += 2; - write_back = 0; - } - - pFinal = pBase; - if (BIT_UP_SET(opcode)) - pFinal += getOffset(opcode); - else - pFinal -= getOffset(opcode); - - if (PREINDEXED(opcode)) pAddress = pFinal; else pAddress = pBase; - - Fd = getFd(opcode); - for (i=getRegisterCount(opcode);i>0;i--) - { - storeMultiple(Fd,pAddress); - pAddress += 3; Fd++; - if (Fd == 8) Fd = 0; - } - - if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal); - return 1; -} - -#if 1 -unsigned int EmulateCPDT(const unsigned int opcode) -{ - unsigned int nRc = 0; - - //printk("EmulateCPDT(0x%08x)\n",opcode); - - if (LDF_OP(opcode)) - { - nRc = PerformLDF(opcode); - } - else if (LFM_OP(opcode)) - { - nRc = PerformLFM(opcode); - } - else if (STF_OP(opcode)) - { - nRc = PerformSTF(opcode); - } - else if (SFM_OP(opcode)) - { - nRc = PerformSFM(opcode); - } - else - { - nRc = 0; - } - - return nRc; -} -#endif diff --git a/target-arm/nwfpe/fpa11_cprt.c b/target-arm/nwfpe/fpa11_cprt.c deleted file mode 100644 index 04eae8c..0000000 --- a/target-arm/nwfpe/fpa11_cprt.c +++ /dev/null @@ -1,286 +0,0 @@ -/* - NetWinder Floating Point Emulator - (c) Rebel.COM, 1998,1999 - (c) Philip Blundell, 1999 - - 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 "softfloat.h" -#include "fpopcode.h" -#include "fpa11.inl" -//#include "fpmodule.h" -//#include "fpmodule.inl" - -void SetRoundingMode(const unsigned int opcode); - -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) -{ - unsigned int nRc = 1; - - //printk("EmulateCPRT(0x%08x)\n",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: nRc = PerformFLT(opcode); break; - case FIX_CODE >> 20: nRc = PerformFIX(opcode); break; - - case WFS_CODE >> 20: writeFPSR(readRegister(getRd(opcode))); break; - case RFS_CODE >> 20: writeRegister(getRd(opcode),readFPSR()); break; - -#if 0 /* We currently have no use for the FPCR, so there's no point - in emulating it. */ - case WFC_CODE >> 20: writeFPCR(readRegister(getRd(opcode))); - case RFC_CODE >> 20: writeRegister(getRd(opcode),readFPCR()); break; -#endif - - default: nRc = 0; - } - - return nRc; -} - -unsigned int PerformFLT(const unsigned int opcode) -{ - FPA11 *fpa11 = GET_FPA11(); - - unsigned int nRc = 1; - SetRoundingMode(opcode); - - switch (opcode & MASK_ROUNDING_PRECISION) - { - case ROUND_SINGLE: - { - fpa11->fType[getFn(opcode)] = typeSingle; - fpa11->fpreg[getFn(opcode)].fSingle = - int32_to_float32(readRegister(getRd(opcode)), &fpa11->fp_status); - } - break; - - case ROUND_DOUBLE: - { - fpa11->fType[getFn(opcode)] = typeDouble; - fpa11->fpreg[getFn(opcode)].fDouble = - int32_to_float64(readRegister(getRd(opcode)), &fpa11->fp_status); - } - break; - - case ROUND_EXTENDED: - { - fpa11->fType[getFn(opcode)] = typeExtended; - fpa11->fpreg[getFn(opcode)].fExtended = - int32_to_floatx80(readRegister(getRd(opcode)), &fpa11->fp_status); - } - break; - - default: nRc = 0; - } - - return nRc; -} - -unsigned int PerformFIX(const unsigned int opcode) -{ - FPA11 *fpa11 = GET_FPA11(); - unsigned int nRc = 1; - unsigned int Fn = getFm(opcode); - - SetRoundingMode(opcode); - - switch (fpa11->fType[Fn]) - { - case typeSingle: - { - writeRegister(getRd(opcode), - float32_to_int32(fpa11->fpreg[Fn].fSingle, &fpa11->fp_status)); - } - break; - - case typeDouble: - { - //printf("F%d is 0x%" PRIx64 "\n",Fn,fpa11->fpreg[Fn].fDouble); - writeRegister(getRd(opcode), - float64_to_int32(fpa11->fpreg[Fn].fDouble, &fpa11->fp_status)); - } - break; - - case typeExtended: - { - writeRegister(getRd(opcode), - floatx80_to_int32(fpa11->fpreg[Fn].fExtended, &fpa11->fp_status)); - } - break; - - default: nRc = 0; - } - - return nRc; -} - - -static unsigned int __inline__ -PerformComparisonOperation(floatx80 Fn, floatx80 Fm) -{ - FPA11 *fpa11 = GET_FPA11(); - unsigned int flags = 0; - - /* test for less than condition */ - if (floatx80_lt(Fn,Fm, &fpa11->fp_status)) - { - flags |= CC_NEGATIVE; - } - - /* test for equal condition */ - if (floatx80_eq(Fn,Fm, &fpa11->fp_status)) - { - flags |= CC_ZERO; - } - - /* test for greater than or equal condition */ - if (floatx80_lt(Fm,Fn, &fpa11->fp_status)) - { - flags |= CC_CARRY; - } - - writeConditionCodes(flags); - return 1; -} - -/* This instruction sets the flags N, Z, C, V in the FPSR. */ - -static unsigned int PerformComparison(const unsigned int opcode) -{ - FPA11 *fpa11 = GET_FPA11(); - unsigned int Fn, Fm; - floatx80 rFn, rFm; - int e_flag = opcode & 0x400000; /* 1 if CxFE */ - int n_flag = opcode & 0x200000; /* 1 if CNxx */ - unsigned int flags = 0; - - //printk("PerformComparison(0x%08x)\n",opcode); - - Fn = getFn(opcode); - Fm = getFm(opcode); - - /* Check for unordered condition and convert all operands to 80-bit - format. - ?? Might be some mileage in avoiding this conversion if possible. - Eg, if both operands are 32-bit, detect this and do a 32-bit - comparison (cheaper than an 80-bit one). */ - switch (fpa11->fType[Fn]) - { - case typeSingle: - //printk("single.\n"); - if (float32_is_nan(fpa11->fpreg[Fn].fSingle)) - goto unordered; - rFn = float32_to_floatx80(fpa11->fpreg[Fn].fSingle, &fpa11->fp_status); - break; - - case typeDouble: - //printk("double.\n"); - if (float64_is_nan(fpa11->fpreg[Fn].fDouble)) - goto unordered; - rFn = float64_to_floatx80(fpa11->fpreg[Fn].fDouble, &fpa11->fp_status); - break; - - case typeExtended: - //printk("extended.\n"); - if (floatx80_is_nan(fpa11->fpreg[Fn].fExtended)) - goto unordered; - rFn = fpa11->fpreg[Fn].fExtended; - break; - - default: return 0; - } - - if (CONSTANT_FM(opcode)) - { - //printk("Fm is a constant: #%d.\n",Fm); - rFm = getExtendedConstant(Fm); - if (floatx80_is_nan(rFm)) - goto unordered; - } - else - { - //printk("Fm = r%d which contains a ",Fm); - switch (fpa11->fType[Fm]) - { - case typeSingle: - //printk("single.\n"); - if (float32_is_nan(fpa11->fpreg[Fm].fSingle)) - goto unordered; - rFm = float32_to_floatx80(fpa11->fpreg[Fm].fSingle, &fpa11->fp_status); - break; - - case typeDouble: - //printk("double.\n"); - if (float64_is_nan(fpa11->fpreg[Fm].fDouble)) - goto unordered; - rFm = float64_to_floatx80(fpa11->fpreg[Fm].fDouble, &fpa11->fp_status); - break; - - case typeExtended: - //printk("extended.\n"); - if (floatx80_is_nan(fpa11->fpreg[Fm].fExtended)) - goto unordered; - rFm = fpa11->fpreg[Fm].fExtended; - break; - - default: return 0; - } - } - - if (n_flag) - { - rFm.high ^= 0x8000; - } - - return PerformComparisonOperation(rFn,rFm); - - unordered: - /* ?? The FPA data sheet is pretty vague about this, in particular - about whether the non-E comparisons can ever raise exceptions. - This implementation is based on a combination of what it says in - the data sheet, observation of how the Acorn emulator actually - behaves (and how programs expect it to) and guesswork. */ - flags |= CC_OVERFLOW; - flags &= ~(CC_ZERO | CC_NEGATIVE); - - if (BIT_AC & readFPSR()) flags |= CC_CARRY; - - if (e_flag) float_raise(float_flag_invalid, &fpa11->fp_status); - - writeConditionCodes(flags); - return 1; -} diff --git a/target-arm/nwfpe/fpopcode.c b/target-arm/nwfpe/fpopcode.c deleted file mode 100644 index a733a1d..0000000 --- a/target-arm/nwfpe/fpopcode.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - NetWinder Floating Point Emulator - (c) Rebel.COM, 1998,1999 - - 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 "softfloat.h" -#include "fpopcode.h" -#include "fpsr.h" -//#include "fpmodule.h" -//#include "fpmodule.inl" - -const floatx80 floatx80Constant[] = { - { 0x0000000000000000ULL, 0x0000}, /* extended 0.0 */ - { 0x8000000000000000ULL, 0x3fff}, /* extended 1.0 */ - { 0x8000000000000000ULL, 0x4000}, /* extended 2.0 */ - { 0xc000000000000000ULL, 0x4000}, /* extended 3.0 */ - { 0x8000000000000000ULL, 0x4001}, /* extended 4.0 */ - { 0xa000000000000000ULL, 0x4001}, /* extended 5.0 */ - { 0x8000000000000000ULL, 0x3ffe}, /* extended 0.5 */ - { 0xa000000000000000ULL, 0x4002} /* extended 10.0 */ -}; - -const float64 float64Constant[] = { - 0x0000000000000000ULL, /* double 0.0 */ - 0x3ff0000000000000ULL, /* double 1.0 */ - 0x4000000000000000ULL, /* double 2.0 */ - 0x4008000000000000ULL, /* double 3.0 */ - 0x4010000000000000ULL, /* double 4.0 */ - 0x4014000000000000ULL, /* double 5.0 */ - 0x3fe0000000000000ULL, /* double 0.5 */ - 0x4024000000000000ULL /* double 10.0 */ -}; - -const float32 float32Constant[] = { - 0x00000000, /* single 0.0 */ - 0x3f800000, /* single 1.0 */ - 0x40000000, /* single 2.0 */ - 0x40400000, /* single 3.0 */ - 0x40800000, /* single 4.0 */ - 0x40a00000, /* single 5.0 */ - 0x3f000000, /* single 0.5 */ - 0x41200000 /* single 10.0 */ -}; - -unsigned int getTransferLength(const unsigned int opcode) -{ - unsigned int nRc; - - switch (opcode & MASK_TRANSFER_LENGTH) - { - case 0x00000000: nRc = 1; break; /* single precision */ - case 0x00008000: nRc = 2; break; /* double precision */ - case 0x00400000: nRc = 3; break; /* extended precision */ - default: nRc = 0; - } - - return(nRc); -} - -unsigned int getRegisterCount(const unsigned int opcode) -{ - unsigned int nRc; - - switch (opcode & MASK_REGISTER_COUNT) - { - case 0x00000000: nRc = 4; break; - case 0x00008000: nRc = 1; break; - case 0x00400000: nRc = 2; break; - case 0x00408000: nRc = 3; break; - default: nRc = 0; - } - - return(nRc); -} - -unsigned int getRoundingPrecision(const unsigned int opcode) -{ - unsigned int nRc; - - switch (opcode & MASK_ROUNDING_PRECISION) - { - case 0x00000000: nRc = 1; break; - case 0x00000080: nRc = 2; break; - case 0x00080000: nRc = 3; break; - default: nRc = 0; - } - - return(nRc); -} - -unsigned int getDestinationSize(const unsigned int opcode) -{ - unsigned int nRc; - - switch (opcode & MASK_DESTINATION_SIZE) - { - case 0x00000000: nRc = typeSingle; break; - case 0x00000080: nRc = typeDouble; break; - case 0x00080000: nRc = typeExtended; break; - default: nRc = typeNone; - } - - return(nRc); -} - -/* condition code lookup table - index into the table is test code: EQ, NE, ... LT, GT, AL, NV - bit position in short is condition code: NZCV */ -static const unsigned short aCC[16] = { - 0xF0F0, // EQ == Z set - 0x0F0F, // NE - 0xCCCC, // CS == C set - 0x3333, // CC - 0xFF00, // MI == N set - 0x00FF, // PL - 0xAAAA, // VS == V set - 0x5555, // VC - 0x0C0C, // HI == C set && Z clear - 0xF3F3, // LS == C clear || Z set - 0xAA55, // GE == (N==V) - 0x55AA, // LT == (N!=V) - 0x0A05, // GT == (!Z && (N==V)) - 0xF5FA, // LE == (Z || (N!=V)) - 0xFFFF, // AL always - 0 // NV -}; - -unsigned int checkCondition(const unsigned int opcode, const unsigned int ccodes) -{ - return (aCC[opcode>>28] >> (ccodes>>28)) & 1; -} diff --git a/target-arm/nwfpe/fpopcode.h b/target-arm/nwfpe/fpopcode.h deleted file mode 100644 index 6c51067..0000000 --- a/target-arm/nwfpe/fpopcode.h +++ /dev/null @@ -1,390 +0,0 @@ -/* - NetWinder Floating Point Emulator - (c) Rebel.COM, 1998,1999 - - 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. -*/ - -#ifndef __FPOPCODE_H__ -#define __FPOPCODE_H__ - -/* -ARM Floating Point Instruction Classes -| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | -|c o n d|1 1 0 P|U|u|W|L| Rn |v| Fd |0|0|0|1| o f f s e t | CPDT -|c o n d|1 1 0 P|U|w|W|L| Rn |x| Fd |0|0|0|1| o f f s e t | CPDT -| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | -|c o n d|1 1 1 0|a|b|c|d|e| Fn |j| Fd |0|0|0|1|f|g|h|0|i| Fm | CPDO -|c o n d|1 1 1 0|a|b|c|L|e| Fn | Rd |0|0|0|1|f|g|h|1|i| Fm | CPRT -|c o n d|1 1 1 0|a|b|c|1|e| Fn |1|1|1|1|0|0|0|1|f|g|h|1|i| Fm | comparisons -| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | - -CPDT data transfer instructions - LDF, STF, LFM, SFM - -CPDO dyadic arithmetic instructions - ADF, MUF, SUF, RSF, DVF, RDF, - POW, RPW, RMF, FML, FDV, FRD, POL - -CPDO monadic arithmetic instructions - MVF, MNF, ABS, RND, SQT, LOG, LGN, EXP, - SIN, COS, TAN, ASN, ACS, ATN, URD, NRM - -CPRT joint arithmetic/data transfer instructions - FIX (arithmetic followed by load/store) - FLT (load/store followed by arithmetic) - CMF, CNF CMFE, CNFE (comparisons) - WFS, RFS (write/read floating point status register) - WFC, RFC (write/read floating point control register) - -cond condition codes -P pre/post index bit: 0 = postindex, 1 = preindex -U up/down bit: 0 = stack grows down, 1 = stack grows up -W write back bit: 1 = update base register (Rn) -L load/store bit: 0 = store, 1 = load -Rn base register -Rd destination/source register -Fd floating point destination register -Fn floating point source register -Fm floating point source register or floating point constant - -uv transfer length (TABLE 1) -wx register count (TABLE 2) -abcd arithmetic opcode (TABLES 3 & 4) -ef destination size (rounding precision) (TABLE 5) -gh rounding mode (TABLE 6) -j dyadic/monadic bit: 0 = dyadic, 1 = monadic -i constant bit: 1 = constant (TABLE 6) -*/ - -/* -TABLE 1 -+-------------------------+---+---+---------+---------+ -| Precision | u | v | FPSR.EP | length | -+-------------------------+---+---+---------+---------+ -| Single | 0 ü 0 | x | 1 words | -| Double | 1 ü 1 | x | 2 words | -| Extended | 1 ü 1 | x | 3 words | -| Packed decimal | 1 ü 1 | 0 | 3 words | -| Expanded packed decimal | 1 ü 1 | 1 | 4 words | -+-------------------------+---+---+---------+---------+ -Note: x = don't care -*/ - -/* -TABLE 2 -+---+---+---------------------------------+ -| w | x | Number of registers to transfer | -+---+---+---------------------------------+ -| 0 ü 1 | 1 | -| 1 ü 0 | 2 | -| 1 ü 1 | 3 | -| 0 ü 0 | 4 | -+---+---+---------------------------------+ -*/ - -/* -TABLE 3: Dyadic Floating Point Opcodes -+---+---+---+---+----------+-----------------------+-----------------------+ -| a | b | c | d | Mnemonic | Description | Operation | -+---+---+---+---+----------+-----------------------+-----------------------+ -| 0 | 0 | 0 | 0 | ADF | Add | Fd := Fn + Fm | -| 0 | 0 | 0 | 1 | MUF | Multiply | Fd := Fn * Fm | -| 0 | 0 | 1 | 0 | SUF | Subtract | Fd := Fn - Fm | -| 0 | 0 | 1 | 1 | RSF | Reverse subtract | Fd := Fm - Fn | -| 0 | 1 | 0 | 0 | DVF | Divide | Fd := Fn / Fm | -| 0 | 1 | 0 | 1 | RDF | Reverse divide | Fd := Fm / Fn | -| 0 | 1 | 1 | 0 | POW | Power | Fd := Fn ^ Fm | -| 0 | 1 | 1 | 1 | RPW | Reverse power | Fd := Fm ^ Fn | -| 1 | 0 | 0 | 0 | RMF | Remainder | Fd := IEEE rem(Fn/Fm) | -| 1 | 0 | 0 | 1 | FML | Fast Multiply | Fd := Fn * Fm | -| 1 | 0 | 1 | 0 | FDV | Fast Divide | Fd := Fn / Fm | -| 1 | 0 | 1 | 1 | FRD | Fast reverse divide | Fd := Fm / Fn | -| 1 | 1 | 0 | 0 | POL | Polar angle (ArcTan2) | Fd := arctan2(Fn,Fm) | -| 1 | 1 | 0 | 1 | | undefined instruction | trap | -| 1 | 1 | 1 | 0 | | undefined instruction | trap | -| 1 | 1 | 1 | 1 | | undefined instruction | trap | -+---+---+---+---+----------+-----------------------+-----------------------+ -Note: POW, RPW, POL are deprecated, and are available for backwards - compatibility only. -*/ - -/* -TABLE 4: Monadic Floating Point Opcodes -+---+---+---+---+----------+-----------------------+-----------------------+ -| a | b | c | d | Mnemonic | Description | Operation | -+---+---+---+---+----------+-----------------------+-----------------------+ -| 0 | 0 | 0 | 0 | MVF | Move | Fd := Fm | -| 0 | 0 | 0 | 1 | MNF | Move negated | Fd := - Fm | -| 0 | 0 | 1 | 0 | ABS | Absolute value | Fd := abs(Fm) | -| 0 | 0 | 1 | 1 | RND | Round to integer | Fd := int(Fm) | -| 0 | 1 | 0 | 0 | SQT | Square root | Fd := sqrt(Fm) | -| 0 | 1 | 0 | 1 | LOG | Log base 10 | Fd := log10(Fm) | -| 0 | 1 | 1 | 0 | LGN | Log base e | Fd := ln(Fm) | -| 0 | 1 | 1 | 1 | EXP | Exponent | Fd := e ^ Fm | -| 1 | 0 | 0 | 0 | SIN | Sine | Fd := sin(Fm) | -| 1 | 0 | 0 | 1 | COS | Cosine | Fd := cos(Fm) | -| 1 | 0 | 1 | 0 | TAN | Tangent | Fd := tan(Fm) | -| 1 | 0 | 1 | 1 | ASN | Arc Sine | Fd := arcsin(Fm) | -| 1 | 1 | 0 | 0 | ACS | Arc Cosine | Fd := arccos(Fm) | -| 1 | 1 | 0 | 1 | ATN | Arc Tangent | Fd := arctan(Fm) | -| 1 | 1 | 1 | 0 | URD | Unnormalized round | Fd := int(Fm) | -| 1 | 1 | 1 | 1 | NRM | Normalize | Fd := norm(Fm) | -+---+---+---+---+----------+-----------------------+-----------------------+ -Note: LOG, LGN, EXP, SIN, COS, TAN, ASN, ACS, ATN are deprecated, and are - available for backwards compatibility only. -*/ - -/* -TABLE 5 -+-------------------------+---+---+ -| Rounding Precision | e | f | -+-------------------------+---+---+ -| IEEE Single precision | 0 ü 0 | -| IEEE Double precision | 0 ü 1 | -| IEEE Extended precision | 1 ü 0 | -| undefined (trap) | 1 ü 1 | -+-------------------------+---+---+ -*/ - -/* -TABLE 5 -+---------------------------------+---+---+ -| Rounding Mode | g | h | -+---------------------------------+---+---+ -| Round to nearest (default) | 0 ü 0 | -| Round toward plus infinity | 0 ü 1 | -| Round toward negative infinity | 1 ü 0 | -| Round toward zero | 1 ü 1 | -+---------------------------------+---+---+ -*/ - -/* -=== -=== Definitions for load and store instructions -=== -*/ - -/* bit masks */ -#define BIT_PREINDEX 0x01000000 -#define BIT_UP 0x00800000 -#define BIT_WRITE_BACK 0x00200000 -#define BIT_LOAD 0x00100000 - -/* masks for load/store */ -#define MASK_CPDT 0x0c000000 /* data processing opcode */ -#define MASK_OFFSET 0x000000ff -#define MASK_TRANSFER_LENGTH 0x00408000 -#define MASK_REGISTER_COUNT MASK_TRANSFER_LENGTH -#define MASK_COPROCESSOR 0x00000f00 - -/* Tests for transfer length */ -#define TRANSFER_SINGLE 0x00000000 -#define TRANSFER_DOUBLE 0x00008000 -#define TRANSFER_EXTENDED 0x00400000 -#define TRANSFER_PACKED MASK_TRANSFER_LENGTH - -/* Get the coprocessor number from the opcode. */ -#define getCoprocessorNumber(opcode) ((opcode & MASK_COPROCESSOR) >> 8) - -/* Get the offset from the opcode. */ -#define getOffset(opcode) (opcode & MASK_OFFSET) - -/* Tests for specific data transfer load/store opcodes. */ -#define TEST_OPCODE(opcode,mask) (((opcode) & (mask)) == (mask)) - -#define LOAD_OP(opcode) TEST_OPCODE((opcode),MASK_CPDT | BIT_LOAD) -#define STORE_OP(opcode) ((opcode & (MASK_CPDT | BIT_LOAD)) == MASK_CPDT) - -#define LDF_OP(opcode) (LOAD_OP(opcode) && (getCoprocessorNumber(opcode) == 1)) -#define LFM_OP(opcode) (LOAD_OP(opcode) && (getCoprocessorNumber(opcode) == 2)) -#define STF_OP(opcode) (STORE_OP(opcode) && (getCoprocessorNumber(opcode) == 1)) -#define SFM_OP(opcode) (STORE_OP(opcode) && (getCoprocessorNumber(opcode) == 2)) - -#define PREINDEXED(opcode) ((opcode & BIT_PREINDEX) != 0) -#define POSTINDEXED(opcode) ((opcode & BIT_PREINDEX) == 0) -#define BIT_UP_SET(opcode) ((opcode & BIT_UP) != 0) -#define BIT_UP_CLEAR(opcode) ((opcode & BIT_DOWN) == 0) -#define WRITE_BACK(opcode) ((opcode & BIT_WRITE_BACK) != 0) -#define LOAD(opcode) ((opcode & BIT_LOAD) != 0) -#define STORE(opcode) ((opcode & BIT_LOAD) == 0) - -/* -=== -=== Definitions for arithmetic instructions -=== -*/ -/* bit masks */ -#define BIT_MONADIC 0x00008000 -#define BIT_CONSTANT 0x00000008 - -#define CONSTANT_FM(opcode) ((opcode & BIT_CONSTANT) != 0) -#define MONADIC_INSTRUCTION(opcode) ((opcode & BIT_MONADIC) != 0) - -/* instruction identification masks */ -#define MASK_CPDO 0x0e000000 /* arithmetic opcode */ -#define MASK_ARITHMETIC_OPCODE 0x00f08000 -#define MASK_DESTINATION_SIZE 0x00080080 - -/* dyadic arithmetic opcodes. */ -#define ADF_CODE 0x00000000 -#define MUF_CODE 0x00100000 -#define SUF_CODE 0x00200000 -#define RSF_CODE 0x00300000 -#define DVF_CODE 0x00400000 -#define RDF_CODE 0x00500000 -#define POW_CODE 0x00600000 -#define RPW_CODE 0x00700000 -#define RMF_CODE 0x00800000 -#define FML_CODE 0x00900000 -#define FDV_CODE 0x00a00000 -#define FRD_CODE 0x00b00000 -#define POL_CODE 0x00c00000 -/* 0x00d00000 is an invalid dyadic arithmetic opcode */ -/* 0x00e00000 is an invalid dyadic arithmetic opcode */ -/* 0x00f00000 is an invalid dyadic arithmetic opcode */ - -/* monadic arithmetic opcodes. */ -#define MVF_CODE 0x00008000 -#define MNF_CODE 0x00108000 -#define ABS_CODE 0x00208000 -#define RND_CODE 0x00308000 -#define SQT_CODE 0x00408000 -#define LOG_CODE 0x00508000 -#define LGN_CODE 0x00608000 -#define EXP_CODE 0x00708000 -#define SIN_CODE 0x00808000 -#define COS_CODE 0x00908000 -#define TAN_CODE 0x00a08000 -#define ASN_CODE 0x00b08000 -#define ACS_CODE 0x00c08000 -#define ATN_CODE 0x00d08000 -#define URD_CODE 0x00e08000 -#define NRM_CODE 0x00f08000 - -/* -=== -=== Definitions for register transfer and comparison instructions -=== -*/ - -#define MASK_CPRT 0x0e000010 /* register transfer opcode */ -#define MASK_CPRT_CODE 0x00f00000 -#define FLT_CODE 0x00000000 -#define FIX_CODE 0x00100000 -#define WFS_CODE 0x00200000 -#define RFS_CODE 0x00300000 -#define WFC_CODE 0x00400000 -#define RFC_CODE 0x00500000 -#define CMF_CODE 0x00900000 -#define CNF_CODE 0x00b00000 -#define CMFE_CODE 0x00d00000 -#define CNFE_CODE 0x00f00000 - -/* -=== -=== Common definitions -=== -*/ - -/* register masks */ -#define MASK_Rd 0x0000f000 -#define MASK_Rn 0x000f0000 -#define MASK_Fd 0x00007000 -#define MASK_Fm 0x00000007 -#define MASK_Fn 0x00070000 - -/* condition code masks */ -#define CC_MASK 0xf0000000 -#define CC_NEGATIVE 0x80000000 -#define CC_ZERO 0x40000000 -#define CC_CARRY 0x20000000 -#define CC_OVERFLOW 0x10000000 -#define CC_EQ 0x00000000 -#define CC_NE 0x10000000 -#define CC_CS 0x20000000 -#define CC_HS CC_CS -#define CC_CC 0x30000000 -#define CC_LO CC_CC -#define CC_MI 0x40000000 -#define CC_PL 0x50000000 -#define CC_VS 0x60000000 -#define CC_VC 0x70000000 -#define CC_HI 0x80000000 -#define CC_LS 0x90000000 -#define CC_GE 0xa0000000 -#define CC_LT 0xb0000000 -#define CC_GT 0xc0000000 -#define CC_LE 0xd0000000 -#define CC_AL 0xe0000000 -#define CC_NV 0xf0000000 - -/* rounding masks/values */ -#define MASK_ROUNDING_MODE 0x00000060 -#define ROUND_TO_NEAREST 0x00000000 -#define ROUND_TO_PLUS_INFINITY 0x00000020 -#define ROUND_TO_MINUS_INFINITY 0x00000040 -#define ROUND_TO_ZERO 0x00000060 - -#define MASK_ROUNDING_PRECISION 0x00080080 -#define ROUND_SINGLE 0x00000000 -#define ROUND_DOUBLE 0x00000080 -#define ROUND_EXTENDED 0x00080000 - -/* Get the condition code from the opcode. */ -#define getCondition(opcode) (opcode >> 28) - -/* Get the source register from the opcode. */ -#define getRn(opcode) ((opcode & MASK_Rn) >> 16) - -/* Get the destination floating point register from the opcode. */ -#define getFd(opcode) ((opcode & MASK_Fd) >> 12) - -/* Get the first source floating point register from the opcode. */ -#define getFn(opcode) ((opcode & MASK_Fn) >> 16) - -/* Get the second source floating point register from the opcode. */ -#define getFm(opcode) (opcode & MASK_Fm) - -/* Get the destination register from the opcode. */ -#define getRd(opcode) ((opcode & MASK_Rd) >> 12) - -/* Get the rounding mode from the opcode. */ -#define getRoundingMode(opcode) ((opcode & MASK_ROUNDING_MODE) >> 5) - -static inline const floatx80 getExtendedConstant(const unsigned int nIndex) -{ - extern const floatx80 floatx80Constant[]; - return floatx80Constant[nIndex]; -} - -static inline const float64 getDoubleConstant(const unsigned int nIndex) -{ - extern const float64 float64Constant[]; - return float64Constant[nIndex]; -} - -static inline const float32 getSingleConstant(const unsigned int nIndex) -{ - extern const float32 float32Constant[]; - return float32Constant[nIndex]; -} - -extern unsigned int getRegisterCount(const unsigned int opcode); -extern unsigned int getDestinationSize(const unsigned int opcode); - -#endif diff --git a/target-arm/nwfpe/fpsr.h b/target-arm/nwfpe/fpsr.h deleted file mode 100644 index 0c66543..0000000 --- a/target-arm/nwfpe/fpsr.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - NetWinder Floating Point Emulator - (c) Rebel.com, 1998-1999 - - 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. -*/ - -#ifndef __FPSR_H__ -#define __FPSR_H__ - -/* -The FPSR is a 32 bit register consisting of 4 parts, each exactly -one byte. - - SYSTEM ID - EXCEPTION TRAP ENABLE BYTE - SYSTEM CONTROL BYTE - CUMULATIVE EXCEPTION FLAGS BYTE - -The FPCR is a 32 bit register consisting of bit flags. -*/ - -/* SYSTEM ID ------------- -Note: the system id byte is read only */ - -typedef unsigned int FPSR; /* type for floating point status register */ -typedef unsigned int FPCR; /* type for floating point control register */ - -#define MASK_SYSID 0xff000000 -#define BIT_HARDWARE 0x80000000 -#define FP_EMULATOR 0x01000000 /* System ID for emulator */ -#define FP_ACCELERATOR 0x81000000 /* System ID for FPA11 */ - -/* EXCEPTION TRAP ENABLE BYTE ------------------------------ */ - -#define MASK_TRAP_ENABLE 0x00ff0000 -#define MASK_TRAP_ENABLE_STRICT 0x001f0000 -#define BIT_IXE 0x00100000 /* inexact exception enable */ -#define BIT_UFE 0x00080000 /* underflow exception enable */ -#define BIT_OFE 0x00040000 /* overflow exception enable */ -#define BIT_DZE 0x00020000 /* divide by zero exception enable */ -#define BIT_IOE 0x00010000 /* invalid operation exception enable */ - -/* SYSTEM CONTROL BYTE ----------------------- */ - -#define MASK_SYSTEM_CONTROL 0x0000ff00 -#define MASK_TRAP_STRICT 0x00001f00 - -#define BIT_AC 0x00001000 /* use alternative C-flag definition - for compares */ -#define BIT_EP 0x00000800 /* use expanded packed decimal format */ -#define BIT_SO 0x00000400 /* select synchronous operation of FPA */ -#define BIT_NE 0x00000200 /* NaN exception bit */ -#define BIT_ND 0x00000100 /* no denormalized numbers bit */ - -/* CUMULATIVE EXCEPTION FLAGS BYTE ----------------------------------- */ - -#define MASK_EXCEPTION_FLAGS 0x000000ff -#define MASK_EXCEPTION_FLAGS_STRICT 0x0000001f - -#define BIT_IXC 0x00000010 /* inexact exception flag */ -#define BIT_UFC 0x00000008 /* underflow exception flag */ -#define BIT_OFC 0x00000004 /* overfloat exception flag */ -#define BIT_DZC 0x00000002 /* divide by zero exception flag */ -#define BIT_IOC 0x00000001 /* invalid operation exception flag */ - -/* Floating Point Control Register -----------------------------------*/ - -#define BIT_RU 0x80000000 /* rounded up bit */ -#define BIT_IE 0x10000000 /* inexact bit */ -#define BIT_MO 0x08000000 /* mantissa overflow bit */ -#define BIT_EO 0x04000000 /* exponent overflow bit */ -#define BIT_SB 0x00000800 /* store bounce */ -#define BIT_AB 0x00000400 /* arithmetic bounce */ -#define BIT_RE 0x00000200 /* rounding exception */ -#define BIT_DA 0x00000100 /* disable FPA */ - -#define MASK_OP 0x00f08010 /* AU operation code */ -#define MASK_PR 0x00080080 /* AU precision */ -#define MASK_S1 0x00070000 /* AU source register 1 */ -#define MASK_S2 0x00000007 /* AU source register 2 */ -#define MASK_DS 0x00007000 /* AU destination register */ -#define MASK_RM 0x00000060 /* AU rounding mode */ -#define MASK_ALU 0x9cfff2ff /* only ALU can write these bits */ -#define MASK_RESET 0x00000d00 /* bits set on reset, all others cleared */ -#define MASK_WFC MASK_RESET -#define MASK_RFC ~MASK_RESET - -#endif diff --git a/target-arm/nwfpe/single_cpdo.c b/target-arm/nwfpe/single_cpdo.c deleted file mode 100644 index 65043bc..0000000 --- a/target-arm/nwfpe/single_cpdo.c +++ /dev/null @@ -1,253 +0,0 @@ -/* - NetWinder Floating Point Emulator - (c) Rebel.COM, 1998,1999 - - 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 "softfloat.h" -#include "fpopcode.h" - -float32 float32_exp(float32 Fm); -float32 float32_ln(float32 Fm); -float32 float32_sin(float32 rFm); -float32 float32_cos(float32 rFm); -float32 float32_arcsin(float32 rFm); -float32 float32_arctan(float32 rFm); -float32 float32_log(float32 rFm); -float32 float32_tan(float32 rFm); -float32 float32_arccos(float32 rFm); -float32 float32_pow(float32 rFn,float32 rFm); -float32 float32_pol(float32 rFn,float32 rFm); - -unsigned int SingleCPDO(const unsigned int opcode) -{ - FPA11 *fpa11 = GET_FPA11(); - float32 rFm, rFn = float32_zero; - unsigned int Fd, Fm, Fn, nRc = 1; - - Fm = getFm(opcode); - if (CONSTANT_FM(opcode)) - { - rFm = getSingleConstant(Fm); - } - else - { - switch (fpa11->fType[Fm]) - { - case typeSingle: - rFm = fpa11->fpreg[Fm].fSingle; - break; - - default: return 0; - } - } - - if (!MONADIC_INSTRUCTION(opcode)) - { - Fn = getFn(opcode); - switch (fpa11->fType[Fn]) - { - case typeSingle: - rFn = fpa11->fpreg[Fn].fSingle; - break; - - default: return 0; - } - } - - Fd = getFd(opcode); - switch (opcode & MASK_ARITHMETIC_OPCODE) - { - /* dyadic opcodes */ - case ADF_CODE: - fpa11->fpreg[Fd].fSingle = float32_add(rFn,rFm, &fpa11->fp_status); - break; - - case MUF_CODE: - case FML_CODE: - fpa11->fpreg[Fd].fSingle = float32_mul(rFn,rFm, &fpa11->fp_status); - break; - - case SUF_CODE: - fpa11->fpreg[Fd].fSingle = float32_sub(rFn,rFm, &fpa11->fp_status); - break; - - case RSF_CODE: - fpa11->fpreg[Fd].fSingle = float32_sub(rFm,rFn, &fpa11->fp_status); - break; - - case DVF_CODE: - case FDV_CODE: - fpa11->fpreg[Fd].fSingle = float32_div(rFn,rFm, &fpa11->fp_status); - break; - - case RDF_CODE: - case FRD_CODE: - fpa11->fpreg[Fd].fSingle = float32_div(rFm,rFn, &fpa11->fp_status); - break; - -#if 0 - case POW_CODE: - fpa11->fpreg[Fd].fSingle = float32_pow(rFn,rFm); - break; - - case RPW_CODE: - fpa11->fpreg[Fd].fSingle = float32_pow(rFm,rFn); - break; -#endif - - case RMF_CODE: - fpa11->fpreg[Fd].fSingle = float32_rem(rFn,rFm, &fpa11->fp_status); - break; - -#if 0 - case POL_CODE: - fpa11->fpreg[Fd].fSingle = float32_pol(rFn,rFm); - break; -#endif - - /* monadic opcodes */ - case MVF_CODE: - fpa11->fpreg[Fd].fSingle = rFm; - break; - - case MNF_CODE: - fpa11->fpreg[Fd].fSingle = float32_chs(rFm); - break; - - case ABS_CODE: - fpa11->fpreg[Fd].fSingle = float32_abs(rFm); - break; - - case RND_CODE: - case URD_CODE: - fpa11->fpreg[Fd].fSingle = float32_round_to_int(rFm, &fpa11->fp_status); - break; - - case SQT_CODE: - fpa11->fpreg[Fd].fSingle = float32_sqrt(rFm, &fpa11->fp_status); - break; - -#if 0 - case LOG_CODE: - fpa11->fpreg[Fd].fSingle = float32_log(rFm); - break; - - case LGN_CODE: - fpa11->fpreg[Fd].fSingle = float32_ln(rFm); - break; - - case EXP_CODE: - fpa11->fpreg[Fd].fSingle = float32_exp(rFm); - break; - - case SIN_CODE: - fpa11->fpreg[Fd].fSingle = float32_sin(rFm); - break; - - case COS_CODE: - fpa11->fpreg[Fd].fSingle = float32_cos(rFm); - break; - - case TAN_CODE: - fpa11->fpreg[Fd].fSingle = float32_tan(rFm); - break; - - case ASN_CODE: - fpa11->fpreg[Fd].fSingle = float32_arcsin(rFm); - break; - - case ACS_CODE: - fpa11->fpreg[Fd].fSingle = float32_arccos(rFm); - break; - - case ATN_CODE: - fpa11->fpreg[Fd].fSingle = float32_arctan(rFm); - break; -#endif - - case NRM_CODE: - break; - - default: - { - nRc = 0; - } - } - - if (0 != nRc) fpa11->fType[Fd] = typeSingle; - return nRc; -} - -#if 0 -float32 float32_exp(float32 Fm) -{ -//series -} - -float32 float32_ln(float32 Fm) -{ -//series -} - -float32 float32_sin(float32 rFm) -{ -//series -} - -float32 float32_cos(float32 rFm) -{ -//series -} - -float32 float32_arcsin(float32 rFm) -{ -//series -} - -float32 float32_arctan(float32 rFm) -{ - //series -} - -float32 float32_arccos(float32 rFm) -{ - //return float32_sub(halfPi,float32_arcsin(rFm)); -} - -float32 float32_log(float32 rFm) -{ - return float32_div(float32_ln(rFm),getSingleConstant(7)); -} - -float32 float32_tan(float32 rFm) -{ - return float32_div(float32_sin(rFm),float32_cos(rFm)); -} - -float32 float32_pow(float32 rFn,float32 rFm) -{ - return float32_exp(float32_mul(rFm,float32_ln(rFn))); -} - -float32 float32_pol(float32 rFn,float32 rFm) -{ - return float32_arctan(float32_div(rFn,rFm)); -} -#endif |