* src/z80/gen.c (genArrayInit): Made it work for on stack arrays.
authormichaelh <michaelh@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sun, 28 Oct 2001 00:35:47 +0000 (00:35 +0000)
committermichaelh <michaelh@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sun, 28 Oct 2001 00:35:47 +0000 (00:35 +0000)
* src/z80/main.c (gbz80_port =): Added rle support to the gbz80 port.

* src/z80/gen.c (genMinus): Fixed for where the result is one byte.
(movLeft2ResultLong): Created.

* src/z80/ralloc.c (packRegsForHLUse): Added a couple of simple cases for the GB.
(joinPushes): Added.  Joins two char pushes into a word push.

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

12 files changed:
ChangeLog
device/lib/gbz80/Makefile
device/lib/gbz80/crt0_rle.s [new file with mode: 0644]
device/lib/z80/Makefile
device/lib/z80/crt0.s
device/lib/z80/crt0_rle.s [new file with mode: 0644]
src/z80/gen.c
src/z80/gen.h
src/z80/main.c
src/z80/ralloc.c
src/z80/z80.h
support/regression/tests/args.c

index 5d3c148a318466e2dd2502653e25876e940220e4..24dbd279a9639ed81f8c76be2a7aacce8487a288 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2001-10-28  Michael Hope  <michaelh@juju.net.nz>
+
+       * src/z80/gen.c (genArrayInit): Made it work for on stack arrays.
+
+       * src/z80/main.c (gbz80_port =): Added rle support to the gbz80 port.
+
+       * src/z80/gen.c (genMinus): Fixed for where the result is one byte.
+       (movLeft2ResultLong): Created.
+
+       * src/z80/ralloc.c (packRegsForHLUse): Added a couple of simple cases for the GB.
+       (joinPushes): Added.  Joins two char pushes into a word push.
+
 2001-10-27  Michael Hope  <michaelh@juju.net.nz>
 
        * support/cpp2/Makefile.in (install): Added creation of dest dir.
index e0bddf0d4f0045a82de2ac3dcf55dd4ce7db8fa0..91098a1ba7625a9763dfa897ca640f8f0a5b9e0a 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
+OBJ = div.o mul.o putchar.o printf.o shift.o stubs.o crt0_rle.o
 
 LIB = gbz80.lib
 CC = $(SCC)
diff --git a/device/lib/gbz80/crt0_rle.s b/device/lib/gbz80/crt0_rle.s
new file mode 100644 (file)
index 0000000..d577814
--- /dev/null
@@ -0,0 +1,45 @@
+        .area   _CODE
+        
+        ;; Special RLE decoder used for initing global data
+__initrleblock::
+        ;; Pull the destination address out
+        ld      c,l
+        ld      b,h
+        
+        ;; Pop the return address
+        pop     hl
+1$:
+        ;; Fetch the run
+        ld      e,(hl)
+        inc     hl
+        ;; Negative means a run
+        bit     7,e
+        jp      z,2$
+        ;; Code for expanding a run
+        ld      a,(hl)
+        inc     hl
+3$:
+        ld      (bc),a
+        inc     bc
+        inc     e
+        jp      nz,3$
+        jp      1$
+2$:
+        ;; Zero means end of a block
+        xor     a
+        or      e
+        jp      z,4$
+        ;; Code for expanding a block
+5$:     
+        ld      a,(hl)        
+        inc     hl
+        ld      (bc),a
+        inc     bc
+        dec     e
+        jp      nz,5$
+        jp      1$
+4$:     
+        ;; Push the return address back onto the stack
+        push    hl
+        ret
+
index 8d40d8678f4a2ed7040349a5ad056911f88abbe2..fac4986d055ca4ff42bfb169e239005773ac3c5a 100644 (file)
@@ -5,7 +5,7 @@ TOPDIR = ../../..
 SCC = $(TOPDIR)/bin/sdcc -mz80
 SAS = $(TOPDIR)/bin/as-z80
 
-OBJ = div.o mul.o putchar.o printf.o shift.o stubs.o
+OBJ = div.o mul.o putchar.o printf.o shift.o stubs.o crt0_rle.o
 
 LIB = z80.lib
 CC = $(SCC)
index 5aa3991d315bc0b3ec33db66401ad7604a2e1ae0..9f21f26b1d52a31b77264a967e2d9aba07ad13ce 100644 (file)
@@ -54,57 +54,6 @@ _exit::
        halt
        jr      1$
 
-        ;; Special RLE decoder used for initing global data
-__initrleblock::
-        ;; Pop the return address
-        pop     hl
-        ;; Save registers
-        push    bc
-        push    de
-
-        ;; Pull the destination address out
-        ld      c,(hl)
-        inc     hl
-        ld      b,(hl)
-        inc     hl
-1$:
-        ;; Fetch the run
-        ld      e,(hl)
-        inc     hl
-        ;; Negative means a run
-        bit     7,e
-        jp      z,2$
-        ;; Code for expanding a run
-        ld      a,(hl)
-        inc     hl
-3$:
-        ld      (bc),a
-        inc     bc
-        inc     e
-        jp      nz,3$
-        jp      1$
-2$:
-        ;; Zero means end of a block
-        xor     a
-        or      e
-        jp      z,4$
-        ;; Code for expanding a block
-5$:     
-        ld      a,(hl)        
-        inc     hl
-        ld      (bc),a
-        inc     bc
-        dec     e
-        jp      nz,5$
-        jp      1$
-4$:     
-        pop     de
-        pop     bc
-
-        ;; Push the return address back onto the stack
-        push    hl
-        ret
-
         .area   _GSINIT
 gsinit::       
 
diff --git a/device/lib/z80/crt0_rle.s b/device/lib/z80/crt0_rle.s
new file mode 100644 (file)
index 0000000..d577814
--- /dev/null
@@ -0,0 +1,45 @@
+        .area   _CODE
+        
+        ;; Special RLE decoder used for initing global data
+__initrleblock::
+        ;; Pull the destination address out
+        ld      c,l
+        ld      b,h
+        
+        ;; Pop the return address
+        pop     hl
+1$:
+        ;; Fetch the run
+        ld      e,(hl)
+        inc     hl
+        ;; Negative means a run
+        bit     7,e
+        jp      z,2$
+        ;; Code for expanding a run
+        ld      a,(hl)
+        inc     hl
+3$:
+        ld      (bc),a
+        inc     bc
+        inc     e
+        jp      nz,3$
+        jp      1$
+2$:
+        ;; Zero means end of a block
+        xor     a
+        or      e
+        jp      z,4$
+        ;; Code for expanding a block
+5$:     
+        ld      a,(hl)        
+        inc     hl
+        ld      (bc),a
+        inc     bc
+        dec     e
+        jp      nz,5$
+        jp      1$
+4$:     
+        ;; Push the return address back onto the stack
+        push    hl
+        ret
+
index 00b019203012252d89804bba1f7a9735b10099d5..d0c7f3a85d6eb1f03ff9115a396c52a6c586b704 100644 (file)
@@ -406,7 +406,7 @@ getPairName (asmop * aop)
          break;
        }
     }
-  else if (aop->type == AOP_STR)
+  else if (aop->type == AOP_STR || aop->type == AOP_HLREG)
     {
       switch (*aop->aopu.aop_str[0])
        {
@@ -445,7 +445,7 @@ getPairId (asmop * aop)
              return PAIR_HL;
            }
        }
