* src/device/lib/_mulint.c : new, with assember functions
authorbernhardheld <bernhardheld@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Wed, 3 Oct 2001 16:24:51 +0000 (16:24 +0000)
committerbernhardheld <bernhardheld@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Wed, 3 Oct 2001 16:24:51 +0000 (16:24 +0000)
* src/device/lib/_mullong.c : new, with assember functions

* src/device/lib/_divuint.c : with assember functions

* src/device/lib/_divsint.c : with assember functions

* src/device/lib/_divulong.c: with assember functions

* src/device/lib/_divslong.c: with assember functions

* src/device/lib/_moduint.c : with assember functions

* src/device/lib/_modsint.c : with assember functions

* src/device/lib/_modulong.c: with assember functions

* src/device/lib/_modslong.c: with assember functions

* src/device/lib/libint.lib:  replaced _muluint.c  and _mulsint.c  by _mulint.c

* src/device/lib/liblong.lib: replaced _mululong.c and _mulslong.c by _mullong.c

* src/device/lib/Makefile.in: replaced _muluint.c  and _mulsint.c  by _mulint.c
                              replaced _mululong.c and _mulslong.c by _mullong.c

git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@1349 4a8a32a2-be11-0410-ad9d-d568d2c75423

14 files changed:
ChangeLog
device/lib/Makefile.in
device/lib/_divsint.c
device/lib/_divslong.c
device/lib/_divuint.c
device/lib/_divulong.c
device/lib/_modsint.c
device/lib/_modslong.c
device/lib/_moduint.c
device/lib/_modulong.c
device/lib/_mulint.c
device/lib/_mullong.c
device/lib/libint.lib
device/lib/liblong.lib

index 0bf0f15559b650a7c3c4150d64dac3950812b94a..e8b11012cf0660073d4ded7d4f338193d9dcf1de 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,32 @@
+2001-10-03 Bernhard Held <bernhard@bernhardheld.de>
+
+       * src/device/lib/_mulint.c  : new, with assember functions
+
+       * src/device/lib/_mullong.c : new, with assember functions
+
+       * src/device/lib/_divuint.c : with assember functions
+
+       * src/device/lib/_divsint.c : with assember functions
+
+       * src/device/lib/_divulong.c: with assember functions
+
+       * src/device/lib/_divslong.c: with assember functions
+
+       * src/device/lib/_moduint.c : with assember functions
+
+       * src/device/lib/_modsint.c : with assember functions
+
+       * src/device/lib/_modulong.c: with assember functions
+
+       * src/device/lib/_modslong.c: with assember functions
+
+       * src/device/lib/libint.lib:  replaced _muluint.c  and _mulsint.c  by _mulint.c
+
+       * src/device/lib/liblong.lib: replaced _mululong.c and _mulslong.c by _mullong.c
+
+       * src/device/lib/Makefile.in: replaced _muluint.c  and _mulsint.c  by _mulint.c
+                                     replaced _mululong.c and _mulslong.c by _mullong.c
+
 2001-10-03 Bernhard Held <bernhard@bernhardheld.de>
 
        * src/SDCCsymt.c: sequence of specifiers in pintTypeChain() corrected
index 7b7437591e5f7523d2283c98a7d0d78c123b93be..54cff88f2b471043d482503254cf0fbea6df424f 100644 (file)
@@ -49,16 +49,15 @@ SOURCES             = _atoi.c _atol.c _autobaud.c _bp.c _schar2fs.c \
                  _islower.c _isprint.c _ispunct.c _isspace.c \
                  _isupper.c _isxdigit.c _slong2fs.c _memcmp.c \
                  _memcpy.c _memset.c _modsint.c _modslong.c \
-                 _moduint.c _modulong.c _mulsint.c _muluint.c \
-                 _mululong.c _mulslong.c _ser.c _setjmp.c \
+                 _moduint.c _modulong.c _mulint.c _mullong.c \
+                 _ser.c _setjmp.c \
                  _spx.c _startup.c _strchr.c _strcmp.c _strcpy.c \
                  _strcspn.c _strlen.c _strncat.c _strncmp.c \
                  _strncpy.c _strpbrk.c _strrchr.c _strspn.c \
                  _strstr.c _strtok.c _uchar2fs.c _uint2fs.c \
                  _ulong2fs.c malloc.c serial.c ser_ir.c printfl.c \
                  printf_large.c vprintf.c puts.c gets.c \
-                 assert.c _strcat.c time.c printf_fast.c \
-                 _mulint.c _mullong.c
+                 assert.c _strcat.c time.c printf_fast.c
 
 OBJECTS                = $(patsubst %.c,$(PORTDIR)/%.rel,$(SOURCES))
 
index 2aa21999960ab5170c62e77600d5d35bd6b0aa06..38745fb0e2edfcafc6ae2ebe5d7601d4860a493e 100644 (file)
@@ -1,5 +1,4 @@
 /*-------------------------------------------------------------------------
-
   _divsint.c :- routine for signed int (16 bit) division. just calls
                 routine for unsigned division after sign adjustment
 
    under the terms of the GNU Library General Public License as published by the
    Free Software Foundation; either version 2, or (at your option) any
    later version.
-   
+
    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Library General Public License for more details.
-   
+
    You should have received a copy of the GNU Library General Public License
    along with this program; if not, write to the Free Software
    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-   
+
    In other words, you are welcome to use, share and improve this program.
    You are forbidden to forbid anyone else to use, share and improve
-   what you give them.   Help stamp out software-hoarding!  
+   what you give them.   Help stamp out software-hoarding!
 -------------------------------------------------------------------------*/
-int _divsint (int a, int b)
-#ifndef SDCC_STACK_AUTO
-       critical
+
+
+#include <sdcc-lib.h>
+
+#if _SDCC_MANGLES_SUPPORT_FUNS
+unsigned unsigned _divuint (unsigned a, unsigned b);
 #endif
+
+/*   Assembler-functions are provided for:
+     mcs51 small
+     mcs51 small stack-auto
+*/
+
+#if !defined(SDCC_USE_XSTACK) && !defined(_SDCC_NO_ASM_LIB_FUNCS)
+#  if defined(SDCC_mcs51)
+#    if defined(SDCC_MODEL_SMALL)
+#      if defined(SDCC_STACK_AUTO)
+#        define _DIVSINT_ASM_SMALL_AUTO
+#      else
+#        define _DIVSINT_ASM_SMALL
+#      endif
+#    endif
+#  endif
+#endif
+
+#if defined _DIVSINT_ASM_SMALL
+
+static void
+_divsint_dummy (void) _naked
 {
-       register int r;
-      
-       r = _divuint((a < 0 ? -a : a),
-                   (b < 0 ? -b : b));
-       if ( (a < 0) ^ (b < 0)) {
-       
-           return -r;
-        }
-       else {
-
-           return r;
-        }
+       _asm
+
+               #define a0      dpl
+               #define a1      dph
+
+               .globl __divsint
+
+               // _divsint_PARM_2 shares the same memory with _divuint_PARM_2
+               // and is defined in _divuint.c
+               #define b0      (__divsint_PARM_2)
+               #define b1      (__divsint_PARM_2 + 1)
+
+       __divsint:
+                                       ; a1 in dph
+                                       ; b1 in (__divsint_PARM_2 + 1)
+
+               clr     F0              ; Flag 0 in PSW
+                                       ; available to user for general purpose
+               mov     a,a1
+               jnb     acc.7,a_not_negative
+
+               setb    F0
+
+               clr     a
+               clr     c
+               subb    a,a0
+               mov     a0,a
+               clr     a
+               subb    a,a1
+               mov     a1,a
+
+       a_not_negative:
+
+               mov     a,b1
+               jnb     acc.7,b_not_negative
+
+               cpl     F0
+
+               clr     a
+               clr     c
+               subb    a,b0
+               mov     b0,a
+               clr     a
+               subb    a,b1
+               mov     b1,a
+
+       b_not_negative:
+
+               lcall   __divuint
+
+               jnb     F0,not_negative
+
+               clr     a
+               clr     c
+               subb    a,a0
+               mov     a0,a
+               clr     a
+               subb    a,a1
+               mov     a1,a
+
+       not_negative:
+               ret
+
+       _endasm ;
 }
