Thorsten Glaser
2011-Jan-29 17:19 UTC
[PATCH] Fix m68k syscall API and support 6-argument syscalls.
Debian: (Closes: #334917) Signed-off-by: Thorsten Glaser <tg at mirbsd.de> --- usr/klibc/arch/m68k/syscall.S | 42 +++++++++++++++++++++++++++++++++------- usr/klibc/arch/m68k/vfork.S | 13 +++-------- 2 files changed, 38 insertions(+), 17 deletions(-) diff --git a/usr/klibc/arch/m68k/syscall.S b/usr/klibc/arch/m68k/syscall.S index 966c92d..f468678 100644 --- a/usr/klibc/arch/m68k/syscall.S +++ b/usr/klibc/arch/m68k/syscall.S @@ -11,17 +11,43 @@ .globl __syscall_common .type __syscall_common, @function __syscall_common: - movem.l %d2-%d6, -(%sp) /* 5 registers saved */ - movem.l 24(%sp), %d1-%d6 + /* + * According to eglibc, separate moves are faster than movem; + * speed is important and this code is not duplicated anyway, + * so we do the same here. We use %a1 as scratch register for + * saving; syscall arguments are to be in %d1 to %d5 and %a0. + */ + move.l 24(%sp), %a0 /* orig.sp+24: arg 6 */ + move.l %d5, -(%sp) /* push d5 (callee saved) */ + move.l 24(%sp), %d5 /* orig.sp+20: arg 5 */ + move.l %d4, -(%sp) /* push d4 (callee saved) */ + move.l 24(%sp), %d4 /* orig.sp+16: arg 4 */ + move.l %d3, -(%sp) /* push d3 (callee saved) */ + move.l 24(%sp), %d3 /* orig.sp+12: arg 3 */ + move.l %d2, %a1 /* save d2 (callee saved) in a1 */ + move.l 20(%sp), %d2 /* orig.sp+8: arg 2 */ + move.l 16(%sp), %d1 /* orig.sp+4: arg 1 */ trap #0 - cmpi.l #-4095, %d0 - blt.l 1f + move.l %a1, %d2 /* restore d2 from a1 (scratch) */ + move.l (%sp)+, %d3 /* pop d3..d5, see above */ + move.l (%sp)+, %d4 + move.l (%sp)+, %d5 + + /* syscall is done, result in %d0, registers are restored */ + .globl __syscall_checkandout +__syscall_checkandout: + /* now check for error */ + cmp.l #-4095, %d0 + bcs.l 1f /* jmp short if _not_ error */ + + /* prepare for error return */ neg.l %d0 move.l %d0, (errno) - moveq #-1, %d0 -1: - movea.l %d0, %a0 /* Redundant return */ - movem.l (%sp)+, %d2-%d6 /* Restore registers */ + move.l #-1, %d0 + /* fallthrough to common return path */ + +1: /* copy return value to %a0 for syscalls returning pointers */ + move.l %d0, %a0 rts .size __syscall_common,.-__syscall_common diff --git a/usr/klibc/arch/m68k/vfork.S b/usr/klibc/arch/m68k/vfork.S index a3a7e44..ec8baeb 100644 --- a/usr/klibc/arch/m68k/vfork.S +++ b/usr/klibc/arch/m68k/vfork.S @@ -15,14 +15,9 @@ vfork: move.l (%sp)+, %d1 /* Return address */ move.l # __NR_vfork, %d0 trap #0 - move.l %d1, -(%sp) - cmpi.l #-4095, %d0 - blt.l 1f - neg.l %d0 - move.l %d0, (errno) - moveq #-1, %d0 -1: - movea.l %d0, %a0 - rts + move.l %d1, -(%sp) /* restore stack */ + + /* common code from syscall.S */ + bra __syscall_checkandout .size vfork, .-vfork -- 1.7.2.3