Improved caching of pointers and division
authorspth <spth@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sat, 4 Apr 2009 17:24:48 +0000 (17:24 +0000)
committerspth <spth@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sat, 4 Apr 2009 17:24:48 +0000 (17:24 +0000)
git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@5427 4a8a32a2-be11-0410-ad9d-d568d2c75423

ChangeLog
device/lib/z80/div.s
src/z80/gen.c
src/z80/peeph-z80.def

index dbbc84a71d9a1f90522ac2a7c25c39f1d420327d..6d36c9e231adbce08577c5dec1421b81198554de 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2009-04-04 Philipp Klaus Krause <pkk AT spth.de>
+
+       * src/z80/gen.c,
+         src/z80/peeph-z80.def:
+         Improved caching of pointers in hl and iy.
+         device/lib/z80/div.s:
+         Applied patch #2727917 from Marco Bodrato.
+
 2009-04-03 Philipp Klaus Krause <pkk AT spth.de>
 
        * src/z80/ralloc.c:
index e64aa07b9fe4e9d70ce36011fe97a184f9a190df..15bcece283d2ad600b8d1955a03553884f042c5e 100644 (file)
@@ -198,63 +198,47 @@ __divu16::
         ld      a,e
         or      d
         jr      NZ,.divide      ; Branch if divisor is non-zero
-        ld      bc,#0x00        ; Divide by zero error
-        ld      d,b
-        ld      e,c
+        ld      b,d             ; Divide by zero error: D=E=0
+        ld      c,e
         scf                     ; Set carry, invalid result
         ret
 .divide:
         ld      hl,#0
-;       ld      l,c             ; L = low byte of dividend/quotient
-;       ld      h,b             ; H = high byte of dividend/quotient
-;       ld      bc,#0x00        ; BC = remainder
-        or      a               ; Clear carry to start
-        ex      af,af'
-        ld      a,#16           ; 16 bits in dividend
+        ld      a,b
+        ld      b,#16           ; 16 bits in dividend
 .dvloop:
