]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: add support for openbsd/arm
authorJoel Sing <jsing@google.com>
Sun, 15 Feb 2015 15:03:53 +0000 (02:03 +1100)
committerJoel Sing <jsing@google.com>
Sun, 15 Mar 2015 04:06:26 +0000 (04:06 +0000)
Change-Id: I2bc101aa19172e705ee4de5f3c73a8b4bbf4fa6f
Reviewed-on: https://go-review.googlesource.com/4912
Reviewed-by: Minux Ma <minux@golang.org>
src/runtime/defs_openbsd_arm.go [new file with mode: 0644]
src/runtime/os_openbsd_arm.go [new file with mode: 0644]
src/runtime/rt0_freebsd_arm.s
src/runtime/rt0_netbsd_arm.s
src/runtime/rt0_openbsd_arm.s [new file with mode: 0644]
src/runtime/signal_openbsd_arm.go [new file with mode: 0644]
src/runtime/sys_openbsd_arm.s [new file with mode: 0644]

diff --git a/src/runtime/defs_openbsd_arm.go b/src/runtime/defs_openbsd_arm.go
new file mode 100644 (file)
index 0000000..aab9276
--- /dev/null
@@ -0,0 +1,170 @@
+// created by cgo -cdefs and then converted to Go
+// cgo -cdefs defs_openbsd.go
+
+package runtime
+
+import "unsafe"
+
+const (
+       _EINTR  = 0x4
+       _EFAULT = 0xe
+
+       _PROT_NONE  = 0x0
+       _PROT_READ  = 0x1
+       _PROT_WRITE = 0x2
+       _PROT_EXEC  = 0x4
+
+       _MAP_ANON    = 0x1000
+       _MAP_PRIVATE = 0x2
+       _MAP_FIXED   = 0x10
+
+       _MADV_FREE = 0x6
+
+       _SA_SIGINFO = 0x40
+       _SA_RESTART = 0x2
+       _SA_ONSTACK = 0x1
+
+       _SIGHUP    = 0x1
+       _SIGINT    = 0x2
+       _SIGQUIT   = 0x3
+       _SIGILL    = 0x4
+       _SIGTRAP   = 0x5
+       _SIGABRT   = 0x6
+       _SIGEMT    = 0x7
+       _SIGFPE    = 0x8
+       _SIGKILL   = 0x9
+       _SIGBUS    = 0xa
+       _SIGSEGV   = 0xb
+       _SIGSYS    = 0xc
+       _SIGPIPE   = 0xd
+       _SIGALRM   = 0xe
+       _SIGTERM   = 0xf
+       _SIGURG    = 0x10
+       _SIGSTOP   = 0x11
+       _SIGTSTP   = 0x12
+       _SIGCONT   = 0x13
+       _SIGCHLD   = 0x14
+       _SIGTTIN   = 0x15
+       _SIGTTOU   = 0x16
+       _SIGIO     = 0x17
+       _SIGXCPU   = 0x18
+       _SIGXFSZ   = 0x19
+       _SIGVTALRM = 0x1a
+       _SIGPROF   = 0x1b
+       _SIGWINCH  = 0x1c
+       _SIGINFO   = 0x1d
+       _SIGUSR1   = 0x1e
+       _SIGUSR2   = 0x1f
+
+       _FPE_INTDIV = 0x1
+       _FPE_INTOVF = 0x2
+       _FPE_FLTDIV = 0x3
+       _FPE_FLTOVF = 0x4
+       _FPE_FLTUND = 0x5
+       _FPE_FLTRES = 0x6
+       _FPE_FLTINV = 0x7
+       _FPE_FLTSUB = 0x8
+
+       _BUS_ADRALN = 0x1
+       _BUS_ADRERR = 0x2
+       _BUS_OBJERR = 0x3
+
+       _SEGV_MAPERR = 0x1
+       _SEGV_ACCERR = 0x2
+
+       _ITIMER_REAL    = 0x0
+       _ITIMER_VIRTUAL = 0x1
+       _ITIMER_PROF    = 0x2
+
+       _EV_ADD       = 0x1
+       _EV_DELETE    = 0x2
+       _EV_CLEAR     = 0x20
+       _EV_ERROR     = 0x4000
+       _EVFILT_READ  = -0x1
+       _EVFILT_WRITE = -0x2
+)
+
+type tforkt struct {
+       tf_tcb   unsafe.Pointer
+       tf_tid   *int32
+       tf_stack uintptr
+}
+
+type sigaltstackt struct {
+       ss_sp    uintptr
+       ss_size  uintptr
+       ss_flags int32
+}
+
+type sigcontext struct {
+       __sc_unused int32
+       sc_mask     int32
+
+       sc_spsr   uint32
+       sc_r0     uint32
+       sc_r1     uint32
+       sc_r2     uint32
+       sc_r3     uint32
+       sc_r4     uint32
+       sc_r5     uint32
+       sc_r6     uint32
+       sc_r7     uint32
+       sc_r8     uint32
+       sc_r9     uint32
+       sc_r10    uint32
+       sc_r11    uint32
+       sc_r12    uint32
+       sc_usr_sp uint32
+       sc_usr_lr uint32
+       sc_svc_lr uint32
+       sc_pc     uint32
+}
+
+type siginfo struct {
+       si_signo int32
+       si_code  int32
+       si_errno int32
+       _data    [116]byte
+}
+
+type stackt struct {
+       ss_sp    uintptr
+       ss_size  uintptr
+       ss_flags int32
+}
+
+type timespec struct {
+       tv_sec  int64
+       tv_nsec int32
+}
+
+func (ts *timespec) set_sec(x int64) {
+       ts.tv_sec = x
+}
+
+func (ts *timespec) set_nsec(x int32) {
+       ts.tv_nsec = x
+}
+
+type timeval struct {
+       tv_sec  int64
+       tv_usec int32
+}
+
+func (tv *timeval) set_usec(x int32) {
+       tv.tv_usec = x
+}
+
+type itimerval struct {
+       it_interval timeval
+       it_value    timeval
+}
+
+type keventt struct {
+       ident  uint32
+       filter int16
+       flags  uint16
+       fflags uint32
+       data   int64
+       udata  *byte
+}
diff --git a/src/runtime/os_openbsd_arm.go b/src/runtime/os_openbsd_arm.go
new file mode 100644 (file)
index 0000000..be3f330
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime
+
+func checkgoarm() {
+       // TODO(minux)
+}
+
+//go:nosplit
+func cputicks() int64 {
+       // Currently cputicks() is used in blocking profiler and to seed runtime·fastrand1().
+       // runtime·nanotime() is a poor approximation of CPU ticks that is enough for the profiler.
+       // TODO: need more entropy to better seed fastrand1.
+       return nanotime()
+}
index f31252698eab2a3f63629c819585a0368efb2be6..e1bb13d53ae5b697e1b78571d7f9506d8901f235 100644 (file)
@@ -4,10 +4,8 @@
 
 #include "textflag.h"
 