+
+#elif defined _DIVSINT_ASM_SMALL_AUTO
+
+static void
+_divsint_dummy (void) _naked
+{
+       _asm
+
+               #define a0      dpl
+               #define a1      dph
+
+               ar0 = 0                 ; BUG register set is not considered
+               ar1 = 1
+
+               .globl __divsint
+
+       __divsint:
+
+               clr     F0              ; Flag 0 in PSW
+                                       ; available to user for general purpose
+               mov     a,a1
+               jnb     acc.7,a_not_negative
+
+               setb    F0
+
+               clr     a
+               clr     c
+               subb    a,a0
+               mov     a0,a
+               clr     a
+               subb    a,a1
+               mov     a1,a
+
+       a_not_negative:
+
+               mov     a,sp
+               add     a,#-2           ; 2 bytes return address
+               mov     r0,a            ; r0 points to b1
+               mov     a,@r0           ; b1
+
+               jnb     acc.7,b_not_negative
+
+               cpl     F0
+
+               dec     r0
+
+               clr     a
+               clr     c
+               subb    a,@r0           ; b0
+               mov     @r0,a
+               clr     a
+               inc     r0
+               subb    a,@r0           ; b1
+               mov     @r0,a
+
+       b_not_negative:
+
+               mov     ar1,@r0         ; b1
+               dec     r0
+               mov     ar0,@r0         ; b0
+
+               lcall   __divint
+
+               jnb     F0,not_negative
+
+               clr     a
+               clr     c
+               subb    a,a0
+               mov     a0,a
+               clr     a
+               subb    a,a1
+               mov     a1,a
+
+       not_negative:
+               ret
+
+       _endasm ;
+}
+
+#else  // _DIVSINT_ASM_
+
+int
+_divsint (int a, int b)
+{
+  register int r;
+
+  r = _divuint((a < 0 ? -a : a),
+               (b < 0 ? -b : b));
+  if ( (a < 0) ^ (b < 0))
+    return -r;
+  else
+    return r;
+}
+
+#endif  // _DIVSINT_ASM_
index 3bd9602aab6a814f528869b6a4d352f68b36095d..5165d01cc02d5e116b4eac352e6fc26f74c4758f 100644 (file)
@@ -1,5 +1,5 @@
 /*-------------------------------------------------------------------------
-   _divslong.c - routine for division of 32 bit signed long
+   _divslong.c - routine for division of 32 bit long
 
              Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1999)
 
    under the terms of the GNU Library General Public License as published by the
    Free Software Foundation; either version 2, or (at your option) any
    later version.
-   
+
    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Library General Public License for more details.
-   
+
    You should have received a copy of the GNU Library General Public License
    along with this program; if not, write to the Free Software
    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-   
+
    In other words, you are welcome to use, share and improve this program.
    You are forbidden to forbid anyone else to use, share and improve
-   what you give them.   Help stamp out software-hoarding!  
+   what you give them.   Help stamp out software-hoarding!
 -------------------------------------------------------------------------*/
 
+
 #include <sdcc-lib.h>
 
 #if _SDCC_MANGLES_SUPPORT_FUNS
 unsigned long _divulong (unsigned long a, unsigned long b);
 #endif
 
-long _divslong (long a, long b)
+/*   Assembler-functions are provided for:
+     mcs51 small
+     mcs51 small stack-auto
+*/
+
+#if !defined(SDCC_USE_XSTACK) && !defined(_SDCC_NO_ASM_LIB_FUNCS)
+#  if defined(SDCC_mcs51)
+#    if defined(SDCC_MODEL_SMALL)
+#      if defined(SDCC_STACK_AUTO)
+#        define _DIVSLONG_ASM_SMALL_AUTO
+#      else
+#        define _DIVSLONG_ASM_SMALL
+#      endif
+#    endif
+#  endif
+#endif
+
+#if defined _DIVSLONG_ASM_SMALL
+
+static void
+_divslong_dummy (void) _naked
 {
-       long r;
-       
-       r = _divulong((a < 0 ? -a : a),
-                    (b < 0 ? -b : b));
-       if ( (a < 0) ^ (b < 0))
-           return -r;
-       else
-           return r;
-}              
+       _asm
+
+               #define a0      dpl
+               #define a1      dph
+               #define a2      b
+               #define a3      r3
+
+               .globl __divslong
+
+               // _divslong_PARM_2 shares the same memory with _divulong_PARM_2
+               // and is defined in _divulong.c
+               #define b0      (__divslong_PARM_2)
+               #define b1      (__divslong_PARM_2 + 1)
+               #define b2      (__divslong_PARM_2 + 2)
+               #define b3      (__divslong_PARM_2 + 3)
+
+       __divslong:
+                                       ; a3 in acc
+                                       ; b3 in (__divslong_PARM_2 + 3)
+               mov     a3,a            ; save a3
+
+               clr     F0              ; Flag 0 in PSW
+                                       ; available to user for general purpose
+               jnb     acc.7,a_not_negative
+
+               setb    F0
+
+               clr     a
+               clr     c
+               subb    a,a0
+               mov     a0,a
+               clr     a
+               subb    a,a1
+               mov     a1,a
+               clr     a
+               subb    a,a2
+               mov     a2,a
+               clr     a
+               subb    a,a3
+               mov     a3,a
+
+       a_not_negative:
+
+               mov     a,b3
+               jnb     acc.7,b_not_negative
+
+               cpl     F0
+
+               clr     a
+               clr     c
+               subb    a,b0
+               mov     b0,a
+               clr     a
+               subb    a,b1
+               mov     b1,a
+               clr     a
+               subb    a,b2
+               mov     b2,a
+               clr     a
+               subb    a,b3
+               mov     b3,a
+
+       b_not_negative:
+
+               mov     a,a3            ; restore a3 in acc
+
+               lcall   __divulong
+
+               jnb     F0,not_negative
+
+               mov     a3,a            ; save a3
+
+               clr     a
+               clr     c
+               subb    a,a0
+               mov     a0,a
+               clr     a
+               subb    a,a1
+               mov     a1,a
+               clr     a
+               subb    a,a2
+               mov     a2,a
+               clr     a
+               subb    a,a3
+               mov     a3,a
+
+       not_negative:
+               ret
+
+       _endasm ;
+}
+
+#elif defined _DIVSLONG_ASM_SMALL_AUTO
+
+static void
+_divslong_dummy (void) _naked
+{
+       _asm
+
+               #define a0      dpl
+               #define a1      dph
+               #define a2      b
+               #define a3      r3
+
+               .globl __divslong
+
+       __divslong:
+
+                                       ; a3 in acc
+               mov     a3,a            ; save a3
+
+               clr     F0              ; Flag 0 in PSW
+                                       ; available to user for general purpose
+               jnb     acc.7,a_not_negative
+
+               setb    F0
+
+               clr     a
+               clr     c
+               subb    a,a0
+               mov     a0,a
+               clr     a
+               subb    a,a1
+               mov     a1,a
+               clr     a
+               subb    a,a2
+               mov     a2,a
+               clr     a
+               subb    a,a3
+               mov     a3,a
+
+       a_not_negative:
+
+               mov     a,sp
+               add     a,#-2           ; 2 bytes return address
+               mov     r0,a            ; r0 points to b3
+               mov     a,@r0           ; b3
+
+               jnb     acc.7,b_not_negative
+
+               cpl     F0
+
+               dec     r0
+               dec     r0
+               dec     r0
+
+               clr     a
+               clr     c
+               subb    a,@r0           ; b0
+               mov     @r0,a
+               clr     a
+               inc     r0
+               subb    a,@r0           ; b1
+               mov     @r0,a
+               clr     a
+               inc     r0
+               subb    a,@r0           ; b2
+               mov     @r0,a
+               clr     a
+               inc     r0
+               subb    a,@r0           ; b3
+               mov     @r0,a
+
+       b_not_negative:
+               dec     r0
+               dec     r0
+               dec     r0              ; r0 points to b0
+
+               lcall   __divlong
+
+               jnb     F0,not_negative
+
+               mov     a3,a            ; save a3
+
+               clr     a
+               clr     c
+               subb    a,a0
+               mov     a0,a
+               clr     a
+               subb    a,a1
+               mov     a1,a
+               clr     a
+               subb    a,a2
+               mov     a2,a
+               clr     a
+               subb    a,a3
+               mov     a3,a
+
+       not_negative:
+               ret
+
+       _endasm ;
+}
+
+#else // _DIVSLONG_ASM
+
+long
+_divslong (long a, long b)
+{
+  long r;
+
+  r = _divulong((a < 0 ? -a : a),
+                (b < 0 ? -b : b));
+  if ( (a < 0) ^ (b < 0))
+    return -r;
+  else
+    return r;
+}
+
+#endif // _DIVSLONG_ASM
index bc3a5b15a029b12eee350c173b1ad0ff043fd344..f85aa8a250cbf56100c1efbc71f35c7e109096c5 100644 (file)
 /*-------------------------------------------------------------------------
-
   _divuint.c :- routine for unsigned int (16 bit) division
 
              Ecrit par -  Jean-Louis Vern . jlvern@writeme.com (1999)
 
-   This program is free software; you can redistribute it and/or modify it
-   under the terms of the GNU General Public License as published by the
+   This library is free software; you can redistribute it and/or modify it
+   under the terms of the GNU Library General Public License as published by the
    Free Software Foundation; either version 2, or (at your option) any
    later version.
-   
-   This program is distributed in the hope that it will be useful,
+
+   This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-   
-   You should have received a copy of the GNU General Public License
+   GNU Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public License
    along with this program; if not, write to the Free Software
    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-   
+
    In other words, you are welcome to use, share and improve this program.
    You are forbidden to forbid anyone else to use, share and improve
-   what you give them.   Help stamp out software-hoarding!  
+   what you give them.   Help stamp out software-hoarding!
 -------------------------------------------------------------------------*/
 
