Applied patch #2741451 and reorganized mod functions
authorspth <spth@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Thu, 9 Apr 2009 13:07:11 +0000 (13:07 +0000)
committerspth <spth@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Thu, 9 Apr 2009 13:07:11 +0000 (13:07 +0000)
git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@5429 4a8a32a2-be11-0410-ad9d-d568d2c75423

ChangeLog
device/lib/z80/Makefile.in
device/lib/z80/div.s
device/lib/z80/divsigned.s
device/lib/z80/mod.s
device/lib/z80/modsigned.s [new file with mode: 0644]

index 28f0c76808c17b59dd7f6f1dafda894da5d33061..d35835c6adab2decf219b2d6f3ab16a1793c8956 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+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
index 9a8345b32645abb5cc6a746eba56a5cf698f7032..8f25860c4338ab7ab90237e183efbdcf0ee07799 100644 (file)
@@ -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)
index 15bcece283d2ad600b8d1955a03553884f042c5e..f0574eb506e80cd759fce009c8d1bea0ca130ce5 100644 (file)
@@ -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
 
index 3614047f2b92c73271bb6c4cb71eccccf4a27088..686e2f7de82b471a457eb26d67fb3da24b6e105b 100644 (file)
@@ -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
 
index 763cf6ce6067e532923c85805e2dac76e56fe2e0..9d3b04808899b6171d7aa898da7d7b99ef654a43 100644 (file)
@@ -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 (file)
index 0000000..e852059
--- /dev/null
@@ -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
+