* src/z80/ralloc.c (packRegsForHLUse): Banned IFXs from being packed into HL.
authormichaelh <michaelh@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Wed, 7 Nov 2001 21:17:05 +0000 (21:17 +0000)
committermichaelh <michaelh@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Wed, 7 Nov 2001 21:17:05 +0000 (21:17 +0000)
(packRegsForHLUse): Added rule to pack address of/pointer get for itemps into HL for the Z80.
(packRegsForAccUse2): Added rule to pack hbit IFXs into A.

* src/z80/main.c (_setDefaultOptions): Made float code re-entrant by default.

* src/z80/gen.c (aopGetLitWordLong): Added word support for floats.
(genNotFloat): Added.
(genUminusFloat): Added.

* device/lib/z80/Makefile: Added floating pt stubs.

* device/lib/Makefile.in (Z80SOURCES): Added floating pt support.

* src/z80/gen.c (genIpush): Fixed up a push of one byte when left is in a pair.

* device/lib/_fsadd.c (__fsadd): Fixed up return where the numbers are hugely different.

git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@1524 4a8a32a2-be11-0410-ad9d-d568d2c75423

23 files changed:
ChangeLog
device/lib/Makefile.in
device/lib/_fs2schar.c
device/lib/_fs2sint.c
device/lib/_fs2slong.c
device/lib/_fs2uchar.c
device/lib/_fs2uint.c
device/lib/_fsadd.c
device/lib/_schar2fs.c
device/lib/_sint2fs.c
device/lib/_slong2fs.c
device/lib/_uchar2fs.c
device/lib/_uint2fs.c
device/lib/gbz80/Makefile
device/lib/gbz80/fstubs.s [new file with mode: 0644]
device/lib/z80/Makefile
device/lib/z80/fstubs.s [new file with mode: 0644]
src/z80/gen.c
src/z80/main.c
src/z80/peeph.def
src/z80/ralloc.c
support/regression/tests/driverstruct.c
support/regression/tests/float.c [new file with mode: 0644]

index a5c420c22e85b40de21c38475c293bbd82111540..11b1f65a93d72772392dabbaf5b6a52aecd8e49e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+2001-11-07  Michael Hope  <michaelh@juju.net.nz>
+
+       * src/z80/ralloc.c (packRegsForHLUse): Banned IFXs from being packed into HL.
+       (packRegsForHLUse): Added rule to pack address of/pointer get for itemps into HL for the Z80.
+       (packRegsForAccUse2): Added rule to pack hbit IFXs into A.
+
+       * src/z80/main.c (_setDefaultOptions): Made float code re-entrant by default.
+
+       * src/z80/gen.c (aopGetLitWordLong): Added word support for floats.
+       (genNotFloat): Added.
+       (genUminusFloat): Added.
+
+       * device/lib/z80/Makefile: Added floating pt stubs.
+
+       * device/lib/Makefile.in (Z80SOURCES): Added floating pt support.
+
+       * src/z80/gen.c (genIpush): Fixed up a push of one byte when left is in a pair.
+
+       * device/lib/_fsadd.c (__fsadd): Fixed up return where the numbers are hugely different.
+
 2001-11-07  Bernhard Held  <bernhard@bernhardheld.de>
 
        * sdcc/sim/ucsim/s51.src/glob.cc: Minor fix.
index 102f62ab55988b74cf13c645c438e632582e1207..4f282582760c78e7bf0b2346a308f8a9f7355571 100644 (file)
@@ -75,7 +75,14 @@ Z80SOURCES      = _atoi.c \
                  _modslong.c _modulong.c \
                  _mullong.c \
                  _divslong.c _divulong.c \
-                 malloc.c
+                 malloc.c \
+                 _fs2schar.c _fs2sint.c _fs2slong.c \
+                 _fs2uchar.c _fs2uint.c _fs2ulong.c _fsadd.c \
+                 _fsdiv.c _fseq.c _fsgt.c _fslt.c _fsmul.c \
+                 _fsneq.c _fssub.c \
+                 _uchar2fs.c _uint2fs.c \
+                 _ulong2fs.c \
+                 _slong2fs.c _sint2fs.c _schar2fs.c 
 
 Z80OBJECTS      = $(Z80SOURCES:%.c=$(PORTDIR)/%.o)
 
index c804e71052ae451533a7f8a49e8d431232946703..b783ea595d71da2a64e064a16c47e724c3a8abe9 100644 (file)
@@ -1,5 +1,7 @@
 #include <limits.h>
 