-#define MSB_SET(x) ((x >> (8*sizeof(x)-1)) & 1)
+/*   Assembler-functions are provided for:
+     mcs51 small
+     mcs51 small stack-auto
+*/
 
-unsigned int _divuint (unsigned int a, unsigned int b)
+#if !defined(SDCC_USE_XSTACK) && !defined(_SDCC_NO_ASM_LIB_FUNCS)
+#  if defined(SDCC_mcs51)
+#    if defined(SDCC_MODEL_SMALL)
+#      if defined(SDCC_STACK_AUTO)
+#        define _DIVUINT_ASM_SMALL_AUTO
+#      else
+#        define _DIVUINT_ASM_SMALL
+#      endif
+#    endif
+#  endif
+#endif
+
+#if defined _DIVUINT_ASM_SMALL || defined _DIVUINT_ASM_SMALL_AUTO
+
+static void
+_divuint_dummy (void) _naked
 {
-       unsigned int reste = 0  ;
-       unsigned char count = 16;
+       _asm
+
+               .globl __divuint
+
+       __divuint:
+
+               #define count   r2
+               #define reste_l r3
+               #define reste_h r4
+               #define al      dpl
+               #define ah      dph
+
 #ifdef SDCC_STACK_AUTO
-       unsigned char c;
+
+               ar0 = 0                 ; BUG register set is not considered
+               ar1 = 1
+
+               .globl __divint
+
+               mov     a,sp
+               add     a,#-2           ; 2 bytes return address
+               mov     r0,a            ; r0 points to bh
+               mov     ar1,@r0         ; load bh
+               dec     r0
+               mov     ar0,@r0         ; load bl
+
+               #define bl      r0
+               #define bh      r1
+
+       __divint:                       ; entry point for __divsint
+
+
+#else // SDCC_STACK_AUTO
+
+#if defined(SDCC_NOOVERLAY)            // BUG SDCC_NOOVERLAY is not set by -no-overlay
+               .area DSEG    (DATA)
 #else
-       bit c;
+               .area OSEG    (OVR,DATA)
 #endif
 
-       do{
-               // reste:a <- 0;
-               c = MSB_SET(a);
-               a <<= 1;
-               reste <<= 1;
-               if(c)
-                       reste |= 1;
-               
-               if(reste >= b){
-                       reste -= b;
-                       // a <- (result = 1)
-                       a |= 1;
-               }
-       } while(--count);
-       
-       return a;
+               .globl __divuint_PARM_2
+               .globl __divsint_PARM_2
+
+       __divuint_PARM_2:
+       __divsint_PARM_2:
+               .ds     2
+
+               .area CSEG    (CODE)
+
+               #define bl      (__divuint_PARM_2)
+               #define bh      (__divuint_PARM_2 + 1)
+
+#endif // SDCC_STACK_AUTO
+
+               mov     count,#16
+               clr     a
+               mov     reste_l,a
+               mov     reste_h,a
+
+       loop:   mov     a,al            ; a <<= 1
+               add     a,acc
+               mov     al,a
+               mov     a,ah
+               rlc     a
+               mov     ah,a
+
+               mov     a,reste_l       ; reste <<= 1
+               rlc     a               ;   feed in carry
+               mov     reste_l,a
+               mov     a,reste_h
+               rlc     a
+               mov     reste_h,a
+
+               mov     a,reste_l       ; reste - b
+               subb    a,bl            ; here carry is always clear, because
+                                       ; reste <<= 1 never overflows
+               mov     b,a
+               mov     a,reste_h
+               subb    a,bh
+
+               jc      smaller         ; reste >= b?
+
+               mov     reste_h,a       ; -> yes;  reste = reste - b;
+               mov     reste_l,b
+               orl     al,#1
+       smaller:                        ; -> no
+               djnz    count,loop
+               ret
+
+       _endasm ;
+}
+
+#else  // defined _DIVUINT_ASM_SMALL || defined _DIVUINT_ASM_SMALL_AUTO
+
+#define MSB_SET(x) ((x >> (8*sizeof(x)-1)) & 1)
+
+unsigned int
+_divuint (unsigned int a, unsigned int b)
+{
+  unsigned int reste = 0;
+  unsigned char count = 16;
+  #if defined(SDCC_STACK_AUTO) || defined(SDCC_z80)
+    char c;
+  #else
+    bit c;
+  #endif
+
+  do
+  {
+    // reste: a <- 0;
+    c = MSB_SET(a);
+    a <<= 1;
+    reste <<= 1;
+    if (c)
+      reste |= 1;
+
+    if (reste >= b)
+    {
+      reste -= b;
+      // a <- (result = 1)
+      a |= 1;
+    }
+  }
+  while (--count);
+  return a;
 }
+
+#endif  // defined _DIVUINT_ASM_SMALL || defined _DIVUINT_ASM_SMALL_AUTO
index 2694bbf2af5878f2c86df539b09dbbd8e7de57a2..6b1e7fd3e80b0d03049a66f067bc1c88708c9c00 100644 (file)
 
              Ecrit par -  Jean-Louis Vern . jlvern@writeme.com (1999)
 
-   This program is free software; you can redistribute it and/or modify it
-   under the terms of the GNU General Public License as published by the
+   This library is free software; you can redistribute it and/or modify it
+   under the terms of the GNU Library General Public License as published by the
    Free Software Foundation; either version 2, or (at your option) any
    later version.
-   
-   This program is distributed in the hope that it will be useful,
+
+   This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-   
-   You should have received a copy of the GNU General Public License
+   GNU Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public License
    along with this program; if not, write to the Free Software
    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-   
+
    In other words, you are welcome to use, share and improve this program.
    You are forbidden to forbid anyone else to use, share and improve
-   what you give them.   Help stamp out software-hoarding!  
+   what you give them.   Help stamp out software-hoarding!
 -------------------------------------------------------------------------*/
 
