Subject: current

From: Philip Blundell <[email-masked]>
Date: Thu, 27 Jul 2000 18:16:01 +0100

The patch below removes some more gratuitous assembly from the kernel.  As 
well as the obvious moral gains, this does actually generate better code.  
The catch is that past changes in this area have tended to expose bugs in 
older compilers, as evidenced by the comment in the middle, but it's not clear 
exactly what the pitfalls are.

If anybody would like to try it out, I'd be glad to hear the results.

Thanks

p.

--- linux/include/asm-arm/current.h	Sun Apr 30 11:00:03 2000
+++ linux/include/asm-arm/current.h	Thu Jul 27 17:57:54 2000
@@ -1,30 +1,19 @@
 #ifndef _ASMARM_CURRENT_H
 #define _ASMARM_CURRENT_H
 
-static inline unsigned long get_sp(void)
-{
-	unsigned long sp;
-	__asm__ ("mov	%0,sp" : "=r" (sp));
-	return sp;
-}
+#define get_sp()	\
+	({ register unsigned long sp asm ("sp"); sp })
 
 /* Old compilers seem to generate bad code if we allow `current' to be
    non volatile.  */
 #if (__GNUC__ > 2) || (__GNUC__ == 2 && __GNUC_MINOR__ > 90)
 static inline struct task_struct *get_current(void) __attribute__ (( __const__ ));
-#define __VOLATILE_CURRENT
-#else
-#define __VOLATILE_CURRENT volatile
 #endif
 
 static inline struct task_struct *get_current(void)
 {
-	struct task_struct *ts;
-	__asm__ __VOLATILE_CURRENT (
-	"bic	%0, sp, #0x1f00		@ get_current
-	bic	%0, %0, #0x00ff" 
-	: "=r" (ts));
-	return ts;
+	register unsigned long sp asm ("sp");
+	return (struct task_struct *)(sp & ~0x1fff);
 }
 
 #define current (get_current())

unsubscribe: body of `unsubscribe linux-arm-kernel' to [email-masked]

---

From: Scott Bambrough <[email-masked]>
Date: Thu, 27 Jul 2000 14:02:34 -0400

> If anybody would like to try it out, I'd be glad to hear the results.

Hi Phil,

This change is could be risky.  Since the function is inline, the compiler can
actually optimize out a read of current if the volatile flag is not applied. 
When you call get_current() you want it to read the value all the time.  

Scott

-- 
Scott Bambrough - Software Engineer
REBEL.COM    http://www.rebel.com
NetWinder    http://www.netwinder.org

---

From: Russell King - ARM Linux Admin <[email-masked]>
Date: Thu, 27 Jul 2000 19:21:44 +0100 (BST)

> If anybody would like to try it out, I'd be glad to hear the results.

The following

> +	({ register unsigned long sp asm ("sp"); sp })

produces the warning: void value not ignored as it ought to be
and generates no code to actually get sp (its optimised away).

Apart from that one major problem, seems to be reasonable.
   _____
  |_____| ------------------------------------------------- ---+---+-
  |   |        Russell King       [email-masked]      --- ---
  | | | |            http://www.arm.linux.org.uk/            /  /  |
  | +-+-+                                                     --- -+-
  /   |               THE developer of ARM Linux              |+| /|\
 /  | | |                                                     ---  |
    +-+-+ -------------------------------------------------  /\\\  |

---

From: Philip Blundell <[email-masked]>
Date: Thu, 27 Jul 2000 19:54:38 +0100

>and generates no code to actually get sp (its optimised away).

Actually, I can't even find a place where get_sp() is used in the kernel (it 
builds fine for me with that macro removed altogether).

What file are you seeing this warning in?

p.

---

From: Philip Blundell <[email-masked]>
Date: Thu, 27 Jul 2000 19:41:39 +0100

>and generates no code to actually get sp (its optimised away).

On which compiler?

p.

---

From: Russell King - ARM Linux Admin <[email-masked]>
Date: Thu, 27 Jul 2000 22:01:41 +0100 (BST)

> >and generates no code to actually get sp (its optimised away).

Does it matter?  The fact that it doesn't work was what I thought
mattered.
   _____

---

From: Russell King - ARM Linux Admin <[email-masked]>
Date: Thu, 27 Jul 2000 22:07:49 +0100 (BST)

> builds fine for me with that macro removed altogether).

You're right - get_sp() isn't used any more.  Ignore my previous mail.
   _____