From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 27327 invoked by alias); 27 Feb 2013 03:17:08 -0000 Received: (qmail 27175 invoked by uid 22791); 27 Feb 2013 03:17:04 -0000 X-SWARE-Spam-Status: No, hits=-5.2 required=5.0 tests=AWL,BAYES_00,DKIM_SIGNED,DKIM_VALID,FREEMAIL_ENVFROM_END_DIGIT,FREEMAIL_FROM,KHOP_RCVD_TRUST,KHOP_SPAMHAUS_DROP,KHOP_THREADED,RCVD_IN_DNSWL_LOW,RCVD_IN_HOSTKARMA_YE,TW_DM X-Spam-Check-By: sourceware.org Received: from mail-pa0-f45.google.com (HELO mail-pa0-f45.google.com) (209.85.220.45) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 27 Feb 2013 03:16:52 +0000 Received: by mail-pa0-f45.google.com with SMTP id kl14so138132pab.4 for ; Tue, 26 Feb 2013 19:16:51 -0800 (PST) X-Received: by 10.68.230.193 with SMTP id ta1mr998630pbc.103.1361935011281; Tue, 26 Feb 2013 19:16:51 -0800 (PST) Received: from pebble.twiddle.net (50-194-63-110-static.hfc.comcastbusiness.net. [50.194.63.110]) by mx.google.com with ESMTPS id pp1sm265271pac.7.2013.02.26.19.16.49 (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Tue, 26 Feb 2013 19:16:50 -0800 (PST) From: Richard Henderson To: libc-ports@sourceware.org Cc: Joseph Myers Subject: [PATCH 11/26] arm: Introduce and use NEGOFF series of macros Date: Wed, 27 Feb 2013 03:17:00 -0000 Message-Id: <1361934986-17018-12-git-send-email-rth@twiddle.net> In-Reply-To: <1361934986-17018-1-git-send-email-rth@twiddle.net> References: <1361934986-17018-1-git-send-email-rth@twiddle.net> 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-02/txt/msg00094.txt.bz2 There are several places in which we access negative offsets from the thread-pointer, but thumb2 only supports positive offsets in memory references. Avoid duplicating the rather large macros in which these references are embedded by abstracting out the operation. --- * sysdeps/arm/sysdep.h (NEGOFF_ADJ_BASE): New macro. (NEGOFF_ADJ_BASE2, NEGOFF_OFF1, NEGOFF_OFF2): New macros. * sysdeps/unix/sysv/linux/arm/clone.S (__clone): Use them. * sysdeps/unix/sysv/linux/arm/nptl/vfork.S: Likewise. * sysdeps/unix/sysv/linux/arm/nptl/pt-vfork.S: Likewise. * sysdeps/unix/sysv/linux/arm/nptl/sysdep-cancel.h (SINGLE_THREAD_P): Likewise. --- ports/sysdeps/arm/sysdep.h | 16 ++++++++++++++++ ports/sysdeps/unix/sysv/linux/arm/clone.S | 5 +++-- ports/sysdeps/unix/sysv/linux/arm/nptl/pt-vfork.S | 11 ++++++----- .../sysdeps/unix/sysv/linux/arm/nptl/sysdep-cancel.h | 19 ++++++++++--------- ports/sysdeps/unix/sysv/linux/arm/nptl/vfork.S | 14 ++++++++------ 5 files changed, 43 insertions(+), 22 deletions(-) diff --git a/ports/sysdeps/arm/sysdep.h b/ports/sysdeps/arm/sysdep.h index b7ba9b1..2d40823 100644 --- a/ports/sysdeps/arm/sysdep.h +++ b/ports/sysdeps/arm/sysdep.h @@ -147,4 +147,20 @@ 99: OP R, [pc, T] #endif +/* Cope with negative memory offsets, which thumb can't encode. + Use NEGOFF_ADJ_BASE to (conditionally) alter the base register, + and then NEGOFF_OFF1 to use 0 for thumb and the offset for arm, + or NEGOFF_OFF2 to use A-B for thumb and A for arm. */ +#ifdef __thumb2__ +# define NEGOFF_ADJ_BASE(R, OFF) add R, R, $OFF +# define NEGOFF_ADJ_BASE2(D, S, OFF) add D, S, $OFF +# define NEGOFF_OFF1(R, OFF) [R] +# define NEGOFF_OFF2(R, OFFA, OFFB) [R, $((OFFA) - (OFFB))] +#else +# define NEGOFF_ADJ_BASE(R, OFF) +# define NEGOFF_ADJ_BASE2(D, S, OFF) mov D, S +# define NEGOFF_OFF1(R, OFF) [R, $OFF] +# define NEGOFF_OFF2(R, OFFA, OFFB) [R, $OFFA] +#endif + #endif /* __ASSEMBLER__ */ diff --git a/ports/sysdeps/unix/sysv/linux/arm/clone.S b/ports/sysdeps/unix/sysv/linux/arm/clone.S index 9de37f2..58ee7b4 100644 --- a/ports/sysdeps/unix/sysv/linux/arm/clone.S +++ b/ports/sysdeps/unix/sysv/linux/arm/clone.S @@ -81,8 +81,9 @@ PSEUDO_END (__clone) ite ne movne r0, #-1 swieq 0x0 - str r0, [r1, #PID_OFFSET] - str r0, [r1, #TID_OFFSET] + NEGOFF_ADJ_BASE(r1, TID_OFFSET) + str r0, NEGOFF_OFF1(r1, TID_OFFSET) + str r0, NEGOFF_OFF2(r1, PID_OFFSET, TID_OFFSET) 3: #endif @ pick the function arg and call address off the stack and execute diff --git a/ports/sysdeps/unix/sysv/linux/arm/nptl/pt-vfork.S b/ports/sysdeps/unix/sysv/linux/arm/nptl/pt-vfork.S index 749aaab..bc0a771 100644 --- a/ports/sysdeps/unix/sysv/linux/arm/nptl/pt-vfork.S +++ b/ports/sysdeps/unix/sysv/linux/arm/nptl/pt-vfork.S @@ -26,14 +26,15 @@ ldr lr, [sp], #4; /* Restore LR. */ \ cfi_adjust_cfa_offset (-4); \ cfi_restore (lr); \ - mov r2, r0; /* Save the TLS addr in r2. */ \ - ldr r3, [r2, #PID_OFFSET]; /* Load the saved PID. */ \ - rsb r0, r3, #0; /* Negate it. */ \ - str r0, [r2, #PID_OFFSET] /* Store the temporary PID. */ + NEGOFF_ADJ_BASE2(r2, r0, PID_OFFSET); /* Save the TLS addr in r2. */ \ + ldr r3, NEGOFF_OFF1(r2, PID_OFFSET); /* Load the saved PID. */ \ + rsb r0, r3, #0; /* Negate it. */ \ + str r0, NEGOFF_OFF1(r2, PID_OFFSET); /* Store the temp PID. */ /* Restore the old PID value in the parent. */ #define RESTORE_PID \ cmp r0, #0; /* If we are the parent... */ \ - strne r3, [r2, #PID_OFFSET] /* ... restore the saved PID. */ + it ne; \ + strne r3, NEGOFF_OFF1(r2, PID_OFFSET); /* restore the saved PID. */ #include "../vfork.S" diff --git a/ports/sysdeps/unix/sysv/linux/arm/nptl/sysdep-cancel.h b/ports/sysdeps/unix/sysv/linux/arm/nptl/sysdep-cancel.h index b6dc3e0..0c9e780 100644 --- a/ports/sysdeps/unix/sysv/linux/arm/nptl/sysdep-cancel.h +++ b/ports/sysdeps/unix/sysv/linux/arm/nptl/sysdep-cancel.h @@ -217,15 +217,16 @@ extern int __local_multiple_threads attribute_hidden; header.multiple_threads) == 0, 1) # else # define SINGLE_THREAD_P \ - stmfd sp!, {r0, lr}; \ - cfi_adjust_cfa_offset (8); \ - cfi_rel_offset (lr, 4); \ - bl __aeabi_read_tp; \ - ldr ip, [r0, #MULTIPLE_THREADS_OFFSET]; \ - ldmfd sp!, {r0, lr}; \ - cfi_adjust_cfa_offset (-8); \ - cfi_restore (lr); \ - teq ip, #0 + stmfd sp!, {r0, lr}; \ + cfi_adjust_cfa_offset (8); \ + cfi_rel_offset (lr, 4); \ + bl __aeabi_read_tp; \ + NEGOFF_ADJ_BASE(r0, MULTIPLE_THREADS_OFFSET); \ + ldr ip, NEGOFF_OFF1(r0, MULTIPLE_THREADS_OFFSET); \ + ldmfd sp!, {r0, lr}; \ + cfi_adjust_cfa_offset (-8); \ + cfi_restore (lr); \ + teq ip, #0 # define SINGLE_THREAD_P_PIC(x) SINGLE_THREAD_P # endif # endif diff --git a/ports/sysdeps/unix/sysv/linux/arm/nptl/vfork.S b/ports/sysdeps/unix/sysv/linux/arm/nptl/vfork.S index 1bbe5c6..3c0ef78 100644 --- a/ports/sysdeps/unix/sysv/linux/arm/nptl/vfork.S +++ b/ports/sysdeps/unix/sysv/linux/arm/nptl/vfork.S @@ -26,15 +26,17 @@ ldr lr, [sp], #4; /* Restore LR. */ \ cfi_adjust_cfa_offset (-4); \ cfi_restore (lr); \ - mov r2, r0; /* Save the TLS addr in r2. */ \ - ldr r3, [r2, #PID_OFFSET]; /* Load the saved PID. */ \ - rsbs r0, r3, #0; /* Negate it. */ \ - moveq r0, #0x80000000; /* Use 0x80000000 if it was 0. */ \ - str r0, [r2, #PID_OFFSET] /* Store the temporary PID. */ + NEGOFF_ADJ_BASE2(r2, r0, PID_OFFSET); /* Save the TLS addr in r2. */ \ + ldr r3, NEGOFF_OFF1(r2, PID_OFFSET); /* Load the saved PID. */ \ + rsbs r0, r3, #0; /* Negate it. */ \ + it eq; \ + moveq r0, #0x80000000; /* Use 0x80000000 if it was 0. */ \ + str r0, NEGOFF_OFF1(r2, PID_OFFSET); /* Store the temp PID. */ /* Restore the old PID value in the parent. */ #define RESTORE_PID \ cmp r0, #0; /* If we are the parent... */ \ - strne r3, [r2, #PID_OFFSET] /* ... restore the saved PID. */ + it ne; \ + strne r3, NEGOFF_OFF1(r2, PID_OFFSET); /* restore the saved PID. */ #include "../vfork.S" -- 1.8.1.2