+signed long __fs2slong (float f);
+
 /* convert float to signed char */
 signed char __fs2schar (float f) {
   signed long sl=__fs2slong(f);
index bb578292012877427c3301b120f3ff9f58a0256d..dd49c4e799974e27c66d10f876cac8cb1d23f539 100644 (file)
@@ -1,5 +1,7 @@
 #include <limits.h>
 
+signed long __fs2slong (float f);
+
 /* convert float to signed int */
 signed int __fs2sint (float f) {
   signed long sl=__fs2slong(f);
index 82f9255f23ed21c7392b256037cca56b8a807831..1c3aec8c8f7d49a2dee2042d9256972010a14819 100644 (file)
@@ -1,5 +1,7 @@
 #include <limits.h>
 
+unsigned long __fs2ulong (float a1);
+
 /* convert float to signed long */
 signed long __fs2slong (float f) {
 
index 3bfa951e12f9fbe72151142ac7ca9b2b039300e2..68e4c6799df0ea114254b44b37f3eb232c998222 100644 (file)
@@ -1,5 +1,7 @@
 #include <limits.h>
 
+unsigned long __fs2ulong (float a1);
+
 /* convert float to unsigned char */
 unsigned char __fs2uchar (float f) {
   unsigned long ul=__fs2ulong(f);
index 0eaa2edf4b26f0757a2dc564345827df8f9adadc..464a729e24649d5ba08588506695b78fee8d8899 100644 (file)
@@ -1,5 +1,7 @@
 #include <limits.h>
 
+unsigned long __fs2ulong (float a1);
+
 /* convert float to unsigned int */
 unsigned int __fs2uint (float f) {
   unsigned long ul=__fs2ulong(f);
index be0b44fc1271bcf72646648275c481180a986c8b..a4273d9abbdb5aaec208bf5535247c0117b3b639 100644 (file)
@@ -19,7 +19,7 @@ __fsadd (float a1, float a2)
   volatile long mant1, mant2;
   volatile union float_long fl1, fl2;
   volatile int exp1, exp2;
-  volatile long sign = 0;
+  volatile unsigned long sign = 0;
 
   fl1.f = a1;
   fl2.f = a2;
@@ -34,9 +34,9 @@ __fsadd (float a1, float a2)
   exp2 = EXP (fl2.l);
 
   if (exp1 > exp2 + 25)
-    return (fl1.l);
+    return (fl1.f);
   if (exp2 > exp1 + 25)
-    return (fl2.l);
+    return (fl2.f);
 
   /* do everything in excess precision so's we can round later */
   mant1 = MANT (fl1.l) << 6;
@@ -67,14 +67,14 @@ __fsadd (float a1, float a2)
     return (0);
 
   /* normalize up */
-  while (!(mant1 & (unsigned long) 0xE0000000))
+  while (!((unsigned long)mant1 & (unsigned long) 0xE0000000))
     {
       mant1 <<= 1;
       exp1--;
     }
 
   /* normalize down? */
-  if (mant1 & (unsigned long)(1 << 30))
+  if ((unsigned long)mant1 & (unsigned long)(1 << 30))
     {
       mant1 >>= 1 ;
       exp1++;
@@ -94,7 +94,7 @@ __fsadd (float a1, float a2)
   mant1 >>= 6;
 
   /* turn off hidden bit */
-  mant1 &= ~HIDDEN;
+  mant1 = (unsigned long)mant1 & ~HIDDEN;
 
   /* pack up and go home */
   fl1.l = PACK (sign, (unsigned long) exp1, mant1);
index d3227fffe266560fb34e518ac7524cfc7a24f5ed..f7c90f33bfe6b2d985e00809ecf86edc1a8646b0 100644 (file)
@@ -1,3 +1,5 @@
+float __slong2fs (long a );
+
 /* convert signed char to float */
 float __schar2fs (signed char sc) {
   signed long sl=sc;
index 679eaf7d214fcf3177eac1de5871b57c622d6591..4ee9c8008dd6e5cca2ec786c3a01dd8b39eeabb8 100644 (file)
@@ -1,3 +1,5 @@
+float __slong2fs (signed long sl);
+
 /* convert signed int to float */
 float __sint2fs (signed int si) {
   signed long sl=si;
index 0b1e2259da4920cc36896a9185763c5c161c877f..11516e4f04ed5d22aedc9c72be7996d142587f5b 100644 (file)
@@ -1,5 +1,9 @@
+float 
+__ulong2fs (unsigned long a );
+
 /* convert signed long to float */
-float __slong2fs (signed long sl) {
+float __slong2fs (signed long sl) 
+{
   if (sl<0) 
     return -__ulong2fs(-sl);
   else 
index 3c9633e8bd3320f4bb75026d08d994718ca7d570..475253016026ebb3a66a659fa44e0c0433d664df 100644 (file)
@@ -1,3 +1,5 @@
+float __ulong2fs (unsigned long a );
+
 /* convert unsigned char to float */
 float __uchar2fs (unsigned char uc) {
   unsigned long ul=uc;
index 9a78b4c9f9919a1798091b66530e5cec9f462dd5..514c0211af94fd1c67284dcacdc819953d3406f6 100644 (file)
@@ -1,3 +1,5 @@
+float __ulong2fs (unsigned long a );
+
 /* convert unsigned int to float */
 float __uint2fs (unsigned int ui) {
   unsigned long ul=ui;
index 40480d66bc552d89aaa5b42cdaee85aedd7ba61d..e41c61f2dd99de98cdd8ba5595fc9927fb43e25e 100644 (file)
@@ -5,7 +5,7 @@ TOPDIR = ../../..
 SCC = $(TOPDIR)/bin/sdcc -mgbz80
 SAS = $(TOPDIR)/bin/as-gbz80
 
-OBJ = div.o mul.o putchar.o printf.o shift.o stubs.o crt0_rle.o heap.o
+OBJ = div.o mul.o putchar.o printf.o shift.o stubs.o crt0_rle.o heap.o fstubs.o
 
 LIB = gbz80.lib
 CC = $(SCC)
diff --git a/device/lib/gbz80/fstubs.s b/device/lib/gbz80/fstubs.s
new file mode 100644 (file)
index 0000000..3d5f610
--- /dev/null
@@ -0,0 +1,5 @@
+        ;; Stubs to match between function names
+        .area _CODE
+
+___slong2fs_rrx_s::     
+        jp      ___slong2fs
index cda0855eebb843b88f8ca9708653a0e90bc7fc64..ae0e16f4ed7f05947da80b0e8e44457d9213b7da 100644 (file)
@@ -5,7 +5,8 @@ TOPDIR = ../../..
 SCC = $(TOPDIR)/bin/sdcc -mz80
 SAS = $(TOPDIR)/bin/as-z80
 
-OBJ = div.o mul.o putchar.o printf.o shift.o stubs.o crt0_rle.o heap.o
+OBJ = div.o mul.o putchar.o printf.o shift.o stubs.o crt0_rle.o heap.o \
+       fstubs.o
 
 LIB = z80.lib
 CC = $(SCC)
diff --git a/device/lib/z80/fstubs.s b/device/lib/z80/fstubs.s
new file mode 100644 (file)
index 0000000..3d5f610
--- /dev/null
@@ -0,0 +1,5 @@
+        ;; Stubs to match between function names
+        .area _CODE
+
+___slong2fs_rrx_s::     
+        jp      ___slong2fs
index b9e9569a832c9b2d7b3611ae14b4fe94c939a2c2..7515252e6f0e69fc3dd40171ea5b5d8f0c72e499 100644 (file)
@@ -940,7 +940,6 @@ char *
 aopGetLitWordLong (asmop * aop, int offset, bool with_hash)
 {
   char *s = buffer;
-  char *rs;
 
   /* depending on type */
   switch (aop->type)
@@ -994,15 +993,27 @@ aopGetLitWordLong (asmop * aop, int offset, bool with_hash)
          }
        else
          {
-           /* A float */
-           Z80_FLOAT f;
-           convertFloat (&f, floatFromVal (val));
+            union {
+              float f;
+              unsigned char c[4];
+            }
+            fl;
+            unsigned int i;
+
+            /* it is type float */
+            fl.f = (float) floatFromVal (val);
+
+#ifdef _BIG_ENDIAN
+            i = fl.c[3-offset] | (fl.c[3-offset-1]<<8);
+#else
+            i = fl.c[offset] | (fl.c[offset+1]<<8);
+#endif
            if (with_hash)
-             tsprintf (buffer, "!immedword", f.w[offset / 2]);
+             tsprintf (buffer, "!immedword", i);
            else
-             tsprintf (buffer, "!constword", f.w[offset / 2]);
-           rs = Safe_calloc (1, strlen (buffer) + 1);
-           return strcpy (rs, buffer);
+             tsprintf (buffer, "!constword", i);
+
+            return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
          }
       }
     default:
@@ -1787,6 +1798,44 @@ _toBoolean (operand * oper)
     }
 }
 
+/*-----------------------------------------------------------------*/
+/* genNotFloat - generates not for float operations              */
+/*-----------------------------------------------------------------*/
+static void
+genNotFloat (operand * op, operand * res)
+{
+  int size, offset;
+  symbol *tlbl;
+
+  emitDebug ("; genNotFloat");
+
+  /* we will put 127 in the first byte of
+     the result */
+  aopPut (AOP (res), "!immedbyte", 0x7F);
+  size = AOP_SIZE (op) - 1;
+  offset = 1;
+
+  _moveA (aopGet (op->aop, offset++, FALSE));
+
+  while (size--)
+    {
+      emit2 ("or a,%s", aopGet (op->aop, offset++, FALSE));
+    }
+
+  tlbl = newiTempLabel (NULL);
+  aopPut (res->aop, "!one", 1);
+  emit2 ("!shortjp z !tlabel", tlbl->key + 100);
+  aopPut (res->aop, "!zero", 1);
+
+  emitLabel(tlbl->key + 100);
+
+  size = res->aop->size - 2;
+  offset = 2;
+  /* put zeros in the rest */
+  while (size--)
+    aopPut (res->aop, "!zero", offset++);
+}
+
 /*-----------------------------------------------------------------*/
 /* genNot - generate code for ! operation                          */
 /*-----------------------------------------------------------------*/
@@ -1808,7 +1857,8 @@ genNot (iCode * ic)
   /* if type float then do float */
   if (IS_FLOAT (optype))
     {
-      wassertl (0, "Tried to negate a float");
+      genNotFloat (IC_LEFT (ic), IC_RESULT (ic));
+      goto release;
     }
 
   _toBoolean (IC_LEFT (ic));
@@ -1820,6 +1870,7 @@ genNot (iCode * ic)
   emit2 ("sub a,!one");
   outBitC (IC_RESULT (ic));
 
+ release:
   /* release the aops */
   freeAsmop (IC_LEFT (ic), NULL, ic);
   freeAsmop (IC_RESULT (ic), NULL, ic);
@@ -1914,6 +1965,32 @@ _gbz80_emitAddSubLong (iCode *ic, bool isAdd)
   _gbz80_emitAddSubLongLong (ic, AOP (IC_LEFT (ic)), AOP (IC_RIGHT (ic)), isAdd);
 }
 
+/*-----------------------------------------------------------------*/
+/* genUminusFloat - unary minus for floating points                */
+/*-----------------------------------------------------------------*/
+static void
+genUminusFloat (operand * op, operand * result)
+{
+  int size, offset = 0;
+
+  emitDebug("; genUminusFloat");
+
+  /* for this we just need to flip the
+     first it then copy the rest in place */
+  size = AOP_SIZE (op) - 1;
+
+  _moveA(aopGet (AOP (op), MSB32, FALSE));
+
+  emit2("xor a,!immedbyte", 0x80);
+  aopPut (AOP (result), "a", MSB32);
+
+  while (size--)
+    {
+      aopPut (AOP (result), aopGet (AOP (op), offset, FALSE), offset);
+      offset++;
+    }
+}
+
 /*-----------------------------------------------------------------*/
 /* genUminus - unary minus code generation                         */
 /*-----------------------------------------------------------------*/
@@ -1942,7 +2019,7 @@ genUminus (iCode * ic)
   /* if float then do float stuff */
   if (IS_FLOAT (optype))
     {
-      wassertl (0, "Tried to do a unary minus on a float");
+      genUminusFloat (IC_LEFT (ic), IC_RESULT (ic));
       goto release;
     }
 
@@ -2140,7 +2217,7 @@ genIpush (iCode * ic)
 
   size = AOP_SIZE (IC_LEFT (ic));
 
-  if (isPair (AOP (IC_LEFT (ic))))
+  if (isPair (AOP (IC_LEFT (ic))) && size == 2)
     {
       _G.stack.pushed += 2;
       emit2 ("push %s", getPairName (AOP (IC_LEFT (ic))));
index d2b2639c53a0910b98c9d471a7ad4c42a0a00373..7727275f4808b2e0876046fdd1b344cc2406db9f 100644 (file)
@@ -320,6 +320,7 @@ _setDefaultOptions (void)
   options.mainreturn = 1;
   /* first the options part */
   options.intlong_rent = 1;
+  options.float_rent = 1;
   options.noRegParams = 1;
   /* Default code and data locations. */
   options.code_loc = 0x200;
index e29001de514754e985d6ad18aac44e2b04bb3b86..a00fd659c13633cb4d20a6532b012532a47ff28c 100644 (file)
@@ -96,12 +96,18 @@ replace restart {
 } by {
         xor     a,a
 }
-replace restart {
+replace {
         ld      e,#0x00
         ld      d,#0x00
 } by {
         ld      de,#0x0000
 }
+replace {
+       ld      l,#0x00
+       ld      h,#0x00
+} by {
+        ld      hl,#0x0000
+}
 replace restart {
        ld      %1,a
        ld      a,%1
@@ -119,3 +125,20 @@ replace restart {
 %2:
        jp      %4
 }
+replace {
+       ld      l,e
+       ld      h,d
+       push    hl
+       ld      l,c
+       ld      h,b
+       push    hl
+} by {
+        push   de
+        push    bc
+}
+replace {
+       and     a,#%1
+       or      a,a
+} by {
+        and     a,#%1
+}
index dd248b713dad259261e08f6b3c7eae6bd78ca010..59ee73c6d33657b3b599144f82e8bfc310bb74ed 100644 (file)
@@ -2018,6 +2018,12 @@ packRegsForHLUse (iCode * ic)
 {
   iCode *uic;
 
+  /* PENDING: Could do IFX */
+  if (ic->op == IFX)
+    {
+      return;
+    }
+
   /* has only one definition */
   if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
     {
@@ -2046,9 +2052,17 @@ packRegsForHLUse (iCode * ic)
       return;
     }
 
-  if (getSize (operandType (IC_RESULT (ic))) != 2)
+  if (uic->op ==IFX)
+    {
+      return;
+    }
+
+  if (getSize (operandType (IC_RESULT (ic))) != 2 ||
+      (IC_LEFT(uic) && getSize (operandType (IC_LEFT (uic))) != 2) ||
+      (IC_RIGHT(uic) && getSize (operandType (IC_RIGHT (uic))) != 2))
     {
       D (D_HLUSE, ("  + Dropping as the result size is not 2\n"));
+      return;
     }
 
   if (IS_Z80)
@@ -2057,6 +2071,8 @@ packRegsForHLUse (iCode * ic)
         goto hluse;
       if (ic->op == ADDRESS_OF && uic->op == IPUSH)
         goto hluse;
+      if (ic->op == ADDRESS_OF && POINTER_GET (uic) && IS_ITEMP( IC_RESULT (uic)))
+        goto hluse;
       if (ic->op == CALL && ic->parmBytes == 0 && (uic->op == '-' || uic->op == '+'))
         goto hluse;
     }
@@ -2223,6 +2239,7 @@ packRegsForAccUse2 (iCode * ic)
        ic->op != '=' &&
        ic->op != EQ_OP &&
        ic->op != CAST &&
+       ic->op != GETHBIT &&
        1)
     {
       D (D_ACCUSE2, ("  + Dropping as not a 'good' source command\n"));
index 542c2db3876899ab23b7ca298b7e37527b1003cb..0a9c4aa660bf15797f1205c3736630bb6e6975c7 100644 (file)
@@ -4,7 +4,7 @@
 #include <testfwk.h>
 
 /* Set to one to show the bug */
-#if 0
+#if 1
 #define NAME(_a)       _a
 #else
 #define NAME(_a)
@@ -38,8 +38,8 @@ static devsw_t _sillyDriver = {
 };
 
 int
-initProxy(void)
+initProxy(devsw_t *pdrv)
 {
-  return (*_sillyDriver.dev_init)(5);
+  return (*pdrv->dev_init)(5);
 }
 
diff --git a/support/regression/tests/float.c b/support/regression/tests/float.c
new file mode 100644 (file)
index 0000000..2a42114
--- /dev/null
@@ -0,0 +1,25 @@
+/* Simple floating pt tests.
+ */
+#include <testfwk.h>
+
+void
+testFloatAdd(void)
+{
+  volatile float result, left, right;
+
+  left = 4;
+  right = 5;
+  ASSERT(left+right == 9);
+
+  left = 7;
+  right = -3;
+  ASSERT(left+right == 4);
+
+  left = -1234;
+  right = 409;
+  ASSERT(left+right == (-1234+409));
+
+  left = -34567;
+  right = -123456;
+  ASSERT(left+right == (-34567-123456));
+}