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

View as plain text