Yahoo Groups archive

Lpc2000

Index last updated: 2026-04-28 23:31 UTC

Message

64-bit integer division problem in CrossWorks(r) for ARM

2005-03-10 by John Doe

Hi!
CrossWorks(c) for ARM has problem with 64-bit integer division when
one or both operands have value exceeds 32-bit capacity. This is
code below to work around.
 
Does somebody knows this is CrossWorks ARM library problem only
or also GCC ARM library has it ???

Regards,
John Doe
 
<pre>
 
/* C-wrapper */
long long y_64div(long long a,long long b)
{
   y_div64();
   return b;
}
/* GCC ASM code - derived from ARM(c) macros */
   .text
   .code 32
   .align 4
   .global  y_div64
 
y_div64:
         STMFD   SP!,{R0,R1,R2,R3,R6-R11,R12,LR}
         ANDS      R9, R3, #1<<31               // get sign of d
         BPL        L_00
         RSBS      R2, R2, #0                   // ensure d +ve
         RSC        R3, R3, #0
L_00:
         EORS       R9, R9, R1, ASR#32           // b31=result b30=sign of n
         BCC        L_01
         RSBS       R0, R0, #0                   // ensure n +ve
         RSC        R1, R1, #0
L_01:
         BL          y_divu64
         MOVS     R9, R9, LSL#1                // get out sign bits
         BCC        L_02
         RSBS      R2, R2, #0
         RSC        R3, R3, #0
L_02:
         MOVS     R9, R9, LSL#1
         BCC        L_03
L_03:
         MOV        R4, R2
         MOV        R5, R3
         LDMFD    SP!,{R0,R1,R2,R3,R6-R11,R12,LR}
         BX           LR
//-----------------------------------------------------------------------
y_divu64:
        STMDB    SP!, {R4,R5,R6,R7,R8}
        MOV        R4,#0                /* zero the quotient */
        MOV        R5,#0
        MOV        R7,R1           /* set the remainder to the current value */
        MOV        R6,R0
        ORRS      R8, R2, R3
        BEQ         LU_08                /* divide by 0 */
        MOVS      R8,#0                /* count number of shifts */
       /* first loop gets $d as large as possible */
LU_00:
        ADDS       R2, R2, R2
        ADCS       R3, R3, R3        /* double d */
        BCS         LU_01             /*  overflowed */
        CMP         R3, R7
        CMPEQ    R2, R6
        ADDLS      R8, R8, #1       /* done an extra shift */
        BLS          LU_00
        ADDS       R8, R8, #0       /* clear carry */
LU_01:                               /* carry the overflow here */
        MOVS       R3, R3, RRX      /* colour */
        MOV         R2, R2, RRX      /* shift back down again */
LU_02:
        SUBS        R0, R6, R2
        SBCS        R1, R7, R3       /* n = r - d and C set if r>=d */
        MOVCS     R7, R1
        MOVCS     R6, R0           /* r=r-d if this goes */
        ADCS        R4, R4, R4
        ADC          R5, R5, R5       /* shift next bit into the answer */
        MOVS       R3, R3, LSR#1
        MOV         R2, R2, RRX      /* shift down d */
        SUBS        R8, R8, #1
        BGE          LU_02            /* do next loop (t+1) loops */
LU_08:
        MOV         R2, R4
        MOV         R3, R5
        MOV         R0, R6
        MOV         R1, R7
        LDMIA       SP!, {R4,R5,R6,R7,R8}
        BX          LR
</pre>

		
---------------------------------
Do you Yahoo!?
 Make Yahoo! your home page   

[Non-text portions of this message have been removed]

Attachments

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.