...
Run Format

Text file src/runtime/asm_mips64x.s

Documentation: runtime

     1	// Copyright 2015 The Go Authors. All rights reserved.
     2	// Use of this source code is governed by a BSD-style
     3	// license that can be found in the LICENSE file.
     4	
     5	// +build mips64 mips64le
     6	
     7	#include "go_asm.h"
     8	#include "go_tls.h"
     9	#include "funcdata.h"
    10	#include "textflag.h"
    11	
    12	#define	REGCTXT	R22
    13	
    14	TEXT runtime·rt0_go(SB),NOSPLIT,$0
    15		// R29 = stack; R4 = argc; R5 = argv
    16	
    17		ADDV	$-24, R29
    18		MOVW	R4, 8(R29) // argc
    19		MOVV	R5, 16(R29) // argv
    20	
    21		// create istack out of the given (operating system) stack.
    22		// _cgo_init may update stackguard.
    23		MOVV	$runtime·g0(SB), g
    24		MOVV	$(-64*1024), R23
    25		ADDV	R23, R29, R1
    26		MOVV	R1, g_stackguard0(g)
    27		MOVV	R1, g_stackguard1(g)
    28		MOVV	R1, (g_stack+stack_lo)(g)
    29		MOVV	R29, (g_stack+stack_hi)(g)
    30	
    31		// if there is a _cgo_init, call it using the gcc ABI.
    32		MOVV	_cgo_init(SB), R25
    33		BEQ	R25, nocgo
    34	
    35		MOVV	R0, R7	// arg 3: not used
    36		MOVV	R0, R6	// arg 2: not used
    37		MOVV	$setg_gcc<>(SB), R5	// arg 1: setg
    38		MOVV	g, R4	// arg 0: G
    39		JAL	(R25)
    40	
    41	nocgo:
    42		// update stackguard after _cgo_init
    43		MOVV	(g_stack+stack_lo)(g), R1
    44		ADDV	$const__StackGuard, R1
    45		MOVV	R1, g_stackguard0(g)
    46		MOVV	R1, g_stackguard1(g)
    47	
    48		// set the per-goroutine and per-mach "registers"
    49		MOVV	$runtime·m0(SB), R1
    50	
    51		// save m->g0 = g0
    52		MOVV	g, m_g0(R1)
    53		// save m0 to g0->m
    54		MOVV	R1, g_m(g)
    55	
    56		JAL	runtime·check(SB)
    57	
    58		// args are already prepared
    59		JAL	runtime·args(SB)
    60		JAL	runtime·osinit(SB)
    61		JAL	runtime·schedinit(SB)
    62	
    63		// create a new goroutine to start program
    64		MOVV	$runtime·mainPC(SB), R1		// entry
    65		ADDV	$-24, R29
    66		MOVV	R1, 16(R29)
    67		MOVV	R0, 8(R29)
    68		MOVV	R0, 0(R29)
    69		JAL	runtime·newproc(SB)
    70		ADDV	$24, R29
    71	
    72		// start this M
    73		JAL	runtime·mstart(SB)
    74	
    75		MOVV	R0, 1(R0)
    76		RET
    77	
    78	DATA	runtime·mainPC+0(SB)/8,$runtime·main(SB)
    79	GLOBL	runtime·mainPC(SB),RODATA,$8
    80	
    81	TEXT runtime·breakpoint(SB),NOSPLIT,$-8-0
    82		MOVV	R0, 2(R0) // TODO: TD
    83		RET
    84	
    85	TEXT runtime·asminit(SB),NOSPLIT,$-8-0
    86		RET
    87	
    88	/*
    89	 *  go-routine
    90	 */
    91	
    92	// void gosave(Gobuf*)
    93	// save state in Gobuf; setjmp
    94	TEXT runtime·gosave(SB), NOSPLIT, $-8-8
    95		MOVV	buf+0(FP), R1
    96		MOVV	R29, gobuf_sp(R1)
    97		MOVV	R31, gobuf_pc(R1)
    98		MOVV	g, gobuf_g(R1)
    99		MOVV	R0, gobuf_lr(R1)
   100		MOVV	R0, gobuf_ret(R1)
   101		// Assert ctxt is zero. See func save.
   102		MOVV	gobuf_ctxt(R1), R1
   103		BEQ	R1, 2(PC)
   104		JAL	runtime·badctxt(SB)
   105		RET
   106	
   107	// void gogo(Gobuf*)
   108	// restore state from Gobuf; longjmp
   109	TEXT runtime·gogo(SB), NOSPLIT, $16-8
   110		MOVV	buf+0(FP), R3
   111	
   112		// If ctxt is not nil, invoke deletion barrier before overwriting.
   113		MOVV	gobuf_ctxt(R3), R1
   114		BEQ	R1, nilctxt
   115		MOVV	$gobuf_ctxt(R3), R1
   116		MOVV	R1, 8(R29)
   117		MOVV	R0, 16(R29)
   118		JAL	runtime·writebarrierptr_prewrite(SB)
   119		MOVV	buf+0(FP), R3
   120	
   121	nilctxt:
   122		MOVV	gobuf_g(R3), g	// make sure g is not nil
   123		JAL	runtime·save_g(SB)
   124	
   125		MOVV	0(g), R2
   126		MOVV	gobuf_sp(R3), R29
   127		MOVV	gobuf_lr(R3), R31
   128		MOVV	gobuf_ret(R3), R1
   129		MOVV	gobuf_ctxt(R3), REGCTXT
   130		MOVV	R0, gobuf_sp(R3)
   131		MOVV	R0, gobuf_ret(R3)
   132		MOVV	R0, gobuf_lr(R3)
   133		MOVV	R0, gobuf_ctxt(R3)
   134		MOVV	gobuf_pc(R3), R4
   135		JMP	(R4)
   136	
   137	// void mcall(fn func(*g))
   138	// Switch to m->g0's stack, call fn(g).
   139	// Fn must never return. It should gogo(&g->sched)
   140	// to keep running g.
   141	TEXT runtime·mcall(SB), NOSPLIT, $-8-8
   142		// Save caller state in g->sched
   143		MOVV	R29, (g_sched+gobuf_sp)(g)
   144		MOVV	R31, (g_sched+gobuf_pc)(g)
   145		MOVV	R0, (g_sched+gobuf_lr)(g)
   146		MOVV	g, (g_sched+gobuf_g)(g)
   147	
   148		// Switch to m->g0 & its stack, call fn.
   149		MOVV	g, R1
   150		MOVV	g_m(g), R3
   151		MOVV	m_g0(R3), g
   152		JAL	runtime·save_g(SB)
   153		BNE	g, R1, 2(PC)
   154		JMP	runtime·badmcall(SB)
   155		MOVV	fn+0(FP), REGCTXT			// context
   156		MOVV	0(REGCTXT), R4			// code pointer
   157		MOVV	(g_sched+gobuf_sp)(g), R29	// sp = m->g0->sched.sp
   158		ADDV	$-16, R29
   159		MOVV	R1, 8(R29)
   160		MOVV	R0, 0(R29)
   161		JAL	(R4)
   162		JMP	runtime·badmcall2(SB)
   163	
   164	// systemstack_switch is a dummy routine that systemstack leaves at the bottom
   165	// of the G stack. We need to distinguish the routine that
   166	// lives at the bottom of the G stack from the one that lives
   167	// at the top of the system stack because the one at the top of
   168	// the system stack terminates the stack walk (see topofstack()).
   169	TEXT runtime·systemstack_switch(SB), NOSPLIT, $0-0
   170		UNDEF
   171		JAL	(R31)	// make sure this function is not leaf
   172		RET
   173	
   174	// func systemstack(fn func())
   175	TEXT runtime·systemstack(SB), NOSPLIT, $0-8
   176		MOVV	fn+0(FP), R1	// R1 = fn
   177		MOVV	R1, REGCTXT		// context
   178		MOVV	g_m(g), R2	// R2 = m
   179	
   180		MOVV	m_gsignal(R2), R3	// R3 = gsignal
   181		BEQ	g, R3, noswitch
   182	
   183		MOVV	m_g0(R2), R3	// R3 = g0
   184		BEQ	g, R3, noswitch
   185	
   186		MOVV	m_curg(R2), R4
   187		BEQ	g, R4, switch
   188	
   189		// Bad: g is not gsignal, not g0, not curg. What is it?
   190		// Hide call from linker nosplit analysis.
   191		MOVV	$runtime·badsystemstack(SB), R4
   192		JAL	(R4)
   193	
   194	switch:
   195		// save our state in g->sched. Pretend to
   196		// be systemstack_switch if the G stack is scanned.
   197		MOVV	$runtime·systemstack_switch(SB), R4
   198		ADDV	$8, R4	// get past prologue
   199		MOVV	R4, (g_sched+gobuf_pc)(g)
   200		MOVV	R29, (g_sched+gobuf_sp)(g)
   201		MOVV	R0, (g_sched+gobuf_lr)(g)
   202		MOVV	g, (g_sched+gobuf_g)(g)
   203	
   204		// switch to g0
   205		MOVV	R3, g
   206		JAL	runtime·save_g(SB)
   207		MOVV	(g_sched+gobuf_sp)(g), R1
   208		// make it look like mstart called systemstack on g0, to stop traceback
   209		ADDV	$-8, R1
   210		MOVV	$runtime·mstart(SB), R2
   211		MOVV	R2, 0(R1)
   212		MOVV	R1, R29
   213	
   214		// call target function
   215		MOVV	0(REGCTXT), R4	// code pointer
   216		JAL	(R4)
   217	
   218		// switch back to g
   219		MOVV	g_m(g), R1
   220		MOVV	m_curg(R1), g
   221		JAL	runtime·save_g(SB)
   222		MOVV	(g_sched+gobuf_sp)(g), R29
   223		MOVV	R0, (g_sched+gobuf_sp)(g)
   224		RET
   225	
   226	noswitch:
   227		// already on m stack, just call directly
   228		MOVV	0(REGCTXT), R4	// code pointer
   229		JAL	(R4)
   230		RET
   231	
   232	/*
   233	 * support for morestack
   234	 */
   235	
   236	// Called during function prolog when more stack is needed.
   237	// Caller has already loaded:
   238	// R1: framesize, R2: argsize, R3: LR
   239	//
   240	// The traceback routines see morestack on a g0 as being
   241	// the top of a stack (for example, morestack calling newstack
   242	// calling the scheduler calling newm calling gc), so we must
   243	// record an argument size. For that purpose, it has no arguments.
   244	TEXT runtime·morestack(SB),NOSPLIT,$-8-0
   245		// Cannot grow scheduler stack (m->g0).
   246		MOVV	g_m(g), R7
   247		MOVV	m_g0(R7), R8
   248		BNE	g, R8, 3(PC)
   249		JAL	runtime·badmorestackg0(SB)
   250		JAL	runtime·abort(SB)
   251	
   252		// Cannot grow signal stack (m->gsignal).
   253		MOVV	m_gsignal(R7), R8
   254		BNE	g, R8, 3(PC)
   255		JAL	runtime·badmorestackgsignal(SB)
   256		JAL	runtime·abort(SB)
   257	
   258		// Called from f.
   259		// Set g->sched to context in f.
   260		MOVV	R29, (g_sched+gobuf_sp)(g)
   261		MOVV	R31, (g_sched+gobuf_pc)(g)
   262		MOVV	R3, (g_sched+gobuf_lr)(g)
   263		// newstack will fill gobuf.ctxt.
   264	
   265		// Called from f.
   266		// Set m->morebuf to f's caller.
   267		MOVV	R3, (m_morebuf+gobuf_pc)(R7)	// f's caller's PC
   268		MOVV	R29, (m_morebuf+gobuf_sp)(R7)	// f's caller's SP
   269		MOVV	g, (m_morebuf+gobuf_g)(R7)
   270	
   271		// Call newstack on m->g0's stack.
   272		MOVV	m_g0(R7), g
   273		JAL	runtime·save_g(SB)
   274		MOVV	(g_sched+gobuf_sp)(g), R29
   275		// Create a stack frame on g0 to call newstack.
   276		MOVV	R0, -16(R29)	// Zero saved LR in frame
   277		ADDV	$-16, R29
   278		MOVV	REGCTXT, 8(R29)	// ctxt argument
   279		JAL	runtime·newstack(SB)
   280	
   281		// Not reached, but make sure the return PC from the call to newstack
   282		// is still in this function, and not the beginning of the next.
   283		UNDEF
   284	
   285	TEXT runtime·morestack_noctxt(SB),NOSPLIT,$-8-0
   286		MOVV	R0, REGCTXT
   287		JMP	runtime·morestack(SB)
   288	
   289	// reflectcall: call a function with the given argument list
   290	// func call(argtype *_type, f *FuncVal, arg *byte, argsize, retoffset uint32).
   291	// we don't have variable-sized frames, so we use a small number
   292	// of constant-sized-frame functions to encode a few bits of size in the pc.
   293	// Caution: ugly multiline assembly macros in your future!
   294	
   295	#define DISPATCH(NAME,MAXSIZE)		\
   296		MOVV	$MAXSIZE, R23;		\
   297		SGTU	R1, R23, R23;		\
   298		BNE	R23, 3(PC);			\
   299		MOVV	$NAME(SB), R4;	\
   300		JMP	(R4)
   301	// Note: can't just "BR NAME(SB)" - bad inlining results.
   302	
   303	TEXT reflect·call(SB), NOSPLIT, $0-0
   304		JMP	·reflectcall(SB)
   305	
   306	TEXT ·reflectcall(SB), NOSPLIT, $-8-32
   307		MOVWU argsize+24(FP), R1
   308		DISPATCH(runtime·call32, 32)
   309		DISPATCH(runtime·call64, 64)
   310		DISPATCH(runtime·call128, 128)
   311		DISPATCH(runtime·call256, 256)
   312		DISPATCH(runtime·call512, 512)
   313		DISPATCH(runtime·call1024, 1024)
   314		DISPATCH(runtime·call2048, 2048)
   315		DISPATCH(runtime·call4096, 4096)
   316		DISPATCH(runtime·call8192, 8192)
   317		DISPATCH(runtime·call16384, 16384)
   318		DISPATCH(runtime·call32768, 32768)
   319		DISPATCH(runtime·call65536, 65536)
   320		DISPATCH(runtime·call131072, 131072)
   321		DISPATCH(runtime·call262144, 262144)
   322		DISPATCH(runtime·call524288, 524288)
   323		DISPATCH(runtime·call1048576, 1048576)
   324		DISPATCH(runtime·call2097152, 2097152)
   325		DISPATCH(runtime·call4194304, 4194304)
   326		DISPATCH(runtime·call8388608, 8388608)
   327		DISPATCH(runtime·call16777216, 16777216)
   328		DISPATCH(runtime·call33554432, 33554432)
   329		DISPATCH(runtime·call67108864, 67108864)
   330		DISPATCH(runtime·call134217728, 134217728)
   331		DISPATCH(runtime·call268435456, 268435456)
   332		DISPATCH(runtime·call536870912, 536870912)
   333		DISPATCH(runtime·call1073741824, 1073741824)
   334		MOVV	$runtime·badreflectcall(SB), R4
   335		JMP	(R4)
   336	
   337	#define CALLFN(NAME,MAXSIZE)			\
   338	TEXT NAME(SB), WRAPPER, $MAXSIZE-24;		\
   339		NO_LOCAL_POINTERS;			\
   340		/* copy arguments to stack */		\
   341		MOVV	arg+16(FP), R1;			\
   342		MOVWU	argsize+24(FP), R2;			\
   343		MOVV	R29, R3;				\
   344		ADDV	$8, R3;			\
   345		ADDV	R3, R2;				\
   346		BEQ	R3, R2, 6(PC);				\
   347		MOVBU	(R1), R4;			\
   348		ADDV	$1, R1;			\
   349		MOVBU	R4, (R3);			\
   350		ADDV	$1, R3;			\
   351		JMP	-5(PC);				\
   352		/* call function */			\
   353		MOVV	f+8(FP), REGCTXT;			\
   354		MOVV	(REGCTXT), R4;			\
   355		PCDATA  $PCDATA_StackMapIndex, $0;	\
   356		JAL	(R4);				\
   357		/* copy return values back */		\
   358		MOVV	argtype+0(FP), R5;		\
   359		MOVV	arg+16(FP), R1;			\
   360		MOVWU	n+24(FP), R2;			\
   361		MOVWU	retoffset+28(FP), R4;		\
   362		ADDV	$8, R29, R3;				\
   363		ADDV	R4, R3; 			\
   364		ADDV	R4, R1;				\
   365		SUBVU	R4, R2;				\
   366		JAL	callRet<>(SB);			\
   367		RET
   368	
   369	// callRet copies return values back at the end of call*. This is a
   370	// separate function so it can allocate stack space for the arguments
   371	// to reflectcallmove. It does not follow the Go ABI; it expects its
   372	// arguments in registers.
   373	TEXT callRet<>(SB), NOSPLIT, $32-0
   374		MOVV	R5, 8(R29)
   375		MOVV	R1, 16(R29)
   376		MOVV	R3, 24(R29)
   377		MOVV	R2, 32(R29)
   378		JAL	runtime·reflectcallmove(SB)
   379		RET
   380	
   381	CALLFN(·call16, 16)
   382	CALLFN(·call32, 32)
   383	CALLFN(·call64, 64)
   384	CALLFN(·call128, 128)
   385	CALLFN(·call256, 256)
   386	CALLFN(·call512, 512)
   387	CALLFN(·call1024, 1024)
   388	CALLFN(·call2048, 2048)
   389	CALLFN(·call4096, 4096)
   390	CALLFN(·call8192, 8192)
   391	CALLFN(·call16384, 16384)
   392	CALLFN(·call32768, 32768)
   393	CALLFN(·call65536, 65536)
   394	CALLFN(·call131072, 131072)
   395	CALLFN(·call262144, 262144)
   396	CALLFN(·call524288, 524288)
   397	CALLFN(·call1048576, 1048576)
   398	CALLFN(·call2097152, 2097152)
   399	CALLFN(·call4194304, 4194304)
   400	CALLFN(·call8388608, 8388608)
   401	CALLFN(·call16777216, 16777216)
   402	CALLFN(·call33554432, 33554432)
   403	CALLFN(·call67108864, 67108864)
   404	CALLFN(·call134217728, 134217728)
   405	CALLFN(·call268435456, 268435456)
   406	CALLFN(·call536870912, 536870912)
   407	CALLFN(·call1073741824, 1073741824)
   408	
   409	TEXT runtime·procyield(SB),NOSPLIT,$0-0
   410		RET
   411	
   412	// void jmpdefer(fv, sp);
   413	// called from deferreturn.
   414	// 1. grab stored LR for caller
   415	// 2. sub 8 bytes to get back to JAL deferreturn
   416	// 3. JMP to fn
   417	TEXT runtime·jmpdefer(SB), NOSPLIT, $-8-16
   418		MOVV	0(R29), R31
   419		ADDV	$-8, R31
   420	
   421		MOVV	fv+0(FP), REGCTXT
   422		MOVV	argp+8(FP), R29
   423		ADDV	$-8, R29
   424		NOR	R0, R0	// prevent scheduling
   425		MOVV	0(REGCTXT), R4
   426		JMP	(R4)
   427	
   428	// Save state of caller into g->sched. Smashes R1.
   429	TEXT gosave<>(SB),NOSPLIT,$-8
   430		MOVV	R31, (g_sched+gobuf_pc)(g)
   431		MOVV	R29, (g_sched+gobuf_sp)(g)
   432		MOVV	R0, (g_sched+gobuf_lr)(g)
   433		MOVV	R0, (g_sched+gobuf_ret)(g)
   434		// Assert ctxt is zero. See func save.
   435		MOVV	(g_sched+gobuf_ctxt)(g), R1
   436		BEQ	R1, 2(PC)
   437		JAL	runtime·badctxt(SB)
   438		RET
   439	
   440	// func asmcgocall(fn, arg unsafe.Pointer) int32
   441	// Call fn(arg) on the scheduler stack,
   442	// aligned appropriately for the gcc ABI.
   443	// See cgocall.go for more details.
   444	TEXT ·asmcgocall(SB),NOSPLIT,$0-20
   445		MOVV	fn+0(FP), R25
   446		MOVV	arg+8(FP), R4
   447	
   448		MOVV	R29, R3	// save original stack pointer
   449		MOVV	g, R2
   450	
   451		// Figure out if we need to switch to m->g0 stack.
   452		// We get called to create new OS threads too, and those
   453		// come in on the m->g0 stack already.
   454		MOVV	g_m(g), R5
   455		MOVV	m_g0(R5), R6
   456		BEQ	R6, g, g0
   457	
   458		JAL	gosave<>(SB)
   459		MOVV	R6, g
   460		JAL	runtime·save_g(SB)
   461		MOVV	(g_sched+gobuf_sp)(g), R29
   462	
   463		// Now on a scheduling stack (a pthread-created stack).
   464	g0:
   465		// Save room for two of our pointers.
   466		ADDV	$-16, R29
   467		MOVV	R2, 0(R29)	// save old g on stack
   468		MOVV	(g_stack+stack_hi)(R2), R2
   469		SUBVU	R3, R2
   470		MOVV	R2, 8(R29)	// save depth in old g stack (can't just save SP, as stack might be copied during a callback)
   471		JAL	(R25)
   472	
   473		// Restore g, stack pointer. R2 is return value.
   474		MOVV	0(R29), g
   475		JAL	runtime·save_g(SB)
   476		MOVV	(g_stack+stack_hi)(g), R5
   477		MOVV	8(R29), R6
   478		SUBVU	R6, R5
   479		MOVV	R5, R29
   480	
   481		MOVW	R2, ret+16(FP)
   482		RET
   483	
   484	// cgocallback(void (*fn)(void*), void *frame, uintptr framesize, uintptr ctxt)
   485	// Turn the fn into a Go func (by taking its address) and call
   486	// cgocallback_gofunc.
   487	TEXT runtime·cgocallback(SB),NOSPLIT,$32-32
   488		MOVV	$fn+0(FP), R1
   489		MOVV	R1, 8(R29)
   490		MOVV	frame+8(FP), R1
   491		MOVV	R1, 16(R29)
   492		MOVV	framesize+16(FP), R1
   493		MOVV	R1, 24(R29)
   494		MOVV	ctxt+24(FP), R1
   495		MOVV	R1, 32(R29)
   496		MOVV	$runtime·cgocallback_gofunc(SB), R1
   497		JAL	(R1)
   498		RET
   499	
   500	// cgocallback_gofunc(FuncVal*, void *frame, uintptr framesize, uintptr ctxt)
   501	// See cgocall.go for more details.
   502	TEXT ·cgocallback_gofunc(SB),NOSPLIT,$16-32
   503		NO_LOCAL_POINTERS
   504	
   505		// Load m and g from thread-local storage.
   506		MOVB	runtime·iscgo(SB), R1
   507		BEQ	R1, nocgo
   508		JAL	runtime·load_g(SB)
   509	nocgo:
   510	
   511		// If g is nil, Go did not create the current thread.
   512		// Call needm to obtain one for temporary use.
   513		// In this case, we're running on the thread stack, so there's
   514		// lots of space, but the linker doesn't know. Hide the call from
   515		// the linker analysis by using an indirect call.
   516		BEQ	g, needm
   517	
   518		MOVV	g_m(g), R3
   519		MOVV	R3, savedm-8(SP)
   520		JMP	havem
   521	
   522	needm:
   523		MOVV	g, savedm-8(SP) // g is zero, so is m.
   524		MOVV	$runtime·needm(SB), R4
   525		JAL	(R4)
   526	
   527		// Set m->sched.sp = SP, so that if a panic happens
   528		// during the function we are about to execute, it will
   529		// have a valid SP to run on the g0 stack.
   530		// The next few lines (after the havem label)
   531		// will save this SP onto the stack and then write
   532		// the same SP back to m->sched.sp. That seems redundant,
   533		// but if an unrecovered panic happens, unwindm will
   534		// restore the g->sched.sp from the stack location
   535		// and then systemstack will try to use it. If we don't set it here,
   536		// that restored SP will be uninitialized (typically 0) and
   537		// will not be usable.
   538		MOVV	g_m(g), R3
   539		MOVV	m_g0(R3), R1
   540		MOVV	R29, (g_sched+gobuf_sp)(R1)
   541	
   542	havem:
   543		// Now there's a valid m, and we're running on its m->g0.
   544		// Save current m->g0->sched.sp on stack and then set it to SP.
   545		// Save current sp in m->g0->sched.sp in preparation for
   546		// switch back to m->curg stack.
   547		// NOTE: unwindm knows that the saved g->sched.sp is at 8(R29) aka savedsp-16(SP).
   548		MOVV	m_g0(R3), R1
   549		MOVV	(g_sched+gobuf_sp)(R1), R2
   550		MOVV	R2, savedsp-16(SP)
   551		MOVV	R29, (g_sched+gobuf_sp)(R1)
   552	
   553		// Switch to m->curg stack and call runtime.cgocallbackg.
   554		// Because we are taking over the execution of m->curg
   555		// but *not* resuming what had been running, we need to
   556		// save that information (m->curg->sched) so we can restore it.
   557		// We can restore m->curg->sched.sp easily, because calling
   558		// runtime.cgocallbackg leaves SP unchanged upon return.
   559		// To save m->curg->sched.pc, we push it onto the stack.
   560		// This has the added benefit that it looks to the traceback
   561		// routine like cgocallbackg is going to return to that
   562		// PC (because the frame we allocate below has the same
   563		// size as cgocallback_gofunc's frame declared above)
   564		// so that the traceback will seamlessly trace back into
   565		// the earlier calls.
   566		//
   567		// In the new goroutine, -8(SP) is unused (where SP refers to
   568		// m->curg's SP while we're setting it up, before we've adjusted it).
   569		MOVV	m_curg(R3), g
   570		JAL	runtime·save_g(SB)
   571		MOVV	(g_sched+gobuf_sp)(g), R2 // prepare stack as R2
   572		MOVV	(g_sched+gobuf_pc)(g), R4
   573		MOVV	R4, -24(R2)
   574		MOVV    ctxt+24(FP), R1
   575		MOVV    R1, -16(R2)
   576		MOVV	$-24(R2), R29
   577		JAL	runtime·cgocallbackg(SB)
   578	
   579		// Restore g->sched (== m->curg->sched) from saved values.
   580		MOVV	0(R29), R4
   581		MOVV	R4, (g_sched+gobuf_pc)(g)
   582		MOVV	$24(R29), R2
   583		MOVV	R2, (g_sched+gobuf_sp)(g)
   584	
   585		// Switch back to m->g0's stack and restore m->g0->sched.sp.
   586		// (Unlike m->curg, the g0 goroutine never uses sched.pc,
   587		// so we do not have to restore it.)
   588		MOVV	g_m(g), R3
   589		MOVV	m_g0(R3), g
   590		JAL	runtime·save_g(SB)
   591		MOVV	(g_sched+gobuf_sp)(g), R29
   592		MOVV	savedsp-16(SP), R2
   593		MOVV	R2, (g_sched+gobuf_sp)(g)
   594	
   595		// If the m on entry was nil, we called needm above to borrow an m
   596		// for the duration of the call. Since the call is over, return it with dropm.
   597		MOVV	savedm-8(SP), R3
   598		BNE	R3, droppedm
   599		MOVV	$runtime·dropm(SB), R4
   600		JAL	(R4)
   601	droppedm:
   602	
   603		// Done!
   604		RET
   605	
   606	// void setg(G*); set g. for use by needm.
   607	TEXT runtime·setg(SB), NOSPLIT, $0-8
   608		MOVV	gg+0(FP), g
   609		// This only happens if iscgo, so jump straight to save_g
   610		JAL	runtime·save_g(SB)
   611		RET
   612	
   613	// void setg_gcc(G*); set g called from gcc with g in R1
   614	TEXT setg_gcc<>(SB),NOSPLIT,$0-0
   615		MOVV	R1, g
   616		JAL	runtime·save_g(SB)
   617		RET
   618	
   619	TEXT runtime·getcallerpc(SB),NOSPLIT,$8-16
   620		MOVV	16(R29), R1		// LR saved by caller
   621		MOVV	R1, ret+8(FP)
   622		RET
   623	
   624	TEXT runtime·abort(SB),NOSPLIT,$-8-0
   625		MOVW	(R0), R0
   626		UNDEF
   627	
   628	// memhash_varlen(p unsafe.Pointer, h seed) uintptr
   629	// redirects to memhash(p, h, size) using the size
   630	// stored in the closure.
   631	TEXT runtime·memhash_varlen(SB),NOSPLIT,$40-24
   632		GO_ARGS
   633		NO_LOCAL_POINTERS
   634		MOVV	p+0(FP), R1
   635		MOVV	h+8(FP), R2
   636		MOVV	8(REGCTXT), R3
   637		MOVV	R1, 8(R29)
   638		MOVV	R2, 16(R29)
   639		MOVV	R3, 24(R29)
   640		JAL	runtime·memhash(SB)
   641		MOVV	32(R29), R1
   642		MOVV	R1, ret+16(FP)
   643		RET
   644	
   645	// AES hashing not implemented for mips64
   646	TEXT runtime·aeshash(SB),NOSPLIT,$-8-0
   647		MOVW	(R0), R1
   648	TEXT runtime·aeshash32(SB),NOSPLIT,$-8-0
   649		MOVW	(R0), R1
   650	TEXT runtime·aeshash64(SB),NOSPLIT,$-8-0
   651		MOVW	(R0), R1
   652	TEXT runtime·aeshashstr(SB),NOSPLIT,$-8-0
   653		MOVW	(R0), R1
   654	
   655	// memequal(p, q unsafe.Pointer, size uintptr) bool
   656	TEXT runtime·memequal(SB),NOSPLIT,$-8-25
   657		MOVV	a+0(FP), R1
   658		MOVV	b+8(FP), R2
   659		BEQ	R1, R2, eq
   660		MOVV	size+16(FP), R3
   661		ADDV	R1, R3, R4
   662	loop:
   663		BNE	R1, R4, test
   664		MOVV	$1, R1
   665		MOVB	R1, ret+24(FP)
   666		RET
   667	test:
   668		MOVBU	(R1), R6
   669		ADDV	$1, R1
   670		MOVBU	(R2), R7
   671		ADDV	$1, R2
   672		BEQ	R6, R7, loop
   673	
   674		MOVB	R0, ret+24(FP)
   675		RET
   676	eq:
   677		MOVV	$1, R1
   678		MOVB	R1, ret+24(FP)
   679		RET
   680	
   681	// memequal_varlen(a, b unsafe.Pointer) bool
   682	TEXT runtime·memequal_varlen(SB),NOSPLIT,$40-17
   683		MOVV	a+0(FP), R1
   684		MOVV	b+8(FP), R2
   685		BEQ	R1, R2, eq
   686		MOVV	8(REGCTXT), R3    // compiler stores size at offset 8 in the closure
   687		MOVV	R1, 8(R29)
   688		MOVV	R2, 16(R29)
   689		MOVV	R3, 24(R29)
   690		JAL	runtime·memequal(SB)
   691		MOVBU	32(R29), R1
   692		MOVB	R1, ret+16(FP)
   693		RET
   694	eq:
   695		MOVV	$1, R1
   696		MOVB	R1, ret+16(FP)
   697		RET
   698	
   699	// eqstring tests whether two strings are equal.
   700	// The compiler guarantees that strings passed
   701	// to eqstring have equal length.
   702	// See runtime_test.go:eqstring_generic for
   703	// equivalent Go code.
   704	TEXT runtime·eqstring(SB),NOSPLIT,$0-33
   705		MOVV	s1_base+0(FP), R1
   706		MOVV	s2_base+16(FP), R2
   707		MOVV	$1, R3
   708		MOVB	R3, ret+32(FP)
   709		BNE	R1, R2, 2(PC)
   710		RET
   711		MOVV	s1_len+8(FP), R3
   712		ADDV	R1, R3, R4
   713	loop:
   714		BNE	R1, R4, 2(PC)
   715		RET
   716		MOVBU	(R1), R6
   717		ADDV	$1, R1
   718		MOVBU	(R2), R7
   719		ADDV	$1, R2
   720		BEQ	R6, R7, loop
   721		MOVB	R0, ret+32(FP)
   722		RET
   723	
   724	// TODO: share code with memequal?
   725	TEXT bytes·Equal(SB),NOSPLIT,$0-49
   726		MOVV	a_len+8(FP), R3
   727		MOVV	b_len+32(FP), R4
   728		BNE	R3, R4, noteq		// unequal lengths are not equal
   729	
   730		MOVV	a+0(FP), R1
   731		MOVV	b+24(FP), R2
   732		ADDV	R1, R3		// end
   733	
   734	loop:
   735		BEQ	R1, R3, equal		// reached the end
   736		MOVBU	(R1), R6
   737		ADDV	$1, R1
   738		MOVBU	(R2), R7
   739		ADDV	$1, R2
   740		BEQ	R6, R7, loop
   741	
   742	noteq:
   743		MOVB	R0, ret+48(FP)
   744		RET
   745	
   746	equal:
   747		MOVV	$1, R1
   748		MOVB	R1, ret+48(FP)
   749		RET
   750	
   751	TEXT bytes·IndexByte(SB),NOSPLIT,$0-40
   752		MOVV	s+0(FP), R1
   753		MOVV	s_len+8(FP), R2
   754		MOVBU	c+24(FP), R3	// byte to find
   755		MOVV	R1, R4		// store base for later
   756		ADDV	R1, R2		// end
   757		ADDV	$-1, R1
   758	
   759	loop:
   760		ADDV	$1, R1
   761		BEQ	R1, R2, notfound
   762		MOVBU	(R1), R5
   763		BNE	R3, R5, loop
   764	
   765		SUBV	R4, R1		// remove base
   766		MOVV	R1, ret+32(FP)
   767		RET
   768	
   769	notfound:
   770		MOVV	$-1, R1
   771		MOVV	R1, ret+32(FP)
   772		RET
   773	
   774	TEXT strings·IndexByte(SB),NOSPLIT,$0-32
   775		MOVV	p+0(FP), R1
   776		MOVV	b_len+8(FP), R2
   777		MOVBU	c+16(FP), R3	// byte to find
   778		MOVV	R1, R4		// store base for later
   779		ADDV	R1, R2		// end
   780		ADDV	$-1, R1
   781	
   782	loop:
   783		ADDV	$1, R1
   784		BEQ	R1, R2, notfound
   785		MOVBU	(R1), R5
   786		BNE	R3, R5, loop
   787	
   788		SUBV	R4, R1		// remove base
   789		MOVV	R1, ret+24(FP)
   790		RET
   791	
   792	notfound:
   793		MOVV	$-1, R1
   794		MOVV	R1, ret+24(FP)
   795		RET
   796	
   797	TEXT runtime·return0(SB), NOSPLIT, $0
   798		MOVW	$0, R1
   799		RET
   800	
   801	// Called from cgo wrappers, this function returns g->m->curg.stack.hi.
   802	// Must obey the gcc calling convention.
   803	TEXT _cgo_topofstack(SB),NOSPLIT,$16
   804		// g (R30) and REGTMP (R23)  might be clobbered by load_g. They
   805		// are callee-save in the gcc calling convention, so save them.
   806		MOVV	R23, savedR23-16(SP)
   807		MOVV	g, savedG-8(SP)
   808	
   809		JAL	runtime·load_g(SB)
   810		MOVV	g_m(g), R1
   811		MOVV	m_curg(R1), R1
   812		MOVV	(g_stack+stack_hi)(R1), R2 // return value in R2
   813	
   814		MOVV	savedG-8(SP), g
   815		MOVV	savedR23-16(SP), R23
   816		RET
   817	
   818	// The top-most function running on a goroutine
   819	// returns to goexit+PCQuantum.
   820	TEXT runtime·goexit(SB),NOSPLIT,$-8-0
   821		NOR	R0, R0	// NOP
   822		JAL	runtime·goexit1(SB)	// does not return
   823		// traceback from goexit1 must hit code range of goexit
   824		NOR	R0, R0	// NOP
   825	
   826	TEXT runtime·prefetcht0(SB),NOSPLIT,$0-8
   827		RET
   828	
   829	TEXT runtime·prefetcht1(SB),NOSPLIT,$0-8
   830		RET
   831	
   832	TEXT runtime·prefetcht2(SB),NOSPLIT,$0-8
   833		RET
   834	
   835	TEXT runtime·prefetchnta(SB),NOSPLIT,$0-8
   836		RET
   837	
   838	TEXT ·checkASM(SB),NOSPLIT,$0-1
   839		MOVW	$1, R1
   840		MOVB	R1, ret+0(FP)
   841		RET

View as plain text