1// REQUIRES-ANY: arm-target-arch,armv6m-target-arch
2// RUN: %arm_call_apsr -o %t.aspr.o
3// RUN: %clang_builtins %s  %t.aspr.o %librt -o %t && %run %t
4
5//===-- aeabi_cdcmple.c - Test __aeabi_cdcmple and __aeabi_cdrcmple -------===//
6//
7// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
8// See https://llvm.org/LICENSE.txt for license information.
9// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
10//
11//===----------------------------------------------------------------------===//
12//
13// This file tests __aeabi_cdcmple and __aeabi_cdrcmple for the compiler_rt
14// library.
15//
16//===----------------------------------------------------------------------===//
17
18#include <stdint.h>
19#include <stdio.h>
20#include <stdlib.h>
21#include <math.h>
22
23#include "call_apsr.h"
24
25#if __arm__
26
27extern __attribute__((pcs("aapcs"))) void __aeabi_cdcmple(double a, double b);
28extern __attribute__((pcs("aapcs"))) void __aeabi_cdrcmple(double a, double b);
29
30int test__aeabi_cdcmple(double a, double b, int expected)
31{
32    int32_t cpsr_value = call_apsr_d(a, b, __aeabi_cdcmple);
33    int32_t r_cpsr_value = call_apsr_d(b, a, __aeabi_cdrcmple);
34
35    if (cpsr_value != r_cpsr_value) {
36        printf("error: __aeabi_cdcmple(%f, %f) != __aeabi_cdrcmple(%f, %f)\n", a, b, b, a);
37        return 1;
38    }
39
40    int expected_z, expected_c;
41    if (expected == -1) {
42        expected_z = 0;
43        expected_c = 0;
44    } else if (expected == 0) {
45        expected_z = 1;
46        expected_c = 1;
47    } else {
48        // a or b is NaN, or a > b
49        expected_z = 0;
50        expected_c = 1;
51    }
52
53    union cpsr cpsr = { .value = cpsr_value };
54    if (expected_z != cpsr.flags.z || expected_c != cpsr.flags.c) {
55        printf("error in __aeabi_cdcmple(%f, %f) => (Z = %d, C = %d), expected (Z = %d, C = %d)\n",
56               a, b, cpsr.flags.z, cpsr.flags.c, expected_z, expected_c);
57        return 1;
58    }
59
60    cpsr.value = r_cpsr_value;
61    if (expected_z != cpsr.flags.z || expected_c != cpsr.flags.c) {
62        printf("error in __aeabi_cdrcmple(%f, %f) => (Z = %d, C = %d), expected (Z = %d, C = %d)\n",
63               a, b, cpsr.flags.z, cpsr.flags.c, expected_z, expected_c);
64        return 1;
65    }
66    return 0;
67}
68#endif
69
70int main()
71{
72#if __arm__
73    if (test__aeabi_cdcmple(1.0, 1.0, 0))
74        return 1;
75    if (test__aeabi_cdcmple(1234.567, 765.4321, 1))
76        return 1;
77    if (test__aeabi_cdcmple(765.4321, 1234.567, -1))
78        return 1;
79    if (test__aeabi_cdcmple(-123.0, -678.0, 1))
80        return 1;
81    if (test__aeabi_cdcmple(-678.0, -123.0, -1))
82        return 1;
83    if (test__aeabi_cdcmple(0.0, -0.0, 0))
84        return 1;
85    if (test__aeabi_cdcmple(1.0, NAN, 1))
86        return 1;
87    if (test__aeabi_cdcmple(NAN, 1.0, 1))
88        return 1;
89    if (test__aeabi_cdcmple(NAN, NAN, 1))
90        return 1;
91#else
92    printf("skipped\n");
93#endif
94    return 0;
95}
96