-// FreeBSD and Linux use the same linkage to main
-
 TEXT _rt0_arm_freebsd(SB),NOSPLIT,$-4
-       MOVW    (R13), R0       // argc
+       MOVW    (R13), R0               // argc
        MOVW    $4(R13), R1             // argv
        MOVM.DB.W [R0-R1], (R13)
        B       runtime·rt0_go(SB)
@@ -15,4 +13,4 @@ TEXT _rt0_arm_freebsd(SB),NOSPLIT,$-4
 TEXT main(SB),NOSPLIT,$-4
        MOVM.DB.W [R0-R1], (R13)
        MOVW    $runtime·rt0_go(SB), R4
-       B               (R4)
+       B       (R4)
index bad66e06cfc5365366b59125830210fe7f26a800..2cb1182c06ed7d4121e93f27f7da9592285292df 100644 (file)
@@ -4,10 +4,8 @@
 
 #include "textflag.h"
 
-// FreeBSD/NetBSD and Linux use the same linkage to main
-
 TEXT _rt0_arm_netbsd(SB),NOSPLIT,$-4
-       MOVW    (R13), R0       // argc
+       MOVW    (R13), R0               // argc
        MOVW    $4(R13), R1             // argv
        MOVM.DB.W [R0-R1], (R13)
        B runtime·rt0_go(SB)
