From: bernhardheld Date: Wed, 3 Oct 2001 16:24:51 +0000 (+0000) Subject: * src/device/lib/_mulint.c : new, with assember functions X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=e06463c2f7f7e77ad74ce0319288798cfbed3e0d;p=fw%2Fsdcc * 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 git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@1349 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- diff --git a/ChangeLog b/ChangeLog index 0bf0f155..e8b11012 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,32 @@ +2001-10-03 Bernhard Held + + * 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 * src/SDCCsymt.c: sequence of specifiers in pintTypeChain() corrected diff --git a/device/lib/Makefile.in b/device/lib/Makefile.in index 7b743759..54cff88f 100644 --- a/device/lib/Makefile.in +++ b/device/lib/Makefile.in @@ -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)) diff --git a/device/lib/_divsint.c b/device/lib/_divsint.c index 2aa21999..38745fb0 100644 --- a/device/lib/_divsint.c +++ b/device/lib/_divsint.c @@ -1,5 +1,4 @@ /*------------------------------------------------------------------------- - _divsint.c :- routine for signed int (16 bit) division. just calls routine for unsigned division after sign adjustment @@ -9,35 +8,207 @@ 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 + +#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_ diff --git a/device/lib/_divslong.c b/device/lib/_divslong.c index 3bd9602a..5165d01c 100644 --- a/device/lib/_divslong.c +++ b/device/lib/_divslong.c @@ -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) @@ -7,35 +7,257 @@ 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 #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 diff --git a/device/lib/_divuint.c b/device/lib/_divuint.c index bc3a5b15..f85aa8a2 100644 --- a/device/lib/_divuint.c +++ b/device/lib/_divuint.c @@ -1,54 +1,174 @@ /*------------------------------------------------------------------------- - _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 diff --git a/device/lib/_divulong.c b/device/lib/_divulong.c index 2694bbf2..6b1e7fd3 100644 --- a/device/lib/_divulong.c +++ b/device/lib/_divulong.c @@ -3,47 +3,349 @@ 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 diff --git a/device/lib/_modsint.c b/device/lib/_modsint.c index 9f12ab1e..fb0147dc 100644 --- a/device/lib/_modsint.c +++ b/device/lib/_modsint.c @@ -1,5 +1,4 @@ /*------------------------------------------------------------------------- - _modsint.c :- routine for signed int (16 bit) modulus Written By - Sandeep Dutta . sandeep.dutta@usa.net (1999) @@ -8,21 +7,196 @@ 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 + +#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_ diff --git a/device/lib/_modslong.c b/device/lib/_modslong.c index 9eb09f65..dc5038cb 100644 --- a/device/lib/_modslong.c +++ b/device/lib/_modslong.c @@ -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 @@ -28,15 +28,240 @@ 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 diff --git a/device/lib/_moduint.c b/device/lib/_moduint.c index fa56e15c..bb58a4bb 100644 --- a/device/lib/_moduint.c +++ b/device/lib/_moduint.c @@ -1,5 +1,4 @@ /*------------------------------------------------------------------------- - _moduint.c :- routine for unsigned int (16 bit) modulus Written By - Sandeep Dutta . sandeep.dutta@usa.net (1999) @@ -10,44 +9,185 @@ 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 diff --git a/device/lib/_modulong.c b/device/lib/_modulong.c index e3d85b85..8008487f 100644 --- a/device/lib/_modulong.c +++ b/device/lib/_modulong.c @@ -9,44 +9,352 @@ 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 diff --git a/device/lib/_mulint.c b/device/lib/_mulint.c index fa184408..960264a5 100644 --- a/device/lib/_mulint.c +++ b/device/lib/_mulint.c @@ -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 diff --git a/device/lib/_mullong.c b/device/lib/_mullong.c index 8ced7e57..feff2d63 100644 --- a/device/lib/_mullong.c +++ b/device/lib/_mullong.c @@ -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 /* diff --git a/device/lib/libint.lib b/device/lib/libint.lib index adc8e636..a2ed4e10 100644 --- a/device/lib/libint.lib +++ b/device/lib/libint.lib @@ -2,5 +2,4 @@ _divsint _divuint _modsint _moduint -_mulsint -_muluint +_mulint diff --git a/device/lib/liblong.lib b/device/lib/liblong.lib index 4675aaa4..5416bf38 100644 --- a/device/lib/liblong.lib +++ b/device/lib/liblong.lib @@ -2,5 +2,4 @@ _divslong.rel _divulong.rel _modslong.rel _modulong.rel -_mululong.rel -_mulslong.rel +_mullong.rel