• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1//===-- aeabi_cdcmp.S - EABI cdcmp* 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_cdcmpeq(double a, double b) {
20//   if (isnan(a) || isnan(b)) {
21//     Z = 0; C = 1;
22//   } else {
23//     __aeabi_cdcmple(a, b);
24//   }
25// }
26
27        .syntax unified
28        .p2align 2
29DEFINE_COMPILERRT_FUNCTION(__aeabi_cdcmpeq)
30        push {r0-r3, lr}
31        bl __aeabi_cdcmpeq_check_nan
32        cmp r0, #1
33        pop {r0-r3, lr}
34
35        // NaN has been ruled out, so __aeabi_cdcmple can't trap
36        bne __aeabi_cdcmple
37
38        msr CPSR_f, #APSR_C
39        JMP(lr)
40END_COMPILERRT_FUNCTION(__aeabi_cdcmpeq)
41
42
43// void __aeabi_cdcmple(double a, double b) {
44//   if (__aeabi_dcmplt(a, b)) {
45//     Z = 0; C = 0;
46//   } else if (__aeabi_dcmpeq(a, b)) {
47//     Z = 1; C = 1;
48//   } else {
49//     Z = 0; C = 1;
50//   }
51// }
52
53        .syntax unified
54        .p2align 2
55DEFINE_COMPILERRT_FUNCTION(__aeabi_cdcmple)
56        // Per the RTABI, this function must preserve r0-r11.
57        // Save lr in the same instruction for compactness
58        push {r0-r3, lr}
59
60        bl __aeabi_dcmplt
61        cmp r0, #1
62        moveq ip, #0
63        beq 1f
64
65        ldm sp, {r0-r3}
66        bl __aeabi_dcmpeq
67        cmp r0, #1
68        moveq ip, #(APSR_C | APSR_Z)
69        movne ip, #(APSR_C)
70
711:
72        msr CPSR_f, ip
73        pop {r0-r3}
74        POP_PC()
75END_COMPILERRT_FUNCTION(__aeabi_cdcmple)
76
77// int __aeabi_cdrcmple(double a, double b) {
78//   return __aeabi_cdcmple(b, a);
79// }
80
81        .syntax unified
82        .p2align 2
83DEFINE_COMPILERRT_FUNCTION(__aeabi_cdrcmple)
84        // Swap r0 and r2
85        mov ip, r0
86        mov r0, r2
87        mov r2, ip
88
89        // Swap r1 and r3
90        mov ip, r1
91        mov r1, r3
92        mov r3, ip
93
94        b __aeabi_cdcmple
95END_COMPILERRT_FUNCTION(__aeabi_cdrcmple)
96
97NO_EXEC_STACK_DIRECTIVE
98
99