All of lore.kernel.org
 help / color / mirror / Atom feed
* [parisc-linux] Any good rules of pratice about branching insn into the delay slot of another one?
@ 2006-04-02 11:46 Joel Soete
  2006-04-02 15:20 ` [parisc-linux] " Randolph Chung
  0 siblings, 1 reply; 3+ messages in thread
From: Joel Soete @ 2006-04-02 11:46 UTC (permalink / raw)
  To: parisc-linux; +Cc: John David Anglin

Hello all,

This question about latest test related to some glibc clone().

This patch:
   # diff -Nau clone.S.orig2 clone.S.New4
--- clone.S.orig2       2006-03-24 09:11:27.000000000 +0000
+++ clone.S.New4        2006-03-31 17:42:25.000000000 +0000
@@ -45,7 +45,31 @@

          .text
  ENTRY(__clone)
+    /* this ENTRY() macro do: stw rp, -20(sp)
+       and "FIXME: I have no idea how profiling works on hppa." */

+       /* Sanity check arguments.  */
+       comib,=         0, %arg0, .Larg_error           /* no NULL function pointers */
+       nop
+       comib,<>,n      0, %arg1, .Lno_arg_error        /* no NULL stack pointers */
+       nop
+
+.Larg_error:
+       /* Create a stack frame */
+/*     stwm            %r3, 64(%sp) */
+       ldo             64(%sp), %sp
+       /* Set errno */
+       bl              __syscall_error, %rp
+       ldi             EINVAL, %arg0
+
+       /* Return after setting errno */
+       /* Restore rp from ENTRY() */
+       ldw             -84(%sp), %rp
+       bv              %r0(%rp)
+/*     ldwm            -64(%sp), %r3 */
+       ldo             -64(%sp), %sp
+
+.Lno_arg_error:
         /* Save the fn ptr and arg on the new stack.  */
         stwm            %arg0, 64(%arg1)
         stw             %arg3, -60(%arg1)
@@ -75,8 +99,10 @@
         ldi             -4096, %r1
         comclr,>>=      %r1, %ret0, %r0         /* Note: unsigned compare. */
         b,n             .Lerror
+       nop

         comib,=,n       0, %ret0, thread_start
+       nop                                     /* to avoid bv in the delay slot? */

         /* Successful return from the parent
            No need to restore the PIC register,
@@ -94,10 +120,12 @@
  #endif
         /* Set errno */
         copy            %ret0, %r3
-       b               __syscall_error
+       bl              __syscall_error, %rp
         sub             %r0, %ret0, %arg0
         copy            %r3, %ret0
         /* Return after setting errno */
+       /* Restore rp from ENTRY() */
+       ldw             -84(%sp), %rp
         bv              %r0(%rp)
         ldwm            -64(%sp), %r3

====<>====

seems to works seems to be ok:
# grep Err glibc-2.3.6-4.3.1
make[3]: *** [/CAD/parisc-linux/Dpkg/dpkg-work/glibc-2.3.6/build-tree/hppa-libc/localedata/sort-test.out] Error 1
make[2]: *** [localedata/tests] Error 2
make[3]: *** [/CAD/parisc-linux/Dpkg/dpkg-work/glibc-2.3.6/build-tree/hppa-libc/math/test-float.out] Error 1
make[3]: *** [/CAD/parisc-linux/Dpkg/dpkg-work/glibc-2.3.6/build-tree/hppa-libc/math/test-double.out] Error 1
make[3]: *** [/CAD/parisc-linux/Dpkg/dpkg-work/glibc-2.3.6/build-tree/hppa-libc/math/test-idouble.out] Error 1
make[2]: *** [math/tests] Error 2
make[3]: *** [/CAD/parisc-linux/Dpkg/dpkg-work/glibc-2.3.6/build-tree/hppa-libc/posix/tst-rxspencer.out] Error 139
make[3]: [/CAD/parisc-linux/Dpkg/dpkg-work/glibc-2.3.6/build-tree/hppa-libc/posix/annexc.out] Error 1 (ignored)
make[2]: *** [posix/tests] Error 2
make[3]: *** [/CAD/parisc-linux/Dpkg/dpkg-work/glibc-2.3.6/build-tree/hppa-libc/linuxthreads/tst-attr1.out] Error 1
make[2]: *** [linuxthreads/tests] Error 2
make[3]: *** [/CAD/parisc-linux/Dpkg/dpkg-work/glibc-2.3.6/build-tree/hppa-libc/rt/tst-timer.out] Error 137
make[3]: *** [/CAD/parisc-linux/Dpkg/dpkg-work/glibc-2.3.6/build-tree/hppa-libc/rt/tst-aio4.out] Error 1
make[3]: *** [/CAD/parisc-linux/Dpkg/dpkg-work/glibc-2.3.6/build-tree/hppa-libc/rt/tst-timer4.out] Error 1
make[2]: *** [rt/tests] Error 2
make[3]: *** [/CAD/parisc-linux/Dpkg/dpkg-work/glibc-2.3.6/build-tree/hppa-libc/elf/tst-execstack-needed.out] Error 1
make[2]: *** [elf/tests] Error 2
make[1]: *** [check] Error 2

(well doesn't seems to introduce regression in test)

OTOH if I remove the nop I added in delay slot of 'b,n .Lerror' and 'comib,=,n 0, %ret0, thread_start' i.e. rm hunk:
@@ -75,8 +99,10 @@
         ldi             -4096, %r1
         comclr,>>=      %r1, %ret0, %r0         /* Note: unsigned compare. */
         b,n             .Lerror
+       nop

         comib,=,n       0, %ret0, thread_start
+       nop                                     /* to avoid bv in the delay slot? */

         /* Successful return from the parent
            No need to restore the PIC register,

test became very regressive:
# grep Err glibc-2.3.6-4.3.2
make[3]: *** [/CAD/parisc-linux/Dpkg/dpkg-work/glibc-2.3.6/build-tree/hppa-libc/iconvdata/tst-iconv4.out] Error 1
make[2]: *** [iconvdata/tests] Error 2
make[3]: *** [/CAD/parisc-linux/Dpkg/dpkg-work/glibc-2.3.6/build-tree/hppa-libc/localedata/sort-test.out] Error 1
make[2]: *** [localedata/tests] Error 2
make[3]: *** [/CAD/parisc-linux/Dpkg/dpkg-work/glibc-2.3.6/build-tree/hppa-libc/math/test-float.out] Error 1
make[3]: *** [/CAD/parisc-linux/Dpkg/dpkg-work/glibc-2.3.6/build-tree/hppa-libc/math/test-double.out] Error 1
make[3]: *** [/CAD/parisc-linux/Dpkg/dpkg-work/glibc-2.3.6/build-tree/hppa-libc/math/test-idouble.out] Error 1
make[2]: *** [math/tests] Error 2
make[3]: *** [/CAD/parisc-linux/Dpkg/dpkg-work/glibc-2.3.6/build-tree/hppa-libc/stdio-common/tst-rndseek.out] Error 1
make[2]: *** [stdio-common/tests] Error 2
make[3]: *** [/CAD/parisc-linux/Dpkg/dpkg-work/glibc-2.3.6/build-tree/hppa-libc/libio/bug-mmap-fflush.out] Error 1
make[2]: *** [libio/tests] Error 2
make[3]: *** [/CAD/parisc-linux/Dpkg/dpkg-work/glibc-2.3.6/build-tree/hppa-libc/posix/tst-chmod.out] Error 1
make[3]: *** [/CAD/parisc-linux/Dpkg/dpkg-work/glibc-2.3.6/build-tree/hppa-libc/posix/bug-regex24.out] Error 1
make[3]: *** [/CAD/parisc-linux/Dpkg/dpkg-work/glibc-2.3.6/build-tree/hppa-libc/posix/tst-regex2.out] Error 1
make[3]: *** [/CAD/parisc-linux/Dpkg/dpkg-work/glibc-2.3.6/build-tree/hppa-libc/posix/tst-rxspencer.out] Error 139
make[3]: [/CAD/parisc-linux/Dpkg/dpkg-work/glibc-2.3.6/build-tree/hppa-libc/posix/annexc.out] Error 1 (ignored)
make[2]: *** [posix/tests] Error 2
make[3]: *** [/CAD/parisc-linux/Dpkg/dpkg-work/glibc-2.3.6/build-tree/hppa-libc/linuxthreads/tst-attr1.out] Error 1
make[2]: *** [linuxthreads/tests] Error 2
make[3]: *** [/CAD/parisc-linux/Dpkg/dpkg-work/glibc-2.3.6/build-tree/hppa-libc/rt/tst-clock.out] Error 1
make[3]: *** [/CAD/parisc-linux/Dpkg/dpkg-work/glibc-2.3.6/build-tree/hppa-libc/rt/tst-timer.out] Error 139
make[3]: *** [/CAD/parisc-linux/Dpkg/dpkg-work/glibc-2.3.6/build-tree/hppa-libc/rt/tst-aio4.out] Error 1
make[3]: *** [/CAD/parisc-linux/Dpkg/dpkg-work/glibc-2.3.6/build-tree/hppa-libc/rt/tst-aio5.out] Error 1
make[3]: *** [/CAD/parisc-linux/Dpkg/dpkg-work/glibc-2.3.6/build-tree/hppa-libc/rt/tst-aio6.out] Error 1
make[3]: *** [/CAD/parisc-linux/Dpkg/dpkg-work/glibc-2.3.6/build-tree/hppa-libc/rt/tst-timer3.out] Error 1
make[3]: *** [/CAD/parisc-linux/Dpkg/dpkg-work/glibc-2.3.6/build-tree/hppa-libc/rt/tst-timer4.out] Error 1
make[2]: *** [rt/tests] Error 2
make[3]: *** [/CAD/parisc-linux/Dpkg/dpkg-work/glibc-2.3.6/build-tree/hppa-libc/elf/tst-tls13.out] Error 1
make[3]: *** [/CAD/parisc-linux/Dpkg/dpkg-work/glibc-2.3.6/build-tree/hppa-libc/elf/tst-execstack-prog.out] Error 1
make[2]: *** [elf/tests] Error 2
make[1]: *** [check] Error 2

Thanks in advance for advise,
	Joel
_______________________________________________
parisc-linux mailing list
parisc-linux@lists.parisc-linux.org
http://lists.parisc-linux.org/mailman/listinfo/parisc-linux

^ permalink raw reply	[flat|nested] 3+ messages in thread
* [parisc-linux] Re: Any good rules of pratice about branching insn into the delay slot of another one?
@ 2006-04-19  8:09 Joel Soete
  0 siblings, 0 replies; 3+ messages in thread
From: Joel Soete @ 2006-04-19  8:09 UTC (permalink / raw)
  To: carlos; +Cc: parisc-linux

[-- Attachment #1: Type: text/plain, Size: 3781 bytes --]

> On 4/3/06, Joel Soete <soete.joel@tiscali.be> wrote:
> > as well the reference test clone04:
> >
> > # ./clone04 ; echo $?
> > clone04     1  PASS  :  expected failure; Got EINVAL
> > 0
>
> What was the outcome of this whole thread?
> In summary what needs to be fixed?
>
Over glibc cvs available at p-l.org this is the best I can do:
--- clone.S.orig2       2006-03-24 10:11:27.000000000 +0100
+++ clone.S.New6        2006-04-13 09:21:11.000000000 +0200
@@ -45,7 +45,29 @@

         .text
 ENTRY(__clone)
+    /* this ENTRY() macro do: stw rp, -20(sp)
+       and "FIXME: I have no idea how profiling works on hppa." */

+       /* Sanity check arguments.  */
+       comib,=         0, %arg0, .Larg_error           /* no NULL function
pointers */
+       nop                                             /* delay slot */
+       comib,<>,n      0, %arg1, .Lno_arg_error        /* no NULL stack
pointers */
+       nop                                             /* delay slot */
+
+.Larg_error:
+       /* Create a stack frame */
+       ldo             64(%sp), %sp
+       /* Set errno (in the delay slot) */
+       bl              __syscall_error, %rp
+       ldi             EINVAL, %arg0
+
+       /* Return after setting errno */
+       /* Restore rp from ENTRY() */
+       ldw             -84(%sp), %rp
+       bv              %r0(%rp)
+       ldo             -64(%sp), %sp
+
+.Lno_arg_error:
        /* Save the fn ptr and arg on the new stack.  */
        stwm            %arg0, 64(%arg1)
        stw             %arg3, -60(%arg1)
@@ -63,41 +85,40 @@
        stwm            %r3, 64(%sp)
        stw             %r21, -4(%sp)

-       /* Save the PIC register. */
-#ifdef PIC
-       copy            %r19, %r3               /* parent */
-#endif
+       SAVE_PIC (TREG)

        /* Do the system call */
        ble             0x100(%sr2, %r0)
-       ldi             __NR_clone, %r20
+       ldi             SYS_ify (clone), %r20

-       ldi             -4096, %r1
-       comclr,>>=      %r1, %ret0, %r0         /* Note: unsigned compare. */
+       ldi             NO_ERROR, %r1
+       comclr,>>=      %r1, %ret0, %r20        /* Note: unsigned compare. */
        b,n             .Lerror
+       nop                     /* to avoid next br insn in the delay slot? */

        comib,=,n       0, %ret0, thread_start
+       nop                     /* to avoid next br insn in the delay slot? */

        /* Successful return from the parent
           No need to restore the PIC register,
           since we return immediately. */
-
        bv              %r0(%rp)
        ldwm            -64(%sp), %r3

        /* Something bad happened -- no child created */
 .Lerror:

-       /* Restore the PIC register on error */
-#ifdef PIC
-       copy            %r3, %r19               /* parent */
-#endif
-       /* Set errno */
-       copy            %ret0, %r3
-       b               __syscall_error
+       LOAD_PIC (TREG)
+
+       /* Use TREG for temp storage */
+       copy            %ret0, TREG
+       /* Set errno (in the delay slot) */
+       bl              __syscall_error, %rp
        sub             %r0, %ret0, %arg0
-       copy            %r3, %ret0
+       copy            TREG, %ret0
        /* Return after setting errno */
+       /* Restore rp from ENTRY() */
+       ldw             -84(%sp), %rp
        bv              %r0(%rp)
        ldwm            -64(%sp), %r3

====<>====

I tried (but without success) to inline  __syscall_error().

Hth,
    Joel

PS:
  1/ debian gcc-4.0 still lake of a jda patch
  2/ against latest debian libc6 src (2.3.6-7) I applied attached patches:
     tls-sysdeps-ng.diff; tst-clone.S.diff

[-- Attachment #2: tls-sysdeps-ng.diff --]
[-- Type: text/plain, Size: 15736 bytes --]

--- glibc-2.3.6/sysdeps/unix/sysv/linux/hppa/sysdep.c.orig	2006-04-05 14:35:11.000000000 +0200
+++ glibc-2.3.6/sysdeps/unix/sysv/linux/hppa/sysdep.c	2006-04-05 14:33:21.000000000 +0200
@@ -16,12 +16,12 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
+#include <stdarg.h>
 #include <sysdep.h>
 #include <errno.h>
 
 extern int __syscall_error(int err_no);
-extern int syscall (int sysnum, int arg0, int arg1, int arg2,
-		    int arg3, int arg4, int arg5);
+extern long int syscall (long int __sysno, ...) __THROW;
 
 /* This routine is jumped to by all the syscall handlers, to stash
    an error number into errno.  */
@@ -37,21 +37,34 @@
    typically be in syscall.S. Also note that we have INLINE_SYSCALL,
    INTERNAL_SYSCALL, and all the generated pure assembly syscall wrappers.
    How often the function is used is unknown. */
-int
-syscall (int sysnum, int arg0, int arg1, int arg2, int arg3, int arg4,
-	 int arg5)
+
+long int 
+syscall (long int __sysno, ...) 
 {
   /* FIXME: Keep this matching INLINE_SYSCALL for hppa */
+  va_list args;
+  long int arg0, arg1, arg2, arg3, arg4, arg5;
   long int __sys_res;
+
+  /* Load varargs */
+  va_start (args, __sysno);
+  arg0 = va_arg (args, long int);
+  arg1 = va_arg (args, long int);
+  arg2 = va_arg (args, long int);
+  arg3 = va_arg (args, long int);
+  arg4 = va_arg (args, long int);
+  arg5 = va_arg (args, long int);
+  va_end (args);
+  
   {
     register unsigned long int __res asm("r28");
     LOAD_ARGS_6 (arg0, arg1, arg2, arg3, arg4, arg5)
     asm volatile (SAVE_ASM_PIC
-		  "	ble  0x100(%%sr2, %%r0)	\n"
-		  "	copy %1, %%r20		\n"
+		  "	ble		0x100(%%sr2, %%r0)	\n"
+		  "	copy		%1, %%r20		\n"
 		  LOAD_ASM_PIC
 		  : "=r" (__res)
-		  : "r" (sysnum) ASM_ARGS_6
+		  : "r" (__sysno) ASM_ARGS_6
 		  : "memory", CALL_CLOB_REGS CLOB_ARGS_6);
     __sys_res = __res;
   }
@@ -62,3 +75,4 @@
     }
   return __sys_res;
 }
+
--- glibc-2.3.6/sysdeps/unix/sysv/linux/hppa/sysdep.h.orig	2006-04-05 14:35:11.000000000 +0200
+++ glibc-2.3.6/sysdeps/unix/sysv/linux/hppa/sysdep.h	2006-04-05 15:16:15.000000000 +0200
@@ -22,7 +22,6 @@
 #include <asm/unistd.h>
 #include <sysdeps/generic/sysdep.h>
 #include <sys/syscall.h>
-#include "config.h"
 
 #undef ASM_LINE_SEP
 #define ASM_LINE_SEP ! 
@@ -35,12 +34,12 @@
    to another function */
 #ifdef PIC
 # define TREG %r3
-# define SAVE_PIC(SREG) copy %r19, SREG ASM_LINE_SEP
-# define LOAD_PIC(LREG) copy LREG, %r19 ASM_LINE_SEP
+# define SAVE_PIC(SREG) copy		%r19, SREG	ASM_LINE_SEP
+# define LOAD_PIC(LREG) copy		LREG, %r19	ASM_LINE_SEP
 /* Inline assembly defines */
 # define TREG_ASM "%r4" /* Cant clobber r3, it holds framemarker */
-# define SAVE_ASM_PIC	"       copy %%r19, %" TREG_ASM "\n"
-# define LOAD_ASM_PIC	"       copy %" TREG_ASM ", %%r19\n"
+# define SAVE_ASM_PIC	"       copy		%%r19, %" TREG_ASM "\n"
+# define LOAD_ASM_PIC	"       copy		%" TREG_ASM ", %%r19\n"
 # define USING_TREG	TREG_ASM,
 #else
 # define TREG %r3
@@ -97,8 +96,8 @@
 #define DOARGS_2 /* nothing */
 #define DOARGS_3 /* nothing */
 #define DOARGS_4 /* nothing */
-#define DOARGS_5 ldw -52(%sp), %r22		ASM_LINE_SEP
-#define DOARGS_6 DOARGS_5 ldw -56(%sp), %r21	ASM_LINE_SEP
+#define DOARGS_5 ldw		-52(%sp), %r22		ASM_LINE_SEP
+#define DOARGS_6 DOARGS_5 ldw		-56(%sp), %r21	ASM_LINE_SEP
 
 #define UNDOARGS_0 /* nothing */
 #define UNDOARGS_1 /* nothing */
@@ -123,14 +122,14 @@
 	.CALLINFO FRAME=64,CALLS,SAVE_RP,ENTRY_GR=3	ASM_LINE_SEP	\
 	.ENTRY						ASM_LINE_SEP	\
 	/* SAVE_RP says we do */			ASM_LINE_SEP	\
-	stw %rp, -20(%sr0,%sp)				ASM_LINE_SEP	\
+	stw		%rp, -20(%sr0, %sp)		ASM_LINE_SEP	\
 	/*FIXME: Call mcount? (carefull with stack!) */
 
 /* Some syscall wrappers do not call other functions, and
    hence are classified as leaf, so add NO_CALLS for gdb */
 #define	ENTRY_LEAF(name)						\
 	.text						ASM_LINE_SEP	\
-	.align ALIGNARG(4)				ASM_LINE_SEP	\
+	.align	ALIGNARG(4)				ASM_LINE_SEP	\
 	.export C_SYMBOL_NAME(name)			ASM_LINE_SEP	\
 	.type	C_SYMBOL_NAME(name),@function		ASM_LINE_SEP	\
 	C_LABEL(name)					ASM_LINE_SEP	\
@@ -138,12 +137,12 @@
 	.CALLINFO FRAME=64,NO_CALLS,SAVE_RP,ENTRY_GR=3	ASM_LINE_SEP	\
 	.ENTRY						ASM_LINE_SEP	\
 	/* SAVE_RP says we do */			ASM_LINE_SEP	\
-	stw %rp, -20(%sr0,%sp)				ASM_LINE_SEP	\
+	stw		%rp, -20(%sr0, %sp)		ASM_LINE_SEP	\
 	/*FIXME: Call mcount? (carefull with stack!) */
 
 #undef	END
 #define END(name)							\
-  	.EXIT						ASM_LINE_SEP	\
+ 	.EXIT						ASM_LINE_SEP	\
 	.PROCEND					ASM_LINE_SEP	\
 .size	C_SYMBOL_NAME(name), .-C_SYMBOL_NAME(name)	ASM_LINE_SEP
 
@@ -166,50 +165,50 @@
 	nop
 */
 
-#define	PSEUDO(name, syscall_name, args)			\
-  ENTRY (name)					ASM_LINE_SEP	\
-  /* If necc. load args from stack */		ASM_LINE_SEP	\
-  DOARGS_##args					ASM_LINE_SEP	\
-  DO_CALL (syscall_name, args)			ASM_LINE_SEP	\
-  UNDOARGS_##args				ASM_LINE_SEP	\
-  nop						ASM_LINE_SEP
+#define	PSEUDO(name, syscall_name, args)				\
+	ENTRY (name)					ASM_LINE_SEP	\
+	/* If necc. load args from stack */		ASM_LINE_SEP	\
+	DOARGS_##args					ASM_LINE_SEP	\
+	DO_CALL (syscall_name, args)			ASM_LINE_SEP	\
+	UNDOARGS_##args					ASM_LINE_SEP	\
+	nop						ASM_LINE_SEP
 
 #define ret \
-  /* Return value set by ERRNO code */		ASM_LINE_SEP	\
-  bv,n 0(2)					ASM_LINE_SEP
+	/* Return value set by ERRNO code */	ASM_LINE_SEP	\
+	bv,n		0(2)				ASM_LINE_SEP
 
 #undef	PSEUDO_END
-#define	PSEUDO_END(name)					\
-  END (name)
+#define	PSEUDO_END(name)						\
+	END (name)
 
 /* We don't set the errno on the return from the syscall */
-#define	PSEUDO_NOERRNO(name, syscall_name, args)		\
-  ENTRY_LEAF (name)				ASM_LINE_SEP	\
-  DOARGS_##args					ASM_LINE_SEP	\
-  DO_CALL_NOERRNO (syscall_name, args)		ASM_LINE_SEP	\
-  UNDOARGS_##args				ASM_LINE_SEP	\
-  nop						ASM_LINE_SEP
+#define	PSEUDO_NOERRNO(name, syscall_name, args)			\
+	ENTRY_LEAF (name)				ASM_LINE_SEP	\
+	DOARGS_##args					ASM_LINE_SEP	\
+	DO_CALL_NOERRNO (syscall_name, args)		ASM_LINE_SEP	\
+	UNDOARGS_##args					ASM_LINE_SEP	\
+	nop						ASM_LINE_SEP
 
-#define ret_NOERRNO ret
+#define ret_NOERRNO	ret
 
 #undef	PSEUDO_END_NOERRNO
-#define	PSEUDO_END_NOERRNO(name)				\
-  END (name)
+#define	PSEUDO_END_NOERRNO(name)					\
+	END (name)
 
 /* This has to return the error value */
 #undef  PSEUDO_ERRVAL
-#define PSEUDO_ERRVAL(name, syscall_name, args)			\
-  ENTRY_LEAF (name)				ASM_LINE_SEP	\
-  DOARGS_##args					ASM_LINE_SEP	\
-  DO_CALL_ERRVAL (syscall_name, args)		ASM_LINE_SEP	\
-  UNDOARGS_##args				ASM_LINE_SEP	\
-  nop						ASM_LINE_SEP
+#define PSEUDO_ERRVAL(name, syscall_name, args)				\
+	ENTRY_LEAF (name)				ASM_LINE_SEP	\
+	DOARGS_##args					ASM_LINE_SEP	\
+	DO_CALL_ERRVAL (syscall_name, args)		ASM_LINE_SEP	\
+	UNDOARGS_##args					ASM_LINE_SEP	\
+	nop						ASM_LINE_SEP
 
 #define ret_ERRVAL ret
 
 #undef	PSEUDO_END_ERRVAL
-#define PSEUDO_END_ERRVAL(name)					\
-	END(name)
+#define PSEUDO_END_ERRVAL(name)						\
+	END (name)
 
 #undef JUMPTARGET
 #define JUMPTARGET(name)	name
@@ -222,10 +221,10 @@
 
 /* int * __errno_location(void) so you have to store your value
    into the return address! */
-#define DEFAULT_SYSCALL_ERROR_HANDLER 			\
-	.import __errno_location,code	ASM_LINE_SEP	\
-	/* branch to errno handler */	ASM_LINE_SEP	\
-	bl __errno_location,%rp		ASM_LINE_SEP
+#define DEFAULT_SYSCALL_ERROR_HANDLER 					\
+	.import __errno_location,code			ASM_LINE_SEP	\
+	/* branch to errno handler */			ASM_LINE_SEP	\
+	bl		__errno_location, %rp		ASM_LINE_SEP
 
 /* Here are the myriad of configuration options that the above can
    work for... what we've done is provide the framework for future
@@ -249,7 +248,6 @@
 # endif
 #endif
 
-
 /* Linux takes system call arguments in registers:
 	syscall number	gr20
 	arg 1		gr26
@@ -278,61 +276,60 @@
 #define NO_ERROR -0x1000
 
 #undef	DO_CALL
-#define DO_CALL(syscall_name, args)				\
-  	copy TREG,%r1				ASM_LINE_SEP	\
-	copy %sp,TREG				ASM_LINE_SEP	\
-	/* Create a frame */			ASM_LINE_SEP	\
-	stwm %r1, 64(%sp)			ASM_LINE_SEP	\
-	stw %rp, -20(%sp)			ASM_LINE_SEP	\
-	stw TREG, -4(%sp)			ASM_LINE_SEP	\
-	/* Save r19 */				ASM_LINE_SEP	\
-	SAVE_PIC(TREG)				ASM_LINE_SEP	\
-	/* Do syscall, delay loads # */		ASM_LINE_SEP	\
-	ble  0x100(%sr2,%r0)			ASM_LINE_SEP	\
-	ldi SYS_ify (syscall_name), %r20	ASM_LINE_SEP	\
-	ldi NO_ERROR,%r1			ASM_LINE_SEP	\
-	cmpb,>>=,n %r1,%ret0,L(pre_end)		ASM_LINE_SEP	\
-	/* Restore r19 from TREG */		ASM_LINE_SEP	\
-	LOAD_PIC(TREG) /* delay */		ASM_LINE_SEP	\
-	SYSCALL_ERROR_HANDLER			ASM_LINE_SEP	\
-	/* Use TREG for temp storage */		ASM_LINE_SEP	\
-	copy %ret0, TREG /* delay */		ASM_LINE_SEP	\
-	/* OPTIMIZE: Don't reload r19 */	ASM_LINE_SEP	\
-	/* do a -1*syscall_ret0 */		ASM_LINE_SEP	\
-	sub %r0, TREG, TREG			ASM_LINE_SEP	\
-	/* Store into errno location */		ASM_LINE_SEP	\
-	stw TREG, 0(%sr0,%ret0)			ASM_LINE_SEP	\
-	/* return -1 as error */		ASM_LINE_SEP	\
-	ldo -1(%r0), %ret0			ASM_LINE_SEP	\
-L(pre_end):					ASM_LINE_SEP	\
-	/* Restore return pointer */		ASM_LINE_SEP	\
-	ldw -84(%sp),%rp			ASM_LINE_SEP	\
-	/* Restore our frame, restoring TREG */	ASM_LINE_SEP	\
-	ldwm -64(%sp), TREG			ASM_LINE_SEP
+#define DO_CALL(syscall_name, args)					\
+  	copy		TREG, %r1			ASM_LINE_SEP	\
+	copy		%sp, TREG			ASM_LINE_SEP	\
+	/* Create a frame */				ASM_LINE_SEP	\
+	stwm		%r1, 64(%sp)			ASM_LINE_SEP	\
+	stw		%rp, -20(%sp)			ASM_LINE_SEP	\
+	stw		TREG, -4(%sp)			ASM_LINE_SEP	\
+	/* Save r19 */					ASM_LINE_SEP	\
+	SAVE_PIC (TREG)					ASM_LINE_SEP	\
+	/* Do syscall, delay loads # */			ASM_LINE_SEP	\
+	ble		0x100(%sr2, %r0)		ASM_LINE_SEP	\
+	ldi		SYS_ify (syscall_name), %r20	ASM_LINE_SEP	\
+	ldi		NO_ERROR, %r1			ASM_LINE_SEP	\
+	cmpb,>>=,n	%r1, %ret0,L(pre_end)		ASM_LINE_SEP	\
+	/* Restore r19 from TREG */			ASM_LINE_SEP	\
+	LOAD_PIC(TREG)			/* delay */	ASM_LINE_SEP	\
+	SYSCALL_ERROR_HANDLER				ASM_LINE_SEP	\
+	/* Use TREG for temp storage */			ASM_LINE_SEP	\
+	copy		%ret0, TREG	/* delay */	ASM_LINE_SEP	\
+	/* OPTIMIZE: Don't reload r19 */		ASM_LINE_SEP	\
+	/* do a -1*syscall_ret0 */			ASM_LINE_SEP	\
+	sub		%r0, TREG, TREG			ASM_LINE_SEP	\
+	/* Store into errno location */			ASM_LINE_SEP	\
+	stw		TREG, 0(%sr0, %ret0)		ASM_LINE_SEP	\
+	/* return -1 as error */			ASM_LINE_SEP	\
+	ldo		-1(%r0), %ret0			ASM_LINE_SEP	\
+L(pre_end):						ASM_LINE_SEP	\
+	/* Restore return pointer */			ASM_LINE_SEP	\
+	ldw		-84(%sp), %rp			ASM_LINE_SEP	\
+	/* Restore our frame, restoring TREG */		ASM_LINE_SEP	\
+	ldwm		-64(%sp), TREG			ASM_LINE_SEP
 
 /* We do nothing with the return, except hand it back to someone else */
 #undef  DO_CALL_NOERRNO
-#define DO_CALL_NOERRNO(syscall_name, args)			\
-	/* No need to store r19 */		ASM_LINE_SEP	\
-	ble  0x100(%sr2,%r0)                    ASM_LINE_SEP    \
-	ldi SYS_ify (syscall_name), %r20        ASM_LINE_SEP    \
-	/* Caller will restore r19 */		ASM_LINE_SEP
+#define DO_CALL_NOERRNO(syscall_name, args)				\
+	/* No need to store r19 */			ASM_LINE_SEP	\
+	ble		0x100(%sr2, %r0)		ASM_LINE_SEP    \
+	ldi		SYS_ify (syscall_name), %r20	ASM_LINE_SEP    \
+	/* Caller will restore r19 */			ASM_LINE_SEP
 
 /* Here, we return the ERRVAL in assembly, note we don't call the
    error handler function, but we do 'negate' the return _IF_
    it's an error. Not sure if this is the right semantic. */
 
 #undef	DO_CALL_ERRVAL
-#define DO_CALL_ERRVAL(syscall_name, args)			\
-	/* No need to store r19 */		ASM_LINE_SEP	\
-	ble  0x100(%sr2,%r0)			ASM_LINE_SEP	\
-	ldi SYS_ify (syscall_name), %r20	ASM_LINE_SEP	\
-	/* Caller will restore r19 */		ASM_LINE_SEP	\
-	ldi NO_ERROR,%r1			ASM_LINE_SEP	\
-	cmpb,>>=,n %r1,%ret0,0f			ASM_LINE_SEP	\
-	sub %r0, %ret0, %ret0			ASM_LINE_SEP	\
-0:						ASM_LINE_SEP
-
+#define DO_CALL_ERRVAL(syscall_name, args)				\
+	/* No need to store r19 */			ASM_LINE_SEP	\
+	ble		0x100(%sr2, %r0)		ASM_LINE_SEP	\
+	ldi		SYS_ify (syscall_name), %r20	ASM_LINE_SEP	\
+	/* Caller will restore r19 */			ASM_LINE_SEP	\
+	ldi		NO_ERROR, %r1			ASM_LINE_SEP	\
+	cmpb,>>=,n	%r1, %ret0, 0f			ASM_LINE_SEP	\
+	sub		%r0, %ret0, %ret0		ASM_LINE_SEP	\
+0:							ASM_LINE_SEP
 
 #else
 
@@ -360,8 +357,8 @@
 		/* FIXME: HACK save/load r19 around syscall */		\
 		asm volatile(						\
 			SAVE_ASM_PIC					\
-			"	ble  0x100(%%sr2, %%r0)\n"		\
-			"	ldi %1, %%r20\n"			\
+			"	ble		0x100(%%sr2, %%r0)\n"	\
+			"	ldi		%1, %%r20\n"		\
 			LOAD_ASM_PIC					\
 			: "=r" (__res)					\
 			: "i" (SYS_ify(name)) ASM_ARGS_##nr		\
@@ -385,7 +382,7 @@
    In our case we just flip the sign. */
 
 #undef INTERNAL_SYSCALL_DECL
-#define INTERNAL_SYSCALL_DECL(err) do { } while (0)
+#define INTERNAL_SYSCALL_DECL(err) 
 
 /* Equivalent to  (val < 0)&&(val > -4095) which is what we want */
 #undef INTERNAL_SYSCALL_ERROR_P
@@ -406,8 +403,8 @@
 		/* FIXME: HACK save/load r19 around syscall */		\
 		asm volatile(						\
 			SAVE_ASM_PIC					\
-			"	ble  0x100(%%sr2, %%r0)\n"		\
-			"	ldi %1, %%r20\n"			\
+			"	ble	0x100(%%sr2, %%r0)\n"		\
+			"	ldi	%1, %%r20\n"			\
 			LOAD_ASM_PIC					\
 			: "=r" (__res)					\
 			: "i" (SYS_ify(name)) ASM_ARGS_##nr		\
@@ -418,25 +415,49 @@
 	__sys_res;							\
  })
 
+
+/* The _NCS variant allows non-constant syscall numbers.  */
+#undef INTERNAL_SYSCALL_NCS
+#define INTERNAL_SYSCALL_NCS(name, err, nr, args...) 			\
+({									\
+	long __sys_res;							\
+	{								\
+		register unsigned long __res asm("r28");		\
+		LOAD_ARGS_##nr(args)					\
+		/* FIXME: HACK save/load r19 around syscall */		\
+		asm volatile(						\
+			SAVE_ASM_PIC					\
+			"	ble	0x100(%%sr2, %%r0)\n"		\
+			"	copy	%1, %%r20\n"			\
+			LOAD_ASM_PIC					\
+			: "=r" (__res)					\
+			: "r" (name) ASM_ARGS_##nr			\
+			: "memory", CALL_CLOB_REGS CLOB_ARGS_##nr	\
+		);							\
+		__sys_res = (long)__res;				\
+	}								\
+	__sys_res;							\
+ })
+
 #define LOAD_ARGS_0()
 #define LOAD_ARGS_1(r26)						\
-  register unsigned long __r26 __asm__("r26") = (unsigned long)(r26);	\
-  LOAD_ARGS_0()
+	register unsigned long __r26 __asm__("r26") = (unsigned long)(r26); \
+	LOAD_ARGS_0()
 #define LOAD_ARGS_2(r26,r25)						\
-  register unsigned long __r25 __asm__("r25") = (unsigned long)(r25);	\
-  LOAD_ARGS_1(r26)
+	register unsigned long __r25 __asm__("r25") = (unsigned long)(r25); \
+	LOAD_ARGS_1(r26)
 #define LOAD_ARGS_3(r26,r25,r24)					\
-  register unsigned long __r24 __asm__("r24") = (unsigned long)(r24);	\
-  LOAD_ARGS_2(r26,r25)
+	register unsigned long __r24 __asm__("r24") = (unsigned long)(r24); \
+	LOAD_ARGS_2(r26,r25)
 #define LOAD_ARGS_4(r26,r25,r24,r23)					\
-  register unsigned long __r23 __asm__("r23") = (unsigned long)(r23);	\
-  LOAD_ARGS_3(r26,r25,r24)
+	register unsigned long __r23 __asm__("r23") = (unsigned long)(r23); \
+	LOAD_ARGS_3(r26,r25,r24)
 #define LOAD_ARGS_5(r26,r25,r24,r23,r22)				\
-  register unsigned long __r22 __asm__("r22") = (unsigned long)(r22);	\
-  LOAD_ARGS_4(r26,r25,r24,r23)
-#define LOAD_ARGS_6(r26,r25,r24,r23,r22,r21)				\
-  register unsigned long __r21 __asm__("r21") = (unsigned long)(r21);	\
-  LOAD_ARGS_5(r26,r25,r24,r23,r22)
+	register unsigned long __r22 __asm__("r22") = (unsigned long)(r22); \
+	LOAD_ARGS_4(r26,r25,r24,r23)
+#define LOAD_ARGS_6(r26,r25,r24,r23,r22,r21)				 \
+	register unsigned long __r21 __asm__("r21") = (unsigned long)(r21); \
+	LOAD_ARGS_5(r26,r25,r24,r23,r22)
 
 /* Even with zero args we use r20 for the syscall number */
 #define ASM_ARGS_0

[-- Attachment #3: tst-clone.S.diff --]
[-- Type: text/plain, Size: 4610 bytes --]

--- glibc-2.3.6/sysdeps/unix/sysv/linux/hppa/clone.S.orig	2006-04-15 15:11:23.000000000 +0200
+++ glibc-2.3.6/sysdeps/unix/sysv/linux/hppa/clone.S	2006-04-15 15:13:02.000000000 +0200
@@ -26,74 +26,121 @@
 #define _ERRNO_H	1
 #include <bits/errno.h>
 
-/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg) */
+/* Non-thread code calls __clone with the following parameters:
+   int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg)
+   
+   NPTL Code will call __clone with the following parameters:
+   int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
+	     int *parent_tidptr, struct user_desc *newtls, int *child_pidptr)
+	
+   The code should not mangle the extra input registers.
+   Syscall expects:				Input to __clone:
+	r26 - clone flags.			(arg2)
+	r25 - user stack pointer.		(arg1)
+	r24 - parent tid pointer.		(stack - 52)
+	r23 - struct user_desc newtls pointer.	(stack - 56)
+	r22 - child tid pointer.		(stack - 60)
+	r20 - clone syscall number		(constant)
+ */
 
         .text
 ENTRY(__clone)
-	/* FIXME: I have no idea how profiling works on hppa. */
+    /* this ENTRY() macro do: stw rp, -20(sp)
+       and "FIXME: I have no idea how profiling works on hppa." */
 
 	/* Sanity check arguments.  */
-	comib,=  0,%arg0,.Lerror        /* no NULL function pointers */
-	ldi     -EINVAL,%ret0
-	comib,=  0,%arg1,.Lerror        /* no NULL stack pointers */
-	nop
-
+	comib,=		0, %arg0, .Larg_error		/* no NULL function pointers */
+	nop						/* delay slot */
+	comib,<>,n	0, %arg1, .Lno_arg_error	/* no NULL stack pointers */
+	nop						/* delay slot */
+
+.Larg_error:
+	/* Create a stack frame */
+	ldo             64(%sp), %sp
+	/* Set errno (in the delay slot) */
+	bl		__syscall_error, %rp
+	ldi		EINVAL, %arg0
+
+	/* Return after setting errno */
+	/* Restore rp from ENTRY() */
+	ldw		-84(%sp), %rp
+	bv		%r0(%rp)
+	ldo             -64(%sp), %sp
+	
+.Lno_arg_error:
 	/* Save the fn ptr and arg on the new stack.  */
-	stwm    %arg0,64(%arg1)
-	stw	%arg3,-60(%arg1)
+	stwm		%arg0, 64(%arg1)
+	stw		%arg3, -60(%arg1)
+	/* Clone arguments are (int flags, void * child_stack) */
+	copy		%arg2, %arg0		/* flags are first */
+	/* User stack pointer is in the correct register already */
+
+	/* Load args from stack... */
+	ldw		-52(%sp), %arg2		/* Load parent_tidptr */
+	ldw		-56(%sp), %arg3		/* Load newtls */
+	ldw		-60(%sp), %r22		/* Load child_tidptr */
+
+	/* Create frame for function */
+	copy		%sp, %r21
+	stwm		%r3, 64(%sp)
+	stw		%r21, -4(%sp)
 
-	/* Save the PIC register. */
-#ifdef PIC
-	stw	%r19,-32(%sr0, %sp)	/* parent */
-#endif
+	SAVE_PIC (TREG)
 
 	/* Do the system call */
-	copy	%arg2,%arg0
-	ble     0x100(%sr2,%r0)
-	ldi	__NR_clone,%r20
-
-	ldi	-4096,%r1
-	comclr,>>= %r1,%ret0,%r0	/* Note: unsigned compare. */
-	b,n	.Lerror
+	ble		0x100(%sr2, %r0)
+	ldi		SYS_ify (clone), %r20
+
+	ldi		NO_ERROR, %r1
+	comclr,>>=	%r1, %ret0, %r0		/* Note: unsigned compare. */
+	ldi		1, %r20
+	comib,=,n	1, %r20, .Lerror
+	nop			/* to avoid next br insn in the delay slot? */
 
-	comib,=,n 0,%ret0,thread_start
+	comib,=,n	0, %ret0, thread_start
+	nop			/* to avoid next br insn in the delay slot? */
 
 	/* Successful return from the parent
 	   No need to restore the PIC register, 
 	   since we return immediately. */
-
-	bv	%r0(%rp)
-	nop
+	bv		%r0(%rp)
+	ldwm		-64(%sp), %r3
 
 	/* Something bad happened -- no child created */
 .Lerror:
 
-	/* Restore the PIC register on error */
-#ifdef PIC
-	ldw	-32(%sr0, %sp), %r19	/* parent */
-#endif
+	LOAD_PIC (TREG)
 
-	b	__syscall_error
-	sub     %r0,%ret0,%arg0
+	/* Use TREG for temp storage */
+	copy		%ret0, TREG
+	/* Set errno (in the delay slot) */
+	bl		__syscall_error, %rp
+	sub		%r0, %ret0, %arg0
+	copy		TREG, %ret0
+	/* Return after setting errno */
+	/* Restore rp from ENTRY() */
+	ldw		-84(%sp), %rp
+	bv		%r0(%rp)
+	ldwm		-64(%sp), %r3
 
 thread_start:
 
 	/* Load up the arguments.  */
-	ldw	-60(%sr0, %sp),%arg0
-	ldw     -64(%sr0, %sp),%r22
+	ldw		-60(%sr0, %sp), %arg0
+	ldw		-64(%sr0, %sp), %r22
 
 	/* $$dyncall fixes childs PIC register */
 
 	/* Call the user's function */
-	bl	$$dyncall,%r31
-	copy	%r31,%rp
+	bl		$$dyncall, %r31
+	copy		%r31, %rp
 
-	bl	_exit,%rp
-	copy	%ret0,%arg0
+	bl		_exit, %rp
+	copy		%ret0, %arg0
 
 	/* Die horribly.  */
-	iitlbp	%r0,(%sr0,%r0)
+	iitlbp		%r0, (%sr0, %r0)
 
 PSEUDO_END(__clone)
 
-weak_alias(__clone, clone)
+weak_alias (__clone, clone)

[-- Attachment #4: Type: text/plain, Size: 169 bytes --]

_______________________________________________
parisc-linux mailing list
parisc-linux@lists.parisc-linux.org
http://lists.parisc-linux.org/mailman/listinfo/parisc-linux

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2006-04-19  8:09 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-04-02 11:46 [parisc-linux] Any good rules of pratice about branching insn into the delay slot of another one? Joel Soete
2006-04-02 15:20 ` [parisc-linux] " Randolph Chung
  -- strict thread matches above, loose matches on Subject: below --
2006-04-19  8:09 Joel Soete

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.