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  /*
   209   * support for morestack
   210   */
   211  
   212  // Called during function prolog when more stack is needed.
   213  // Caller has already loaded:
   214  // R1: framesize, R2: argsize, R3: LR
   215  //
   216  // The traceback routines see morestack on a g0 as being
   217  // the top of a stack (for example, morestack calling newstack
   218  // calling the scheduler calling newm calling gc), so we must
   219  // record an argument size. For that purpose, it has no arguments.
   220  TEXT runtime·morestack(SB),NOSPLIT|NOFRAME,$0-0
   221  	// Cannot grow scheduler stack (m->g0).
   222  	MOVV	g_m(g), R7
   223  	MOVV	m_g0(R7), R8
   224  	BNE	g, R8, 3(PC)
   225  	JAL	runtime·badmorestackg0(SB)
   226  	JAL	runtime·abort(SB)
   227  
   228  	// Cannot grow signal stack (m->gsignal).
   229  	MOVV	m_gsignal(R7), R8
   230  	BNE	g, R8, 3(PC)
   231  	JAL	runtime·badmorestackgsignal(SB)
   232  	JAL	runtime·abort(SB)
   233  
   234  	// Called from f.
   235  	// Set g->sched to context in f.
   236  	MOVV	R29, (g_sched+gobuf_sp)(g)
   237  	MOVV	R31, (g_sched+gobuf_pc)(g)
   238  	MOVV	R3, (g_sched+gobuf_lr)(g)
   239  	MOVV	REGCTXT, (g_sched+gobuf_ctxt)(g)
   240  
   241  	// Called from f.
   242  	// Set m->morebuf to f's caller.
   243  	MOVV	R3, (m_morebuf+gobuf_pc)(R7)	// f's caller's PC
   244  	MOVV	R29, (m_morebuf+gobuf_sp)(R7)	// f's caller's SP
   245  	MOVV	g, (m_morebuf+gobuf_g)(R7)
   246  
   247  	// Call newstack on m->g0's stack.
   248  	MOVV	m_g0(R7), g
   249  	JAL	runtime·save_g(SB)
   250  	MOVV	(g_sched+gobuf_sp)(g), R29
   251  	// Create a stack frame on g0 to call newstack.
   252  	MOVV	R0, -8(R29)	// Zero saved LR in frame
   253  	ADDV	$-8, R29
   254  	JAL	runtime·newstack(SB)
   255  
   256  	// Not reached, but make sure the return PC from the call to newstack
   257  	// is still in this function, and not the beginning of the next.
   258  	UNDEF
   259  
   260  TEXT runtime·morestack_noctxt(SB),NOSPLIT|NOFRAME,$0-0
   261  	// Force SPWRITE. This function doesn't actually write SP,
   262  	// but it is called with a special calling convention where
   263  	// the caller doesn't save LR on stack but passes it as a
   264  	// register (R3), and the unwinder currently doesn't understand.
   265  	// Make it SPWRITE to stop unwinding. (See issue 54332)
   266  	MOVV	R29, R29
   267  
   268  	MOVV	R0, REGCTXT
   269  	JMP	runtime·morestack(SB)
   270  
   271  // reflectcall: call a function with the given argument list
   272  // func call(stackArgsType *_type, f *FuncVal, stackArgs *byte, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs).
   273  // we don't have variable-sized frames, so we use a small number
   274  // of constant-sized-frame functions to encode a few bits of size in the pc.
   275  // Caution: ugly multiline assembly macros in your future!
   276  
   277  #define DISPATCH(NAME,MAXSIZE)		\
   278  	MOVV	$MAXSIZE, R23;		\
   279  	SGTU	R1, R23, R23;		\
   280  	BNE	R23, 3(PC);			\
   281  	MOVV	$NAME(SB), R4;	\
   282  	JMP	(R4)
   283  // Note: can't just "BR NAME(SB)" - bad inlining results.
   284  
   285  TEXT ·reflectcall(SB), NOSPLIT|NOFRAME, $0-48
   286  	MOVWU	frameSize+32(FP), R1
   287  	DISPATCH(runtime·call16, 16)
   288  	DISPATCH(runtime·call32, 32)
   289  	DISPATCH(runtime·call64, 64)
   290  	DISPATCH(runtime·call128, 128)
   291  	DISPATCH(runtime·call256, 256)
   292  	DISPATCH(runtime·call512, 512)
   293  	DISPATCH(runtime·call1024, 1024)
   294  	DISPATCH(runtime·call2048, 2048)
   295  	DISPATCH(runtime·call4096, 4096)
   296  	DISPATCH(runtime·call8192, 8192)
   297  	DISPATCH(runtime·call16384, 16384)
   298  	DISPATCH(runtime·call32768, 32768)
   299  	DISPATCH(runtime·call65536, 65536)
   300  	DISPATCH(runtime·call131072, 131072)
   301  	DISPATCH(runtime·call262144, 262144)
   302  	DISPATCH(runtime·call524288, 524288)
   303  	DISPATCH(runtime·call1048576, 1048576)
   304  	DISPATCH(runtime·call2097152, 2097152)
   305  	DISPATCH(runtime·call4194304, 4194304)
   306  	DISPATCH(runtime·call8388608, 8388608)
   307  	DISPATCH(runtime·call16777216, 16777216)
   308  	DISPATCH(runtime·call33554432, 33554432)
   309  	DISPATCH(runtime·call67108864, 67108864)
   310  	DISPATCH(runtime·call134217728, 134217728)
   311  	DISPATCH(runtime·call268435456, 268435456)
   312  	DISPATCH(runtime·call536870912, 536870912)
   313  	DISPATCH(runtime·call1073741824, 1073741824)
   314  	MOVV	$runtime·badreflectcall(SB), R4
   315  	JMP	(R4)
   316  
   317  #define CALLFN(NAME,MAXSIZE)			\
   318  TEXT NAME(SB), WRAPPER, $MAXSIZE-48;		\
   319  	NO_LOCAL_POINTERS;			\
   320  	/* copy arguments to stack */		\
   321  	MOVV	stackArgs+16(FP), R1;			\
   322  	MOVWU	stackArgsSize+24(FP), R2;			\
   323  	MOVV	R29, R3;				\
   324  	ADDV	$8, R3;			\
   325  	ADDV	R3, R2;				\
   326  	BEQ	R3, R2, 6(PC);				\
   327  	MOVBU	(R1), R4;			\
   328  	ADDV	$1, R1;			\
   329  	MOVBU	R4, (R3);			\
   330  	ADDV	$1, R3;			\
   331  	JMP	-5(PC);				\
   332  	/* call function */			\
   333  	MOVV	f+8(FP), REGCTXT;			\
   334  	MOVV	(REGCTXT), R4;			\
   335  	PCDATA  $PCDATA_StackMapIndex, $0;	\
   336  	JAL	(R4);				\
   337  	/* copy return values back */		\
   338  	MOVV	stackArgsType+0(FP), R5;		\
   339  	MOVV	stackArgs+16(FP), R1;			\
   340  	MOVWU	stackArgsSize+24(FP), R2;			\
   341  	MOVWU	stackRetOffset+28(FP), R4;		\
   342  	ADDV	$8, R29, R3;				\
   343  	ADDV	R4, R3; 			\
   344  	ADDV	R4, R1;				\
   345  	SUBVU	R4, R2;				\
   346  	JAL	callRet<>(SB);			\
   347  	RET
   348  
   349  // callRet copies return values back at the end of call*. This is a
   350  // separate function so it can allocate stack space for the arguments
   351  // to reflectcallmove. It does not follow the Go ABI; it expects its
   352  // arguments in registers.
   353  TEXT callRet<>(SB), NOSPLIT, $40-0
   354  	MOVV	R5, 8(R29)
   355  	MOVV	R1, 16(R29)
   356  	MOVV	R3, 24(R29)
   357  	MOVV	R2, 32(R29)
   358  	MOVV	$0, 40(R29)
   359  	JAL	runtime·reflectcallmove(SB)
   360  	RET
   361  
   362  CALLFN(·call16, 16)
   363  CALLFN(·call32, 32)
   364  CALLFN(·call64, 64)
   365  CALLFN(·call128, 128)
   366  CALLFN(·call256, 256)
   367  CALLFN(·call512, 512)
   368  CALLFN(·call1024, 1024)
   369  CALLFN(·call2048, 2048)
   370  CALLFN(·call4096, 4096)
   371  CALLFN(·call8192, 8192)
   372  CALLFN(·call16384, 16384)
   373  CALLFN(·call32768, 32768)
   374  CALLFN(·call65536, 65536)
   375  CALLFN(·call131072, 131072)
   376  CALLFN(·call262144, 262144)
   377  CALLFN(·call524288, 524288)
   378  CALLFN(·call1048576, 1048576)
   379  CALLFN(·call2097152, 2097152)
   380  CALLFN(·call4194304, 4194304)
   381  CALLFN(·call8388608, 8388608)
   382  CALLFN(·call16777216, 16777216)
   383  CALLFN(·call33554432, 33554432)
   384  CALLFN(·call67108864, 67108864)
   385  CALLFN(·call134217728, 134217728)
   386  CALLFN(·call268435456, 268435456)
   387  CALLFN(·call536870912, 536870912)
   388  CALLFN(·call1073741824, 1073741824)
   389  
   390  TEXT runtime·procyield(SB),NOSPLIT,$0-0
   391  	RET
   392  
   393  // Save state of caller into g->sched,
   394  // but using fake PC from systemstack_switch.
   395  // Must only be called from functions with no locals ($0)
   396  // or else unwinding from systemstack_switch is incorrect.
   397  // Smashes R1.
   398  TEXT gosave_systemstack_switch<>(SB),NOSPLIT|NOFRAME,$0
   399  	MOVV	$runtime·systemstack_switch(SB), R1
   400  	ADDV	$8, R1	// get past prologue
   401  	MOVV	R1, (g_sched+gobuf_pc)(g)
   402  	MOVV	R29, (g_sched+gobuf_sp)(g)
   403  	MOVV	R0, (g_sched+gobuf_lr)(g)
   404  	MOVV	R0, (g_sched+gobuf_ret)(g)
   405  	// Assert ctxt is zero. See func save.
   406  	MOVV	(g_sched+gobuf_ctxt)(g), R1
   407  	BEQ	R1, 2(PC)
   408  	JAL	runtime·abort(SB)
   409  	RET
   410  
   411  // func asmcgocall_no_g(fn, arg unsafe.Pointer)
   412  // Call fn(arg) aligned appropriately for the gcc ABI.
   413  // Called on a system stack, and there may be no g yet (during needm).
   414  TEXT ·asmcgocall_no_g(SB),NOSPLIT,$0-16
   415  	MOVV	fn+0(FP), R25
   416  	MOVV	arg+8(FP), R4
   417  	JAL	(R25)
   418  	RET
   419  
   420  // func asmcgocall(fn, arg unsafe.Pointer) int32
   421  // Call fn(arg) on the scheduler stack,
   422  // aligned appropriately for the gcc ABI.
   423  // See cgocall.go for more details.
   424  TEXT ·asmcgocall(SB),NOSPLIT,$0-20
   425  	MOVV	fn+0(FP), R25
   426  	MOVV	arg+8(FP), R4
   427  
   428  	MOVV	R29, R3	// save original stack pointer
   429  	MOVV	g, R2
   430  
   431  	// Figure out if we need to switch to m->g0 stack.
   432  	// We get called to create new OS threads too, and those
   433  	// come in on the m->g0 stack already. Or we might already
   434  	// be on the m->gsignal stack.
   435  	MOVV	g_m(g), R5
   436  	MOVV	m_gsignal(R5), R6
   437  	BEQ	R6, g, g0
   438  	MOVV	m_g0(R5), R6
   439  	BEQ	R6, g, g0
   440  
   441  	JAL	gosave_systemstack_switch<>(SB)
   442  	MOVV	R6, g
   443  	JAL	runtime·save_g(SB)
   444  	MOVV	(g_sched+gobuf_sp)(g), R29
   445  
   446  	// Now on a scheduling stack (a pthread-created stack).
   447  g0:
   448  	// Save room for two of our pointers.
   449  	ADDV	$-16, R29
   450  	MOVV	R2, 0(R29)	// save old g on stack
   451  	MOVV	(g_stack+stack_hi)(R2), R2
   452  	SUBVU	R3, R2
   453  	MOVV	R2, 8(R29)	// save depth in old g stack (can't just save SP, as stack might be copied during a callback)
   454  	JAL	(R25)
   455  
   456  	// Restore g, stack pointer. R2 is return value.
   457  	MOVV	0(R29), g
   458  	JAL	runtime·save_g(SB)
   459  	MOVV	(g_stack+stack_hi)(g), R5
   460  	MOVV	8(R29), R6
   461  	SUBVU	R6, R5
   462  	MOVV	R5, R29
   463  
   464  	MOVW	R2, ret+16(FP)
   465  	RET
   466  
   467  // func cgocallback(fn, frame unsafe.Pointer, ctxt uintptr)
   468  // See cgocall.go for more details.
   469  TEXT ·cgocallback(SB),NOSPLIT,$24-24
   470  	NO_LOCAL_POINTERS
   471  
   472  	// Load m and g from thread-local storage.
   473  	MOVB	runtime·iscgo(SB), R1
   474  	BEQ	R1, nocgo
   475  	JAL	runtime·load_g(SB)
   476  nocgo:
   477  
   478  	// If g is nil, Go did not create the current thread.
   479  	// Call needm to obtain one for temporary use.
   480  	// In this case, we're running on the thread stack, so there's
   481  	// lots of space, but the linker doesn't know. Hide the call from
   482  	// the linker analysis by using an indirect call.
   483  	BEQ	g, needm
   484  
   485  	MOVV	g_m(g), R3
   486  	MOVV	R3, savedm-8(SP)
   487  	JMP	havem
   488  
   489  needm:
   490  	MOVV	g, savedm-8(SP) // g is zero, so is m.
   491  	MOVV	$runtime·needm(SB), R4
   492  	JAL	(R4)
   493  
   494  	// Set m->sched.sp = SP, so that if a panic happens
   495  	// during the function we are about to execute, it will
   496  	// have a valid SP to run on the g0 stack.
   497  	// The next few lines (after the havem label)
   498  	// will save this SP onto the stack and then write
   499  	// the same SP back to m->sched.sp. That seems redundant,
   500  	// but if an unrecovered panic happens, unwindm will
   501  	// restore the g->sched.sp from the stack location
   502  	// and then systemstack will try to use it. If we don't set it here,
   503  	// that restored SP will be uninitialized (typically 0) and
   504  	// will not be usable.
   505  	MOVV	g_m(g), R3
   506  	MOVV	m_g0(R3), R1
   507  	MOVV	R29, (g_sched+gobuf_sp)(R1)
   508  
   509  havem:
   510  	// Now there's a valid m, and we're running on its m->g0.
   511  	// Save current m->g0->sched.sp on stack and then set it to SP.
   512  	// Save current sp in m->g0->sched.sp in preparation for
   513  	// switch back to m->curg stack.
   514  	// NOTE: unwindm knows that the saved g->sched.sp is at 8(R29) aka savedsp-16(SP).
   515  	MOVV	m_g0(R3), R1
   516  	MOVV	(g_sched+gobuf_sp)(R1), R2
   517  	MOVV	R2, savedsp-24(SP)	// must match frame size
   518  	MOVV	R29, (g_sched+gobuf_sp)(R1)
   519  
   520  	// Switch to m->curg stack and call runtime.cgocallbackg.
   521  	// Because we are taking over the execution of m->curg
   522  	// but *not* resuming what had been running, we need to
   523  	// save that information (m->curg->sched) so we can restore it.
   524  	// We can restore m->curg->sched.sp easily, because calling
   525  	// runtime.cgocallbackg leaves SP unchanged upon return.
   526  	// To save m->curg->sched.pc, we push it onto the curg stack and
   527  	// open a frame the same size as cgocallback's g0 frame.
   528  	// Once we switch to the curg stack, the pushed PC will appear
   529  	// to be the return PC of cgocallback, so that the traceback
   530  	// will seamlessly trace back into the earlier calls.
   531  	MOVV	m_curg(R3), g
   532  	JAL	runtime·save_g(SB)
   533  	MOVV	(g_sched+gobuf_sp)(g), R2 // prepare stack as R2
   534  	MOVV	(g_sched+gobuf_pc)(g), R4
   535  	MOVV	R4, -(24+8)(R2)	// "saved LR"; must match frame size
   536  	// Gather our arguments into registers.
   537  	MOVV	fn+0(FP), R5
   538  	MOVV	frame+8(FP), R6
   539  	MOVV	ctxt+16(FP), R7
   540  	MOVV	$-(24+8)(R2), R29	// switch stack; must match frame size
   541  	MOVV	R5, 8(R29)
   542  	MOVV	R6, 16(R29)
   543  	MOVV	R7, 24(R29)
   544  	JAL	runtime·cgocallbackg(SB)
   545  
   546  	// Restore g->sched (== m->curg->sched) from saved values.
   547  	MOVV	0(R29), R4
   548  	MOVV	R4, (g_sched+gobuf_pc)(g)
   549  	MOVV	$(24+8)(R29), R2	// must match frame size
   550  	MOVV	R2, (g_sched+gobuf_sp)(g)
   551  
   552  	// Switch back to m->g0's stack and restore m->g0->sched.sp.
   553  	// (Unlike m->curg, the g0 goroutine never uses sched.pc,
   554  	// so we do not have to restore it.)
   555  	MOVV	g_m(g), R3
   556  	MOVV	m_g0(R3), g
   557  	JAL	runtime·save_g(SB)
   558  	MOVV	(g_sched+gobuf_sp)(g), R29
   559  	MOVV	savedsp-24(SP), R2	// must match frame size
   560  	MOVV	R2, (g_sched+gobuf_sp)(g)
   561  
   562  	// If the m on entry was nil, we called needm above to borrow an m
   563  	// for the duration of the call. Since the call is over, return it with dropm.
   564  	MOVV	savedm-8(SP), R3
   565  	BNE	R3, droppedm
   566  	MOVV	$runtime·dropm(SB), R4
   567  	JAL	(R4)
   568  droppedm:
   569  
   570  	// Done!
   571  	RET
   572  
   573  // void setg(G*); set g. for use by needm.
   574  TEXT runtime·setg(SB), NOSPLIT, $0-8
   575  	MOVV	gg+0(FP), g
   576  	// This only happens if iscgo, so jump straight to save_g
   577  	JAL	runtime·save_g(SB)
   578  	RET
   579  
   580  // void setg_gcc(G*); set g called from gcc with g in R1
   581  TEXT setg_gcc<>(SB),NOSPLIT,$0-0
   582  	MOVV	R1, g
   583  	JAL	runtime·save_g(SB)
   584  	RET
   585  
   586  TEXT runtime·abort(SB),NOSPLIT|NOFRAME,$0-0
   587  	MOVW	(R0), R0
   588  	UNDEF
   589  
   590  // AES hashing not implemented for mips64
   591  TEXT runtime·memhash(SB),NOSPLIT|NOFRAME,$0-32
   592  	JMP	runtime·memhashFallback(SB)
   593  TEXT runtime·strhash(SB),NOSPLIT|NOFRAME,$0-24
   594  	JMP	runtime·strhashFallback(SB)
   595  TEXT runtime·memhash32(SB),NOSPLIT|NOFRAME,$0-24
   596  	JMP	runtime·memhash32Fallback(SB)
   597  TEXT runtime·memhash64(SB),NOSPLIT|NOFRAME,$0-24
   598  	JMP	runtime·memhash64Fallback(SB)
   599  
   600  TEXT runtime·return0(SB), NOSPLIT, $0
   601  	MOVW	$0, R1
   602  	RET
   603  
   604  // Called from cgo wrappers, this function returns g->m->curg.stack.hi.
   605  // Must obey the gcc calling convention.
   606  TEXT _cgo_topofstack(SB),NOSPLIT,$16
   607  	// g (R30) and REGTMP (R23)  might be clobbered by load_g. They
   608  	// are callee-save in the gcc calling convention, so save them.
   609  	MOVV	R23, savedR23-16(SP)
   610  	MOVV	g, savedG-8(SP)
   611  
   612  	JAL	runtime·load_g(SB)
   613  	MOVV	g_m(g), R1
   614  	MOVV	m_curg(R1), R1
   615  	MOVV	(g_stack+stack_hi)(R1), R2 // return value in R2
   616  
   617  	MOVV	savedG-8(SP), g
   618  	MOVV	savedR23-16(SP), R23
   619  	RET
   620  
   621  // The top-most function running on a goroutine
   622  // returns to goexit+PCQuantum.
   623  TEXT runtime·goexit(SB),NOSPLIT|NOFRAME|TOPFRAME,$0-0
   624  	NOR	R0, R0	// NOP
   625  	JAL	runtime·goexit1(SB)	// does not return
   626  	// traceback from goexit1 must hit code range of goexit
   627  	NOR	R0, R0	// NOP
   628  
   629  TEXT ·checkASM(SB),NOSPLIT,$0-1
   630  	MOVW	$1, R1
   631  	MOVB	R1, ret+0(FP)
   632  	RET
   633  
   634  // gcWriteBarrier performs a heap pointer write and informs the GC.
   635  //
   636  // gcWriteBarrier does NOT follow the Go ABI. It takes two arguments:
   637  // - R20 is the destination of the write
   638  // - R21 is the value being written at R20.
   639  // It clobbers R23 (the linker temp register).
   640  // The act of CALLing gcWriteBarrier will clobber R31 (LR).
   641  // It does not clobber any other general-purpose registers,
   642  // but may clobber others (e.g., floating point registers).
   643  TEXT runtime·gcWriteBarrier(SB),NOSPLIT,$192
   644  	// Save the registers clobbered by the fast path.
   645  	MOVV	R1, 184(R29)
   646  	MOVV	R2, 192(R29)
   647  	MOVV	g_m(g), R1
   648  	MOVV	m_p(R1), R1
   649  	MOVV	(p_wbBuf+wbBuf_next)(R1), R2
   650  	// Increment wbBuf.next position.
   651  	ADDV	$16, R2
   652  	MOVV	R2, (p_wbBuf+wbBuf_next)(R1)
   653  	MOVV	(p_wbBuf+wbBuf_end)(R1), R1
   654  	MOVV	R1, R23		// R23 is linker temp register
   655  	// Record the write.
   656  	MOVV	R21, -16(R2)	// Record value
   657  	MOVV	(R20), R1	// TODO: This turns bad writes into bad reads.
   658  	MOVV	R1, -8(R2)	// Record *slot
   659  	// Is the buffer full?
   660  	BEQ	R2, R23, flush
   661  ret:
   662  	MOVV	184(R29), R1
   663  	MOVV	192(R29), R2
   664  	// Do the write.
   665  	MOVV	R21, (R20)
   666  	RET
   667  
   668  flush:
   669  	// Save all general purpose registers since these could be
   670  	// clobbered by wbBufFlush and were not saved by the caller.
   671  	MOVV	R20, 8(R29)	// Also first argument to wbBufFlush
   672  	MOVV	R21, 16(R29)	// Also second argument to wbBufFlush
   673  	// R1 already saved
   674  	// R2 already saved
   675  	MOVV	R3, 24(R29)
   676  	MOVV	R4, 32(R29)
   677  	MOVV	R5, 40(R29)
   678  	MOVV	R6, 48(R29)
   679  	MOVV	R7, 56(R29)
   680  	MOVV	R8, 64(R29)
   681  	MOVV	R9, 72(R29)
   682  	MOVV	R10, 80(R29)
   683  	MOVV	R11, 88(R29)
   684  	MOVV	R12, 96(R29)
   685  	MOVV	R13, 104(R29)
   686  	MOVV	R14, 112(R29)
   687  	MOVV	R15, 120(R29)
   688  	MOVV	R16, 128(R29)
   689  	MOVV	R17, 136(R29)
   690  	MOVV	R18, 144(R29)
   691  	MOVV	R19, 152(R29)
   692  	// R20 already saved
   693  	// R21 already saved.
   694  	MOVV	R22, 160(R29)
   695  	// R23 is tmp register.
   696  	MOVV	R24, 168(R29)
   697  	MOVV	R25, 176(R29)
   698  	// R26 is reserved by kernel.
   699  	// R27 is reserved by kernel.
   700  	// R28 is REGSB (not modified by Go code).
   701  	// R29 is SP.
   702  	// R30 is g.
   703  	// R31 is LR, which was saved by the prologue.
   704  
   705  	// This takes arguments R20 and R21.
   706  	CALL	runtime·wbBufFlush(SB)
   707  
   708  	MOVV	8(R29), R20
   709  	MOVV	16(R29), R21
   710  	MOVV	24(R29), R3
   711  	MOVV	32(R29), R4
   712  	MOVV	40(R29), R5
   713  	MOVV	48(R29), R6
   714  	MOVV	56(R29), R7
   715  	MOVV	64(R29), R8
   716  	MOVV	72(R29), R9
   717  	MOVV	80(R29), R10
   718  	MOVV	88(R29), R11
   719  	MOVV	96(R29), R12
   720  	MOVV	104(R29), R13
   721  	MOVV	112(R29), R14
   722  	MOVV	120(R29), R15
   723  	MOVV	128(R29), R16
   724  	MOVV	136(R29), R17
   725  	MOVV	144(R29), R18
   726  	MOVV	152(R29), R19
   727  	MOVV	160(R29), R22
   728  	MOVV	168(R29), R24
   729  	MOVV	176(R29), R25
   730  	JMP	ret
   731  
   732  // Note: these functions use a special calling convention to save generated code space.
   733  // Arguments are passed in registers, but the space for those arguments are allocated
   734  // in the caller's stack frame. These stubs write the args into that stack space and
   735  // then tail call to the corresponding runtime handler.
   736  // The tail call makes these stubs disappear in backtraces.
   737  TEXT runtime·panicIndex(SB),NOSPLIT,$0-16
   738  	MOVV	R1, x+0(FP)
   739  	MOVV	R2, y+8(FP)
   740  	JMP	runtime·goPanicIndex(SB)
   741  TEXT runtime·panicIndexU(SB),NOSPLIT,$0-16
   742  	MOVV	R1, x+0(FP)
   743  	MOVV	R2, y+8(FP)
   744  	JMP	runtime·goPanicIndexU(SB)
   745  TEXT runtime·panicSliceAlen(SB),NOSPLIT,$0-16
   746  	MOVV	R2, x+0(FP)
   747  	MOVV	R3, y+8(FP)
   748  	JMP	runtime·goPanicSliceAlen(SB)
   749  TEXT runtime·panicSliceAlenU(SB),NOSPLIT,$0-16
   750  	MOVV	R2, x+0(FP)
   751  	MOVV	R3, y+8(FP)
   752  	JMP	runtime·goPanicSliceAlenU(SB)
   753  TEXT runtime·panicSliceAcap(SB),NOSPLIT,$0-16
   754  	MOVV	R2, x+0(FP)
   755  	MOVV	R3, y+8(FP)
   756  	JMP	runtime·goPanicSliceAcap(SB)
   757  TEXT runtime·panicSliceAcapU(SB),NOSPLIT,$0-16
   758  	MOVV	R2, x+0(FP)
   759  	MOVV	R3, y+8(FP)
   760  	JMP	runtime·goPanicSliceAcapU(SB)
   761  TEXT runtime·panicSliceB(SB),NOSPLIT,$0-16
   762  	MOVV	R1, x+0(FP)
   763  	MOVV	R2, y+8(FP)
   764  	JMP	runtime·goPanicSliceB(SB)
   765  TEXT runtime·panicSliceBU(SB),NOSPLIT,$0-16
   766  	MOVV	R1, x+0(FP)
   767  	MOVV	R2, y+8(FP)
   768  	JMP	runtime·goPanicSliceBU(SB)
   769  TEXT runtime·panicSlice3Alen(SB),NOSPLIT,$0-16
   770  	MOVV	R3, x+0(FP)
   771  	MOVV	R4, y+8(FP)
   772  	JMP	runtime·goPanicSlice3Alen(SB)
   773  TEXT runtime·panicSlice3AlenU(SB),NOSPLIT,$0-16
   774  	MOVV	R3, x+0(FP)
   775  	MOVV	R4, y+8(FP)
   776  	JMP	runtime·goPanicSlice3AlenU(SB)
   777  TEXT runtime·panicSlice3Acap(SB),NOSPLIT,$0-16
   778  	MOVV	R3, x+0(FP)
   779  	MOVV	R4, y+8(FP)
   780  	JMP	runtime·goPanicSlice3Acap(SB)
   781  TEXT runtime·panicSlice3AcapU(SB),NOSPLIT,$0-16
   782  	MOVV	R3, x+0(FP)
   783  	MOVV	R4, y+8(FP)
   784  	JMP	runtime·goPanicSlice3AcapU(SB)
   785  TEXT runtime·panicSlice3B(SB),NOSPLIT,$0-16
   786  	MOVV	R2, x+0(FP)
   787  	MOVV	R3, y+8(FP)
   788  	JMP	runtime·goPanicSlice3B(SB)
   789  TEXT runtime·panicSlice3BU(SB),NOSPLIT,$0-16
   790  	MOVV	R2, x+0(FP)
   791  	MOVV	R3, y+8(FP)
   792  	JMP	runtime·goPanicSlice3BU(SB)
   793  TEXT runtime·panicSlice3C(SB),NOSPLIT,$0-16
   794  	MOVV	R1, x+0(FP)
   795  	MOVV	R2, y+8(FP)
   796  	JMP	runtime·goPanicSlice3C(SB)
   797  TEXT runtime·panicSlice3CU(SB),NOSPLIT,$0-16
   798  	MOVV	R1, x+0(FP)
   799  	MOVV	R2, y+8(FP)
   800  	JMP	runtime·goPanicSlice3CU(SB)
   801  TEXT runtime·panicSliceConvert(SB),NOSPLIT,$0-16
   802  	MOVV	R3, x+0(FP)
   803  	MOVV	R4, y+8(FP)
   804  	JMP	runtime·goPanicSliceConvert(SB)
   805  

View as plain text