+        ;; Cleaned up on April 2009 by Marco Bodrato(http://bodrato.it/ )
         ;; Shift next bit of quotient into bit 0 of dividend
         ;; Shift next MSB of dividend into LSB of remainder
-        ;; BC holds both dividend and quotient. While we shift a bit from
+        ;; AC holds both dividend and quotient. While we shift a bit from
         ;;  MSB of dividend, we shift next bit of quotient in from carry
         ;; HL holds remainder
-        ;; Do a 32-bit left shift, shifting carry to L, L to H,
-        ;;  H to C, C to B
-        ex      af,af'
+        ;; Do a 32-bit left shift, shifting carry to C, C to A,
+        ;;  A to HL
         rl      c               ; Carry (next bit of quotient) to bit 0
-        rl      b               ; Clears carry since BC was 0
-        adc     hl,hl
+        rla
+        adc     hl,hl           ; HL < 32768 before, no carry, ever.
 
         ;; If remainder is >= divisor, next bit of quotient is 1. This
         ;;  bit goes to carry
-        push    hl              ; Save current remainder
         sbc     hl,de
-;       ld      a,c             ; Substract divisor from remainder
-;       sbc     e
-;       ld      c,a
-;       ld      a,b
-;       sbc     d
-;       ld      b,a
+        jr      NC,.nodrop      ; Jump if remainder is >= dividend
+        add     hl,de           ; Otherwise, restore remainder
+       ;; The add above sets the carry, because sbc hl,de did set it.
+.nodrop:
         ccf                     ; Complement borrow so 1 indicates a
                                 ;  successful substraction (this is the
                                 ;  next bit of quotient)
-        jr      C,.drop         ; Jump if remainder is >= dividend
-        pop     hl              ; Otherwise, restore remainder
-        jr      .nodrop
-.drop:
-        inc     sp
-        inc     sp
-.nodrop:
-        ex      af,af'
-        dec     a               ; DEC does not affect carry flag
-        jp      NZ,.dvloop
-        ex      af,af'
+        djnz    .dvloop
         ;; Shift last carry bit into quotient
-        ld      d,h             ; DE = remainder
-        ld      e,l
-        rl      c               ; Carry to L
-;       ld      c,l             ; C = low byte of quotient
-        rl      b
-;       ld      b,h             ; B = high byte of quotient
-        or      a               ; Clear carry, valid result
+        ex      de,hl           ; DE = remainder, HL = divisor...
+        ;; HL does not contain remainder, it contains the divisor!
+        ; ld      d,h             ; DE = remainder
+        ; ld      e,l
+        rl      c               ; Carry to C
+        rla
+        ld      b,a             ; BC = quotient
+        ;; Carry now contains the same value it contained before
+        ;; entering .dvloop[*]: "0" = valid result.
         ret
 
index fc94f60c1e323250f438d5c0165c9f71238e0328..b45d7a8516c2fe621b1cb7e75ce53458700e8f8e 100644 (file)
@@ -1385,7 +1385,8 @@ fetchLitPair (PAIR_ID pairId, asmop * left, int offset)
     {
       if (pairId == PAIR_HL || pairId == PAIR_IY)
         {
-          if (_G.pairs[pairId].last_type == AOP_IMMD && left->type == AOP_IMMD)
+          if ((_G.pairs[pairId].last_type == AOP_IMMD && left->type == AOP_IMMD) ||
+            (_G.pairs[pairId].last_type == AOP_IY && left->type == AOP_IY))
             {
               if (_G.pairs[pairId].base && !strcmp (_G.pairs[pairId].base, base))
                 {
@@ -1682,6 +1683,14 @@ setupPair (PAIR_ID pairId, asmop * aop, int offset)
   _G.pairs[pairId].last_type = aop->type;
 }
 
+/* Can be used for local labels where Code generation takes care of spilling */
+static void
+emitLabelNoSpill (int key)
+{
+  emit2 ("!tlabeldef", key);
+  _G.lines.current->isLabel = 1;
+}
+
 static void
 emitLabel (int key)
 {
@@ -3629,7 +3638,7 @@ genPlusIncr (iCode * ic)
               emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100);
             }
         }
-      emitLabel (tlbl->key + 100);
+      emitLabelNoSpill (tlbl->key + 100);
       return TRUE;
     }
 
@@ -3681,7 +3690,7 @@ outBitAcc (operand * result)
     {
       emit2 ("!shortjp Z,!tlabel", tlbl->key + 100);
       emit2 ("ld a,!one");
-      emitLabel (tlbl->key + 100);
+      emitLabelNoSpill (tlbl->key + 100);
       outAcc (result);
     }
 }
@@ -4287,11 +4296,11 @@ genMultOneChar (iCode * ic)
   emit2 ("ld l,#0x00");
   emit2 ("ld d,l");
   emit2 ("ld b,#0x08");
-  emitLabel (tlbl1->key + 100);
+  emitLabelNoSpill (tlbl1->key + 100);
   emit2 ("add hl,hl");
   emit2 ("jp NC,!tlabel", tlbl2->key + 100);
   emit2 ("add hl,de");
-  emitLabel (tlbl2->key + 100);
+  emitLabelNoSpill (tlbl2->key + 100);
   emit2 ("djnz !tlabel", tlbl1->key + 100);
 
   spillPair(PAIR_HL);
@@ -5064,7 +5073,7 @@ gencjne (operand * left, operand * right, symbol * lbl)
   emit2 ("!shortjp !tlabel", tlbl->key + 100);
   emitLabel (lbl->key + 100);
   emit2 ("xor a,a");
-  emitLabel (tlbl->key + 100);
+  emitLabelNoSpill (tlbl->key + 100);
   _pop (pop);
 }
 
