about summary refs log tree commit diff
path: root/sysdeps/unix/sysv/linux/powerpc/sysdep.h
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/unix/sysv/linux/powerpc/sysdep.h')
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/sysdep.h42
1 files changed, 22 insertions, 20 deletions
diff --git a/sysdeps/unix/sysv/linux/powerpc/sysdep.h b/sysdeps/unix/sysv/linux/powerpc/sysdep.h
index 48f3d0d1b2..62b77a79f0 100644
--- a/sysdeps/unix/sysv/linux/powerpc/sysdep.h
+++ b/sysdeps/unix/sysv/linux/powerpc/sysdep.h
@@ -32,6 +32,18 @@
 #undef SYS_ify
 #define SYS_ify(syscall_name)  __NR_##syscall_name
 
+#define tostring(s) #s
+#define stringify(s) tostring(s)
+
+#ifdef _ARCH_PWR4
+/* Power4 and later cpus introduced a faster instruction to copy one
+   CR field, rather than the slower microcoded mfcr which copies all
+   CR fields.  */
+# define MFCR0(REG) "mfocrf " stringify(REG) ",0x80"
+#else
+# define MFCR0(REG) "mfcr " stringify(REG)
+#endif
+
 /* Define a macro which expands inline into the wrapper code for a system
    call. This use is for internal calls that do not need to handle errors
    normally. It will never touch errno. This returns just what the kernel
@@ -52,7 +64,7 @@
     __asm__ __volatile__						\
       ("mtctr %0\n\t"							\
        "bctrl\n\t"							\
-       "mfcr  %0\n\t"							\
+       MFCR0(%0) "\n\t"							\
        "0:"								\
        : "+r" (r0), "+r" (r3), "+r" (r4), "+r" (r5),  "+r" (r6),        \
          "+r" (r7), "+r" (r8)						\
@@ -83,11 +95,10 @@
        "scv 0\n\t"				\
        ".machine \"pop\"\n\t"			\
        "0:"					\
-       : "=&r" (r0),				\
-	 "=&r" (r3), "=&r" (r4), "=&r" (r5),	\
-	 "=&r" (r6), "=&r" (r7), "=&r" (r8)	\
-       : ASM_INPUT_##nr			\
-       : "r9", "r10", "r11", "r12",		\
+       : "+r" (r0),				\
+	 "+r" (r3), "+r" (r4), "+r" (r5),	\
+	 "+r" (r6), "+r" (r7), "+r" (r8)	\
+       : : "r9", "r10", "r11", "r12",		\
 	 "cr0", "cr1", "cr5", "cr6", "cr7",	\
 	 "xer", "lr", "ctr", "memory"); 	\
     r3;					\
@@ -97,13 +108,12 @@
   ({						\
     __asm__ __volatile__			\
       ("sc\n\t"				\
-       "mfcr %0\n\t"				\
+       MFCR0(%0) "\n\t"				\
        "0:"					\
-       : "=&r" (r0),				\
-	 "=&r" (r3), "=&r" (r4), "=&r" (r5),	\
-	 "=&r" (r6), "=&r" (r7), "=&r" (r8)	\
-       : ASM_INPUT_##nr			\
-       : "r9", "r10", "r11", "r12",		\
+       : "+r" (r0),				\
+	 "+r" (r3), "+r" (r4), "+r" (r5),	\
+	 "+r" (r6), "+r" (r7), "+r" (r8)	\
+       : : "r9", "r10", "r11", "r12",		\
 	 "xer", "cr0", "ctr", "memory");	\
     r0 & (1 << 28) ? -r3 : r3;			\
   })
@@ -199,14 +209,6 @@
 	  __illegally_sized_syscall_arg6 (); \
 	r8 = _arg6
 
-#define ASM_INPUT_0 "0" (r0)
-#define ASM_INPUT_1 ASM_INPUT_0, "1" (r3)
-#define ASM_INPUT_2 ASM_INPUT_1, "2" (r4)
-#define ASM_INPUT_3 ASM_INPUT_2, "3" (r5)
-#define ASM_INPUT_4 ASM_INPUT_3, "4" (r6)
-#define ASM_INPUT_5 ASM_INPUT_4, "5" (r7)
-#define ASM_INPUT_6 ASM_INPUT_5, "6" (r8)
-
 /* List of system calls which are supported as vsyscalls.  */
 #define VDSO_NAME  "LINUX_2.6.15"
 #define VDSO_HASH  123718565