github.com/x04/go/src@v0.0.0-20200202162449-3d481ceb3525/runtime/asm_riscv64.s (about)

     1  // Copyright 2017 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  #include "go_asm.h"
     6  #include "funcdata.h"
     7  #include "textflag.h"
     8  
     9  // func rt0_go()
    10  TEXT runtime·rt0_go(SB),NOSPLIT,$0
    11  	// X2 = stack; A0 = argc; A1 = argv
    12  
    13  	ADD	$-24, X2
    14  	MOV	A0, 8(X2) // argc
    15  	MOV	A1, 16(X2) // argv
    16  
    17  	// create istack out of the given (operating system) stack.
    18  	// _cgo_init may update stackguard.
    19  	MOV	$runtime·g0(SB), g
    20  	MOV	$(-64*1024), T0
    21  	ADD	T0, X2, T1
    22  	MOV	T1, g_stackguard0(g)
    23  	MOV	T1, g_stackguard1(g)
    24  	MOV	T1, (g_stack+stack_lo)(g)
    25  	MOV	X2, (g_stack+stack_hi)(g)
    26  
    27  	// if there is a _cgo_init, call it using the gcc ABI.
    28  	MOV	_cgo_init(SB), T0
    29  	BEQ	T0, ZERO, nocgo
    30  
    31  	MOV	ZERO, A3	// arg 3: not used
    32  	MOV	ZERO, A2	// arg 2: not used
    33  	MOV	$setg_gcc<>(SB), A1	// arg 1: setg
    34  	MOV	g, A0	// arg 0: G
    35  	JALR	RA, T0
    36  
    37  nocgo:
    38  	// update stackguard after _cgo_init
    39  	MOV	(g_stack+stack_lo)(g), T0
    40  	ADD	$const__StackGuard, T0
    41  	MOV	T0, g_stackguard0(g)
    42  	MOV	T0, g_stackguard1(g)
    43  
    44  	// set the per-goroutine and per-mach "registers"
    45  	MOV	$runtime·m0(SB), T0
    46  
    47  	// save m->g0 = g0
    48  	MOV	g, m_g0(T0)
    49  	// save m0 to g0->m
    50  	MOV	T0, g_m(g)
    51  
    52  	CALL	runtime·check(SB)
    53  
    54  	// args are already prepared
    55  	CALL	runtime·args(SB)
    56  	CALL	runtime·osinit(SB)
    57  	CALL	runtime·schedinit(SB)
    58  
    59  	// create a new goroutine to start program
    60  	MOV	$runtime·mainPC(SB), T0		// entry
    61  	ADD	$-24, X2
    62  	MOV	T0, 16(X2)
    63  	MOV	ZERO, 8(X2)
    64  	MOV	ZERO, 0(X2)
    65  	CALL	runtime·newproc(SB)
    66  	ADD	$24, X2
    67  
    68  	// start this M
    69  	CALL	runtime·mstart(SB)
    70  
    71  	WORD $0 // crash if reached
    72  	RET
    73  
    74  // void setg_gcc(G*); set g called from gcc with g in A0
    75  TEXT setg_gcc<>(SB),NOSPLIT,$0-0
    76  	MOV	A0, g
    77  	CALL	runtime·save_g(SB)
    78  	RET
    79  
    80  // func cputicks() int64
    81  TEXT runtime·cputicks(SB),NOSPLIT,$0-8
    82  	WORD	$0xc0102573	// rdtime a0
    83  	MOV	A0, ret+0(FP)
    84  	RET
    85  
    86  // systemstack_switch is a dummy routine that systemstack leaves at the bottom
    87  // of the G stack. We need to distinguish the routine that
    88  // lives at the bottom of the G stack from the one that lives
    89  // at the top of the system stack because the one at the top of
    90  // the system stack terminates the stack walk (see topofstack()).
    91  TEXT runtime·systemstack_switch(SB), NOSPLIT, $0-0
    92  	UNDEF
    93  	JALR	RA, ZERO	// make sure this function is not leaf
    94  	RET
    95  
    96  // func systemstack(fn func())
    97  TEXT runtime·systemstack(SB), NOSPLIT, $0-8
    98  	MOV	fn+0(FP), CTXT	// CTXT = fn
    99  	MOV	g_m(g), T0	// T0 = m
   100  
   101  	MOV	m_gsignal(T0), T1	// T1 = gsignal
   102  	BEQ	g, T1, noswitch
   103  
   104  	MOV	m_g0(T0), T1	// T1 = g0
   105  	BEQ	g, T1, noswitch
   106  
   107  	MOV	m_curg(T0), T2
   108  	BEQ	g, T2, switch
   109  
   110  	// Bad: g is not gsignal, not g0, not curg. What is it?
   111  	// Hide call from linker nosplit analysis.
   112  	MOV	$runtime·badsystemstack(SB), T1
   113  	JALR	RA, T1
   114  
   115  switch:
   116  	// save our state in g->sched. Pretend to
   117  	// be systemstack_switch if the G stack is scanned.
   118  	MOV	$runtime·systemstack_switch(SB), T2
   119  	ADD	$8, T2	// get past prologue
   120  	MOV	T2, (g_sched+gobuf_pc)(g)
   121  	MOV	X2, (g_sched+gobuf_sp)(g)
   122  	MOV	ZERO, (g_sched+gobuf_lr)(g)
   123  	MOV	g, (g_sched+gobuf_g)(g)
   124  
   125  	// switch to g0
   126  	MOV	T1, g
   127  	CALL	runtime·save_g(SB)
   128  	MOV	(g_sched+gobuf_sp)(g), T0
   129  	// make it look like mstart called systemstack on g0, to stop traceback
   130  	ADD	$-8, T0
   131  	MOV	$runtime·mstart(SB), T1
   132  	MOV	T1, 0(T0)
   133  	MOV	T0, X2
   134  
   135  	// call target function
   136  	MOV	0(CTXT), T1	// code pointer
   137  	JALR	RA, T1
   138  
   139  	// switch back to g
   140  	MOV	g_m(g), T0
   141  	MOV	m_curg(T0), g
   142  	CALL	runtime·save_g(SB)
   143  	MOV	(g_sched+gobuf_sp)(g), X2
   144  	MOV	ZERO, (g_sched+gobuf_sp)(g)
   145  	RET
   146  
   147  noswitch:
   148  	// already on m stack, just call directly
   149  	// Using a tail call here cleans up tracebacks since we won't stop
   150  	// at an intermediate systemstack.
   151  	MOV	0(CTXT), T1	// code pointer
   152  	ADD	$8, X2
   153  	JMP	(T1)
   154  
   155  TEXT runtime·getcallerpc(SB),NOSPLIT|NOFRAME,$0-8
   156  	MOV	0(X2), T0		// LR saved by caller
   157  	MOV	T0, ret+0(FP)
   158  	RET
   159  
   160  /*
   161   * support for morestack
   162   */
   163  
   164  // Called during function prolog when more stack is needed.
   165  // Caller has already loaded:
   166  // R1: framesize, R2: argsize, R3: LR
   167  //
   168  // The traceback routines see morestack on a g0 as being
   169  // the top of a stack (for example, morestack calling newstack
   170  // calling the scheduler calling newm calling gc), so we must
   171  // record an argument size. For that purpose, it has no arguments.
   172  
   173  // func morestack()
   174  TEXT runtime·morestack(SB),NOSPLIT|NOFRAME,$0-0
   175  	// Cannot grow scheduler stack (m->g0).
   176  	MOV	g_m(g), A0
   177  	MOV	m_g0(A0), A1
   178  	BNE	g, A1, 3(PC)
   179  	CALL	runtime·badmorestackg0(SB)
   180  	CALL	runtime·abort(SB)
   181  
   182  	// Cannot grow signal stack (m->gsignal).
   183  	MOV	m_gsignal(A0), A1
   184  	BNE	g, A1, 3(PC)
   185  	CALL	runtime·badmorestackgsignal(SB)
   186  	CALL	runtime·abort(SB)
   187  
   188  	// Called from f.
   189  	// Set g->sched to context in f.
   190  	MOV	X2, (g_sched+gobuf_sp)(g)
   191  	MOV	T0, (g_sched+gobuf_pc)(g)
   192  	MOV	RA, (g_sched+gobuf_lr)(g)
   193  	MOV	CTXT, (g_sched+gobuf_ctxt)(g)
   194  
   195  	// Called from f.
   196  	// Set m->morebuf to f's caller.
   197  	MOV	RA, (m_morebuf+gobuf_pc)(A0)	// f's caller's PC
   198  	MOV	X2, (m_morebuf+gobuf_sp)(A0)	// f's caller's SP
   199  	MOV	g, (m_morebuf+gobuf_g)(A0)
   200  
   201  	// Call newstack on m->g0's stack.
   202  	MOV	m_g0(A0), g
   203  	CALL	runtime·save_g(SB)
   204  	MOV	(g_sched+gobuf_sp)(g), X2
   205  	// Create a stack frame on g0 to call newstack.
   206  	MOV	ZERO, -8(X2)	// Zero saved LR in frame
   207  	ADD	$-8, X2
   208  	CALL	runtime·newstack(SB)
   209  
   210  	// Not reached, but make sure the return PC from the call to newstack
   211  	// is still in this function, and not the beginning of the next.
   212  	UNDEF
   213  
   214  // func morestack_noctxt()
   215  TEXT runtime·morestack_noctxt(SB),NOSPLIT|NOFRAME,$0-0
   216  	MOV	ZERO, CTXT
   217  	JMP	runtime·morestack(SB)
   218  
   219  // AES hashing not implemented for riscv64
   220  TEXT runtime·memhash(SB),NOSPLIT|NOFRAME,$0-32
   221  	JMP	runtime·memhashFallback(SB)
   222  TEXT runtime·strhash(SB),NOSPLIT|NOFRAME,$0-24
   223  	JMP	runtime·strhashFallback(SB)
   224  TEXT runtime·memhash32(SB),NOSPLIT|NOFRAME,$0-24
   225  	JMP	runtime·memhash32Fallback(SB)
   226  TEXT runtime·memhash64(SB),NOSPLIT|NOFRAME,$0-24
   227  	JMP	runtime·memhash64Fallback(SB)
   228  
   229  // func return0()
   230  TEXT runtime·return0(SB), NOSPLIT, $0
   231  	MOV	$0, A0
   232  	RET
   233  
   234  // restore state from Gobuf; longjmp
   235  
   236  // func gogo(buf *gobuf)
   237  TEXT runtime·gogo(SB), NOSPLIT, $16-8
   238  	MOV	buf+0(FP), T0
   239  	MOV	gobuf_g(T0), g	// make sure g is not nil
   240  	CALL	runtime·save_g(SB)
   241  
   242  	MOV	(g), ZERO // make sure g is not nil
   243  	MOV	gobuf_sp(T0), X2
   244  	MOV	gobuf_lr(T0), RA
   245  	MOV	gobuf_ret(T0), A0
   246  	MOV	gobuf_ctxt(T0), CTXT
   247  	MOV	ZERO, gobuf_sp(T0)
   248  	MOV	ZERO, gobuf_ret(T0)
   249  	MOV	ZERO, gobuf_lr(T0)
   250  	MOV	ZERO, gobuf_ctxt(T0)
   251  	MOV	gobuf_pc(T0), T0
   252  	JALR	ZERO, T0
   253  
   254  // func jmpdefer(fv *funcval, argp uintptr)
   255  // called from deferreturn
   256  // 1. grab stored return address from the caller's frame
   257  // 2. sub 8 bytes to get back to JAL deferreturn
   258  // 3. JMP to fn
   259  TEXT runtime·jmpdefer(SB), NOSPLIT|NOFRAME, $0-16
   260  	MOV	0(X2), RA
   261  	ADD	$-8, RA
   262  
   263  	MOV	fv+0(FP), CTXT
   264  	MOV	argp+8(FP), X2
   265  	ADD	$-8, X2
   266  	MOV	0(CTXT), T0
   267  	JALR	ZERO, T0
   268  
   269  // func procyield(cycles uint32)
   270  TEXT runtime·procyield(SB),NOSPLIT,$0-0
   271  	RET
   272  
   273  // Switch to m->g0's stack, call fn(g).
   274  // Fn must never return. It should gogo(&g->sched)
   275  // to keep running g.
   276  
   277  // func mcall(fn func(*g))
   278  TEXT runtime·mcall(SB), NOSPLIT|NOFRAME, $0-8
   279  	// Save caller state in g->sched
   280  	MOV	X2, (g_sched+gobuf_sp)(g)
   281  	MOV	RA, (g_sched+gobuf_pc)(g)
   282  	MOV	ZERO, (g_sched+gobuf_lr)(g)
   283  	MOV	g, (g_sched+gobuf_g)(g)
   284  
   285  	// Switch to m->g0 & its stack, call fn.
   286  	MOV	g, T0
   287  	MOV	g_m(g), T1
   288  	MOV	m_g0(T1), g
   289  	CALL	runtime·save_g(SB)
   290  	BNE	g, T0, 2(PC)
   291  	JMP	runtime·badmcall(SB)
   292  	MOV	fn+0(FP), CTXT			// context
   293  	MOV	0(CTXT), T1			// code pointer
   294  	MOV	(g_sched+gobuf_sp)(g), X2	// sp = m->g0->sched.sp
   295  	ADD	$-16, X2
   296  	MOV	T0, 8(X2)
   297  	MOV	ZERO, 0(X2)
   298  	JALR	RA, T1
   299  	JMP	runtime·badmcall2(SB)
   300  
   301  // func gosave(buf *gobuf)
   302  // save state in Gobuf; setjmp
   303  TEXT runtime·gosave(SB), NOSPLIT|NOFRAME, $0-8
   304  	MOV	buf+0(FP), T1
   305  	MOV	X2, gobuf_sp(T1)
   306  	MOV	RA, gobuf_pc(T1)
   307  	MOV	g, gobuf_g(T1)
   308  	MOV	ZERO, gobuf_lr(T1)
   309  	MOV	ZERO, gobuf_ret(T1)
   310  	// Assert ctxt is zero. See func save.
   311  	MOV	gobuf_ctxt(T1), T1
   312  	BEQ	T1, ZERO, 2(PC)
   313  	CALL	runtime·badctxt(SB)
   314  	RET
   315  
   316  // func asmcgocall(fn, arg unsafe.Pointer) int32
   317  TEXT ·asmcgocall(SB),NOSPLIT,$0-20
   318  	// TODO(jsing): Add support for cgo - issue #36641.
   319  	WORD $0		// crash
   320  
   321  // func asminit()
   322  TEXT runtime·asminit(SB),NOSPLIT|NOFRAME,$0-0
   323  	RET
   324  
   325  // reflectcall: call a function with the given argument list
   326  // func call(argtype *_type, f *FuncVal, arg *byte, argsize, retoffset uint32).
   327  // we don't have variable-sized frames, so we use a small number
   328  // of constant-sized-frame functions to encode a few bits of size in the pc.
   329  // Caution: ugly multiline assembly macros in your future!
   330  
   331  #define DISPATCH(NAME,MAXSIZE)	\
   332  	MOV	$MAXSIZE, T1	\
   333  	BLTU	T1, T0, 3(PC)	\
   334  	MOV	$NAME(SB), T2;	\
   335  	JALR	ZERO, T2
   336  // Note: can't just "BR NAME(SB)" - bad inlining results.
   337  
   338  // func call(argtype *rtype, fn, arg unsafe.Pointer, n uint32, retoffset uint32)
   339  TEXT reflect·call(SB), NOSPLIT, $0-0
   340  	JMP	·reflectcall(SB)
   341  
   342  // func reflectcall(argtype *_type, fn, arg unsafe.Pointer, argsize uint32, retoffset uint32)
   343  TEXT ·reflectcall(SB), NOSPLIT|NOFRAME, $0-32
   344  	MOVWU argsize+24(FP), T0
   345  	DISPATCH(runtime·call32, 32)
   346  	DISPATCH(runtime·call64, 64)
   347  	DISPATCH(runtime·call128, 128)
   348  	DISPATCH(runtime·call256, 256)
   349  	DISPATCH(runtime·call512, 512)
   350  	DISPATCH(runtime·call1024, 1024)
   351  	DISPATCH(runtime·call2048, 2048)
   352  	DISPATCH(runtime·call4096, 4096)
   353  	DISPATCH(runtime·call8192, 8192)
   354  	DISPATCH(runtime·call16384, 16384)
   355  	DISPATCH(runtime·call32768, 32768)
   356  	DISPATCH(runtime·call65536, 65536)
   357  	DISPATCH(runtime·call131072, 131072)
   358  	DISPATCH(runtime·call262144, 262144)
   359  	DISPATCH(runtime·call524288, 524288)
   360  	DISPATCH(runtime·call1048576, 1048576)
   361  	DISPATCH(runtime·call2097152, 2097152)
   362  	DISPATCH(runtime·call4194304, 4194304)
   363  	DISPATCH(runtime·call8388608, 8388608)
   364  	DISPATCH(runtime·call16777216, 16777216)
   365  	DISPATCH(runtime·call33554432, 33554432)
   366  	DISPATCH(runtime·call67108864, 67108864)
   367  	DISPATCH(runtime·call134217728, 134217728)
   368  	DISPATCH(runtime·call268435456, 268435456)
   369  	DISPATCH(runtime·call536870912, 536870912)
   370  	DISPATCH(runtime·call1073741824, 1073741824)
   371  	MOV	$runtime·badreflectcall(SB), T2
   372  	JALR	ZERO, T2
   373  
   374  #define CALLFN(NAME,MAXSIZE)			\
   375  TEXT NAME(SB), WRAPPER, $MAXSIZE-24;		\
   376  	NO_LOCAL_POINTERS;			\
   377  	/* copy arguments to stack */		\
   378  	MOV	arg+16(FP), A1;			\
   379  	MOVWU	argsize+24(FP), A2;		\
   380  	MOV	X2, A3;				\
   381  	ADD	$8, A3;				\
   382  	ADD	A3, A2;				\
   383  	BEQ	A3, A2, 6(PC);			\
   384  	MOVBU	(A1), A4;			\
   385  	ADD	$1, A1;				\
   386  	MOVB	A4, (A3);			\
   387  	ADD	$1, A3;				\
   388  	JMP	-5(PC);				\
   389  	/* call function */			\
   390  	MOV	f+8(FP), CTXT;			\
   391  	MOV	(CTXT), A4;			\
   392  	PCDATA  $PCDATA_StackMapIndex, $0;	\
   393  	JALR	RA, A4;				\
   394  	/* copy return values back */		\
   395  	MOV	argtype+0(FP), A5;		\
   396  	MOV	arg+16(FP), A1;			\
   397  	MOVWU	n+24(FP), A2;			\
   398  	MOVWU	retoffset+28(FP), A4;		\
   399  	ADD	$8, X2, A3;			\
   400  	ADD	A4, A3; 			\
   401  	ADD	A4, A1;				\
   402  	SUB	A4, A2;				\
   403  	CALL	callRet<>(SB);			\
   404  	RET
   405  
   406  // callRet copies return values back at the end of call*. This is a
   407  // separate function so it can allocate stack space for the arguments
   408  // to reflectcallmove. It does not follow the Go ABI; it expects its
   409  // arguments in registers.
   410  TEXT callRet<>(SB), NOSPLIT, $32-0
   411  	MOV	A5, 8(X2)
   412  	MOV	A1, 16(X2)
   413  	MOV	A3, 24(X2)
   414  	MOV	A2, 32(X2)
   415  	CALL	runtime·reflectcallmove(SB)
   416  	RET
   417  
   418  CALLFN(·call16, 16)
   419  CALLFN(·call32, 32)
   420  CALLFN(·call64, 64)
   421  CALLFN(·call128, 128)
   422  CALLFN(·call256, 256)
   423  CALLFN(·call512, 512)
   424  CALLFN(·call1024, 1024)
   425  CALLFN(·call2048, 2048)
   426  CALLFN(·call4096, 4096)
   427  CALLFN(·call8192, 8192)
   428  CALLFN(·call16384, 16384)
   429  CALLFN(·call32768, 32768)
   430  CALLFN(·call65536, 65536)
   431  CALLFN(·call131072, 131072)
   432  CALLFN(·call262144, 262144)
   433  CALLFN(·call524288, 524288)
   434  CALLFN(·call1048576, 1048576)
   435  CALLFN(·call2097152, 2097152)
   436  CALLFN(·call4194304, 4194304)
   437  CALLFN(·call8388608, 8388608)
   438  CALLFN(·call16777216, 16777216)
   439  CALLFN(·call33554432, 33554432)
   440  CALLFN(·call67108864, 67108864)
   441  CALLFN(·call134217728, 134217728)
   442  CALLFN(·call268435456, 268435456)
   443  CALLFN(·call536870912, 536870912)
   444  CALLFN(·call1073741824, 1073741824)
   445  
   446  // func goexit(neverCallThisFunction)
   447  // The top-most function running on a goroutine
   448  // returns to goexit+PCQuantum.
   449  TEXT runtime·goexit(SB),NOSPLIT|NOFRAME,$0-0
   450  	MOV	ZERO, ZERO	// NOP
   451  	JMP	runtime·goexit1(SB)	// does not return
   452  	// traceback from goexit1 must hit code range of goexit
   453  	MOV	ZERO, ZERO	// NOP
   454  
   455  // func cgocallback_gofunc(fv uintptr, frame uintptr, framesize, ctxt uintptr)
   456  TEXT ·cgocallback_gofunc(SB),NOSPLIT,$24-32
   457  	// TODO(jsing): Add support for cgo - issue #36641.
   458  	WORD $0		// crash
   459  
   460  TEXT runtime·breakpoint(SB),NOSPLIT|NOFRAME,$0-0
   461  	EBREAK
   462  	RET
   463  
   464  TEXT runtime·abort(SB),NOSPLIT|NOFRAME,$0-0
   465  	EBREAK
   466  	RET
   467  
   468  // void setg(G*); set g. for use by needm.
   469  TEXT runtime·setg(SB), NOSPLIT, $0-8
   470  	MOV	gg+0(FP), g
   471  	// This only happens if iscgo, so jump straight to save_g
   472  	CALL	runtime·save_g(SB)
   473  	RET
   474  
   475  TEXT ·checkASM(SB),NOSPLIT,$0-1
   476  	MOV	$1, T0
   477  	MOV	T0, ret+0(FP)
   478  	RET
   479  
   480  // gcWriteBarrier performs a heap pointer write and informs the GC.
   481  //
   482  // gcWriteBarrier does NOT follow the Go ABI. It takes two arguments:
   483  // - T0 is the destination of the write
   484  // - T1 is the value being written at T0.
   485  // It clobbers R30 (the linker temp register - REG_TMP).
   486  // The act of CALLing gcWriteBarrier will clobber RA (LR).
   487  // It does not clobber any other general-purpose registers,
   488  // but may clobber others (e.g., floating point registers).
   489  TEXT runtime·gcWriteBarrier(SB),NOSPLIT,$296
   490  	// Save the registers clobbered by the fast path.
   491  	MOV	A0, 280(X2)
   492  	MOV	A1, 288(X2)
   493  	MOV	g_m(g), A0
   494  	MOV	m_p(A0), A0
   495  	MOV	(p_wbBuf+wbBuf_next)(A0), A1
   496  	// Increment wbBuf.next position.
   497  	ADD	$16, A1
   498  	MOV	A1, (p_wbBuf+wbBuf_next)(A0)
   499  	MOV	(p_wbBuf+wbBuf_end)(A0), A0
   500  	MOV	A0, T6		// T6 is linker temp register (REG_TMP)
   501  	// Record the write.
   502  	MOV	T1, -16(A1)	// Record value
   503  	MOV	(T0), A0	// TODO: This turns bad writes into bad reads.
   504  	MOV	A0, -8(A1)	// Record *slot
   505  	// Is the buffer full?
   506  	BEQ	A1, T6, flush
   507  ret:
   508  	MOV	280(X2), A0
   509  	MOV	288(X2), A1
   510  	// Do the write.
   511  	MOV	T1, (T0)
   512  	RET
   513  
   514  flush:
   515  	// Save all general purpose registers since these could be
   516  	// clobbered by wbBufFlush and were not saved by the caller.
   517  	MOV	T0, 8(X2)	// Also first argument to wbBufFlush
   518  	MOV	T1, 16(X2)	// Also second argument to wbBufFlush
   519  
   520  	// TODO: Optimise
   521  	// R3 is g.
   522  	// R4 already saved (T0)
   523  	// R5 already saved (T1)
   524  	// R9 already saved (A0)
   525  	// R10 already saved (A1)
   526  	// R30 is tmp register.
   527  	MOV	X0, 24(X2)
   528  	MOV	X1, 32(X2)
   529  	MOV	X2, 40(X2)
   530  	MOV	X3, 48(X2)
   531  	MOV	X4, 56(X2)
   532  	MOV	X5, 64(X2)
   533  	MOV	X6, 72(X2)
   534  	MOV	X7, 80(X2)
   535  	MOV	X8, 88(X2)
   536  	MOV	X9, 96(X2)
   537  	MOV	X10, 104(X2)
   538  	MOV	X11, 112(X2)
   539  	MOV	X12, 120(X2)
   540  	MOV	X13, 128(X2)
   541  	MOV	X14, 136(X2)
   542  	MOV	X15, 144(X2)
   543  	MOV	X16, 152(X2)
   544  	MOV	X17, 160(X2)
   545  	MOV	X18, 168(X2)
   546  	MOV	X19, 176(X2)
   547  	MOV	X20, 184(X2)
   548  	MOV	X21, 192(X2)
   549  	MOV	X22, 200(X2)
   550  	MOV	X23, 208(X2)
   551  	MOV	X24, 216(X2)
   552  	MOV	X25, 224(X2)
   553  	MOV	X26, 232(X2)
   554  	MOV	X27, 240(X2)
   555  	MOV	X28, 248(X2)
   556  	MOV	X29, 256(X2)
   557  	MOV	X30, 264(X2)
   558  	MOV	X31, 272(X2)
   559  
   560  	// This takes arguments T0 and T1.
   561  	CALL	runtime·wbBufFlush(SB)
   562  
   563  	MOV	24(X2), X0
   564  	MOV	32(X2), X1
   565  	MOV	40(X2), X2
   566  	MOV	48(X2), X3
   567  	MOV	56(X2), X4
   568  	MOV	64(X2), X5
   569  	MOV	72(X2), X6
   570  	MOV	80(X2), X7
   571  	MOV	88(X2), X8
   572  	MOV	96(X2), X9
   573  	MOV	104(X2), X10
   574  	MOV	112(X2), X11
   575  	MOV	120(X2), X12
   576  	MOV	128(X2), X13
   577  	MOV	136(X2), X14
   578  	MOV	144(X2), X15
   579  	MOV	152(X2), X16
   580  	MOV	160(X2), X17
   581  	MOV	168(X2), X18
   582  	MOV	176(X2), X19
   583  	MOV	184(X2), X20
   584  	MOV	192(X2), X21
   585  	MOV	200(X2), X22
   586  	MOV	208(X2), X23
   587  	MOV	216(X2), X24
   588  	MOV	224(X2), X25
   589  	MOV	232(X2), X26
   590  	MOV	240(X2), X27
   591  	MOV	248(X2), X28
   592  	MOV	256(X2), X29
   593  	MOV	264(X2), X30
   594  	MOV	272(X2), X31
   595  
   596  	JMP	ret
   597  
   598  // Note: these functions use a special calling convention to save generated code space.
   599  // Arguments are passed in registers, but the space for those arguments are allocated
   600  // in the caller's stack frame. These stubs write the args into that stack space and
   601  // then tail call to the corresponding runtime handler.
   602  // The tail call makes these stubs disappear in backtraces.
   603  TEXT runtime·panicIndex(SB),NOSPLIT,$0-16
   604  	MOV	T0, x+0(FP)
   605  	MOV	T1, y+8(FP)
   606  	JMP	runtime·goPanicIndex(SB)
   607  TEXT runtime·panicIndexU(SB),NOSPLIT,$0-16
   608  	MOV	T0, x+0(FP)
   609  	MOV	T1, y+8(FP)
   610  	JMP	runtime·goPanicIndexU(SB)
   611  TEXT runtime·panicSliceAlen(SB),NOSPLIT,$0-16
   612  	MOV	T1, x+0(FP)
   613  	MOV	T2, y+8(FP)
   614  	JMP	runtime·goPanicSliceAlen(SB)
   615  TEXT runtime·panicSliceAlenU(SB),NOSPLIT,$0-16
   616  	MOV	T1, x+0(FP)
   617  	MOV	T2, y+8(FP)
   618  	JMP	runtime·goPanicSliceAlenU(SB)
   619  TEXT runtime·panicSliceAcap(SB),NOSPLIT,$0-16
   620  	MOV	T1, x+0(FP)
   621  	MOV	T2, y+8(FP)
   622  	JMP	runtime·goPanicSliceAcap(SB)
   623  TEXT runtime·panicSliceAcapU(SB),NOSPLIT,$0-16
   624  	MOV	T1, x+0(FP)
   625  	MOV	T2, y+8(FP)
   626  	JMP	runtime·goPanicSliceAcapU(SB)
   627  TEXT runtime·panicSliceB(SB),NOSPLIT,$0-16
   628  	MOV	T0, x+0(FP)
   629  	MOV	T1, y+8(FP)
   630  	JMP	runtime·goPanicSliceB(SB)
   631  TEXT runtime·panicSliceBU(SB),NOSPLIT,$0-16
   632  	MOV	T0, x+0(FP)
   633  	MOV	T1, y+8(FP)
   634  	JMP	runtime·goPanicSliceBU(SB)
   635  TEXT runtime·panicSlice3Alen(SB),NOSPLIT,$0-16
   636  	MOV	T2, x+0(FP)
   637  	MOV	T3, y+8(FP)
   638  	JMP	runtime·goPanicSlice3Alen(SB)
   639  TEXT runtime·panicSlice3AlenU(SB),NOSPLIT,$0-16
   640  	MOV	T2, x+0(FP)
   641  	MOV	T3, y+8(FP)
   642  	JMP	runtime·goPanicSlice3AlenU(SB)
   643  TEXT runtime·panicSlice3Acap(SB),NOSPLIT,$0-16
   644  	MOV	T2, x+0(FP)
   645  	MOV	T3, y+8(FP)
   646  	JMP	runtime·goPanicSlice3Acap(SB)
   647  TEXT runtime·panicSlice3AcapU(SB),NOSPLIT,$0-16
   648  	MOV	T2, x+0(FP)
   649  	MOV	T3, y+8(FP)
   650  	JMP	runtime·goPanicSlice3AcapU(SB)
   651  TEXT runtime·panicSlice3B(SB),NOSPLIT,$0-16
   652  	MOV	T1, x+0(FP)
   653  	MOV	T2, y+8(FP)
   654  	JMP	runtime·goPanicSlice3B(SB)
   655  TEXT runtime·panicSlice3BU(SB),NOSPLIT,$0-16
   656  	MOV	T1, x+0(FP)
   657  	MOV	T2, y+8(FP)
   658  	JMP	runtime·goPanicSlice3BU(SB)
   659  TEXT runtime·panicSlice3C(SB),NOSPLIT,$0-16
   660  	MOV	T0, x+0(FP)
   661  	MOV	T1, y+8(FP)
   662  	JMP	runtime·goPanicSlice3C(SB)
   663  TEXT runtime·panicSlice3CU(SB),NOSPLIT,$0-16
   664  	MOV	T0, x+0(FP)
   665  	MOV	T1, y+8(FP)
   666  	JMP	runtime·goPanicSlice3CU(SB)
   667  
   668  DATA	runtime·mainPC+0(SB)/8,$runtime·main(SB)
   669  GLOBL	runtime·mainPC(SB),RODATA,$8