diff options
| author | Kai Backman <kaib@golang.org> | 2009-10-29 21:21:14 -0700 |
|---|---|---|
| committer | Kai Backman <kaib@golang.org> | 2009-10-29 21:21:14 -0700 |
| commit | 770b87275223b9b0530b73063d8ee33b796b135b (patch) | |
| tree | 6446f27f00b75965077e9dee96e6eaeacf57b046 /src/pkg/runtime/linux/arm/sys.s | |
| parent | 09d68334cc9da0f6d6db65c8e155f3dc3eb03d9e (diff) | |
| download | go-770b87275223b9b0530b73063d8ee33b796b135b.tar.xz | |
clone and futex
go/test: passes 99% (343/347)
R=rsc
http://go/go-review/1016004
Diffstat (limited to 'src/pkg/runtime/linux/arm/sys.s')
| -rw-r--r-- | src/pkg/runtime/linux/arm/sys.s | 92 |
1 files changed, 87 insertions, 5 deletions
diff --git a/src/pkg/runtime/linux/arm/sys.s b/src/pkg/runtime/linux/arm/sys.s index 2d45955815..2d70adf827 100644 --- a/src/pkg/runtime/linux/arm/sys.s +++ b/src/pkg/runtime/linux/arm/sys.s @@ -6,10 +6,16 @@ // System calls and other sys.stuff for arm, Linux // +#include "arm/asm.h" + #define SYS_BASE 0x00900000 #define SYS_exit (SYS_BASE + 1) #define SYS_write (SYS_BASE + 4) +#define SYS_clone (SYS_BASE + 120) #define SYS_mmap2 (SYS_BASE + 192) +#define SYS_gettid (SYS_BASE + 224) +#define SYS_futex (SYS_BASE + 240) +#define SYS_exit_group (SYS_BASE + 248) TEXT write(SB),7,$0 MOVW 0(FP), R0 @@ -20,7 +26,17 @@ TEXT write(SB),7,$0 TEXT exit(SB),7,$-4 MOVW 0(FP), R0 + SWI $SYS_exit_group + MOVW $1234, R0 + MOVW $1002, R1 + MOVW R0, (R1) // fail hard + +TEXT exit1(SB),7,$-4 + MOVW 0(FP), R0 SWI $SYS_exit + MOVW $1234, R0 + MOVW $1003, R1 + MOVW R0, (R1) // fail hard TEXT runtime·mmap(SB),7,$0 MOVW 0(FP), R0 @@ -32,13 +48,79 @@ TEXT runtime·mmap(SB),7,$0 SWI $SYS_mmap2 RET -// int64 futex(int32 *uaddr, int32 op, int32 val, +// int32 futex(int32 *uaddr, int32 op, int32 val, // struct timespec *timeout, int32 *uaddr2, int32 val2); TEXT futex(SB),7,$0 - BL abort(SB) + MOVW 4(SP), R0 + MOVW 8(SP), R1 + MOVW 12(SP), R2 + MOVW 16(SP), R3 + MOVW 20(SP), R4 + MOVW 24(SP), R5 + SWI $SYS_futex RET -// int64 clone(int32 flags, void *stack, M *m, G *g, void (*fn)(void)); + +// int32 clone(int32 flags, void *stack, M *m, G *g, void (*fn)(void)); TEXT clone(SB),7,$0 - BL abort(SB) - RET + MOVW flags+0(FP), R0 + MOVW stack+4(FP), R1 + MOVW $0, R2 // parent tid ptr + MOVW $0, R3 // tls_val + MOVW $0, R4 // child tid ptr + MOVW $0, R5 + + // Copy m, g, fn off parent stack for use by child. + // TODO(kaib): figure out which registers are clobbered by clone and avoid stack copying + MOVW $-16(R1), R1 + MOVW mm+8(FP), R6 + MOVW R6, 0(R1) + MOVW gg+12(FP), R6 + MOVW R6, 4(R1) + MOVW fn+16(FP), R6 + MOVW R6, 8(R1) + MOVW $1234, R6 + MOVW R6, 12(R1) + + SWI $SYS_clone + + // In parent, return. + CMP $0, R0 + BEQ 2(PC) + RET + + // Paranoia: check that SP is as we expect. Use R13 to avoid linker 'fixup' + MOVW 12(R13), R0 + MOVW $1234, R1 + CMP R0, R1 + BEQ 2(PC) + B abort(SB) + + MOVW 0(R13), m + MOVW 4(R13), g + + // paranoia; check they are not nil + MOVW 0(m), R0 + MOVW 0(g), R0 + + BL emptyfunc(SB) // fault if stack check is wrong + + // Initialize m->procid to Linux tid + SWI $SYS_gettid + MOVW R0, m_procid(m) + + // Call fn + MOVW 8(R13), R0 + MOVW $16(R13), R13 + BL (R0) + + MOVW $0, R0 + MOVW R0, 4(R13) + BL exit1(SB) + + // It shouldn't return + MOVW $1234, R0 + MOVW $1005, R1 + MOVW R0, (R1) + + |
