| 1 | // REQUIRES: arm-target-arch || armv6m-target-arch |
| 2 | // RUN: %clang_builtins %s %librt -o %t && %run %t |
| 3 | |
| 4 | #include <stdint.h> |
| 5 | #include <stdio.h> |
| 6 | #include <stdlib.h> |
| 7 | #include <math.h> |
| 8 | |
| 9 | #include "call_apsr.h" |
| 10 | |
| 11 | #if __arm__ |
| 12 | |
| 13 | extern __attribute__((pcs("aapcs" ))) void __aeabi_cfcmple(float a, float b); |
| 14 | extern __attribute__((pcs("aapcs" ))) void __aeabi_cfrcmple(float a, float b); |
| 15 | |
| 16 | int test__aeabi_cfcmple(float a, float b, int expected) |
| 17 | { |
| 18 | int32_t cpsr_value = call_apsr_f(a, b, __aeabi_cfcmple); |
| 19 | int32_t r_cpsr_value = call_apsr_f(b, a, __aeabi_cfrcmple); |
| 20 | |
| 21 | if (cpsr_value != r_cpsr_value) { |
| 22 | printf("error: __aeabi_cfcmple(%f, %f) != __aeabi_cfrcmple(%f, %f)\n" , a, b, b, a); |
| 23 | return 1; |
| 24 | } |
| 25 | |
| 26 | int expected_z, expected_c; |
| 27 | if (expected == -1) { |
| 28 | expected_z = 0; |
| 29 | expected_c = 0; |
| 30 | } else if (expected == 0) { |
| 31 | expected_z = 1; |
| 32 | expected_c = 1; |
| 33 | } else { |
| 34 | // a or b is NaN, or a > b |
| 35 | expected_z = 0; |
| 36 | expected_c = 1; |
| 37 | } |
| 38 | |
| 39 | union cpsr cpsr = { .value = cpsr_value }; |
| 40 | if (expected_z != cpsr.flags.z || expected_c != cpsr.flags.c) { |
| 41 | printf("error in __aeabi_cfcmple(%f, %f) => (Z = %d, C = %d), expected (Z = %d, C = %d)\n" , |
| 42 | a, b, cpsr.flags.z, cpsr.flags.c, expected_z, expected_c); |
| 43 | return 1; |
| 44 | } |
| 45 | |
| 46 | cpsr.value = r_cpsr_value; |
| 47 | if (expected_z != cpsr.flags.z || expected_c != cpsr.flags.c) { |
| 48 | printf("error in __aeabi_cfrcmple(%f, %f) => (Z = %d, C = %d), expected (Z = %d, C = %d)\n" , |
| 49 | a, b, cpsr.flags.z, cpsr.flags.c, expected_z, expected_c); |
| 50 | return 1; |
| 51 | } |
| 52 | return 0; |
| 53 | } |
| 54 | #endif |
| 55 | |
| 56 | int main() |
| 57 | { |
| 58 | #if __arm__ |
| 59 | if (test__aeabi_cfcmple(1.0, 1.0, 0)) |
| 60 | return 1; |
| 61 | if (test__aeabi_cfcmple(1234.567, 765.4321, 1)) |
| 62 | return 1; |
| 63 | if (test__aeabi_cfcmple(765.4321, 1234.567, -1)) |
| 64 | return 1; |
| 65 | if (test__aeabi_cfcmple(-123.0, -678.0, 1)) |
| 66 | return 1; |
| 67 | if (test__aeabi_cfcmple(-678.0, -123.0, -1)) |
| 68 | return 1; |
| 69 | if (test__aeabi_cfcmple(0.0, -0.0, 0)) |
| 70 | return 1; |
| 71 | if (test__aeabi_cfcmple(1.0, NAN, 1)) |
| 72 | return 1; |
| 73 | if (test__aeabi_cfcmple(NAN, 1.0, 1)) |
| 74 | return 1; |
| 75 | if (test__aeabi_cfcmple(NAN, NAN, 1)) |
| 76 | return 1; |
| 77 | #else |
| 78 | printf(format: "skipped\n" ); |
| 79 | #endif |
| 80 | return 0; |
| 81 | } |
| 82 | |