git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@5429
4a8a32a2-be11-0410-ad9d-
d568d2c75423
+2009-04-09 Philipp Klaus Krause <pkk AT spth.de>
+
+ * 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 <Frieder.Ferlemann AT web.de>
* src/mcs51/peeph.def: disabled rule 270, fixing bug #2736282
2009-04-06 Frieder Ferlemann <Frieder.Ferlemann AT web.de>
* src/mcs51/peeph.def: disabled rule 270, fixing bug #2736282
Z80SOURCES = $(addprefix ../,$(Z80_FLOAT) $(Z80_INT) $(Z80_LONG) $(Z80_SDCC))
Z8OBJECTS = $(patsubst %.c,%.o,$(Z80_FLOAT) $(Z80_INT) $(Z80_LONG) $(Z80_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)
LIB = z80.lib
CC = $(SCC)
- ;; 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
-
- 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
__divsuchar_rrx_s::
ld hl,#2+1
__divsuchar_rrx_s::
ld hl,#2+1
- ld c,(hl)
- ld b, #0
-
- call signexte
-
- ld l,c
- ld h,b
__modsuchar_rrx_s::
ld hl,#2+1
__modsuchar_rrx_s::
ld hl,#2+1
ld e,(hl)
ld d, #0
dec hl
ld e,(hl)
ld d, #0
dec hl
+__divschar_rrx_s::
+ ld hl,#2+1
+ add hl,sp
+ ld e,(hl)
+ dec hl
+ ld l,(hl)
+ ;; Fall through
+__divschar_rrx_hds::
-.mod8::
- ld a,c ; Sign extend
ld a,e ; Sign extend
rlca
sbc a
ld d,a
ld a,e ; Sign extend
rlca
sbc a
ld d,a
; Fall through to __div16
; Fall through to __div16
+ ;; signed 16-bit division
;; DE = divisor
;;
;; Exit conditions
;; DE = divisor
;;
;; Exit conditions
;; 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
;; 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
;; 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
;; 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
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
;; Take absolute value of divisor
- 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
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
;; 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 a ; Substract quotient from 0
sbc a ; Propagate borrow (A=0xFF if borrow)
sbc a ; Propagate borrow (A=0xFF if borrow)
+ sub h
+ ld h,a
+ ld a,b
.dorem:
;; Negate remainder if it is negative
.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
sub a ; Substract remainder from 0
sub e
ld e,a
+
+.dividebyzero:
+ ld h,d ; Divide by zero error: D=E=0
+ ld l,e
+ scf ; Set carry, invalid result
+ ;; Unsigned
+__divuchar_rrx_s::
+ ld hl,#2+1
+ add hl,sp
+
+ ld e,(hl)
+ dec hl
+ ld l,(hl)
+
+ ;; Fall through
+__divuchar_rrx_hds::
-.modu8::
- ld b,#0x00
- ld d,b
+ ;; 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::
;; Check for division by zero
ld a,e
or d
;; 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
+ ;; 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/ )
ld b,#16 ; 16 bits in dividend
.dvloop:
;; Cleaned up on April 2009 by Marco Bodrato(http://bodrato.it/ )
rla
adc hl,hl ; HL < 32768 before, no carry, ever.
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
sbc hl,de
jr NC,.nodrop ; Jump if remainder is >= dividend
add hl,de ; Otherwise, restore remainder
; next bit of quotient)
djnz .dvloop
;; Shift last carry bit into quotient
; 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
;; Carry now contains the same value it contained before
;; entering .dvloop[*]: "0" = valid result.
;; 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
-__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
-
- 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
;; Fall through
__moduchar_rrx_hds::
;; Fall through
__moduchar_rrx_hds::
;; Fall through
__moduint_rrx_hds::
;; Fall through
__moduint_rrx_hds::
ld e,(hl)
ld d, #0
dec hl
ld e,(hl)
ld d, #0
dec hl
--- /dev/null
+ .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
+