diff --git a/src/runtime/rt0_openbsd_arm.s b/src/runtime/rt0_openbsd_arm.s
new file mode 100644 (file)
index 0000000..6207e55
--- /dev/null
@@ -0,0 +1,11 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT _rt0_arm_openbsd(SB),NOSPLIT,$-4
+       MOVW    (R13), R0               // argc
+       MOVW    $4(R13), R1             // argv
+       MOVM.DB.W [R0-R1], (R13)
+       B       runtime·rt0_go(SB)
diff --git a/src/runtime/signal_openbsd_arm.go b/src/runtime/signal_openbsd_arm.go
new file mode 100644 (file)
index 0000000..8ee255c
--- /dev/null
@@ -0,0 +1,53 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime
+
+import "unsafe"
+
+type sigctxt struct {
+       info *siginfo
+       ctxt unsafe.Pointer
+}
+
+func (c *sigctxt) regs() *sigcontext {
+       return (*sigcontext)(c.ctxt)
+}
+
+func (c *sigctxt) r0() uint32      { return c.regs().sc_r0 }
+func (c *sigctxt) r1() uint32      { return c.regs().sc_r1 }
+func (c *sigctxt) r2() uint32      { return c.regs().sc_r2 }
+func (c *sigctxt) r3() uint32      { return c.regs().sc_r3 }
+func (c *sigctxt) r4() uint32      { return c.regs().sc_r4 }
+func (c *sigctxt) r5() uint32      { return c.regs().sc_r5 }
+func (c *sigctxt) r6() uint32      { return c.regs().sc_r6 }
+func (c *sigctxt) r7() uint32      { return c.regs().sc_r7 }
+func (c *sigctxt) r8() uint32      { return c.regs().sc_r8 }
+func (c *sigctxt) r9() uint32      { return c.regs().sc_r9 }
+func (c *sigctxt) r10() uint32     { return c.regs().sc_r10 }
+func (c *sigctxt) fp() uint32      { return c.regs().sc_r11 }
+func (c *sigctxt) ip() uint32      { return c.regs().sc_r12 }
+func (c *sigctxt) sp() uint32      { return c.regs().sc_usr_sp }
+func (c *sigctxt) lr() uint32      { return c.regs().sc_usr_lr }
+func (c *sigctxt) pc() uint32      { return c.regs().sc_pc }
+func (c *sigctxt) cpsr() uint32    { return c.regs().sc_spsr }
+func (c *sigctxt) fault() uint32   { return c.sigaddr() }
+func (c *sigctxt) trap() uint32    { return 0 }
+func (c *sigctxt) error() uint32   { return 0 }
+func (c *sigctxt) oldmask() uint32 { return 0 }
+
+func (c *sigctxt) sigcode() uint32 { return uint32(c.info.si_code) }
+func (c *sigctxt) sigaddr() uint32 {
+       return *(*uint32)(add(unsafe.Pointer(c.info), 12))
+}
+
+func (c *sigctxt) set_pc(x uint32)  { c.regs().sc_pc = x }
+func (c *sigctxt) set_sp(x uint32)  { c.regs().sc_usr_sp = x }
+func (c *sigctxt) set_lr(x uint32)  { c.regs().sc_usr_lr = x }
+func (c *sigctxt) set_r10(x uint32) { c.regs().sc_r10 = x }
+
+func (c *sigctxt) set_sigcode(x uint32) { c.info.si_code = int32(x) }
+func (c *sigctxt) set_sigaddr(x uint32) {
+       *(*uint32)(add(unsafe.Pointer(c.info), 12)) = x
+}
diff --git a/src/runtime/sys_openbsd_arm.s b/src/runtime/sys_openbsd_arm.s
new file mode 100644 (file)
index 0000000..bc9dbdd
--- /dev/null
@@ -0,0 +1,377 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+//
+// System calls and other sys.stuff for ARM, OpenBSD
+// /usr/src/sys/kern/syscalls.master for syscall numbers.
+//
+
+#include "go_asm.h"
+#include "go_tls.h"
+#include "textflag.h"
+
+#define CLOCK_REALTIME $0
+#define        CLOCK_MONOTONIC $3
+
+// Exit the entire program (like C exit)
+TEXT runtime·exit(SB),NOSPLIT,$-4
+       MOVW    status+0(FP), R0        // arg 1 - status
+       MOVW    $1, R12                 // sys_exit
+       SWI     $0
+       MOVW.CS $0, R8                  // crash on syscall failure
+       MOVW.CS R8, (R8)
+       RET
+
+TEXT runtime·exit1(SB),NOSPLIT,$-4
+       MOVW    $0, R0                  // arg 1 - notdead
+       MOVW    $302, R12               // sys___threxit
+       SWI     $0
+       MOVW.CS $1, R8                  // crash on syscall failure
+       MOVW.CS R8, (R8)
+       RET
+
+TEXT runtime·open(SB),NOSPLIT,$-4
+       MOVW    path+0(FP), R0          // arg 1 - path
+       MOVW    flags+4(FP), R1         // arg 2 - flags
+       MOVW    mode+8(FP), R2          // arg 3 - mode
+       MOVW    $5, R12                 // sys_open
+       SWI     $0
+       MOVW    R0, ret+12(FP)
+       RET
+
+TEXT runtime·close(SB),NOSPLIT,$-4
+       MOVW    path+0(FP), R0          // arg 1 - path
+       MOVW    $6, R12                 // sys_close
+       SWI     $0
+       MOVW    R0, ret+4(FP)
+       RET
+
+TEXT runtime·read(SB),NOSPLIT,$-4
+       MOVW    fd+0(FP), R0            // arg 1 - fd
+       MOVW    buf+4(FP), R1           // arg 2 - buf
+       MOVW    nbyte+8(FP), R2         // arg 3 - nbyte
+       MOVW    $3, R12                 // sys_read
+       SWI     $0
+       MOVW    R0, ret+12(FP)
+       RET
+
+TEXT runtime·write(SB),NOSPLIT,$-4
+       MOVW    fd+0(FP), R0            // arg 1 - fd
+       MOVW    buf+4(FP), R1           // arg 2 - buf
+       MOVW    nbyte+8(FP), R2         // arg 3 - nbyte
+       MOVW    $4, R12                 // sys_write
+       SWI     $0
+       MOVW    R0, ret+12(FP)
+       RET
+
+TEXT runtime·usleep(SB),NOSPLIT,$16
+       MOVW    usec+0(FP), R0
+       MOVW    R0, R2
+       MOVW    $1000000, R1
+       DIV     R1, R0
+       MOVW    R0, 4(R13)              // tv_sec - l32
+       MOVW    $0, R0
+       MOVW    R0, 8(R13)              // tv_sec - h32
+       MOD     R1, R2
+       MOVW    $1000, R1
+       MUL     R1, R2
+       MOVW    R2, 12(R13)             // tv_nsec
+
+       MOVW    $4(R13), R0             // arg 1 - rqtp
+       MOVW    $0, R1                  // arg 2 - rmtp
+       MOVW    $91, R12                // sys_nanosleep
+       SWI     $0
+       RET
+
+TEXT runtime·raise(SB),NOSPLIT,$12
+       MOVW    $0x12B, R12
+       SWI     $0                      // sys_getthrid
+                                       // arg 1 - pid, already in R0
+       MOVW    sig+0(FP), R1           // arg 2 - signum
+       MOVW    $37, R12                // sys_kill
+       SWI     $0
+       RET
+
+TEXT runtime·mmap(SB),NOSPLIT,$16
+       MOVW    addr+0(FP), R0          // arg 1 - addr
+       MOVW    len+4(FP), R1           // arg 2 - len
+       MOVW    prot+8(FP), R2          // arg 3 - prot
+       MOVW    flags+12(FP), R3        // arg 4 - flags
+       MOVW    fd+16(FP), R4           // arg 5 - fd (on stack)
+       MOVW    R4, 4(R13)
+       MOVW    $0, R5                  // arg 6 - pad (on stack)
+       MOVW    R5, 8(R13)
+       MOVW    offset+20(FP), R6       // arg 7 - offset (on stack)
+       MOVW    R6, 12(R13)             // lower 32 bits (from Go runtime)
+       MOVW    $0, R7
+       MOVW    R7, 16(R13)             // high 32 bits
+       ADD     $4, R13
+       MOVW    $197, R12               // sys_mmap
+       SWI     $0
+       SUB     $4, R13
+       MOVW    R0, ret+24(FP)
+       RET
+
+TEXT runtime·munmap(SB),NOSPLIT,$0
+       MOVW    addr+0(FP), R0          // arg 1 - addr
+       MOVW    len+4(FP), R1           // arg 2 - len
+       MOVW    $73, R12                // sys_munmap
+       SWI     $0
+       MOVW.CS $0, R8                  // crash on syscall failure
+       MOVW.CS R8, (R8)
+       RET
+
+TEXT runtime·madvise(SB),NOSPLIT,$0
+       MOVW    addr+0(FP), R0          // arg 1 - addr
+       MOVW    len+4(FP), R1           // arg 2 - len
+       MOVW    behav+8(FP), R2         // arg 2 - behav
+       MOVW    $75, R12                // sys_madvise
+       SWI     $0
+       MOVW.CS $0, R8                  // crash on syscall failure
+       MOVW.CS R8, (R8)
+       RET
+
+TEXT runtime·setitimer(SB),NOSPLIT,$0
+       MOVW    which+0(FP), R0         // arg 1 - which
+       MOVW    value+4(FP), R1         // arg 2 - value
+       MOVW    ovalue+8(FP), R2        // arg 3 - ovalue
+       MOVW    $69, R12                // sys_setitimer
+       SWI     $0
+       RET
+
+// func now() (sec int64, nsec int32)
+TEXT time·now(SB), NOSPLIT, $32
+       MOVW    CLOCK_REALTIME, R0      // arg 1 - clock_id
+       MOVW    $8(R13), R1             // arg 2 - tp
+       MOVW    $87, R12                // sys_clock_gettime
+       SWI     $0
+
+       MOVW    8(R13), R0              // sec - l32
+       MOVW    12(R13), R1             // sec - h32
+       MOVW    16(R13), R2             // nsec
+
+       MOVW    R0, sec_lo+0(FP)
+       MOVW    R1, sec_hi+4(FP)
+       MOVW    R2, nsec+8(FP)
+
+       RET
+
+// int64 nanotime(void) so really
+// void nanotime(int64 *nsec)
+TEXT runtime·nanotime(SB),NOSPLIT,$32
+       MOVW    CLOCK_MONOTONIC, R0     // arg 1 - clock_id
+       MOVW    $8(R13), R1             // arg 2 - tp
+       MOVW    $87, R12                // sys_clock_gettime
+       SWI     $0
+
+       MOVW    8(R13), R0              // sec - l32
+       MOVW    12(R13), R4             // sec - h32
+       MOVW    16(R13), R2             // nsec
+
+       MOVW    $1000000000, R3
+       MULLU   R0, R3, (R1, R0)
+       MUL     R3, R4
+       ADD.S   R2, R0
+       ADC     R4, R1
+
+       MOVW    R0, ret_lo+0(FP)
+       MOVW    R1, ret_hi+4(FP)
+       RET
+
+TEXT runtime·sigaction(SB),NOSPLIT,$0
+       MOVW    signum+0(FP), R0        // arg 1 - signum
+       MOVW    nsa+4(FP), R1           // arg 2 - nsa
+       MOVW    osa+8(FP), R2           // arg 3 - osa
+       MOVW    $46, R12                // sys_sigaction
+       SWI     $0
+       MOVW.CS $3, R8                  // crash on syscall failure
+       MOVW.CS R8, (R8)
+       RET
+
+TEXT runtime·sigprocmask(SB),NOSPLIT,$0
+       MOVW    how+0(FP), R0           // arg 1 - how
+       MOVW    mask+4(FP), R1          // arg 2 - mask
+       MOVW    $48, R12                // sys_sigprocmask
+       SWI     $0
+       MOVW.CS $3, R8                  // crash on syscall failure
+       MOVW.CS R8, (R8)
+       MOVW    R0, ret+8(FP)
+       RET
+
+TEXT runtime·sigtramp(SB),NOSPLIT,$24
+       // If called from an external code context, g will not be set.
+       // Save R0, since runtime·load_g will clobber it.
+       MOVW    R0, 4(R13)              // signum
+       MOVB    runtime·iscgo(SB), R0
+       CMP     $0, R0
+       BL.NE   runtime·load_g(SB)
+
+       CMP     $0, g
+       BNE     4(PC)
+       // Signal number saved in 4(R13).
+       MOVW    runtime·badsignal(SB), R11
+       BL      (R11)
+       RET
+
+       // Save g.
+       MOVW    g, R3
+       MOVW    g, 20(R13)
+
+       // g = m->signal
+       MOVW    g_m(g), R8
+       MOVW    m_gsignal(R8), g
+
+       // R0 already saved.
+       MOVW    R1, 8(R13)              // info
+       MOVW    R2, 12(R13)             // context
+       MOVW    R3, 16(R13)             // gp (original g)
+
+       BL      runtime·sighandler(SB)
+
+       // Restore g.
+       MOVW    20(R13), g
+       RET
+
+// int32 tfork(void *param, uintptr psize, M *mp, G *gp, void (*fn)(void));
+TEXT runtime·tfork(SB),NOSPLIT,$0
+
+       // Copy mp, gp and fn off parent stack for use by child.
+       MOVW    mm+8(FP), R4
+       MOVW    gg+12(FP), R5
+       MOVW    fn+16(FP), R6
+
+       MOVW    param+0(FP), R0         // arg 1 - param
+       MOVW    psize+4(FP), R1         // arg 2 - psize
+       MOVW    $8, R12                 // sys___tfork
+       SWI     $0
+
+       // Return if syscall failed.
+       B.CC    4(PC)
+       RSB     $0, R0
+       MOVW    R0, ret+20(FP)
+       RET
+
+       // In parent, return.
+       CMP     $0, R0
+       BEQ     3(PC)
+       MOVW    R0, ret+20(FP)
+       RET
+
+       // Initialise m, g.
+       MOVW    R5, g
+       MOVW    R4, g_m(g)
+
+       // Paranoia; check that stack splitting code works.
+       BL      runtime·emptyfunc(SB)
+
+       // Call fn.
+       BL      (R6)
+
+       BL      runtime·exit1(SB)
+       MOVW    $2, R8                  // crash if reached
+       MOVW    R8, (R8)
+       RET
+
+TEXT runtime·sigaltstack(SB),NOSPLIT,$0
+       MOVW    nss+0(FP), R0           // arg 1 - nss
+       MOVW    oss+4(FP), R1           // arg 2 - oss
+       MOVW    $288, R12               // sys_sigaltstack
+       SWI     $0
+       MOVW.CS $0, R8                  // crash on syscall failure
+       MOVW.CS R8, (R8)
+       RET
+
+TEXT runtime·osyield(SB),NOSPLIT,$0
+       MOVW    $298, R12               // sys_sched_yield
+       SWI     $0
+       RET
+
+TEXT runtime·thrsleep(SB),NOSPLIT,$4
+       MOVW    ident+0(FP), R0         // arg 1 - ident
+       MOVW    clock_id+4(FP), R1      // arg 2 - clock_id
+       MOVW    tp+8(FP), R2            // arg 3 - tp
+       MOVW    lock+12(FP), R3         // arg 4 - lock
+       MOVW    abort+16(FP), R4        // arg 5 - abort (on stack)
+       MOVW    R4, 4(R13)
+       ADD     $4, R13
+       MOVW    $94, R12                // sys___thrsleep
+       SWI     $0
+       SUB     $4, R13
+       MOVW    R0, ret+20(FP)
+       RET
+
+TEXT runtime·thrwakeup(SB),NOSPLIT,$0
+       MOVW    ident+0(FP), R0         // arg 1 - ident
+       MOVW    n+4(FP), R1             // arg 2 - n
+       MOVW    $301, R12               // sys___thrwakeup
+       SWI     $0
+       MOVW    R0, ret+8(FP)
+       RET
+
+TEXT runtime·sysctl(SB),NOSPLIT,$8
+       MOVW    name+0(FP), R0          // arg 1 - name
+       MOVW    namelen+4(FP), R1       // arg 2 - namelen
+       MOVW    oldp+8(FP), R2          // arg 3 - oldp
+       MOVW    oldlenp+12(FP), R3      // arg 4 - oldlenp
+       MOVW    newp+16(FP), R4         // arg 5 - newp (on stack)
+       MOVW    R4, 4(R13)
+       MOVW    newlen+20(FP), R5       // arg 6 - newlen (on stack)
+       MOVW    R5, 8(R13)
+       ADD     $4, R13
+       MOVW    $202, R12               // sys___sysctl
+       SWI     $0
+       SUB     $4, R13
+       MOVW.CC $0, R0
+       RSB.CS  $0, R0
+       MOVW    R0, ret+24(FP)
+       RET
+
+// int32 runtime·kqueue(void);
+TEXT runtime·kqueue(SB),NOSPLIT,$0
+       MOVW    $269, R12               // sys_kqueue
+       SWI     $0
+       RSB.CS  $0, R0
+       MOVW    R0, ret+0(FP)
+       RET
+
+// int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout);
+TEXT runtime·kevent(SB),NOSPLIT,$8
+       MOVW    fd+0(FP), R0            // arg 1 - fd
+       MOVW    changelist+4(FP), R1    // arg 2 - changelist
+       MOVW    nchanges+8(FP), R2      // arg 3 - nchanges
+       MOVW    eventlist+12(FP), R3    // arg 4 - eventlist
+       MOVW    nevents+16(FP), R4      // arg 5 - nevents (on stack)
+       MOVW    R4, 4(R13)
+       MOVW    timeout+20(FP), R5      // arg 6 - timeout (on stack)
+       MOVW    R5, 8(R13)
+       ADD     $4, R13
+       MOVW    $72, R12                // sys_kevent
+       SWI     $0
+       RSB.CS  $0, R0
+       SUB     $4, R13
+       MOVW    R0, ret+24(FP)
+       RET
+
+// int32 runtime·closeonexec(int32 fd);
+TEXT runtime·closeonexec(SB),NOSPLIT,$0
+       MOVW    fd+0(FP), R0            // arg 1 - fd
+       MOVW    $2, R1                  // arg 2 - cmd (F_SETFD)
+       MOVW    $1, R2                  // arg 3 - arg (FD_CLOEXEC)
+       MOVW    $92, R12                // sys_fcntl
+       SWI     $0
+       RSB.CS  $0, R0
+       MOVW    R0, ret+4(FP)
+       RET
+
+TEXT runtime·casp1(SB),NOSPLIT,$0
+       //B     runtime·armcas(SB)
+       B       runtime·cas(SB)
+
+TEXT runtime·cas(SB),NOSPLIT,$0
+       B       runtime·armcas(SB)
+
+// TODO(jsing): Implement.
+TEXT runtime·read_tls_fallback(SB),NOSPLIT,$-4
+       MOVW    $5, R0
+       MOVW    R0, (R0)
+       RET