-      if (aop->type == AOP_STR)
+      if (aop->type == AOP_STR || aop->type == AOP_HLREG)
        {
          if (!strcmp (aop->aopu.aop_str[0], "c") && !strcmp (aop->aopu.aop_str[1], "b"))
            {
@@ -840,9 +840,8 @@ aopOp (operand * op, iCode * ic, bool result, bool requires_a)
 
               aop->aopu.aop_str[0] = _pairs[PAIR_AF].h;
            }
-         else if (sym->accuse == ACCUSE_HL)
+         else if (sym->accuse == ACCUSE_SCRATCH)
            {
-             wassert (!IS_GB);
              aop = op->aop = sym->aop = newAsmop (AOP_HLREG);
              aop->size = getSize (sym->type);
               wassertl(aop->size <= 2, "Internal error: Caching in HL, but too big to fit in HL");
@@ -1062,6 +1061,7 @@ requiresHL (asmop * aop)
     case AOP_HL:
     case AOP_STK:
     case AOP_EXSTK:
+    case AOP_HLREG:
       return TRUE;
     default:
       return FALSE;
@@ -1656,6 +1656,7 @@ movLeft2Result (operand * left, int offl,
                operand * result, int offr, int sign)
 {
   const char *l;
+
   if (!sameRegs (AOP (left), AOP (result)) || (offl != offr))
     {
       l = aopGet (AOP (left), offl, FALSE);
@@ -1675,6 +1676,33 @@ movLeft2Result (operand * left, int offl,
     }
 }
 
+static void
+movLeft2ResultLong (operand * left, int offl,
+               operand * result, int offr, int sign,
+                int size)
+{
+  if (size == 1)
+    {
+      movLeft2Result (left, offl, result, offr, sign);
+    }
+  else
+    {
+      wassertl (offl == 0 && offr == 0, "Only implemented for zero offset");
+      wassertl (size == 2, "Only implemented for two bytes or one");
+
+      if ( IS_GB && requiresHL ( AOP (left)) && getPairId ( AOP (result)) == PAIR_HL)
+        {
+          emit2 ("ld a,%s", aopGet (AOP (left), LSB, FALSE));
+          emit2 ("ld h,%s", aopGet (AOP (left), MSB16, FALSE));
+          emit2 ("ld l,a");
+        }
+      else
+        {
+          movLeft2Result (left, offl, result, offr, sign);
+          movLeft2Result (left, offl+1, result, offr+1, sign);
+        }
+    }
+}
 
 /** Put Acc into a register set
  */
@@ -1976,6 +2004,25 @@ assignResultValue (operand * oper)
     }
 }
 
+/** Simple restore that doesn't take into account what is used in the
+    return.
+*/
+static void
+_restoreRegsAfterCall(void)
+{
+  if (_G.stack.pushedDE)
+    {
+      _pop ( PAIR_DE);
+      _G.stack.pushedDE = FALSE;
+    }
+  if (_G.stack.pushedBC)
+    {
+      _pop ( PAIR_BC);
+      _G.stack.pushedBC = FALSE;
+    }
+  _G.saves.saved = FALSE;
+}
+
 static void
 _saveRegsForCall(iCode *ic, int sendSetSize)
 {
@@ -2784,7 +2831,7 @@ genPlusIncr (iCode * ic)
     {
       if (isLitWord (AOP (IC_LEFT (ic))))
        {
-         fetchLitPair (getPairId (AOP (IC_RESULT (ic))), AOP (IC_LEFT (ic)), icount);
+          fetchLitPair (getPairId (AOP (IC_RESULT (ic))), AOP (IC_LEFT (ic)), icount);
          return TRUE;
        }
       if (isPair (AOP (IC_LEFT (ic))) && resultId == PAIR_HL && icount > 2)
@@ -2800,8 +2847,7 @@ genPlusIncr (iCode * ic)
        {
          if (icount > 2)
            return FALSE;
-         movLeft2Result (IC_LEFT (ic), 0, IC_RESULT (ic), 0, 0);
-         movLeft2Result (IC_LEFT (ic), 1, IC_RESULT (ic), 1, 0);
+         movLeft2ResultLong (IC_LEFT (ic), 0, IC_RESULT (ic), 0, 0, 2);
        }
       while (icount--)
        {
@@ -3187,8 +3233,7 @@ genMinusDec (iCode * ic)
   /* If result is a pair */
   if (isPair (AOP (IC_RESULT (ic))))
     {
-      movLeft2Result (IC_LEFT (ic), 0, IC_RESULT (ic), 0, 0);
-      movLeft2Result (IC_LEFT (ic), 1, IC_RESULT (ic), 1, 0);
+      movLeft2ResultLong (IC_LEFT (ic), 0, IC_RESULT (ic), 0, 0, 2);
       while (icount--)
        emit2 ("dec %s", getPairName (AOP (IC_RESULT (ic))));
       return TRUE;
@@ -3300,7 +3345,10 @@ genMinus (iCode * ic)
              emit2 ("ld a,%s", _pairs[left].h);
              emit2 ("sbc a,%s", _pairs[right].h);
 
-             aopPut (AOP (IC_RESULT (ic)), "a", 1);
+              if ( AOP_SIZE (IC_RESULT (ic)) > 1)
+                {
+                  aopPut (AOP (IC_RESULT (ic)), "a", 1);
+                }
              aopPut (AOP (IC_RESULT (ic)), "e", 0);
              goto release;
            }
@@ -6189,16 +6237,10 @@ genArrayInit (iCode * ic)
 
   aopOp (IC_LEFT(ic), ic, FALSE, FALSE);
 
-  if (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD)
-    {
-      /* Emit the support function call and the destination address. */
-      emit2("call __initrleblock");
-      emit2(".dw %s", aopGetWord (AOP(IC_LEFT(ic)), 0));
-    }
-  else
-    {
-      wassertl (0, "Unexpected operand to genArrayInit.\n");
-    }
+  _saveRegsForCall(ic, 0);
+
+  fetchPair (PAIR_HL, AOP (IC_LEFT (ic)));
+  emit2 ("call __initrleblock");
     
   type = operandType(IC_LEFT(ic));
     
@@ -6242,6 +6284,10 @@ genArrayInit (iCode * ic)
   /* Mark the end of the run. */
   emit2(".db 0");
 
+  _restoreRegsAfterCall();
+
+  spillCached ();
+
   freeAsmop (IC_LEFT(ic), NULL, ic);
 }
 
@@ -6517,6 +6563,7 @@ genZ80Code (iCode * lic)
          break;
 
        case ARRAYINIT:
+         emitDebug ("; genArrayInit");
           genArrayInit(ic);
           break;
            
index 20b5787716eaccf371854c5d95ccc74f242e4ed8..becc53adba735c71d4474dbc1703fdaca2f4e166 100644 (file)
@@ -22,8 +22,8 @@
    what you give them.   Help stamp out software-hoarding!  
 -------------------------------------------------------------------------*/
 
-#ifndef SDCCGEN51_H
-#define SDCCGEN51_H
+#ifndef Z80GEN_H
+#define Z80GEN_H
 
 typedef enum
   {
index a3d70ca92469abcc0c5268e59a772da4ed4b3bba..d2b2639c53a0910b98c9d471a7ad4c42a0a00373 100644 (file)
@@ -592,6 +592,6 @@ PORT gbz80_port =
   1,                           /* transform >= to ! < */
   1,                           /* transform != to !(a == b) */
   0,                           /* leave == */
-  FALSE,                        /* No array initializer support. */
+  TRUE,                         /* Array initializer support. */
   PORT_MAGIC
 };
index bc1c337e98af9f7ed13a3c2ab9ab3af07b0b069b..95682c0f9f223efdca7f4c8408511081c5b8bb7d 100644 (file)
@@ -63,7 +63,8 @@ enum
     D_ALLOC = 0,
     D_ALLOC2 = 0,
     D_ACCUSE2 = 0,
-    D_ACCUSE2_VERBOSE = 0
+    D_ACCUSE2_VERBOSE = 0,
+    D_HLUSE = 0
   };
 
 #if 1
@@ -2017,34 +2018,63 @@ packRegsForHLUse (iCode * ic)
 {
   iCode *uic;
 
-  if (IS_GB)
-    return;
-
   /* has only one definition */
   if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
-    return;
+    {
+      D (D_HLUSE, ("  + Dropping as has more than one def\n"));
+      return;
+    }
 
   /* has only one use */
   if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
-    return;
+    {
+      D (D_HLUSE, ("  + Dropping as has more than one use\n"));
+      return;
+    }
 
   /* and the usage immediately follows this iCode */
   if (!(uic = hTabItemWithKey (iCodehTab,
                               bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
-    return;
+    {
+      D (D_HLUSE, ("  + Dropping as usage isn't in this block\n"));
+      return;
+    }
 
   if (ic->next != uic)
-    return;
+    {
+      D (D_HLUSE, ("  + Dropping as usage doesn't follow this\n"));
+      return;
+    }
 
-  if (ic->op == CAST && uic->op == IPUSH)
-    goto hluse;
-  if (ic->op == ADDRESS_OF && uic->op == IPUSH)
-    goto hluse;
-  if (ic->op == CALL && ic->parmBytes == 0 && (uic->op == '-' || uic->op == '+'))
-    goto hluse;
+  if (IS_Z80)
+    {
+      if (ic->op == CAST && uic->op == IPUSH)
+        goto hluse;
+      if (ic->op == ADDRESS_OF && uic->op == IPUSH)
+        goto hluse;
+      if (ic->op == CALL && ic->parmBytes == 0 && (uic->op == '-' || uic->op == '+'))
+        goto hluse;
+    }
+  else if (IS_GB)
+    {
+      /* Case of assign a constant to offset in a static array. */
+      if (ic->op == '+' && IS_VALOP (IC_RIGHT (ic)))
+        {
+          if (uic->op == '=' && POINTER_SET (uic))
+            {
+              goto hluse;
+            }
+          else if (uic->op == IPUSH)
+            {
+              goto hluse;
+            }
+        }
+    }
+
+  D (D_HLUSE, ("  + Dropping as it's a bad op\n"));
   return;
 hluse:
-  OP_SYMBOL (IC_RESULT (ic))->accuse = ACCUSE_HL;
+  OP_SYMBOL (IC_RESULT (ic))->accuse = ACCUSE_SCRATCH;
 }
 
 static bool 
@@ -2533,6 +2563,62 @@ packRegisters (eBBlock * ebp)
     }
 }
 
+/** Joins together two byte constant pushes into one word push.
+ */
+static iCode *
+joinPushes (iCode *lic)
+{
+  iCode *ic, *uic;
+
+  for (ic = lic; ic; ic = ic->next)
+    {
+      int first, second;
+      value *val;
+
+      uic = ic->next;
+
+      /* Anything past this? */
+      if (uic == NULL)
+        {
+          continue;
+        }
+      /* This and the next pushes? */
+      if (ic->op != IPUSH || uic->op != IPUSH)
+        {
+          continue;
+        }
+      /* Both literals? */
+      if ( !IS_OP_LITERAL (IC_LEFT (ic)) || !IS_OP_LITERAL (IC_LEFT (uic)))
+        {
+          continue;
+        }
+      /* Both characters? */
+      if ( getSize (operandType (IC_LEFT (ic))) != 1 || getSize (operandType (IC_LEFT (uic))) != 1)
+        {
+          continue;
+        }
+      /* Pull out the values, make a new type, and create the new iCode for it.
+       */
+      first = (int)operandLitValue ( IC_LEFT (ic));
+      second = (int)operandLitValue ( IC_LEFT (uic));
+
+      sprintf (buffer, "%u", ((first << 8) | (second & 0xFF)) & 0xFFFFU);
+      val = constVal (buffer);
+      SPEC_NOUN (val->type) = V_INT;
+      IC_LEFT (ic)->operand.valOperand = val;
+      
+      /* Now remove the second one from the list. */
+      ic->next = uic->next;
+      if (uic->next)
+        {
+          /* Patch up the reverse link */
+          uic->next->prev = ic;
+        }
+    }
+
+  return lic;
+}
+
 /*-----------------------------------------------------------------*/
 /* assignRegisters - assigns registers to each live range as need  */
 /*-----------------------------------------------------------------*/
@@ -2601,6 +2687,8 @@ z80_assignRegisters (eBBlock ** ebbs, int count)
   /* now get back the chain */
   ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
 
+  ic = joinPushes (ic);
+
   /* redo that offsets for stacked automatic variables */
   redoStackOffsets ();
 
index 9b112ded939e72e933115b140fde47daf5a4c909..66c5567664873e6b792fa8cd3208d94e02ba0e6f 100644 (file)
@@ -26,5 +26,5 @@ extern Z80_OPTS z80_opts;
 enum
   {
     ACCUSE_A = 1,
-    ACCUSE_HL
+    ACCUSE_SCRATCH
   };
index 4c73c619e0faaaf9ed130ac43a7d41038d407d76..9754344ada933d1b37fa41aa940beafdd1ac861e 100644 (file)
@@ -42,4 +42,5 @@ testArgs(void)
 
     ASSERT(returnThirdArg(-33, -34, -35) == -35);
     ASSERT(returnThirdArg(-33, -34, 35) == 35);
+
 }