-#define MSB_SET(x) ((x >> (8*sizeof(x)-1)) & 1) 
+/*   Assembler-functions are provided for:
+     mcs51 small
+     mcs51 small stack-auto
+*/
+
+#if !defined(SDCC_USE_XSTACK) && !defined(_SDCC_NO_ASM_LIB_FUNCS)
+#  if defined(SDCC_mcs51)
+#    if defined(SDCC_MODEL_SMALL)
+#      if defined(SDCC_STACK_AUTO)
+#        define _DIVULONG_ASM_SMALL_AUTO
+#      else
+#        define _DIVULONG_ASM_SMALL
+#      endif
+#    endif
+#  endif
+#endif
+
+#if defined _DIVULONG_ASM_SMALL
+
+static void
+_divlong_dummy (void) _naked
+{
+       _asm
+
+               .globl __divulong
+
+       __divulong:
+
+               #define count   r2
+
+               #define a0      dpl
+               #define a1      dph
+               #define a2      b
+               #define a3      r3
+
+               #define reste0  r4
+               #define reste1  r5
+               #define reste2  r6
+               #define reste3  r7
+
+#if defined(SDCC_NOOVERLAY)            // BUG SDCC_NOOVERLAY is not set by -no-overlay
+               .area DSEG    (DATA)
+#else
+               .area OSEG    (OVR,DATA)
+#endif
+
+               .globl __divulong_PARM_2
+               .globl __divslong_PARM_2
+
+       __divulong_PARM_2:
+       __divslong_PARM_2:
+               .ds     4
+
+               .area CSEG    (CODE)
+
+               #define b0      (__divulong_PARM_2)
+               #define b1      (__divulong_PARM_2 + 1)
+               #define b2      (__divulong_PARM_2 + 2)
+               #define b3      (__divulong_PARM_2 + 3)
+
+                                       ; parameter a comes in a, b, dph, dpl
+               mov     a3,a            ; save parameter a3
+
+               mov     count,#32
+               clr     a
+               mov     reste0,a
+               mov     reste1,a
+               mov     reste2,a
+               mov     reste3,a
+
+       ; optimization  loop in lp0 until the first bit is shifted into rest
+
+       lp0:    mov     a,a0            ; a <<= 1
+               add     a,a0
+               mov     a0,a
+               mov     a,a1
+               rlc     a
+               mov     a1,a
+               mov     a,a2
+               rlc     a
+               mov     a2,a
+               mov     a,a3
+               rlc     a
+               mov     a3,a
+
+               jc      in_lp
+               djnz    count,lp0
+
+               sjmp    exit
+
+       loop:   mov     a,a0            ; a <<= 1
+               add     a,a0
+               mov     a0,a
+               mov     a,a1
+               rlc     a
+               mov     a1,a
+               mov     a,a2
+               rlc     a
+               mov     a2,a
+               mov     a,a3
+               rlc     a
+               mov     a3,a
+
+       in_lp:  mov     a,reste0        ; reste <<= 1
+               rlc     a               ;   feed in carry
+               mov     reste0,a
+               mov     a,reste1
+               rlc     a
+               mov     reste1,a
+               mov     a,reste2
+               rlc     a
+               mov     reste2,a
+               mov     a,reste3
+               rlc     a
+               mov     reste3,a
+
+               mov     a,reste0        ; reste - b
+               subb    a,b0            ; carry is always clear here, because
+                                       ; reste <<= 1 never overflows
+               mov     a,reste1
+               subb    a,b1
+               mov     a,reste2
+               subb    a,b2
+               mov     a,reste3
+               subb    a,b3
+
+               jc      minus           ; reste >= b?
+
+                                       ; -> yes;  reste -= b;
+               mov     a,reste0
+               subb    a,b0            ; carry is always clear here (jc)
+               mov     reste0,a
+               mov     a,reste1
+               subb    a,b1
+               mov     reste1,a
+               mov     a,reste2
+               subb    a,b2
+               mov     reste2,a
+               mov     a,reste3
+               subb    a,b3
+               mov     reste3,a
+
+               orl     a0,#1
+
+       minus:  djnz    count,loop      ; -> no
+
+       exit:   mov     a,a3            ; prepare the return value
+               ret
+
+       _endasm ;
+}
+
+#elif defined _DIVULONG_ASM_SMALL_AUTO
 
-unsigned long _divulong (unsigned long a, unsigned long b)
+static void
+_divlong_dummy (void) _naked
 {
-       unsigned long reste = 0L;
-       unsigned char count = 32;
-       char c;
-
-       do{
-               // reste:a <- 0;
-               c = MSB_SET(a);
-               a <<= 1;
-               reste <<= 1;
-               if(c)
-                       reste |= 1L;
-
-               if(reste >= b){
-                       reste -= b;
-                       // a <- (result = 1)
-                       a |= 1L;
-               }
-       } while(--count);
-
-       return a;
+       _asm
+
+               .globl __divulong
+
+       __divulong:
+
+               #define count   r2
+
+               #define a0      dpl
+               #define a1      dph
+               #define a2      b
+               #define a3      r3
+
+               #define reste0  r4
+               #define reste1  r5
+               #define reste2  r6
+               #define reste3  r7
+
+               .globl __divlong        ; entry point for __divslong
+
+               #define b0      r1
+
+               ar0 = 0                 ; BUG register set is not considered
+               ar1 = 1
+
+                                       ; parameter a comes in a, b, dph, dpl
+               mov     a3,a            ; save parameter a3
+
+               mov     a,sp
+               add     a,#-2-3         ; 2 bytes return address, 3 bytes param b
+               mov     r0,a            ; r0 points to b0
+
+       __divlong:                      ; entry point for __divslong
+
+               mov     ar1,@r0         ; load b0
+               inc     r0              ; r0 points to b1
+
+               mov     count,#32
+               clr     a
+               mov     reste0,a
+               mov     reste1,a
+               mov     reste2,a
+               mov     reste3,a
+
+       ; optimization  loop in lp0 until the first bit is shifted into rest
+
+       lp0:    mov     a,a0            ; a <<= 1
+               add     a,a0
+               mov     a0,a
+               mov     a,a1
+               rlc     a
+               mov     a1,a
+               mov     a,a2
+               rlc     a
+               mov     a2,a
+               mov     a,a3
+               rlc     a
+               mov     a3,a
+
+               jc      in_lp
+               djnz    count,lp0
+
+               sjmp    exit
+
+       loop:   mov     a,a0            ; a <<= 1
+               add     a,a0
+               mov     a0,a
+               mov     a,a1
+               rlc     a
+               mov     a1,a
+               mov     a,a2
+               rlc     a
+               mov     a2,a
+               mov     a,a3
+               rlc     a
+               mov     a3,a
+
+       in_lp:  mov     a,reste0        ; reste <<= 1
+               rlc     a               ;   feed in carry
+               mov     reste0,a
+               mov     a,reste1
+               rlc     a
+               mov     reste1,a
+               mov     a,reste2
+               rlc     a
+               mov     reste2,a
+               mov     a,reste3
+               rlc     a
+               mov     reste3,a
+
+               mov     a,reste0        ; reste - b
+               subb    a,b0            ; carry is always clear here, because
+                                       ; reste <<= 1 never overflows
+               mov     a,reste1
+               subb    a,@r0           ; b1
+               mov     a,reste2
+               inc     r0
+               subb    a,@r0           ; b2
+               mov     a,reste3
+               inc     r0
+               subb    a,@r0           ; b3
+               dec     r0
+               dec     r0
+
+               jc      minus           ; reste >= b?
+
+                                       ; -> yes;  reste -= b;
+               mov     a,reste0
+               subb    a,b0            ; carry is always clear here (jc)
+               mov     reste0,a
+               mov     a,reste1
+               subb    a,@r0           ; b1
+               mov     reste1,a
+               mov     a,reste2
+               inc     r0
+               subb    a,@r0           ; b2
+               mov     reste2,a
+               mov     a,reste3
+               inc     r0
+               subb    a,@r0           ; b3
+               mov     reste3,a
+               dec     r0
+               dec     r0
+
+               orl     a0,#1
+
+       minus:  djnz    count,loop      ; -> no
+
+       exit:   mov     a,a3            ; prepare the return value
+               ret
+
+       _endasm ;
 }
