From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 27286 invoked by alias); 1 Mar 2013 17:36:27 -0000 Received: (qmail 26389 invoked by uid 22791); 1 Mar 2013 17:36:05 -0000 X-SWARE-Spam-Status: No, hits=-5.3 required=5.0 tests=AWL,BAYES_00,DKIM_SIGNED,DKIM_VALID,FREEMAIL_ENVFROM_END_DIGIT,FREEMAIL_FROM,KHOP_RCVD_TRUST,KHOP_THREADED,RCVD_IN_DNSWL_LOW,RCVD_IN_HOSTKARMA_YE,TW_DM X-Spam-Check-By: sourceware.org Received: from mail-pb0-f51.google.com (HELO mail-pb0-f51.google.com) (209.85.160.51) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 01 Mar 2013 17:35:36 +0000 Received: by mail-pb0-f51.google.com with SMTP id un15so1860515pbc.24 for ; Fri, 01 Mar 2013 09:35:35 -0800 (PST) X-Received: by 10.68.192.106 with SMTP id hf10mr15455054pbc.122.1362159335793; Fri, 01 Mar 2013 09:35:35 -0800 (PST) Received: from fremont.twiddle.net (50-194-63-110-static.hfc.comcastbusiness.net. [50.194.63.110]) by mx.google.com with ESMTPS id kl4sm12679430pbc.31.2013.03.01.09.35.29 (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Fri, 01 Mar 2013 09:35:34 -0800 (PST) From: Richard Henderson To: libc-ports@sourceware.org Cc: joseph@codesourcery.com Subject: [PATCH v2 02/14] arm: Introduce and use NEGOFF series of macros Date: Fri, 01 Mar 2013 17:36:00 -0000 Message-Id: <1362159320-5934-3-git-send-email-rth@twiddle.net> In-Reply-To: <1362159320-5934-1-git-send-email-rth@twiddle.net> References: <1362159320-5934-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-03/txt/msg00007.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 ++++++----- ports/sysdeps/unix/sysv/linux/arm/nptl/sysdep-cancel.h | 3 ++- ports/sysdeps/unix/sysv/linux/arm/nptl/vfork.S | 14 ++++++++------ 5 files changed, 35 insertions(+), 14 deletions(-) diff --git a/ports/sysdeps/arm/sysdep.h b/ports/sysdeps/arm/sysdep.h index 29a78f0..9230131 100644 --- a/ports/sysdeps/arm/sysdep.h +++ b/ports/sysdeps/arm/sysdep.h @@ -134,6 +134,22 @@ .previous; \ 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__ */ /* This number is the offset from the pc at the current location. */ diff --git a/ports/sysdeps/unix/sysv/linux/arm/clone.S b/ports/sysdeps/unix/sysv/linux/arm/clone.S index 732a3ff..a5f9b4d 100644 --- a/ports/sysdeps/unix/sysv/linux/arm/clone.S +++ b/ports/sysdeps/unix/sysv/linux/arm/clone.S @@ -83,8 +83,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 a38d564..ff88510 100644 --- a/ports/sysdeps/unix/sysv/linux/arm/nptl/pt-vfork.S +++ b/ports/sysdeps/unix/sysv/linux/arm/nptl/pt-vfork.S @@ -28,14 +28,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 8889369..47d4c70 100644 --- a/ports/sysdeps/unix/sysv/linux/arm/nptl/sysdep-cancel.h +++ b/ports/sysdeps/unix/sysv/linux/arm/nptl/sysdep-cancel.h @@ -217,7 +217,8 @@ extern int __local_multiple_threads attribute_hidden; cfi_adjust_cfa_offset (8); \ cfi_rel_offset (lr, 4); \ bl __aeabi_read_tp; \ - ldr ip, [r0, #MULTIPLE_THREADS_OFFSET]; \ + 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); \ diff --git a/ports/sysdeps/unix/sysv/linux/arm/nptl/vfork.S b/ports/sysdeps/unix/sysv/linux/arm/nptl/vfork.S index 3fce2d1..c4be1e2 100644 --- a/ports/sysdeps/unix/sysv/linux/arm/nptl/vfork.S +++ b/ports/sysdeps/unix/sysv/linux/arm/nptl/vfork.S @@ -28,15 +28,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