[compiler-rt] r245648 - Implement __aeabi_c{d, f}{cmpeq, cmple, rcmple}.
Josh Gao via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 20 17:25:37 PDT 2015
Author: jmgao
Date: Thu Aug 20 19:25:37 2015
New Revision: 245648
URL: http://llvm.org/viewvc/llvm-project?rev=245648&view=rev
Log:
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
Added:
compiler-rt/trunk/lib/builtins/arm/aeabi_cdcmp.S
compiler-rt/trunk/lib/builtins/arm/aeabi_cdcmpeq_check_nan.c
compiler-rt/trunk/lib/builtins/arm/aeabi_cfcmp.S
compiler-rt/trunk/lib/builtins/arm/aeabi_cfcmpeq_check_nan.c
compiler-rt/trunk/test/builtins/Unit/arm/aeabi_cdcmpeq_test.c
compiler-rt/trunk/test/builtins/Unit/arm/aeabi_cdcmple_test.c
compiler-rt/trunk/test/builtins/Unit/arm/aeabi_cfcmpeq_test.c
compiler-rt/trunk/test/builtins/Unit/arm/aeabi_cfcmple_test.c
compiler-rt/trunk/test/builtins/Unit/arm/call_apsr.S
compiler-rt/trunk/test/builtins/Unit/arm/call_apsr.h
Modified:
compiler-rt/trunk/lib/builtins/CMakeLists.txt
compiler-rt/trunk/lib/builtins/assembly.h
Modified: compiler-rt/trunk/lib/builtins/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/builtins/CMakeLists.txt?rev=245648&r1=245647&r2=245648&view=diff
==============================================================================
--- compiler-rt/trunk/lib/builtins/CMakeLists.txt (original)
+++ compiler-rt/trunk/lib/builtins/CMakeLists.txt Thu Aug 20 19:25:37 2015
@@ -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
Added: compiler-rt/trunk/lib/builtins/arm/aeabi_cdcmp.S
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/builtins/arm/aeabi_cdcmp.S?rev=245648&view=auto
==============================================================================
--- compiler-rt/trunk/lib/builtins/arm/aeabi_cdcmp.S (added)
+++ compiler-rt/trunk/lib/builtins/arm/aeabi_cdcmp.S Thu Aug 20 19:25:37 2015
@@ -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)
+
Added: compiler-rt/trunk/lib/builtins/arm/aeabi_cdcmpeq_check_nan.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/builtins/arm/aeabi_cdcmpeq_check_nan.c?rev=245648&view=auto
==============================================================================
--- compiler-rt/trunk/lib/builtins/arm/aeabi_cdcmpeq_check_nan.c (added)
+++ compiler-rt/trunk/lib/builtins/arm/aeabi_cdcmpeq_check_nan.c Thu Aug 20 19:25:37 2015
@@ -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);
+}
Added: compiler-rt/trunk/lib/builtins/arm/aeabi_cfcmp.S
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/builtins/arm/aeabi_cfcmp.S?rev=245648&view=auto
==============================================================================
--- compiler-rt/trunk/lib/builtins/arm/aeabi_cfcmp.S (added)
+++ compiler-rt/trunk/lib/builtins/arm/aeabi_cfcmp.S Thu Aug 20 19:25:37 2015
@@ -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)
+
Added: compiler-rt/trunk/lib/builtins/arm/aeabi_cfcmpeq_check_nan.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/builtins/arm/aeabi_cfcmpeq_check_nan.c?rev=245648&view=auto
==============================================================================
--- compiler-rt/trunk/lib/builtins/arm/aeabi_cfcmpeq_check_nan.c (added)
+++ compiler-rt/trunk/lib/builtins/arm/aeabi_cfcmpeq_check_nan.c Thu Aug 20 19:25:37 2015
@@ -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);
+}
Modified: compiler-rt/trunk/lib/builtins/assembly.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/builtins/assembly.h?rev=245648&r1=245647&r2=245648&view=diff
==============================================================================
--- compiler-rt/trunk/lib/builtins/assembly.h (original)
+++ compiler-rt/trunk/lib/builtins/assembly.h Thu Aug 20 19:25:37 2015
@@ -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
Added: compiler-rt/trunk/test/builtins/Unit/arm/aeabi_cdcmpeq_test.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/builtins/Unit/arm/aeabi_cdcmpeq_test.c?rev=245648&view=auto
==============================================================================
--- compiler-rt/trunk/test/builtins/Unit/arm/aeabi_cdcmpeq_test.c (added)
+++ compiler-rt/trunk/test/builtins/Unit/arm/aeabi_cdcmpeq_test.c Thu Aug 20 19:25:37 2015
@@ -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;
+}
Added: compiler-rt/trunk/test/builtins/Unit/arm/aeabi_cdcmple_test.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/builtins/Unit/arm/aeabi_cdcmple_test.c?rev=245648&view=auto
==============================================================================
--- compiler-rt/trunk/test/builtins/Unit/arm/aeabi_cdcmple_test.c (added)
+++ compiler-rt/trunk/test/builtins/Unit/arm/aeabi_cdcmple_test.c Thu Aug 20 19:25:37 2015
@@ -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;
+}
Added: compiler-rt/trunk/test/builtins/Unit/arm/aeabi_cfcmpeq_test.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/builtins/Unit/arm/aeabi_cfcmpeq_test.c?rev=245648&view=auto
==============================================================================
--- compiler-rt/trunk/test/builtins/Unit/arm/aeabi_cfcmpeq_test.c (added)
+++ compiler-rt/trunk/test/builtins/Unit/arm/aeabi_cfcmpeq_test.c Thu Aug 20 19:25:37 2015
@@ -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;
+}
Added: compiler-rt/trunk/test/builtins/Unit/arm/aeabi_cfcmple_test.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/builtins/Unit/arm/aeabi_cfcmple_test.c?rev=245648&view=auto
==============================================================================
--- compiler-rt/trunk/test/builtins/Unit/arm/aeabi_cfcmple_test.c (added)
+++ compiler-rt/trunk/test/builtins/Unit/arm/aeabi_cfcmple_test.c Thu Aug 20 19:25:37 2015
@@ -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;
+}
Added: compiler-rt/trunk/test/builtins/Unit/arm/call_apsr.S
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/builtins/Unit/arm/call_apsr.S?rev=245648&view=auto
==============================================================================
--- compiler-rt/trunk/test/builtins/Unit/arm/call_apsr.S (added)
+++ compiler-rt/trunk/test/builtins/Unit/arm/call_apsr.S Thu Aug 20 19:25:37 2015
@@ -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)
Added: compiler-rt/trunk/test/builtins/Unit/arm/call_apsr.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/builtins/Unit/arm/call_apsr.h?rev=245648&view=auto
==============================================================================
--- compiler-rt/trunk/test/builtins/Unit/arm/call_apsr.h (added)
+++ compiler-rt/trunk/test/builtins/Unit/arm/call_apsr.h Thu Aug 20 19:25:37 2015
@@ -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
More information about the llvm-commits
mailing list