@@ -5110,7 +5119,7 @@ genCmpEq (iCode * ic, iCode * ifx)
             {
               _pop (pop);
               emit2 ("jp !tlabel", IC_TRUE (ifx)->key + 100);
-              emitLabel (tlbl->key + 100);
+              emitLabelNoSpill (tlbl->key + 100);
               _pop (pop);
             }
           else
@@ -5119,10 +5128,10 @@ genCmpEq (iCode * ic, iCode * ifx)
               symbol *lbl = newiTempLabel (NULL);
               _pop (pop);
               emit2 ("!shortjp !tlabel", lbl->key + 100);
-              emitLabel (tlbl->key + 100);
+              emitLabelNoSpill (tlbl->key + 100);
               _pop (pop);
               emit2 ("jp !tlabel", IC_FALSE (ifx)->key + 100);
-              emitLabel (lbl->key + 100);
+              emitLabelNoSpill (lbl->key + 100);
             }
         }
       /* mark the icode as generated */
@@ -5217,7 +5226,7 @@ genAndOp (iCode * ic)
       _toBoolean (left);
       emit2 ("!shortjp Z,!tlabel", tlbl->key + 100);
       _toBoolean (right);
-      emitLabel (tlbl->key + 100);
+      emitLabelNoSpill (tlbl->key + 100);
       outBitAcc (result);
     }
 
@@ -5254,7 +5263,7 @@ genOrOp (iCode * ic)
       _toBoolean (left);
       emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100);
       _toBoolean (right);
-      emitLabel (tlbl->key + 100);
+      emitLabelNoSpill (tlbl->key + 100);
       outBitAcc (result);
     }
 
@@ -5296,14 +5305,14 @@ jmpTrueOrFalse (iCode * ic, symbol * tlbl)
     {
       symbol *nlbl = newiTempLabel (NULL);
       emit2 ("jp !tlabel", nlbl->key + 100);
-      emitLabel (tlbl->key + 100);
+      emitLabelNoSpill (tlbl->key + 100);
       emit2 ("jp !tlabel", IC_TRUE (ic)->key + 100);
-      emitLabel (nlbl->key + 100);
+      emitLabelNoSpill (nlbl->key + 100);
     }
   else
     {
       emit2 ("jp !tlabel", IC_FALSE (ic)->key + 100);
-      emitLabel (tlbl->key + 100);
+      emitLabelNoSpill (tlbl->key + 100);
     }
   ic->generated = 1;
 }
@@ -5987,7 +5996,7 @@ shiftR2Left2Result (operand * left, int offl,
     {
       emit2 ("ld a,!immedbyte", shCount);
 
-      emitLabel (tlbl->key + 100);
+      emitLabelNoSpill (tlbl->key + 100);
 
       emitRsh2 (AOP (result), size, is_signed);
 
@@ -6061,7 +6070,7 @@ shiftL2Left2Result (operand * left, int offl,
           {
             emit2 ("ld a,!immedbyte+1", shCount);
             emit2 ("!shortjp !tlabel", tlbl1->key + 100);
-            emitLabel (tlbl->key + 100);
+            emitLabelNoSpill (tlbl->key + 100);
           }
 
         while (size--)
@@ -6081,7 +6090,7 @@ shiftL2Left2Result (operand * left, int offl,
           }
         if (shCount > 1)
           {
-            emitLabel (tlbl1->key + 100);
+            emitLabelNoSpill (tlbl1->key + 100);
             emit2 ("dec a");
             emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100);
           }
@@ -6400,7 +6409,7 @@ genLeftShift (iCode * ic)
      _pop (PAIR_AF);
 
   emit2 ("!shortjp !tlabel", tlbl1->key + 100);
-  emitLabel (tlbl->key + 100);
+  emitLabelNoSpill (tlbl->key + 100);
   l = aopGet (AOP (result), offset, FALSE);
 
   while (size--)
@@ -6417,7 +6426,7 @@ genLeftShift (iCode * ic)
         }
       offset++;
     }
