__rt_div fixes for arm (#3843)

[CRT/arm] Fix __rt_udiv and __rt_sdiv
This commit is contained in:
Roman Masanin 2021-07-24 21:23:58 +03:00 committed by GitHub
parent c30b1fe893
commit f2bc1f0e11
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 39 additions and 32 deletions

View file

@ -25,10 +25,18 @@ __brkdiv0(void)
__emit(0xDEF9);
}
typedef struct _ARM_DIVRESULT
typedef union _ARM_DIVRESULT
{
UINT3264 quotient; /* to be returned in R0 */
UINT3264 modulus; /* to be returned in R1 */
#ifdef _USE_64_BITS_
unsigned int raw_data[4];
#else
unsigned long long raw_data;
#endif
struct
{
UINT3264 quotient; /* to be returned in R0(R0,R1) */
UINT3264 modulus; /* to be returned in R1(R2,R3) */
} data;
} ARM_DIVRESULT;
#ifndef _USE_64_BITS_
@ -36,9 +44,9 @@ __forceinline
#endif
void
__rt_div_worker(
ARM_DIVRESULT *result,
UINT3264 divisor,
UINT3264 dividend)
UINT3264 dividend,
ARM_DIVRESULT* result)
{
UINT3264 shift;
UINT3264 mask;
@ -70,8 +78,8 @@ __rt_div_worker(
if (divisor > dividend)
{
result->quotient = 0;
result->modulus = divisor;
result->data.quotient = 0;
result->data.modulus = divisor;
return;
}
@ -110,7 +118,6 @@ __rt_div_worker(
}
#endif // _SIGNED_DIV_
result->quotient = quotient;
result->modulus = dividend;
return;
result->data.quotient = quotient;
result->data.modulus = dividend;
}

View file

@ -13,14 +13,15 @@
#include "__rt_div_worker.h"
ARM_DIVRESULT
unsigned long long
__rt_sdiv(
int divisor,
int dividend)
{
ARM_DIVRESULT result;
__rt_sdiv_worker(&result, divisor, dividend);
return result;
__rt_sdiv_worker(divisor, dividend, &result);
return result.raw_data;
}

View file

@ -18,19 +18,18 @@
NESTED_ENTRY __rt_sdiv64
/* Allocate stack space and store parameters there */
stmdb sp!,{r0,r1,r2,r3,lr}
push {lr}
sub sp,sp,0x10
mov r12,sp
push {r12}
PROLOG_END
/* Load pointer to stack structure into R0 */
mov r0, sp
/* Call the C worker function */
adr lr, Return
b __rt_sdiv64_worker
bl __rt_sdiv64_worker
add sp,sp,0x04
Return
/* Move result data into the appropriate registers and return */
ldmia sp!,{r0,r1,r2,r3,pc}
pop {r0,r1,r2,r3,pc}
NESTED_END __rt_sdiv64
END

View file

@ -11,14 +11,15 @@
#include "__rt_div_worker.h"
ARM_DIVRESULT
unsigned long long
__rt_udiv(
unsigned int divisor,
unsigned int dividend)
{
ARM_DIVRESULT result;
__rt_udiv_worker(&result, divisor, dividend);
return result;
__rt_udiv_worker(divisor, dividend, &result);
return result.raw_data;
}

View file

@ -18,19 +18,18 @@
NESTED_ENTRY __rt_udiv64
/* Allocate stack space and store parameters there */
stmdb sp!,{r0,r1,r2,r3,lr}
push {lr}
sub sp,sp,0x10
mov r12,sp
push {r12}
PROLOG_END
/* Load pointer to stack structure into R0 */
mov r0, sp
/* Call the C worker function */
adr lr, Return
b __rt_udiv64_worker
bl __rt_udiv64_worker
add sp,sp,0x04
Return
/* Move result data into the appropriate registers and return */
ldmia sp!,{r0,r1,r2,r3,pc}
pop {r0,r1,r2,r3,pc}
NESTED_END __rt_udiv64
END