This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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));	\
+}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]