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