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-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 ` Randolph Chung
  0 siblings, 0 replies; 3+ messages in thread
From: Randolph Chung @ 2006-04-02 15:20 UTC (permalink / raw)
  To: Joel Soete; +Cc: John David Anglin, parisc-linux

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

why don't you try to step through the code with gdb (using stepi) and 
see the sequence of insns that get executed in the different cases?

randolph
_______________________________________________
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.