Only exe buildmode without cgo supported.
Change-Id: Id104a79a99d3285c04db00fd98b8affa94ea3c37
Reviewed-on: https://go-review.googlesource.com/31487
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
--- /dev/null
+// Copyright 2016 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.
+
+// +build mips mipsle
+
+#include "go_asm.h"
+#include "go_tls.h"
+#include "funcdata.h"
+#include "textflag.h"
+
+#define REGCTXT R22
+
+TEXT runtime·rt0_go(SB),NOSPLIT,$0
+ // R29 = stack; R1 = argc; R2 = argv
+
+ ADDU $-12, R29
+ MOVW R1, 4(R29) // argc
+ MOVW R2, 8(R29) // argv
+
+ // create istack out of the given (operating system) stack.
+ // _cgo_init may update stackguard.
+ MOVW $runtime·g0(SB), g
+ MOVW $(-64*1024), R23
+ ADD R23, R29, R1
+ MOVW R1, g_stackguard0(g)
+ MOVW R1, g_stackguard1(g)
+ MOVW R1, (g_stack+stack_lo)(g)
+ MOVW R29, (g_stack+stack_hi)(g)
+
+// TODO(mips32): cgo
+
+nocgo:
+ // update stackguard after _cgo_init
+ MOVW (g_stack+stack_lo)(g), R1
+ ADD $const__StackGuard, R1
+ MOVW R1, g_stackguard0(g)
+ MOVW R1, g_stackguard1(g)
+
+ // set the per-goroutine and per-mach "registers"
+ MOVW $runtime·m0(SB), R1
+
+ // save m->g0 = g0
+ MOVW g, m_g0(R1)
+ // save m0 to g0->m
+ MOVW R1, g_m(g)
+
+ JAL runtime·check(SB)
+
+ // args are already prepared
+ JAL runtime·args(SB)
+ JAL runtime·osinit(SB)
+ JAL runtime·schedinit(SB)
+
+ // create a new goroutine to start program
+ MOVW $runtime·mainPC(SB), R1 // entry
+ ADDU $-12, R29
+ MOVW R1, 8(R29)
+ MOVW R0, 4(R29)
+ MOVW R0, 0(R29)
+ JAL runtime·newproc(SB)
+ ADDU $12, R29
+
+ // start this M
+ JAL runtime·mstart(SB)
+
+ UNDEF
+ RET
+
+DATA runtime·mainPC+0(SB)/4,$runtime·main(SB)
+GLOBL runtime·mainPC(SB),RODATA,$4
+
+TEXT runtime·breakpoint(SB),NOSPLIT,$0-0
+ BREAK
+ RET
+
+TEXT runtime·asminit(SB),NOSPLIT,$0-0
+ RET
+
+/*
+ * go-routine
+ */
+
+// void gosave(Gobuf*)
+// save state in Gobuf; setjmp
+TEXT runtime·gosave(SB),NOSPLIT,$-4-4
+ MOVW buf+0(FP), R1
+ MOVW R29, gobuf_sp(R1)
+ MOVW R31, gobuf_pc(R1)
+ MOVW g, gobuf_g(R1)
+ MOVW R0, gobuf_lr(R1)
+ MOVW R0, gobuf_ret(R1)
+ // Assert ctxt is zero. See func save.
+ MOVW gobuf_ctxt(R1), R1
+ BEQ R1, 2(PC)
+ JAL runtime·badctxt(SB)
+ RET
+
+// void gogo(Gobuf*)
+// restore state from Gobuf; longjmp
+TEXT runtime·gogo(SB),NOSPLIT,$8-4
+ MOVW buf+0(FP), R3
+
+ // If ctxt is not nil, invoke deletion barrier before overwriting.
+ MOVW gobuf_ctxt(R3), R1
+ BEQ R1, nilctxt
+ MOVW $gobuf_ctxt(R3), R1
+ MOVW R1, 4(R29)
+ MOVW R0, 8(R29)
+ JAL runtime·writebarrierptr_prewrite(SB)
+ MOVW buf+0(FP), R3
+
+nilctxt:
+ MOVW gobuf_g(R3), g // make sure g is not nil
+ JAL runtime·save_g(SB)
+
+ MOVW 0(g), R2
+ MOVW gobuf_sp(R3), R29
+ MOVW gobuf_lr(R3), R31
+ MOVW gobuf_ret(R3), R1
+ MOVW gobuf_ctxt(R3), REGCTXT
+ MOVW R0, gobuf_sp(R3)
+ MOVW R0, gobuf_ret(R3)
+ MOVW R0, gobuf_lr(R3)
+ MOVW R0, gobuf_ctxt(R3)
+ MOVW gobuf_pc(R3), R4
+ JMP (R4)
+
+// void mcall(fn func(*g))
+// Switch to m->g0's stack, call fn(g).
+// Fn must never return. It should gogo(&g->sched)
+// to keep running g.
+TEXT runtime·mcall(SB),NOSPLIT,$-4-4
+ // Save caller state in g->sched
+ MOVW R29, (g_sched+gobuf_sp)(g)
+ MOVW R31, (g_sched+gobuf_pc)(g)
+ MOVW R0, (g_sched+gobuf_lr)(g)
+ MOVW g, (g_sched+gobuf_g)(g)
+
+ // Switch to m->g0 & its stack, call fn.
+ MOVW g, R1
+ MOVW g_m(g), R3
+ MOVW m_g0(R3), g
+ JAL runtime·save_g(SB)
+ BNE g, R1, 2(PC)
+ JMP runtime·badmcall(SB)
+ MOVW fn+0(FP), REGCTXT // context
+ MOVW 0(REGCTXT), R4 // code pointer
+ MOVW (g_sched+gobuf_sp)(g), R29 // sp = m->g0->sched.sp
+ ADDU $-8, R29 // make room for 1 arg and fake LR
+ MOVW R1, 4(R29)
+ MOVW R0, 0(R29)
+ JAL (R4)
+ JMP runtime·badmcall2(SB)
+
+// systemstack_switch is a dummy routine that systemstack leaves at the bottom
+// of the G stack. We need to distinguish the routine that
+// lives at the bottom of the G stack from the one that lives
+// at the top of the system stack because the one at the top of
+// the system stack terminates the stack walk (see topofstack()).
+TEXT runtime·systemstack_switch(SB),NOSPLIT,$0-0
+ UNDEF
+ JAL (R31) // make sure this function is not leaf
+ RET
+
+// func systemstack(fn func())
+TEXT runtime·systemstack(SB),NOSPLIT,$0-4
+ MOVW fn+0(FP), R1 // R1 = fn
+ MOVW R1, REGCTXT // context
+ MOVW g_m(g), R2 // R2 = m
+
+ MOVW m_gsignal(R2), R3 // R3 = gsignal
+ BEQ g, R3, noswitch
+
+ MOVW m_g0(R2), R3 // R3 = g0
+ BEQ g, R3, noswitch
+
+ MOVW m_curg(R2), R4
+ BEQ g, R4, switch
+
+ // Bad: g is not gsignal, not g0, not curg. What is it?
+ // Hide call from linker nosplit analysis.
+ MOVW $runtime·badsystemstack(SB), R4
+ JAL (R4)
+
+switch:
+ // save our state in g->sched. Pretend to
+ // be systemstack_switch if the G stack is scanned.
+ MOVW $runtime·systemstack_switch(SB), R4
+ ADDU $8, R4 // get past prologue
+ MOVW R4, (g_sched+gobuf_pc)(g)
+ MOVW R29, (g_sched+gobuf_sp)(g)
+ MOVW R0, (g_sched+gobuf_lr)(g)
+ MOVW g, (g_sched+gobuf_g)(g)
+
+ // switch to g0
+ MOVW R3, g
+ JAL runtime·save_g(SB)
+ MOVW (g_sched+gobuf_sp)(g), R1
+ // make it look like mstart called systemstack on g0, to stop traceback
+ ADDU $-4, R1
+ MOVW $runtime·mstart(SB), R2
+ MOVW R2, 0(R1)
+ MOVW R1, R29
+
+ // call target function
+ MOVW 0(REGCTXT), R4 // code pointer
+ JAL (R4)
+
+ // switch back to g
+ MOVW g_m(g), R1
+ MOVW m_curg(R1), g
+ JAL runtime·save_g(SB)
+ MOVW (g_sched+gobuf_sp)(g), R29
+ MOVW R0, (g_sched+gobuf_sp)(g)
+ RET
+
+noswitch:
+ // already on m stack, just call directly
+ MOVW 0(REGCTXT), R4 // code pointer
+ JAL (R4)
+ RET
+
+/*
+ * support for morestack
+ */
+
+// Called during function prolog when more stack is needed.
+// Caller has already loaded:
+// R1: framesize, R2: argsize, R3: LR
+//
+// The traceback routines see morestack on a g0 as being
+// the top of a stack (for example, morestack calling newstack
+// calling the scheduler calling newm calling gc), so we must
+// record an argument size. For that purpose, it has no arguments.
+TEXT runtime·morestack(SB),NOSPLIT,$-4-0
+ // Cannot grow scheduler stack (m->g0).
+ MOVW g_m(g), R7
+ MOVW m_g0(R7), R8
+ BNE g, R8, 3(PC)
+ JAL runtime·badmorestackg0(SB)
+ JAL runtime·abort(SB)
+
+ // Cannot grow signal stack (m->gsignal).
+ MOVW m_gsignal(R7), R8
+ BNE g, R8, 3(PC)
+ JAL runtime·badmorestackgsignal(SB)
+ JAL runtime·abort(SB)
+
+ // Called from f.
+ // Set g->sched to context in f.
+ MOVW R29, (g_sched+gobuf_sp)(g)
+ MOVW R31, (g_sched+gobuf_pc)(g)
+ MOVW R3, (g_sched+gobuf_lr)(g)
+ // newstack will fill gobuf.ctxt.
+
+ // Called from f.
+ // Set m->morebuf to f's caller.
+ MOVW R3, (m_morebuf+gobuf_pc)(R7) // f's caller's PC
+ MOVW R29, (m_morebuf+gobuf_sp)(R7) // f's caller's SP
+ MOVW g, (m_morebuf+gobuf_g)(R7)
+
+ // Call newstack on m->g0's stack.
+ MOVW m_g0(R7), g
+ JAL runtime·save_g(SB)
+ MOVW (g_sched+gobuf_sp)(g), R29
+ // Create a stack frame on g0 to call newstack.
+ MOVW R0, -8(R29) // Zero saved LR in frame
+ ADDU $-8, R29
+ MOVW REGCTXT, 4(R29) // ctxt argument
+ JAL runtime·newstack(SB)
+
+ // Not reached, but make sure the return PC from the call to newstack
+ // is still in this function, and not the beginning of the next.
+ UNDEF
+
+TEXT runtime·morestack_noctxt(SB),NOSPLIT,$0-0
+ MOVW R0, REGCTXT
+ JMP runtime·morestack(SB)
+
+TEXT runtime·stackBarrier(SB),NOSPLIT,$0
+ // We came here via a RET to an overwritten LR.
+ // R1 may be live. Other registers are available.
+
+ // Get the original return PC, g.stkbar[g.stkbarPos].savedLRVal.
+ MOVW (g_stkbar+slice_array)(g), R2
+ MOVW g_stkbarPos(g), R3
+ MOVW $stkbar__size, R4
+ MULU R3, R4
+ MOVW LO, R4
+ ADDU R2, R4
+ MOVW stkbar_savedLRVal(R4), R4
+ ADDU $1, R3
+ MOVW R3, g_stkbarPos(g) // Record that this stack barrier was hit.
+ JMP (R4) // Jump to the original return PC.
+
+// reflectcall: call a function with the given argument list
+// func call(argtype *_type, f *FuncVal, arg *byte, argsize, retoffset uint32).
+// we don't have variable-sized frames, so we use a small number
+// of constant-sized-frame functions to encode a few bits of size in the pc.
+
+#define DISPATCH(NAME,MAXSIZE) \
+ MOVW $MAXSIZE, R23; \
+ SGTU R1, R23, R23; \
+ BNE R23, 3(PC); \
+ MOVW $NAME(SB), R4; \
+ JMP (R4)
+
+TEXT reflect·call(SB),NOSPLIT,$0-20
+ JMP ·reflectcall(SB)
+
+TEXT ·reflectcall(SB),NOSPLIT,$-4-20
+ MOVW argsize+12(FP), R1
+
+ DISPATCH(runtime·call16, 16)
+ DISPATCH(runtime·call32, 32)
+ DISPATCH(runtime·call64, 64)
+ DISPATCH(runtime·call128, 128)
+ DISPATCH(runtime·call256, 256)
+ DISPATCH(runtime·call512, 512)
+ DISPATCH(runtime·call1024, 1024)
+ DISPATCH(runtime·call2048, 2048)
+ DISPATCH(runtime·call4096, 4096)
+ DISPATCH(runtime·call8192, 8192)
+ DISPATCH(runtime·call16384, 16384)
+ DISPATCH(runtime·call32768, 32768)
+ DISPATCH(runtime·call65536, 65536)
+ DISPATCH(runtime·call131072, 131072)
+ DISPATCH(runtime·call262144, 262144)
+ DISPATCH(runtime·call524288, 524288)
+ DISPATCH(runtime·call1048576, 1048576)
+ DISPATCH(runtime·call2097152, 2097152)
+ DISPATCH(runtime·call4194304, 4194304)
+ DISPATCH(runtime·call8388608, 8388608)
+ DISPATCH(runtime·call16777216, 16777216)
+ DISPATCH(runtime·call33554432, 33554432)
+ DISPATCH(runtime·call67108864, 67108864)
+ DISPATCH(runtime·call134217728, 134217728)
+ DISPATCH(runtime·call268435456, 268435456)
+ DISPATCH(runtime·call536870912, 536870912)
+ DISPATCH(runtime·call1073741824, 1073741824)
+ MOVW $runtime·badreflectcall(SB), R4
+ JMP (R4)
+
+#define CALLFN(NAME,MAXSIZE) \
+TEXT NAME(SB),WRAPPER,$MAXSIZE-20; \
+ NO_LOCAL_POINTERS; \
+ /* copy arguments to stack */ \
+ MOVW arg+8(FP), R1; \
+ MOVW argsize+12(FP), R2; \
+ MOVW R29, R3; \
+ ADDU $4, R3; \
+ ADDU R3, R2; \
+ BEQ R3, R2, 6(PC); \
+ MOVBU (R1), R4; \
+ ADDU $1, R1; \
+ MOVBU R4, (R3); \
+ ADDU $1, R3; \
+ JMP -5(PC); \
+ /* call function */ \
+ MOVW f+4(FP), REGCTXT; \
+ MOVW (REGCTXT), R4; \
+ PCDATA $PCDATA_StackMapIndex, $0; \
+ JAL (R4); \
+ /* copy return values back */ \
+ MOVW argtype+0(FP), R5; \
+ MOVW arg+8(FP), R1; \
+ MOVW n+12(FP), R2; \
+ MOVW retoffset+16(FP), R4; \
+ ADDU $4, R29, R3; \
+ ADDU R4, R3; \
+ ADDU R4, R1; \
+ SUBU R4, R2; \
+ JAL callRet<>(SB); \
+ RET
+
+// callRet copies return values back at the end of call*. This is a
+// separate function so it can allocate stack space for the arguments
+// to reflectcallmove. It does not follow the Go ABI; it expects its
+// arguments in registers.
+TEXT callRet<>(SB), NOSPLIT, $16-0
+ MOVW R5, 4(R29)
+ MOVW R1, 8(R29)
+ MOVW R3, 12(R29)
+ MOVW R2, 16(R29)
+ JAL runtime·reflectcallmove(SB)
+ RET
+
+CALLFN(·call16, 16)
+CALLFN(·call32, 32)
+CALLFN(·call64, 64)
+CALLFN(·call128, 128)
+CALLFN(·call256, 256)
+CALLFN(·call512, 512)
+CALLFN(·call1024, 1024)
+CALLFN(·call2048, 2048)
+CALLFN(·call4096, 4096)
+CALLFN(·call8192, 8192)
+CALLFN(·call16384, 16384)
+CALLFN(·call32768, 32768)
+CALLFN(·call65536, 65536)
+CALLFN(·call131072, 131072)
+CALLFN(·call262144, 262144)
+CALLFN(·call524288, 524288)
+CALLFN(·call1048576, 1048576)
+CALLFN(·call2097152, 2097152)
+CALLFN(·call4194304, 4194304)
+CALLFN(·call8388608, 8388608)
+CALLFN(·call16777216, 16777216)
+CALLFN(·call33554432, 33554432)
+CALLFN(·call67108864, 67108864)
+CALLFN(·call134217728, 134217728)
+CALLFN(·call268435456, 268435456)
+CALLFN(·call536870912, 536870912)
+CALLFN(·call1073741824, 1073741824)
+
+TEXT runtime·procyield(SB),NOSPLIT,$0-4
+ RET
+
+// void jmpdefer(fv, sp);
+// called from deferreturn.
+// 1. grab stored LR for caller
+// 2. sub 8 bytes to get back to JAL deferreturn
+// 3. JMP to fn
+TEXT runtime·jmpdefer(SB),NOSPLIT,$0-8
+ MOVW 0(R29), R31
+ ADDU $-8, R31
+
+ MOVW fv+0(FP), REGCTXT
+ MOVW argp+4(FP), R29
+ ADDU $-4, R29
+ NOR R0, R0 // prevent scheduling
+ MOVW 0(REGCTXT), R4
+ JMP (R4)
+
+// Save state of caller into g->sched. Smashes R1.
+TEXT gosave<>(SB),NOSPLIT,$0
+ MOVW R31, (g_sched+gobuf_pc)(g)
+ MOVW R29, (g_sched+gobuf_sp)(g)
+ MOVW R0, (g_sched+gobuf_lr)(g)
+ MOVW R0, (g_sched+gobuf_ret)(g)
+ // Assert ctxt is zero. See func save.
+ MOVW (g_sched+gobuf_ctxt)(g), R1
+ BEQ R1, 2(PC)
+ JAL runtime·badctxt(SB)
+ RET
+
+// func asmcgocall(fn, arg unsafe.Pointer) int32
+// Call fn(arg) on the scheduler stack,
+// aligned appropriately for the gcc ABI.
+// See cgocall.go for more details.
+// Not implemented.
+TEXT ·asmcgocall(SB),NOSPLIT,$0-12
+ UNDEF
+
+// cgocallback(void (*fn)(void*), void *frame, uintptr framesize)
+// Turn the fn into a Go func (by taking its address) and call
+// cgocallback_gofunc.
+// Not implemented.
+TEXT runtime·cgocallback(SB),NOSPLIT,$0-16
+ UNDEF
+
+// cgocallback_gofunc(FuncVal*, void *frame, uintptr framesize)
+// See cgocall.go for more details.
+// Not implemented.
+TEXT ·cgocallback_gofunc(SB),NOSPLIT,$0-16
+ UNDEF
+
+// void setg(G*); set g. for use by needm.
+// This only happens if iscgo, so jump straight to save_g
+TEXT runtime·setg(SB),NOSPLIT,$0-4
+ MOVW gg+0(FP), g
+ JAL runtime·save_g(SB)
+ RET
+
+// void setg_gcc(G*); set g in C TLS.
+// Must obey the gcc calling convention.
+// Not implemented.
+TEXT setg_gcc<>(SB),NOSPLIT,$0
+ UNDEF
+
+TEXT runtime·getcallerpc(SB),NOSPLIT,$4-8
+ MOVW 8(R29), R1 // LR saved by caller
+ MOVW runtime·stackBarrierPC(SB), R2
+ BNE R1, R2, nobar
+ JAL runtime·nextBarrierPC(SB) // Get original return PC.
+ MOVW 4(R29), R1
+nobar:
+ MOVW R1, ret+4(FP)
+ RET
+
+TEXT runtime·setcallerpc(SB),NOSPLIT,$4-8
+ MOVW pc+4(FP), R1
+ MOVW 8(R29), R2
+ MOVW runtime·stackBarrierPC(SB), R3
+ BEQ R2, R3, setbar
+ MOVW R1, 8(R29) // set LR in caller
+ RET
+setbar:
+ MOVW R1, 4(R29)
+ JAL runtime·setNextBarrierPC(SB) // Set the stack barrier return PC.
+ RET
+
+TEXT runtime·abort(SB),NOSPLIT,$0-0
+ UNDEF
+
+// memhash_varlen(p unsafe.Pointer, h seed) uintptr
+// redirects to memhash(p, h, size) using the size
+// stored in the closure.
+TEXT runtime·memhash_varlen(SB),NOSPLIT,$16-12
+ GO_ARGS
+ NO_LOCAL_POINTERS
+ MOVW p+0(FP), R1
+ MOVW h+4(FP), R2
+ MOVW 4(REGCTXT), R3
+ MOVW R1, 4(R29)
+ MOVW R2, 8(R29)
+ MOVW R3, 12(R29)
+ JAL runtime·memhash(SB)
+ MOVW 16(R29), R1
+ MOVW R1, ret+8(FP)
+ RET
+
+// Not implemented.
+TEXT runtime·aeshash(SB),NOSPLIT,$0
+ UNDEF
+
+// Not implemented.
+TEXT runtime·aeshash32(SB),NOSPLIT,$0
+ UNDEF
+
+// Not implemented.
+TEXT runtime·aeshash64(SB),NOSPLIT,$0
+ UNDEF
+
+// Not implemented.
+TEXT runtime·aeshashstr(SB),NOSPLIT,$0
+ UNDEF
+
+// memequal(a, b unsafe.Pointer, size uintptr) bool
+TEXT runtime·memequal(SB),NOSPLIT,$0-13
+ MOVW a+0(FP), R1
+ MOVW b+4(FP), R2
+ BEQ R1, R2, eq
+ MOVW size+8(FP), R3
+ ADDU R1, R3, R4
+loop:
+ BNE R1, R4, test
+ MOVW $1, R1
+ MOVB R1, ret+12(FP)
+ RET
+test:
+ MOVBU (R1), R6
+ ADDU $1, R1
+ MOVBU (R2), R7
+ ADDU $1, R2
+ BEQ R6, R7, loop
+
+ MOVB R0, ret+12(FP)
+ RET
+eq:
+ MOVW $1, R1
+ MOVB R1, ret+12(FP)
+ RET
+
+// memequal_varlen(a, b unsafe.Pointer) bool
+TEXT runtime·memequal_varlen(SB),NOSPLIT,$0-9
+ MOVW a+0(FP), R1
+ MOVW b+4(FP), R2
+ BEQ R1, R2, eq
+ MOVW 4(REGCTXT), R3 // compiler stores size at offset 4 in the closure
+ ADDU R1, R3, R4
+loop:
+ BNE R1, R4, test
+ MOVW $1, R1
+ MOVB R1, ret+8(FP)
+ RET
+test:
+ MOVBU (R1), R6
+ ADDU $1, R1
+ MOVBU (R2), R7
+ ADDU $1, R2
+ BEQ R6, R7, loop
+
+ MOVB R0, ret+8(FP)
+ RET
+eq:
+ MOVW $1, R1
+ MOVB R1, ret+8(FP)
+ RET
+
+// eqstring tests whether two strings are equal.
+// The compiler guarantees that strings passed
+// to eqstring have equal length.
+// See runtime_test.go:eqstring_generic for
+// equivalent Go code.
+TEXT runtime·eqstring(SB),NOSPLIT,$0-17
+ MOVW s1_base+0(FP), R1
+ MOVW s2_base+8(FP), R2
+ MOVW $1, R3
+ MOVBU R3, ret+16(FP)
+ BNE R1, R2, 2(PC)
+ RET
+ MOVW s1_len+4(FP), R3
+ ADDU R1, R3, R4
+loop:
+ BNE R1, R4, 2(PC)
+ RET
+ MOVBU (R1), R6
+ ADDU $1, R1
+ MOVBU (R2), R7
+ ADDU $1, R2
+ BEQ R6, R7, loop
+ MOVB R0, ret+16(FP)
+ RET
+
+TEXT bytes·Equal(SB),NOSPLIT,$0-25
+ MOVW a_len+4(FP), R3
+ MOVW b_len+16(FP), R4
+ BNE R3, R4, noteq // unequal lengths are not equal
+
+ MOVW a+0(FP), R1
+ MOVW b+12(FP), R2
+ ADDU R1, R3 // end
+
+loop:
+ BEQ R1, R3, equal // reached the end
+ MOVBU (R1), R6
+ ADDU $1, R1
+ MOVBU (R2), R7
+ ADDU $1, R2
+ BEQ R6, R7, loop
+
+noteq:
+ MOVB R0, ret+24(FP)
+ RET
+
+equal:
+ MOVW $1, R1
+ MOVB R1, ret+24(FP)
+ RET
+
+TEXT bytes·IndexByte(SB),NOSPLIT,$0-20
+ MOVW s+0(FP), R1
+ MOVW s_len+4(FP), R2
+ MOVBU c+12(FP), R3 // byte to find
+ ADDU $1, R1, R4 // store base+1 for later
+ ADDU R1, R2 // end
+
+loop:
+ BEQ R1, R2, notfound
+ MOVBU (R1), R5
+ ADDU $1, R1
+ BNE R3, R5, loop
+
+ SUBU R4, R1 // R1 will be one beyond the position we want so remove (base+1)
+ MOVW R1, ret+16(FP)
+ RET
+
+notfound:
+ MOVW $-1, R1
+ MOVW R1, ret+16(FP)
+ RET
+
+TEXT strings·IndexByte(SB),NOSPLIT,$0-16
+ MOVW s_base+0(FP), R1
+ MOVW s_len+4(FP), R2
+ MOVBU c+8(FP), R3 // byte to find
+ ADDU $1, R1, R4 // store base+1 for later
+ ADDU R1, R2 // end
+
+loop:
+ BEQ R1, R2, notfound
+ MOVBU (R1), R5
+ ADDU $1, R1
+ BNE R3, R5, loop
+
+ SUBU R4, R1 // remove (base+1)
+ MOVW R1, ret+12(FP)
+ RET
+
+notfound:
+ MOVW $-1, R1
+ MOVW R1, ret+12(FP)
+ RET
+
+TEXT runtime·cmpstring(SB),NOSPLIT,$0-20
+ MOVW s1_base+0(FP), R3
+ MOVW s1_len+4(FP), R1
+ MOVW s2_base+8(FP), R4
+ MOVW s2_len+12(FP), R2
+ BEQ R3, R4, samebytes
+ SGTU R1, R2, R7
+ MOVW R1, R8
+ CMOVN R7, R2, R8 // R8 is min(R1, R2)
+
+ ADDU R3, R8 // R3 is current byte in s1, R8 is last byte in s1 to compare
+loop:
+ BEQ R3, R8, samebytes // all compared bytes were the same; compare lengths
+
+ MOVBU (R3), R6
+ ADDU $1, R3
+ MOVBU (R4), R7
+ ADDU $1, R4
+ BEQ R6, R7 , loop
+ // bytes differed
+ SGTU R6, R7, R8
+ MOVW $-1, R6
+ CMOVZ R8, R6, R8
+ JMP cmp_ret
+samebytes:
+ SGTU R1, R2, R6
+ SGTU R2, R1, R7
+ SUBU R7, R6, R8
+cmp_ret:
+ MOVW R8, ret+16(FP)
+ RET
+
+TEXT bytes·Compare(SB),NOSPLIT,$0-28
+ MOVW s1_base+0(FP), R3
+ MOVW s2_base+12(FP), R4
+ MOVW s1_len+4(FP), R1
+ MOVW s2_len+16(FP), R2
+ BEQ R3, R4, samebytes
+ SGTU R1, R2, R7
+ MOVW R1, R8
+ CMOVN R7, R2, R8 // R8 is min(R1, R2)
+
+ ADDU R3, R8 // R3 is current byte in s1, R8 is last byte in s1 to compare
+loop:
+ BEQ R3, R8, samebytes
+
+ MOVBU (R3), R6
+ ADDU $1, R3
+ MOVBU (R4), R7
+ ADDU $1, R4
+ BEQ R6, R7 , loop
+
+ SGTU R6, R7, R8
+ MOVW $-1, R6
+ CMOVZ R8, R6, R8
+ JMP cmp_ret
+samebytes:
+ SGTU R1, R2, R6
+ SGTU R2, R1, R7
+ SUBU R7, R6, R8
+cmp_ret:
+ MOVW R8, ret+24(FP)
+ RET
+
+TEXT runtime·fastrand(SB),NOSPLIT,$0-4
+ MOVW g_m(g), R2
+ MOVW m_fastrand(R2), R1
+ ADDU R1, R1
+ BGEZ R1, 2(PC)
+ XOR $0x88888eef, R1
+ MOVW R1, m_fastrand(R2)
+ MOVW R1, ret+0(FP)
+ RET
+
+TEXT runtime·return0(SB),NOSPLIT,$0
+ MOVW $0, R1
+ RET
+
+// Called from cgo wrappers, this function returns g->m->curg.stack.hi.
+// Must obey the gcc calling convention.
+// Not implemented.
+TEXT _cgo_topofstack(SB),NOSPLIT,$-4
+ UNDEF
+
+// The top-most function running on a goroutine
+// returns to goexit+PCQuantum.
+TEXT runtime·goexit(SB),NOSPLIT,$-4-0
+ NOR R0, R0 // NOP
+ JAL runtime·goexit1(SB) // does not return
+ // traceback from goexit1 must hit code range of goexit
+ NOR R0, R0 // NOP
+
+TEXT runtime·prefetcht0(SB),NOSPLIT,$0-4
+ RET
+
+TEXT runtime·prefetcht1(SB),NOSPLIT,$0-4
+ RET
+
+TEXT runtime·prefetcht2(SB),NOSPLIT,$0-4
+ RET
+
+TEXT runtime·prefetchnta(SB),NOSPLIT,$0-4
+ RET
+
+TEXT ·checkASM(SB),NOSPLIT,$0-1
+ MOVW $1, R1
+ MOVB R1, ret+0(FP)
+ RET
--- /dev/null
+// Copyright 2016 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.
+
+// +build mips mipsle
+
+#include "textflag.h"
+
+TEXT ·publicationBarrier(SB),NOSPLIT,$0
+ SYNC
+ RET
// +build !arm64
// +build !mips64
// +build !mips64le
+// +build !mips
+// +build !mipsle
package runtime
--- /dev/null
+// Copyright 2016 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.
+
+// +build mips mipsle
+// +build linux
+
+package runtime
+
+const (
+ _EINTR = 0x4
+ _EAGAIN = 0xb
+ _ENOMEM = 0xc
+
+ _PROT_NONE = 0x0
+ _PROT_READ = 0x1
+ _PROT_WRITE = 0x2
+ _PROT_EXEC = 0x4
+
+ _MAP_ANON = 0x800
+ _MAP_PRIVATE = 0x2
+ _MAP_FIXED = 0x10
+
+ _MADV_DONTNEED = 0x4
+ _MADV_HUGEPAGE = 0xe
+ _MADV_NOHUGEPAGE = 0xf
+
+ _SA_RESTART = 0x10000000
+ _SA_ONSTACK = 0x8000000
+ _SA_SIGINFO = 0x8
+
+ _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
+ _SIGUSR1 = 0x10
+ _SIGUSR2 = 0x11
+ _SIGCHLD = 0x12
+ _SIGPWR = 0x13
+ _SIGWINCH = 0x14
+ _SIGURG = 0x15
+ _SIGIO = 0x16
+ _SIGSTOP = 0x17
+ _SIGTSTP = 0x18
+ _SIGCONT = 0x19
+ _SIGTTIN = 0x1a
+ _SIGTTOU = 0x1b
+ _SIGVTALRM = 0x1c
+ _SIGPROF = 0x1d
+ _SIGXCPU = 0x1e
+ _SIGXFSZ = 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
+
+ _EPOLLIN = 0x1
+ _EPOLLOUT = 0x4
+ _EPOLLERR = 0x8
+ _EPOLLHUP = 0x10
+ _EPOLLRDHUP = 0x2000
+ _EPOLLET = 0x80000000
+ _EPOLL_CLOEXEC = 0x80000
+ _EPOLL_CTL_ADD = 0x1
+ _EPOLL_CTL_DEL = 0x2
+ _EPOLL_CTL_MOD = 0x3
+)
+
+type timespec struct {
+ tv_sec int32
+ tv_nsec int32
+}
+
+//go:nosplit
+func (ts *timespec) set_sec(x int64) {
+ ts.tv_sec = int32(x)
+}
+
+//go:nosplit
+func (ts *timespec) set_nsec(x int32) {
+ ts.tv_nsec = x
+}
+
+type timeval struct {
+ tv_sec int32
+ tv_usec int32
+}
+
+//go:nosplit
+func (tv *timeval) set_usec(x int32) {
+ tv.tv_usec = x
+}
+
+type sigactiont struct {
+ sa_flags uint32
+ sa_handler uintptr
+ sa_mask [4]uint32
+ // linux header does not have sa_restorer field,
+ // but it is used in setsig(). it is no harm to put it here
+ sa_restorer uintptr
+}
+
+type siginfo struct {
+ si_signo int32
+ si_code int32
+ si_errno int32
+ // below here is a union; si_addr is the only field we use
+ si_addr uint32
+}
+
+type itimerval struct {
+ it_interval timeval
+ it_value timeval
+}
+
+type epollevent struct {
+ events uint32
+ pad_cgo_0 [4]byte
+ data uint64
+}
+
+const (
+ _O_RDONLY = 0x0
+ _O_CLOEXEC = 0x80000
+ _SA_RESTORER = 0
+)
+
+type stackt struct {
+ ss_sp *byte
+ ss_size uintptr
+ ss_flags int32
+}
+
+type sigcontext struct {
+ sc_regmask uint32
+ sc_status uint32
+ sc_pc uint64
+ sc_regs [32]uint64
+ sc_fpregs [32]uint64
+ sc_acx uint32
+ sc_fpc_csr uint32
+ sc_fpc_eir uint32
+ sc_used_math uint32
+ sc_dsp uint32
+ sc_mdhi uint64
+ sc_mdlo uint64
+ sc_hi1 uint32
+ sc_lo1 uint32
+ sc_hi2 uint32
+ sc_lo2 uint32
+ sc_hi3 uint32
+ sc_lo3 uint32
+}
+
+type ucontext struct {
+ uc_flags uint32
+ uc_link *ucontext
+ uc_stack stackt
+ Pad_cgo_0 [4]byte
+ uc_mcontext sigcontext
+ uc_sigmask [4]uint32
+}
func infoBigStruct() []byte {
switch runtime.GOARCH {
- case "386", "arm":
+ case "386", "arm", "mips", "mipsle":
return []byte{
typePointer, // q *int
typeScalar, typeScalar, typeScalar, typeScalar, typeScalar, // w byte; e [17]byte
// xxhash: https://code.google.com/p/xxhash/
// cityhash: https://code.google.com/p/cityhash/
-// +build 386 arm
+// +build 386 arm mips mipsle
package runtime
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build 386 arm nacl
+// +build 386 arm nacl mips mipsle
package runtime
// See https://golang.org/issue/5402 and https://golang.org/issue/5236.
// On other 64-bit platforms, we limit the arena to 512GB, or 39 bits.
// On 32-bit, we don't bother limiting anything, so we use the full 32-bit address.
+ // The only exception is mips32 which only has access to low 2GB of virtual memory.
// On Darwin/arm64, we cannot reserve more than ~5GB of virtual memory,
// but as most devices have less than 4GB of physical memory anyway, we
// try to be conservative here, and only ask for a 2GB heap.
- _MHeapMap_TotalBits = (_64bit*sys.GoosWindows)*35 + (_64bit*(1-sys.GoosWindows)*(1-sys.GoosDarwin*sys.GoarchArm64))*39 + sys.GoosDarwin*sys.GoarchArm64*31 + (1-_64bit)*32
+ _MHeapMap_TotalBits = (_64bit*sys.GoosWindows)*35 + (_64bit*(1-sys.GoosWindows)*(1-sys.GoosDarwin*sys.GoarchArm64))*39 + sys.GoosDarwin*sys.GoarchArm64*31 + (1-_64bit)*(32-(sys.GoarchMips+sys.GoarchMipsle))
_MHeapMap_Bits = _MHeapMap_TotalBits - _PageShift
_MaxMem = uintptr(1<<_MHeapMap_TotalBits - 1)
--- /dev/null
+// Copyright 2016 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.
+
+// +build mips mipsle
+
+#include "textflag.h"
+
+#ifdef GOARCH_mips
+#define MOVWHI MOVWL
+#define MOVWLO MOVWR
+#else
+#define MOVWHI MOVWR
+#define MOVWLO MOVWL
+#endif
+
+// void runtime·memclrNoHeapPointers(void*, uintptr)
+TEXT runtime·memclrNoHeapPointers(SB),NOSPLIT,$0-8
+ MOVW n+4(FP), R2
+ MOVW ptr+0(FP), R1
+
+ SGTU $4, R2, R3
+ ADDU R2, R1, R4
+ BNE R3, small_zero
+
+ptr_align:
+ AND $3, R1, R3
+ BEQ R3, setup
+ SUBU R1, R0, R3
+ AND $3, R3 // R3 contains number of bytes needed to align ptr
+ MOVWHI R0, 0(R1) // MOVWHI will write zeros up to next word boundary
+ SUBU R3, R2
+ ADDU R3, R1
+
+setup:
+ AND $31, R2, R6
+ AND $3, R2, R5
+ SUBU R6, R4, R6 // end pointer for 32-byte chunks
+ SUBU R5, R4, R5 // end pointer for 4-byte chunks
+
+large:
+ BEQ R1, R6, words
+ MOVW R0, 0(R1)
+ MOVW R0, 4(R1)
+ MOVW R0, 8(R1)
+ MOVW R0, 12(R1)
+ MOVW R0, 16(R1)
+ MOVW R0, 20(R1)
+ MOVW R0, 24(R1)
+ MOVW R0, 28(R1)
+ ADDU $32, R1
+ JMP large
+
+words:
+ BEQ R1, R5, tail
+ MOVW R0, 0(R1)
+ ADDU $4, R1
+ JMP words
+
+tail:
+ BEQ R1, R4, ret
+ MOVWLO R0, -1(R4)
+
+ret:
+ RET
+
+small_zero:
+ BEQ R1, R4, ret
+ MOVB R0, 0(R1)
+ ADDU $1, R1
+ JMP small_zero
--- /dev/null
+// Copyright 2016 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.
+
+// +build mips mipsle
+
+#include "textflag.h"
+
+#ifdef GOARCH_mips
+#define MOVWHI MOVWL
+#define MOVWLO MOVWR
+#else
+#define MOVWHI MOVWR
+#define MOVWLO MOVWL
+#endif
+
+// void runtime·memmove(void*, void*, uintptr)
+TEXT runtime·memmove(SB),NOSPLIT,$-0-12
+ MOVW n+8(FP), R3
+ MOVW from+4(FP), R2
+ MOVW to+0(FP), R1
+
+ ADDU R3, R2, R4 // end pointer for source
+ ADDU R3, R1, R5 // end pointer for destination
+
+ // if destination is ahead of source, start at the end of the buffer and go backward.
+ SGTU R1, R2, R6
+ BNE R6, backward
+
+ // if less than 4 bytes, use byte by byte copying
+ SGTU $4, R3, R6
+ BNE R6, f_small_copy
+
+ // align destination to 4 bytes
+ AND $3, R1, R6
+ BEQ R6, f_dest_aligned
+ SUBU R1, R0, R6
+ AND $3, R6
+ MOVWHI 0(R2), R7
+ SUBU R6, R3
+ MOVWLO 3(R2), R7
+ ADDU R6, R2
+ MOVWHI R7, 0(R1)
+ ADDU R6, R1
+
+f_dest_aligned:
+ AND $31, R3, R7
+ AND $3, R3, R6
+ SUBU R7, R5, R7 // end pointer for 32-byte chunks
+ SUBU R6, R5, R6 // end pointer for 4-byte chunks
+
+ // if source is not aligned, use unaligned reads
+ AND $3, R2, R8
+ BNE R8, f_large_ua
+
+f_large:
+ BEQ R1, R7, f_words
+ ADDU $32, R1
+ MOVW 0(R2), R8
+ MOVW 4(R2), R9
+ MOVW 8(R2), R10
+ MOVW 12(R2), R11
+ MOVW 16(R2), R12
+ MOVW 20(R2), R13
+ MOVW 24(R2), R14
+ MOVW 28(R2), R15
+ ADDU $32, R2
+ MOVW R8, -32(R1)
+ MOVW R9, -28(R1)
+ MOVW R10, -24(R1)
+ MOVW R11, -20(R1)
+ MOVW R12, -16(R1)
+ MOVW R13, -12(R1)
+ MOVW R14, -8(R1)
+ MOVW R15, -4(R1)
+ JMP f_large
+
+f_words:
+ BEQ R1, R6, f_tail
+ ADDU $4, R1
+ MOVW 0(R2), R8
+ ADDU $4, R2
+ MOVW R8, -4(R1)
+ JMP f_words
+
+f_tail:
+ BEQ R1, R5, ret
+ MOVWLO -1(R4), R8
+ MOVWLO R8, -1(R5)
+
+ret:
+ RET
+
+f_large_ua:
+ BEQ R1, R7, f_words_ua
+ ADDU $32, R1
+ MOVWHI 0(R2), R8
+ MOVWHI 4(R2), R9
+ MOVWHI 8(R2), R10
+ MOVWHI 12(R2), R11
+ MOVWHI 16(R2), R12
+ MOVWHI 20(R2), R13
+ MOVWHI 24(R2), R14
+ MOVWHI 28(R2), R15
+ MOVWLO 3(R2), R8
+ MOVWLO 7(R2), R9
+ MOVWLO 11(R2), R10
+ MOVWLO 15(R2), R11
+ MOVWLO 19(R2), R12
+ MOVWLO 23(R2), R13
+ MOVWLO 27(R2), R14
+ MOVWLO 31(R2), R15
+ ADDU $32, R2
+ MOVW R8, -32(R1)
+ MOVW R9, -28(R1)
+ MOVW R10, -24(R1)
+ MOVW R11, -20(R1)
+ MOVW R12, -16(R1)
+ MOVW R13, -12(R1)
+ MOVW R14, -8(R1)
+ MOVW R15, -4(R1)
+ JMP f_large_ua
+
+f_words_ua:
+ BEQ R1, R6, f_tail_ua
+ MOVWHI 0(R2), R8
+ ADDU $4, R1
+ MOVWLO 3(R2), R8
+ ADDU $4, R2
+ MOVW R8, -4(R1)
+ JMP f_words_ua
+
+f_tail_ua:
+ BEQ R1, R5, ret
+ MOVWHI -4(R4), R8
+ MOVWLO -1(R4), R8
+ MOVWLO R8, -1(R5)
+ JMP ret
+
+f_small_copy:
+ BEQ R1, R5, ret
+ ADDU $1, R1
+ MOVB 0(R2), R6
+ ADDU $1, R2
+ MOVB R6, -1(R1)
+ JMP f_small_copy
+
+backward:
+ SGTU $4, R3, R6
+ BNE R6, b_small_copy
+
+ AND $3, R5, R6
+ BEQ R6, b_dest_aligned
+ MOVWHI -4(R4), R7
+ SUBU R6, R3
+ MOVWLO -1(R4), R7
+ SUBU R6, R4
+ MOVWLO R7, -1(R5)
+ SUBU R6, R5
+
+b_dest_aligned:
+ AND $31, R3, R7
+ AND $3, R3, R6
+ ADDU R7, R1, R7
+ ADDU R6, R1, R6
+
+ AND $3, R4, R8
+ BNE R8, b_large_ua
+
+b_large:
+ BEQ R5, R7, b_words
+ ADDU $-32, R5
+ MOVW -4(R4), R8
+ MOVW -8(R4), R9
+ MOVW -12(R4), R10
+ MOVW -16(R4), R11
+ MOVW -20(R4), R12
+ MOVW -24(R4), R13
+ MOVW -28(R4), R14
+ MOVW -32(R4), R15
+ ADDU $-32, R4
+ MOVW R8, 28(R5)
+ MOVW R9, 24(R5)
+ MOVW R10, 20(R5)
+ MOVW R11, 16(R5)
+ MOVW R12, 12(R5)
+ MOVW R13, 8(R5)
+ MOVW R14, 4(R5)
+ MOVW R15, 0(R5)
+ JMP b_large
+
+b_words:
+ BEQ R5, R6, b_tail
+ ADDU $-4, R5
+ MOVW -4(R4), R8
+ ADDU $-4, R4
+ MOVW R8, 0(R5)
+ JMP b_words
+
+b_tail:
+ BEQ R5, R1, ret
+ MOVWHI 0(R2), R8 // R2 and R1 have the same alignment so we don't need to load a whole word
+ MOVWHI R8, 0(R1)
+ JMP ret
+
+b_large_ua:
+ BEQ R5, R7, b_words_ua
+ ADDU $-32, R5
+ MOVWHI -4(R4), R8
+ MOVWHI -8(R4), R9
+ MOVWHI -12(R4), R10
+ MOVWHI -16(R4), R11
+ MOVWHI -20(R4), R12
+ MOVWHI -24(R4), R13
+ MOVWHI -28(R4), R14
+ MOVWHI -32(R4), R15
+ MOVWLO -1(R4), R8
+ MOVWLO -5(R4), R9
+ MOVWLO -9(R4), R10
+ MOVWLO -13(R4), R11
+ MOVWLO -17(R4), R12
+ MOVWLO -21(R4), R13
+ MOVWLO -25(R4), R14
+ MOVWLO -29(R4), R15
+ ADDU $-32, R4
+ MOVW R8, 28(R5)
+ MOVW R9, 24(R5)
+ MOVW R10, 20(R5)
+ MOVW R11, 16(R5)
+ MOVW R12, 12(R5)
+ MOVW R13, 8(R5)
+ MOVW R14, 4(R5)
+ MOVW R15, 0(R5)
+ JMP b_large_ua
+
+b_words_ua:
+ BEQ R5, R6, b_tail_ua
+ MOVWHI -4(R4), R8
+ ADDU $-4, R5
+ MOVWLO -1(R4), R8
+ ADDU $-4, R4
+ MOVW R8, 0(R5)
+ JMP b_words_ua
+
+b_tail_ua:
+ BEQ R5, R1, ret
+ MOVWHI (R2), R8
+ MOVWLO 3(R2), R8
+ MOVWHI R8, 0(R1)
+ JMP ret
+
+b_small_copy:
+ BEQ R5, R1, ret
+ ADDU $-1, R5
+ MOVB -1(R4), R6
+ ADDU $-1, R4
+ MOVB R6, 0(R5)
+ JMP b_small_copy
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+// +build !mips
+// +build !mipsle
// +build !mips64
// +build !mips64le
// +build !s390x
const (
_SS_DISABLE = 2
- _NSIG = 65
+ _NSIG = 129
_SI_USER = 0
_SIG_BLOCK = 1
_SIG_UNBLOCK = 2
--- /dev/null
+// Copyright 2016 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.
+
+// +build linux
+// +build mips mipsle
+
+package runtime
+
+var randomNumber uint32
+
+func archauxv(tag, val uintptr) {
+ switch tag {
+ case _AT_RANDOM:
+ // sysargs filled in startupRandomData, but that
+ // pointer may not be word aligned, so we must treat
+ // it as a byte array.
+ randomNumber = uint32(startupRandomData[4]) | uint32(startupRandomData[5])<<8 |
+ uint32(startupRandomData[6])<<16 | uint32(startupRandomData[7])<<24
+ }
+}
+
+//go:nosplit
+func cputicks() int64 {
+ // Currently cputicks() is used in blocking profiler and to seed fastrand().
+ // nanotime() is a poor approximation of CPU ticks that is enough for the profiler.
+ // randomNumber provides better seeding of fastrand1.
+ return nanotime() + int64(randomNumber)
+}
+
+const (
+ _SS_DISABLE = 2
+ _NSIG = 128 + 1
+ _SI_USER = 0
+ _SIG_BLOCK = 1
+ _SIG_UNBLOCK = 2
+ _SIG_SETMASK = 3
+ _RLIMIT_AS = 6
+)
+
+type sigset [4]uint32
+
+type rlimit struct {
+ rlim_cur uintptr
+ rlim_max uintptr
+}
+
+var sigset_all = sigset{^uint32(0), ^uint32(0), ^uint32(0), ^uint32(0)}
+
+//go:nosplit
+//go:nowritebarrierrec
+func sigaddset(mask *sigset, i int) {
+ (*mask)[(i-1)/32] |= 1 << ((uint32(i) - 1) & 31)
+}
+
+func sigdelset(mask *sigset, i int) {
+ (*mask)[(i-1)/32] &^= 1 << ((uint32(i) - 1) & 31)
+}
+
+func sigfillset(mask *[4]uint32) {
+ (*mask)[0], (*mask)[1], (*mask)[2], (*mask)[3] = ^uint32(0), ^uint32(0), ^uint32(0), ^uint32(0)
+}
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !amd64,!arm,!arm64,!mips64,!mips64le,!s390x,!ppc64,!ppc64le
+// +build !amd64,!arm,!arm64,!mips,!mipsle,!mips64,!mips64le,!s390x,!ppc64,!ppc64le
package runtime
--- /dev/null
+// Copyright 2016 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.
+
+// +build linux
+// +build mips mipsle
+
+#include "textflag.h"
+
+TEXT _rt0_mips_linux(SB),NOSPLIT,$0
+ JMP _main<>(SB)
+
+TEXT _rt0_mipsle_linux(SB),NOSPLIT,$0
+ JMP _main<>(SB)
+
+TEXT _main<>(SB),NOSPLIT,$-4
+ // In a statically linked binary, the stack contains argc,
+ // argv as argc string pointers followed by a NULL, envv as a
+ // sequence of string pointers followed by a NULL, and auxv.
+ // There is no TLS base pointer.
+ MOVW 0(R29), R1 // argc
+ ADD $4, R29, R2 // argv
+ JMP main(SB)
+
+TEXT main(SB),NOSPLIT,$-4
+ MOVW $runtime·rt0_go(SB), R4
+ JMP (R4)
--- /dev/null
+// Copyright 2016 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.
+
+// +build linux
+// +build mips mipsle
+
+package runtime
+
+import "unsafe"
+
+type sigctxt struct {
+ info *siginfo
+ ctxt unsafe.Pointer
+}
+
+func (c *sigctxt) regs() *sigcontext { return &(*ucontext)(c.ctxt).uc_mcontext }
+func (c *sigctxt) r0() uint32 { return uint32(c.regs().sc_regs[0]) }
+func (c *sigctxt) r1() uint32 { return uint32(c.regs().sc_regs[1]) }
+func (c *sigctxt) r2() uint32 { return uint32(c.regs().sc_regs[2]) }
+func (c *sigctxt) r3() uint32 { return uint32(c.regs().sc_regs[3]) }
+func (c *sigctxt) r4() uint32 { return uint32(c.regs().sc_regs[4]) }
+func (c *sigctxt) r5() uint32 { return uint32(c.regs().sc_regs[5]) }
+func (c *sigctxt) r6() uint32 { return uint32(c.regs().sc_regs[6]) }
+func (c *sigctxt) r7() uint32 { return uint32(c.regs().sc_regs[7]) }
+func (c *sigctxt) r8() uint32 { return uint32(c.regs().sc_regs[8]) }
+func (c *sigctxt) r9() uint32 { return uint32(c.regs().sc_regs[9]) }
+func (c *sigctxt) r10() uint32 { return uint32(c.regs().sc_regs[10]) }
+func (c *sigctxt) r11() uint32 { return uint32(c.regs().sc_regs[11]) }
+func (c *sigctxt) r12() uint32 { return uint32(c.regs().sc_regs[12]) }
+func (c *sigctxt) r13() uint32 { return uint32(c.regs().sc_regs[13]) }
+func (c *sigctxt) r14() uint32 { return uint32(c.regs().sc_regs[14]) }
+func (c *sigctxt) r15() uint32 { return uint32(c.regs().sc_regs[15]) }
+func (c *sigctxt) r16() uint32 { return uint32(c.regs().sc_regs[16]) }
+func (c *sigctxt) r17() uint32 { return uint32(c.regs().sc_regs[17]) }
+func (c *sigctxt) r18() uint32 { return uint32(c.regs().sc_regs[18]) }
+func (c *sigctxt) r19() uint32 { return uint32(c.regs().sc_regs[19]) }
+func (c *sigctxt) r20() uint32 { return uint32(c.regs().sc_regs[20]) }
+func (c *sigctxt) r21() uint32 { return uint32(c.regs().sc_regs[21]) }
+func (c *sigctxt) r22() uint32 { return uint32(c.regs().sc_regs[22]) }
+func (c *sigctxt) r23() uint32 { return uint32(c.regs().sc_regs[23]) }
+func (c *sigctxt) r24() uint32 { return uint32(c.regs().sc_regs[24]) }
+func (c *sigctxt) r25() uint32 { return uint32(c.regs().sc_regs[25]) }
+func (c *sigctxt) r26() uint32 { return uint32(c.regs().sc_regs[26]) }
+func (c *sigctxt) r27() uint32 { return uint32(c.regs().sc_regs[27]) }
+func (c *sigctxt) r28() uint32 { return uint32(c.regs().sc_regs[28]) }
+func (c *sigctxt) r29() uint32 { return uint32(c.regs().sc_regs[29]) }
+func (c *sigctxt) r30() uint32 { return uint32(c.regs().sc_regs[30]) }
+func (c *sigctxt) r31() uint32 { return uint32(c.regs().sc_regs[31]) }
+func (c *sigctxt) sp() uint32 { return uint32(c.regs().sc_regs[29]) }
+func (c *sigctxt) pc() uint32 { return uint32(c.regs().sc_pc) }
+func (c *sigctxt) link() uint32 { return uint32(c.regs().sc_regs[31]) }
+func (c *sigctxt) lo() uint32 { return uint32(c.regs().sc_mdlo) }
+func (c *sigctxt) hi() uint32 { return uint32(c.regs().sc_mdhi) }
+
+func (c *sigctxt) sigcode() uint32 { return uint32(c.info.si_code) }
+func (c *sigctxt) sigaddr() uint32 { return c.info.si_addr }
+
+func (c *sigctxt) set_r30(x uint32) { c.regs().sc_regs[30] = uint64(x) }
+func (c *sigctxt) set_pc(x uint32) { c.regs().sc_pc = uint64(x) }
+func (c *sigctxt) set_sp(x uint32) { c.regs().sc_regs[29] = uint64(x) }
+func (c *sigctxt) set_link(x uint32) { c.regs().sc_regs[31] = uint64(x) }
+
+func (c *sigctxt) set_sigcode(x uint32) { c.info.si_code = int32(x) }
+func (c *sigctxt) set_sigaddr(x uint32) { c.info.si_addr = x }
--- /dev/null
+// Copyright 2016 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.
+
+// +build linux
+// +build mips mipsle
+
+package runtime
+
+import (
+ "runtime/internal/sys"
+ "unsafe"
+)
+
+func dumpregs(c *sigctxt) {
+ print("r0 ", hex(c.r0()), "\t")
+ print("r1 ", hex(c.r1()), "\n")
+ print("r2 ", hex(c.r2()), "\t")
+ print("r3 ", hex(c.r3()), "\n")
+ print("r4 ", hex(c.r4()), "\t")
+ print("r5 ", hex(c.r5()), "\n")
+ print("r6 ", hex(c.r6()), "\t")
+ print("r7 ", hex(c.r7()), "\n")
+ print("r8 ", hex(c.r8()), "\t")
+ print("r9 ", hex(c.r9()), "\n")
+ print("r10 ", hex(c.r10()), "\t")
+ print("r11 ", hex(c.r11()), "\n")
+ print("r12 ", hex(c.r12()), "\t")
+ print("r13 ", hex(c.r13()), "\n")
+ print("r14 ", hex(c.r14()), "\t")
+ print("r15 ", hex(c.r15()), "\n")
+ print("r16 ", hex(c.r16()), "\t")
+ print("r17 ", hex(c.r17()), "\n")
+ print("r18 ", hex(c.r18()), "\t")
+ print("r19 ", hex(c.r19()), "\n")
+ print("r20 ", hex(c.r20()), "\t")
+ print("r21 ", hex(c.r21()), "\n")
+ print("r22 ", hex(c.r22()), "\t")
+ print("r23 ", hex(c.r23()), "\n")
+ print("r24 ", hex(c.r24()), "\t")
+ print("r25 ", hex(c.r25()), "\n")
+ print("r26 ", hex(c.r26()), "\t")
+ print("r27 ", hex(c.r27()), "\n")
+ print("r28 ", hex(c.r28()), "\t")
+ print("r29 ", hex(c.r29()), "\n")
+ print("r30 ", hex(c.r30()), "\t")
+ print("r31 ", hex(c.r31()), "\n")
+ print("pc ", hex(c.pc()), "\t")
+ print("link ", hex(c.link()), "\n")
+ print("lo ", hex(c.lo()), "\t")
+ print("hi ", hex(c.hi()), "\n")
+}
+
+func (c *sigctxt) sigpc() uintptr { return uintptr(c.pc()) }
+func (c *sigctxt) sigsp() uintptr { return uintptr(c.sp()) }
+func (c *sigctxt) siglr() uintptr { return uintptr(c.link()) }
+func (c *sigctxt) fault() uintptr { return uintptr(c.sigaddr()) }
+
+// preparePanic sets up the stack to look like a call to sigpanic.
+func (c *sigctxt) preparePanic(sig uint32, gp *g) {
+ // We arrange link, and pc to pretend the panicking
+ // function calls sigpanic directly.
+ // Always save LINK to stack so that panics in leaf
+ // functions are correctly handled. This smashes
+ // the stack frame but we're not going back there
+ // anyway.
+ sp := c.sp() - sys.MinFrameSize
+ c.set_sp(sp)
+ *(*uint32)(unsafe.Pointer(uintptr(sp))) = c.link()
+
+ pc := gp.sigpc
+
+ // If we don't recognize the PC as code
+ // but we do recognize the link register as code,
+ // then assume this was a call to non-code and treat like
+ // pc == 0, to make unwinding show the context.
+ if pc != 0 && findfunc(pc) == nil && findfunc(uintptr(c.link())) != nil {
+ pc = 0
+ }
+
+ // Don't bother saving PC if it's zero, which is
+ // probably a call to a nil func: the old link register
+ // is more useful in the stack trace.
+ if pc != 0 {
+ c.set_link(uint32(pc))
+ }
+
+ // In case we are panicking from external C code
+ c.set_r30(uint32(uintptr(unsafe.Pointer(gp))))
+ c.set_pc(uint32(funcPC(sigpanic)))
+}
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+// +build !mips
+// +build !mipsle
// +build !mips64
// +build !mips64le
// +build linux
+++ /dev/null
-// Copyright 2015 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.
-
-// +build mips64 mips64le
-// +build linux
-
-package runtime
-
-type sigTabT struct {
- flags int32
- name string
-}
-
-var sigtable = [...]sigTabT{
- /* 0 */ {0, "SIGNONE: no trap"},
- /* 1 */ {_SigNotify + _SigKill, "SIGHUP: terminal line hangup"},
- /* 2 */ {_SigNotify + _SigKill, "SIGINT: interrupt"},
- /* 3 */ {_SigNotify + _SigThrow, "SIGQUIT: quit"},
- /* 4 */ {_SigThrow + _SigUnblock, "SIGILL: illegal instruction"},
- /* 5 */ {_SigThrow + _SigUnblock, "SIGTRAP: trace trap"},
- /* 6 */ {_SigNotify + _SigThrow, "SIGABRT: abort"},
- /* 7 */ {_SigThrow, "SIGEMT"},
- /* 8 */ {_SigPanic + _SigUnblock, "SIGFPE: floating-point exception"},
- /* 9 */ {0, "SIGKILL: kill"},
- /* 10 */ {_SigPanic + _SigUnblock, "SIGBUS: bus error"},
- /* 11 */ {_SigPanic + _SigUnblock, "SIGSEGV: segmentation violation"},
- /* 12 */ {_SigThrow, "SIGSYS: bad system call"},
- /* 13 */ {_SigNotify, "SIGPIPE: write to broken pipe"},
- /* 14 */ {_SigNotify, "SIGALRM: alarm clock"},
- /* 15 */ {_SigNotify + _SigKill, "SIGTERM: termination"},
- /* 16 */ {_SigNotify, "SIGUSR1: user-defined signal 1"},
- /* 17 */ {_SigNotify, "SIGUSR2: user-defined signal 2"},
- /* 18 */ {_SigNotify + _SigUnblock, "SIGCHLD: child status has changed"},
- /* 19 */ {_SigNotify, "SIGPWR: power failure restart"},
- /* 20 */ {_SigNotify, "SIGWINCH: window size change"},
- /* 21 */ {_SigNotify, "SIGURG: urgent condition on socket"},
- /* 22 */ {_SigNotify, "SIGIO: i/o now possible"},
- /* 23 */ {0, "SIGSTOP: stop, unblockable"},
- /* 24 */ {_SigNotify + _SigDefault, "SIGTSTP: keyboard stop"},
- /* 25 */ {_SigNotify + _SigDefault, "SIGCONT: continue"},
- /* 26 */ {_SigNotify + _SigDefault, "SIGTTIN: background read from tty"},
- /* 27 */ {_SigNotify + _SigDefault, "SIGTTOU: background write to tty"},
- /* 28 */ {_SigNotify, "SIGVTALRM: virtual alarm clock"},
- /* 29 */ {_SigNotify + _SigUnblock, "SIGPROF: profiling alarm clock"},
- /* 30 */ {_SigNotify, "SIGXCPU: cpu limit exceeded"},
- /* 31 */ {_SigNotify, "SIGXFSZ: file size limit exceeded"},
- /* 32 */ {_SigSetStack + _SigUnblock, "signal 32"}, /* SIGCANCEL; see issue 6997 */
- /* 33 */ {_SigSetStack + _SigUnblock, "signal 33"}, /* SIGSETXID; see issues 3871, 9400, 12498 */
- /* 34 */ {_SigNotify, "signal 34"},
- /* 35 */ {_SigNotify, "signal 35"},
- /* 36 */ {_SigNotify, "signal 36"},
- /* 37 */ {_SigNotify, "signal 37"},
- /* 38 */ {_SigNotify, "signal 38"},
- /* 39 */ {_SigNotify, "signal 39"},
- /* 40 */ {_SigNotify, "signal 40"},
- /* 41 */ {_SigNotify, "signal 41"},
- /* 42 */ {_SigNotify, "signal 42"},
- /* 43 */ {_SigNotify, "signal 43"},
- /* 44 */ {_SigNotify, "signal 44"},
- /* 45 */ {_SigNotify, "signal 45"},
- /* 46 */ {_SigNotify, "signal 46"},
- /* 47 */ {_SigNotify, "signal 47"},
- /* 48 */ {_SigNotify, "signal 48"},
- /* 49 */ {_SigNotify, "signal 49"},
- /* 50 */ {_SigNotify, "signal 50"},
- /* 51 */ {_SigNotify, "signal 51"},
- /* 52 */ {_SigNotify, "signal 52"},
- /* 53 */ {_SigNotify, "signal 53"},
- /* 54 */ {_SigNotify, "signal 54"},
- /* 55 */ {_SigNotify, "signal 55"},
- /* 56 */ {_SigNotify, "signal 56"},
- /* 57 */ {_SigNotify, "signal 57"},
- /* 58 */ {_SigNotify, "signal 58"},
- /* 59 */ {_SigNotify, "signal 59"},
- /* 60 */ {_SigNotify, "signal 60"},
- /* 61 */ {_SigNotify, "signal 61"},
- /* 62 */ {_SigNotify, "signal 62"},
- /* 63 */ {_SigNotify, "signal 63"},
- /* 64 */ {_SigNotify, "signal 64"},
-}
--- /dev/null
+// Copyright 2015 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.
+
+// +build mips mipsle mips64 mips64le
+// +build linux
+
+package runtime
+
+type sigTabT struct {
+ flags int32
+ name string
+}
+
+var sigtable = [...]sigTabT{
+ /* 0 */ {0, "SIGNONE: no trap"},
+ /* 1 */ {_SigNotify + _SigKill, "SIGHUP: terminal line hangup"},
+ /* 2 */ {_SigNotify + _SigKill, "SIGINT: interrupt"},
+ /* 3 */ {_SigNotify + _SigThrow, "SIGQUIT: quit"},
+ /* 4 */ {_SigThrow + _SigUnblock, "SIGILL: illegal instruction"},
+ /* 5 */ {_SigThrow + _SigUnblock, "SIGTRAP: trace trap"},
+ /* 6 */ {_SigNotify + _SigThrow, "SIGABRT: abort"},
+ /* 7 */ {_SigThrow, "SIGEMT"},
+ /* 8 */ {_SigPanic + _SigUnblock, "SIGFPE: floating-point exception"},
+ /* 9 */ {0, "SIGKILL: kill"},
+ /* 10 */ {_SigPanic + _SigUnblock, "SIGBUS: bus error"},
+ /* 11 */ {_SigPanic + _SigUnblock, "SIGSEGV: segmentation violation"},
+ /* 12 */ {_SigThrow, "SIGSYS: bad system call"},
+ /* 13 */ {_SigNotify, "SIGPIPE: write to broken pipe"},
+ /* 14 */ {_SigNotify, "SIGALRM: alarm clock"},
+ /* 15 */ {_SigNotify + _SigKill, "SIGTERM: termination"},
+ /* 16 */ {_SigNotify, "SIGUSR1: user-defined signal 1"},
+ /* 17 */ {_SigNotify, "SIGUSR2: user-defined signal 2"},
+ /* 18 */ {_SigNotify + _SigUnblock, "SIGCHLD: child status has changed"},
+ /* 19 */ {_SigNotify, "SIGPWR: power failure restart"},
+ /* 20 */ {_SigNotify, "SIGWINCH: window size change"},
+ /* 21 */ {_SigNotify, "SIGURG: urgent condition on socket"},
+ /* 22 */ {_SigNotify, "SIGIO: i/o now possible"},
+ /* 23 */ {0, "SIGSTOP: stop, unblockable"},
+ /* 24 */ {_SigNotify + _SigDefault, "SIGTSTP: keyboard stop"},
+ /* 25 */ {_SigNotify + _SigDefault, "SIGCONT: continue"},
+ /* 26 */ {_SigNotify + _SigDefault, "SIGTTIN: background read from tty"},
+ /* 27 */ {_SigNotify + _SigDefault, "SIGTTOU: background write to tty"},
+ /* 28 */ {_SigNotify, "SIGVTALRM: virtual alarm clock"},
+ /* 29 */ {_SigNotify + _SigUnblock, "SIGPROF: profiling alarm clock"},
+ /* 30 */ {_SigNotify, "SIGXCPU: cpu limit exceeded"},
+ /* 31 */ {_SigNotify, "SIGXFSZ: file size limit exceeded"},
+ /* 32 */ {_SigSetStack + _SigUnblock, "signal 32"}, /* SIGCANCEL; see issue 6997 */
+ /* 33 */ {_SigSetStack + _SigUnblock, "signal 33"}, /* SIGSETXID; see issues 3871, 9400, 12498 */
+ /* 34 */ {_SigNotify, "signal 34"},
+ /* 35 */ {_SigNotify, "signal 35"},
+ /* 36 */ {_SigNotify, "signal 36"},
+ /* 37 */ {_SigNotify, "signal 37"},
+ /* 38 */ {_SigNotify, "signal 38"},
+ /* 39 */ {_SigNotify, "signal 39"},
+ /* 40 */ {_SigNotify, "signal 40"},
+ /* 41 */ {_SigNotify, "signal 41"},
+ /* 42 */ {_SigNotify, "signal 42"},
+ /* 43 */ {_SigNotify, "signal 43"},
+ /* 44 */ {_SigNotify, "signal 44"},
+ /* 45 */ {_SigNotify, "signal 45"},
+ /* 46 */ {_SigNotify, "signal 46"},
+ /* 47 */ {_SigNotify, "signal 47"},
+ /* 48 */ {_SigNotify, "signal 48"},
+ /* 49 */ {_SigNotify, "signal 49"},
+ /* 50 */ {_SigNotify, "signal 50"},
+ /* 51 */ {_SigNotify, "signal 51"},
+ /* 52 */ {_SigNotify, "signal 52"},
+ /* 53 */ {_SigNotify, "signal 53"},
+ /* 54 */ {_SigNotify, "signal 54"},
+ /* 55 */ {_SigNotify, "signal 55"},
+ /* 56 */ {_SigNotify, "signal 56"},
+ /* 57 */ {_SigNotify, "signal 57"},
+ /* 58 */ {_SigNotify, "signal 58"},
+ /* 59 */ {_SigNotify, "signal 59"},
+ /* 60 */ {_SigNotify, "signal 60"},
+ /* 61 */ {_SigNotify, "signal 61"},
+ /* 62 */ {_SigNotify, "signal 62"},
+ /* 63 */ {_SigNotify, "signal 63"},
+ /* 64 */ {_SigNotify, "signal 64"},
+ /* 65 */ {_SigNotify, "signal 65"},
+ /* 66 */ {_SigNotify, "signal 66"},
+ /* 67 */ {_SigNotify, "signal 67"},
+ /* 68 */ {_SigNotify, "signal 68"},
+ /* 69 */ {_SigNotify, "signal 69"},
+ /* 70 */ {_SigNotify, "signal 70"},
+ /* 71 */ {_SigNotify, "signal 71"},
+ /* 72 */ {_SigNotify, "signal 72"},
+ /* 73 */ {_SigNotify, "signal 73"},
+ /* 74 */ {_SigNotify, "signal 74"},
+ /* 75 */ {_SigNotify, "signal 75"},
+ /* 76 */ {_SigNotify, "signal 76"},
+ /* 77 */ {_SigNotify, "signal 77"},
+ /* 78 */ {_SigNotify, "signal 78"},
+ /* 79 */ {_SigNotify, "signal 79"},
+ /* 80 */ {_SigNotify, "signal 80"},
+ /* 81 */ {_SigNotify, "signal 81"},
+ /* 82 */ {_SigNotify, "signal 82"},
+ /* 83 */ {_SigNotify, "signal 83"},
+ /* 84 */ {_SigNotify, "signal 84"},
+ /* 85 */ {_SigNotify, "signal 85"},
+ /* 86 */ {_SigNotify, "signal 86"},
+ /* 87 */ {_SigNotify, "signal 87"},
+ /* 88 */ {_SigNotify, "signal 88"},
+ /* 89 */ {_SigNotify, "signal 89"},
+ /* 90 */ {_SigNotify, "signal 90"},
+ /* 91 */ {_SigNotify, "signal 91"},
+ /* 92 */ {_SigNotify, "signal 92"},
+ /* 93 */ {_SigNotify, "signal 93"},
+ /* 94 */ {_SigNotify, "signal 94"},
+ /* 95 */ {_SigNotify, "signal 95"},
+ /* 96 */ {_SigNotify, "signal 96"},
+ /* 97 */ {_SigNotify, "signal 97"},
+ /* 98 */ {_SigNotify, "signal 98"},
+ /* 99 */ {_SigNotify, "signal 99"},
+ /* 100 */ {_SigNotify, "signal 100"},
+ /* 101 */ {_SigNotify, "signal 101"},
+ /* 102 */ {_SigNotify, "signal 102"},
+ /* 103 */ {_SigNotify, "signal 103"},
+ /* 104 */ {_SigNotify, "signal 104"},
+ /* 105 */ {_SigNotify, "signal 105"},
+ /* 106 */ {_SigNotify, "signal 106"},
+ /* 107 */ {_SigNotify, "signal 107"},
+ /* 108 */ {_SigNotify, "signal 108"},
+ /* 109 */ {_SigNotify, "signal 109"},
+ /* 110 */ {_SigNotify, "signal 110"},
+ /* 111 */ {_SigNotify, "signal 111"},
+ /* 112 */ {_SigNotify, "signal 112"},
+ /* 113 */ {_SigNotify, "signal 113"},
+ /* 114 */ {_SigNotify, "signal 114"},
+ /* 115 */ {_SigNotify, "signal 115"},
+ /* 116 */ {_SigNotify, "signal 116"},
+ /* 117 */ {_SigNotify, "signal 117"},
+ /* 118 */ {_SigNotify, "signal 118"},
+ /* 119 */ {_SigNotify, "signal 119"},
+ /* 120 */ {_SigNotify, "signal 120"},
+ /* 121 */ {_SigNotify, "signal 121"},
+ /* 122 */ {_SigNotify, "signal 122"},
+ /* 123 */ {_SigNotify, "signal 123"},
+ /* 124 */ {_SigNotify, "signal 124"},
+ /* 125 */ {_SigNotify, "signal 125"},
+ /* 126 */ {_SigNotify, "signal 126"},
+ /* 127 */ {_SigNotify, "signal 127"},
+ /* 128 */ {_SigNotify, "signal 128"},
+}
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build 386 arm amd64p32
+// +build 386 arm amd64p32 mips mipsle
package runtime
--- /dev/null
+// Copyright 2016 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.
+
+// +build linux
+// +build mips mipsle
+
+//
+// System calls and other sys.stuff for mips, Linux
+//
+
+#include "go_asm.h"
+#include "go_tls.h"
+#include "textflag.h"
+
+#define SYS_exit 4001
+#define SYS_read 4003
+#define SYS_write 4004
+#define SYS_open 4005
+#define SYS_close 4006
+#define SYS_getpid 4020
+#define SYS_kill 4037
+#define SYS_fcntl 4055
+#define SYS_gettimeofday 4078
+#define SYS_mmap 4090
+#define SYS_munmap 4091
+#define SYS_setitimer 4104
+#define SYS_clone 4120
+#define SYS_newselect 4142
+#define SYS_sched_yield 4162
+#define SYS_rt_sigreturn 4193
+#define SYS_rt_sigaction 4194
+#define SYS_rt_sigprocmask 4195
+#define SYS_sigaltstack 4206
+#define SYS_getrlimit 4076
+#define SYS_madvise 4218
+#define SYS_mincore 4217
+#define SYS_gettid 4222
+#define SYS_tkill 4236
+#define SYS_futex 4238
+#define SYS_sched_getaffinity 4240
+#define SYS_exit_group 4246
+#define SYS_epoll_create 4248
+#define SYS_epoll_ctl 4249
+#define SYS_epoll_wait 4250
+#define SYS_clock_gettime 4263
+#define SYS_epoll_create1 4326
+
+TEXT runtime·exit(SB),NOSPLIT,$0-4
+ MOVW code+0(FP), R4
+ MOVW $SYS_exit_group, R2
+ SYSCALL
+ UNDEF
+ RET
+
+TEXT runtime·exit1(SB),NOSPLIT,$0-4
+ MOVW code+0(FP), R4
+ MOVW $SYS_exit, R2
+ SYSCALL
+ UNDEF
+ RET
+
+TEXT runtime·open(SB),NOSPLIT,$0-16
+ MOVW name+0(FP), R4
+ MOVW mode+4(FP), R5
+ MOVW perm+8(FP), R6
+ MOVW $SYS_open, R2
+ SYSCALL
+ BEQ R7, 2(PC)
+ MOVW $-1, R2
+ MOVW R2, ret+12(FP)
+ RET
+
+TEXT runtime·closefd(SB),NOSPLIT,$0-8
+ MOVW fd+0(FP), R4
+ MOVW $SYS_close, R2
+ SYSCALL
+ BEQ R7, 2(PC)
+ MOVW $-1, R2
+ MOVW R2, ret+4(FP)
+ RET
+
+TEXT runtime·write(SB),NOSPLIT,$0-16
+ MOVW fd+0(FP), R4
+ MOVW p+4(FP), R5
+ MOVW n+8(FP), R6
+ MOVW $SYS_write, R2
+ SYSCALL
+ BEQ R7, 2(PC)
+ MOVW $-1, R2
+ MOVW R2, ret+12(FP)
+ RET
+
+TEXT runtime·read(SB),NOSPLIT,$0-16
+ MOVW fd+0(FP), R4
+ MOVW p+4(FP), R5
+ MOVW n+8(FP), R6
+ MOVW $SYS_read, R2
+ SYSCALL
+ BEQ R7, 2(PC)
+ MOVW $-1, R2
+ MOVW R2, ret+12(FP)
+ RET
+
+TEXT runtime·getrlimit(SB),NOSPLIT,$0-12
+ MOVW kind+0(FP), R4
+ MOVW limit+4(FP), R5
+ MOVW $SYS_getrlimit, R2
+ SYSCALL
+ MOVW R2, ret+8(FP)
+ RET
+
+TEXT runtime·usleep(SB),NOSPLIT,$28-4
+ MOVW usec+0(FP), R3
+ MOVW R3, R5
+ MOVW $1000000, R4
+ DIVU R4, R3
+ MOVW LO, R3
+ MOVW R3, 24(R29)
+ MULU R3, R4
+ MOVW LO, R4
+ SUBU R4, R5
+ MOVW R5, 28(R29)
+
+ // select(0, 0, 0, 0, &tv)
+ MOVW $0, R4
+ MOVW $0, R5
+ MOVW $0, R6
+ MOVW $0, R7
+ ADDU $24, R29, R8
+ MOVW R8, 16(R29)
+ MOVW $SYS_newselect, R2
+ SYSCALL
+ RET
+
+TEXT runtime·gettid(SB),NOSPLIT,$0-4
+ MOVW $SYS_gettid, R2
+ SYSCALL
+ MOVW R2, ret+0(FP)
+ RET
+
+TEXT runtime·raise(SB),NOSPLIT,$0-4
+ MOVW $SYS_gettid, R2
+ SYSCALL
+ MOVW R2, R4 // arg 1 tid
+ MOVW sig+0(FP), R5 // arg 2
+ MOVW $SYS_tkill, R2
+ SYSCALL
+ RET
+
+TEXT runtime·raiseproc(SB),NOSPLIT,$0
+ MOVW $SYS_getpid, R2
+ SYSCALL
+ MOVW R2, R4 // arg 1 pid
+ MOVW sig+0(FP), R5 // arg 2
+ MOVW $SYS_kill, R2
+ SYSCALL
+ RET
+
+TEXT runtime·setitimer(SB),NOSPLIT,$0-12
+ MOVW mode+0(FP), R4
+ MOVW new+4(FP), R5
+ MOVW old+8(FP), R6
+ MOVW $SYS_setitimer, R2
+ SYSCALL
+ RET
+
+TEXT runtime·mincore(SB),NOSPLIT,$0-16
+ MOVW addr+0(FP), R4
+ MOVW n+4(FP), R5
+ MOVW dst+8(FP), R6
+ MOVW $SYS_mincore, R2
+ SYSCALL
+ SUBU R2, R0, R2 // caller expects negative errno
+ MOVW R2, ret+12(FP)
+ RET
+
+// func now() (sec int64, nsec int32)
+TEXT time·now(SB),NOSPLIT,$8-12
+ MOVW $0, R4 // CLOCK_REALTIME
+ MOVW $4(R29), R5
+ MOVW $SYS_clock_gettime, R2
+ SYSCALL
+ MOVW 4(R29), R3 // sec
+ MOVW 8(R29), R5 // nsec
+#ifdef GOARCH_mips
+ MOVW R3, sec_lo+4(FP)
+ MOVW R0, sec_hi+0(FP)
+#else
+ MOVW R3, sec_lo+0(FP)
+ MOVW R0, sec_hi+4(FP)
+#endif
+ MOVW R5, nsec+8(FP)
+ RET
+
+TEXT runtime·nanotime(SB),NOSPLIT,$8-8
+ MOVW $1, R4 // CLOCK_MONOTONIC
+ MOVW $4(R29), R5
+ MOVW $SYS_clock_gettime, R2
+ SYSCALL
+ MOVW 4(R29), R3 // sec
+ MOVW 8(R29), R5 // nsec
+ // sec is in R3, nsec in R5
+ // return nsec in R3
+ MOVW $1000000000, R4
+ MULU R4, R3
+ MOVW LO, R3
+ ADDU R5, R3
+ SGTU R5, R3, R4
+#ifdef GOARCH_mips
+ MOVW R3, ret_lo+4(FP)
+#else
+ MOVW R3, ret_lo+0(FP)
+#endif
+ MOVW HI, R3
+ ADDU R4, R3
+#ifdef GOARCH_mips
+ MOVW R3, ret_hi+0(FP)
+#else
+ MOVW R3, ret_hi+4(FP)
+#endif
+ RET
+
+TEXT runtime·rtsigprocmask(SB),NOSPLIT,$0-16
+ MOVW how+0(FP), R4
+ MOVW new+4(FP), R5
+ MOVW old+8(FP), R6
+ MOVW size+12(FP), R7
+ MOVW $SYS_rt_sigprocmask, R2
+ SYSCALL
+ BEQ R7, 2(PC)
+ UNDEF // crash
+ RET
+
+TEXT runtime·rt_sigaction(SB),NOSPLIT,$0-20
+ MOVW sig+0(FP), R4
+ MOVW new+4(FP), R5
+ MOVW old+8(FP), R6
+ MOVW size+12(FP), R7
+ MOVW $SYS_rt_sigaction, R2
+ SYSCALL
+ MOVW R2, ret+16(FP)
+ RET
+
+TEXT runtime·sigfwd(SB),NOSPLIT,$0-16
+ MOVW sig+4(FP), R4
+ MOVW info+8(FP), R5
+ MOVW ctx+12(FP), R6
+ MOVW fn+0(FP), R25
+ MOVW R29, R22
+ SUBU $16, R29
+ AND $0x7, R29 // shadow space for 4 args aligned to 8 bytes as per O32 ABI
+ JAL (R25)
+ MOVW R22, R29
+ RET
+
+TEXT runtime·sigtramp(SB),NOSPLIT,$12
+ // this might be called in external code context,
+ // where g is not set.
+ MOVB runtime·iscgo(SB), R1
+ BEQ R1, 2(PC)
+ JAL runtime·load_g(SB)
+
+ MOVW R4, 4(R29)
+ MOVW R5, 8(R29)
+ MOVW R6, 12(R29)
+ MOVW $runtime·sigtrampgo(SB), R1
+ JAL (R1)
+ RET
+
+TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
+ JMP runtime·sigtramp(SB)
+
+TEXT runtime·mmap(SB),NOSPLIT,$20-28
+ MOVW addr+0(FP), R4
+ MOVW n+4(FP), R5
+ MOVW prot+8(FP), R6
+ MOVW flags+12(FP), R7
+ MOVW fd+16(FP), R8
+ MOVW off+20(FP), R9
+ MOVW R8, 16(R29)
+ MOVW R9, 20(R29)
+
+ MOVW $SYS_mmap, R2
+ SYSCALL
+ MOVW R2, ret+24(FP)
+ RET
+
+TEXT runtime·munmap(SB),NOSPLIT,$0-8
+ MOVW addr+0(FP), R4
+ MOVW n+4(FP), R5
+ MOVW $SYS_munmap, R2
+ SYSCALL
+ BEQ R7, 2(PC)
+ UNDEF // crash
+ RET
+
+TEXT runtime·madvise(SB),NOSPLIT,$0-12
+ MOVW addr+0(FP), R4
+ MOVW n+4(FP), R5
+ MOVW flags+8(FP), R6
+ MOVW $SYS_madvise, R2
+ SYSCALL
+ // ignore failure - maybe pages are locked
+ RET
+
+// int32 futex(int32 *uaddr, int32 op, int32 val, struct timespec *timeout, int32 *uaddr2, int32 val2);
+TEXT runtime·futex(SB),NOSPLIT,$20-28
+ MOVW addr+0(FP), R4
+ MOVW op+4(FP), R5
+ MOVW val+8(FP), R6
+ MOVW ts+12(FP), R7
+
+ MOVW addr2+16(FP), R8
+ MOVW val3+20(FP), R9
+
+ MOVW R8, 16(R29)
+ MOVW R9, 20(R29)
+
+ MOVW $SYS_futex, R2
+ SYSCALL
+ MOVW R2, ret+24(FP)
+ RET
+
+
+// int32 clone(int32 flags, void *stk, M *mm, G *gg, void (*fn)(void));
+TEXT runtime·clone(SB),NOSPLIT,$-4-24
+ MOVW flags+0(FP), R4
+ MOVW stk+4(FP), R5
+ MOVW R0, R6 // ptid
+ MOVW R0, R7 // tls
+
+ // O32 syscall handler unconditionally copies arguments 5-8 from stack,
+ // even for syscalls with less than 8 arguments. Reserve 32 bytes of new
+ // stack so that any syscall invoked immediately in the new thread won't fail.
+ ADD $-32, R5
+
+ // Copy mm, gg, fn off parent stack for use by child.
+ MOVW mm+8(FP), R16
+ MOVW gg+12(FP), R17
+ MOVW fn+16(FP), R18
+
+ MOVW $1234, R1
+
+ MOVW R16, 0(R5)
+ MOVW R17, 4(R5)
+ MOVW R18, 8(R5)
+
+ MOVW R1, 12(R5)
+
+ MOVW $SYS_clone, R2
+ SYSCALL
+
+ // In parent, return.
+ BEQ R2, 5(PC)
+ SUBU R2, R0, R3
+ CMOVN R7, R3, R2
+ MOVW R2, ret+20(FP)
+ RET
+
+ // In child, on new stack.
+ // Check that SP is as we expect
+ MOVW 12(R29), R16
+ MOVW $1234, R1
+ BEQ R16, R1, 2(PC)
+ MOVW (R0), R0
+
+ // Initialize m->procid to Linux tid
+ MOVW $SYS_gettid, R2
+ SYSCALL
+
+ MOVW 0(R29), R16 // m
+ MOVW 4(R29), R17 // g
+ MOVW 8(R29), R18 // fn
+
+ BEQ R16, nog
+ BEQ R17, nog
+
+ MOVW R2, m_procid(R16)
+
+ // In child, set up new stack
+ MOVW R16, g_m(R17)
+ MOVW R17, g
+
+// TODO(mips32): doesn't have runtime·stackcheck(SB)
+
+nog:
+ // Call fn
+ ADDU $32, R29
+ JAL (R18)
+
+ // It shouldn't return. If it does, exit that thread.
+ ADDU $-32, R29
+ MOVW $0xf4, R4
+ MOVW $SYS_exit, R2
+ SYSCALL
+ UNDEF
+
+TEXT runtime·sigaltstack(SB),NOSPLIT,$0
+ MOVW new+0(FP), R4
+ MOVW old+4(FP), R5
+ MOVW $SYS_sigaltstack, R2
+ SYSCALL
+ BEQ R7, 2(PC)
+ UNDEF // crash
+ RET
+
+TEXT runtime·osyield(SB),NOSPLIT,$0
+ MOVW $SYS_sched_yield, R2
+ SYSCALL
+ RET
+
+TEXT runtime·sched_getaffinity(SB),NOSPLIT,$0-16
+ MOVW pid+0(FP), R4
+ MOVW len+4(FP), R5
+ MOVW buf+8(FP), R6
+ MOVW $SYS_sched_getaffinity, R2
+ SYSCALL
+ MOVW R2, ret+12(FP)
+ RET
+
+// int32 runtime·epollcreate(int32 size);
+TEXT runtime·epollcreate(SB),NOSPLIT,$0-8
+ MOVW size+0(FP), R4
+ MOVW $SYS_epoll_create, R2
+ SYSCALL
+ MOVW R2, ret+4(FP)
+ RET
+
+// int32 runtime·epollcreate1(int32 flags);
+TEXT runtime·epollcreate1(SB),NOSPLIT,$0-8
+ MOVW flags+0(FP), R4
+ MOVW $SYS_epoll_create1, R2
+ SYSCALL
+ MOVW R2, ret+4(FP)
+ RET
+
+// func epollctl(epfd, op, fd int32, ev *epollEvent) int
+TEXT runtime·epollctl(SB),NOSPLIT,$0-20
+ MOVW epfd+0(FP), R4
+ MOVW op+4(FP), R5
+ MOVW fd+8(FP), R6
+ MOVW ev+12(FP), R7
+ MOVW $SYS_epoll_ctl, R2
+ SYSCALL
+ MOVW R2, ret+16(FP)
+ RET
+
+// int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout);
+TEXT runtime·epollwait(SB),NOSPLIT,$0-20
+ MOVW epfd+0(FP), R4
+ MOVW ev+4(FP), R5
+ MOVW nev+8(FP), R6
+ MOVW timeout+12(FP), R7
+ MOVW $SYS_epoll_wait, R2
+ SYSCALL
+ MOVW R2, ret+16(FP)
+ RET
+
+// void runtime·closeonexec(int32 fd);
+TEXT runtime·closeonexec(SB),NOSPLIT,$0-4
+ MOVW fd+0(FP), R4 // fd
+ MOVW $2, R5 // F_SETFD
+ MOVW $1, R6 // FD_CLOEXEC
+ MOVW $SYS_fcntl, R2
+ SYSCALL
+ RET
--- /dev/null
+// Copyright 2016 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.
+
+// +build mips mipsle
+
+package runtime
+
+import "unsafe"
+
+// adjust Gobuf as if it executed a call to fn with context ctxt
+// and then did an immediate Gosave.
+func gostartcall(buf *gobuf, fn, ctxt unsafe.Pointer) {
+ if buf.lr != 0 {
+ throw("invalid use of gostartcall")
+ }
+ buf.lr = buf.pc
+ buf.pc = uintptr(fn)
+ buf.ctxt = ctxt
+}
--- /dev/null
+// Copyright 2016 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.
+
+// +build mips mipsle
+
+#include "go_asm.h"
+#include "go_tls.h"
+#include "funcdata.h"
+#include "textflag.h"
+
+// If !iscgo, this is a no-op.
+TEXT runtime·save_g(SB),NOSPLIT,$-4-0
+ MOVB runtime·iscgo(SB), R23
+ BEQ R23, nocgo
+ UNDEF
+nocgo:
+ RET
+
+TEXT runtime·load_g(SB),NOSPLIT,$-4-0
+ RET
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build arm mips64 mips64le
+// +build arm mips mipsle mips64 mips64le
package runtime
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
-// +build arm 386
+// +build arm 386 mips mipsle
package runtime
return slowdodiv(n, d)
}
+ if GOARCH == "mips" || GOARCH == "mipsle" {
+ // No _div64by32 on mips and using only _mul64by32 doesn't bring much benefit
+ return slowdodiv(n, d)
+ }
+
if d > n {
return 0, n
}