Home | History | Annotate | Line # | Download | only in arm
      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
     29 DEFINE_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)
     41 END_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
     56 DEFINE_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 
     73 1:
     74         msr CPSR_f, ip
     75         pop {r0-r3, ip}
     76         POP_PC()
     77 END_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
     85 DEFINE_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
     92 END_COMPILERRT_FUNCTION(__aeabi_cfrcmple)
     93 
     94