xref: /netbsd-src/sys/external/bsd/compiler_rt/dist/lib/builtins/arm/aeabi_cfcmp.S (revision f6e43b3179e19718c2af5950ddbd1384060c23e7)
1//===-- aeabi_cfcmp.S - EABI cfcmp* implementation ------------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "../assembly.h"
11
12#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__
13#error big endian support not implemented
14#endif
15
16#define APSR_Z (1 << 30)
17#define APSR_C (1 << 29)
18
19// void __aeabi_cfcmpeq(float a, float b) {
20//   if (isnan(a) || isnan(b)) {
21//     Z = 0; C = 1;
22//   } else {
23//     __aeabi_cfcmple(a, b);
24//   }
25// }
26
27        .syntax unified
28        .p2align 2
29DEFINE_COMPILERRT_FUNCTION(__aeabi_cfcmpeq)
30        // Save ip to ensure stack alignment (could be any register)
31        push {r0-r3, ip, lr}
32        bl __aeabi_cfcmpeq_check_nan
33        cmp r0, #1
34        pop {r0-r3, ip, lr}
35
36        // NaN has been ruled out, so __aeabi_cfcmple can't trap
37        bne __aeabi_cfcmple
38
39        msr CPSR_f, #APSR_C
40        JMP(lr)
41END_COMPILERRT_FUNCTION(__aeabi_cfcmpeq)
42
43
44// void __aeabi_cfcmple(float a, float b) {
45//   if (__aeabi_fcmplt(a, b)) {
46//     Z = 0; C = 0;
47//   } else if (__aeabi_fcmpeq(a, b)) {
48//     Z = 1; C = 1;
49//   } else {
50//     Z = 0; C = 1;
51//   }
52// }
53
54        .syntax unified
55        .p2align 2
56DEFINE_COMPILERRT_FUNCTION(__aeabi_cfcmple)
57        // Per the RTABI, this function must preserve r0-r11.
58        // Save lr in the same instruction for compactness
59        // Save ip to ensure stack alignment (could be any register)
60        push {r0-r3, ip, lr}
61
62        bl __aeabi_fcmplt
63        cmp r0, #1
64        moveq ip, #0
65        beq 1f
66
67        ldm sp, {r0-r3}
68        bl __aeabi_fcmpeq
69        cmp r0, #1
70        moveq ip, #(APSR_C | APSR_Z)
71        movne ip, #(APSR_C)
72
731:
74        msr CPSR_f, ip
75        pop {r0-r3, ip}
76        POP_PC()
77END_COMPILERRT_FUNCTION(__aeabi_cfcmple)
78
79// int __aeabi_cfrcmple(float a, float b) {
80//   return __aeabi_cfcmple(b, a);
81// }
82
83        .syntax unified
84        .p2align 2
85DEFINE_COMPILERRT_FUNCTION(__aeabi_cfrcmple)
86        // Swap r0 and r1
87        mov ip, r0
88        mov r0, r1
89        mov r1, ip
90
91        b __aeabi_cfcmple
92END_COMPILERRT_FUNCTION(__aeabi_cfrcmple)
93
94