+
+#else // _DIVULONG_ASM
+
+#define MSB_SET(x) ((x >> (8*sizeof(x)-1)) & 1)
+
+unsigned long
+_divulong (unsigned long a, unsigned long b)
+{
+  unsigned long reste = 0L;
+  unsigned char count = 32;
+  #if defined(SDCC_STACK_AUTO) || defined(SDCC_z80)
+    char c;
+  #else
+    bit c;
+  #endif
+
+  do
+  {
+    // reste: a <- 0;
+    c = MSB_SET(a);
+    a <<= 1;
+    reste <<= 1;
+    if (c)
+      reste |= 1L;
+
+    if (reste >= b)
+    {
+      reste -= b;
+      // a <- (result = 1)
+      a |= 1L;
+    }
+  }
+  while (--count);
+  return a;
+}
+
+#endif // _DIVULONG_ASM
index 9f12ab1e960b4e4d02578977ebb427f7bc08b0ac..fb0147dcfb4b72af4c97ec1add2c1e97c5793c86 100644 (file)
@@ -1,5 +1,4 @@
 /*-------------------------------------------------------------------------
-
   _modsint.c :- routine for signed int (16 bit) modulus
 
              Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1999)
    under the terms of the GNU Library General Public License as published by the
    Free Software Foundation; either version 2, or (at your option) any
    later version.
-   
+
    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Library General Public License for more details.
-   
+
    You should have received a copy of the GNU Library General Public License
    along with this program; if not, write to the Free Software
    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-   
+
    In other words, you are welcome to use, share and improve this program.
    You are forbidden to forbid anyone else to use, share and improve
-   what you give them.   Help stamp out software-hoarding!  
+   what you give them.   Help stamp out software-hoarding!
 -------------------------------------------------------------------------*/
 
+
+#include <sdcc-lib.h>
+
+#if _SDCC_MANGLES_SUPPORT_FUNS
+unsigned unsigned _moduint (unsigned a, unsigned b);
+#endif
+
+/*   Assembler-functions are provided for:
+     mcs51 small
+     mcs51 small stack-auto
+*/
+
+#if !defined(SDCC_USE_XSTACK) && !defined(_SDCC_NO_ASM_LIB_FUNCS)
+#  if defined(SDCC_mcs51)
+#    if defined(SDCC_MODEL_SMALL)
+#      if defined(SDCC_STACK_AUTO)
+#        define _MODSINT_ASM_SMALL_AUTO
+#      else
+#        define _MODSINT_ASM_SMALL
+#      endif
+#    endif
+#  endif
+#endif
+
+#if defined _MODSINT_ASM_SMALL
+
+static void
+_modsint_dummy (void) _naked
+{
+       _asm
+
+               #define a0      dpl
+               #define a1      dph
+
+               .globl __modsint
+
+               // _modsint_PARM_2 shares the same memory with _moduint_PARM_2
+               // and is defined in _moduint.c
+               #define b0      (__modsint_PARM_2)
+               #define b1      (__modsint_PARM_2 + 1)
+
+       __modsint:
+                                       ; a1 in dph
+                                       ; b1 in (__modsint_PARM_2 + 1)
+
+               clr     F0              ; Flag 0 in PSW
+                                       ; available to user for general purpose
+               mov     a,a1
+               jnb     acc.7,a_not_negative
+
+               setb    F0
+
+               clr     a
+               clr     c
+               subb    a,a0
+               mov     a0,a
+               clr     a
+               subb    a,a1
+               mov     a1,a
+
+       a_not_negative:
+
+               mov     a,b1
+               jnb     acc.7,b_not_negative
+
+               cpl     F0
+
+               clr     a
+               clr     c
+               subb    a,b0
+               mov     b0,a
+               clr     a
+               subb    a,b1
+               mov     b1,a
+
+       b_not_negative:
+
+               lcall   __moduint
+
+               jnb     F0,not_negative
+
+               clr     a
+               clr     c
+               subb    a,a0
+               mov     a0,a
+               clr     a
+               subb    a,a1
+               mov     a1,a
+
+       not_negative:
+               ret
+
+       _endasm ;
+}
+
+#elif defined _MODSINT_ASM_SMALL_AUTO
+
+static void
+_modsint_dummy (void) _naked
+{
+       _asm
+
+               #define a0      dpl
+               #define a1      dph
+
+               ar0 = 0                 ; BUG register set is not considered
+               ar1 = 1
+
+               .globl __modsint
+
+       __modsint:
+
+               clr     F0              ; Flag 0 in PSW
+                                       ; available to user for general purpose
+               mov     a,a1
+               jnb     acc.7,a_not_negative
+
+               setb    F0
+
+               clr     a
+               clr     c
+               subb    a,a0
+               mov     a0,a
+               clr     a
+               subb    a,a1
+               mov     a1,a
+
+       a_not_negative:
+
+               mov     a,sp
+               add     a,#-2           ; 2 bytes return address
+               mov     r0,a            ; r0 points to b1
+               mov     a,@r0           ; b1
+
+               jnb     acc.7,b_not_negative
+
+               cpl     F0
+
+               dec     r0
+
+               clr     a
+               clr     c
+               subb    a,@r0           ; b0
+               mov     @r0,a
+               clr     a
+               inc     r0
+               subb    a,@r0           ; b1
+               mov     @r0,a
+
+       b_not_negative:
+
+               mov     ar1,@r0         ; b1
+               dec     r0
+               mov     ar0,@r0         ; b0
+
+               lcall   __modint
+
+               jnb     F0,not_negative
+
+               clr     a
+               clr     c
+               subb    a,a0
+               mov     a0,a
+               clr     a
+               subb    a,a1
+               mov     a1,a
+
+       not_negative:
+               ret
+
+       _endasm ;
+}
+
+#else  // _MODSINT_ASM_
+
 int _modsint (int a, int b)
 {
        register int r;
@@ -35,3 +209,5 @@ int _modsint (int a, int b)
        else
            return r;
 }              
+
+#endif  // _MODSINT_ASM_
index 9eb09f65faa660b639c2bb34da9054a09842b54c..dc5038cbb4bc331215f0205f0b9a769fb0e83fe9 100644 (file)
@@ -7,19 +7,19 @@
    under the terms of the GNU Library General Public License as published by the
    Free Software Foundation; either version 2, or (at your option) any
    later version.
-   
+
    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Library General Public License for more details.
-   
+
    You should have received a copy of the GNU Library General Public License
    along with this program; if not, write to the Free Software
    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-   
+
    In other words, you are welcome to use, share and improve this program.
    You are forbidden to forbid anyone else to use, share and improve
-   what you give them.   Help stamp out software-hoarding!  
+   what you give them.   Help stamp out software-hoarding!
 -------------------------------------------------------------------------*/
 
 #include <sdcc-lib.h>
 unsigned long _modulong (unsigned long a, unsigned long b);
 #endif
 
