From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 11420 invoked by alias); 11 Mar 2013 20:54:18 -0000 Received: (qmail 11410 invoked by uid 22791); 11 Mar 2013 20:54:16 -0000 X-SWARE-Spam-Status: No, hits=-2.3 required=5.0 tests=AWL,BAYES_00 X-Spam-Check-By: sourceware.org Received: from toast.topped-with-meat.com (HELO topped-with-meat.com) (204.197.218.159) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 11 Mar 2013 20:54:11 +0000 Received: by topped-with-meat.com (Postfix, from userid 5281) id 2A99B2C08D; Mon, 11 Mar 2013 13:54:10 -0700 (PDT) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit From: Roland McGrath To: Joseph Myers Cc: libc-ports@sourceware.org Subject: [PATCH roland/arm-avoid-pc] ARM: Support avoiding pc as destination register. Message-Id: <20130311205410.2A99B2C08D@topped-with-meat.com> Date: Mon, 11 Mar 2013 20:54:00 -0000 X-CMAE-Score: 0 X-CMAE-Analysis: v=2.1 cv=LYSvtFvi c=1 sm=1 tr=0 a=WkljmVdYkabdwxfqvArNOQ==:117 a=14OXPxybAAAA:8 a=Cp02NCq-BFIA:10 a=Z6MIti7PxpgA:10 a=kj9zAlcOel0A:10 a=hOe2yjtxAAAA:8 a=lBSqbSby7r8A:10 a=_vp9jPSF4CocLalKbEUA:9 a=CjuIK1q_8ugA:10 X-IsSubscribed: yes Mailing-List: contact libc-ports-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: libc-ports-owner@sourceware.org X-SW-Source: 2013-03/txt/msg00097.txt.bz2 Updated for current trunk. Tested as before: On arm-linux-gnueabihf, I tested that this doesn't change the object code at all. I also tested the changes by hacking the local copy of arm-features.h to define ARM_ALWAYS_BX and verifying that there are no regressions (no failures at all) when running 'make check subdirs=string'. I'd be grateful for any suggestions to improve the efficiency of the code in the ARM_ALWAYS_BX case. The extra push/pop for the scratch register seems unavoidable without reworking the whole function in some way more complicated than I wanted to think about. But maybe ARM experts have better ideas. OK? Thanks, Roland ports/ChangeLog.arm 2013-03-11 Roland McGrath * sysdeps/arm/arm-features.h: Add comment about ARM_ALWAYS_BX. * sysdeps/arm/memcpy.S: Include . [ARM_ALWAYS_BX]: Avoid pc as destination. * sysdeps/arm/memmove.S: Likewise. --- a/ports/sysdeps/arm/arm-features.h +++ b/ports/sysdeps/arm/arm-features.h @@ -36,4 +36,8 @@ at runtime (or that we never care about its state) and so need not be checked for. */ +/* A more-specific arm-features.h file may define ARM_ALWAYS_BX to indicate + that instructions using pc as a destination register must never be used, + so a "bx" (or "blx") instruction is always required. */ + #endif /* arm-features.h */ --- a/ports/sysdeps/arm/memcpy.S +++ b/ports/sysdeps/arm/memcpy.S @@ -20,6 +20,7 @@ /* Thumb requires excessive IT insns here. */ #define NO_THUMB #include +#include /* * Data preload for architectures that support it (ARM V5TE and above) @@ -88,7 +89,12 @@ ENTRY(memcpy) CALGN( bcs 2f ) CALGN( adr r4, 6f ) CALGN( subs r2, r2, r3 ) @ C gets set +#ifndef ARM_ALWAYS_BX CALGN( add pc, r4, ip ) +#else + CALGN( add r4, r4, ip ) + CALGN( bx r4 ) +#endif PLD( pld [r1, #0] ) 2: PLD( subs r2, r2, #96 ) @@ -107,8 +113,16 @@ ENTRY(memcpy) 5: ands ip, r2, #28 rsb ip, ip, #32 +#ifndef ARM_ALWAYS_BX addne pc, pc, ip @ C is always clear here b 7f +#else + beq 7f + push {r10} + cfi_adjust_cfa_offset (4) + add r10, pc, ip + bx r10 +#endif 6: nop ldr r3, [r1], #4 ldr r4, [r1], #4 @@ -118,8 +132,13 @@ ENTRY(memcpy) ldr r8, [r1], #4 ldr lr, [r1], #4 +#ifndef ARM_ALWAYS_BX add pc, pc, ip nop +#else + add r10, pc, ip + bx r10 +#endif nop str r3, [r0], #4 str r4, [r0], #4 @@ -129,6 +148,11 @@ ENTRY(memcpy) str r8, [r0], #4 str lr, [r0], #4 +#ifdef ARM_ALWAYS_BX + pop {r10} + cfi_adjust_cfa_offset (-4) +#endif + CALGN( bcs 2b ) 7: pop {r5 - r8} @@ -146,7 +170,8 @@ ENTRY(memcpy) strcsb r4, [r0], #1 strcsb ip, [r0] -#if defined (__ARM_ARCH_4T__) && defined(__THUMB_INTERWORK__) +#if ((defined (__ARM_ARCH_4T__) && defined(__THUMB_INTERWORK__)) \ + || defined (ARM_ALWAYS_BX)) pop {r0, r4, lr} cfi_adjust_cfa_offset (-12) cfi_restore (r4) --- a/ports/sysdeps/arm/memmove.S +++ b/ports/sysdeps/arm/memmove.S @@ -20,6 +20,7 @@ /* Thumb requires excessive IT insns here. */ #define NO_THUMB #include +#include /* * Data preload for architectures that support it (ARM V5TE and above) @@ -104,7 +105,12 @@ ENTRY(memmove) CALGN( bcs 2f ) CALGN( adr r4, 6f ) CALGN( subs r2, r2, ip ) @ C is set here +#ifndef ARM_ALWAYS_BX CALGN( add pc, r4, ip ) +#else + CALGN( add r4, r4, ip ) + CALGN( bx r4 ) +#endif PLD( pld [r1, #-4] ) 2: PLD( subs r2, r2, #96 ) @@ -123,8 +129,16 @@ ENTRY(memmove) 5: ands ip, r2, #28 rsb ip, ip, #32 +#ifndef ARM_ALWAYS_BX addne pc, pc, ip @ C is always clear here b 7f +#else + beq 7f + push {r10} + cfi_adjust_cfa_offset (4) + add r10, pc, ip + bx r10 +#endif 6: nop ldr r3, [r1, #-4]! ldr r4, [r1, #-4]! @@ -134,8 +148,13 @@ ENTRY(memmove) ldr r8, [r1, #-4]! ldr lr, [r1, #-4]! +#ifndef ARM_ALWAYS_BX add pc, pc, ip nop +#else + add r10, pc, ip + bx r10 +#endif nop str r3, [r0, #-4]! str r4, [r0, #-4]! @@ -145,6 +164,11 @@ ENTRY(memmove) str r8, [r0, #-4]! str lr, [r0, #-4]! +#ifdef ARM_ALWAYS_BX + pop {r10} + cfi_adjust_cfa_offset (-4) +#endif + CALGN( bcs 2b ) 7: pop {r5 - r8} @@ -162,7 +186,8 @@ ENTRY(memmove) strcsb r4, [r0, #-1]! strcsb ip, [r0, #-1] -#if defined (__ARM_ARCH_4T__) && defined (__THUMB_INTERWORK__) +#if ((defined (__ARM_ARCH_4T__) && defined (__THUMB_INTERWORK__)) \ + || defined (ARM_ALWAYS_BX)) pop {r0, r4, lr} cfi_adjust_cfa_offset (-12) cfi_restore (r4)