From c615519f4d6c36e4357a9cd54e4e4b2b13188fbe Mon Sep 17 00:00:00 2001 From: yroux Date: Tue, 13 Jan 2015 07:43:13 +0000 Subject: [PATCH] 2015-01-13 Michael Collison Backport from trunk r211789, r211790, r211791, r211792, r211793, r211794, r211795, r211796, r211797. 2014-06-18 Charles Baylis * config/arm/bpabi.c (__gnu_uldivmod_helper): Remove. 2014-06-18 Charles Baylis * config/arm/bpabi-v6m.S (__aeabi_uldivmod): Perform division using __udivmoddi4. 2014-06-18 Charles Baylis * config/arm/bpabi.S (__aeabi_ldivmod, __aeabi_uldivmod, push_for_divide, pop_for_divide): Use .cfi_* directives for DWARF annotations. Fix DWARF information. 2014-06-18 Charles Baylis * config/arm/bpabi.S (__aeabi_ldivmod): Perform division using __udivmoddi4, and fixups for negative operands. 2014-06-18 Charles Baylis * config/arm/bpabi.S (__aeabi_ldivmod): Optimise stack manipulation. 2014-06-18 Charles Baylis * config/arm/bpabi.S (__aeabi_uldivmod): Perform division using call to __udivmoddi4. 2014-06-18 Charles Baylis * config/arm/bpabi.S (__aeabi_uldivmod): Optimise stack pointer manipulation. 2014-06-18 Charles Baylis * config/arm/bpabi.S (__aeabi_uldivmod, __aeabi_ldivmod): Add comment describing register usage on function entry and exit. 2014-06-18 Charles Baylis * config/arm/bpabi.S (__aeabi_uldivmod): Fix whitespace. (__aeabi_ldivmod): Fix whitespace. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/linaro/gcc-4_9-branch@219517 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog.linaro | 48 ++++++++++++++ libgcc/config/arm/bpabi-v6m.S | 2 +- libgcc/config/arm/bpabi.S | 150 +++++++++++++++++++++++++++++++++--------- libgcc/config/arm/bpabi.c | 14 ---- 4 files changed, 169 insertions(+), 45 deletions(-) diff --git a/gcc/ChangeLog.linaro b/gcc/ChangeLog.linaro index 29f70e5..4727415 100644 --- a/gcc/ChangeLog.linaro +++ b/gcc/ChangeLog.linaro @@ -1,3 +1,51 @@ +2015-01-13 Michael Collison + + Backport from trunk r211789, r211790, r211791, r211792, r211793, r211794, + r211795, r211796, r211797. + 2014-06-18 Charles Baylis + + * config/arm/bpabi.c (__gnu_uldivmod_helper): Remove. + + 2014-06-18 Charles Baylis + + * config/arm/bpabi-v6m.S (__aeabi_uldivmod): Perform division using + __udivmoddi4. + + 2014-06-18 Charles Baylis + + * config/arm/bpabi.S (__aeabi_ldivmod, __aeabi_uldivmod, + push_for_divide, pop_for_divide): Use .cfi_* directives for DWARF + annotations. Fix DWARF information. + + 2014-06-18 Charles Baylis + + * config/arm/bpabi.S (__aeabi_ldivmod): Perform division using + __udivmoddi4, and fixups for negative operands. + + 2014-06-18 Charles Baylis + + * config/arm/bpabi.S (__aeabi_ldivmod): Optimise stack manipulation. + + 2014-06-18 Charles Baylis + + * config/arm/bpabi.S (__aeabi_uldivmod): Perform division using call + to __udivmoddi4. + + 2014-06-18 Charles Baylis + + * config/arm/bpabi.S (__aeabi_uldivmod): Optimise stack pointer + manipulation. + + 2014-06-18 Charles Baylis + + * config/arm/bpabi.S (__aeabi_uldivmod, __aeabi_ldivmod): Add comment + describing register usage on function entry and exit. + + 2014-06-18 Charles Baylis + + * config/arm/bpabi.S (__aeabi_uldivmod): Fix whitespace. + (__aeabi_ldivmod): Fix whitespace. + 2015-01-13 Yvan Roux Backport from trunk r217593. diff --git a/libgcc/config/arm/bpabi-v6m.S b/libgcc/config/arm/bpabi-v6m.S index 0bf2e55..d549fa6 100644 --- a/libgcc/config/arm/bpabi-v6m.S +++ b/libgcc/config/arm/bpabi-v6m.S @@ -148,7 +148,7 @@ FUNC_START aeabi_uldivmod mov r0, sp push {r0, lr} ldr r0, [sp, #8] - bl SYM(__gnu_uldivmod_helper) + bl SYM(__udivmoddi4) ldr r3, [sp, #4] mov lr, r3 add sp, sp, #8 diff --git a/libgcc/config/arm/bpabi.S b/libgcc/config/arm/bpabi.S index 7772301..959ecb1 100644 --- a/libgcc/config/arm/bpabi.S +++ b/libgcc/config/arm/bpabi.S @@ -22,6 +22,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see . */ + .cfi_sections .debug_frame + #ifdef __ARM_EABI__ /* Some attributes that are common to all routines in this file. */ /* Tag_ABI_align_needed: This code does not require 8-byte @@ -120,49 +122,137 @@ ARM_FUNC_START aeabi_ulcmp #endif .endm -#ifdef L_aeabi_ldivmod +/* we can use STRD/LDRD on v5TE and later, and any Thumb-2 architecture. */ +#if (defined(__ARM_EABI__) \ + && (defined(__thumb2__) \ + || (__ARM_ARCH >= 5 && defined(__TARGET_FEATURE_DSP)))) +#define CAN_USE_LDRD 1 +#else +#define CAN_USE_LDRD 0 +#endif -ARM_FUNC_START aeabi_ldivmod - cfi_start __aeabi_ldivmod, LSYM(Lend_aeabi_ldivmod) - test_div_by_zero signed +/* set up stack from for call to __udivmoddi4. At the end of the macro the + stack is arranged as follows: + sp+12 / space for remainder + sp+8 \ (written by __udivmoddi4) + sp+4 lr + sp+0 sp+8 [rp (remainder pointer) argument for __udivmoddi4] - sub sp, sp, #8 -#if defined(__thumb2__) - mov ip, sp - push {ip, lr} + */ +.macro push_for_divide fname +#if defined(__thumb2__) && CAN_USE_LDRD + sub ip, sp, #8 + strd ip, lr, [sp, #-16]! #else - do_push {sp, lr} + sub sp, sp, #8 + do_push {sp, lr} #endif -98: cfi_push 98b - __aeabi_ldivmod, 0xe, -0xc, 0x10 - bl SYM(__gnu_ldivmod_helper) __PLT__ - ldr lr, [sp, #4] - add sp, sp, #8 - do_pop {r2, r3} + .cfi_adjust_cfa_offset 16 + .cfi_offset 14, -12 +.endm + +/* restore stack */ +.macro pop_for_divide + ldr lr, [sp, #4] +#if CAN_USE_LDRD + ldrd r2, r3, [sp, #8] + add sp, sp, #16 +#else + add sp, sp, #8 + do_pop {r2, r3} +#endif + .cfi_restore 14 + .cfi_adjust_cfa_offset 0 +.endm + +#ifdef L_aeabi_ldivmod + +/* Perform 64 bit signed division. + Inputs: + r0:r1 numerator + r2:r3 denominator + Outputs: + r0:r1 quotient + r2:r3 remainder + */ +ARM_FUNC_START aeabi_ldivmod + .cfi_startproc + test_div_by_zero signed + + push_for_divide __aeabi_ldivmod + cmp xxh, #0 + blt 1f + cmp yyh, #0 + blt 2f + /* arguments in (r0:r1), (r2:r3) and *sp */ + bl SYM(__udivmoddi4) __PLT__ + .cfi_remember_state + pop_for_divide + RET + +1: /* xxh:xxl is negative */ + .cfi_restore_state + negs xxl, xxl + sbc xxh, xxh, xxh, lsl #1 /* Thumb-2 has no RSC, so use X - 2X */ + cmp yyh, #0 + blt 3f + /* arguments in (r0:r1), (r2:r3) and *sp */ + bl SYM(__udivmoddi4) __PLT__ + .cfi_remember_state + pop_for_divide + negs xxl, xxl + sbc xxh, xxh, xxh, lsl #1 /* Thumb-2 has no RSC, so use X - 2X */ + negs yyl, yyl + sbc yyh, yyh, yyh, lsl #1 /* Thumb-2 has no RSC, so use X - 2X */ + RET + +2: /* only yyh:yyl is negative */ + .cfi_restore_state + negs yyl, yyl + sbc yyh, yyh, yyh, lsl #1 /* Thumb-2 has no RSC, so use X - 2X */ + /* arguments in (r0:r1), (r2:r3) and *sp */ + bl SYM(__udivmoddi4) __PLT__ + .cfi_remember_state + pop_for_divide + negs xxl, xxl + sbc xxh, xxh, xxh, lsl #1 /* Thumb-2 has no RSC, so use X - 2X */ + RET + +3: /* both xxh:xxl and yyh:yyl are negative */ + .cfi_restore_state + negs yyl, yyl + sbc yyh, yyh, yyh, lsl #1 /* Thumb-2 has no RSC, so use X - 2X */ + /* arguments in (r0:r1), (r2:r3) and *sp */ + bl SYM(__udivmoddi4) __PLT__ + pop_for_divide + negs yyl, yyl + sbc yyh, yyh, yyh, lsl #1 /* Thumb-2 has no RSC, so use X - 2X */ RET - cfi_end LSYM(Lend_aeabi_ldivmod) + + .cfi_endproc #endif /* L_aeabi_ldivmod */ #ifdef L_aeabi_uldivmod +/* Perform 64 bit signed division. + Inputs: + r0:r1 numerator + r2:r3 denominator + Outputs: + r0:r1 quotient + r2:r3 remainder + */ ARM_FUNC_START aeabi_uldivmod - cfi_start __aeabi_uldivmod, LSYM(Lend_aeabi_uldivmod) - test_div_by_zero unsigned + .cfi_startproc + test_div_by_zero unsigned - sub sp, sp, #8 -#if defined(__thumb2__) - mov ip, sp - push {ip, lr} -#else - do_push {sp, lr} -#endif -98: cfi_push 98b - __aeabi_uldivmod, 0xe, -0xc, 0x10 - bl SYM(__gnu_uldivmod_helper) __PLT__ - ldr lr, [sp, #4] - add sp, sp, #8 - do_pop {r2, r3} + push_for_divide __aeabi_uldivmod + /* arguments in (r0:r1), (r2:r3) and *sp */ + bl SYM(__udivmoddi4) __PLT__ + pop_for_divide RET - cfi_end LSYM(Lend_aeabi_uldivmod) + .cfi_endproc #endif /* L_aeabi_divmod */ diff --git a/libgcc/config/arm/bpabi.c b/libgcc/config/arm/bpabi.c index 7b155cc..e90d044 100644 --- a/libgcc/config/arm/bpabi.c +++ b/libgcc/config/arm/bpabi.c @@ -26,9 +26,6 @@ extern long long __divdi3 (long long, long long); extern unsigned long long __udivdi3 (unsigned long long, unsigned long long); extern long long __gnu_ldivmod_helper (long long, long long, long long *); -extern unsigned long long __gnu_uldivmod_helper (unsigned long long, - unsigned long long, - unsigned long long *); long long @@ -43,14 +40,3 @@ __gnu_ldivmod_helper (long long a, return quotient; } -unsigned long long -__gnu_uldivmod_helper (unsigned long long a, - unsigned long long b, - unsigned long long *remainder) -{ - unsigned long long quotient; - - quotient = __udivdi3 (a, b); - *remainder = a - b * quotient; - return quotient; -} -- 2.7.4