Index: lib/builtins/CMakeLists.txt =================================================================== --- lib/builtins/CMakeLists.txt +++ lib/builtins/CMakeLists.txt @@ -328,8 +328,11 @@ arm/aeabi_uldivmod.S) set(thumb1_EABI_SOURCES + arm/aeabi_cdcmp.S arm/aeabi_cdcmpeq_check_nan.c + arm/aeabi_cfcmp.S arm/aeabi_cfcmpeq_check_nan.c + arm/aeabi_dcmp.S arm/aeabi_div0.c arm/aeabi_drsub.c arm/aeabi_fcmp.S Index: lib/builtins/arm/aeabi_cdcmp.S =================================================================== --- lib/builtins/arm/aeabi_cdcmp.S +++ lib/builtins/arm/aeabi_cdcmp.S @@ -13,8 +13,10 @@ #error big endian support not implemented #endif -#define APSR_Z (1 << 30) -#define APSR_C (1 << 29) +#define APSR_Z_SHIFT 30 +#define APSR_C_SHIFT 29 +#define APSR_Z (1 << APSR_Z_SHIFT) +#define APSR_C (1 << APSR_C_SHIFT) // void __aeabi_cdcmpeq(double a, double b) { // if (isnan(a) || isnan(b)) { @@ -30,6 +32,17 @@ push {r0-r3, lr} bl __aeabi_cdcmpeq_check_nan cmp r0, #1 +#if __ARM_ARCH_ISA_THUMB == 1 + beq 1f + // NaN has been ruled out, so __aeabi_cdcmple can't trap + bl __aeabi_cdcmple + pop {r0-r3, pc} +1: + movs r0, #1 + lsls r0, #APSR_C_SHIFT + msr APSR, r0 + pop {r0-r3, pc} +#else pop {r0-r3, lr} // NaN has been ruled out, so __aeabi_cdcmple can't trap @@ -37,6 +50,7 @@ msr CPSR_f, #APSR_C JMP(lr) +#endif END_COMPILERRT_FUNCTION(__aeabi_cdcmpeq) @@ -55,6 +69,28 @@ DEFINE_COMPILERRT_FUNCTION(__aeabi_cdcmple) // Per the RTABI, this function must preserve r0-r11. // Save lr in the same instruction for compactness +#if __ARM_ARCH_ISA_THUMB == 1 + push {r0-r4, lr} + bl __aeabi_dcmplt + cmp r0, #1 + bne 1f + movs r4, #0 + b 2f +1: + mov r0, sp + movs r4, #1 + ldm r0, {r0-r3} + lsls r4, #(APSR_C_SHIFT) + bl __aeabi_dcmpeq + cmp r0, #1 + bne 2f + movs r0, #1 + lsls r0, #(APSR_Z_SHIFT) + orrs r4, r0 +2: + msr APSR, r4 + pop {r0,r4} +#else push {r0-r3, lr} bl __aeabi_dcmplt @@ -71,6 +107,7 @@ 1: msr CPSR_f, ip pop {r0-r3} +#endif POP_PC() END_COMPILERRT_FUNCTION(__aeabi_cdcmple) Index: lib/builtins/arm/aeabi_cfcmp.S =================================================================== --- lib/builtins/arm/aeabi_cfcmp.S +++ lib/builtins/arm/aeabi_cfcmp.S @@ -12,9 +12,10 @@ #if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ #error big endian support not implemented #endif - -#define APSR_Z (1 << 30) -#define APSR_C (1 << 29) +#define APSR_Z_SHIFT 30 +#define APSR_C_SHIFT 29 +#define APSR_Z (1 << APSR_Z_SHIFT) +#define APSR_C (1 << APSR_C_SHIFT) // void __aeabi_cfcmpeq(float a, float b) { // if (isnan(a) || isnan(b)) { @@ -30,6 +31,18 @@ push {r0-r3, lr} bl __aeabi_cfcmpeq_check_nan cmp r0, #1 +#if __ARM_ARCH_ISA_THUMB == 1 + beq 1f + + // NaN has been ruled out, so __aeabi_cfcmple can't trap + bl __aeabi_cfcmple + pop {r0-r3, pc} +1: + movs r0, #1 + lsls r0, #APSR_C_SHIFT + msr APSR, r0 + pop {r0-r3, pc} +#else pop {r0-r3, lr} // NaN has been ruled out, so __aeabi_cfcmple can't trap @@ -37,6 +50,7 @@ msr CPSR_f, #APSR_C JMP(lr) +#endif END_COMPILERRT_FUNCTION(__aeabi_cfcmpeq) @@ -55,6 +69,30 @@ DEFINE_COMPILERRT_FUNCTION(__aeabi_cfcmple) // Per the RTABI, this function must preserve r0-r11. // Save lr in the same instruction for compactness +#if __ARM_ARCH_ISA_THUMB == 1 + push {r0-r4, lr} + + bl __aeabi_fcmplt + cmp r0, #1 + + bne 1f + movs r4, #0 + b 2f +1: + mov r0, sp + movs r4, #1 + ldm r0, {r0-r3} + lsls r4, #APSR_C_SHIFT + bl __aeabi_fcmpeq + cmp r0, #1 + bne 2f + movs r0, #1 + lsls r0, #APSR_Z_SHIFT + orrs r4, r0 +2: + msr APSR, r4 + pop {r0-r4, pc} +#else push {r0-r3, lr} bl __aeabi_fcmplt @@ -72,6 +110,7 @@ msr CPSR_f, ip pop {r0-r3} POP_PC() +#endif END_COMPILERRT_FUNCTION(__aeabi_cfcmple) // int __aeabi_cfrcmple(float a, float b) { Index: lib/builtins/arm/aeabi_dcmp.S =================================================================== --- lib/builtins/arm/aeabi_dcmp.S +++ lib/builtins/arm/aeabi_dcmp.S @@ -26,10 +26,10 @@ bl SYMBOL_NAME(__ ## cond ## df2) SEPARATOR \ cmp r0, #0 SEPARATOR \ b ## cond 1f SEPARATOR \ - mov r0, #0 SEPARATOR \ + movs r0, #0 SEPARATOR \ pop { r4, pc } SEPARATOR \ 1: SEPARATOR \ - mov r0, #1 SEPARATOR \ + movs r0, #1 SEPARATOR \ pop { r4, pc } SEPARATOR \ END_COMPILERRT_FUNCTION(__aeabi_dcmp ## cond)