forked from OSchip/llvm-project
Implement __aeabi_c{d,f}{cmpeq,cmple,rcmple}.
Summary: Implement more missing ARM EABI runtime functions. Reviewers: rengolin, compnerd Subscribers: pirama, srhines, danalbert, aemerson, llvm-commits Differential Revision: http://reviews.llvm.org/D12089 llvm-svn: 245648
This commit is contained in:
parent
25fd09a756
commit
1108ae03b1
|
@ -189,6 +189,10 @@ set(i686_SOURCES
|
|||
set(arm_SOURCES
|
||||
arm/adddf3vfp.S
|
||||
arm/addsf3vfp.S
|
||||
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
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
//===-- aeabi_cdcmp.S - EABI cdcmp* implementation ------------------------===//
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__
|
||||
#error big endian support not implemented
|
||||
#endif
|
||||
|
||||
#define APSR_Z (1 << 30)
|
||||
#define APSR_C (1 << 29)
|
||||
|
||||
// void __aeabi_cdcmpeq(double a, double b) {
|
||||
// if (isnan(a) || isnan(b)) {
|
||||
// Z = 0; C = 1;
|
||||
// } else {
|
||||
// __aeabi_cdcmple(a, b);
|
||||
// }
|
||||
// }
|
||||
|
||||
.syntax unified
|
||||
.p2align 2
|
||||
DEFINE_COMPILERRT_FUNCTION(__aeabi_cdcmpeq)
|
||||
push {r0-r3, lr}
|
||||
bl __aeabi_cdcmpeq_check_nan
|
||||
cmp r0, #1
|
||||
pop {r0-r3, lr}
|
||||
|
||||
// NaN has been ruled out, so __aeabi_cdcmple can't trap
|
||||
bne __aeabi_cdcmple
|
||||
|
||||
msr CPSR_f, #APSR_C
|
||||
JMP(lr)
|
||||
END_COMPILERRT_FUNCTION(__aeabi_cdcmpeq)
|
||||
|
||||
|
||||
// void __aeabi_cdcmple(double a, double b) {
|
||||
// if (__aeabi_dcmplt(a, b)) {
|
||||
// Z = 0; C = 0;
|
||||
// } else if (__aeabi_dcmpeq(a, b)) {
|
||||
// Z = 1; C = 1;
|
||||
// } else {
|
||||
// Z = 0; C = 1;
|
||||
// }
|
||||
// }
|
||||
|
||||
.syntax unified
|
||||
.p2align 2
|
||||
DEFINE_COMPILERRT_FUNCTION(__aeabi_cdcmple)
|
||||
// Per the RTABI, this function must preserve r0-r11.
|
||||
// Save lr in the same instruction for compactness
|
||||
push {r0-r3, lr}
|
||||
|
||||
bl __aeabi_dcmplt
|
||||
cmp r0, #1
|
||||
moveq ip, #0
|
||||
beq 1f
|
||||
|
||||
ldm sp, {r0-r3}
|
||||
bl __aeabi_dcmpeq
|
||||
cmp r0, #1
|
||||
moveq ip, #(APSR_C | APSR_Z)
|
||||
movne ip, #(APSR_C)
|
||||
|
||||
1:
|
||||
msr CPSR_f, ip
|
||||
pop {r0-r3}
|
||||
POP_PC()
|
||||
END_COMPILERRT_FUNCTION(__aeabi_cdcmple)
|
||||
|
||||
// int __aeabi_cdrcmple(double a, double b) {
|
||||
// return __aeabi_cdcmple(b, a);
|
||||
// }
|
||||
|
||||
.syntax unified
|
||||
.p2align 2
|
||||
DEFINE_COMPILERRT_FUNCTION(__aeabi_cdrcmple)
|
||||
// Swap r0 and r2
|
||||
mov ip, r0
|
||||
mov r0, r2
|
||||
mov r2, ip
|
||||
|
||||
// Swap r1 and r3
|
||||
mov ip, r1
|
||||
mov r1, r3
|
||||
mov r3, ip
|
||||
|
||||
b __aeabi_cdcmple
|
||||
END_COMPILERRT_FUNCTION(__aeabi_cdrcmple)
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
//===-- lib/arm/aeabi_cdcmpeq_helper.c - Helper for cdcmpeq ---------------===//
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
__attribute__((pcs("aapcs")))
|
||||
__attribute__((visibility("hidden")))
|
||||
int __aeabi_cdcmpeq_check_nan(double a, double b) {
|
||||
return __builtin_isnan(a) || __builtin_isnan(b);
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
//===-- aeabi_cfcmp.S - EABI cfcmp* implementation ------------------------===//
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../assembly.h"
|
||||
|
||||
#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__
|
||||
#error big endian support not implemented
|
||||
#endif
|
||||
|
||||
#define APSR_Z (1 << 30)
|
||||
#define APSR_C (1 << 29)
|
||||
|
||||
// void __aeabi_cfcmpeq(float a, float b) {
|
||||
// if (isnan(a) || isnan(b)) {
|
||||
// Z = 0; C = 1;
|
||||
// } else {
|
||||
// __aeabi_cfcmple(a, b);
|
||||
// }
|
||||
// }
|
||||
|
||||
.syntax unified
|
||||
.p2align 2
|
||||
DEFINE_COMPILERRT_FUNCTION(__aeabi_cfcmpeq)
|
||||
push {r0-r3, lr}
|
||||
bl __aeabi_cfcmpeq_check_nan
|
||||
cmp r0, #1
|
||||
pop {r0-r3, lr}
|
||||
|
||||
// NaN has been ruled out, so __aeabi_cfcmple can't trap
|
||||
bne __aeabi_cfcmple
|
||||
|
||||
msr CPSR_f, #APSR_C
|
||||
JMP(lr)
|
||||
END_COMPILERRT_FUNCTION(__aeabi_cfcmpeq)
|
||||
|
||||
|
||||
// void __aeabi_cfcmple(float a, float b) {
|
||||
// if (__aeabi_fcmplt(a, b)) {
|
||||
// Z = 0; C = 0;
|
||||
// } else if (__aeabi_fcmpeq(a, b)) {
|
||||
// Z = 1; C = 1;
|
||||
// } else {
|
||||
// Z = 0; C = 1;
|
||||
// }
|
||||
// }
|
||||
|
||||
.syntax unified
|
||||
.p2align 2
|
||||
DEFINE_COMPILERRT_FUNCTION(__aeabi_cfcmple)
|
||||
// Per the RTABI, this function must preserve r0-r11.
|
||||
// Save lr in the same instruction for compactness
|
||||
push {r0-r3, lr}
|
||||
|
||||
bl __aeabi_fcmplt
|
||||
cmp r0, #1
|
||||
moveq ip, #0
|
||||
beq 1f
|
||||
|
||||
ldm sp, {r0-r3}
|
||||
bl __aeabi_fcmpeq
|
||||
cmp r0, #1
|
||||
moveq ip, #(APSR_C | APSR_Z)
|
||||
movne ip, #(APSR_C)
|
||||
|
||||
1:
|
||||
msr CPSR_f, ip
|
||||
pop {r0-r3}
|
||||
POP_PC()
|
||||
END_COMPILERRT_FUNCTION(__aeabi_cfcmple)
|
||||
|
||||
// int __aeabi_cfrcmple(float a, float b) {
|
||||
// return __aeabi_cfcmple(b, a);
|
||||
// }
|
||||
|
||||
.syntax unified
|
||||
.p2align 2
|
||||
DEFINE_COMPILERRT_FUNCTION(__aeabi_cfrcmple)
|
||||
// Swap r0 and r1
|
||||
mov ip, r0
|
||||
mov r0, r1
|
||||
mov r1, ip
|
||||
|
||||
b __aeabi_cfcmple
|
||||
END_COMPILERRT_FUNCTION(__aeabi_cfrcmple)
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
//===-- lib/arm/aeabi_cfcmpeq_helper.c - Helper for cdcmpeq ---------------===//
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
__attribute__((pcs("aapcs")))
|
||||
__attribute__((visibility("hidden")))
|
||||
int __aeabi_cfcmpeq_check_nan(float a, float b) {
|
||||
return __builtin_isnan(a) || __builtin_isnan(b);
|
||||
}
|
|
@ -73,6 +73,15 @@
|
|||
#define JMPc(r, c) mov##c pc, r
|
||||
#endif
|
||||
|
||||
// pop {pc} can't switch Thumb mode on ARMv4T
|
||||
#if __ARM_ARCH >= 5
|
||||
#define POP_PC() pop {pc}
|
||||
#else
|
||||
#define POP_PC() \
|
||||
pop {ip}; \
|
||||
JMP(ip)
|
||||
#endif
|
||||
|
||||
#if __ARM_ARCH_ISA_THUMB == 2
|
||||
#define IT(cond) it cond
|
||||
#define ITT(cond) itt cond
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
//===-- aeabi_cdcmpeq.c - Test __aeabi_cdcmpeq ----------------------------===//
|
||||
//
|
||||
// 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_cdcmpeq for the compiler_rt library.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#if __arm__
|
||||
#include "call_apsr.h"
|
||||
|
||||
extern __attribute__((pcs("aapcs"))) void __aeabi_cdcmpeq(double a, double b);
|
||||
|
||||
int test__aeabi_cdcmpeq(double a, double b, int expected)
|
||||
{
|
||||
uint32_t cpsr_value = call_apsr_d(a, b, __aeabi_cdcmpeq);
|
||||
union cpsr cpsr = { .value = cpsr_value };
|
||||
if (expected != cpsr.flags.z) {
|
||||
printf("error in __aeabi_cdcmpeq(%f, %f) => Z = %d, expected %d\n",
|
||||
a, b, cpsr.flags.z, expected);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
#if __arm__
|
||||
if (test__aeabi_cdcmpeq(1.0, 1.0, 1))
|
||||
return 1;
|
||||
if (test__aeabi_cdcmpeq(1234.567, 765.4321, 0))
|
||||
return 1;
|
||||
if (test__aeabi_cdcmpeq(-123.0, -678.0, 0))
|
||||
return 1;
|
||||
if (test__aeabi_cdcmpeq(0.0, -0.0, 1))
|
||||
return 1;
|
||||
if (test__aeabi_cdcmpeq(1.0, NAN, 0))
|
||||
return 1;
|
||||
if (test__aeabi_cdcmpeq(NAN, 1.0, 0))
|
||||
return 1;
|
||||
if (test__aeabi_cdcmpeq(NAN, NAN, 0))
|
||||
return 1;
|
||||
if (test__aeabi_cdcmpeq(INFINITY, 1.0, 0))
|
||||
return 1;
|
||||
if (test__aeabi_cdcmpeq(0.0, INFINITY, 0))
|
||||
return 1;
|
||||
if (test__aeabi_cdcmpeq(-INFINITY, 0.0, 0))
|
||||
return 1;
|
||||
if (test__aeabi_cdcmpeq(0.0, -INFINITY, 0))
|
||||
return 1;
|
||||
if (test__aeabi_cdcmpeq(INFINITY, INFINITY, 1))
|
||||
return 1;
|
||||
if (test__aeabi_cdcmpeq(-INFINITY, -INFINITY, 1))
|
||||
return 1;
|
||||
#else
|
||||
printf("skipped\n");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
//===-- aeabi_cdcmple.c - Test __aeabi_cdcmple and __aeabi_cdrcmple -------===//
|
||||
//
|
||||
// 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_cdcmple and __aeabi_cdrcmple for the compiler_rt
|
||||
// library.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "call_apsr.h"
|
||||
|
||||
#if __arm__
|
||||
|
||||
extern __attribute__((pcs("aapcs"))) void __aeabi_cdcmple(double a, double b);
|
||||
extern __attribute__((pcs("aapcs"))) void __aeabi_cdrcmple(double a, double b);
|
||||
|
||||
int test__aeabi_cdcmple(double a, double b, int expected)
|
||||
{
|
||||
int32_t cpsr_value = call_apsr_d(a, b, __aeabi_cdcmple);
|
||||
int32_t r_cpsr_value = call_apsr_d(b, a, __aeabi_cdrcmple);
|
||||
|
||||
if (cpsr_value != r_cpsr_value) {
|
||||
printf("error: __aeabi_cdcmple(%f, %f) != __aeabi_cdrcmple(%f, %f)\n", a, b, b, a);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int expected_z, expected_c;
|
||||
if (expected == -1) {
|
||||
expected_z = 0;
|
||||
expected_c = 0;
|
||||
} else if (expected == 0) {
|
||||
expected_z = 1;
|
||||
expected_c = 1;
|
||||
} else {
|
||||
// a or b is NaN, or a > b
|
||||
expected_z = 0;
|
||||
expected_c = 1;
|
||||
}
|
||||
|
||||
union cpsr cpsr = { .value = cpsr_value };
|
||||
if (expected_z != cpsr.flags.z || expected_c != cpsr.flags.c) {
|
||||
printf("error in __aeabi_cdcmple(%f, %f) => (Z = %d, C = %d), expected (Z = %d, C = %d)\n",
|
||||
a, b, cpsr.flags.z, cpsr.flags.c, expected_z, expected_c);
|
||||
return 1;
|
||||
}
|
||||
|
||||
cpsr.value = r_cpsr_value;
|
||||
if (expected_z != cpsr.flags.z || expected_c != cpsr.flags.c) {
|
||||
printf("error in __aeabi_cdrcmple(%f, %f) => (Z = %d, C = %d), expected (Z = %d, C = %d)\n",
|
||||
a, b, cpsr.flags.z, cpsr.flags.c, expected_z, expected_c);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
#if __arm__
|
||||
if (test__aeabi_cdcmple(1.0, 1.0, 0))
|
||||
return 1;
|
||||
if (test__aeabi_cdcmple(1234.567, 765.4321, 1))
|
||||
return 1;
|
||||
if (test__aeabi_cdcmple(765.4321, 1234.567, -1))
|
||||
return 1;
|
||||
if (test__aeabi_cdcmple(-123.0, -678.0, 1))
|
||||
return 1;
|
||||
if (test__aeabi_cdcmple(-678.0, -123.0, -1))
|
||||
return 1;
|
||||
if (test__aeabi_cdcmple(0.0, -0.0, 0))
|
||||
return 1;
|
||||
if (test__aeabi_cdcmple(1.0, NAN, 1))
|
||||
return 1;
|
||||
if (test__aeabi_cdcmple(NAN, 1.0, 1))
|
||||
return 1;
|
||||
if (test__aeabi_cdcmple(NAN, NAN, 1))
|
||||
return 1;
|
||||
#else
|
||||
printf("skipped\n");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
//===-- aeabi_cfcmpeq.c - Test __aeabi_cfcmpeq ----------------------------===//
|
||||
//
|
||||
// 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_cfcmpeq for the compiler_rt library.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#if __arm__
|
||||
#include "call_apsr.h"
|
||||
|
||||
extern __attribute__((pcs("aapcs"))) void __aeabi_cfcmpeq(float a, float b);
|
||||
|
||||
int test__aeabi_cfcmpeq(float a, float b, int expected)
|
||||
{
|
||||
uint32_t cpsr_value = call_apsr_f(a, b, __aeabi_cfcmpeq);
|
||||
union cpsr cpsr = { .value = cpsr_value };
|
||||
if (expected != cpsr.flags.z) {
|
||||
printf("error in __aeabi_cfcmpeq(%f, %f) => Z = %d, expected %d\n",
|
||||
a, b, cpsr.flags.z, expected);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
#if __arm__
|
||||
if (test__aeabi_cfcmpeq(1.0, 1.0, 1))
|
||||
return 1;
|
||||
if (test__aeabi_cfcmpeq(1234.567, 765.4321, 0))
|
||||
return 1;
|
||||
if (test__aeabi_cfcmpeq(-123.0, -678.0, 0))
|
||||
return 1;
|
||||
if (test__aeabi_cfcmpeq(0.0, -0.0, 1))
|
||||
return 1;
|
||||
if (test__aeabi_cfcmpeq(1.0, NAN, 0))
|
||||
return 1;
|
||||
if (test__aeabi_cfcmpeq(NAN, 1.0, 0))
|
||||
return 1;
|
||||
if (test__aeabi_cfcmpeq(NAN, NAN, 0))
|
||||
return 1;
|
||||
if (test__aeabi_cfcmpeq(INFINITY, 1.0, 0))
|
||||
return 1;
|
||||
if (test__aeabi_cfcmpeq(0.0, INFINITY, 0))
|
||||
return 1;
|
||||
if (test__aeabi_cfcmpeq(-INFINITY, 0.0, 0))
|
||||
return 1;
|
||||
if (test__aeabi_cfcmpeq(0.0, -INFINITY, 0))
|
||||
return 1;
|
||||
if (test__aeabi_cfcmpeq(INFINITY, INFINITY, 1))
|
||||
return 1;
|
||||
if (test__aeabi_cfcmpeq(-INFINITY, -INFINITY, 1))
|
||||
return 1;
|
||||
#else
|
||||
printf("skipped\n");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
//===-- aeabi_cfcmple.c - Test __aeabi_cfcmple and __aeabi_cfrcmple -------===//
|
||||
//
|
||||
// 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_cfcmple and __aeabi_cfrcmple for the compiler_rt
|
||||
// library.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "call_apsr.h"
|
||||
|
||||
#if __arm__
|
||||
|
||||
extern __attribute__((pcs("aapcs"))) void __aeabi_cfcmple(float a, float b);
|
||||
extern __attribute__((pcs("aapcs"))) void __aeabi_cfrcmple(float a, float b);
|
||||
|
||||
int test__aeabi_cfcmple(float a, float b, int expected)
|
||||
{
|
||||
int32_t cpsr_value = call_apsr_f(a, b, __aeabi_cfcmple);
|
||||
int32_t r_cpsr_value = call_apsr_f(b, a, __aeabi_cfrcmple);
|
||||
|
||||
if (cpsr_value != r_cpsr_value) {
|
||||
printf("error: __aeabi_cfcmple(%f, %f) != __aeabi_cfrcmple(%f, %f)\n", a, b, b, a);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int expected_z, expected_c;
|
||||
if (expected == -1) {
|
||||
expected_z = 0;
|
||||
expected_c = 0;
|
||||
} else if (expected == 0) {
|
||||
expected_z = 1;
|
||||
expected_c = 1;
|
||||
} else {
|
||||
// a or b is NaN, or a > b
|
||||
expected_z = 0;
|
||||
expected_c = 1;
|
||||
}
|
||||
|
||||
union cpsr cpsr = { .value = cpsr_value };
|
||||
if (expected_z != cpsr.flags.z || expected_c != cpsr.flags.c) {
|
||||
printf("error in __aeabi_cfcmple(%f, %f) => (Z = %d, C = %d), expected (Z = %d, C = %d)\n",
|
||||
a, b, cpsr.flags.z, cpsr.flags.c, expected_z, expected_c);
|
||||
return 1;
|
||||
}
|
||||
|
||||
cpsr.value = r_cpsr_value;
|
||||
if (expected_z != cpsr.flags.z || expected_c != cpsr.flags.c) {
|
||||
printf("error in __aeabi_cfrcmple(%f, %f) => (Z = %d, C = %d), expected (Z = %d, C = %d)\n",
|
||||
a, b, cpsr.flags.z, cpsr.flags.c, expected_z, expected_c);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
#if __arm__
|
||||
if (test__aeabi_cfcmple(1.0, 1.0, 0))
|
||||
return 1;
|
||||
if (test__aeabi_cfcmple(1234.567, 765.4321, 1))
|
||||
return 1;
|
||||
if (test__aeabi_cfcmple(765.4321, 1234.567, -1))
|
||||
return 1;
|
||||
if (test__aeabi_cfcmple(-123.0, -678.0, 1))
|
||||
return 1;
|
||||
if (test__aeabi_cfcmple(-678.0, -123.0, -1))
|
||||
return 1;
|
||||
if (test__aeabi_cfcmple(0.0, -0.0, 0))
|
||||
return 1;
|
||||
if (test__aeabi_cfcmple(1.0, NAN, 1))
|
||||
return 1;
|
||||
if (test__aeabi_cfcmple(NAN, 1.0, 1))
|
||||
return 1;
|
||||
if (test__aeabi_cfcmple(NAN, NAN, 1))
|
||||
return 1;
|
||||
#else
|
||||
printf("skipped\n");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
//===-- call_apsr.S - Helpers for ARM EABI floating point tests -----------===//
|
||||
//
|
||||
// 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 implements helpers for ARM EABI floating point tests for the
|
||||
// compiler_rt library.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "../../../../lib/builtins/assembly.h"
|
||||
|
||||
.syntax unified
|
||||
// __attribute__((pcs("aapcs")))
|
||||
// int32_t call_apsr_d(double a, double b, void(*fn)(double, double)) {
|
||||
// fn(a, b);
|
||||
// return apsr;
|
||||
// }
|
||||
|
||||
DEFINE_COMPILERRT_PRIVATE_FUNCTION(call_apsr_d)
|
||||
push {lr}
|
||||
ldr ip, [sp, #4]
|
||||
blx ip
|
||||
mrs r0, apsr
|
||||
pop {pc}
|
||||
END_COMPILERRT_FUNCTION(call_apsr_d)
|
||||
|
||||
// __attribute__((pcs("aapcs")))
|
||||
// int32_t call_apsr_f(float a, float b, void(*fn)(float, float)) {
|
||||
// fn(a, b);
|
||||
// return apsr;
|
||||
// }
|
||||
|
||||
DEFINE_COMPILERRT_PRIVATE_FUNCTION(call_apsr_f)
|
||||
push {lr}
|
||||
blx r2
|
||||
mrs r0, apsr
|
||||
pop {pc}
|
||||
END_COMPILERRT_FUNCTION(call_apsr_f)
|
|
@ -0,0 +1,39 @@
|
|||
//===-- call_apsr.h - Helpers for ARM EABI floating point tests -----------===//
|
||||
//
|
||||
// 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 declares helpers for ARM EABI floating point tests for the
|
||||
// compiler_rt library.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef CALL_APSR_H
|
||||
#define CALL_APSR_H
|
||||
|
||||
#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__
|
||||
#error big endian support not implemented
|
||||
#endif
|
||||
|
||||
union cpsr {
|
||||
struct {
|
||||
uint32_t filler: 28;
|
||||
uint32_t v: 1;
|
||||
uint32_t c: 1;
|
||||
uint32_t z: 1;
|
||||
uint32_t n: 1;
|
||||
} flags;
|
||||
uint32_t value;
|
||||
};
|
||||
|
||||
extern __attribute__((pcs("aapcs")))
|
||||
uint32_t call_apsr_f(float a, float b, __attribute__((pcs("aapcs"))) void (*fn)(float, float));
|
||||
|
||||
extern __attribute__((pcs("aapcs")))
|
||||
uint32_t call_apsr_d(double a, double b, __attribute__((pcs("aapcs"))) void (*fn)(double, double));
|
||||
|
||||
#endif // CALL_APSR_H
|
Loading…
Reference in New Issue