From 7b43aada0d2aa8d2f4a6a4be856e57b3fd8e32f6 Mon Sep 17 00:00:00 2001 From: spth Date: Sat, 4 Apr 2009 17:24:48 +0000 Subject: [PATCH] Improved caching of pointers and division git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@5427 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- ChangeLog | 8 ++++++ device/lib/z80/div.s | 64 ++++++++++++++++--------------------------- src/z80/gen.c | 57 ++++++++++++++++++++++---------------- src/z80/peeph-z80.def | 23 ++++++++++++++-- 4 files changed, 86 insertions(+), 66 deletions(-) diff --git a/ChangeLog b/ChangeLog index dbbc84a7..6d36c9e2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2009-04-04 Philipp Klaus Krause + + * 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 * src/z80/ralloc.c: diff --git a/device/lib/z80/div.s b/device/lib/z80/div.s index e64aa07b..15bcece2 100644 --- a/device/lib/z80/div.s +++ b/device/lib/z80/div.s @@ -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 diff --git a/src/z80/gen.c b/src/z80/gen.c index fc94f60c..b45d7a85 100644 --- a/src/z80/gen.c +++ b/src/z80/gen.c @@ -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++); } diff --git a/src/z80/peeph-z80.def b/src/z80/peeph-z80.def index 6d43c9b2..a1299d44 100644 --- a/src/z80/peeph-z80.def +++ b/src/z80/peeph-z80.def @@ -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 -- 2.30.2