| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |