Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cherry-pick: Integrating Changes from PR #126277 and #127096 #136

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion compiler-rt/lib/builtins/arm/negdf2vfp.S
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ DEFINE_COMPILERRT_FUNCTION(__negdf2vfp)
#if defined(COMPILER_RT_ARMHF_TARGET)
vneg.f64 d0, d0
#else
eor r1, r1, #-2147483648 // flip sign bit on double in r0/r1 pair
#if _YUGA_BIG_ENDIAN
eor r0, r0, #0x80000000 // flip sign bit on double in r0/r1 pair
#else
eor r1, r1, #0x80000000 // flip sign bit on double in r0/r1 pair
#endif
#endif
bx lr
END_COMPILERRT_FUNCTION(__negdf2vfp)
Expand Down
11 changes: 11 additions & 0 deletions compiler-rt/test/builtins/Unit/arm/aeabi_idivmod_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,19 @@ int test__aeabi_idivmod(si_int a, si_int b,
{
si_int rem;
du_int ret = __aeabi_idivmod(a, b);
// __aeabi_idivmod actually returns a struct { quotient; remainder; } using
// value_in_regs calling convention. Due to the ABI rules, struct fields
// come in the same order regardless of endianness. However since the
// result is received here as a 64-bit integer, in which endianness does
// matter, the position of each component (quotient and remainder) varies
// depending on endianness.
# if _YUGA_BIG_ENDIAN
rem = ret & 0xFFFFFFFF;
si_int result = ret >> 32;
# else
rem = ret >> 32;
si_int result = ret & 0xFFFFFFFF;
# endif
if (result != expected_result) {
printf("error in __aeabi_idivmod: %d / %d = %d, expected %d\n",
a, b, result, expected_result);
Expand Down
11 changes: 11 additions & 0 deletions compiler-rt/test/builtins/Unit/arm/aeabi_uidivmod_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,19 @@ int test__aeabi_uidivmod(su_int a, su_int b,
su_int expected_result, su_int expected_rem)
{
du_int ret = __aeabi_uidivmod(a, b);
// __aeabi_uidivmod actually returns a struct { quotient; remainder; }
// using value_in_regs calling convention. Due to the ABI rules, struct
// fields come in the same order regardless of endianness. However since
// the result is received here as a 64-bit integer, in which endianness
// does matter, the position of each component (quotient and remainder)
// varies depending on endianness.
# if _YUGA_BIG_ENDIAN
su_int rem = ret & 0xFFFFFFFF;
si_int result = ret >> 32;
# else
su_int rem = ret >> 32;
si_int result = ret & 0xFFFFFFFF;
# endif

if (result != expected_result) {
printf("error in __aeabi_uidivmod: %u / %u = %u, expected %u\n",
Expand Down
23 changes: 20 additions & 3 deletions compiler-rt/test/builtins/Unit/arm/aeabi_uldivmod_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,37 @@ COMPILER_RT_ABI void /* __value_in_regs */ __aeabi_uldivmod(du_int a, du_int b);
int test_aeabi_uldivmod(du_int a, du_int b, du_int expected_q, du_int expected_r)
{
du_int q, r;
// __aeabi_uldivmod returns a struct { quotient; remainder; } using
// value_in_regs calling convention. Each field is a 64-bit integer, so the
// quotient resides in r0 and r1, while the remainder in r2 and r3. The
// byte order however depends on the endianness.
__asm__(
# if _YUGA_BIG_ENDIAN
"movs r1, %Q[a] \n"
"movs r0, %R[a] \n"
"movs r3, %Q[b] \n"
"movs r2, %R[b] \n"
# else
"movs r0, %Q[a] \n"
"movs r1, %R[a] \n"
"movs r2, %Q[b] \n"
"movs r3, %R[b] \n"
# endif
"bl __aeabi_uldivmod \n"
# if _YUGA_BIG_ENDIAN
"movs %Q[q], r1\n"
"movs %R[q], r0\n"
"movs %Q[r], r3\n"
"movs %R[r], r2\n"
# else
"movs %Q[q], r0\n"
"movs %R[q], r1\n"
"movs %Q[r], r2\n"
"movs %R[r], r3\n"
: [q] "=r" (q), [r] "=r"(r)
# endif
: [q] "=r"(q), [r] "=r"(r)
: [a] "r"(a), [b] "r"(b)
: "lr", "r0", "r1", "r2", "r3"
);
: "lr", "r0", "r1", "r2", "r3");
if (q != expected_q || r != expected_r)
printf("error in aeabi_uldivmod: %llX / %llX = %llX, R = %llX, expected %llX, %llX\n",
a, b, q, r, expected_q, expected_r);
Expand Down