-  emitLabel (tlbl1->key + 100);
+  emitLabelNoSpill (tlbl1->key + 100);
   emit2 ("dec a");
   emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100);
 
@@ -6675,7 +6684,7 @@ genRightShift (iCode * ic)
      _pop (PAIR_AF);
 
   emit2 ("!shortjp !tlabel", tlbl1->key + 100);
-  emitLabel (tlbl->key + 100);
+  emitLabelNoSpill (tlbl->key + 100);
   while (size--)
     {
       l = aopGet (AOP (result), offset--, FALSE);
@@ -6689,7 +6698,7 @@ genRightShift (iCode * ic)
           emit2 ("rr %s", l);
         }
     }
-  emitLabel (tlbl1->key + 100);
+  emitLabelNoSpill (tlbl1->key + 100);
   emit2 ("dec a");
   emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100);
 
@@ -6732,7 +6741,7 @@ genUnpackBits (operand * result, int pair)
           emit2 ("bit %d,a", blen - 1);
           emit2 ("jp Z,!tlabel", tlbl->key + 100);
           emit2 ("or a,!immedbyte", (unsigned char) (0xff << blen));
-          emitLabel (tlbl->key + 100);
+          emitLabelNoSpill (tlbl->key + 100);
         }
       aopPut (AOP (result), "a", offset++);
       goto finish;
@@ -6755,7 +6764,7 @@ genUnpackBits (operand * result, int pair)
           emit2 ("bit %d,a", blen - 1 - 8);
           emit2 ("jp Z,!tlabel", tlbl->key + 100);
           emit2 ("or a,!immedbyte", (unsigned char) (0xff << (blen - 8)));
-          emitLabel (tlbl->key + 100);
+          emitLabelNoSpill (tlbl->key + 100);
         }
       emit2 ("ld h,a");
       spillPair (PAIR_HL);
@@ -6788,7 +6797,7 @@ genUnpackBits (operand * result, int pair)
           emit2 ("bit %d,a", rlen - 1);
           emit2 ("jp Z,!tlabel", tlbl->key + 100);
           emit2 ("or a,!immedbyte", (unsigned char) (0xff << rlen));
-          emitLabel (tlbl->key + 100);
+          emitLabelNoSpill (tlbl->key + 100);
         }
       aopPut (AOP (result), "a", offset++);
     }
index 6d43c9b2439c503ca1d660a50ee2256ddffc6695..a1299d443ec0fccadfaf17907bf9ed36c4ef360f 100644 (file)
@@ -62,9 +62,17 @@ replace restart {
        ld      a,%3 (%1)
 } by {
        ; peephole 0d loaded %2 into a directly instead of going through %1.
-       ld      a,(#%2+%3)
+       ld      a,(#%2 + %3)
 } if notUsed(%1)
 
+replace restart {
+       ld      hl,#%1 + %2
+       ld      a, (hl)
+} by {
+       ; peephole 0d' loaded %2 into a directly instead of going through %1.
+       ld      a, (#%1 + %2)
+} if notUsed('hl')
+
 replace restart {
        srl     %1
        ld      a,%1
@@ -403,13 +411,24 @@ replace restart {
 
 replace restart {
        ld      iy,#%1
-       ld      %2,%3 (%4)
+       ld      %2,%3 (iy)
 } by {
        ; peephole 0ze used hl instead of iy.
        ld      hl,#%1 + %3
        ld      %2,(hl)
 } if notUsed('iy'), notUsed('hl')
 
+replace restart {
+       ld      iy,#%1
+       ld      %2 (iy),%3
+       ld      l,%2 (iy)
+} by {
+       ; peephole 0ze' used hl instead of iy.
+       ld      hl,#%1 + %2
+       ld      (hl),%3
+       ld      l,(hl)
+} if notUsed('iy'), notUsed('h')
+
 replace restart {
        ld      iy,#%1
        ld      %2 (%3), %4