Move target-arm/nwfpe into linux-user/arm/nwfpe
authoraurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162>
Wed, 9 Apr 2008 06:53:01 +0000 (06:53 +0000)
committeraurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162>
Wed, 9 Apr 2008 06:53:01 +0000 (06:53 +0000)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4185 c046a42c-6fe2-441c-8c8c-71466251a162

25 files changed:
Makefile.target
linux-user/arm/nwfpe/double_cpdo.c [new file with mode: 0644]
linux-user/arm/nwfpe/extended_cpdo.c [new file with mode: 0644]
linux-user/arm/nwfpe/fpa11.c [new file with mode: 0644]
linux-user/arm/nwfpe/fpa11.h [new file with mode: 0644]
linux-user/arm/nwfpe/fpa11.inl [new file with mode: 0644]
linux-user/arm/nwfpe/fpa11_cpdo.c [new file with mode: 0644]
linux-user/arm/nwfpe/fpa11_cpdt.c [new file with mode: 0644]
linux-user/arm/nwfpe/fpa11_cprt.c [new file with mode: 0644]
linux-user/arm/nwfpe/fpopcode.c [new file with mode: 0644]
linux-user/arm/nwfpe/fpopcode.h [new file with mode: 0644]
linux-user/arm/nwfpe/fpsr.h [new file with mode: 0644]
linux-user/arm/nwfpe/single_cpdo.c [new file with mode: 0644]
target-arm/nwfpe/double_cpdo.c [deleted file]
target-arm/nwfpe/extended_cpdo.c [deleted file]
target-arm/nwfpe/fpa11.c [deleted file]
target-arm/nwfpe/fpa11.h [deleted file]
target-arm/nwfpe/fpa11.inl [deleted file]
target-arm/nwfpe/fpa11_cpdo.c [deleted file]
target-arm/nwfpe/fpa11_cpdt.c [deleted file]
target-arm/nwfpe/fpa11_cprt.c [deleted file]
target-arm/nwfpe/fpopcode.c [deleted file]
target-arm/nwfpe/fpopcode.h [deleted file]
target-arm/nwfpe/fpsr.h [deleted file]
target-arm/nwfpe/single_cpdo.c [deleted file]

index 8177e7d..d92c109 100644 (file)
@@ -322,10 +322,10 @@ cpu-exec.o: cpu-exec.c
 
 ifdef CONFIG_LINUX_USER
 
-VPATH+=:$(SRC_PATH)/linux-user
 ifndef TARGET_ABI_DIR
   TARGET_ABI_DIR=$(TARGET_ARCH)
 endif
+VPATH+=:$(SRC_PATH)/linux-user:$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR)
 CPPFLAGS+=-I$(SRC_PATH)/linux-user -I$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR)
 
 ifdef CONFIG_STATIC
diff --git a/linux-user/arm/nwfpe/double_cpdo.c b/linux-user/arm/nwfpe/double_cpdo.c
new file mode 100644 (file)
index 0000000..b5320c8
--- /dev/null
@@ -0,0 +1,296 @@
+/*
+    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/linux-user/arm/nwfpe/extended_cpdo.c b/linux-user/arm/nwfpe/extended_cpdo.c
new file mode 100644 (file)
index 0000000..05e32b0
--- /dev/null
@@ -0,0 +1,273 @@
+/*
+    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/linux-user/arm/nwfpe/fpa11.c b/linux-user/arm/nwfpe/fpa11.c
new file mode 100644 (file)
index 0000000..626a87a
--- /dev/null
@@ -0,0 +1,244 @@
+/*
+    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/linux-user/arm/nwfpe/fpa11.h b/linux-user/arm/nwfpe/fpa11.h
new file mode 100644 (file)
index 0000000..4fc0b3b
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+    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/linux-user/arm/nwfpe/fpa11.inl b/linux-user/arm/nwfpe/fpa11.inl
new file mode 100644 (file)
index 0000000..7183ec9
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+    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/linux-user/arm/nwfpe/fpa11_cpdo.c b/linux-user/arm/nwfpe/fpa11_cpdo.c
new file mode 100644 (file)
index 0000000..7779637
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+    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/linux-user/arm/nwfpe/fpa11_cpdt.c b/linux-user/arm/nwfpe/fpa11_cpdt.c
new file mode 100644 (file)
index 0000000..41877df
--- /dev/null
@@ -0,0 +1,386 @@
+/*
+    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/linux-user/arm/nwfpe/fpa11_cprt.c b/linux-user/arm/nwfpe/fpa11_cprt.c
new file mode 100644 (file)
index 0000000..04eae8c
--- /dev/null
@@ -0,0 +1,286 @@
+/*
+    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/linux-user/arm/nwfpe/fpopcode.c b/linux-user/arm/nwfpe/fpopcode.c
new file mode 100644 (file)
index 0000000..a733a1d
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+    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/linux-user/arm/nwfpe/fpopcode.h b/linux-user/arm/nwfpe/fpopcode.h
new file mode 100644 (file)
index 0000000..6c51067
--- /dev/null
@@ -0,0 +1,390 @@
+/*
+    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/linux-user/arm/nwfpe/fpsr.h b/linux-user/arm/nwfpe/fpsr.h
new file mode 100644 (file)
index 0000000..0c66543
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+    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/linux-user/arm/nwfpe/single_cpdo.c b/linux-user/arm/nwfpe/single_cpdo.c
new file mode 100644 (file)
index 0000000..65043bc
--- /dev/null
@@ -0,0 +1,253 @@
+/*
+    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
diff --git a/target-arm/nwfpe/double_cpdo.c b/target-arm/nwfpe/double_cpdo.c
deleted file mode 100644 (file)
index b5320c8..0000000
+++ /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 (file)
index 05e32b0..0000000
+++ /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 (file)
index 626a87a..0000000
+++ /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 (file)
index 4fc0b3b..0000000
+++ /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 (file)
index 7183ec9..0000000
+++ /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 (file)
index 7779637..0000000
+++ /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 (file)
index 41877df..0000000
+++ /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 (file)
index 04eae8c..0000000
+++ /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 (file)
index a733a1d..0000000
+++ /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 (file)
index 6c51067..0000000
+++ /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 (file)
index 0c66543..0000000
+++ /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 (file)
index 65043bc..0000000
+++ /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