]> git.gag.com Git - fw/sdcc/blobdiff - src/z80/gen.c
Stopped a couple of warnings.
[fw/sdcc] / src / z80 / gen.c
index 0482186cb9c36f3596c5acae63522b2ff97086d6..f065a37e76e2f74d4267f0b05ab92da52f16aa6c 100644 (file)
@@ -1,6 +1,33 @@
 /*-------------------------------------------------------------------------
   gen.c - Z80 specific code generator.
+     
+  Michael Hope <michaelh@juju.net.nz> 2000
+  Based on the mcs51 generator -
+      Sandeep Dutta . sandeep.dutta@usa.net (1998)
+   and -  Jean-Louis VERN.jlvern@writeme.com (1999)
+
+  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, 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+  In other words, you are welcome to use, share and improve this program.
+  You are forbidden to forbid anyone else to use, share and improve
+  what you give them.   Help stamp out software-hoarding!
+
+-------------------------------------------------------------------------*/
+
+/*
   Benchmarks on dhry.c 2.1 with 32766 loops and a 10ms clock:
                                        ticks dhry  size
   Base with asm strcpy / strcmp / memcpy: 23198 141 1A14
   5. Optimised strcmp further          21660 151 228C
   6. Optimised memcpy by unroling      20885 157 2201
   7. After turning loop induction on   19862 165 236D
+  8. Same as 7 but with more info      
+  9. With asm optimised strings                17030 192 2223
 
-  Michael Hope <michaelh@juju.net.nz> 2000
-  Based on the mcs51 generator -
-      Sandeep Dutta . sandeep.dutta@usa.net (1998)
-   and -  Jean-Louis VERN.jlvern@writeme.com (1999)
-
-  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, 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-  In other words, you are welcome to use, share and improve this program.
-  You are forbidden to forbid anyone else to use, share and improve
-  what you give them.   Help stamp out software-hoarding!
-
--------------------------------------------------------------------------*/
+  10 and below are with asm strings off.
+  
+  Apparent advantage of turning on regparams:
+  1.  Cost of push
+        Decent case is push of a constant 
+          - ld hl,#n; push hl: (10+11)*nargs
+  2.  Cost of pull from stack
+        Using asm with ld hl, etc
+          - ld hl,#2; add hl,sp; (ld bc,(hl); hl+=2)*nargs
+            10+11+(7+6+7+6)*nargs
+  3.  Cost of fixing stack
+          - pop hl*nargs
+            10*nargs
+  
+  So cost is (10+11+7+6+7+10)*nargs+10+11 
+      = 51*nargs+21
+      = 123 for mul, div, strcmp, strcpy
+  Saving of (98298+32766+32766+32766)*123 = 24181308
+  At 192 d/s for 682411768t, speed up to 199.  Hmm.
+*/
 
 #include <stdio.h>
 #include <stdlib.h>
 */
 
 enum {
-  DISABLE_DEBUG = 1
+  DISABLE_DEBUG = 0
 };
 
 static char *_z80_return[] =
@@ -193,6 +217,42 @@ static struct
 
 static const char *aopGet (asmop * aop, int offset, bool bit16);
 
+static PAIR_ID
+_getTempPairId(void)
+{
+  if (IS_GB)
+    {
+      return PAIR_DE;
+    }
+  else
+    {
+      return PAIR_HL;
+    }
+}
+
+static const char *
+_getTempPairName(void)
+{
+  return _pairs[_getTempPairId()].name;
+}
+
+#if 0
+static const char *
+_getTempPairPart(int idx)
+{
+  wassertl (idx == LSB || idx == MSB16, "Invalid pair offset");
+  
+  if (idx == LSB)
+    {
+      return _pairs[_getTempPairId()].l;
+    }
+  else
+    {
+      return _pairs[_getTempPairId()].h;
+    }
+}
+#endif
+
 static void
 _tidyUp (char *buf)
 {
@@ -958,27 +1018,6 @@ requiresHL (asmop * aop)
     }
 }
 