-long  _modslong (long a, long b)
+/*   Assembler-functions are provided for:
+     mcs51 small
+     mcs51 small stack-auto
+*/
+
+#if !defined(SDCC_USE_XSTACK) && !defined(_SDCC_NO_ASM_LIB_FUNCS)
+#  if defined(SDCC_mcs51)
+#    if defined(SDCC_MODEL_SMALL)
+#      if defined(SDCC_STACK_AUTO)
+#        define _MODSLONG_ASM_SMALL_AUTO
+#      else
+#        define _MODSLONG_ASM_SMALL
+#      endif
+#    endif
+#  endif
+#endif
+
+#if defined _MODSLONG_ASM_SMALL
+
+static void
+_modslong_dummy (void) _naked
+{
+       _asm
+
+               #define a0      dpl
+               #define a1      dph
+               #define a2      b
+               #define a3      r1
+
+               .globl __modslong
+
+               // _modslong_PARM_2 shares the same memory with _modulong_PARM_2
+               // and is defined in _modulong.c
+               #define b0      (__modslong_PARM_2)
+               #define b1      (__modslong_PARM_2 + 1)
+               #define b2      (__modslong_PARM_2 + 2)
+               #define b3      (__modslong_PARM_2 + 3)
+
+       __modslong:
+                                       ; a3 in acc
+                                       ; b3 in (__modslong_PARM_2 + 3)
+               mov     a3,a            ; save a3
+
+               clr     F0              ; Flag 0 in PSW
+                                       ; available to user for general purpose
+               jnb     acc.7,a_not_negative
+
+               setb    F0
+
+               clr     a               ; a = -a;
+               clr     c
+               subb    a,a0
+               mov     a0,a
+               clr     a
+               subb    a,a1
+               mov     a1,a
+               clr     a
+               subb    a,a2
+               mov     a2,a
+               clr     a
+               subb    a,a3
+               mov     a3,a
+
+       a_not_negative:
+
+               mov     a,b3
+               jnb     acc.7,b_not_negative
+
+               cpl     F0
+
+               clr     a               ; b = -b;
+               clr     c
+               subb    a,b0
+               mov     b0,a
+               clr     a
+               subb    a,b1
+               mov     b1,a
+               clr     a
+               subb    a,b2
+               mov     b2,a
+               clr     a
+               subb    a,b3
+               mov     b3,a
+
+       b_not_negative:
+
+               mov     a,a3            ; restore a3 in acc
+
+               lcall   __modulong
+
+               jnb     F0,not_negative
+
+                               ; result in (a == r1), b, dph, dpl
+               clr     a
+               clr     c
+               subb    a,a0
+               mov     a0,a
+               clr     a
+               subb    a,a1
+               mov     a1,a
+               clr     a
+               subb    a,a2
+               mov     a2,a
+               clr     a
+               subb    a,a3
+                               ; result in a, b, dph, dpl
+       not_negative:
+               ret
+
+       _endasm ;
+}
+
+#elif defined _MODSLONG_ASM_SMALL_AUTO
+
+static void
+_modslong_dummy (void) _naked
 {
-       long r;
-       
-       r = _modulong((a < 0 ? -a : a),
-                   (b < 0 ? -b : b));
-
-       if ( (a < 0) ^ (b < 0))
-           return -r;
-       else
-           return r;
-}              
+       _asm
+
+               #define a0      dpl
+               #define a1      dph
+               #define a2      b
+               #define a3      r1
+
+               #define b0      r2
+               #define b1      r3
+               #define b2      r4
+               #define b3      r5
+
+               ar2 = 2                 ; BUG register set is not considered
+               ar3 = 3
+               ar4 = 4
+               ar5 = 5
+
+               .globl __modslong
+
+       __modslong:
+
+                                       ; a3 in acc
+               mov     a3,a            ; save a3
+
+               clr     F0              ; F0 (Flag 0)
+                                       ; available to user for general purpose
+               jnb     acc.7,a_not_negative
+
+               setb    F0
+
+               clr     a               ; a = -a;
+               clr     c
+               subb    a,a0
+               mov     a0,a
+               clr     a
+               subb    a,a1
+               mov     a1,a
+               clr     a
+               subb    a,a2
+               mov     a2,a
+               clr     a
+               subb    a,a3
+               mov     a3,a
+
+       a_not_negative:
+
+               mov     a,sp
+               add     a,#-2-3         ; 2 bytes return address, 3 bytes param b
+               mov     r0,a            ; r1 points to b0
+
+
+               mov     ar2,@r0         ; load b0
+               inc     r0              ; r0 points to b1
+               mov     ar3,@r0         ; b1
+               inc     r0
+               mov     ar4,@r0         ; b2
+               inc     r0
+               mov     a,@r0           ; b3
+               mov     b3,a
+
+               jnb     acc.7,b_not_negative
+
+               cpl     F0
+
+               clr     a               ; b = -b;
+               clr     c
+               subb    a,b0
+               mov     b0,a
+               clr     a
+               subb    a,b1
+               mov     b1,a
+               clr     a
+               subb    a,b2
+               mov     b2,a
+               clr     a
+               subb    a,b3
+               mov     b3,a
+
+       b_not_negative:
+
+               lcall   __modlong
+
+               jnb     F0,not_negative
+
+                               ; result in (a == r1), b, dph, dpl
+               clr     a
+               clr     c
+               subb    a,a0
+               mov     a0,a
+               clr     a
+               subb    a,a1
+               mov     a1,a
+               clr     a
+               subb    a,a2
+               mov     a2,a
+               clr     a
+               subb    a,a3    ; result in a, b, dph, dpl
+
+       not_negative:
+               ret
+
+       _endasm ;
+}
+
+#else // _MODSLONG_ASM
+
+long
+_modslong (long a, long b)
+{
+  long r;
+
+  r = _modulong((a < 0 ? -a : a),
+                (b < 0 ? -b : b));
+  if ( (a < 0) ^ (b < 0))
+    return -r;
+  else
+    return r;
+}
+
+#endif // _MODSLONG_ASM
index fa56e15ccb7be2271265a563d6f337365599b6fb..bb58a4bb9c3bcd06690b985a5b417c42d676154c 100644 (file)
@@ -1,5 +1,4 @@
 /*-------------------------------------------------------------------------
-
   _moduint.c :- routine for unsigned int (16 bit) modulus
 
              Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1999)
    under the terms of the GNU Library General Public License as published by the
    Free Software Foundation; either version 2, or (at your option) any
    later version.
-   
+
    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Library General Public License for more details.
-   
+
    You should have received a copy of the GNU Library General Public License
    along with this program; if not, write to the Free Software
    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-   
+
    In other words, you are welcome to use, share and improve this program.
    You are forbidden to forbid anyone else to use, share and improve
-   what you give them.   Help stamp out software-hoarding!  
+   what you give them.   Help stamp out software-hoarding!
 -------------------------------------------------------------------------*/
 
+/*   Assembler-functions are provided for:
+     mcs51 small
+     mcs51 small stack-auto
+*/
+
+#if !defined(SDCC_USE_XSTACK) && !defined(_SDCC_NO_ASM_LIB_FUNCS)
+#  if defined(SDCC_mcs51)
+#    if defined(SDCC_MODEL_SMALL)
+#      if defined(SDCC_STACK_AUTO)
+#        define _MODUINT_ASM_SMALL_AUTO
+#      else
+#        define _MODUINT_ASM_SMALL
+#      endif
+#    endif
+#  endif
+#endif
+
+#if defined _MODUINT_ASM_SMALL || defined _MODUINT_ASM_SMALL_AUTO
+
+static void
+_moduint_dummy (void) _naked
+{
+       _asm
+
+               .globl __moduint
+
+       __moduint:
+
+               #define count   r2
+               #define al      dpl
+               #define ah      dph
+
+#ifdef SDCC_STACK_AUTO
+
+               ar0 = 0                 ; BUG register set is not considered
+               ar1 = 1
+
+               .globl __modint
+
+               mov     a,sp
+               add     a,#-2           ; 2 bytes return address
+               mov     r0,a            ; r0 points to bh
+               mov     ar1,@r0         ; load bh
+               dec     r0
+               mov     ar0,@r0         ; load bl
+
+               #define bl      r0
+               #define bh      r1
+
+       __modint:                       ; entry point for __modsint
+
+
+#else // SDCC_STACK_AUTO
+
+#if defined(SDCC_NOOVERLAY)            // BUG SDCC_NOOVERLAY is not set by -no-overlay
+               .area DSEG    (DATA)
+#else
+               .area OSEG    (OVR,DATA)
+#endif
+
+               .globl __moduint_PARM_2
+               .globl __modsint_PARM_2
+
+       __moduint_PARM_2:
+       __modsint_PARM_2:
+               .ds     2
+
+               .area CSEG    (CODE)
+
+               #define bl      (__moduint_PARM_2)
+               #define bh      (__moduint_PARM_2 + 1)
+
+#endif // SDCC_STACK_AUTO
+
+               mov     a,bl            ; avoid endless loop
+               orl     a,bh
+               jz      div_by_0
+
+               mov     count,#1
+
+       loop1:  mov     a,bl            ; b <<= 1
+               add     a,acc
+               mov     bl,a
+               mov     a,bh
+               rlc     a
+               jc      msbset
+               mov     bh,a
+
+               mov     a,al            ; a - b
+               subb    a,bl            ; here carry is always clear
+               mov     a,ah
+               subb    a,bh
+
+               jc      start
+
+               inc     count
+               sjmp    loop1
+
+
+       start:  clr     c
+               mov     a,bh            ; b >>= 1;
+       msbset: rrc     a
+               mov     bh,a
+               mov     a,bl
+               rrc     a
+               mov     bl,a
+
+
+       loop2:  clr     c
+               mov     a,al            ; a - b
+               subb    a,bl
+
+               mov     b,a
+               mov     a,ah
+               subb    a,bh
+
+               jc      smaller         ; a >= b?
+
+               mov     ah,a            ; -> yes;  a = a - b;
+               mov     al,b
+       smaller:                        ; -> no
+               clr     c
+               mov     a,bh            ; b >>= 1;
+               rrc     a
+               mov     bh,a
+               mov     a,bl
+               rrc     a
+               mov     bl,a
+
+               djnz    count,loop2
+       div_by_0:
+               ret
+
+       _endasm ;
+}
+
+#else  // defined _MODUINT_ASM_SMALL || defined _MODUINT_ASM_SMALL_AUTO
+
 #define MSB_SET(x) ((x >> (8*sizeof(x)-1)) & 1) 
 
