From d55072f68fcf3718b20b1a2c86058b01157bd189 Mon Sep 17 00:00:00 2001 From: spth Date: Thu, 9 Apr 2009 13:07:11 +0000 Subject: [PATCH] Applied patch #2741451 and reorganized mod functions git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@5429 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- ChangeLog | 11 ++ device/lib/z80/Makefile.in | 2 +- device/lib/z80/div.s | 207 +++++++++++++++++-------------------- device/lib/z80/divsigned.s | 94 ++--------------- device/lib/z80/mod.s | 19 ++-- device/lib/z80/modsigned.s | 33 ++++++ 6 files changed, 156 insertions(+), 210 deletions(-) create mode 100644 device/lib/z80/modsigned.s diff --git a/ChangeLog b/ChangeLog index 28f0c768..d35835c6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2009-04-09 Philipp Klaus Krause + + * device/lib/z80/mod.s, + device/lib/z80/Makefile.in, + device/lib/z80/div.s, + device/lib/z80/modsigned.s, + device/lib/z80/divsigned.s: + Applied patch #2741451 from Marco Bodrato + and moved functions for signed modulo into + separate file. + 2009-04-06 Frieder Ferlemann * src/mcs51/peeph.def: disabled rule 270, fixing bug #2736282 diff --git a/device/lib/z80/Makefile.in b/device/lib/z80/Makefile.in index 9a8345b3..8f25860c 100644 --- a/device/lib/z80/Makefile.in +++ b/device/lib/z80/Makefile.in @@ -33,7 +33,7 @@ Z80_SDCC = $(COMMON_SDCC) \ Z80SOURCES = $(addprefix ../,$(Z80_FLOAT) $(Z80_INT) $(Z80_LONG) $(Z80_SDCC)) Z8OBJECTS = $(patsubst %.c,%.o,$(Z80_FLOAT) $(Z80_INT) $(Z80_LONG) $(Z80_SDCC)) -OBJ = div.o divsigned.o mod.o mul.o mulchar.o putchar.o shift.o stubs.o crt0_rle.o heap.o fstubs.o memmove.o strlen.o +OBJ = div.o divsigned.o mod.o modsigned.o mul.o mulchar.o putchar.o shift.o stubs.o crt0_rle.o heap.o fstubs.o memmove.o strlen.o LIB = z80.lib CC = $(SCC) diff --git a/device/lib/z80/div.s b/device/lib/z80/div.s index 15bcece2..f0574eb5 100644 --- a/device/lib/z80/div.s +++ b/device/lib/z80/div.s @@ -2,48 +2,15 @@ .area _CODE - ;; Unsigned -__divuchar_rrx_s:: - ld hl,#2+1 - add hl,sp - - ld e,(hl) - dec hl - ld l,(hl) - - ;; Fall through -__divuchar_rrx_hds:: - ld c,l - call __divu8 - - ld l,c - ld h,b - - ret - __divuint_rrx_s:: - ld hl,#2+3 - add hl,sp - - ld d,(hl) - dec hl - ld e,(hl) - dec hl - ld a,(hl) - dec hl - ld l,(hl) - ld h,a - - ;; Fall through -__divuint_rrx_hds:: - ld b,h - ld c,l - call __divu16 - - ld l,c - ld h,b + pop af + pop hl + pop de + push de + push hl + push af - ret + jr __divu16 __divsuchar_rrx_s:: ld hl,#2+1 @@ -51,15 +18,10 @@ __divsuchar_rrx_s:: ld e,(hl) dec hl - ld c,(hl) - ld b, #0 - - call signexte - - ld l,c - ld h,b + ld l,(hl) + xor a - ret + jr signexte __modsuchar_rrx_s:: ld hl,#2+1 @@ -67,14 +29,12 @@ __modsuchar_rrx_s:: ld e,(hl) dec hl - ld c,(hl) - ld b, #0 + ld l,(hl) + xor a call signexte - ld l,e - ld h,d - + ex de,hl ret __divuschar_rrx_s:: @@ -84,96 +44,100 @@ __divuschar_rrx_s:: ld e,(hl) ld d, #0 dec hl - ld c,(hl) + ld l,(hl) - ld a,c ; Sign extend + ld a,l ; Sign extend rlca sbc a - ld b,a + ld h,a - call __div16 + jr __div16 - ld l,c - ld h,b +__divschar_rrx_s:: + ld hl,#2+1 + add hl,sp - ret + ld e,(hl) + dec hl + ld l,(hl) + ;; Fall through +__divschar_rrx_hds:: __div8:: -.mod8:: - ld a,c ; Sign extend + ld a,l ; Sign extend rlca sbc a - ld b,a signexte: + ld h,a ld a,e ; Sign extend rlca sbc a ld d,a - ; Fall through to __div16 - ;; 16-bit division + ;; signed 16-bit division ;; ;; Entry conditions - ;; BC = dividend + ;; HL = dividend ;; DE = divisor ;; ;; Exit conditions - ;; BC = quotient + ;; HL = quotient ;; DE = remainder ;; If divisor is non-zero, carry=0 ;; If divisor is 0, carry=1 and both quotient and remainder are 0 ;; ;; Register used: AF,BC,DE,HL +__divsint_rrx_hds:: __div16:: -.mod16:: ;; Determine sign of quotient by xor-ing high bytes of dividend ;; and divisor. Quotient is positive if signs are the same, negative ;; if signs are different ;; Remainder has same sign as dividend - ld a,b ; Get high byte of dividend - push af ; Save as sign of remainder + ld a,h ; Get high byte of dividend xor d ; Xor with high byte of divisor - push af ; Save sign of quotient + rla ; Sign of quotient goes into the carry + ld a,h ; Get high byte of dividend + push af ; Save sign of both quotient and reminder + ;; Take absolute value of dividend + rla + jr NC,.chkde ; Jump if dividend is positive + sub a ; Substract dividend from 0 + sub l + ld l,a + sbc a ; Propagate borrow (A=0xFF if borrow) + sub h + ld h,a ;; Take absolute value of divisor +.chkde: bit 7,d - jr Z,.chkde ; Jump if divisor is positive + jr Z,.dodiv ; Jump if divisor is positive sub a ; Substract divisor from 0 sub e ld e,a sbc a ; Propagate borrow (A=0xFF if borrow) sub d ld d,a - ;; Take absolute value of dividend -.chkde: - bit 7,b - jr Z,.dodiv ; Jump if dividend is positive - sub a ; Substract dividend from 0 - sub c - ld c,a - sbc a ; Propagate borrow (A=0xFF if borrow) - sub b - ld b,a ;; Divide absolute values .dodiv: call __divu16 jr C,.exit ; Exit if divide by zero ;; Negate quotient if it is negative pop af ; recover sign of quotient - and #0x80 - jr Z,.dorem ; Jump if quotient is positive + jr NC,.dorem ; Jump if quotient is positive + ld b,a sub a ; Substract quotient from 0 - sub c - ld c,a + sub l + ld l,a sbc a ; Propagate borrow (A=0xFF if borrow) - sub b - ld b,a + sub h + ld h,a + ld a,b .dorem: ;; Negate remainder if it is negative - pop af ; recover sign of remainder - and #0x80 - ret Z ; Return if remainder is positive + rla + ret NC ; Return if remainder is positive sub a ; Substract remainder from 0 sub e ld e,a @@ -183,28 +147,53 @@ __div16:: ret .exit: pop af - pop af + +.dividebyzero: + ld h,d ; Divide by zero error: D=E=0 + ld l,e + scf ; Set carry, invalid result ret + ;; Unsigned +__divuchar_rrx_s:: + ld hl,#2+1 + add hl,sp + + ld e,(hl) + dec hl + ld l,(hl) + + ;; Fall through +__divuchar_rrx_hds:: __divu8:: -.modu8:: - ld b,#0x00 - ld d,b + ld h,#0x00 + ld d,h ; Fall through to divu16 + ;; unsigned 16-bit division + ;; Restructured on April 2009 by Marco Bodrato(http://bodrato.it/ ) + ;; + ;; Entry conditions + ;; HL = dividend + ;; DE = divisor + ;; + ;; Exit conditions + ;; HL = quotient + ;; DE = remainder + ;; If divisor is non-zero, carry=0 + ;; If divisor is 0, carry=1 and both quotient and remainder are 0 + ;; + ;; Register used: AF,B,DE,HL +__divuint_rrx_hds:: __divu16:: -.modu16:: ;; Check for division by zero ld a,e or d - jr NZ,.divide ; Branch if divisor is non-zero - ld b,d ; Divide by zero error: D=E=0 - ld c,e - scf ; Set carry, invalid result - ret -.divide: + jr Z,.dividebyzero ; Branch if divisor is non-zero + ld a,h + ld c,l ld hl,#0 - ld a,b + ;; Carry was cleared by OR, this "0" bit will pass trough AC.[*] ld b,#16 ; 16 bits in dividend .dvloop: ;; Cleaned up on April 2009 by Marco Bodrato(http://bodrato.it/ ) @@ -219,8 +208,8 @@ __divu16:: 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 + ;; If remainder is >= divisor, next bit of quotient is 1. We try + ;; to compute the difference. sbc hl,de jr NC,.nodrop ; Jump if remainder is >= dividend add hl,de ; Otherwise, restore remainder @@ -231,14 +220,12 @@ __divu16:: ; next bit of quotient) djnz .dvloop ;; Shift last carry bit into quotient - 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. + ld d,a + ld e,c ; DE = quotient, HL = remainder + ex de,hl ; HL = quotient, DE = remainder ret diff --git a/device/lib/z80/divsigned.s b/device/lib/z80/divsigned.s index 3614047f..686e2f7d 100644 --- a/device/lib/z80/divsigned.s +++ b/device/lib/z80/divsigned.s @@ -1,90 +1,12 @@ .area _CODE -__divschar_rrx_s:: - ld hl,#2+1 - add hl,sp - - ld e,(hl) - dec hl - ld l,(hl) - - ;; Fall through -__divschar_rrx_hds:: - ld c,l - - call __div8 - - ld l,c - ld h,b - - ret - -__modschar_rrx_s:: - ld hl,#2+1 - add hl,sp - - ld e,(hl) - dec hl - ld l,(hl) - - ;; Fall through -__modschar_rrx_hds:: - ld c,l - - call __div8 - - ld l,e - ld h,d - - ret - __divsint_rrx_s:: - ld hl,#2+3 - add hl,sp - - ld d,(hl) - dec hl - ld e,(hl) - dec hl - ld a,(hl) - dec hl - ld l,(hl) - ld h,a - - ;; Fall through -__divsint_rrx_hds:: - ld b,h - ld c,l - - call __div16 - - ld l,c - ld h,b - - ret - -__modsint_rrx_s:: - ld hl,#2+3 - add hl,sp - - ld d,(hl) - dec hl - ld e,(hl) - dec hl - ld a,(hl) - dec hl - ld l,(hl) - ld h,a - - ;; Fall through -__modsint_rrx_hds:: - ld b,h - ld c,l - - call __div16 - - ld l,e - ld h,d - - ret + pop af + pop hl + pop de + push de + push hl + push af + + jp __div16 diff --git a/device/lib/z80/mod.s b/device/lib/z80/mod.s index 763cf6ce..9d3b0480 100644 --- a/device/lib/z80/mod.s +++ b/device/lib/z80/mod.s @@ -10,11 +10,9 @@ __moduchar_rrx_s:: ;; Fall through __moduchar_rrx_hds:: - ld c,l call __divu8 - ld l,e - ld h,d + ex de,hl ret @@ -33,13 +31,9 @@ __moduint_rrx_s:: ;; Fall through __moduint_rrx_hds:: - ld b,h - ld c,l - call __divu16 - ld l,e - ld h,d + ex de,hl ret @@ -50,17 +44,16 @@ __moduschar_rrx_s:: ld e,(hl) ld d, #0 dec hl - ld c,(hl) + ld l,(hl) - ld a,c ; Sign extend + ld a,l ; Sign extend rlca sbc a - ld b,a + ld h,a call __div16 - ld l,e - ld h,d + ex de,hl ret diff --git a/device/lib/z80/modsigned.s b/device/lib/z80/modsigned.s new file mode 100644 index 00000000..e8520592 --- /dev/null +++ b/device/lib/z80/modsigned.s @@ -0,0 +1,33 @@ + .area _CODE + +__modschar_rrx_s:: + ld hl,#2+1 + add hl,sp + + ld e,(hl) + dec hl + ld l,(hl) + + ;; Fall through +__modschar_rrx_hds:: + call __div8 + + ex de,hl + ret + +__modsint_rrx_s:: + pop af + pop hl + pop de + push de + push hl + push af + + ;; Fall through +__modsint_rrx_hds:: + call __div16 + + ex de,hl + + ret + -- 2.30.2