Index: head/contrib/compiler-rt/lib/builtins/arm/aeabi_idivmod.S =================================================================== --- head/contrib/compiler-rt/lib/builtins/arm/aeabi_idivmod.S (revision 316004) +++ head/contrib/compiler-rt/lib/builtins/arm/aeabi_idivmod.S (revision 316005) @@ -1,49 +1,58 @@ //===-- aeabi_idivmod.S - EABI idivmod 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" // struct { int quot, int rem} __aeabi_idivmod(int numerator, int denominator) { // int rem, quot; // quot = __divmodsi4(numerator, denominator, &rem); // return {quot, rem}; // } #if defined(__MINGW32__) #define __aeabi_idivmod __rt_sdiv #endif .syntax unified + .syntax unified + .text +#if defined(USE_THUMB_PROLOGUE) + .thumb +#endif .p2align 2 +#if defined(USE_THUMB_PROLOGUE) +DEFINE_COMPILERRT_THUMB_FUNCTION(__aeabi_idivmod) +#else DEFINE_COMPILERRT_FUNCTION(__aeabi_idivmod) -#if __ARM_ARCH_ISA_THUMB == 1 +#endif +#if defined(USE_THUMB_1) push {r0, r1, lr} bl SYMBOL_NAME(__divsi3) pop {r1, r2, r3} // now r0 = quot, r1 = num, r2 = denom muls r2, r2, r0 // r2 = quot * denom subs r1, r1, r2 JMP (r3) -#else +#else // defined(USE_THUMB_1) push { lr } sub sp, sp, #4 mov r2, sp #if defined(__MINGW32__) mov r3, r0 mov r0, r1 mov r1, r3 #endif bl SYMBOL_NAME(__divmodsi4) ldr r1, [sp] add sp, sp, #4 pop { pc } -#endif // __ARM_ARCH_ISA_THUMB == 1 +#endif // defined(USE_THUMB_1) END_COMPILERRT_FUNCTION(__aeabi_idivmod) NO_EXEC_STACK_DIRECTIVE Index: head/contrib/compiler-rt/lib/builtins/arm/aeabi_uidivmod.S =================================================================== --- head/contrib/compiler-rt/lib/builtins/arm/aeabi_uidivmod.S (revision 316004) +++ head/contrib/compiler-rt/lib/builtins/arm/aeabi_uidivmod.S (revision 316005) @@ -1,56 +1,64 @@ //===-- aeabi_uidivmod.S - EABI uidivmod 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" // struct { unsigned quot, unsigned rem} // __aeabi_uidivmod(unsigned numerator, unsigned denominator) { // unsigned rem, quot; // quot = __udivmodsi4(numerator, denominator, &rem); // return {quot, rem}; // } #if defined(__MINGW32__) #define __aeabi_uidivmod __rt_udiv #endif .syntax unified + .text +#if defined(USE_THUMB_PROLOGUE) + .thumb +#endif .p2align 2 +#if defined(USE_THUMB_PROLOGUE) +DEFINE_COMPILERRT_THUMB_FUNCTION(__aeabi_uidivmod) +#else DEFINE_COMPILERRT_FUNCTION(__aeabi_uidivmod) +#endif #if __ARM_ARCH_ISA_THUMB == 1 cmp r0, r1 bcc LOCAL_LABEL(case_denom_larger) push {r0, r1, lr} bl SYMBOL_NAME(__aeabi_uidiv) pop {r1, r2, r3} muls r2, r2, r0 // r2 = quot * denom subs r1, r1, r2 JMP (r3) LOCAL_LABEL(case_denom_larger): movs r1, r0 movs r0, #0 JMP (lr) #else push { lr } sub sp, sp, #4 mov r2, sp #if defined(__MINGW32__) mov r3, r0 mov r0, r1 mov r1, r3 #endif bl SYMBOL_NAME(__udivmodsi4) ldr r1, [sp] add sp, sp, #4 pop { pc } #endif END_COMPILERRT_FUNCTION(__aeabi_uidivmod) NO_EXEC_STACK_DIRECTIVE Index: head/contrib/compiler-rt/lib/builtins/arm/bswapdi2.S =================================================================== --- head/contrib/compiler-rt/lib/builtins/arm/bswapdi2.S (revision 316004) +++ head/contrib/compiler-rt/lib/builtins/arm/bswapdi2.S (revision 316005) @@ -1,50 +1,50 @@ //===------- bswapdi2 - Implement bswapdi2 --------------------------------===// // // 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" .syntax unified .text -#if __ARM_ARCH_ISA_THUMB == 2 +#if defined(USE_THUMB_PROLOGUE) .thumb #endif // // extern uint64_t __bswapdi2(uint64_t); // // Reverse all the bytes in a 64-bit integer. // .p2align 2 -#if __ARM_ARCH_ISA_THUMB == 2 +#if defined(USE_THUMB_PROLOGUE) DEFINE_COMPILERRT_THUMB_FUNCTION(__bswapdi2) #else DEFINE_COMPILERRT_FUNCTION(__bswapdi2) #endif #if __ARM_ARCH < 6 // before armv6 does not have "rev" instruction // r2 = rev(r0) eor r2, r0, r0, ror #16 bic r2, r2, #0xff0000 mov r2, r2, lsr #8 eor r2, r2, r0, ror #8 // r0 = rev(r1) eor r0, r1, r1, ror #16 bic r0, r0, #0xff0000 mov r0, r0, lsr #8 eor r0, r0, r1, ror #8 #else rev r2, r0 // r2 = rev(r0) rev r0, r1 // r0 = rev(r1) #endif mov r1, r2 // r1 = r2 = rev(r0) JMP(lr) END_COMPILERRT_FUNCTION(__bswapdi2) NO_EXEC_STACK_DIRECTIVE Index: head/contrib/compiler-rt/lib/builtins/arm/bswapsi2.S =================================================================== --- head/contrib/compiler-rt/lib/builtins/arm/bswapsi2.S (revision 316004) +++ head/contrib/compiler-rt/lib/builtins/arm/bswapsi2.S (revision 316005) @@ -1,42 +1,42 @@ //===------- bswapsi2 - Implement bswapsi2 --------------------------------===// // // 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" .syntax unified .text -#if __ARM_ARCH_ISA_THUMB == 2 +#if defined(USE_THUMB_PROLOGUE) .thumb #endif // // extern uint32_t __bswapsi2(uint32_t); // // Reverse all the bytes in a 32-bit integer. // .p2align 2 -#if __ARM_ARCH_ISA_THUMB == 2 +#if defined(USE_THUMB_PROLOGUE) DEFINE_COMPILERRT_THUMB_FUNCTION(__bswapsi2) #else DEFINE_COMPILERRT_FUNCTION(__bswapsi2) #endif #if __ARM_ARCH < 6 // before armv6 does not have "rev" instruction eor r1, r0, r0, ror #16 bic r1, r1, #0xff0000 mov r1, r1, lsr #8 eor r0, r1, r0, ror #8 #else rev r0, r0 #endif JMP(lr) END_COMPILERRT_FUNCTION(__bswapsi2) NO_EXEC_STACK_DIRECTIVE Index: head/contrib/compiler-rt/lib/builtins/arm/clzdi2.S =================================================================== --- head/contrib/compiler-rt/lib/builtins/arm/clzdi2.S (revision 316004) +++ head/contrib/compiler-rt/lib/builtins/arm/clzdi2.S (revision 316005) @@ -1,100 +1,100 @@ /* ===-- clzdi2.c - Implement __clzdi2 -------------------------------------=== * * 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. * * ===----------------------------------------------------------------------=== * * This file implements count leading zeros for 64bit arguments. * * ===----------------------------------------------------------------------=== */ #include "../assembly.h" .syntax unified .text -#if __ARM_ARCH_ISA_THUMB == 2 +#if defined(USE_THUMB_PROLOGUE) .thumb #endif .p2align 2 -#if __ARM_ARCH_ISA_THUMB == 2 +#if defined(USE_THUMB_PROLOGUE) DEFINE_COMPILERRT_THUMB_FUNCTION(__clzdi2) #else DEFINE_COMPILERRT_FUNCTION(__clzdi2) #endif #ifdef __ARM_FEATURE_CLZ #ifdef __ARMEB__ cmp r0, 0 itee ne clzne r0, r0 clzeq r0, r1 addeq r0, r0, 32 #else cmp r1, 0 itee ne clzne r0, r1 clzeq r0, r0 addeq r0, r0, 32 #endif JMP(lr) #else /* Assumption: n != 0 */ /* * r0: n * r1: upper half of n, overwritten after check * r1: count of leading zeros in n + 1 * r2: scratch register for shifted r0 */ #ifdef __ARMEB__ cmp r0, 0 moveq r0, r1 #else cmp r1, 0 movne r0, r1 #endif movne r1, 1 moveq r1, 33 /* * Basic block: * if ((r0 >> SHIFT) == 0) * r1 += SHIFT; * else * r0 >>= SHIFT; * for descending powers of two as SHIFT. */ #define BLOCK(shift) \ lsrs r2, r0, shift; \ movne r0, r2; \ addeq r1, shift \ BLOCK(16) BLOCK(8) BLOCK(4) BLOCK(2) /* * The basic block invariants at this point are (r0 >> 2) == 0 and * r0 != 0. This means 1 <= r0 <= 3 and 0 <= (r0 >> 1) <= 1. * * r0 | (r0 >> 1) == 0 | (r0 >> 1) == 1 | -(r0 >> 1) | 1 - (r0 >> 1) * ---+----------------+----------------+------------+-------------- * 1 | 1 | 0 | 0 | 1 * 2 | 0 | 1 | -1 | 0 * 3 | 0 | 1 | -1 | 0 * * The r1's initial value of 1 compensates for the 1 here. */ sub r0, r1, r0, lsr #1 JMP(lr) #endif // __ARM_FEATURE_CLZ END_COMPILERRT_FUNCTION(__clzdi2) NO_EXEC_STACK_DIRECTIVE Index: head/contrib/compiler-rt/lib/builtins/arm/clzsi2.S =================================================================== --- head/contrib/compiler-rt/lib/builtins/arm/clzsi2.S (revision 316004) +++ head/contrib/compiler-rt/lib/builtins/arm/clzsi2.S (revision 316005) @@ -1,79 +1,79 @@ /* ===-- clzsi2.c - Implement __clzsi2 -------------------------------------=== * * 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. * * ===----------------------------------------------------------------------=== * * This file implements count leading zeros for 32bit arguments. * * ===----------------------------------------------------------------------=== */ #include "../assembly.h" .syntax unified .text -#if __ARM_ARCH_ISA_THUMB == 2 +#if defined(USE_THUMB_PROLOGUE) .thumb #endif .p2align 2 -#if __ARM_ARCH_ISA_THUMB == 2 +#if defined(USE_THUMB_PROLOGUE) DEFINE_COMPILERRT_THUMB_FUNCTION(__clzsi2) #else DEFINE_COMPILERRT_FUNCTION(__clzsi2) #endif #ifdef __ARM_FEATURE_CLZ clz r0, r0 JMP(lr) #else /* Assumption: n != 0 */ /* * r0: n * r1: count of leading zeros in n + 1 * r2: scratch register for shifted r0 */ mov r1, 1 /* * Basic block: * if ((r0 >> SHIFT) == 0) * r1 += SHIFT; * else * r0 >>= SHIFT; * for descending powers of two as SHIFT. */ #define BLOCK(shift) \ lsrs r2, r0, shift; \ movne r0, r2; \ addeq r1, shift \ BLOCK(16) BLOCK(8) BLOCK(4) BLOCK(2) /* * The basic block invariants at this point are (r0 >> 2) == 0 and * r0 != 0. This means 1 <= r0 <= 3 and 0 <= (r0 >> 1) <= 1. * * r0 | (r0 >> 1) == 0 | (r0 >> 1) == 1 | -(r0 >> 1) | 1 - (r0 >> 1) * ---+----------------+----------------+------------+-------------- * 1 | 1 | 0 | 0 | 1 * 2 | 0 | 1 | -1 | 0 * 3 | 0 | 1 | -1 | 0 * * The r1's initial value of 1 compensates for the 1 here. */ sub r0, r1, r0, lsr #1 JMP(lr) #endif // __ARM_FEATURE_CLZ END_COMPILERRT_FUNCTION(__clzsi2) NO_EXEC_STACK_DIRECTIVE Index: head/contrib/compiler-rt/lib/builtins/arm/comparesf2.S =================================================================== --- head/contrib/compiler-rt/lib/builtins/arm/comparesf2.S (revision 316004) +++ head/contrib/compiler-rt/lib/builtins/arm/comparesf2.S (revision 316005) @@ -1,296 +1,310 @@ //===-- comparesf2.S - Implement single-precision soft-float comparisons --===// // // 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. // //===----------------------------------------------------------------------===// // // This file implements the following soft-fp_t comparison routines: // // __eqsf2 __gesf2 __unordsf2 // __lesf2 __gtsf2 // __ltsf2 // __nesf2 // // The semantics of the routines grouped in each column are identical, so there // is a single implementation for each, with multiple names. // // The routines behave as follows: // // __lesf2(a,b) returns -1 if a < b // 0 if a == b // 1 if a > b // 1 if either a or b is NaN // // __gesf2(a,b) returns -1 if a < b // 0 if a == b // 1 if a > b // -1 if either a or b is NaN // // __unordsf2(a,b) returns 0 if both a and b are numbers // 1 if either a or b is NaN // // Note that __lesf2( ) and __gesf2( ) are identical except in their handling of // NaN values. // //===----------------------------------------------------------------------===// #include "../assembly.h" -.syntax unified -#if __ARM_ARCH_ISA_THUMB == 2 -.thumb + .syntax unified + .text +#if defined(USE_THUMB_PROLOGUE) + .thumb #endif @ int __eqsf2(float a, float b) .p2align 2 +#if defined(USE_THUMB_PROLOGUE) +DEFINE_COMPILERRT_THUMB_FUNCTION(__eqsf2) +#else DEFINE_COMPILERRT_FUNCTION(__eqsf2) +#endif #if defined(COMPILER_RT_ARMHF_TARGET) vmov r0, s0 vmov r1, s1 #endif // Make copies of a and b with the sign bit shifted off the top. These will // be used to detect zeros and NaNs. #if __ARM_ARCH_ISA_THUMB == 1 push {r6, lr} lsls r2, r0, #1 lsls r3, r1, #1 #else mov r2, r0, lsl #1 mov r3, r1, lsl #1 #endif // We do the comparison in three stages (ignoring NaN values for the time // being). First, we orr the absolute values of a and b; this sets the Z // flag if both a and b are zero (of either sign). The shift of r3 doesn't // effect this at all, but it *does* make sure that the C flag is clear for // the subsequent operations. -#if __ARM_ARCH_ISA_THUMB == 1 +#if defined(USE_THUMB_1) lsrs r6, r3, #1 orrs r6, r2, r6 #else orrs r12, r2, r3, lsr #1 #endif // Next, we check if a and b have the same or different signs. If they have // opposite signs, this eor will set the N flag. -#if __ARM_ARCH_ISA_THUMB == 1 +#if defined(USE_THUMB_1) beq 1f movs r6, r0 eors r6, r1 1: #else it ne eorsne r12, r0, r1 #endif // If a and b are equal (either both zeros or bit identical; again, we're // ignoring NaNs for now), this subtract will zero out r0. If they have the // same sign, the flags are updated as they would be for a comparison of the // absolute values of a and b. -#if __ARM_ARCH_ISA_THUMB == 1 +#if defined(USE_THUMB_1) bmi 1f subs r0, r2, r3 1: #else it pl subspl r0, r2, r3 #endif // If a is smaller in magnitude than b and both have the same sign, place // the negation of the sign of b in r0. Thus, if both are negative and // a > b, this sets r0 to 0; if both are positive and a < b, this sets // r0 to -1. // // This is also done if a and b have opposite signs and are not both zero, // because in that case the subtract was not performed and the C flag is // still clear from the shift argument in orrs; if a is positive and b // negative, this places 0 in r0; if a is negative and b positive, -1 is // placed in r0. -#if __ARM_ARCH_ISA_THUMB == 1 +#if defined(USE_THUMB_1) bhs 1f // Here if a and b have the same sign and absA < absB, the result is thus // b < 0 ? 1 : -1. Same if a and b have the opposite sign (ignoring Nan). movs r0, #1 lsrs r1, #31 bne LOCAL_LABEL(CHECK_NAN) negs r0, r0 b LOCAL_LABEL(CHECK_NAN) 1: #else it lo mvnlo r0, r1, asr #31 #endif // If a is greater in magnitude than b and both have the same sign, place // the sign of b in r0. Thus, if both are negative and a < b, -1 is placed // in r0, which is the desired result. Conversely, if both are positive // and a > b, zero is placed in r0. -#if __ARM_ARCH_ISA_THUMB == 1 +#if defined(USE_THUMB_1) bls 1f // Here both have the same sign and absA > absB. movs r0, #1 lsrs r1, #31 beq LOCAL_LABEL(CHECK_NAN) negs r0, r0 1: #else it hi movhi r0, r1, asr #31 #endif // If you've been keeping track, at this point r0 contains -1 if a < b and // 0 if a >= b. All that remains to be done is to set it to 1 if a > b. // If a == b, then the Z flag is set, so we can get the correct final value // into r0 by simply or'ing with 1 if Z is clear. // For Thumb-1, r0 contains -1 if a < b, 0 if a > b and 0 if a == b. -#if __ARM_ARCH_ISA_THUMB != 1 +#if defined(USE_THUMB_1) it ne orrne r0, r0, #1 #endif // Finally, we need to deal with NaNs. If either argument is NaN, replace // the value in r0 with 1. -#if __ARM_ARCH_ISA_THUMB == 1 +#if defined(USE_THUMB_1) LOCAL_LABEL(CHECK_NAN): movs r6, #0xff lsls r6, #24 cmp r2, r6 bhi 1f cmp r3, r6 1: bls 2f movs r0, #1 2: pop {r6, pc} #else cmp r2, #0xff000000 ite ls cmpls r3, #0xff000000 movhi r0, #1 JMP(lr) #endif END_COMPILERRT_FUNCTION(__eqsf2) DEFINE_COMPILERRT_FUNCTION_ALIAS(__lesf2, __eqsf2) DEFINE_COMPILERRT_FUNCTION_ALIAS(__ltsf2, __eqsf2) DEFINE_COMPILERRT_FUNCTION_ALIAS(__nesf2, __eqsf2) @ int __gtsf2(float a, float b) .p2align 2 +#if defined(USE_THUMB) +DEFINE_COMPILERRT_THUMB_FUNCTION(__gtsf2) +#else DEFINE_COMPILERRT_FUNCTION(__gtsf2) +#endif // Identical to the preceding except in that we return -1 for NaN values. // Given that the two paths share so much code, one might be tempted to // unify them; however, the extra code needed to do so makes the code size // to performance tradeoff very hard to justify for such small functions. #if defined(COMPILER_RT_ARMHF_TARGET) vmov r0, s0 vmov r1, s1 #endif -#if __ARM_ARCH_ISA_THUMB == 1 +#if defined(USE_THUMB_1) push {r6, lr} lsls r2, r0, #1 lsls r3, r1, #1 lsrs r6, r3, #1 orrs r6, r2, r6 beq 1f movs r6, r0 eors r6, r1 1: bmi 2f subs r0, r2, r3 2: bhs 3f movs r0, #1 lsrs r1, #31 bne LOCAL_LABEL(CHECK_NAN_2) negs r0, r0 b LOCAL_LABEL(CHECK_NAN_2) 3: bls 4f movs r0, #1 lsrs r1, #31 beq LOCAL_LABEL(CHECK_NAN_2) negs r0, r0 4: LOCAL_LABEL(CHECK_NAN_2): movs r6, #0xff lsls r6, #24 cmp r2, r6 bhi 5f cmp r3, r6 5: bls 6f movs r0, #1 negs r0, r0 6: pop {r6, pc} #else mov r2, r0, lsl #1 mov r3, r1, lsl #1 orrs r12, r2, r3, lsr #1 it ne eorsne r12, r0, r1 it pl subspl r0, r2, r3 it lo mvnlo r0, r1, asr #31 it hi movhi r0, r1, asr #31 it ne orrne r0, r0, #1 cmp r2, #0xff000000 ite ls cmpls r3, #0xff000000 movhi r0, #-1 JMP(lr) #endif END_COMPILERRT_FUNCTION(__gtsf2) DEFINE_COMPILERRT_FUNCTION_ALIAS(__gesf2, __gtsf2) @ int __unordsf2(float a, float b) .p2align 2 +#if defined(USE_THUMB) +DEFINE_COMPILERRT_THUMB_FUNCTION(__unordsf2) +#else DEFINE_COMPILERRT_FUNCTION(__unordsf2) +#endif + #if defined(COMPILER_RT_ARMHF_TARGET) vmov r0, s0 vmov r1, s1 #endif // Return 1 for NaN values, 0 otherwise. lsls r2, r0, #1 lsls r3, r1, #1 movs r0, #0 -#if __ARM_ARCH_ISA_THUMB == 1 +#if defined(USE_THUMB_1) movs r1, #0xff lsls r1, #24 cmp r2, r1 bhi 1f cmp r3, r1 1: bls 2f movs r0, #1 2: #else cmp r2, #0xff000000 ite ls cmpls r3, #0xff000000 movhi r0, #1 #endif JMP(lr) END_COMPILERRT_FUNCTION(__unordsf2) #if defined(COMPILER_RT_ARMHF_TARGET) DEFINE_COMPILERRT_FUNCTION(__aeabi_fcmpum) vmov s0, r0 vmov s1, r1 b SYMBOL_NAME(__unordsf2) END_COMPILERRT_FUNCTION(__aeabi_fcmpum) #else DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_fcmpun, __unordsf2) #endif NO_EXEC_STACK_DIRECTIVE Index: head/contrib/compiler-rt/lib/builtins/arm/divmodsi4.S =================================================================== --- head/contrib/compiler-rt/lib/builtins/arm/divmodsi4.S (revision 316004) +++ head/contrib/compiler-rt/lib/builtins/arm/divmodsi4.S (revision 316005) @@ -1,77 +1,77 @@ /*===-- divmodsi4.S - 32-bit signed integer divide and modulus ------------===// * * 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. * *===----------------------------------------------------------------------===// * * This file implements the __divmodsi4 (32-bit signed integer divide and * modulus) function for the ARM architecture. A naive digit-by-digit * computation is employed for simplicity. * *===----------------------------------------------------------------------===*/ #include "../assembly.h" #define ESTABLISH_FRAME \ push {r4-r7, lr} ;\ add r7, sp, #12 #define CLEAR_FRAME_AND_RETURN \ pop {r4-r7, pc} .syntax unified .text -#if __ARM_ARCH_ISA_THUMB == 2 +#if defined(USE_THUMB_PROLOGUE) .thumb #endif @ int __divmodsi4(int divident, int divisor, int *remainder) @ Calculate the quotient and remainder of the (signed) division. The return @ value is the quotient, the remainder is placed in the variable. .p2align 3 -#if __ARM_ARCH_ISA_THUMB == 2 +#if defined(USE_THUMB_PROLOGUE) DEFINE_COMPILERRT_THUMB_FUNCTION(__divmodsi4) #else DEFINE_COMPILERRT_FUNCTION(__divmodsi4) #endif #if __ARM_ARCH_EXT_IDIV__ tst r1, r1 beq LOCAL_LABEL(divzero) mov r3, r0 sdiv r0, r3, r1 mls r1, r0, r1, r3 str r1, [r2] bx lr LOCAL_LABEL(divzero): mov r0, #0 bx lr #else ESTABLISH_FRAME // Set aside the sign of the quotient and modulus, and the address for the // modulus. eor r4, r0, r1 mov r5, r0 mov r6, r2 // Take the absolute value of a and b via abs(x) = (x^(x >> 31)) - (x >> 31). eor ip, r0, r0, asr #31 eor lr, r1, r1, asr #31 sub r0, ip, r0, asr #31 sub r1, lr, r1, asr #31 // Unsigned divmod: bl SYMBOL_NAME(__udivmodsi4) // Apply the sign of quotient and modulus ldr r1, [r6] eor r0, r0, r4, asr #31 eor r1, r1, r5, asr #31 sub r0, r0, r4, asr #31 sub r1, r1, r5, asr #31 str r1, [r6] CLEAR_FRAME_AND_RETURN #endif END_COMPILERRT_FUNCTION(__divmodsi4) NO_EXEC_STACK_DIRECTIVE Index: head/contrib/compiler-rt/lib/builtins/arm/divsi3.S =================================================================== --- head/contrib/compiler-rt/lib/builtins/arm/divsi3.S (revision 316004) +++ head/contrib/compiler-rt/lib/builtins/arm/divsi3.S (revision 316005) @@ -1,88 +1,88 @@ /*===-- divsi3.S - 32-bit signed integer divide ---------------------------===// * * 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. * *===----------------------------------------------------------------------===// * * This file implements the __divsi3 (32-bit signed integer divide) function * for the ARM architecture as a wrapper around the unsigned routine. * *===----------------------------------------------------------------------===*/ #include "../assembly.h" #define ESTABLISH_FRAME \ push {r4, r7, lr} ;\ add r7, sp, #4 #define CLEAR_FRAME_AND_RETURN \ pop {r4, r7, pc} - .syntax unified - .text -#if __ARM_ARCH_ISA_THUMB == 2 - .thumb + .syntax unified + .text +#if defined(USE_THUMB_PROLOGUE) + .thumb #endif .p2align 3 // Ok, APCS and AAPCS agree on 32 bit args, so it's safe to use the same routine. DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_idiv, __divsi3) @ int __divsi3(int divident, int divisor) @ Calculate and return the quotient of the (signed) division. -#if __ARM_ARCH_ISA_THUMB == 2 +#if defined(USE_THUMB_PROLOGUE) DEFINE_COMPILERRT_THUMB_FUNCTION(__divsi3) #else DEFINE_COMPILERRT_FUNCTION(__divsi3) #endif #if __ARM_ARCH_EXT_IDIV__ tst r1,r1 beq LOCAL_LABEL(divzero) sdiv r0, r0, r1 bx lr LOCAL_LABEL(divzero): mov r0,#0 bx lr #else ESTABLISH_FRAME // Set aside the sign of the quotient. # if __ARM_ARCH_ISA_THUMB == 1 movs r4, r0 eors r4, r1 # else eor r4, r0, r1 # endif // Take absolute value of a and b via abs(x) = (x^(x >> 31)) - (x >> 31). # if __ARM_ARCH_ISA_THUMB == 1 asrs r2, r0, #31 asrs r3, r1, #31 eors r0, r2 eors r1, r3 subs r0, r0, r2 subs r1, r1, r3 # else eor r2, r0, r0, asr #31 eor r3, r1, r1, asr #31 sub r0, r2, r0, asr #31 sub r1, r3, r1, asr #31 # endif // abs(a) / abs(b) bl SYMBOL_NAME(__udivsi3) // Apply sign of quotient to result and return. -# if __ARM_ARCH_ISA_THUMB == 1 +# if defined(USE_THUMB_1) asrs r4, #31 eors r0, r4 subs r0, r0, r4 # else eor r0, r0, r4, asr #31 sub r0, r0, r4, asr #31 # endif CLEAR_FRAME_AND_RETURN #endif END_COMPILERRT_FUNCTION(__divsi3) NO_EXEC_STACK_DIRECTIVE Index: head/contrib/compiler-rt/lib/builtins/arm/modsi3.S =================================================================== --- head/contrib/compiler-rt/lib/builtins/arm/modsi3.S (revision 316004) +++ head/contrib/compiler-rt/lib/builtins/arm/modsi3.S (revision 316005) @@ -1,66 +1,66 @@ /*===-- modsi3.S - 32-bit signed integer modulus --------------------------===// * * 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. * *===----------------------------------------------------------------------===// * * This file implements the __modsi3 (32-bit signed integer modulus) function * for the ARM architecture as a wrapper around the unsigned routine. * *===----------------------------------------------------------------------===*/ #include "../assembly.h" #define ESTABLISH_FRAME \ push {r4, r7, lr} ;\ add r7, sp, #4 #define CLEAR_FRAME_AND_RETURN \ pop {r4, r7, pc} .syntax unified .text -#if __ARM_ARCH_ISA_THUMB == 2 +#if defined(USE_THUMB_PROLOGUE) .thumb #endif @ int __modsi3(int divident, int divisor) @ Calculate and return the remainder of the (signed) division. .p2align 3 -#if __ARM_ARCH_ISA_THUMB == 2 +#if defined(USE_THUMB_PROLOGUE) DEFINE_COMPILERRT_THUMB_FUNCTION(__modsi3) #else DEFINE_COMPILERRT_FUNCTION(__modsi3) #endif #if __ARM_ARCH_EXT_IDIV__ tst r1, r1 beq LOCAL_LABEL(divzero) sdiv r2, r0, r1 mls r0, r2, r1, r0 bx lr LOCAL_LABEL(divzero): mov r0, #0 bx lr #else ESTABLISH_FRAME // Set aside the sign of the dividend. mov r4, r0 // Take absolute value of a and b via abs(x) = (x^(x >> 31)) - (x >> 31). eor r2, r0, r0, asr #31 eor r3, r1, r1, asr #31 sub r0, r2, r0, asr #31 sub r1, r3, r1, asr #31 // abs(a) % abs(b) bl SYMBOL_NAME(__umodsi3) // Apply sign of dividend to result and return. eor r0, r0, r4, asr #31 sub r0, r0, r4, asr #31 CLEAR_FRAME_AND_RETURN #endif END_COMPILERRT_FUNCTION(__modsi3) NO_EXEC_STACK_DIRECTIVE Index: head/contrib/compiler-rt/lib/builtins/arm/udivmodsi4.S =================================================================== --- head/contrib/compiler-rt/lib/builtins/arm/udivmodsi4.S (revision 316004) +++ head/contrib/compiler-rt/lib/builtins/arm/udivmodsi4.S (revision 316005) @@ -1,187 +1,186 @@ /*===-- udivmodsi4.S - 32-bit unsigned integer divide and modulus ---------===// * * 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. * *===----------------------------------------------------------------------===// * * This file implements the __udivmodsi4 (32-bit unsigned integer divide and * modulus) function for the ARM 32-bit architecture. * *===----------------------------------------------------------------------===*/ #include "../assembly.h" .syntax unified .text - -#if __ARM_ARCH_ISA_THUMB == 2 +#if defined(USE_THUMB_PROLOGUE) .thumb #endif @ unsigned int __udivmodsi4(unsigned int divident, unsigned int divisor, @ unsigned int *remainder) @ Calculate the quotient and remainder of the (unsigned) division. The return @ value is the quotient, the remainder is placed in the variable. .p2align 2 -#if __ARM_ARCH_ISA_THUMB == 2 +#if defined(USE_THUMB_PROLOGUE) DEFINE_COMPILERRT_THUMB_FUNCTION(__udivmodsi4) #else DEFINE_COMPILERRT_FUNCTION(__udivmodsi4) #endif #if __ARM_ARCH_EXT_IDIV__ tst r1, r1 beq LOCAL_LABEL(divby0) mov r3, r0 udiv r0, r3, r1 mls r1, r0, r1, r3 str r1, [r2] bx lr #else cmp r1, #1 bcc LOCAL_LABEL(divby0) beq LOCAL_LABEL(divby1) cmp r0, r1 bcc LOCAL_LABEL(quotient0) /* * Implement division using binary long division algorithm. * * r0 is the numerator, r1 the denominator. * * The code before JMP computes the correct shift I, so that * r0 and (r1 << I) have the highest bit set in the same position. * At the time of JMP, ip := .Ldiv0block - 12 * I. * This depends on the fixed instruction size of block. * For ARM mode, this is 12 Bytes, for THUMB mode 14 Bytes. * * block(shift) implements the test-and-update-quotient core. * It assumes (r0 << shift) can be computed without overflow and * that (r0 << shift) < 2 * r1. The quotient is stored in r3. */ # ifdef __ARM_FEATURE_CLZ clz ip, r0 clz r3, r1 /* r0 >= r1 implies clz(r0) <= clz(r1), so ip <= r3. */ sub r3, r3, ip -# if __ARM_ARCH_ISA_THUMB == 2 +# if defined(USE_THUMB_2) adr ip, LOCAL_LABEL(div0block) + 1 sub ip, ip, r3, lsl #1 # else adr ip, LOCAL_LABEL(div0block) # endif sub ip, ip, r3, lsl #2 sub ip, ip, r3, lsl #3 mov r3, #0 bx ip # else -# if __ARM_ARCH_ISA_THUMB == 2 +# if defined(USE_THUMB_2) # error THUMB mode requires CLZ or UDIV # endif str r4, [sp, #-8]! mov r4, r0 adr ip, LOCAL_LABEL(div0block) lsr r3, r4, #16 cmp r3, r1 movhs r4, r3 subhs ip, ip, #(16 * 12) lsr r3, r4, #8 cmp r3, r1 movhs r4, r3 subhs ip, ip, #(8 * 12) lsr r3, r4, #4 cmp r3, r1 movhs r4, r3 subhs ip, #(4 * 12) lsr r3, r4, #2 cmp r3, r1 movhs r4, r3 subhs ip, ip, #(2 * 12) /* Last block, no need to update r3 or r4. */ cmp r1, r4, lsr #1 subls ip, ip, #(1 * 12) ldr r4, [sp], #8 /* restore r4, we are done with it. */ mov r3, #0 JMP(ip) # endif #define IMM # #define block(shift) \ cmp r0, r1, lsl IMM shift; \ ITT(hs); \ WIDE(addhs) r3, r3, IMM (1 << shift); \ WIDE(subhs) r0, r0, r1, lsl IMM shift block(31) block(30) block(29) block(28) block(27) block(26) block(25) block(24) block(23) block(22) block(21) block(20) block(19) block(18) block(17) block(16) block(15) block(14) block(13) block(12) block(11) block(10) block(9) block(8) block(7) block(6) block(5) block(4) block(3) block(2) block(1) LOCAL_LABEL(div0block): block(0) str r0, [r2] mov r0, r3 JMP(lr) LOCAL_LABEL(quotient0): str r0, [r2] mov r0, #0 JMP(lr) LOCAL_LABEL(divby1): mov r3, #0 str r3, [r2] JMP(lr) #endif /* __ARM_ARCH_EXT_IDIV__ */ LOCAL_LABEL(divby0): mov r0, #0 #ifdef __ARM_EABI__ b __aeabi_idiv0 #else JMP(lr) #endif END_COMPILERRT_FUNCTION(__udivmodsi4) NO_EXEC_STACK_DIRECTIVE Index: head/contrib/compiler-rt/lib/builtins/arm/udivsi3.S =================================================================== --- head/contrib/compiler-rt/lib/builtins/arm/udivsi3.S (revision 316004) +++ head/contrib/compiler-rt/lib/builtins/arm/udivsi3.S (revision 316005) @@ -1,268 +1,267 @@ /*===-- udivsi3.S - 32-bit unsigned integer divide ------------------------===// * * 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. * *===----------------------------------------------------------------------===// * * This file implements the __udivsi3 (32-bit unsigned integer divide) * function for the ARM 32-bit architecture. * *===----------------------------------------------------------------------===*/ #include "../assembly.h" .syntax unified .text - -#if __ARM_ARCH_ISA_THUMB == 2 +#if defined(USE_THUMB_PROLOGUE) .thumb #endif .p2align 2 DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_uidiv, __udivsi3) @ unsigned int __udivsi3(unsigned int divident, unsigned int divisor) @ Calculate and return the quotient of the (unsigned) division. -#if __ARM_ARCH_ISA_THUMB == 2 +#if defined(USE_THUMB_PROLOGUE) DEFINE_COMPILERRT_THUMB_FUNCTION(__udivsi3) #else DEFINE_COMPILERRT_FUNCTION(__udivsi3) #endif #if __ARM_ARCH_EXT_IDIV__ tst r1, r1 beq LOCAL_LABEL(divby0) udiv r0, r0, r1 bx lr #else cmp r1, #1 bcc LOCAL_LABEL(divby0) -#if __ARM_ARCH_ISA_THUMB == 1 +#if defined(USE_THUMB_1) bne LOCAL_LABEL(num_neq_denom) JMP(lr) LOCAL_LABEL(num_neq_denom): #else IT(eq) JMPc(lr, eq) #endif cmp r0, r1 -#if __ARM_ARCH_ISA_THUMB == 1 +#if defined(USE_THUMB_1) bhs LOCAL_LABEL(num_ge_denom) movs r0, #0 JMP(lr) LOCAL_LABEL(num_ge_denom): #else ITT(cc) movcc r0, #0 JMPc(lr, cc) #endif /* * Implement division using binary long division algorithm. * * r0 is the numerator, r1 the denominator. * * The code before JMP computes the correct shift I, so that * r0 and (r1 << I) have the highest bit set in the same position. * At the time of JMP, ip := .Ldiv0block - 12 * I. * This depends on the fixed instruction size of block. * For ARM mode, this is 12 Bytes, for THUMB mode 14 Bytes. * * block(shift) implements the test-and-update-quotient core. * It assumes (r0 << shift) can be computed without overflow and * that (r0 << shift) < 2 * r1. The quotient is stored in r3. */ # if defined(__ARM_FEATURE_CLZ) clz ip, r0 clz r3, r1 /* r0 >= r1 implies clz(r0) <= clz(r1), so ip <= r3. */ sub r3, r3, ip -# if __ARM_ARCH_ISA_THUMB == 2 +# if defined(USE_THUMB_2) adr ip, LOCAL_LABEL(div0block) + 1 sub ip, ip, r3, lsl #1 # else adr ip, LOCAL_LABEL(div0block) # endif sub ip, ip, r3, lsl #2 sub ip, ip, r3, lsl #3 mov r3, #0 bx ip # else /* No CLZ Feature */ -# if __ARM_ARCH_ISA_THUMB == 2 +# if defined(USE_THUMB_2) # error THUMB mode requires CLZ or UDIV # endif -# if __ARM_ARCH_ISA_THUMB == 1 +# if defined(USE_THUMB_1) # define BLOCK_SIZE 10 # else # define BLOCK_SIZE 12 # endif mov r2, r0 -# if __ARM_ARCH_ISA_THUMB == 1 +# if defined(USE_THUMB_1) mov ip, r0 adr r0, LOCAL_LABEL(div0block) adds r0, #1 # else adr ip, LOCAL_LABEL(div0block) # endif lsrs r3, r2, #16 cmp r3, r1 -# if __ARM_ARCH_ISA_THUMB == 1 +# if defined(USE_THUMB_1) blo LOCAL_LABEL(skip_16) movs r2, r3 subs r0, r0, #(16 * BLOCK_SIZE) LOCAL_LABEL(skip_16): # else movhs r2, r3 subhs ip, ip, #(16 * BLOCK_SIZE) # endif lsrs r3, r2, #8 cmp r3, r1 -# if __ARM_ARCH_ISA_THUMB == 1 +# if defined(USE_THUMB_1) blo LOCAL_LABEL(skip_8) movs r2, r3 subs r0, r0, #(8 * BLOCK_SIZE) LOCAL_LABEL(skip_8): # else movhs r2, r3 subhs ip, ip, #(8 * BLOCK_SIZE) # endif lsrs r3, r2, #4 cmp r3, r1 -# if __ARM_ARCH_ISA_THUMB == 1 +# if defined(USE_THUMB_1) blo LOCAL_LABEL(skip_4) movs r2, r3 subs r0, r0, #(4 * BLOCK_SIZE) LOCAL_LABEL(skip_4): # else movhs r2, r3 subhs ip, #(4 * BLOCK_SIZE) # endif lsrs r3, r2, #2 cmp r3, r1 -# if __ARM_ARCH_ISA_THUMB == 1 +# if defined(USE_THUMB_1) blo LOCAL_LABEL(skip_2) movs r2, r3 subs r0, r0, #(2 * BLOCK_SIZE) LOCAL_LABEL(skip_2): # else movhs r2, r3 subhs ip, ip, #(2 * BLOCK_SIZE) # endif /* Last block, no need to update r2 or r3. */ -# if __ARM_ARCH_ISA_THUMB == 1 +# if defined(USE_THUMB_1) lsrs r3, r2, #1 cmp r3, r1 blo LOCAL_LABEL(skip_1) subs r0, r0, #(1 * BLOCK_SIZE) LOCAL_LABEL(skip_1): movs r2, r0 mov r0, ip movs r3, #0 JMP (r2) # else cmp r1, r2, lsr #1 subls ip, ip, #(1 * BLOCK_SIZE) movs r3, #0 JMP(ip) # endif # endif /* __ARM_FEATURE_CLZ */ #define IMM # /* due to the range limit of branch in Thumb1, we have to place the block closer */ LOCAL_LABEL(divby0): movs r0, #0 # if defined(__ARM_EABI__) bl __aeabi_idiv0 // due to relocation limit, can't use b. # endif JMP(lr) -#if __ARM_ARCH_ISA_THUMB == 1 +#if defined(USE_THUMB_1) #define block(shift) \ lsls r2, r1, IMM shift; \ cmp r0, r2; \ blo LOCAL_LABEL(block_skip_##shift); \ subs r0, r0, r2; \ LOCAL_LABEL(block_skip_##shift) :; \ adcs r3, r3 /* same as ((r3 << 1) | Carry). Carry is set if r0 >= r2. */ /* TODO: if current location counter is not not word aligned, we don't need the .p2align and nop */ /* Label div0block must be word-aligned. First align block 31 */ .p2align 2 nop /* Padding to align div0block as 31 blocks = 310 bytes */ #else #define block(shift) \ cmp r0, r1, lsl IMM shift; \ ITT(hs); \ WIDE(addhs) r3, r3, IMM (1 << shift); \ WIDE(subhs) r0, r0, r1, lsl IMM shift #endif block(31) block(30) block(29) block(28) block(27) block(26) block(25) block(24) block(23) block(22) block(21) block(20) block(19) block(18) block(17) block(16) block(15) block(14) block(13) block(12) block(11) block(10) block(9) block(8) block(7) block(6) block(5) block(4) block(3) block(2) block(1) LOCAL_LABEL(div0block): block(0) mov r0, r3 JMP(lr) #endif /* __ARM_ARCH_EXT_IDIV__ */ #if __ARM_ARCH_EXT_IDIV__ LOCAL_LABEL(divby0): mov r0, #0 # ifdef __ARM_EABI__ b __aeabi_idiv0 # else JMP(lr) # endif #endif END_COMPILERRT_FUNCTION(__udivsi3) NO_EXEC_STACK_DIRECTIVE Index: head/contrib/compiler-rt/lib/builtins/arm/umodsi3.S =================================================================== --- head/contrib/compiler-rt/lib/builtins/arm/umodsi3.S (revision 316004) +++ head/contrib/compiler-rt/lib/builtins/arm/umodsi3.S (revision 316005) @@ -1,164 +1,164 @@ /*===-- umodsi3.S - 32-bit unsigned integer modulus -----------------------===// * * 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. * *===----------------------------------------------------------------------===// * * This file implements the __umodsi3 (32-bit unsigned integer modulus) * function for the ARM 32-bit architecture. * *===----------------------------------------------------------------------===*/ #include "../assembly.h" .syntax unified .text -#if __ARM_ARCH_ISA_THUMB == 2 +#if defined(USE_THUMB_PROLOGUE) .thumb #endif @ unsigned int __umodsi3(unsigned int divident, unsigned int divisor) @ Calculate and return the remainder of the (unsigned) division. .p2align 2 -#if __ARM_ARCH_ISA_THUMB == 2 +#if defined(USE_THUMB_PROLOGUE) DEFINE_COMPILERRT_THUMB_FUNCTION(__umodsi3) #else DEFINE_COMPILERRT_FUNCTION(__umodsi3) #endif #if __ARM_ARCH_EXT_IDIV__ tst r1, r1 beq LOCAL_LABEL(divby0) udiv r2, r0, r1 mls r0, r2, r1, r0 bx lr #else cmp r1, #1 bcc LOCAL_LABEL(divby0) ITT(eq) moveq r0, #0 JMPc(lr, eq) cmp r0, r1 IT(cc) JMPc(lr, cc) /* * Implement division using binary long division algorithm. * * r0 is the numerator, r1 the denominator. * * The code before JMP computes the correct shift I, so that * r0 and (r1 << I) have the highest bit set in the same position. * At the time of JMP, ip := .Ldiv0block - 8 * I. * This depends on the fixed instruction size of block. * For ARM mode, this is 8 Bytes, for THUMB mode 10 Bytes. * * block(shift) implements the test-and-update-quotient core. * It assumes (r0 << shift) can be computed without overflow and * that (r0 << shift) < 2 * r1. The quotient is stored in r3. */ # ifdef __ARM_FEATURE_CLZ clz ip, r0 clz r3, r1 /* r0 >= r1 implies clz(r0) <= clz(r1), so ip <= r3. */ sub r3, r3, ip -# if __ARM_ARCH_ISA_THUMB == 2 +# if defined(USE_THUMB_2) adr ip, LOCAL_LABEL(div0block) + 1 sub ip, ip, r3, lsl #1 # else adr ip, LOCAL_LABEL(div0block) # endif sub ip, ip, r3, lsl #3 bx ip # else -# if __ARM_ARCH_ISA_THUMB == 2 +# if defined(USE_THUMB_2) # error THUMB mode requires CLZ or UDIV # endif mov r2, r0 adr ip, LOCAL_LABEL(div0block) lsr r3, r2, #16 cmp r3, r1 movhs r2, r3 subhs ip, ip, #(16 * 8) lsr r3, r2, #8 cmp r3, r1 movhs r2, r3 subhs ip, ip, #(8 * 8) lsr r3, r2, #4 cmp r3, r1 movhs r2, r3 subhs ip, #(4 * 8) lsr r3, r2, #2 cmp r3, r1 movhs r2, r3 subhs ip, ip, #(2 * 8) /* Last block, no need to update r2 or r3. */ cmp r1, r2, lsr #1 subls ip, ip, #(1 * 8) JMP(ip) # endif #define IMM # #define block(shift) \ cmp r0, r1, lsl IMM shift; \ IT(hs); \ WIDE(subhs) r0, r0, r1, lsl IMM shift block(31) block(30) block(29) block(28) block(27) block(26) block(25) block(24) block(23) block(22) block(21) block(20) block(19) block(18) block(17) block(16) block(15) block(14) block(13) block(12) block(11) block(10) block(9) block(8) block(7) block(6) block(5) block(4) block(3) block(2) block(1) LOCAL_LABEL(div0block): block(0) JMP(lr) #endif /* __ARM_ARCH_EXT_IDIV__ */ LOCAL_LABEL(divby0): mov r0, #0 #ifdef __ARM_EABI__ b __aeabi_idiv0 #else JMP(lr) #endif END_COMPILERRT_FUNCTION(__umodsi3) NO_EXEC_STACK_DIRECTIVE Index: head/contrib/compiler-rt/lib/builtins/assembly.h =================================================================== --- head/contrib/compiler-rt/lib/builtins/assembly.h (revision 316004) +++ head/contrib/compiler-rt/lib/builtins/assembly.h (revision 316005) @@ -1,172 +1,184 @@ /* ===-- assembly.h - compiler-rt assembler support macros -----------------=== * * 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. * * ===----------------------------------------------------------------------=== * * This file defines macros for use in compiler-rt assembler source. * This file is not part of the interface of this library. * * ===----------------------------------------------------------------------=== */ #ifndef COMPILERRT_ASSEMBLY_H #define COMPILERRT_ASSEMBLY_H #if defined(__POWERPC__) || defined(__powerpc__) || defined(__ppc__) #define SEPARATOR @ #else #define SEPARATOR ; #endif #if defined(__APPLE__) #define HIDDEN(name) .private_extern name #define LOCAL_LABEL(name) L_##name // tell linker it can break up file at label boundaries #define FILE_LEVEL_DIRECTIVE .subsections_via_symbols #define SYMBOL_IS_FUNC(name) #define CONST_SECTION .const #define NO_EXEC_STACK_DIRECTIVE #elif defined(__ELF__) #define HIDDEN(name) .hidden name #define LOCAL_LABEL(name) .L_##name #define FILE_LEVEL_DIRECTIVE #if defined(__arm__) #define SYMBOL_IS_FUNC(name) .type name,%function #else #define SYMBOL_IS_FUNC(name) .type name,@function #endif #define CONST_SECTION .section .rodata #if defined(__GNU__) || defined(__ANDROID__) || defined(__FreeBSD__) #define NO_EXEC_STACK_DIRECTIVE .section .note.GNU-stack,"",%progbits #else #define NO_EXEC_STACK_DIRECTIVE #endif #else // !__APPLE__ && !__ELF__ #define HIDDEN(name) #define LOCAL_LABEL(name) .L ## name #define FILE_LEVEL_DIRECTIVE #define SYMBOL_IS_FUNC(name) \ .def name SEPARATOR \ .scl 2 SEPARATOR \ .type 32 SEPARATOR \ .endef #define CONST_SECTION .section .rdata,"rd" #define NO_EXEC_STACK_DIRECTIVE #endif #if defined(__arm__) #if defined(__ARM_ARCH_4T__) || __ARM_ARCH >= 5 #define ARM_HAS_BX #endif #if !defined(__ARM_FEATURE_CLZ) && __ARM_ARCH_ISA_THUMB != 1 && \ (__ARM_ARCH >= 6 || (__ARM_ARCH == 5 && !defined(__ARM_ARCH_5__))) #define __ARM_FEATURE_CLZ #endif -#undef __ARM_ARCH_ISA_THUMB -#define __ARM_ARCH_ISA_THUMB 0 - #ifdef ARM_HAS_BX #define JMP(r) bx r #define JMPc(r, c) bx##c r #else #define JMP(r) mov pc, r #define JMPc(r, c) mov##c pc, r #endif // pop {pc} can't switch Thumb mode on ARMv4T #if __ARM_ARCH >= 5 #define POP_PC() pop {pc} #else #define POP_PC() \ pop {ip}; \ JMP(ip) #endif -#if __ARM_ARCH_ISA_THUMB == 2 +/* + * Determine actual [ARM][THUMB[1][2]] ISA using compiler predefined macros: + * - for '-mthumb -march=armv6' compiler defines '__thumb__' + * - for '-mthumb -march=armv7' compiler defines '__thumb__' and '__thumb2__' + */ +#if defined(__thumb2__) +#define USE_THUMB_2 1 +#elif defined(__thumb__) +#define USE_THUMB_1 1 +#endif + +#if defined(USE_THUMB_1) && defined(USE_THUMB_2) +#error "USE_THUMB_1 and USE_THUMB_2 can't be defined together." +#endif + +#if defined(USE_THUMB_1) || defined(USE_THUMB_1) +#define USE_THUMB_PROLOGUE 1 +#endif + +#if defined(USE_THUMB_2) #define IT(cond) it cond #define ITT(cond) itt cond +#define WIDE(op) op.w #else #define IT(cond) #define ITT(cond) -#endif - -#if __ARM_ARCH_ISA_THUMB == 2 -#define WIDE(op) op.w -#else #define WIDE(op) op #endif -#endif +#endif /* defined(__arm__) */ #define GLUE2(a, b) a##b #define GLUE(a, b) GLUE2(a, b) #define SYMBOL_NAME(name) GLUE(__USER_LABEL_PREFIX__, name) #ifdef VISIBILITY_HIDDEN #define DECLARE_SYMBOL_VISIBILITY(name) \ HIDDEN(SYMBOL_NAME(name)) SEPARATOR #else #define DECLARE_SYMBOL_VISIBILITY(name) #endif #define DEFINE_COMPILERRT_FUNCTION(name) \ FILE_LEVEL_DIRECTIVE SEPARATOR \ .globl SYMBOL_NAME(name) SEPARATOR \ SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \ DECLARE_SYMBOL_VISIBILITY(name) \ SYMBOL_NAME(name): #define DEFINE_COMPILERRT_THUMB_FUNCTION(name) \ FILE_LEVEL_DIRECTIVE SEPARATOR \ .globl SYMBOL_NAME(name) SEPARATOR \ SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \ DECLARE_SYMBOL_VISIBILITY(name) SEPARATOR \ .thumb_func SEPARATOR \ SYMBOL_NAME(name): #define DEFINE_COMPILERRT_PRIVATE_FUNCTION(name) \ FILE_LEVEL_DIRECTIVE SEPARATOR \ .globl SYMBOL_NAME(name) SEPARATOR \ SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \ HIDDEN(SYMBOL_NAME(name)) SEPARATOR \ SYMBOL_NAME(name): #define DEFINE_COMPILERRT_PRIVATE_FUNCTION_UNMANGLED(name) \ .globl name SEPARATOR \ SYMBOL_IS_FUNC(name) SEPARATOR \ HIDDEN(name) SEPARATOR \ name: #define DEFINE_COMPILERRT_FUNCTION_ALIAS(name, target) \ .globl SYMBOL_NAME(name) SEPARATOR \ SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \ DECLARE_SYMBOL_VISIBILITY(SYMBOL_NAME(name)) SEPARATOR \ .set SYMBOL_NAME(name), SYMBOL_NAME(target) SEPARATOR #if defined(__ARM_EABI__) #define DEFINE_AEABI_FUNCTION_ALIAS(aeabi_name, name) \ DEFINE_COMPILERRT_FUNCTION_ALIAS(aeabi_name, name) #else #define DEFINE_AEABI_FUNCTION_ALIAS(aeabi_name, name) #endif #ifdef __ELF__ #define END_COMPILERRT_FUNCTION(name) \ .size SYMBOL_NAME(name), . - SYMBOL_NAME(name) #else #define END_COMPILERRT_FUNCTION(name) #endif #endif /* COMPILERRT_ASSEMBLY_H */