Atteched code will fix some problems with long long division. (the code will
be smaller I hope less than 1K :)
This is untested, but that's all I can make within an hour just returned from
a pub :)
~d
P.S. this will not work right away. some defines required. check code.
On Saturday 30 November 2002 17:29, Dmitry wrote:
> yes we do...
> otherwise one has to write its own divmod code, which is really simple :)
> ~d
>
> On Saturday 30 November 2002 16:42, Oleg Skidan wrote:
> > Hi, All !
> >
> > Do we really need 4K flash for 64 bit division routine ?
> >
> > #include <sys/inttypes.h>
> >
> > uint64_t l;
> > uint32_t a,b,h;
> >
> > int main()
> > {
> > a=l/h;
> > }
> >
> >
> > D:\msp430\$>msp430-size
> > text data bss dec hex filename
> > 4322 0 20 4342 10f6 a.out
> >
> > All the best,
> > Oleg.
--
*********************************************************************
("`-''-/").___..--''"`-._ (\ Dimmy the Wild UA1ACZ
`6_ 6 ) `-. ( ).`-.__.`) Enterprise Information Sys
(_Y_.)' ._ ) `._ `. ``-..-' Nevsky prospekt, 20 / 44
_..`--'_..-_/ /--'_.' ,' Saint Petersburg, Russia
(il),-'' (li),' ((!.-' +7 (812) 314-8860, 5585314
*********************************************************************
#define r_remhh r11
#define r_remhl r10 /* remainder */
#define r_remlh r9
#define r_remll r8
#define r_remhh r15
#define r_remhl r14 /* dividend, quotient */
#define r_remlh r13
#define r_remll r12
#define r_arg2hh r7
#define r_arg2hl r6 /* divisor */
#define r_arg2lh r5
#define r_arg2ll r4
#define r_cnt 2(r1) /* loop count */
#define r_tmp 0(r1)
#if defined (L_udivmoddi4_parts)
.global __udivmoddi4_parts
.func __udivmoddi4_parts
__udivmoddi4_parts:
xor r_remhh, r_remhh ; clear reminder and carry
xor r_remhl, r_remhl
xor r_remlh, r_remlh
xor r_remll, r_remll
mov #65, r_cnt
jmp .L__udivmoddi4_ep
.L__udivmoddi4_loop:
rrc r_tmp ; restore carry bit
rlc r_remll
rlc r_remlh
rlc r_remhl
rlc r_remhh
cmp r_arg2hh, r_remhh ; is reminder < divisor ?
jlo .L__udivmoddi4_ep ; yes, skip correction
jne .L_udmdcrt
; they equal. check LSBytes
cmp r_arg2hl, r_remhl
jlo .L__udivmoddi4_ep ; is reminder still < divisor ?
jne .L_udmdcrt
cmp r_arg2lh, r_remlh
jlo .L__udivmoddi4_ep
jne .L_udmdcrt
cmp r_arg2ll, r_remll
jlo .L__udivmoddi4_ep
jne .L_udmdcrt
.L_udmdcrt:
sub r_arg2ll, r_remll ; adjust reminder
subc r_arg2lh, r_remlh
subc r_arg2hl, r_remhl
subc r_arg2hh, r_remhh
.L__udivmoddi4_ep:
rlc r_remll
rlc r_remlh
rlc r_remhl
rlc r_remhh
rlc r_tmp
dec r_cnt ; this clobbers C bit.
jnz .L__udivmoddi4_loop
ret
.endfunc
#endif /* defined (L_udivmoddi4_parts) */
#if defined (L_umoddi4)
;; First arg will be in r15:r12
;; next on stack
;; return in r15:r12
;; rearrange them as:
;; r15:r12 -> r15:r12
;; stack+8:stack+2 -> r_arg2hh:r_arg2ll
.global __umoddi4
.func __umoddi4
__umoddi4:
push r4
push r5
push r6
push r7
push r8
push r9
push r10
push r11
mov 18+0(r1), r_arg2ll
mov 18+2(r1), r_arg2lh
mov 18+4(r1), r_arg2hl
mov 18+6(r1), r_arg2hh
sub #4, r1
call #__udivmoddi4_parts
add #4, r1
pop r11
pop r10
pop r9
pop r8
pop r7
pop r6
pop r5
pop r4
ret
.endfunc
#endif
#if defined (L_umoddi4)
;; First arg will be in r15:r12
;; next on stack
;; return in r15:r12
;; rearrange them as:
;; r15:r12 -> r15:r12
;; stack+8:stack+2 -> r_arg2hh:r_arg2ll
.global __umoddi4
.func __umoddi4
__umoddi4:
call #__udivmoddi4_parts
push r4
push r5
push r6
push r7
push r8
push r9
push r10
push r11
mov 18+0(r1), r_arg2ll
mov 18+2(r1), r_arg2lh
mov 18+4(r1), r_arg2hl
mov 18+6(r1), r_arg2hh
sub #4, r1
call #__udivmoddi4_parts
add #4, r1
mov r_remhh, r15
mov r_remhl, r14
mov r_remlh, r13
mov r_remll, r12
pop r11
pop r10
pop r9
pop r8
pop r7
pop r6
pop r5
pop r4
ret
.endfunc
#endif
#if defined (L_moddi4)
;; First arg will be in r15:r12
;; next on stack
;; return in r15:r12
;; rearrange them as:
;; r15:r12 -> r15:r12
;; stack+8:stack+2 -> r_arg2hh:r_arg2ll
.global __moddi4
.func __moddi4
__moddi4:
push r4
push r5
push r6
push r7
push r8
push r9
push r10
push r11
mov 18+0(r1), r_arg2ll
mov 18+2(r1), r_arg2lh
mov 18+4(r1), r_arg2hl
mov 18+6(r1), r_arg2hh
sub #4, r1
clr t_tmp
bit #0x8000, r_remhh
jnc .L__moddi4rempos
inv r_remhh
inv r_remhl
inv r_remlh
inv r_remll
inc r_remll
adc r_remlh
adc r_remhl
adc r_remhh
bis #4, r_tmp
.L__moddi4rempos:
bit #0x8000, r_arg2hh
jnc .L__moddi4arg2pos
inv r_arg2hh
inv r_arg2hl
inv r_arg2lh
inv r_arg2ll
inc r_arg2ll
adc r_arg2lh
adc r_arg2hl
adc r_arg2hh
bis #8, r_tmp
.L__moddi4arg2pos:
call #__udivmoddi4_parts
rrc r_tmp
bit #4, r_tmp
jz .L__moddi4rem
inv r_remhh
inv r_remhl
inv r_remlh
inv r_remll
inc r_remll
adc r_remlh
adc r_remhl
adc r_remhh
.L__moddi4rem:
bit #8, r_tmp
jz .L__moddi4end
inv r_remhh
inv r_remhl
inv r_remlh
inv r_remll
inc r_remll
adc r_remlh
adc r_remhl
adc r_remhh
.L__moddi4end:
add #4, r1
pop r11
pop r10
pop r9
pop r8
pop r7
pop r6
pop r5
pop r4
ret
.endfunc
#endif
#if defined (L_moddi4)
;; First arg will be in r15:r12
;; next on stack
;; return in r15:r12
;; rearrange them as:
;; r15:r12 -> r15:r12
;; stack+8:stack+2 -> r_arg2hh:r_arg2ll
.global __moddi4
.func __moddi4
__moddi4:
push r4
push r5
push r6
push r7
push r8
push r9
push r10
push r11
mov 18+0(r1), r_arg2ll
mov 18+2(r1), r_arg2lh
mov 18+4(r1), r_arg2hl
mov 18+6(r1), r_arg2hh
sub #4, r1
clr t_tmp
bit #0x8000, r_remhh
jnc .L__moddi4rempos
inv r_remhh
inv r_remhl
inv r_remlh
inv r_remll
inc r_remll
adc r_remlh
adc r_remhl
adc r_remhh
bis #4, r_tmp
.L__moddi4rempos:
bit #0x8000, r_arg2hh
jnc .L__moddi4arg2pos
inv r_arg2hh
inv r_arg2hl
inv r_arg2lh
inv r_arg2ll
inc r_arg2ll
adc r_arg2lh
adc r_arg2hl
adc r_arg2hh
bis #8, r_tmp
.L__moddi4arg2pos:
call #__udivmoddi4_parts
rrc r_tmp
bit #4, r_tmp
jz .L__moddi4rem
inv r_remhh
inv r_remhl
inv r_remlh
inv r_remll
inc r_remll
adc r_remlh
adc r_remhl
adc r_remhh
.L__moddi4rem:
mov r_remhh, r15
mov r_remhl, r14
mov r_remlh, r13
mov r_remll, r12
add #4, r1
pop r11
pop r10
pop r9
pop r8
pop r7
pop r6
pop r5
pop r4
ret
.endfunc
#endif