X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=device%2Flib%2F_divulong.c;h=4ec6d2dda88e53e1815b1171f4f6346a11aefc63;hb=ac2a3bee4ffe024a919c1b360cc888679a45f326;hp=6b1e7fd3e80b0d03049a66f067bc1c88708c9c00;hpb=e06463c2f7f7e77ad74ce0319288798cfbed3e0d;p=fw%2Fsdcc diff --git a/device/lib/_divulong.c b/device/lib/_divulong.c index 6b1e7fd3..4ec6d2dd 100644 --- a/device/lib/_divulong.c +++ b/device/lib/_divulong.c @@ -27,10 +27,12 @@ mcs51 small stack-auto */ +#include + #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_STACK_AUTO) && !defined(SDCC_PARMS_IN_BANK1) # define _DIVULONG_ASM_SMALL_AUTO # else # define _DIVULONG_ASM_SMALL @@ -42,275 +44,279 @@ #if defined _DIVULONG_ASM_SMALL static void -_divlong_dummy (void) _naked +_divlong_dummy (void) __naked { - _asm + __asm - .globl __divulong + .globl __divulong - __divulong: +__divulong: - #define count r2 + #define count r2 - #define a0 dpl - #define a1 dph - #define a2 b - #define a3 r3 + #define x0 dpl + #define x1 dph + #define x2 b + #define x3 r3 - #define reste0 r4 - #define reste1 r5 - #define reste2 r6 - #define reste3 r7 + #define reste0 r4 + #define reste1 r5 + #define reste2 r6 + #define reste3 r7 +#if !defined(SDCC_PARMS_IN_BANK1) -#if defined(SDCC_NOOVERLAY) // BUG SDCC_NOOVERLAY is not set by -no-overlay - .area DSEG (DATA) +#if defined(SDCC_NOOVERLAY) + .area DSEG (DATA) #else - .area OSEG (OVR,DATA) + .area OSEG (OVR,DATA) #endif - .globl __divulong_PARM_2 - .globl __divslong_PARM_2 - - __divulong_PARM_2: - __divslong_PARM_2: - .ds 4 - - .area CSEG (CODE) + .globl __divulong_PARM_2 + .globl __divslong_PARM_2 - #define b0 (__divulong_PARM_2) - #define b1 (__divulong_PARM_2 + 1) - #define b2 (__divulong_PARM_2 + 2) - #define b3 (__divulong_PARM_2 + 3) +__divulong_PARM_2: +__divslong_PARM_2: + .ds 4 - ; parameter a comes in a, b, dph, dpl - mov a3,a ; save parameter a3 + .area CSEG (CODE) - mov count,#32 - clr a - mov reste0,a - mov reste1,a - mov reste2,a - mov reste3,a + #define y0 (__divulong_PARM_2) + #define y1 (__divulong_PARM_2 + 1) + #define y2 (__divulong_PARM_2 + 2) + #define y3 (__divulong_PARM_2 + 3) +#else + #define y0 (b1_0) + #define y1 (b1_1) + #define y2 (b1_2) + #define y3 (b1_3) +#endif // !SDCC_PARMS_IN_BANK1 + ; parameter x comes in a, b, dph, dpl + mov x3,a ; save parameter x3 + + 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 +lp0: mov a,x0 ; x <<= 1 + add a,x0 + mov x0,a + mov a,x1 + rlc a + mov x1,a + mov a,x2 + rlc a + mov x2,a + mov a,x3 + rlc a + mov x3,a + + jc in_lp + djnz count,lp0 + + sjmp exit + +loop: mov a,x0 ; x <<= 1 + add a,x0 + mov x0,a + mov a,x1 + rlc a + mov x1,a + mov a,x2 + rlc a + mov x2,a + mov a,x3 + rlc a + mov x3,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 - y + subb a,y0 ; 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 ; + mov a,reste1 + subb a,y1 + mov a,reste2 + subb a,y2 + mov a,reste3 + subb a,y3 + + jc minus ; reste >= y? + + ; -> yes; reste -= y; + mov a,reste0 + subb a,y0 ; carry is always clear here (jc) + mov reste0,a + mov a,reste1 + subb a,y1 + mov reste1,a + mov a,reste2 + subb a,y2 + mov reste2,a + mov a,reste3 + subb a,y3 + mov reste3,a + + orl x0,#1 + +minus: djnz count,loop ; -> no + +exit: mov a,x3 ; prepare the return value + ret + + __endasm; } #elif defined _DIVULONG_ASM_SMALL_AUTO static void -_divlong_dummy (void) _naked +_divlong_dummy (void) __naked { - _asm - - .globl __divulong + __asm - __divulong: + .globl __divulong - #define count r2 +__divulong: - #define a0 dpl - #define a1 dph - #define a2 b - #define a3 r3 + #define count r2 - #define reste0 r4 - #define reste1 r5 - #define reste2 r6 - #define reste3 r7 + #define x0 dpl + #define x1 dph + #define x2 b + #define x3 r3 - .globl __divlong ; entry point for __divslong + #define reste0 r4 + #define reste1 r5 + #define reste2 r6 + #define reste3 r7 - #define b0 r1 + .globl __divlong ; entry point for __divslong - ar0 = 0 ; BUG register set is not considered - ar1 = 1 + #define y0 r1 - ; parameter a comes in a, b, dph, dpl - mov a3,a ; save parameter a3 + ; parameter x comes in a, b, dph, dpl + mov x3,a ; save parameter x3 - mov a,sp - add a,#-2-3 ; 2 bytes return address, 3 bytes param b - mov r0,a ; r0 points to b0 + mov a,sp + add a,#-2-3 ; 2 bytes return address, 3 bytes param y + mov r0,a ; r0 points to y0 - __divlong: ; entry point for __divslong +__divlong: ; entry point for __divslong - mov ar1,@r0 ; load b0 - inc r0 ; r0 points to b1 + mov a,@r0 ; load y0 + mov r1,a + inc r0 ; r0 points to y1 - mov count,#32 - clr a - mov reste0,a - mov reste1,a - mov reste2,a - mov reste3,a + 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 ; +lp0: mov a,x0 ; x <<= 1 + add a,x0 + mov x0,a + mov a,x1 + rlc a + mov x1,a + mov a,x2 + rlc a + mov x2,a + mov a,x3 + rlc a + mov x3,a + + jc in_lp + djnz count,lp0 + + sjmp exit + +loop: mov a,x0 ; x <<= 1 + add a,x0 + mov x0,a + mov a,x1 + rlc a + mov x1,a + mov a,x2 + rlc a + mov x2,a + mov a,x3 + rlc a + mov x3,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 - y + subb a,y0 ; carry is always clear here, because + ; reste <<= 1 never overflows + mov a,reste1 + subb a,@r0 ; y1 + mov a,reste2 + inc r0 + subb a,@r0 ; y2 + mov a,reste3 + inc r0 + subb a,@r0 ; y3 + dec r0 + dec r0 + + jc minus ; reste >= y? + + ; -> yes; reste -= y; + mov a,reste0 + subb a,y0 ; carry is always clear here (jc) + mov reste0,a + mov a,reste1 + subb a,@r0 ; y1 + mov reste1,a + mov a,reste2 + inc r0 + subb a,@r0 ; y2 + mov reste2,a + mov a,reste3 + inc r0 + subb a,@r0 ; y3 + mov reste3,a + dec r0 + dec r0 + + orl x0,#1 + +minus: djnz count,loop ; -> no + +exit: mov a,x3 ; prepare the return value + ret + + __endasm; } #else // _DIVULONG_ASM @@ -318,34 +324,30 @@ _divlong_dummy (void) _naked #define MSB_SET(x) ((x >> (8*sizeof(x)-1)) & 1) unsigned long -_divulong (unsigned long a, unsigned long b) +_divulong (unsigned long x, unsigned long y) { unsigned long reste = 0L; unsigned char count = 32; - #if defined(SDCC_STACK_AUTO) || defined(SDCC_z80) - char c; - #else - bit c; - #endif + BOOL c; do { - // reste: a <- 0; - c = MSB_SET(a); - a <<= 1; + // reste: x <- 0; + c = MSB_SET(x); + x <<= 1; reste <<= 1; if (c) reste |= 1L; - if (reste >= b) + if (reste >= y) { - reste -= b; - // a <- (result = 1) - a |= 1L; + reste -= y; + // x <- (result = 1) + x |= 1L; } } while (--count); - return a; + return x; } #endif // _DIVULONG_ASM