-unsigned int  _moduint (unsigned int a ,unsigned int b)
+unsigned int
+_moduint (unsigned int a, unsigned int b)
 {
-    unsigned char count = 0;
+  unsigned char count = 0;
     
     
-        while (!MSB_SET(b)) {
-               b <<= 1;
-               if (b > a)
-               {
-                 b >>=1;
-                 break;
-               }
-               count++;
-       }
-
-        do {
-               if (b <= a) {
-                 a -= b;
-               }
-               b >>= 1;
-       } while (count--);
-
-    return a;
+  while (!MSB_SET(b))
+  {
+    b <<= 1;
+    if (b > a)
+    {
+      b >>=1;
+      break;
+    }
+    count++;
+  }
+  do
+  {
+    if (a >= b)
+      a -= b;
+    b >>= 1;
+  }
+  while (count--);
+  return a;
 }
+
+#endif  // defined _MODUINT_ASM_SMALL || defined _MODUINT_ASM_SMALL_AUTO
index e3d85b8566a372a49b6c0e5746af62169bf85b57..8008487fae3c9bcee394c2d7b94cb9ddf3bf59c2 100644 (file)
    under the terms of the GNU Library General Public License as published by the
    Free Software Foundation; either version 2, or (at your option) any
    later version.
-   
+
    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Library General Public License for more details.
-   
+
    You should have received a copy of the GNU Library General Public License
    along with this program; if not, write to the Free Software
    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-   
+
    In other words, you are welcome to use, share and improve this program.
    You are forbidden to forbid anyone else to use, share and improve
-   what you give them.   Help stamp out software-hoarding!  
+   what you give them.   Help stamp out software-hoarding!
 -------------------------------------------------------------------------*/
 
-#define MSB_SET(x) ((x >> (8*sizeof(x)-1)) & 1) 
+/*   Assembler-functions are provided for:
+     mcs51 small
+     mcs51 small stack-auto
+*/
+
+#if !defined(SDCC_USE_XSTACK) && !defined(_SDCC_NO_ASM_LIB_FUNCS)
+#  if defined(SDCC_mcs51)
+#    if defined(SDCC_MODEL_SMALL)
+#      if defined(SDCC_STACK_AUTO)
+#        define _MODULONG_ASM_SMALL_AUTO
+#      else
+#        define _MODULONG_ASM_SMALL
+#      endif
+#    endif
+#  endif
+#endif
+
+#if defined _MODULONG_ASM_SMALL
+
+static void
+_modlong_dummy (void) _naked
+{
+       _asm
+
+               .globl __modulong
+
+       __modulong:
+
+#if defined(SDCC_NOOVERLAY)            // BUG SDCC_NOOVERLAY is not set by -no-overlay
+               .area DSEG    (DATA)
+#else
+               .area OSEG    (OVR,DATA)
+#endif
+
+               .globl __modulong_PARM_2
+               .globl __modslong_PARM_2
+
+       __modulong_PARM_2:
+       __modslong_PARM_2:
+               .ds     4
+
+               .area CSEG    (CODE)
+
+               #define count   r0
+
+               #define a0      dpl
+               #define a1      dph
+               #define a2      b
+               #define a3      r1
+
+               #define b0      (__modulong_PARM_2)
+               #define b1      (__modulong_PARM_2 + 1)
+               #define b2      (__modulong_PARM_2 + 2)
+               #define b3      (__modulong_PARM_2 + 3)
+
+                                       ; parameter a comes in a, b, dph, dpl
+               mov     a3,a            ; save parameter a3
+
+               mov     a,b0            ; b == 0? avoid endless loop
+               orl     a,b1
+               orl     a,b2
+               orl     a,b3
+               jz      div_by_0
+
+               mov     count,#0
+               clr     c               ; when loop1 jumps immediately to loop2
+
+       loop1:  inc     count
+
+               mov     a,b3            ; if (!MSB_SET(b))
+               jb      acc.7,loop2
+
+               mov     a,b0            ; b <<= 1
+               add     a,acc
+               mov     b0,a
+               mov     a,b1
+               rlc     a
+               mov     b1,a
+               mov     a,b2
+               rlc     a
+               mov     b2,a
+               mov     a,b3
+               rlc     a
+               mov     b3,a
+
+               mov     a,a0            ; a - b
+               subb    a,b0            ; here carry is always clear
+               mov     a,a1
+               subb    a,b1
+               mov     a,a2
+               subb    a,b2
+               mov     a,a3
+               subb    a,b3
+
+               jnc     loop1
+
+
+               clr     c
+               mov     a,b3            ; b >>= 1;
+               rrc     a
+               mov     b3,a
+               mov     a,b2
+               rrc     a
+               mov     b2,a
+               mov     a,b1
+               rrc     a
+               mov     b1,a
+               mov     a,b0
+               rrc     a
+               mov     b0,a
+
+       loop2:  ; clr   c                 never set
+               mov     a,a0            ; a - b
+               subb    a,b0
+               mov     r4,a
+               mov     a,a1
+               subb    a,b1
+               mov     r5,a
+               mov     a,a2
+               subb    a,b2
+               mov     r6,a
+               mov     a,a3
+               subb    a,b3
+
+               jc      smaller         ; a >= b?
+
+               mov     a3,a            ; -> yes;  a = a - b;
+               mov     a2,r6
+               mov     a1,r5
+               mov     a0,r4
+       smaller:                        ; -> no
+               clr     c
+               mov     a,b3            ; b >>= 1;
+               rrc     a
+               mov     b3,a
+               mov     a,b2
+               rrc     a
+               mov     b2,a
+               mov     a,b1
+               rrc     a
+               mov     b1,a
+               mov     a,b0
+               rrc     a
+               mov     b0,a
+
+               djnz    count,loop2
+
+               mov     a,a3            ; prepare the return value
+       div_by_0:
+               ret
+
+       _endasm ;
+}
+
+#elif defined _MODULONG_ASM_SMALL_AUTO
+
+static void
+_modlong_dummy (void) _naked
+{
+       _asm
+
+               .globl __modulong
+
+       __modulong:
+
+               #define count   r0
+
+               #define a0      dpl
+               #define a1      dph
+               #define a2      b
+               #define a3      r1
+
+               #define b0      r2
+               #define b1      r3
+               #define b2      r4
+               #define b3      r5
+
+               ar2 = 2                 ; BUG register set is not considered
+               ar3 = 3
+               ar4 = 4
+               ar5 = 5
+
+               .globl __modlong        ; entry point for __modslong
+
+                                       ; parameter a comes in a, b, dph, dpl
+               mov     a3,a            ; save parameter a3
+
+               mov     a,sp
+               add     a,#-2-3         ; 2 bytes return address, 3 bytes param b
+               mov     r0,a            ; r1 points to b0
+
+
+               mov     ar2,@r0         ; load b0
+               inc     r0              ; r0 points to b1
+               mov     ar3,@r0         ; b1
+               inc     r0
+               mov     ar4,@r0         ; b2
+               inc     r0
+               mov     ar5,@r0         ; b3
+
+       __modlong:                      ; entry point for __modslong
+                                       ; a in r1, b, dph, dpl
+                                       ; b in r5, r4, r3, r2 
+
+               mov     count,#0
+
+               mov     a,b0            ; b == 0? avoid endless loop
+               orl     a,b1
+               orl     a,b2
+               orl     a,b3
+               jz      div_by_0
+
+               mov     count,#0
+               clr     c               ; when loop1 jumps immediately to loop2
+
+       loop1:  inc     count
+
+               mov     a,b3            ; if (!MSB_SET(b))
+               jb      acc.7,loop2
 
-unsigned long  _modulong (unsigned long a ,unsigned long b)
+               mov     a,b0            ; b <<= 1
+               add     a,acc
+               mov     b0,a
+               mov     a,b1
+               rlc     a
+               mov     b1,a
+               mov     a,b2
+               rlc     a
+               mov     b2,a
+               mov     a,b3
+               rlc     a
+               mov     b3,a
+
+               mov     a,a0            ; a - b
+               subb    a,b0            ; here carry is always clear
+               mov     a,a1
+               subb    a,b1
+               mov     a,a2
+               subb    a,b2
+               mov     a,a3
+               subb    a,b3
+
+               jnc     loop1
+
+
+               clr     c
+               mov     a,b3            ; b >>= 1;
+               rrc     a
+               mov     b3,a
+               mov     a,b2
+               rrc     a
+               mov     b2,a
+               mov     a,b1
+               rrc     a
+               mov     b1,a
+               mov     a,b0
+               rrc     a
+               mov     b0,a
+
+       loop2:  ; clr   c                 never set
+               mov     a,a0            ; a - b
+               subb    a,b0
+               mov     a,a1
+               subb    a,b1
+               mov     r6,a            ; d1
+               mov     a,a2
+               subb    a,b2
+               mov     r7,a            ; d2
+               mov     a,a3
+               subb    a,b3
+
+               jc      smaller         ; a >= b?
+
+               mov     a3,a            ; -> yes;  a = a - b;
+               mov     a2,r7
+               mov     a1,r6
+               mov     a,a0
+               subb    a,b0
+               mov     a0,a
+       smaller:                        ; -> no
+               clr     c
+               mov     a,b3            ; b >>= 1;
+               rrc     a
+               mov     b3,a
+               mov     a,b2
+               rrc     a
+               mov     b2,a
+               mov     a,b1
+               rrc     a
+               mov     b1,a
+               mov     a,b0
+               rrc     a
+               mov     b0,a
+
+               djnz    count,loop2
+
+               mov     a,a3            ; prepare the return value
+       div_by_0:
+               ret
+
+       _endasm ;
+}
+
+#else // _MODULONG_ASM
+
+#define MSB_SET(x) ((x >> (8*sizeof(x)-1)) & 1)
+
+unsigned long
+_modulong (unsigned long a, unsigned long b)
 {
-    unsigned char count = 0;
-    
-    
-        while (!MSB_SET(b)) {
-               b <<= 1;
-               if (b > a)
-               {
-                 b >>=1;
-                 break;
-               }
-               count++;
-       }
-
-        do {
-               if (b <= a) {
-                 a -= b;
-               }
-               b >>= 1;
-       } while (count--);
-
-    return a;
+  unsigned char count = 0;
+
+  while (!MSB_SET(b))
+  {
+     b <<= 1;
+     if (b > a)
+     {
+        b >>=1;
+        break;
+     }
+     count++;
+  }
+  do
+  {
+    if (a >= b)
+      a -= b;
+    b >>= 1;
+  }
+  while (count--);
+
+  return a;
 }
