Hi,
Which version of CrossWorks for ARM are you using? You can use "Help |
About CrossStudio" to determine the version and build number.
I can't reproduce the problem, so can you provide some source code
that demonstrates the problem you are seeing?
Regards,
Jon Elliott
Rowley Associates Ltd
--- In , John Doe <ytremil@y...> wrote:
> 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
> ---------------------------------
>
|