This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
ARM: EABI GNU/Linux tweaks
- From: Daniel Jacobowitz <drow at false dot org>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 14 Nov 2005 11:47:16 -0500
- Subject: ARM: EABI GNU/Linux tweaks
In the next couple of weeks, the ARM Linux kernel is going to gain support
for building as EABI. It's going to get a new syscall interface at the same
time, in which syscall numbers are passed in r7 instead of in the swi
instruction (I'm told this is more efficient on modern cores).
This patch adjusts the two places where GCC formerly made syscalls. One
is in the __div0 handler; I've adjusted that to just call raise. This
caused a glibc build failure, but the fix for that was committed last week.
The other is in CLEAR_CACHE, where a valid fix is to use both the old-style
swi and set r7. NOTE! This is not a generally acceptable technique; it
works for __NR_ARM_cacheflush, but may not for many other syscalls.
Is this OK?
--
Daniel Jacobowitz
CodeSourcery, LLC
2005-11-14 Daniel Jacobowitz <dan@codesourcery.com>
* config/arm/lib1funcs.asm (div0) [L_dvmd_lnx]: Call raise instead
of making syscalls.
* config/arm/linux-eabi.h (CLEAR_INSN_CACHE): Define. Set r7 also.
Index: gcc/gcc/config/arm/lib1funcs.asm
===================================================================
--- gcc.orig/gcc/config/arm/lib1funcs.asm 2005-10-18 20:54:15.000000000 -0400
+++ gcc/gcc/config/arm/lib1funcs.asm 2005-10-26 15:08:08.000000000 -0400
@@ -989,29 +989,15 @@ LSYM(Lover12):
#ifdef L_dvmd_lnx
@ GNU/Linux division-by zero handler. Used in place of L_dvmd_tls
-/* Constants taken from <asm/unistd.h> and <asm/signal.h> */
+/* Constant taken from <asm/signal.h>. */
#define SIGFPE 8
-#define __NR_SYSCALL_BASE 0x900000
-#define __NR_getpid (__NR_SYSCALL_BASE+ 20)
-#define __NR_kill (__NR_SYSCALL_BASE+ 37)
-#define __NR_gettid (__NR_SYSCALL_BASE+ 224)
-#define __NR_tkill (__NR_SYSCALL_BASE+ 238)
.code 32
FUNC_START div0
stmfd sp!, {r1, lr}
- swi __NR_gettid
- cmn r0, #1000
- swihs __NR_getpid
- cmnhs r0, #1000
- RETLDM r1 hs
- mov ip, r0
- mov r1, #SIGFPE
- swi __NR_tkill
- movs r0, r0
- movne r0, ip
- swine __NR_kill
+ mov r0, #SIGFPE
+ bl SYM(raise) __PLT__
RETLDM r1
FUNC_END div0
Index: gcc/gcc/config/arm/linux-eabi.h
===================================================================
--- gcc.orig/gcc/config/arm/linux-eabi.h 2005-10-08 14:17:19.000000000 -0400
+++ gcc/gcc/config/arm/linux-eabi.h 2005-10-27 11:21:24.000000000 -0400
@@ -1,5 +1,5 @@
/* Configuration file for ARM GNU/Linux EABI targets.
- Copyright (C) 2004
+ Copyright (C) 2004, 2005
Free Software Foundation, Inc.
Contributed by CodeSourcery, LLC
@@ -68,3 +68,18 @@
non-AAPCS. */
#undef WCHAR_TYPE
#define WCHAR_TYPE (TARGET_AAPCS_BASED ? "unsigned int" : "long int")
+
+/* Clear the instruction cache from `beg' to `end'. This makes an
+ inline system call to SYS_cacheflush. It is modified to work with
+ both the original and EABI-only syscall interfaces. */
+#undef CLEAR_INSN_CACHE
+#define CLEAR_INSN_CACHE(BEG, END) \
+{ \
+ register unsigned long _beg __asm ("a1") = (unsigned long) (BEG); \
+ register unsigned long _end __asm ("a2") = (unsigned long) (END); \
+ register unsigned long _flg __asm ("a3") = 0; \
+ register unsigned long _scno __asm ("r7") = 0xf0002; \
+ __asm __volatile ("swi 0x9f0002 @ sys_cacheflush" \
+ : "=r" (_beg) \
+ : "0" (_beg), "r" (_end), "r" (_flg), "r" (_scno)); \
+}