blob: 036a6f542f79311c1fa41997f42bd9ea7f8eb004 [file] [log] [blame]
//===-- aeabi_cdcmp.S - EABI cdcmp* implementation ------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "../assembly.h"
#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__
#error big endian support not implemented
#endif
#define APSR_Z (1 << 30)
#define APSR_C (1 << 29)
// void __aeabi_cdcmpeq(double a, double b) {
// if (isnan(a) || isnan(b)) {
// Z = 0; C = 1;
// } else {
// __aeabi_cdcmple(a, b);
// }
// }
.syntax unified
.p2align 2
DEFINE_COMPILERRT_FUNCTION(__aeabi_cdcmpeq)
push {r0-r3, lr}
bl __aeabi_cdcmpeq_check_nan
cmp r0, #1
pop {r0-r3, lr}
// NaN has been ruled out, so __aeabi_cdcmple can't trap
bne __aeabi_cdcmple
msr CPSR_f, #APSR_C
JMP(lr)
END_COMPILERRT_FUNCTION(__aeabi_cdcmpeq)
// void __aeabi_cdcmple(double a, double b) {
// if (__aeabi_dcmplt(a, b)) {
// Z = 0; C = 0;
// } else if (__aeabi_dcmpeq(a, b)) {
// Z = 1; C = 1;
// } else {
// Z = 0; C = 1;
// }
// }
.syntax unified
.p2align 2
DEFINE_COMPILERRT_FUNCTION(__aeabi_cdcmple)
// Per the RTABI, this function must preserve r0-r11.
// Save lr in the same instruction for compactness
push {r0-r3, lr}
bl __aeabi_dcmplt
cmp r0, #1
moveq ip, #0
beq 1f
ldm sp, {r0-r3}
bl __aeabi_dcmpeq
cmp r0, #1
moveq ip, #(APSR_C | APSR_Z)
movne ip, #(APSR_C)
1:
msr CPSR_f, ip
pop {r0-r3}
POP_PC()
END_COMPILERRT_FUNCTION(__aeabi_cdcmple)
// int __aeabi_cdrcmple(double a, double b) {
// return __aeabi_cdcmple(b, a);
// }
.syntax unified
.p2align 2
DEFINE_COMPILERRT_FUNCTION(__aeabi_cdrcmple)
// Swap r0 and r2
mov ip, r0
mov r0, r2
mov r2, ip
// Swap r1 and r3
mov ip, r1
mov r1, r3
mov r3, ip
b __aeabi_cdcmple
END_COMPILERRT_FUNCTION(__aeabi_cdrcmple)