[Bultin][ARM] Make aeabi_uldivmod and aeabi_ldivmod be Thumb1 compatible

Summary:
in aeabi_ldivmod and uldivmod, using r6 instead of r12 as the temp reg due to limitation of Thumb1 ISA.
Now, all EABI sources are Thumb1 compatible.

Also added test cases by reusing the test cases from divmodsi4_test.c, udivmodsi4_test and udivmoddi4_test.c

Reviewers: rengolin, compnerd

Reviewed By: rengolin

Subscribers: javed.absar, aemerson, mgorny, llvm-commits

Differential Revision: https://reviews.llvm.org/D29226

llvm-svn: 293527
This commit is contained in:
Weiming Zhao 2017-01-30 18:48:05 +00:00
parent a846e0b082
commit a000b467d3
6 changed files with 20806 additions and 38 deletions

View File

@ -327,23 +327,6 @@ set(arm_EABI_SOURCES
arm/aeabi_uidivmod.S
arm/aeabi_uldivmod.S)
set(thumb1_EABI_SOURCES
arm/aeabi_cdcmp.S
arm/aeabi_cdcmpeq_check_nan.c
arm/aeabi_cfcmp.S
arm/aeabi_cfcmpeq_check_nan.c
arm/aeabi_dcmp.S
arm/aeabi_div0.c
arm/aeabi_drsub.c
arm/aeabi_fcmp.S
arm/aeabi_frsub.c
arm/aeabi_idivmod.S
arm/aeabi_memcmp.S
arm/aeabi_memcpy.S
arm/aeabi_memset.S
arm/aeabi_memmove.S
arm/aeabi_uidivmod.S)
set(arm_Thumb1_JT_SOURCES
arm/switch16.S
arm/switch32.S
@ -428,7 +411,7 @@ elseif(NOT WIN32)
set(thumb1_SOURCES
${thumb1_SOURCES}
${thumb1_EABI_SOURCES})
${arm_EABI_SOURCES})
endif()
set(aarch64_SOURCES

View File

@ -23,23 +23,23 @@
.syntax unified
.p2align 2
DEFINE_COMPILERRT_FUNCTION(__aeabi_ldivmod)
push {r11, lr}
push {r6, lr}
sub sp, sp, #16
add r12, sp, #8
str r12, [sp]
add r6, sp, #8
str r6, [sp]
#if defined(__MINGW32__)
mov r12, r0
mov r0, r2
mov r2, r12
mov r12, r1
mov r1, r3
mov r3, r12
movs r6, r0
movs r0, r2
movs r2, r6
movs r6, r1
movs r1, r3
movs r3, r6
#endif
bl SYMBOL_NAME(__divmoddi4)
ldr r2, [sp, #8]
ldr r3, [sp, #12]
add sp, sp, #16
pop {r11, pc}
pop {r6, pc}
END_COMPILERRT_FUNCTION(__aeabi_ldivmod)
NO_EXEC_STACK_DIRECTIVE

View File

@ -23,23 +23,23 @@
.syntax unified
.p2align 2
DEFINE_COMPILERRT_FUNCTION(__aeabi_uldivmod)
push {r11, lr}
push {r6, lr}
sub sp, sp, #16
add r12, sp, #8
str r12, [sp]
add r6, sp, #8
str r6, [sp]
#if defined(__MINGW32__)
mov r12, r0
mov r0, r2
mov r2, r12
mov r12, r1
mov r1, r3
mov r3, r12
movs r6, r0
movs r0, r2
movs r2, r6
movs r6, r1
movs r1, r3
movs r3, r6
#endif
bl SYMBOL_NAME(__udivmoddi4)
ldr r2, [sp, #8]
ldr r3, [sp, #12]
add sp, sp, #16
pop {r11, pc}
pop {r6, pc}
END_COMPILERRT_FUNCTION(__aeabi_uldivmod)
NO_EXEC_STACK_DIRECTIVE

View File

@ -0,0 +1,74 @@
//===-- aeabi_idivmod_test.c - Test __aeabi_idivmod -----------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file tests __aeabi_idivmod for the compiler_rt library.
//
//===----------------------------------------------------------------------===//
#include "int_lib.h"
#include <stdio.h>
// Based on divmodsi4_test.c
extern du_int __aeabi_idivmod(si_int a, si_int b);
int test__aeabi_idivmod(si_int a, si_int b,
si_int expected_result, si_int expected_rem)
{
si_int rem;
du_int ret = __aeabi_idivmod(a, b);
rem = ret >> 32;
si_int result = ret & 0xFFFFFFFF;
if (result != expected_result) {
printf("error in __aeabi_idivmod: %d / %d = %d, expected %d\n",
a, b, result, expected_result);
return 1;
}
if (rem != expected_rem) {
printf("error in __aeabi_idivmod: %d mod %d = %d, expected %d\n",
a, b, rem, expected_rem);
return 1;
}
return 0;
}
int main()
{
if (test__aeabi_idivmod(0, 1, 0, 0))
return 1;
if (test__aeabi_idivmod(0, -1, 0, 0))
return 1;
if (test__aeabi_idivmod(2, 1, 2, 0))
return 1;
if (test__aeabi_idivmod(2, -1, -2, 0))
return 1;
if (test__aeabi_idivmod(-2, 1, -2, 0))
return 1;
if (test__aeabi_idivmod(-2, -1, 2, 0))
return 1;
if (test__aeabi_idivmod(7, 5, 1, 2))
return 1;
if (test__aeabi_idivmod(-7, 5, -1, -2))
return 1;
if (test__aeabi_idivmod(19, 5, 3, 4))
return 1;
if (test__aeabi_idivmod(19, -5, -3, 4))
return 1;
if (test__aeabi_idivmod(0x80000000, 8, 0xf0000000, 0))
return 1;
if (test__aeabi_idivmod(0x80000007, 8, 0xf0000001, -1))
return 1;
return 0;
}

View File

@ -0,0 +1,61 @@
//===-- aeabi_uidivmod_test.c - Test __aeabi_uidivmod ---------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file tests __aeabi_uidivmod for the compiler_rt library.
//
//===----------------------------------------------------------------------===//
#include "int_lib.h"
#include <stdio.h>
// Based on udivmodsi4_test.c
extern du_int __aeabi_uidivmod(su_int a, su_int b);
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);
su_int rem = ret >> 32;
si_int result = ret & 0xFFFFFFFF;
if (result != expected_result) {
printf("error in __aeabi_uidivmod: %u / %u = %u, expected %u\n",
a, b, result, expected_result);
return 1;
}
if (rem != expected_rem) {
printf("error in __aeabi_uidivmod: %u mod %u = %u, expected %u\n",
a, b, rem, expected_rem);
return 1;
}
return 0;
}
int main()
{
if (test__aeabi_uidivmod(0, 1, 0, 0))
return 1;
if (test__aeabi_uidivmod(2, 1, 2, 0))
return 1;
if (test__aeabi_uidivmod(19, 5, 3, 4))
return 1;
if (test__aeabi_uidivmod(0x80000000, 8, 0x10000000, 0))
return 1;
if (test__aeabi_uidivmod(0x80000003, 8, 0x10000000, 3))
return 1;
return 0;
}

File diff suppressed because it is too large Load Diff