* [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.