Text file src/runtime/asm_mips64x.s

     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  //go: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|TOPFRAME,$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	$-16, R29
    66  	MOVV	R1, 8(R29)
    67  	MOVV	R0, 0(R29)
    68  	JAL	runtime·newproc(SB)
    69  	ADDV	$16, R29
    70  
    71  	// start this M
    72  	JAL	runtime·mstart(SB)
    73  
    74  	MOVV	R0, 1(R0)
    75  	RET
    76  
    77  DATA	runtime·mainPC+0(SB)/8,$runtime·main(SB)
    78  GLOBL	runtime·mainPC(SB),RODATA,$8
    79  
    80  TEXT runtime·breakpoint(SB),NOSPLIT|NOFRAME,$0-0
    81  	MOVV	R0, 2(R0) // TODO: TD
    82  	RET
    83  
    84  TEXT runtime·asminit(SB),NOSPLIT|NOFRAME,$0-0
    85  	RET
    86  
    87  TEXT runtime·mstart(SB),NOSPLIT|TOPFRAME,$0
    88  	JAL	runtime·mstart0(SB)
    89  	RET // not reached
    90  
    91  /*
    92   *  go-routine
    93   */
    94  
    95  // void gogo(Gobuf*)
    96  // restore state from Gobuf; longjmp
    97  TEXT runtime·gogo(SB), NOSPLIT|NOFRAME, $0-8
    98  	MOVV	buf+0(FP), R3
    99  	MOVV	gobuf_g(R3), R4
   100  	MOVV	0(R4), R0	// make sure g != nil
   101  	JMP	gogo<>(SB)
   102  
   103  TEXT gogo<>(SB), NOSPLIT|NOFRAME, $0
   104  	MOVV	R4, g
   105  	JAL	runtime·save_g(SB)
   106  
   107  	MOVV	0(g), R2
   108  	MOVV	gobuf_sp(R3), R29
   109  	MOVV	gobuf_lr(R3), R31
   110  	MOVV	gobuf_ret(R3), R1
   111  	MOVV	gobuf_ctxt(R3), REGCTXT
   112  	MOVV	R0, gobuf_sp(R3)
   113  	MOVV	R0, gobuf_ret(R3)
   114  	MOVV	R0, gobuf_lr(R3)
   115  	MOVV	R0, gobuf_ctxt(R3)
   116  	MOVV	gobuf_pc(R3), R4
   117  	JMP	(R4)
   118  
   119  // void mcall(fn func(*g))
   120  // Switch to m->g0's stack, call fn(g).
   121  // Fn must never return. It should gogo(&g->sched)
   122  // to keep running g.
   123  TEXT runtime·mcall(SB), NOSPLIT|NOFRAME, $0-8
   124  	// Save caller state in g->sched
   125  	MOVV	R29, (g_sched+gobuf_sp)(g)
   126  	MOVV	R31, (g_sched+gobuf_pc)(g)
   127  	MOVV	R0, (g_sched+gobuf_lr)(g)
   128  
   129  	// Switch to m->g0 & its stack, call fn.
   130  	MOVV	g, R1
   131  	MOVV	g_m(g), R3
   132  	MOVV	m_g0(R3), g
   133  	JAL	runtime·save_g(SB)
   134  	BNE	g, R1, 2(PC)
   135  	JMP	runtime·badmcall(SB)
   136  	MOVV	fn+0(FP), REGCTXT			// context
   137  	MOVV	0(REGCTXT), R4			// code pointer
   138  	MOVV	(g_sched+gobuf_sp)(g), R29	// sp = m->g0->sched.sp
   139  	ADDV	$-16, R29
   140  	MOVV	R1, 8(R29)
   141  	MOVV	R0, 0(R29)
   142  	JAL	(R4)
   143  	JMP	runtime·badmcall2(SB)
   144  
   145  // systemstack_switch is a dummy routine that systemstack leaves at the bottom
   146  // of the G stack. We need to distinguish the routine that
   147  // lives at the bottom of the G stack from the one that lives
   148  // at the top of the system stack because the one at the top of
   149  // the system stack terminates the stack walk (see topofstack()).
   150  TEXT runtime·systemstack_switch(SB), NOSPLIT, $0-0
   151  	UNDEF
   152  	JAL	(R31)	// make sure this function is not leaf
   153  	RET
   154  
   155  // func systemstack(fn func())
   156  TEXT runtime·systemstack(SB), NOSPLIT, $0-8
   157  	MOVV	fn+0(FP), R1	// R1 = fn
   158  	MOVV	R1, REGCTXT		// context
   159  	MOVV	g_m(g), R2	// R2 = m
   160  
   161  	MOVV	m_gsignal(R2), R3	// R3 = gsignal
   162  	BEQ	g, R3, noswitch
   163  
   164  	MOVV	m_g0(R2), R3	// R3 = g0
   165  	BEQ	g, R3, noswitch
   166  
   167  	MOVV	m_curg(R2), R4
   168  	BEQ	g, R4, switch
   169  
   170  	// Bad: g is not gsignal, not g0, not curg. What is it?
   171  	// Hide call from linker nosplit analysis.
   172  	MOVV	$runtime·badsystemstack(SB), R4
   173  	JAL	(R4)
   174  	JAL	runtime·abort(SB)
   175  
   176  switch:
   177  	// save our state in g->sched. Pretend to
   178  	// be systemstack_switch if the G stack is scanned.
   179  	JAL	gosave_systemstack_switch<>(SB)
   180  
   181  	// switch to g0
   182  	MOVV	R3, g
   183  	JAL	runtime·save_g(SB)
   184  	MOVV	(g_sched+gobuf_sp)(g), R1
   185  	MOVV	R1, R29
   186  
   187  	// call target function
   188  	MOVV	0(REGCTXT), R4	// code pointer
   189  	JAL	(R4)
   190  
   191  	// switch back to g
   192  	MOVV	g_m(g), R1
   193  	MOVV	m_curg(R1), g
   194  	JAL	runtime·save_g(SB)
   195  	MOVV	(g_sched+gobuf_sp)(g), R29
   196  	MOVV	R0, (g_sched+gobuf_sp)(g)
   197  	RET
   198  
   199  noswitch:
   200  	// already on m stack, just call directly
   201  	// Using a tail call here cleans up tracebacks since we won't stop
   202  	// at an intermediate systemstack.
   203  	MOVV	0(REGCTXT), R4	// code pointer
   204  	MOVV	0(R29), R31	// restore LR
   205  	ADDV	$8, R29
   206  	JMP	(R4)
   207  
   208  // func switchToCrashStack0(fn func())
   209  TEXT runtime·switchToCrashStack0(SB), NOSPLIT, $0-8
   210  	MOVV	fn+0(FP), REGCTXT	// context register
   211  	MOVV	g_m(g), R2	// curm
   212  
   213  	// set g to gcrash
   214  	MOVV	$runtime·gcrash(SB), g	// g = &gcrash
   215  	CALL	runtime·save_g(SB)
   216  	MOVV	R2, g_m(g)	// g.m = curm
   217  	MOVV	g, m_g0(R2)	// curm.g0 = g
   218  
   219  	// switch to crashstack
   220  	MOVV	(g_stack+stack_hi)(g), R2
   221  	ADDV	$(-4*8), R2, R29
   222  
   223  	// call target function
   224  	MOVV	0(REGCTXT), R25
   225  	JAL	(R25)
   226  
   227  	// should never return
   228  	CALL	runtime·abort(SB)
   229  	UNDEF
   230  
   231  /*
   232   * support for morestack
   233   */
   234  
   235  // Called during function prolog when more stack is needed.
   236  // Caller has already loaded:
   237  // R1: framesize, R2: argsize, R3: LR
   238  //
   239  // The traceback routines see morestack on a g0 as being
   240  // the top of a stack (for example, morestack calling newstack
   241  // calling the scheduler calling newm calling gc), so we must
   242  // record an argument size. For that purpose, it has no arguments.
   243  TEXT runtime·morestack(SB),NOSPLIT|NOFRAME,$0-0
   244  	// Called from f.
   245  	// Set g->sched to context in f.
   246  	MOVV	R29, (g_sched+gobuf_sp)(g)
   247  	MOVV	R31, (g_sched+gobuf_pc)(g)
   248  	MOVV	R3, (g_sched+gobuf_lr)(g)
   249  	MOVV	REGCTXT, (g_sched+gobuf_ctxt)(g)
   250  
   251  	// Cannot grow scheduler stack (m->g0).
   252  	MOVV	g_m(g), R7
   253  	MOVV	m_g0(R7), R8
   254  	BNE	g, R8, 3(PC)
   255  	JAL	runtime·badmorestackg0(SB)
   256  	JAL	runtime·abort(SB)
   257  
   258  	// Cannot grow signal stack (m->gsignal).
   259  	MOVV	m_gsignal(R7), R8
   260  	BNE	g, R8, 3(PC)
   261  	JAL	runtime·badmorestackgsignal(SB)
   262  	JAL	runtime·abort(SB)
   263  
   264  	// Called from f.
   265  	// Set m->morebuf to f's caller.
   266  	MOVV	R3, (m_morebuf+gobuf_pc)(R7)	// f's caller's PC
   267  	MOVV	R29, (m_morebuf+gobuf_sp)(R7)	// f's caller's SP
   268  	MOVV	g, (m_morebuf+gobuf_g)(R7)
   269  
   270  	// Call newstack on m->g0's stack.
   271  	MOVV	m_g0(R7), g
   272  	JAL	runtime·save_g(SB)
   273  	MOVV	(g_sched+gobuf_sp)(g), R29
   274  	// Create a stack frame on g0 to call newstack.
   275  	MOVV	R0, -8(R29)	// Zero saved LR in frame
   276  	ADDV	$-8, R29
   277  	JAL	runtime·newstack(SB)
   278  
   279  	// Not reached, but make sure the return PC from the call to newstack
   280  	// is still in this function, and not the beginning of the next.
   281  	UNDEF
   282  
   283  TEXT runtime·morestack_noctxt(SB),NOSPLIT|NOFRAME,$0-0
   284  	// Force SPWRITE. This function doesn't actually write SP,
   285  	// but it is called with a special calling convention where
   286  	// the caller doesn't save LR on stack but passes it as a
   287  	// register (R3), and the unwinder currently doesn't understand.
   288  	// Make it SPWRITE to stop unwinding. (See issue 54332)
   289  	MOVV	R29, R29
   290  
   291  	MOVV	R0, REGCTXT
   292  	JMP	runtime·morestack(SB)
   293  
   294  // reflectcall: call a function with the given argument list
   295  // func call(stackArgsType *_type, f *FuncVal, stackArgs *byte, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs).
   296  // we don't have variable-sized frames, so we use a small number
   297  // of constant-sized-frame functions to encode a few bits of size in the pc.
   298  // Caution: ugly multiline assembly macros in your future!
   299  
   300  #define DISPATCH(NAME,MAXSIZE)		\
   301  	MOVV	$MAXSIZE, R23;		\
   302  	SGTU	R1, R23, R23;		\
   303  	BNE	R23, 3(PC);			\
   304  	MOVV	$NAME(SB), R4;	\
   305  	JMP	(R4)
   306  // Note: can't just "BR NAME(SB)" - bad inlining results.
   307  
   308  TEXT ·reflectcall(SB), NOSPLIT|NOFRAME, $0-48
   309  	MOVWU	frameSize+32(FP), R1
   310  	DISPATCH(runtime·call16, 16)
   311  	DISPATCH(runtime·call32, 32)
   312  	DISPATCH(runtime·call64, 64)
   313  	DISPATCH(runtime·call128, 128)
   314  	DISPATCH(runtime·call256, 256)
   315  	DISPATCH(runtime·call512, 512)
   316  	DISPATCH(runtime·call1024, 1024)
   317  	DISPATCH(runtime·call2048, 2048)
   318  	DISPATCH(runtime·call4096, 4096)
   319  	DISPATCH(runtime·call8192, 8192)
   320  	DISPATCH(runtime·call16384, 16384)
   321  	DISPATCH(runtime·call32768, 32768)
   322  	DISPATCH(runtime·call65536, 65536)
   323  	DISPATCH(runtime·call131072, 131072)
   324  	DISPATCH(runtime·call262144, 262144)
   325  	DISPATCH(runtime·call524288, 524288)
   326  	DISPATCH(runtime·call1048576, 1048576)
   327  	DISPATCH(runtime·call2097152, 2097152)
   328  	DISPATCH(runtime·call4194304, 4194304)
   329  	DISPATCH(runtime·call8388608, 8388608)
   330  	DISPATCH(runtime·call16777216, 16777216)
   331  	DISPATCH(runtime·call33554432, 33554432)
   332  	DISPATCH(runtime·call67108864, 67108864)
   333  	DISPATCH(runtime·call134217728, 134217728)
   334  	DISPATCH(runtime·call268435456, 268435456)
   335  	DISPATCH(runtime·call536870912, 536870912)
   336  	DISPATCH(runtime·call1073741824, 1073741824)
   337  	MOVV	$runtime·badreflectcall(SB), R4
   338  	JMP	(R4)
   339  
   340  #define CALLFN(NAME,MAXSIZE)			\
   341  TEXT NAME(SB), WRAPPER, $MAXSIZE-48;		\
   342  	NO_LOCAL_POINTERS;			\
   343  	/* copy arguments to stack */		\
   344  	MOVV	stackArgs+16(FP), R1;			\
   345  	MOVWU	stackArgsSize+24(FP), R2;			\
   346  	MOVV	R29, R3;				\
   347  	ADDV	$8, R3;			\
   348  	ADDV	R3, R2;				\
   349  	BEQ	R3, R2, 6(PC);				\
   350  	MOVBU	(R1), R4;			\
   351  	ADDV	$1, R1;			\
   352  	MOVBU	R4, (R3);			\
   353  	ADDV	$1, R3;			\
   354  	JMP	-5(PC);				\
   355  	/* call function */			\
   356  	MOVV	f+8(FP), REGCTXT;			\
   357  	MOVV	(REGCTXT), R4;			\
   358  	PCDATA  $PCDATA_StackMapIndex, $0;	\
   359  	JAL	(R4);				\
   360  	/* copy return values back */		\
   361  	MOVV	stackArgsType+0(FP), R5;		\
   362  	MOVV	stackArgs+16(FP), R1;			\
   363  	MOVWU	stackArgsSize+24(FP), R2;			\
   364  	MOVWU	stackRetOffset+28(FP), R4;		\
   365  	ADDV	$8, R29, R3;				\
   366  	ADDV	R4, R3; 			\
   367  	ADDV	R4, R1;				\
   368  	SUBVU	R4, R2;				\
   369  	JAL	callRet<>(SB);			\
   370  	RET
   371  
   372  // callRet copies return values back at the end of call*. This is a
   373  // separate function so it can allocate stack space for the arguments
   374  // to reflectcallmove. It does not follow the Go ABI; it expects its
   375  // arguments in registers.
   376  TEXT callRet<>(SB), NOSPLIT, $40-0
   377  	MOVV	R5, 8(R29)
   378  	MOVV	R1, 16(R29)
   379  	MOVV	R3, 24(R29)
   380  	MOVV	R2, 32(R29)
   381  	MOVV	$0, 40(R29)
   382  	JAL	runtime·reflectcallmove(SB)
   383  	RET
   384  
   385  CALLFN(·call16, 16)
   386  CALLFN(·call32, 32)
   387  CALLFN(·call64, 64)
   388  CALLFN(·call128, 128)
   389  CALLFN(·call256, 256)
   390  CALLFN(·call512, 512)
   391  CALLFN(·call1024, 1024)
   392  CALLFN(·call2048, 2048)
   393  CALLFN(·call4096, 4096)
   394  CALLFN(·call8192, 8192)
   395  CALLFN(·call16384, 16384)
   396  CALLFN(·call32768, 32768)
   397  CALLFN(·call65536, 65536)
   398  CALLFN(·call131072, 131072)
   399  CALLFN(·call262144, 262144)
   400  CALLFN(·call524288, 524288)
   401  CALLFN(·call1048576, 1048576)
   402  CALLFN(·call2097152, 2097152)
   403  CALLFN(·call4194304, 4194304)
   404  CALLFN(·call8388608, 8388608)
   405  CALLFN(·call16777216, 16777216)
   406  CALLFN(·call33554432, 33554432)
   407  CALLFN(·call67108864, 67108864)
   408  CALLFN(·call134217728, 134217728)
   409  CALLFN(·call268435456, 268435456)
   410  CALLFN(·call536870912, 536870912)
   411  CALLFN(·call1073741824, 1073741824)
   412  
   413  TEXT runtime·procyield(SB),NOSPLIT,$0-0
   414  	RET
   415  
   416  // Save state of caller into g->sched,
   417  // but using fake PC from systemstack_switch.
   418  // Must only be called from functions with no locals ($0)
   419  // or else unwinding from systemstack_switch is incorrect.
   420  // Smashes R1.
   421  TEXT gosave_systemstack_switch<>(SB),NOSPLIT|NOFRAME,$0
   422  	MOVV	$runtime·systemstack_switch(SB), R1
   423  	ADDV	$8, R1	// get past prologue
   424  	MOVV	R1, (g_sched+gobuf_pc)(g)
   425  	MOVV	R29, (g_sched+gobuf_sp)(g)
   426  	MOVV	R0, (g_sched+gobuf_lr)(g)
   427  	MOVV	R0, (g_sched+gobuf_ret)(g)
   428  	// Assert ctxt is zero. See func save.
   429  	MOVV	(g_sched+gobuf_ctxt)(g), R1
   430  	BEQ	R1, 2(PC)
   431  	JAL	runtime·abort(SB)
   432  	RET
   433  
   434  // func asmcgocall_no_g(fn, arg unsafe.Pointer)
   435  // Call fn(arg) aligned appropriately for the gcc ABI.
   436  // Called on a system stack, and there may be no g yet (during needm).
   437  TEXT ·asmcgocall_no_g(SB),NOSPLIT,$0-16
   438  	MOVV	fn+0(FP), R25
   439  	MOVV	arg+8(FP), R4
   440  	JAL	(R25)
   441  	RET
   442  
   443  // func asmcgocall(fn, arg unsafe.Pointer) int32
   444  // Call fn(arg) on the scheduler stack,
   445  // aligned appropriately for the gcc ABI.
   446  // See cgocall.go for more details.
   447  TEXT ·asmcgocall(SB),NOSPLIT,$0-20
   448  	MOVV	fn+0(FP), R25
   449  	MOVV	arg+8(FP), R4
   450  
   451  	MOVV	R29, R3	// save original stack pointer
   452  	MOVV	g, R2
   453  
   454  	// Figure out if we need to switch to m->g0 stack.
   455  	// We get called to create new OS threads too, and those
   456  	// come in on the m->g0 stack already. Or we might already
   457  	// be on the m->gsignal stack.
   458  	MOVV	g_m(g), R5
   459  	MOVV	m_gsignal(R5), R6
   460  	BEQ	R6, g, g0
   461  	MOVV	m_g0(R5), R6
   462  	BEQ	R6, g, g0
   463  
   464  	JAL	gosave_systemstack_switch<>(SB)
   465  	MOVV	R6, g
   466  	JAL	runtime·save_g(SB)
   467  	MOVV	(g_sched+gobuf_sp)(g), R29
   468  
   469  	// Now on a scheduling stack (a pthread-created stack).
   470  g0:
   471  	// Save room for two of our pointers.
   472  	ADDV	$-16, R29
   473  	MOVV	R2, 0(R29)	// save old g on stack
   474  	MOVV	(g_stack+stack_hi)(R2), R2
   475  	SUBVU	R3, R2
   476  	MOVV	R2, 8(R29)	// save depth in old g stack (can't just save SP, as stack might be copied during a callback)
   477  	JAL	(R25)
   478  
   479  	// Restore g, stack pointer. R2 is return value.
   480  	MOVV	0(R29), g
   481  	JAL	runtime·save_g(SB)
   482  	MOVV	(g_stack+stack_hi)(g), R5
   483  	MOVV	8(R29), R6
   484  	SUBVU	R6, R5
   485  	MOVV	R5, R29
   486  
   487  	MOVW	R2, ret+16(FP)
   488  	RET
   489  
   490  // func cgocallback(fn, frame unsafe.Pointer, ctxt uintptr)
   491  // See cgocall.go for more details.
   492  TEXT ·cgocallback(SB),NOSPLIT,$24-24
   493  	NO_LOCAL_POINTERS
   494  
   495  	// Skip cgocallbackg, just dropm when fn is nil, and frame is the saved g.
   496  	// It is used to dropm while thread is exiting.
   497  	MOVV	fn+0(FP), R5
   498  	BNE	R5, loadg
   499  	// Restore the g from frame.
   500  	MOVV	frame+8(FP), g
   501  	JMP	dropm
   502  
   503  loadg:
   504  	// Load m and g from thread-local storage.
   505  	MOVB	runtime·iscgo(SB), R1
   506  	BEQ	R1, nocgo
   507  	JAL	runtime·load_g(SB)
   508  nocgo:
   509  
   510  	// If g is nil, Go did not create the current thread,
   511  	// or if this thread never called into Go on pthread platforms.
   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·needAndBindM(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-24(SP)	// must match frame size
   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 curg stack and
   560  	// open a frame the same size as cgocallback's g0 frame.
   561  	// Once we switch to the curg stack, the pushed PC will appear
   562  	// to be the return PC of cgocallback, so that the traceback
   563  	// will seamlessly trace back into the earlier calls.
   564  	MOVV	m_curg(R3), g
   565  	JAL	runtime·save_g(SB)
   566  	MOVV	(g_sched+gobuf_sp)(g), R2 // prepare stack as R2
   567  	MOVV	(g_sched+gobuf_pc)(g), R4
   568  	MOVV	R4, -(24+8)(R2)	// "saved LR"; must match frame size
   569  	// Gather our arguments into registers.
   570  	MOVV	fn+0(FP), R5
   571  	MOVV	frame+8(FP), R6
   572  	MOVV	ctxt+16(FP), R7
   573  	MOVV	$-(24+8)(R2), R29	// switch stack; must match frame size
   574  	MOVV	R5, 8(R29)
   575  	MOVV	R6, 16(R29)
   576  	MOVV	R7, 24(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+8)(R29), R2	// must match frame size
   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-24(SP), R2	// must match frame size
   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  	// 1. for the duration of the call on non-pthread platforms,
   597  	// 2. or the duration of the C thread alive on pthread platforms.
   598  	// If the m on entry wasn't nil,
   599  	// 1. the thread might be a Go thread,
   600  	// 2. or it wasn't the first call from a C thread on pthread platforms,
   601  	//    since then we skip dropm to reuse the m in the first call.
   602  	MOVV	savedm-8(SP), R3
   603  	BNE	R3, droppedm
   604  
   605  	// Skip dropm to reuse it in the next call, when a pthread key has been created.
   606  	MOVV	_cgo_pthread_key_created(SB), R3
   607  	// It means cgo is disabled when _cgo_pthread_key_created is a nil pointer, need dropm.
   608  	BEQ	R3, dropm
   609  	MOVV	(R3), R3
   610  	BNE	R3, droppedm
   611  
   612  dropm:
   613  	MOVV	$runtime·dropm(SB), R4
   614  	JAL	(R4)
   615  droppedm:
   616  
   617  	// Done!
   618  	RET
   619  
   620  // void setg(G*); set g. for use by needm.
   621  TEXT runtime·setg(SB), NOSPLIT, $0-8
   622  	MOVV	gg+0(FP), g
   623  	// This only happens if iscgo, so jump straight to save_g
   624  	JAL	runtime·save_g(SB)
   625  	RET
   626  
   627  // void setg_gcc(G*); set g called from gcc with g in R1
   628  TEXT setg_gcc<>(SB),NOSPLIT,$0-0
   629  	MOVV	R1, g
   630  	JAL	runtime·save_g(SB)
   631  	RET
   632  
   633  TEXT runtime·abort(SB),NOSPLIT|NOFRAME,$0-0
   634  	MOVW	(R0), R0
   635  	UNDEF
   636  
   637  // AES hashing not implemented for mips64
   638  TEXT runtime·memhash(SB),NOSPLIT|NOFRAME,$0-32
   639  	JMP	runtime·memhashFallback(SB)
   640  TEXT runtime·strhash(SB),NOSPLIT|NOFRAME,$0-24
   641  	JMP	runtime·strhashFallback(SB)
   642  TEXT runtime·memhash32(SB),NOSPLIT|NOFRAME,$0-24
   643  	JMP	runtime·memhash32Fallback(SB)
   644  TEXT runtime·memhash64(SB),NOSPLIT|NOFRAME,$0-24
   645  	JMP	runtime·memhash64Fallback(SB)
   646  
   647  TEXT runtime·return0(SB), NOSPLIT, $0
   648  	MOVW	$0, R1
   649  	RET
   650  
   651  // Called from cgo wrappers, this function returns g->m->curg.stack.hi.
   652  // Must obey the gcc calling convention.
   653  TEXT _cgo_topofstack(SB),NOSPLIT,$16
   654  	// g (R30) and REGTMP (R23)  might be clobbered by load_g. They
   655  	// are callee-save in the gcc calling convention, so save them.
   656  	MOVV	R23, savedR23-16(SP)
   657  	MOVV	g, savedG-8(SP)
   658  
   659  	JAL	runtime·load_g(SB)
   660  	MOVV	g_m(g), R1
   661  	MOVV	m_curg(R1), R1
   662  	MOVV	(g_stack+stack_hi)(R1), R2 // return value in R2
   663  
   664  	MOVV	savedG-8(SP), g
   665  	MOVV	savedR23-16(SP), R23
   666  	RET
   667  
   668  // The top-most function running on a goroutine
   669  // returns to goexit+PCQuantum.
   670  TEXT runtime·goexit(SB),NOSPLIT|NOFRAME|TOPFRAME,$0-0
   671  	NOR	R0, R0	// NOP
   672  	JAL	runtime·goexit1(SB)	// does not return
   673  	// traceback from goexit1 must hit code range of goexit
   674  	NOR	R0, R0	// NOP
   675  
   676  TEXT ·checkASM(SB),NOSPLIT,$0-1
   677  	MOVW	$1, R1
   678  	MOVB	R1, ret+0(FP)
   679  	RET
   680  
   681  // gcWriteBarrier informs the GC about heap pointer writes.
   682  //
   683  // gcWriteBarrier does NOT follow the Go ABI. It accepts the
   684  // number of bytes of buffer needed in R25, and returns a pointer
   685  // to the buffer space in R25.
   686  // It clobbers R23 (the linker temp register).
   687  // The act of CALLing gcWriteBarrier will clobber R31 (LR).
   688  // It does not clobber any other general-purpose registers,
   689  // but may clobber others (e.g., floating point registers).
   690  TEXT gcWriteBarrier<>(SB),NOSPLIT,$192
   691  	// Save the registers clobbered by the fast path.
   692  	MOVV	R1, 184(R29)
   693  	MOVV	R2, 192(R29)
   694  retry:
   695  	MOVV	g_m(g), R1
   696  	MOVV	m_p(R1), R1
   697  	MOVV	(p_wbBuf+wbBuf_next)(R1), R2
   698  	MOVV	(p_wbBuf+wbBuf_end)(R1), R23 // R23 is linker temp register
   699  	// Increment wbBuf.next position.
   700  	ADDV	R25, R2
   701  	// Is the buffer full?
   702  	SGTU	R2, R23, R23
   703  	BNE	R23, flush
   704  	// Commit to the larger buffer.
   705  	MOVV	R2, (p_wbBuf+wbBuf_next)(R1)
   706  	// Make return value (the original next position)
   707  	SUBV	R25, R2, R25
   708  	// Restore registers.
   709  	MOVV	184(R29), R1
   710  	MOVV	192(R29), R2
   711  	RET
   712  
   713  flush:
   714  	// Save all general purpose registers since these could be
   715  	// clobbered by wbBufFlush and were not saved by the caller.
   716  	MOVV	R20, 8(R29)
   717  	MOVV	R21, 16(R29)
   718  	// R1 already saved
   719  	// R2 already saved
   720  	MOVV	R3, 24(R29)
   721  	MOVV	R4, 32(R29)
   722  	MOVV	R5, 40(R29)
   723  	MOVV	R6, 48(R29)
   724  	MOVV	R7, 56(R29)
   725  	MOVV	R8, 64(R29)
   726  	MOVV	R9, 72(R29)
   727  	MOVV	R10, 80(R29)
   728  	MOVV	R11, 88(R29)
   729  	MOVV	R12, 96(R29)
   730  	MOVV	R13, 104(R29)
   731  	MOVV	R14, 112(R29)
   732  	MOVV	R15, 120(R29)
   733  	MOVV	R16, 128(R29)
   734  	MOVV	R17, 136(R29)
   735  	MOVV	R18, 144(R29)
   736  	MOVV	R19, 152(R29)
   737  	// R20 already saved
   738  	// R21 already saved.
   739  	MOVV	R22, 160(R29)
   740  	// R23 is tmp register.
   741  	MOVV	R24, 168(R29)
   742  	MOVV	R25, 176(R29)
   743  	// R26 is reserved by kernel.
   744  	// R27 is reserved by kernel.
   745  	// R28 is REGSB (not modified by Go code).
   746  	// R29 is SP.
   747  	// R30 is g.
   748  	// R31 is LR, which was saved by the prologue.
   749  
   750  	CALL	runtime·wbBufFlush(SB)
   751  
   752  	MOVV	8(R29), R20
   753  	MOVV	16(R29), R21
   754  	MOVV	24(R29), R3
   755  	MOVV	32(R29), R4
   756  	MOVV	40(R29), R5
   757  	MOVV	48(R29), R6
   758  	MOVV	56(R29), R7
   759  	MOVV	64(R29), R8
   760  	MOVV	72(R29), R9
   761  	MOVV	80(R29), R10
   762  	MOVV	88(R29), R11
   763  	MOVV	96(R29), R12
   764  	MOVV	104(R29), R13
   765  	MOVV	112(R29), R14
   766  	MOVV	120(R29), R15
   767  	MOVV	128(R29), R16
   768  	MOVV	136(R29), R17
   769  	MOVV	144(R29), R18
   770  	MOVV	152(R29), R19
   771  	MOVV	160(R29), R22
   772  	MOVV	168(R29), R24
   773  	MOVV	176(R29), R25
   774  	JMP	retry
   775  
   776  TEXT runtime·gcWriteBarrier1<ABIInternal>(SB),NOSPLIT,$0
   777  	MOVV	$8, R25
   778  	JMP	gcWriteBarrier<>(SB)
   779  TEXT runtime·gcWriteBarrier2<ABIInternal>(SB),NOSPLIT,$0
   780  	MOVV	$16, R25
   781  	JMP	gcWriteBarrier<>(SB)
   782  TEXT runtime·gcWriteBarrier3<ABIInternal>(SB),NOSPLIT,$0
   783  	MOVV	$24, R25
   784  	JMP	gcWriteBarrier<>(SB)
   785  TEXT runtime·gcWriteBarrier4<ABIInternal>(SB),NOSPLIT,$0
   786  	MOVV	$32, R25
   787  	JMP	gcWriteBarrier<>(SB)
   788  TEXT runtime·gcWriteBarrier5<ABIInternal>(SB),NOSPLIT,$0
   789  	MOVV	$40, R25
   790  	JMP	gcWriteBarrier<>(SB)
   791  TEXT runtime·gcWriteBarrier6<ABIInternal>(SB),NOSPLIT,$0
   792  	MOVV	$48, R25
   793  	JMP	gcWriteBarrier<>(SB)
   794  TEXT runtime·gcWriteBarrier7<ABIInternal>(SB),NOSPLIT,$0
   795  	MOVV	$56, R25
   796  	JMP	gcWriteBarrier<>(SB)
   797  TEXT runtime·gcWriteBarrier8<ABIInternal>(SB),NOSPLIT,$0
   798  	MOVV	$64, R25
   799  	JMP	gcWriteBarrier<>(SB)
   800  
   801  // Note: these functions use a special calling convention to save generated code space.
   802  // Arguments are passed in registers, but the space for those arguments are allocated
   803  // in the caller's stack frame. These stubs write the args into that stack space and
   804  // then tail call to the corresponding runtime handler.
   805  // The tail call makes these stubs disappear in backtraces.
   806  TEXT runtime·panicIndex(SB),NOSPLIT,$0-16
   807  	MOVV	R1, x+0(FP)
   808  	MOVV	R2, y+8(FP)
   809  	JMP	runtime·goPanicIndex(SB)
   810  TEXT runtime·panicIndexU(SB),NOSPLIT,$0-16
   811  	MOVV	R1, x+0(FP)
   812  	MOVV	R2, y+8(FP)
   813  	JMP	runtime·goPanicIndexU(SB)
   814  TEXT runtime·panicSliceAlen(SB),NOSPLIT,$0-16
   815  	MOVV	R2, x+0(FP)
   816  	MOVV	R3, y+8(FP)
   817  	JMP	runtime·goPanicSliceAlen(SB)
   818  TEXT runtime·panicSliceAlenU(SB),NOSPLIT,$0-16
   819  	MOVV	R2, x+0(FP)
   820  	MOVV	R3, y+8(FP)
   821  	JMP	runtime·goPanicSliceAlenU(SB)
   822  TEXT runtime·panicSliceAcap(SB),NOSPLIT,$0-16
   823  	MOVV	R2, x+0(FP)
   824  	MOVV	R3, y+8(FP)
   825  	JMP	runtime·goPanicSliceAcap(SB)
   826  TEXT runtime·panicSliceAcapU(SB),NOSPLIT,$0-16
   827  	MOVV	R2, x+0(FP)
   828  	MOVV	R3, y+8(FP)
   829  	JMP	runtime·goPanicSliceAcapU(SB)
   830  TEXT runtime·panicSliceB(SB),NOSPLIT,$0-16
   831  	MOVV	R1, x+0(FP)
   832  	MOVV	R2, y+8(FP)
   833  	JMP	runtime·goPanicSliceB(SB)
   834  TEXT runtime·panicSliceBU(SB),NOSPLIT,$0-16
   835  	MOVV	R1, x+0(FP)
   836  	MOVV	R2, y+8(FP)
   837  	JMP	runtime·goPanicSliceBU(SB)
   838  TEXT runtime·panicSlice3Alen(SB),NOSPLIT,$0-16
   839  	MOVV	R3, x+0(FP)
   840  	MOVV	R4, y+8(FP)
   841  	JMP	runtime·goPanicSlice3Alen(SB)
   842  TEXT runtime·panicSlice3AlenU(SB),NOSPLIT,$0-16
   843  	MOVV	R3, x+0(FP)
   844  	MOVV	R4, y+8(FP)
   845  	JMP	runtime·goPanicSlice3AlenU(SB)
   846  TEXT runtime·panicSlice3Acap(SB),NOSPLIT,$0-16
   847  	MOVV	R3, x+0(FP)
   848  	MOVV	R4, y+8(FP)
   849  	JMP	runtime·goPanicSlice3Acap(SB)
   850  TEXT runtime·panicSlice3AcapU(SB),NOSPLIT,$0-16
   851  	MOVV	R3, x+0(FP)
   852  	MOVV	R4, y+8(FP)
   853  	JMP	runtime·goPanicSlice3AcapU(SB)
   854  TEXT runtime·panicSlice3B(SB),NOSPLIT,$0-16
   855  	MOVV	R2, x+0(FP)
   856  	MOVV	R3, y+8(FP)
   857  	JMP	runtime·goPanicSlice3B(SB)
   858  TEXT runtime·panicSlice3BU(SB),NOSPLIT,$0-16
   859  	MOVV	R2, x+0(FP)
   860  	MOVV	R3, y+8(FP)
   861  	JMP	runtime·goPanicSlice3BU(SB)
   862  TEXT runtime·panicSlice3C(SB),NOSPLIT,$0-16
   863  	MOVV	R1, x+0(FP)
   864  	MOVV	R2, y+8(FP)
   865  	JMP	runtime·goPanicSlice3C(SB)
   866  TEXT runtime·panicSlice3CU(SB),NOSPLIT,$0-16
   867  	MOVV	R1, x+0(FP)
   868  	MOVV	R2, y+8(FP)
   869  	JMP	runtime·goPanicSlice3CU(SB)
   870  TEXT runtime·panicSliceConvert(SB),NOSPLIT,$0-16
   871  	MOVV	R3, x+0(FP)
   872  	MOVV	R4, y+8(FP)
   873  	JMP	runtime·goPanicSliceConvert(SB)
   874  

View as plain text