gbdk-2020 | GameBoy Development Kit |
| download: https://git.y1.nz/archives/gbdk.tar.gz | |
| README | Files | Log | Refs | LICENSE |
commit e0f9f1f817ccd1944a1d63aa1d604d008ef34e1f parent 5eb3687558de50c64f4af64208d5d76dd002aeab Author: Toxa <untoxa@mail.ru> Date: Wed, 16 Dec 2020 13:45:58 +0300 __mullong support fixed Diffstat:
| M | gbdk-lib/libc/_mullong.c | 1108 | +++++++++++++++++++++++++++++++++++++++++++++++-------------------------------- |
1 file changed, 663 insertions(+), 445 deletions(-)
diff --git a/gbdk-lib/libc/_mullong.c b/gbdk-lib/libc/_mullong.c @@ -1,496 +1,666 @@ /*------------------------------------------------------------------------- _mullong.c - routine for multiplication of 32 bit (unsigned) long - Written By - Jean Louis VERN jlvern@writeme.com (1999) - Written By - Sandeep Dutta . sandeep.dutta@usa.net (1999) + Copyright (C) 1999, Sandeep Dutta . sandeep.dutta@usa.net + Copyright (C) 1999, Jean Louis VERN jlvern@writeme.com 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 + under the terms of the GNU 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! + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this library; see the file COPYING. If not, write to the + Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. + + As a special exception, if you link this library with other files, + some of which are compiled with SDCC, to produce an executable, + this library does not by itself cause the resulting executable to + be covered by the GNU General Public License. This exception does + not however invalidate any other reasons why the executable file + might be covered by the GNU General Public License. -------------------------------------------------------------------------*/ /* Signed and unsigned multiplication are the same - as long as the output has the same precision as the input. - To do: _mululong and _mulslong should be replaced by _mullong. - - bernhard@bernhardheld.de - 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) +#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) && !defined(__SDCC_PARMS_IN_BANK1) # define _MULLONG_ASM_SMALL_AUTO # else # define _MULLONG_ASM_SMALL # endif -# elif defined(SDCC_MODEL_LARGE) -# if !defined(SDCC_STACK_AUTO) +# elif defined(__SDCC_MODEL_LARGE) +# if !defined(__SDCC_STACK_AUTO) # define _MULLONG_ASM_LARGE # endif # endif # endif #endif -#if defined _MULLONG_ASM_SMALL || defined _MULLONG_ASM_SMALL_AUTO +#if defined(_MULLONG_ASM_SMALL) || defined(_MULLONG_ASM_SMALL_AUTO) void -_mullong_dummy (void) _naked +_mullong_dummy (void) __naked { - _asm + __asm - __mullong: - __mululong: ; obsolete - __mulslong: ; obsolete +__mullong: - .globl __mullong - .globl __mululong ; obsolete - .globl __mulslong ; obsolete + .globl __mullong - ; the result c will be stored in r4...r7 - #define c0 r4 - #define c1 r5 - #define c2 r6 - #define c3 r7 + ; the result c will be stored in r4...r7 + #define c0 r4 + #define c1 r5 + #define c2 r6 + #define c3 r7 + + #define a0 dpl + #define a1 dph + #define a2 r2 + #define a3 r3 ; c0 a0 * b0 ; c1 a1 * b0 + a0 * b1 ; c2 a2 * b0 + a1 * b1 + a0 * b2 ; c3 a3 * b0 + a2 * b1 + a1 * b2 + a0 * b3 -#if !defined SDCC_STACK_AUTO - -#if defined(SDCC_NOOVERLAY) - .area DSEG (DATA) +#if !defined(__SDCC_STACK_AUTO) || defined(__SDCC_PARMS_IN_BANK1) +#if defined(__SDCC_PARMS_IN_BANK1) + #define b0 (b1_0) + #define b1 (b1_1) + #define b2 (b1_2) + #define b3 (b1_3) +#else +#if defined(__SDCC_NOOVERLAY) + .area DSEG (DATA) #else - .area OSEG (OVR,DATA) + .area OSEG (OVR,DATA) #endif - __mullong_PARM_2: - __mululong_PARM_2: ; obsolete - __mulslong_PARM_2: ; obsolete - - .globl __mullong_PARM_2 - .globl __mululong_PARM_2 ; obsolete - .globl __mulslong_PARM_2 ; obsolete - - .ds 4 - - .area CSEG (CODE) - - ; parameter a comes in a, b, dph, dpl - mov r2,b ; save parameter a - mov r3,a - - #define a0 dpl - #define a1 dph - #define a2 r2 - #define a3 r3 - - b0 = __mullong_PARM_2 - b1 = (__mullong_PARM_2+1) - b2 = (__mullong_PARM_2+2) - b3 = (__mullong_PARM_2+3) - - ; Byte 0 - mov a,a0 - mov b,b0 - mul ab ; a0 * b0 - mov c0,a - mov c1,b - - ; Byte 1 - mov a,a1 - mov b,b0 - mul ab ; a1 * b0 - add a,c1 - mov c1,a - clr a - addc a,b - mov c2,a - - - mov a,a0 - mov b,b1 - mul ab ; a0 * b1 - add a,c1 - mov c1,a - mov a,b - addc a,c2 - mov c2,a - clr a - rlc a - mov c3,a - - ; Byte 2 - mov a,a2 - mov b,b0 - mul ab ; a2 * b0 - add a,c2 - mov c2,a - mov a,b - addc a,c3 - mov c3,a - - mov a,a1 - mov b,b1 - mul ab ; a1 * b1 - add a,c2 - mov c2,a - mov a,b - addc a,c3 - mov c3,a - - mov a,a0 - mov b,b2 - mul ab ; a0 * b2 - add a,c2 - mov c2,a - mov a,b - addc a,c3 - mov c3,a - - ; Byte 3 - mov a,a3 - mov b,b0 - mul ab ; a3 * b0 - add a,c3 - mov c3,a - - mov a,a2 - mov b,b1 - mul ab ; a2 * b1 - add a,c3 - mov c3,a - - mov a,a1 - mov b,b2 - mul ab ; a1 * b2 - add a,c3 - mov c3,a - - mov a,a0 - mov b,b3 - mul ab ; a0 * b3 - add a,c3 - - mov b,c2 - mov dph,c1 - mov dpl,c0 - ret - -#else // SDCC_STACK_AUTO - - ; parameter a comes in a, b, dph, dpl - mov r2,b ; save parameter a - mov r3,a - - #define a0 dpl - #define a1 dph - #define a2 r2 - #define a3 r3 - - #define b0 r1 - - mov a,#-2-3 ; 1 return address 2 bytes, b 4 bytes - add a,sp ; 1 - mov r0,a ; 1 r0 points to b0 - - ; Byte 0 - mov a,a0 - mov b,@r0 ; b0 - mov b0,b ; we need b0 several times - inc r0 ; r0 points to b1 - mul ab ; a0 * b0 - mov c0,a - mov c1,b - - ; Byte 1 - mov a,a1 - mov b,b0 - mul ab ; a1 * b0 - add a,c1 - mov c1,a - clr a - addc a,b - mov c2,a - - - mov a,a0 - mov b,@r0 ; b1 - mul ab ; a0 * b1 - add a,c1 - mov c1,a - mov a,b - addc a,c2 - mov c2,a - clr a - rlc a - mov c3,a - - ; Byte 2 - mov a,a2 - mov b,b0 - mul ab ; a2 * b0 - add a,c2 - mov c2,a - mov a,b - addc a,c3 - mov c3,a - - mov a,a1 - mov b,@r0 ; b1 - mul ab ; a1 * b1 - add a,c2 - mov c2,a - mov a,b - addc a,c3 - mov c3,a - - mov a,a0 - inc r0 - mov b,@r0 ; b2 - mul ab ; a0 * b2 - add a,c2 - mov c2,a - mov a,b - addc a,c3 - mov c3,a - - ; Byte 3 - mov a,a3 - mov b,b0 - mul ab ; a3 * b0 - add a,c3 - mov c3,a - - mov a,a1 - mov b,@r0 ; b2 - mul ab ; a1 * b2 - add a,c3 - mov c3,a - - mov a,a2 - dec r0 - mov b,@r0 ; b1 - mul ab ; a2 * b1 - add a,c3 - mov c3,a - - mov a,a0 - inc r0 - inc r0 - mov b,@r0 ; b3 - mul ab ; a0 * b3 - add a,c3 - - mov b,c2 - mov dph,c1 - mov dpl,c0 - - ret - -#endif // SDCC_STACK_AUTO - - _endasm ; +__mullong_PARM_2: + + .globl __mullong_PARM_2 + + .ds 4 + + b0 = __mullong_PARM_2 + b1 = (__mullong_PARM_2+1) + b2 = (__mullong_PARM_2+2) + b3 = (__mullong_PARM_2+3) + +#endif + .area CSEG (CODE) + + ; parameter a comes in a, b, dph, dpl + mov r2,b ; save parameter a + mov r3,a + + ; Byte 0 + mov a,a0 + mov b,b0 + mul ab ; a0 * b0 + mov c0,a + mov c1,b + + ; Byte 1 + mov a,a1 + mov b,b0 + mul ab ; a1 * b0 + add a,c1 + mov c1,a + clr a + addc a,b + mov c2,a + + mov a,a0 + mov b,b1 + mul ab ; a0 * b1 + add a,c1 + mov c1,a + mov a,b + addc a,c2 + mov c2,a + clr a + rlc a + mov c3,a + + ; Byte 2 + mov a,a2 + mov b,b0 + mul ab ; a2 * b0 + add a,c2 + mov c2,a + mov a,b + addc a,c3 + mov c3,a + + mov a,a1 + mov b,b1 + mul ab ; a1 * b1 + add a,c2 + mov c2,a + mov a,b + addc a,c3 + mov c3,a + + mov a,a0 + mov b,b2 + mul ab ; a0 * b2 + add a,c2 + mov c2,a + mov a,b + addc a,c3 + mov c3,a + + ; Byte 3 + mov a,a3 + mov b,b0 + mul ab ; a3 * b0 + add a,c3 + mov c3,a + + mov a,a2 + mov b,b1 + mul ab ; a2 * b1 + add a,c3 + mov c3,a + + mov a,a1 + mov b,b2 + mul ab ; a1 * b2 + add a,c3 + mov c3,a + + mov a,a0 + mov b,b3 + mul ab ; a0 * b3 + add a,c3 + + mov b,c2 + mov dph,c1 + mov dpl,c0 + ret + +#else // __SDCC_STACK_AUTO + + ; parameter a comes in a, b, dph, dpl + mov r2,b ; save parameter a + mov r3,a + + #define a0 dpl + #define a1 dph + #define a2 r2 + #define a3 r3 + + #define b0 r1 + + mov a,#-2-3 ; 1 return address 2 bytes, b 4 bytes + add a,sp ; 1 + mov r0,a ; 1 r0 points to b0 + + ; Byte 0 + mov a,a0 + mov b,@r0 ; b0 + mov b0,b ; we need b0 several times + inc r0 ; r0 points to b1 + mul ab ; a0 * b0 + mov c0,a + mov c1,b + + ; Byte 1 + mov a,a1 + mov b,b0 + mul ab ; a1 * b0 + add a,c1 + mov c1,a + clr a + addc a,b + mov c2,a + + mov a,a0 + mov b,@r0 ; b1 + mul ab ; a0 * b1 + add a,c1 + mov c1,a + mov a,b + addc a,c2 + mov c2,a + clr a + rlc a + mov c3,a + + ; Byte 2 + mov a,a2 + mov b,b0 + mul ab ; a2 * b0 + add a,c2 + mov c2,a + mov a,b + addc a,c3 + mov c3,a + + mov a,a1 + mov b,@r0 ; b1 + mul ab ; a1 * b1 + add a,c2 + mov c2,a + mov a,b + addc a,c3 + mov c3,a + + mov a,a0 + inc r0 + mov b,@r0 ; b2 + mul ab ; a0 * b2 + add a,c2 + mov c2,a + mov a,b + addc a,c3 + mov c3,a + + ; Byte 3 + mov a,a3 + mov b,b0 + mul ab ; a3 * b0 + add a,c3 + mov c3,a + + mov a,a1 + mov b,@r0 ; b2 + mul ab ; a1 * b2 + add a,c3 + mov c3,a + + mov a,a2 + dec r0 + mov b,@r0 ; b1 + mul ab ; a2 * b1 + add a,c3 + mov c3,a + + mov a,a0 + inc r0 + inc r0 + mov b,@r0 ; b3 + mul ab ; a0 * b3 + add a,c3 + + mov b,c2 + mov dph,c1 + mov dpl,c0 + + ret + +#endif // __SDCC_STACK_AUTO + + __endasm; } +#elif defined(_MULLONG_ASM_LARGE) + +void +_mullong_dummy (void) __naked +{ + __asm + +__mullong: + + .globl __mullong + + ; the result c will be stored in r4...r7 + #define c0 r4 + #define c1 r5 + #define c2 r6 + #define c3 r7 + + ; c0 a0 * b0 + ; c1 a1 * b0 + a0 * b1 + ; c2 a2 * b0 + a1 * b1 + a0 * b2 + ; c3 a3 * b0 + a2 * b1 + a1 * b2 + a0 * b3 + +#if !defined(__SDCC_PARMS_IN_BANK1) + .area XSEG (XDATA) + +__mullong_PARM_2: + + .globl __mullong_PARM_2 + + .ds 4 +#endif + .area CSEG (CODE) + + ; parameter a comes in a, b, dph, dpl + mov r0,dpl ; save parameter a + mov r1,dph + mov r2,b + mov r3,a + + #define a0 r0 + #define a1 r1 + #define a2 r2 + #define a3 r3 + + ; Byte 0 + mov b,a0 +#if defined(__SDCC_PARMS_IN_BANK1) + mov a,b1_0 ; b0 +#else + mov dptr,#__mullong_PARM_2 + movx a,@dptr ; b0 +#endif + mul ab ; a0 * b0 + mov c0,a + mov c1,b + + ; Byte 1 + mov b,a1 +#if defined(__SDCC_PARMS_IN_BANK1) + mov a,b1_0 ; b0 +#else + movx a,@dptr ; b0 +#endif + mul ab ; a1 * b0 + add a,c1 + mov c1,a + clr a + addc a,b + mov c2,a + + mov b,a0 +#if defined(__SDCC_PARMS_IN_BANK1) + mov a,b1_1 ; b1 +#else + inc dptr ; b1 + movx a,@dptr +#endif + mul ab ; a0 * b1 + add a,c1 + mov c1,a + mov a,b + addc a,c2 + mov c2,a + clr a + rlc a + mov c3,a + + ; Byte 2 + mov b,a1 +#if defined(__SDCC_PARMS_IN_BANK1) + mov a,b1_1 ; b1 +#else + movx a,@dptr ; b1 +#endif + mul ab ; a1 * b1 + add a,c2 + mov c2,a + mov a,b + addc a,c3 + mov c3,a + + mov b,a0 +#if defined(__SDCC_PARMS_IN_BANK1) + mov a,b1_2 ; b2 +#else + inc dptr ; b2 + movx a,@dptr +#endif + mul ab ; a0 * b2 + add a,c2 + mov c2,a + mov a,b + addc a,c3 + mov c3,a + + mov b,a2 +#if defined(__SDCC_PARMS_IN_BANK1) + mov a,b1_0 ; b0 +#else + mov dptr,#__mullong_PARM_2 + movx a,@dptr ; b0 +#endif + mul ab ; a2 * b0 + add a,c2 + mov c2,a + mov a,b + addc a,c3 + mov c3,a + + ; Byte 3 + mov b,a3 +#if defined(__SDCC_PARMS_IN_BANK1) + mov a,b1_0 ; b0 +#else + movx a,@dptr ; b0 +#endif + mul ab ; a3 * b0 + add a,c3 + mov c3,a + + mov b,a2 +#if defined(__SDCC_PARMS_IN_BANK1) + mov a,b1_1 ; b1 +#else + inc dptr ; b1 + movx a,@dptr +#endif + mul ab ; a2 * b1 + add a,c3 + mov c3,a + + mov b,a1 +#if defined(__SDCC_PARMS_IN_BANK1) + mov a,b1_2 ; b2 +#else + inc dptr ; b2 + movx a,@dptr +#endif + mul ab ; a1 * b2 + add a,c3 + mov c3,a -#elif defined _MULLONG_ASM_LARGE + mov b,a0 +#if defined(__SDCC_PARMS_IN_BANK1) + mov a,b1_3 ; b3 +#else + inc dptr ; b3 + movx a,@dptr +#endif + mul ab ; a0 * b3 + add a,c3 + + mov b,c2 + mov dph,c1 + mov dpl,c0 + ret + + __endasm; +} + +#elif defined(__SDCC_USE_XSTACK) && defined(__SDCC_STACK_AUTO) void -_mullong_dummy (void) _naked +_mullong_dummy (void) __naked { - _asm + __asm + +__mullong: - __mullong: - __mululong: ; obsolete - __mulslong: ; obsolete + .globl __mullong - .globl __mullong - .globl __mululong ; obsolete - .globl __mulslong ; obsolete + ; the result c will be stored in r4...r7 + #define c0 r4 + #define c1 r5 + #define c2 r6 + #define c3 r7 - ; the result c will be stored in r4...r7 - #define c0 r4 - #define c1 r5 - #define c2 r6 - #define c3 r7 + #define a0 dpl + #define a1 dph + #define a2 r2 + #define a3 r3 + + #define b0 r1 ; c0 a0 * b0 ; c1 a1 * b0 + a0 * b1 ; c2 a2 * b0 + a1 * b1 + a0 * b2 ; c3 a3 * b0 + a2 * b1 + a1 * b2 + a0 * b3 - .area XSEG (XDATA) - - __mullong_PARM_2: - __mululong_PARM_2: ; obsolete - __mulslong_PARM_2: ; obsolete - - .globl __mullong_PARM_2 - .globl __mululong_PARM_2 ; obsolete - .globl __mulslong_PARM_2 ; obsolete - - .ds 4 - - .area CSEG (CODE) - - ; parameter a comes in a, b, dph, dpl - mov r0,dpl ; save parameter a - mov r1,dph - mov r2,b - mov r3,a - - #define a0 r0 - #define a1 r1 - #define a2 r2 - #define a3 r3 - - ; Byte 0 - mov b,a0 - mov dptr,#__mullong_PARM_2 - movx a,@dptr ; b0 - mul ab ; a0 * b0 - mov c0,a - mov c1,b - - ; Byte 1 - mov b,a1 - movx a,@dptr ; b0 - mul ab ; a1 * b0 - add a,c1 - mov c1,a - clr a - addc a,b - mov c2,a - - - mov b,a0 - inc dptr ; b1 - movx a,@dptr - mul ab ; a0 * b1 - add a,c1 - mov c1,a - mov a,b - addc a,c2 - mov c2,a - clr a - rlc a - mov c3,a - - ; Byte 2 - mov b,a1 - movx a,@dptr ; b1 - mul ab ; a1 * b1 - add a,c2 - mov c2,a - mov a,b - addc a,c3 - mov c3,a - - mov b,a0 - inc dptr ; b2 - movx a,@dptr - mul ab ; a0 * b2 - add a,c2 - mov c2,a - mov a,b - addc a,c3 - mov c3,a - - mov b,a2 - mov dptr,#__mullong_PARM_2 - movx a,@dptr ; b0 - mul ab ; a2 * b0 - add a,c2 - mov c2,a - mov a,b - addc a,c3 - mov c3,a - - ; Byte 3 - mov b,a3 - movx a,@dptr ; b0 - mul ab ; a3 * b0 - add a,c3 - mov c3,a - - mov b,a2 - inc dptr ; b1 - movx a,@dptr - mul ab ; a2 * b1 - add a,c3 - mov c3,a - - mov b,a1 - inc dptr ; b2 - movx a,@dptr - mul ab ; a1 * b2 - add a,c3 - mov c3,a - - mov b,a0 - inc dptr ; b3 - movx a,@dptr - mul ab ; a0 * b3 - add a,c3 - - mov b,c2 - mov dph,c1 - mov dpl,c0 - ret - - _endasm ; + ; parameter a comes in a, b, dph, dpl + mov r2,b ; save parameter a + mov r3,a + + mov a,#-4 ; 1 b 4 bytes + add a,_spx ; 1 + mov r0,a ; 1 r0 points to b0 + + ; Byte 0 + movx a,@r0 ; b0 + mov b0,a ; we need b0 several times + inc r0 ; r0 points to b1 + mov b,a0 + mul ab ; a0 * b0 + mov c0,a + mov c1,b + + ; Byte 1 + mov a,a1 + mov b,b0 + mul ab ; a1 * b0 + add a,c1 + mov c1,a + clr a + addc a,b + mov c2,a + + mov b,a0 + movx a,@r0 ; b1 + mul ab ; a0 * b1 + add a,c1 + mov c1,a + mov a,b + addc a,c2 + mov c2,a + clr a + rlc a + mov c3,a + + ; Byte 2 + mov a,a2 + mov b,b0 + mul ab ; a2 * b0 + add a,c2 + mov c2,a + mov a,b + addc a,c3 + mov c3,a + + mov b,a1 + movx a,@r0 ; b1 + mul ab ; a1 * b1 + add a,c2 + mov c2,a + mov a,b + addc a,c3 + mov c3,a + + mov b,a0 + inc r0 + movx a,@r0 ; b2 + mul ab ; a0 * b2 + add a,c2 + mov c2,a + mov a,b + addc a,c3 + mov c3,a + + ; Byte 3 + mov a,a3 + mov b,b0 + mul ab ; a3 * b0 + add a,c3 + mov c3,a + + mov b,a1 + movx a,@r0 ; b2 + mul ab ; a1 * b2 + add a,c3 + mov c3,a + + mov b,a2 + dec r0 + movx a,@r0 ; b1 + mul ab ; a2 * b1 + add a,c3 + mov c3,a + + mov b,a0 + inc r0 + inc r0 + movx a,@r0 ; b3 + mul ab ; a0 * b3 + add a,c3 + + mov b,c2 + mov dph,c1 + mov dpl,c0 + + ret + + __endasm; } #else // _MULLONG_ASM struct some_struct { - int a ; + short a ; char b; long c ;}; +#if defined(__SDCC_hc08) || defined(__SDCC_s08) || defined(__SDCC_stm8) +/* big endian order */ union bil { - struct {unsigned char b0,b1,b2,b3 ;} b; - struct {unsigned int lo,hi ;} i; + struct {unsigned char b3,b2,b1,b0 ;} b; + struct {unsigned short hi,lo ;} i; unsigned long l; - struct { unsigned char b0; unsigned int i12; unsigned char b3;} bi; + struct { unsigned char b3; unsigned short i12; unsigned char b0;} bi; } ; -#if defined(SDCC_MODEL_LARGE) || defined (SDCC_ds390) -#define bcast(x) ((union bil xdata *)&(x)) -#elif defined(__z80) || defined(__gbz80) -#define bcast(x) ((union bil *)&(x)) #else -#define bcast(x) ((union bil near *)&(x)) +/* little endian order */ +union bil { + struct {unsigned char b0,b1,b2,b3 ;} b; + struct {unsigned short lo,hi ;} i; + unsigned long l; + struct { unsigned char b0; unsigned short i12; unsigned char b3;} bi; +} ; #endif +#if defined(__SDCC) + #include <sdcc-lib.h> +#endif + +#define bcast(x) ((union bil _AUTOMEM *)&(x)) + /* 3 2 1 0 X 3 2 1 0 ---------------------------- - 0.3 0.2 0.1 0.0 - 1.3 1.2 1.1 1.0 - 2.3 2.2 2.1 2.0 - 3.3 3.2 3.1 3.0 + 0.3 0.2 0.1 0.0 + 1.3 1.2 1.1 1.0 + 2.3 2.2 2.1 2.0 + 3.3 3.2 3.1 3.0 ---------------------------- |3.3|1.3|0.2|0.0| A |2.3|0.3|0.1| B @@ -501,42 +671,90 @@ union bil { |3.0| G |-------> only this side 32 x 32 -> 32 */ -unsigned long -_mululong (unsigned long a, unsigned long b) // in future: _mullong +#if defined(__SDCC_USE_XSTACK) +// currently the original code without u fails with --xstack +// it runs out of pointer registers +long +_mullong (long a, long b) +{ + union bil t, u; + + t.i.hi = bcast(a)->b.b0 * bcast(b)->b.b2; // A + t.i.lo = bcast(a)->b.b0 * bcast(b)->b.b0; // A + u.bi.b3 = bcast(a)->b.b0 * bcast(b)->b.b3; // B + u.bi.i12 = bcast(a)->b.b0 * bcast(b)->b.b1; // B + u.bi.b0 = 0; // B + t.l += u.l; + + t.b.b3 += bcast(a)->b.b3 * bcast(b)->b.b0; // G + t.b.b3 += bcast(a)->b.b2 * bcast(b)->b.b1; // F + t.i.hi += bcast(a)->b.b2 * bcast(b)->b.b0; // E + t.i.hi += bcast(a)->b.b1 * bcast(b)->b.b1; // D + + u.bi.b3 = bcast(a)->b.b1 * bcast(b)->b.b2; // C + u.bi.i12 = bcast(a)->b.b1 * bcast(b)->b.b0; // C + u.bi.b0 = 0; // C + t.l += u.l; + + return t.l; +} +#elif defined(__SDCC_z80) || defined(__SDCC_gbz80) || defined(__SDCC_r2k) || defined(__SDCC_r3k) +/* 32x32->32 multiplication to be used + if 16x16->16 is faster than three 8x8->16. + 2009, by M.Bodrato ( http://bodrato.it/ ) + + z80 and gbz80 don't have any hardware multiplication. + r2k and r3k have 16x16 hardware multiplication. + */ +long +_mullong (long a, long b) +{ + unsigned short i12; + + bcast(a)->i.hi *= bcast(b)->i.lo; + bcast(a)->i.hi += bcast(b)->i.hi * bcast(a)->i.lo; + + /* only (a->i.lo * b->i.lo) 16x16->32 to do. asm? */ + bcast(a)->i.hi += bcast(a)->b.b1 * bcast(b)->b.b1; + + i12 = bcast(b)->b.b0 * bcast(a)->b.b1; + bcast(b)->bi.i12 = bcast(a)->b.b0 * bcast(b)->b.b1; + + /* add up the two partial result, store carry in b3 */ + bcast(b)->b.b3 = ((bcast(b)->bi.i12 += i12) < i12); + + bcast(a)->i.lo = bcast(a)->b.b0 * bcast(b)->b.b0; + + bcast(b)->bi.b0 = 0; + + return a + b; +} +#else +long +_mullong (long a, long b) { union bil t; - t.i.hi = bcast(a)->b.b0 * bcast(b)->b.b2; // A - t.i.lo = bcast(a)->b.b0 * bcast(b)->b.b0; // A - __asm ;johan __endasm; - t.b.b3 += bcast(a)->b.b3 * - bcast(b)->b.b0; // G - t.b.b3 += bcast(a)->b.b2 * - bcast(b)->b.b1; // F - t.i.hi += bcast(a)->b.b2 * bcast(b)->b.b0; // E <- b lost in .lst + t.i.hi = bcast(a)->b.b0 * bcast(b)->b.b2; // A + t.i.lo = bcast(a)->b.b0 * bcast(b)->b.b0; // A + t.b.b3 += bcast(a)->b.b3 * bcast(b)->b.b0; // G + t.b.b3 += bcast(a)->b.b2 * bcast(b)->b.b1; // F + t.i.hi += bcast(a)->b.b2 * bcast(b)->b.b0; // E <- b lost in .lst // bcast(a)->i.hi is free ! - t.i.hi += bcast(a)->b.b1 * bcast(b)->b.b1; // D <- b lost in .lst - - bcast(a)->bi.b3 = bcast(a)->b.b1 * - bcast(b)->b.b2; - bcast(a)->bi.i12 = bcast(a)->b.b1 * - bcast(b)->b.b0; // C - - bcast(b)->bi.b3 = bcast(a)->b.b0 * - bcast(b)->b.b3; - bcast(b)->bi.i12 = bcast(a)->b.b0 * - bcast(b)->b.b1; // B - bcast(b)->bi.b0 = 0; // B - bcast(a)->bi.b0 = 0; // C + t.i.hi += bcast(a)->b.b1 * bcast(b)->b.b1; // D <- b lost in .lst + + bcast(a)->bi.b3 = bcast(a)->b.b1 * bcast(b)->b.b2; // C + bcast(a)->bi.i12 = bcast(a)->b.b1 * bcast(b)->b.b0; // C + + bcast(b)->bi.b3 = bcast(a)->b.b0 * bcast(b)->b.b3; // B + bcast(b)->bi.i12 = bcast(a)->b.b0 * bcast(b)->b.b1; // B + + bcast(b)->bi.b0 = 0; // B + bcast(a)->bi.b0 = 0; // C t.l += a; return t.l + b; } - -long -_mulslong (long a, long b) // obsolete -{ - return _mululong (a, b); -} +#endif #endif // _MULLONG_ASM
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.