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()
10TEXT 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
37nocgo:
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
75TEXT setg_gcc<>(SB),NOSPLIT,$0-0
76	MOV	A0, g
77	CALL	runtime·save_g(SB)
78	RET
79
80// func cputicks() int64
81TEXT 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()).
91TEXT 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())
97TEXT 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
115switch:
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
147noswitch:
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
155TEXT 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()
174TEXT 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()
215TEXT 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
220TEXT runtime·memhash(SB),NOSPLIT|NOFRAME,$0-32
221	JMP	runtime·memhashFallback(SB)
222TEXT runtime·strhash(SB),NOSPLIT|NOFRAME,$0-24
223	JMP	runtime·strhashFallback(SB)
224TEXT runtime·memhash32(SB),NOSPLIT|NOFRAME,$0-24
225	JMP	runtime·memhash32Fallback(SB)
226TEXT runtime·memhash64(SB),NOSPLIT|NOFRAME,$0-24
227	JMP	runtime·memhash64Fallback(SB)
228
229// func return0()
230TEXT runtime·return0(SB), NOSPLIT, $0
231	MOV	$0, A0
232	RET
233
234// restore state from Gobuf; longjmp
235
236// func gogo(buf *gobuf)
237TEXT 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
259TEXT 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)
270TEXT 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))
278TEXT 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
303TEXT 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
317TEXT ·asmcgocall(SB),NOSPLIT,$0-20
318	// TODO(jsing): Add support for cgo - issue #36641.
319	WORD $0		// crash
320
321// func asminit()
322TEXT 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)
339TEXT reflect·call(SB), NOSPLIT, $0-0
340	JMP	·reflectcall(SB)
341
342// func reflectcall(argtype *_type, fn, arg unsafe.Pointer, argsize uint32, retoffset uint32)
343TEXT ·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)			\
375TEXT 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.
410TEXT 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
418CALLFNcall16, 16)
419CALLFNcall32, 32)
420CALLFNcall64, 64)
421CALLFNcall128, 128)
422CALLFNcall256, 256)
423CALLFNcall512, 512)
424CALLFNcall1024, 1024)
425CALLFNcall2048, 2048)
426CALLFNcall4096, 4096)
427CALLFNcall8192, 8192)
428CALLFNcall16384, 16384)
429CALLFNcall32768, 32768)
430CALLFNcall65536, 65536)
431CALLFNcall131072, 131072)
432CALLFNcall262144, 262144)
433CALLFNcall524288, 524288)
434CALLFNcall1048576, 1048576)
435CALLFNcall2097152, 2097152)
436CALLFNcall4194304, 4194304)
437CALLFNcall8388608, 8388608)
438CALLFNcall16777216, 16777216)
439CALLFNcall33554432, 33554432)
440CALLFNcall67108864, 67108864)
441CALLFNcall134217728, 134217728)
442CALLFNcall268435456, 268435456)
443CALLFNcall536870912, 536870912)
444CALLFNcall1073741824, 1073741824)
445
446// func goexit(neverCallThisFunction)
447// The top-most function running on a goroutine
448// returns to goexit+PCQuantum.
449TEXT 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)
456TEXT ·cgocallback_gofunc(SB),NOSPLIT,$24-32
457	// TODO(jsing): Add support for cgo - issue #36641.
458	WORD $0		// crash
459
460TEXT runtime·breakpoint(SB),NOSPLIT|NOFRAME,$0-0
461	EBREAK
462	RET
463
464TEXT runtime·abort(SB),NOSPLIT|NOFRAME,$0-0
465	EBREAK
466	RET
467
468// void setg(G*); set g. for use by needm.
469TEXT 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
475TEXT ·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).
489TEXT 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
507ret:
508	MOV	280(X2), A0
509	MOV	288(X2), A1
510	// Do the write.
511	MOV	T1, (T0)
512	RET
513
514flush:
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.
603TEXT runtime·panicIndex(SB),NOSPLIT,$0-16
604	MOV	T0, x+0(FP)
605	MOV	T1, y+8(FP)
606	JMP	runtime·goPanicIndex(SB)
607TEXT runtime·panicIndexU(SB),NOSPLIT,$0-16
608	MOV	T0, x+0(FP)
609	MOV	T1, y+8(FP)
610	JMP	runtime·goPanicIndexU(SB)
611TEXT runtime·panicSliceAlen(SB),NOSPLIT,$0-16
612	MOV	T1, x+0(FP)
613	MOV	T2, y+8(FP)
614	JMP	runtime·goPanicSliceAlen(SB)
615TEXT runtime·panicSliceAlenU(SB),NOSPLIT,$0-16
616	MOV	T1, x+0(FP)
617	MOV	T2, y+8(FP)
618	JMP	runtime·goPanicSliceAlenU(SB)
619TEXT runtime·panicSliceAcap(SB),NOSPLIT,$0-16
620	MOV	T1, x+0(FP)
621	MOV	T2, y+8(FP)
622	JMP	runtime·goPanicSliceAcap(SB)
623TEXT runtime·panicSliceAcapU(SB),NOSPLIT,$0-16
624	MOV	T1, x+0(FP)
625	MOV	T2, y+8(FP)
626	JMP	runtime·goPanicSliceAcapU(SB)
627TEXT runtime·panicSliceB(SB),NOSPLIT,$0-16
628	MOV	T0, x+0(FP)
629	MOV	T1, y+8(FP)
630	JMP	runtime·goPanicSliceB(SB)
631TEXT runtime·panicSliceBU(SB),NOSPLIT,$0-16
632	MOV	T0, x+0(FP)
633	MOV	T1, y+8(FP)
634	JMP	runtime·goPanicSliceBU(SB)
635TEXT runtime·panicSlice3Alen(SB),NOSPLIT,$0-16
636	MOV	T2, x+0(FP)
637	MOV	T3, y+8(FP)
638	JMP	runtime·goPanicSlice3Alen(SB)
639TEXT runtime·panicSlice3AlenU(SB),NOSPLIT,$0-16
640	MOV	T2, x+0(FP)
641	MOV	T3, y+8(FP)
642	JMP	runtime·goPanicSlice3AlenU(SB)
643TEXT runtime·panicSlice3Acap(SB),NOSPLIT,$0-16
644	MOV	T2, x+0(FP)
645	MOV	T3, y+8(FP)
646	JMP	runtime·goPanicSlice3Acap(SB)
647TEXT runtime·panicSlice3AcapU(SB),NOSPLIT,$0-16
648	MOV	T2, x+0(FP)
649	MOV	T3, y+8(FP)
650	JMP	runtime·goPanicSlice3AcapU(SB)
651TEXT runtime·panicSlice3B(SB),NOSPLIT,$0-16
652	MOV	T1, x+0(FP)
653	MOV	T2, y+8(FP)
654	JMP	runtime·goPanicSlice3B(SB)
655TEXT runtime·panicSlice3BU(SB),NOSPLIT,$0-16
656	MOV	T1, x+0(FP)
657	MOV	T2, y+8(FP)
658	JMP	runtime·goPanicSlice3BU(SB)
659TEXT runtime·panicSlice3C(SB),NOSPLIT,$0-16
660	MOV	T0, x+0(FP)
661	MOV	T1, y+8(FP)
662	JMP	runtime·goPanicSlice3C(SB)
663TEXT runtime·panicSlice3CU(SB),NOSPLIT,$0-16
664	MOV	T0, x+0(FP)
665	MOV	T1, y+8(FP)
666	JMP	runtime·goPanicSlice3CU(SB)
667
668DATA	runtime·mainPC+0(SB)/8,$runtime·main(SB)
669GLOBL	runtime·mainPC(SB),RODATA,$8
670