+
+#endif // _MODULONG_ASM
index fa18440878d2f5d09581a73be7d3e7d9d95a71cc..960264a5eb0d31afdc8e04e1a57bb050fdb27517 100644 (file)
@@ -1,5 +1,5 @@
 /*-------------------------------------------------------------------------
-  _mulint.c :- routine for (unsigned) int (16 bit) multiplication               
+  _mulint.c :- routine for (unsigned) int (16 bit) multiplication
 
              Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1999)
 
@@ -7,19 +7,19 @@
    under the terms of the GNU Library General Public License as published by the
    Free Software Foundation; either version 2, or (at your option) any
    later version.
-   
+
    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Library General Public License for more details.
-   
+
    You should have received a copy of the GNU Library General Public License
    along with this program; if not, write to the Free Software
    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-   
+
    In other words, you are welcome to use, share and improve this program.
    You are forbidden to forbid anyone else to use, share and improve
-   what you give them.   Help stamp out software-hoarding!  
+   what you give them.   Help stamp out software-hoarding!
 -------------------------------------------------------------------------*/
 
 /* Signed and unsigned multiplication are the same - as long as the output
@@ -69,7 +69,7 @@ _muluint (unsigned int a, unsigned int b)     // in future: _mulint
       (char)(lsb_a*msb_b)<<8
   */
 
-  _asm 
+  _asm
     mov r2,dph ; msb_a
     mov r3,dpl ; lsb_a
 
@@ -190,7 +190,7 @@ _mulint_dummy (void) _naked
                mov     dph,a                   ;  1
 
                ret
-       
+
 #endif // SDCC_STACK_AUTO
 
        _endasm ;
@@ -208,13 +208,13 @@ _muluint (unsigned int a, unsigned int b) // in future: _mulint
 {
 #ifdef SDCC_MODEL_LARGE                // still needed for large + stack-auto
        union uu xdata *x;
-       union uu xdata *y; 
+       union uu xdata *y;
        union uu t;
         x = (union uu xdata *)&a;
         y = (union uu xdata *)&b;
 #else
        register union uu *x;
-       register union uu *y; 
+       register union uu *y;
        union uu t;
         x = (union uu *)&a;
         y = (union uu *)&b;
@@ -224,7 +224,7 @@ _muluint (unsigned int a, unsigned int b)   // in future: _mulint
         t.s.hi += (x->s.lo * y->s.hi) + (x->s.hi * y->s.lo);
 
        return t.t;
-} 
+}
 
 int
 _mulsint (int a, int b)                // obsolete
index 8ced7e575587281d884f78162bf13878257d2776..feff2d638b12298c9acd78d0331de9f19c09329f 100644 (file)
@@ -480,7 +480,7 @@ union bil {
 #elif defined(__z80) || defined(__gbz80)
 #define bcast(x) ((union bil *)&(x))
 #else
-#define bcast(x) ((union bil near *)&(x))
+#define bcast(x) ((union bil near  *)&(x))
 #endif
 
 /*
index adc8e636cb9dfe2cb9747abd41a86426ac4d9f9a..a2ed4e1035ca4908ec4bb43aac5152b7e83d42cf 100644 (file)
@@ -2,5 +2,4 @@ _divsint
 _divuint
 _modsint
 _moduint
-_mulsint
-_muluint
+_mulint
index 4675aaa47b33b8547837173419139191732feedb..5416bf38b6ae28fae992c667918800b2e01473b8 100644 (file)
@@ -2,5 +2,4 @@ _divslong.rel
 _divulong.rel
 _modslong.rel
 _modulong.rel
-_mululong.rel
-_mulslong.rel
+_mullong.rel