-static char *
-fetchLitSpecial (asmop * aop, bool negate, bool xor)
-{
-  unsigned long v;
-  value *val = aop->aopu.aop_lit;
-
-  wassert (aop->type == AOP_LIT);
-  wassert (!IS_FLOAT (val->type));
-
-  v = (unsigned long) floatFromVal (val);
-
-  if (xor)
-    v ^= 0x8000;
-  if (negate)
-    v = 0-v;
-  v &= 0xFFFF;
-
-  tsprintf (buffer, "!immedword", v);
-  return gc_strdup (buffer);
-}
-
 static void
 fetchLitPair (PAIR_ID pairId, asmop * left, int offset)
 {
@@ -1040,18 +1079,21 @@ fetchPairLong (PAIR_ID pairId, asmop * aop, int offset)
         /* we need to get it byte by byte */
         if (pairId == PAIR_HL && IS_GB && requiresHL (aop)) {
             aopGet (aop, offset, FALSE);
-            switch (aop->size) {
+            switch (aop->size - offset) {
             case 1:
                 emit2 ("ld l,!*hl");
                 emit2 ("ld h,!immedbyte", 0);
                             break;
             case 2:
+              // PENDING: Requires that you are only fetching two bytes.
+            case 4:
                 emit2 ("!ldahli");
                 emit2 ("ld h,!*hl");
                 emit2 ("ld l,a");
                 break;
             default:
-                emitDebug ("; WARNING: mlh woosed out.  This code is invalid.");
+              wassertl (0, "Attempted to fetch too much data into HL");
+              break;
             }
         }
         else if (IS_Z80 && aop->type == AOP_IY) {
@@ -1744,8 +1786,7 @@ assignResultValue (operand * oper)
       _push (PAIR_HL);
       aopPut (AOP (oper), _fReturn[0], 0);
       aopPut (AOP (oper), _fReturn[1], 1);
-      emit2 ("pop de");
-      _G.stack.pushed -= 2;
+      _pop (PAIR_DE);
       aopPut (AOP (oper), _fReturn[0], 2);
       aopPut (AOP (oper), _fReturn[1], 3);
     }
@@ -2724,7 +2765,7 @@ genPlus (iCode * ic)
   if (genPlusIncr (ic) == TRUE)
     goto release;
 
-  emitDebug ("; genPlusIncr failed");
+  emitDebug ("; Can't optimise plus by inc, falling back to the normal way");
 
   size = getDataSize (IC_RESULT (ic));
 
@@ -2732,10 +2773,11 @@ genPlus (iCode * ic)
   if (isPair (AOP (IC_RESULT (ic))))
     {
       char *left, *right;
-
       left = aopGetLitWordLong (AOP (IC_LEFT (ic)), 0, FALSE);
       right = aopGetLitWordLong (AOP (IC_RIGHT (ic)), 0, FALSE);
-      if (left && right)
+
+      if (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT && AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT &&
+          left && right)
        {
          /* It's a pair */
          /* PENDING: fix */
@@ -2817,7 +2859,7 @@ genPlus (iCode * ic)
            }
          else if (size == 4)
            {
-             emitDebug ("; WARNING: This add is probably broken.\n");
+              // Fall through
            }
        }
     }
@@ -2896,15 +2938,16 @@ genMinusDec (iCode * ic)
 
   /* if increment 16 bits in register */
   if (sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))) &&
-      (size == 2))
+      (size == 2)
+      )
     {
-      fetchPair (PAIR_HL, AOP (IC_RESULT (ic)));
+      fetchPair (_getTempPairId(), AOP (IC_RESULT (ic)));
 
       while (icount--) {
-        emit2 ("dec hl");
+        emit2 ("dec %s", _getTempPairName());
       }
-      aopPut (AOP (IC_RESULT (ic)), "l", LSB);
-      aopPut (AOP (IC_RESULT (ic)), "h", MSB16);
+
+      commitPair (AOP (IC_RESULT (ic)), _getTempPairId());
 
       return TRUE;
     }
@@ -3005,6 +3048,9 @@ genMinus (iCode * ic)
            }
          else if (size == 4)
            {
+              /* Anything could be on the stack, and we can't afford
+                 to setup the base pointer as that may nuke the carry.
+              */
              emitDebug ("; WARNING: This sub is probably broken.\n");
            }
        }
@@ -3150,11 +3196,13 @@ genIfxJump (iCode * ic, char *jval)
   ic->generated = 1;
 }
 
+#if DISABLED
 static const char *
 _getPairIdName (PAIR_ID id)
 {
   return _pairs[id].name;
 }
+#endif
 
 /** Generic compare for > or <
  */
@@ -3195,6 +3243,9 @@ genCmp (operand * left, operand * right,
        }
       else
        {
+#if 0
+          // PENDING: Doesn't work around zero
+
          /* Special cases:
             On the GB:
             If the left or the right is a lit:
@@ -3234,6 +3285,7 @@ genCmp (operand * left, operand * right,
              emit2 ("add hl,%s", _getPairIdName (id));
              goto release;
            }
+#endif
          if (AOP_TYPE (right) == AOP_LIT)
            {
              lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
@@ -6131,4 +6183,26 @@ _isPairUsed (iCode * ic, PAIR_ID pairId)
   return ret;
 }
 
+static char *
+fetchLitSpecial (asmop * aop, bool negate, bool xor)
+{
+  unsigned long v;
+  value *val = aop->aopu.aop_lit;
+
+  wassert (aop->type == AOP_LIT);
+  wassert (!IS_FLOAT (val->type));
+
+  v = (unsigned long) floatFromVal (val);
+
+  if (xor)
+    v ^= 0x8000;
+  if (negate)
+    v = 0-v;
+  v &= 0xFFFF;
+
+  tsprintf (buffer, "!immedword", v);
+  return gc_strdup (buffer);
+}
+
+
 */