]> Cypherpunks.ru repositories - gostls13.git/blob - src/runtime/asm_arm64.s
e35131051cb5223057c1bada71345934cca7b5af
[gostls13.git] / src / runtime / asm_arm64.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 #include "go_asm.h"
6 #include "go_tls.h"
7 #include "tls_arm64.h"
8 #include "funcdata.h"
9 #include "textflag.h"
10
11 TEXT runtime·rt0_go(SB),NOSPLIT|TOPFRAME,$0
12         // SP = stack; R0 = argc; R1 = argv
13
14         SUB     $32, RSP
15         MOVW    R0, 8(RSP) // argc
16         MOVD    R1, 16(RSP) // argv
17
18 #ifdef TLS_darwin
19         // Initialize TLS.
20         MOVD    ZR, g // clear g, make sure it's not junk.
21         SUB     $32, RSP
22         MRS_TPIDR_R0
23         AND     $~7, R0
24         MOVD    R0, 16(RSP)             // arg2: TLS base
25         MOVD    $runtime·tls_g(SB), R2
26         MOVD    R2, 8(RSP)              // arg1: &tlsg
27         BL      ·tlsinit(SB)
28         ADD     $32, RSP
29 #endif
30
31         // create istack out of the given (operating system) stack.
32         // _cgo_init may update stackguard.
33         MOVD    $runtime·g0(SB), g
34         MOVD    RSP, R7
35         MOVD    $(-64*1024)(R7), R0
36         MOVD    R0, g_stackguard0(g)
37         MOVD    R0, g_stackguard1(g)
38         MOVD    R0, (g_stack+stack_lo)(g)
39         MOVD    R7, (g_stack+stack_hi)(g)
40
41         // if there is a _cgo_init, call it using the gcc ABI.
42         MOVD    _cgo_init(SB), R12
43         CBZ     R12, nocgo
44
45 #ifdef GOOS_android
46         MRS_TPIDR_R0                    // load TLS base pointer
47         MOVD    R0, R3                  // arg 3: TLS base pointer
48         MOVD    $runtime·tls_g(SB), R2         // arg 2: &tls_g
49 #else
50         MOVD    $0, R2                  // arg 2: not used when using platform's TLS
51 #endif
52         MOVD    $setg_gcc<>(SB), R1     // arg 1: setg
53         MOVD    g, R0                   // arg 0: G
54         SUB     $16, RSP                // reserve 16 bytes for sp-8 where fp may be saved.
55         BL      (R12)
56         ADD     $16, RSP
57
58 nocgo:
59         BL      runtime·save_g(SB)
60         // update stackguard after _cgo_init
61         MOVD    (g_stack+stack_lo)(g), R0
62         ADD     $const__StackGuard, R0
63         MOVD    R0, g_stackguard0(g)
64         MOVD    R0, g_stackguard1(g)
65
66         // set the per-goroutine and per-mach "registers"
67         MOVD    $runtime·m0(SB), R0
68
69         // save m->g0 = g0
70         MOVD    g, m_g0(R0)
71         // save m0 to g0->m
72         MOVD    R0, g_m(g)
73
74         BL      runtime·check(SB)
75
76 #ifdef GOOS_windows
77         BL      runtime·wintls(SB)
78 #endif
79
80         MOVW    8(RSP), R0      // copy argc
81         MOVW    R0, -8(RSP)
82         MOVD    16(RSP), R0             // copy argv
83         MOVD    R0, 0(RSP)
84         BL      runtime·args(SB)
85         BL      runtime·osinit(SB)
86         BL      runtime·schedinit(SB)
87
88         // create a new goroutine to start program
89         MOVD    $runtime·mainPC(SB), R0                // entry
90         SUB     $16, RSP
91         MOVD    R0, 8(RSP) // arg
92         MOVD    $0, 0(RSP) // dummy LR
93         BL      runtime·newproc(SB)
94         ADD     $16, RSP
95
96         // start this M
97         BL      runtime·mstart(SB)
98
99         // Prevent dead-code elimination of debugCallV2, which is
100         // intended to be called by debuggers.
101         MOVD    $runtime·debugCallV2<ABIInternal>(SB), R0
102
103         MOVD    $0, R0
104         MOVD    R0, (R0)        // boom
105         UNDEF
106
107 DATA    runtime·mainPC+0(SB)/8,$runtime·main<ABIInternal>(SB)
108 GLOBL   runtime·mainPC(SB),RODATA,$8
109
110 // Windows ARM64 needs an immediate 0xf000 argument.
111 // See go.dev/issues/53837.
112 #define BREAK   \
113 #ifdef GOOS_windows     \
114         BRK     $0xf000         \
115 #else                           \
116         BRK                     \
117 #endif                          \
118
119
120 TEXT runtime·breakpoint(SB),NOSPLIT|NOFRAME,$0-0
121         BREAK
122         RET
123
124 TEXT runtime·asminit(SB),NOSPLIT|NOFRAME,$0-0
125         RET
126
127 TEXT runtime·mstart(SB),NOSPLIT|TOPFRAME,$0
128         BL      runtime·mstart0(SB)
129         RET // not reached
130
131 /*
132  *  go-routine
133  */
134
135 // void gogo(Gobuf*)
136 // restore state from Gobuf; longjmp
137 TEXT runtime·gogo(SB), NOSPLIT|NOFRAME, $0-8
138         MOVD    buf+0(FP), R5
139         MOVD    gobuf_g(R5), R6
140         MOVD    0(R6), R4       // make sure g != nil
141         B       gogo<>(SB)
142
143 TEXT gogo<>(SB), NOSPLIT|NOFRAME, $0
144         MOVD    R6, g
145         BL      runtime·save_g(SB)
146
147         MOVD    gobuf_sp(R5), R0
148         MOVD    R0, RSP
149         MOVD    gobuf_bp(R5), R29
150         MOVD    gobuf_lr(R5), LR
151         MOVD    gobuf_ret(R5), R0
152         MOVD    gobuf_ctxt(R5), R26
153         MOVD    $0, gobuf_sp(R5)
154         MOVD    $0, gobuf_bp(R5)
155         MOVD    $0, gobuf_ret(R5)
156         MOVD    $0, gobuf_lr(R5)
157         MOVD    $0, gobuf_ctxt(R5)
158         CMP     ZR, ZR // set condition codes for == test, needed by stack split
159         MOVD    gobuf_pc(R5), R6
160         B       (R6)
161
162 // void mcall(fn func(*g))
163 // Switch to m->g0's stack, call fn(g).
164 // Fn must never return. It should gogo(&g->sched)
165 // to keep running g.
166 TEXT runtime·mcall<ABIInternal>(SB), NOSPLIT|NOFRAME, $0-8
167         MOVD    R0, R26                         // context
168
169         // Save caller state in g->sched
170         MOVD    RSP, R0
171         MOVD    R0, (g_sched+gobuf_sp)(g)
172         MOVD    R29, (g_sched+gobuf_bp)(g)
173         MOVD    LR, (g_sched+gobuf_pc)(g)
174         MOVD    $0, (g_sched+gobuf_lr)(g)
175
176         // Switch to m->g0 & its stack, call fn.
177         MOVD    g, R3
178         MOVD    g_m(g), R8
179         MOVD    m_g0(R8), g
180         BL      runtime·save_g(SB)
181         CMP     g, R3
182         BNE     2(PC)
183         B       runtime·badmcall(SB)
184
185         MOVD    (g_sched+gobuf_sp)(g), R0
186         MOVD    R0, RSP // sp = m->g0->sched.sp
187         MOVD    (g_sched+gobuf_bp)(g), R29
188         MOVD    R3, R0                          // arg = g
189         MOVD    $0, -16(RSP)                    // dummy LR
190         SUB     $16, RSP
191         MOVD    0(R26), R4                      // code pointer
192         BL      (R4)
193         B       runtime·badmcall2(SB)
194
195 // systemstack_switch is a dummy routine that systemstack leaves at the bottom
196 // of the G stack. We need to distinguish the routine that
197 // lives at the bottom of the G stack from the one that lives
198 // at the top of the system stack because the one at the top of
199 // the system stack terminates the stack walk (see topofstack()).
200 TEXT runtime·systemstack_switch(SB), NOSPLIT, $0-0
201         UNDEF
202         BL      (LR)    // make sure this function is not leaf
203         RET
204
205 // func systemstack(fn func())
206 TEXT runtime·systemstack(SB), NOSPLIT, $0-8
207         MOVD    fn+0(FP), R3    // R3 = fn
208         MOVD    R3, R26         // context
209         MOVD    g_m(g), R4      // R4 = m
210
211         MOVD    m_gsignal(R4), R5       // R5 = gsignal
212         CMP     g, R5
213         BEQ     noswitch
214
215         MOVD    m_g0(R4), R5    // R5 = g0
216         CMP     g, R5
217         BEQ     noswitch
218
219         MOVD    m_curg(R4), R6
220         CMP     g, R6
221         BEQ     switch
222
223         // Bad: g is not gsignal, not g0, not curg. What is it?
224         // Hide call from linker nosplit analysis.
225         MOVD    $runtime·badsystemstack(SB), R3
226         BL      (R3)
227         B       runtime·abort(SB)
228
229 switch:
230         // save our state in g->sched. Pretend to
231         // be systemstack_switch if the G stack is scanned.
232         BL      gosave_systemstack_switch<>(SB)
233
234         // switch to g0
235         MOVD    R5, g
236         BL      runtime·save_g(SB)
237         MOVD    (g_sched+gobuf_sp)(g), R3
238         MOVD    R3, RSP
239         MOVD    (g_sched+gobuf_bp)(g), R29
240
241         // call target function
242         MOVD    0(R26), R3      // code pointer
243         BL      (R3)
244
245         // switch back to g
246         MOVD    g_m(g), R3
247         MOVD    m_curg(R3), g
248         BL      runtime·save_g(SB)
249         MOVD    (g_sched+gobuf_sp)(g), R0
250         MOVD    R0, RSP
251         MOVD    (g_sched+gobuf_bp)(g), R29
252         MOVD    $0, (g_sched+gobuf_sp)(g)
253         MOVD    $0, (g_sched+gobuf_bp)(g)
254         RET
255
256 noswitch:
257         // already on m stack, just call directly
258         // Using a tail call here cleans up tracebacks since we won't stop
259         // at an intermediate systemstack.
260         MOVD    0(R26), R3      // code pointer
261         MOVD.P  16(RSP), R30    // restore LR
262         SUB     $8, RSP, R29    // restore FP
263         B       (R3)
264
265 /*
266  * support for morestack
267  */
268
269 // Called during function prolog when more stack is needed.
270 // Caller has already loaded:
271 // R3 prolog's LR (R30)
272 //
273 // The traceback routines see morestack on a g0 as being
274 // the top of a stack (for example, morestack calling newstack
275 // calling the scheduler calling newm calling gc), so we must
276 // record an argument size. For that purpose, it has no arguments.
277 TEXT runtime·morestack(SB),NOSPLIT|NOFRAME,$0-0
278         // Cannot grow scheduler stack (m->g0).
279         MOVD    g_m(g), R8
280         MOVD    m_g0(R8), R4
281         CMP     g, R4
282         BNE     3(PC)
283         BL      runtime·badmorestackg0(SB)
284         B       runtime·abort(SB)
285
286         // Cannot grow signal stack (m->gsignal).
287         MOVD    m_gsignal(R8), R4
288         CMP     g, R4
289         BNE     3(PC)
290         BL      runtime·badmorestackgsignal(SB)
291         B       runtime·abort(SB)
292
293         // Called from f.
294         // Set g->sched to context in f
295         MOVD    RSP, R0
296         MOVD    R0, (g_sched+gobuf_sp)(g)
297         MOVD    R29, (g_sched+gobuf_bp)(g)
298         MOVD    LR, (g_sched+gobuf_pc)(g)
299         MOVD    R3, (g_sched+gobuf_lr)(g)
300         MOVD    R26, (g_sched+gobuf_ctxt)(g)
301
302         // Called from f.
303         // Set m->morebuf to f's callers.
304         MOVD    R3, (m_morebuf+gobuf_pc)(R8)    // f's caller's PC
305         MOVD    RSP, R0
306         MOVD    R0, (m_morebuf+gobuf_sp)(R8)    // f's caller's RSP
307         MOVD    g, (m_morebuf+gobuf_g)(R8)
308
309         // Call newstack on m->g0's stack.
310         MOVD    m_g0(R8), g
311         BL      runtime·save_g(SB)
312         MOVD    (g_sched+gobuf_sp)(g), R0
313         MOVD    R0, RSP
314         MOVD    (g_sched+gobuf_bp)(g), R29
315         MOVD.W  $0, -16(RSP)    // create a call frame on g0 (saved LR; keep 16-aligned)
316         BL      runtime·newstack(SB)
317
318         // Not reached, but make sure the return PC from the call to newstack
319         // is still in this function, and not the beginning of the next.
320         UNDEF
321
322 TEXT runtime·morestack_noctxt(SB),NOSPLIT|NOFRAME,$0-0
323         // Force SPWRITE. This function doesn't actually write SP,
324         // but it is called with a special calling convention where
325         // the caller doesn't save LR on stack but passes it as a
326         // register (R3), and the unwinder currently doesn't understand.
327         // Make it SPWRITE to stop unwinding. (See issue 54332)
328         MOVD    RSP, RSP
329
330         MOVW    $0, R26
331         B runtime·morestack(SB)
332
333 // spillArgs stores return values from registers to a *internal/abi.RegArgs in R20.
334 TEXT ·spillArgs(SB),NOSPLIT,$0-0
335         STP     (R0, R1), (0*8)(R20)
336         STP     (R2, R3), (2*8)(R20)
337         STP     (R4, R5), (4*8)(R20)
338         STP     (R6, R7), (6*8)(R20)
339         STP     (R8, R9), (8*8)(R20)
340         STP     (R10, R11), (10*8)(R20)
341         STP     (R12, R13), (12*8)(R20)
342         STP     (R14, R15), (14*8)(R20)
343         FSTPD   (F0, F1), (16*8)(R20)
344         FSTPD   (F2, F3), (18*8)(R20)
345         FSTPD   (F4, F5), (20*8)(R20)
346         FSTPD   (F6, F7), (22*8)(R20)
347         FSTPD   (F8, F9), (24*8)(R20)
348         FSTPD   (F10, F11), (26*8)(R20)
349         FSTPD   (F12, F13), (28*8)(R20)
350         FSTPD   (F14, F15), (30*8)(R20)
351         RET
352
353 // unspillArgs loads args into registers from a *internal/abi.RegArgs in R20.
354 TEXT ·unspillArgs(SB),NOSPLIT,$0-0
355         LDP     (0*8)(R20), (R0, R1)
356         LDP     (2*8)(R20), (R2, R3)
357         LDP     (4*8)(R20), (R4, R5)
358         LDP     (6*8)(R20), (R6, R7)
359         LDP     (8*8)(R20), (R8, R9)
360         LDP     (10*8)(R20), (R10, R11)
361         LDP     (12*8)(R20), (R12, R13)
362         LDP     (14*8)(R20), (R14, R15)
363         FLDPD   (16*8)(R20), (F0, F1)
364         FLDPD   (18*8)(R20), (F2, F3)
365         FLDPD   (20*8)(R20), (F4, F5)
366         FLDPD   (22*8)(R20), (F6, F7)
367         FLDPD   (24*8)(R20), (F8, F9)
368         FLDPD   (26*8)(R20), (F10, F11)
369         FLDPD   (28*8)(R20), (F12, F13)
370         FLDPD   (30*8)(R20), (F14, F15)
371         RET
372
373 // reflectcall: call a function with the given argument list
374 // func call(stackArgsType *_type, f *FuncVal, stackArgs *byte, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs).
375 // we don't have variable-sized frames, so we use a small number
376 // of constant-sized-frame functions to encode a few bits of size in the pc.
377 // Caution: ugly multiline assembly macros in your future!
378
379 #define DISPATCH(NAME,MAXSIZE)          \
380         MOVD    $MAXSIZE, R27;          \
381         CMP     R27, R16;               \
382         BGT     3(PC);                  \
383         MOVD    $NAME(SB), R27; \
384         B       (R27)
385 // Note: can't just "B NAME(SB)" - bad inlining results.
386
387 TEXT ·reflectcall(SB), NOSPLIT|NOFRAME, $0-48
388         MOVWU   frameSize+32(FP), R16
389         DISPATCH(runtime·call16, 16)
390         DISPATCH(runtime·call32, 32)
391         DISPATCH(runtime·call64, 64)
392         DISPATCH(runtime·call128, 128)
393         DISPATCH(runtime·call256, 256)
394         DISPATCH(runtime·call512, 512)
395         DISPATCH(runtime·call1024, 1024)
396         DISPATCH(runtime·call2048, 2048)
397         DISPATCH(runtime·call4096, 4096)
398         DISPATCH(runtime·call8192, 8192)
399         DISPATCH(runtime·call16384, 16384)
400         DISPATCH(runtime·call32768, 32768)
401         DISPATCH(runtime·call65536, 65536)
402         DISPATCH(runtime·call131072, 131072)
403         DISPATCH(runtime·call262144, 262144)
404         DISPATCH(runtime·call524288, 524288)
405         DISPATCH(runtime·call1048576, 1048576)
406         DISPATCH(runtime·call2097152, 2097152)
407         DISPATCH(runtime·call4194304, 4194304)
408         DISPATCH(runtime·call8388608, 8388608)
409         DISPATCH(runtime·call16777216, 16777216)
410         DISPATCH(runtime·call33554432, 33554432)
411         DISPATCH(runtime·call67108864, 67108864)
412         DISPATCH(runtime·call134217728, 134217728)
413         DISPATCH(runtime·call268435456, 268435456)
414         DISPATCH(runtime·call536870912, 536870912)
415         DISPATCH(runtime·call1073741824, 1073741824)
416         MOVD    $runtime·badreflectcall(SB), R0
417         B       (R0)
418
419 #define CALLFN(NAME,MAXSIZE)                    \
420 TEXT NAME(SB), WRAPPER, $MAXSIZE-48;            \
421         NO_LOCAL_POINTERS;                      \
422         /* copy arguments to stack */           \
423         MOVD    stackArgs+16(FP), R3;                   \
424         MOVWU   stackArgsSize+24(FP), R4;               \
425         ADD     $8, RSP, R5;                    \
426         BIC     $0xf, R4, R6;                   \
427         CBZ     R6, 6(PC);                      \
428         /* if R6=(argsize&~15) != 0 */          \
429         ADD     R6, R5, R6;                     \
430         /* copy 16 bytes a time */              \
431         LDP.P   16(R3), (R7, R8);               \
432         STP.P   (R7, R8), 16(R5);               \
433         CMP     R5, R6;                         \
434         BNE     -3(PC);                         \
435         AND     $0xf, R4, R6;                   \
436         CBZ     R6, 6(PC);                      \
437         /* if R6=(argsize&15) != 0 */           \
438         ADD     R6, R5, R6;                     \
439         /* copy 1 byte a time for the rest */   \
440         MOVBU.P 1(R3), R7;                      \
441         MOVBU.P R7, 1(R5);                      \
442         CMP     R5, R6;                         \
443         BNE     -3(PC);                         \
444         /* set up argument registers */         \
445         MOVD    regArgs+40(FP), R20;            \
446         CALL    ·unspillArgs(SB);              \
447         /* call function */                     \
448         MOVD    f+8(FP), R26;                   \
449         MOVD    (R26), R20;                     \
450         PCDATA  $PCDATA_StackMapIndex, $0;      \
451         BL      (R20);                          \
452         /* copy return values back */           \
453         MOVD    regArgs+40(FP), R20;            \
454         CALL    ·spillArgs(SB);                \
455         MOVD    stackArgsType+0(FP), R7;                \
456         MOVD    stackArgs+16(FP), R3;                   \
457         MOVWU   stackArgsSize+24(FP), R4;                       \
458         MOVWU   stackRetOffset+28(FP), R6;              \
459         ADD     $8, RSP, R5;                    \
460         ADD     R6, R5;                         \
461         ADD     R6, R3;                         \
462         SUB     R6, R4;                         \
463         BL      callRet<>(SB);                  \
464         RET
465
466 // callRet copies return values back at the end of call*. This is a
467 // separate function so it can allocate stack space for the arguments
468 // to reflectcallmove. It does not follow the Go ABI; it expects its
469 // arguments in registers.
470 TEXT callRet<>(SB), NOSPLIT, $48-0
471         NO_LOCAL_POINTERS
472         STP     (R7, R3), 8(RSP)
473         STP     (R5, R4), 24(RSP)
474         MOVD    R20, 40(RSP)
475         BL      runtime·reflectcallmove(SB)
476         RET
477
478 CALLFN(·call16, 16)
479 CALLFN(·call32, 32)
480 CALLFN(·call64, 64)
481 CALLFN(·call128, 128)
482 CALLFN(·call256, 256)
483 CALLFN(·call512, 512)
484 CALLFN(·call1024, 1024)
485 CALLFN(·call2048, 2048)
486 CALLFN(·call4096, 4096)
487 CALLFN(·call8192, 8192)
488 CALLFN(·call16384, 16384)
489 CALLFN(·call32768, 32768)
490 CALLFN(·call65536, 65536)
491 CALLFN(·call131072, 131072)
492 CALLFN(·call262144, 262144)
493 CALLFN(·call524288, 524288)
494 CALLFN(·call1048576, 1048576)
495 CALLFN(·call2097152, 2097152)
496 CALLFN(·call4194304, 4194304)
497 CALLFN(·call8388608, 8388608)
498 CALLFN(·call16777216, 16777216)
499 CALLFN(·call33554432, 33554432)
500 CALLFN(·call67108864, 67108864)
501 CALLFN(·call134217728, 134217728)
502 CALLFN(·call268435456, 268435456)
503 CALLFN(·call536870912, 536870912)
504 CALLFN(·call1073741824, 1073741824)
505
506 // func memhash32(p unsafe.Pointer, h uintptr) uintptr
507 TEXT runtime·memhash32<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-24
508         MOVB    runtime·useAeshash(SB), R10
509         CBZ     R10, noaes
510         MOVD    $runtime·aeskeysched+0(SB), R3
511
512         VEOR    V0.B16, V0.B16, V0.B16
513         VLD1    (R3), [V2.B16]
514         VLD1    (R0), V0.S[1]
515         VMOV    R1, V0.S[0]
516
517         AESE    V2.B16, V0.B16
518         AESMC   V0.B16, V0.B16
519         AESE    V2.B16, V0.B16
520         AESMC   V0.B16, V0.B16
521         AESE    V2.B16, V0.B16
522
523         VMOV    V0.D[0], R0
524         RET
525 noaes:
526         B       runtime·memhash32Fallback<ABIInternal>(SB)
527
528 // func memhash64(p unsafe.Pointer, h uintptr) uintptr
529 TEXT runtime·memhash64<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-24
530         MOVB    runtime·useAeshash(SB), R10
531         CBZ     R10, noaes
532         MOVD    $runtime·aeskeysched+0(SB), R3
533
534         VEOR    V0.B16, V0.B16, V0.B16
535         VLD1    (R3), [V2.B16]
536         VLD1    (R0), V0.D[1]
537         VMOV    R1, V0.D[0]
538
539         AESE    V2.B16, V0.B16
540         AESMC   V0.B16, V0.B16
541         AESE    V2.B16, V0.B16
542         AESMC   V0.B16, V0.B16
543         AESE    V2.B16, V0.B16
544
545         VMOV    V0.D[0], R0
546         RET
547 noaes:
548         B       runtime·memhash64Fallback<ABIInternal>(SB)
549
550 // func memhash(p unsafe.Pointer, h, size uintptr) uintptr
551 TEXT runtime·memhash<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-32
552         MOVB    runtime·useAeshash(SB), R10
553         CBZ     R10, noaes
554         B       aeshashbody<>(SB)
555 noaes:
556         B       runtime·memhashFallback<ABIInternal>(SB)
557
558 // func strhash(p unsafe.Pointer, h uintptr) uintptr
559 TEXT runtime·strhash<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-24
560         MOVB    runtime·useAeshash(SB), R10
561         CBZ     R10, noaes
562         LDP     (R0), (R0, R2)  // string data / length
563         B       aeshashbody<>(SB)
564 noaes:
565         B       runtime·strhashFallback<ABIInternal>(SB)
566
567 // R0: data
568 // R1: seed data
569 // R2: length
570 // At return, R0 = return value
571 TEXT aeshashbody<>(SB),NOSPLIT|NOFRAME,$0
572         VEOR    V30.B16, V30.B16, V30.B16
573         VMOV    R1, V30.D[0]
574         VMOV    R2, V30.D[1] // load length into seed
575
576         MOVD    $runtime·aeskeysched+0(SB), R4
577         VLD1.P  16(R4), [V0.B16]
578         AESE    V30.B16, V0.B16
579         AESMC   V0.B16, V0.B16
580         CMP     $16, R2
581         BLO     aes0to15
582         BEQ     aes16
583         CMP     $32, R2
584         BLS     aes17to32
585         CMP     $64, R2
586         BLS     aes33to64
587         CMP     $128, R2
588         BLS     aes65to128
589         B       aes129plus
590
591 aes0to15:
592         CBZ     R2, aes0
593         VEOR    V2.B16, V2.B16, V2.B16
594         TBZ     $3, R2, less_than_8
595         VLD1.P  8(R0), V2.D[0]
596
597 less_than_8:
598         TBZ     $2, R2, less_than_4
599         VLD1.P  4(R0), V2.S[2]
600
601 less_than_4:
602         TBZ     $1, R2, less_than_2
603         VLD1.P  2(R0), V2.H[6]
604
605 less_than_2:
606         TBZ     $0, R2, done
607         VLD1    (R0), V2.B[14]
608 done:
609         AESE    V0.B16, V2.B16
610         AESMC   V2.B16, V2.B16
611         AESE    V0.B16, V2.B16
612         AESMC   V2.B16, V2.B16
613         AESE    V0.B16, V2.B16
614
615         VMOV    V2.D[0], R0
616         RET
617
618 aes0:
619         VMOV    V0.D[0], R0
620         RET
621
622 aes16:
623         VLD1    (R0), [V2.B16]
624         B       done
625
626 aes17to32:
627         // make second seed
628         VLD1    (R4), [V1.B16]
629         AESE    V30.B16, V1.B16
630         AESMC   V1.B16, V1.B16
631         SUB     $16, R2, R10
632         VLD1.P  (R0)(R10), [V2.B16]
633         VLD1    (R0), [V3.B16]
634
635         AESE    V0.B16, V2.B16
636         AESMC   V2.B16, V2.B16
637         AESE    V1.B16, V3.B16
638         AESMC   V3.B16, V3.B16
639
640         AESE    V0.B16, V2.B16
641         AESMC   V2.B16, V2.B16
642         AESE    V1.B16, V3.B16
643         AESMC   V3.B16, V3.B16
644
645         AESE    V0.B16, V2.B16
646         AESE    V1.B16, V3.B16
647
648         VEOR    V3.B16, V2.B16, V2.B16
649
650         VMOV    V2.D[0], R0
651         RET
652
653 aes33to64:
654         VLD1    (R4), [V1.B16, V2.B16, V3.B16]
655         AESE    V30.B16, V1.B16
656         AESMC   V1.B16, V1.B16
657         AESE    V30.B16, V2.B16
658         AESMC   V2.B16, V2.B16
659         AESE    V30.B16, V3.B16
660         AESMC   V3.B16, V3.B16
661         SUB     $32, R2, R10
662
663         VLD1.P  (R0)(R10), [V4.B16, V5.B16]
664         VLD1    (R0), [V6.B16, V7.B16]
665
666         AESE    V0.B16, V4.B16
667         AESMC   V4.B16, V4.B16
668         AESE    V1.B16, V5.B16
669         AESMC   V5.B16, V5.B16
670         AESE    V2.B16, V6.B16
671         AESMC   V6.B16, V6.B16
672         AESE    V3.B16, V7.B16
673         AESMC   V7.B16, V7.B16
674
675         AESE    V0.B16, V4.B16
676         AESMC   V4.B16, V4.B16
677         AESE    V1.B16, V5.B16
678         AESMC   V5.B16, V5.B16
679         AESE    V2.B16, V6.B16
680         AESMC   V6.B16, V6.B16
681         AESE    V3.B16, V7.B16
682         AESMC   V7.B16, V7.B16
683
684         AESE    V0.B16, V4.B16
685         AESE    V1.B16, V5.B16
686         AESE    V2.B16, V6.B16
687         AESE    V3.B16, V7.B16
688
689         VEOR    V6.B16, V4.B16, V4.B16
690         VEOR    V7.B16, V5.B16, V5.B16
691         VEOR    V5.B16, V4.B16, V4.B16
692
693         VMOV    V4.D[0], R0
694         RET
695
696 aes65to128:
697         VLD1.P  64(R4), [V1.B16, V2.B16, V3.B16, V4.B16]
698         VLD1    (R4), [V5.B16, V6.B16, V7.B16]
699         AESE    V30.B16, V1.B16
700         AESMC   V1.B16, V1.B16
701         AESE    V30.B16, V2.B16
702         AESMC   V2.B16, V2.B16
703         AESE    V30.B16, V3.B16
704         AESMC   V3.B16, V3.B16
705         AESE    V30.B16, V4.B16
706         AESMC   V4.B16, V4.B16
707         AESE    V30.B16, V5.B16
708         AESMC   V5.B16, V5.B16
709         AESE    V30.B16, V6.B16
710         AESMC   V6.B16, V6.B16
711         AESE    V30.B16, V7.B16
712         AESMC   V7.B16, V7.B16
713
714         SUB     $64, R2, R10
715         VLD1.P  (R0)(R10), [V8.B16, V9.B16, V10.B16, V11.B16]
716         VLD1    (R0), [V12.B16, V13.B16, V14.B16, V15.B16]
717         AESE    V0.B16,  V8.B16
718         AESMC   V8.B16,  V8.B16
719         AESE    V1.B16,  V9.B16
720         AESMC   V9.B16,  V9.B16
721         AESE    V2.B16, V10.B16
722         AESMC   V10.B16,  V10.B16
723         AESE    V3.B16, V11.B16
724         AESMC   V11.B16,  V11.B16
725         AESE    V4.B16, V12.B16
726         AESMC   V12.B16,  V12.B16
727         AESE    V5.B16, V13.B16
728         AESMC   V13.B16,  V13.B16
729         AESE    V6.B16, V14.B16
730         AESMC   V14.B16,  V14.B16
731         AESE    V7.B16, V15.B16
732         AESMC   V15.B16,  V15.B16
733
734         AESE    V0.B16,  V8.B16
735         AESMC   V8.B16,  V8.B16
736         AESE    V1.B16,  V9.B16
737         AESMC   V9.B16,  V9.B16
738         AESE    V2.B16, V10.B16
739         AESMC   V10.B16,  V10.B16
740         AESE    V3.B16, V11.B16
741         AESMC   V11.B16,  V11.B16
742         AESE    V4.B16, V12.B16
743         AESMC   V12.B16,  V12.B16
744         AESE    V5.B16, V13.B16
745         AESMC   V13.B16,  V13.B16
746         AESE    V6.B16, V14.B16
747         AESMC   V14.B16,  V14.B16
748         AESE    V7.B16, V15.B16
749         AESMC   V15.B16,  V15.B16
750
751         AESE    V0.B16,  V8.B16
752         AESE    V1.B16,  V9.B16
753         AESE    V2.B16, V10.B16
754         AESE    V3.B16, V11.B16
755         AESE    V4.B16, V12.B16
756         AESE    V5.B16, V13.B16
757         AESE    V6.B16, V14.B16
758         AESE    V7.B16, V15.B16
759
760         VEOR    V12.B16, V8.B16, V8.B16
761         VEOR    V13.B16, V9.B16, V9.B16
762         VEOR    V14.B16, V10.B16, V10.B16
763         VEOR    V15.B16, V11.B16, V11.B16
764         VEOR    V10.B16, V8.B16, V8.B16
765         VEOR    V11.B16, V9.B16, V9.B16
766         VEOR    V9.B16, V8.B16, V8.B16
767
768         VMOV    V8.D[0], R0
769         RET
770
771 aes129plus:
772         PRFM (R0), PLDL1KEEP
773         VLD1.P  64(R4), [V1.B16, V2.B16, V3.B16, V4.B16]
774         VLD1    (R4), [V5.B16, V6.B16, V7.B16]
775         AESE    V30.B16, V1.B16
776         AESMC   V1.B16, V1.B16
777         AESE    V30.B16, V2.B16
778         AESMC   V2.B16, V2.B16
779         AESE    V30.B16, V3.B16
780         AESMC   V3.B16, V3.B16
781         AESE    V30.B16, V4.B16
782         AESMC   V4.B16, V4.B16
783         AESE    V30.B16, V5.B16
784         AESMC   V5.B16, V5.B16
785         AESE    V30.B16, V6.B16
786         AESMC   V6.B16, V6.B16
787         AESE    V30.B16, V7.B16
788         AESMC   V7.B16, V7.B16
789         ADD     R0, R2, R10
790         SUB     $128, R10, R10
791         VLD1.P  64(R10), [V8.B16, V9.B16, V10.B16, V11.B16]
792         VLD1    (R10), [V12.B16, V13.B16, V14.B16, V15.B16]
793         SUB     $1, R2, R2
794         LSR     $7, R2, R2
795
796 aesloop:
797         AESE    V8.B16,  V0.B16
798         AESMC   V0.B16,  V0.B16
799         AESE    V9.B16,  V1.B16
800         AESMC   V1.B16,  V1.B16
801         AESE    V10.B16, V2.B16
802         AESMC   V2.B16,  V2.B16
803         AESE    V11.B16, V3.B16
804         AESMC   V3.B16,  V3.B16
805         AESE    V12.B16, V4.B16
806         AESMC   V4.B16,  V4.B16
807         AESE    V13.B16, V5.B16
808         AESMC   V5.B16,  V5.B16
809         AESE    V14.B16, V6.B16
810         AESMC   V6.B16,  V6.B16
811         AESE    V15.B16, V7.B16
812         AESMC   V7.B16,  V7.B16
813
814         VLD1.P  64(R0), [V8.B16, V9.B16, V10.B16, V11.B16]
815         AESE    V8.B16,  V0.B16
816         AESMC   V0.B16,  V0.B16
817         AESE    V9.B16,  V1.B16
818         AESMC   V1.B16,  V1.B16
819         AESE    V10.B16, V2.B16
820         AESMC   V2.B16,  V2.B16
821         AESE    V11.B16, V3.B16
822         AESMC   V3.B16,  V3.B16
823
824         VLD1.P  64(R0), [V12.B16, V13.B16, V14.B16, V15.B16]
825         AESE    V12.B16, V4.B16
826         AESMC   V4.B16,  V4.B16
827         AESE    V13.B16, V5.B16
828         AESMC   V5.B16,  V5.B16
829         AESE    V14.B16, V6.B16
830         AESMC   V6.B16,  V6.B16
831         AESE    V15.B16, V7.B16
832         AESMC   V7.B16,  V7.B16
833         SUB     $1, R2, R2
834         CBNZ    R2, aesloop
835
836         AESE    V8.B16,  V0.B16
837         AESMC   V0.B16,  V0.B16
838         AESE    V9.B16,  V1.B16
839         AESMC   V1.B16,  V1.B16
840         AESE    V10.B16, V2.B16
841         AESMC   V2.B16,  V2.B16
842         AESE    V11.B16, V3.B16
843         AESMC   V3.B16,  V3.B16
844         AESE    V12.B16, V4.B16
845         AESMC   V4.B16,  V4.B16
846         AESE    V13.B16, V5.B16
847         AESMC   V5.B16,  V5.B16
848         AESE    V14.B16, V6.B16
849         AESMC   V6.B16,  V6.B16
850         AESE    V15.B16, V7.B16
851         AESMC   V7.B16,  V7.B16
852
853         AESE    V8.B16,  V0.B16
854         AESMC   V0.B16,  V0.B16
855         AESE    V9.B16,  V1.B16
856         AESMC   V1.B16,  V1.B16
857         AESE    V10.B16, V2.B16
858         AESMC   V2.B16,  V2.B16
859         AESE    V11.B16, V3.B16
860         AESMC   V3.B16,  V3.B16
861         AESE    V12.B16, V4.B16
862         AESMC   V4.B16,  V4.B16
863         AESE    V13.B16, V5.B16
864         AESMC   V5.B16,  V5.B16
865         AESE    V14.B16, V6.B16
866         AESMC   V6.B16,  V6.B16
867         AESE    V15.B16, V7.B16
868         AESMC   V7.B16,  V7.B16
869
870         AESE    V8.B16,  V0.B16
871         AESE    V9.B16,  V1.B16
872         AESE    V10.B16, V2.B16
873         AESE    V11.B16, V3.B16
874         AESE    V12.B16, V4.B16
875         AESE    V13.B16, V5.B16
876         AESE    V14.B16, V6.B16
877         AESE    V15.B16, V7.B16
878
879         VEOR    V0.B16, V1.B16, V0.B16
880         VEOR    V2.B16, V3.B16, V2.B16
881         VEOR    V4.B16, V5.B16, V4.B16
882         VEOR    V6.B16, V7.B16, V6.B16
883         VEOR    V0.B16, V2.B16, V0.B16
884         VEOR    V4.B16, V6.B16, V4.B16
885         VEOR    V4.B16, V0.B16, V0.B16
886
887         VMOV    V0.D[0], R0
888         RET
889
890 TEXT runtime·procyield(SB),NOSPLIT,$0-0
891         MOVWU   cycles+0(FP), R0
892 again:
893         YIELD
894         SUBW    $1, R0
895         CBNZ    R0, again
896         RET
897
898 // Save state of caller into g->sched,
899 // but using fake PC from systemstack_switch.
900 // Must only be called from functions with no locals ($0)
901 // or else unwinding from systemstack_switch is incorrect.
902 // Smashes R0.
903 TEXT gosave_systemstack_switch<>(SB),NOSPLIT|NOFRAME,$0
904         MOVD    $runtime·systemstack_switch(SB), R0
905         ADD     $8, R0  // get past prologue
906         MOVD    R0, (g_sched+gobuf_pc)(g)
907         MOVD    RSP, R0
908         MOVD    R0, (g_sched+gobuf_sp)(g)
909         MOVD    R29, (g_sched+gobuf_bp)(g)
910         MOVD    $0, (g_sched+gobuf_lr)(g)
911         MOVD    $0, (g_sched+gobuf_ret)(g)
912         // Assert ctxt is zero. See func save.
913         MOVD    (g_sched+gobuf_ctxt)(g), R0
914         CBZ     R0, 2(PC)
915         CALL    runtime·abort(SB)
916         RET
917
918 // func asmcgocall_no_g(fn, arg unsafe.Pointer)
919 // Call fn(arg) aligned appropriately for the gcc ABI.
920 // Called on a system stack, and there may be no g yet (during needm).
921 TEXT ·asmcgocall_no_g(SB),NOSPLIT,$0-16
922         MOVD    fn+0(FP), R1
923         MOVD    arg+8(FP), R0
924         SUB     $16, RSP        // skip over saved frame pointer below RSP
925         BL      (R1)
926         ADD     $16, RSP        // skip over saved frame pointer below RSP
927         RET
928
929 // func asmcgocall(fn, arg unsafe.Pointer) int32
930 // Call fn(arg) on the scheduler stack,
931 // aligned appropriately for the gcc ABI.
932 // See cgocall.go for more details.
933 TEXT ·asmcgocall(SB),NOSPLIT,$0-20
934         MOVD    fn+0(FP), R1
935         MOVD    arg+8(FP), R0
936
937         MOVD    RSP, R2         // save original stack pointer
938         CBZ     g, nosave
939         MOVD    g, R4
940
941         // Figure out if we need to switch to m->g0 stack.
942         // We get called to create new OS threads too, and those
943         // come in on the m->g0 stack already. Or we might already
944         // be on the m->gsignal stack.
945         MOVD    g_m(g), R8
946         MOVD    m_gsignal(R8), R3
947         CMP     R3, g
948         BEQ     nosave
949         MOVD    m_g0(R8), R3
950         CMP     R3, g
951         BEQ     nosave
952
953         // Switch to system stack.
954         MOVD    R0, R9  // gosave_systemstack_switch<> and save_g might clobber R0
955         BL      gosave_systemstack_switch<>(SB)
956         MOVD    R3, g
957         BL      runtime·save_g(SB)
958         MOVD    (g_sched+gobuf_sp)(g), R0
959         MOVD    R0, RSP
960         MOVD    (g_sched+gobuf_bp)(g), R29
961         MOVD    R9, R0
962
963         // Now on a scheduling stack (a pthread-created stack).
964         // Save room for two of our pointers /*, plus 32 bytes of callee
965         // save area that lives on the caller stack. */
966         MOVD    RSP, R13
967         SUB     $16, R13
968         MOVD    R13, RSP
969         MOVD    R4, 0(RSP)      // save old g on stack
970         MOVD    (g_stack+stack_hi)(R4), R4
971         SUB     R2, R4
972         MOVD    R4, 8(RSP)      // save depth in old g stack (can't just save SP, as stack might be copied during a callback)
973         BL      (R1)
974         MOVD    R0, R9
975
976         // Restore g, stack pointer. R0 is errno, so don't touch it
977         MOVD    0(RSP), g
978         BL      runtime·save_g(SB)
979         MOVD    (g_stack+stack_hi)(g), R5
980         MOVD    8(RSP), R6
981         SUB     R6, R5
982         MOVD    R9, R0
983         MOVD    R5, RSP
984
985         MOVW    R0, ret+16(FP)
986         RET
987
988 nosave:
989         // Running on a system stack, perhaps even without a g.
990         // Having no g can happen during thread creation or thread teardown
991         // (see needm/dropm on Solaris, for example).
992         // This code is like the above sequence but without saving/restoring g
993         // and without worrying about the stack moving out from under us
994         // (because we're on a system stack, not a goroutine stack).
995         // The above code could be used directly if already on a system stack,
996         // but then the only path through this code would be a rare case on Solaris.
997         // Using this code for all "already on system stack" calls exercises it more,
998         // which should help keep it correct.
999         MOVD    RSP, R13
1000         SUB     $16, R13
1001         MOVD    R13, RSP
1002         MOVD    $0, R4
1003         MOVD    R4, 0(RSP)      // Where above code stores g, in case someone looks during debugging.
1004         MOVD    R2, 8(RSP)      // Save original stack pointer.
1005         BL      (R1)
1006         // Restore stack pointer.
1007         MOVD    8(RSP), R2
1008         MOVD    R2, RSP
1009         MOVD    R0, ret+16(FP)
1010         RET
1011
1012 // cgocallback(fn, frame unsafe.Pointer, ctxt uintptr)
1013 // See cgocall.go for more details.
1014 TEXT ·cgocallback(SB),NOSPLIT,$24-24
1015         NO_LOCAL_POINTERS
1016
1017         // Skip cgocallbackg, just dropm when fn is nil, and frame is the saved g.
1018         // It is used to dropm while thread is exiting.
1019         MOVD    fn+0(FP), R1
1020         CBNZ    R1, loadg
1021         // Restore the g from frame.
1022         MOVD    frame+8(FP), g
1023         B       dropm
1024
1025 loadg:
1026         // Load g from thread-local storage.
1027         BL      runtime·load_g(SB)
1028
1029         // If g is nil, Go did not create the current thread,
1030         // or if this thread never called into Go on pthread platforms.
1031         // Call needm to obtain one for temporary use.
1032         // In this case, we're running on the thread stack, so there's
1033         // lots of space, but the linker doesn't know. Hide the call from
1034         // the linker analysis by using an indirect call.
1035         CBZ     g, needm
1036
1037         MOVD    g_m(g), R8
1038         MOVD    R8, savedm-8(SP)
1039         B       havem
1040
1041 needm:
1042         MOVD    g, savedm-8(SP) // g is zero, so is m.
1043         MOVD    $runtime·needAndBindM(SB), R0
1044         BL      (R0)
1045
1046         // Set m->g0->sched.sp = SP, so that if a panic happens
1047         // during the function we are about to execute, it will
1048         // have a valid SP to run on the g0 stack.
1049         // The next few lines (after the havem label)
1050         // will save this SP onto the stack and then write
1051         // the same SP back to m->sched.sp. That seems redundant,
1052         // but if an unrecovered panic happens, unwindm will
1053         // restore the g->sched.sp from the stack location
1054         // and then systemstack will try to use it. If we don't set it here,
1055         // that restored SP will be uninitialized (typically 0) and
1056         // will not be usable.
1057         MOVD    g_m(g), R8
1058         MOVD    m_g0(R8), R3
1059         MOVD    RSP, R0
1060         MOVD    R0, (g_sched+gobuf_sp)(R3)
1061         MOVD    R29, (g_sched+gobuf_bp)(R3)
1062
1063 havem:
1064         // Now there's a valid m, and we're running on its m->g0.
1065         // Save current m->g0->sched.sp on stack and then set it to SP.
1066         // Save current sp in m->g0->sched.sp in preparation for
1067         // switch back to m->curg stack.
1068         // NOTE: unwindm knows that the saved g->sched.sp is at 16(RSP) aka savedsp-16(SP).
1069         // Beware that the frame size is actually 32+16.
1070         MOVD    m_g0(R8), R3
1071         MOVD    (g_sched+gobuf_sp)(R3), R4
1072         MOVD    R4, savedsp-16(SP)
1073         MOVD    RSP, R0
1074         MOVD    R0, (g_sched+gobuf_sp)(R3)
1075
1076         // Switch to m->curg stack and call runtime.cgocallbackg.
1077         // Because we are taking over the execution of m->curg
1078         // but *not* resuming what had been running, we need to
1079         // save that information (m->curg->sched) so we can restore it.
1080         // We can restore m->curg->sched.sp easily, because calling
1081         // runtime.cgocallbackg leaves SP unchanged upon return.
1082         // To save m->curg->sched.pc, we push it onto the curg stack and
1083         // open a frame the same size as cgocallback's g0 frame.
1084         // Once we switch to the curg stack, the pushed PC will appear
1085         // to be the return PC of cgocallback, so that the traceback
1086         // will seamlessly trace back into the earlier calls.
1087         MOVD    m_curg(R8), g
1088         BL      runtime·save_g(SB)
1089         MOVD    (g_sched+gobuf_sp)(g), R4 // prepare stack as R4
1090         MOVD    (g_sched+gobuf_pc)(g), R5
1091         MOVD    R5, -48(R4)
1092         MOVD    (g_sched+gobuf_bp)(g), R5
1093         MOVD    R5, -56(R4)
1094         // Gather our arguments into registers.
1095         MOVD    fn+0(FP), R1
1096         MOVD    frame+8(FP), R2
1097         MOVD    ctxt+16(FP), R3
1098         MOVD    $-48(R4), R0 // maintain 16-byte SP alignment
1099         MOVD    R0, RSP // switch stack
1100         MOVD    R1, 8(RSP)
1101         MOVD    R2, 16(RSP)
1102         MOVD    R3, 24(RSP)
1103         MOVD    $runtime·cgocallbackg(SB), R0
1104         CALL    (R0) // indirect call to bypass nosplit check. We're on a different stack now.
1105
1106         // Restore g->sched (== m->curg->sched) from saved values.
1107         MOVD    0(RSP), R5
1108         MOVD    R5, (g_sched+gobuf_pc)(g)
1109         MOVD    RSP, R4
1110         ADD     $48, R4, R4
1111         MOVD    R4, (g_sched+gobuf_sp)(g)
1112
1113         // Switch back to m->g0's stack and restore m->g0->sched.sp.
1114         // (Unlike m->curg, the g0 goroutine never uses sched.pc,
1115         // so we do not have to restore it.)
1116         MOVD    g_m(g), R8
1117         MOVD    m_g0(R8), g
1118         BL      runtime·save_g(SB)
1119         MOVD    (g_sched+gobuf_sp)(g), R0
1120         MOVD    R0, RSP
1121         MOVD    savedsp-16(SP), R4
1122         MOVD    R4, (g_sched+gobuf_sp)(g)
1123
1124         // If the m on entry was nil, we called needm above to borrow an m,
1125         // 1. for the duration of the call on non-pthread platforms,
1126         // 2. or the duration of the C thread alive on pthread platforms.
1127         // If the m on entry wasn't nil,
1128         // 1. the thread might be a Go thread,
1129         // 2. or it's wasn't the first call from a C thread on pthread platforms,
1130         //    since the we skip dropm to resue the m in the first call.
1131         MOVD    savedm-8(SP), R6
1132         CBNZ    R6, droppedm
1133
1134         // Skip dropm to reuse it in the next call, when a pthread key has been created.
1135         MOVD    _cgo_pthread_key_created(SB), R6
1136         // It means cgo is disabled when _cgo_pthread_key_created is a nil pointer, need dropm.
1137         CBZ     R6, dropm
1138         MOVD    (R6), R6
1139         CBNZ    R6, droppedm
1140
1141 dropm:
1142         MOVD    $runtime·dropm(SB), R0
1143         BL      (R0)
1144 droppedm:
1145
1146         // Done!
1147         RET
1148
1149 // Called from cgo wrappers, this function returns g->m->curg.stack.hi.
1150 // Must obey the gcc calling convention.
1151 TEXT _cgo_topofstack(SB),NOSPLIT,$24
1152         // g (R28) and REGTMP (R27)  might be clobbered by load_g. They
1153         // are callee-save in the gcc calling convention, so save them.
1154         MOVD    R27, savedR27-8(SP)
1155         MOVD    g, saveG-16(SP)
1156
1157         BL      runtime·load_g(SB)
1158         MOVD    g_m(g), R0
1159         MOVD    m_curg(R0), R0
1160         MOVD    (g_stack+stack_hi)(R0), R0
1161
1162         MOVD    saveG-16(SP), g
1163         MOVD    savedR28-8(SP), R27
1164         RET
1165
1166 // void setg(G*); set g. for use by needm.
1167 TEXT runtime·setg(SB), NOSPLIT, $0-8
1168         MOVD    gg+0(FP), g
1169         // This only happens if iscgo, so jump straight to save_g
1170         BL      runtime·save_g(SB)
1171         RET
1172
1173 // void setg_gcc(G*); set g called from gcc
1174 TEXT setg_gcc<>(SB),NOSPLIT,$8
1175         MOVD    R0, g
1176         MOVD    R27, savedR27-8(SP)
1177         BL      runtime·save_g(SB)
1178         MOVD    savedR27-8(SP), R27
1179         RET
1180
1181 TEXT runtime·emptyfunc(SB),0,$0-0
1182         RET
1183
1184 TEXT runtime·abort(SB),NOSPLIT|NOFRAME,$0-0
1185         MOVD    ZR, R0
1186         MOVD    (R0), R0
1187         UNDEF
1188
1189 TEXT runtime·return0(SB), NOSPLIT, $0
1190         MOVW    $0, R0
1191         RET
1192
1193 // The top-most function running on a goroutine
1194 // returns to goexit+PCQuantum.
1195 TEXT runtime·goexit(SB),NOSPLIT|NOFRAME|TOPFRAME,$0-0
1196         MOVD    R0, R0  // NOP
1197         BL      runtime·goexit1(SB)    // does not return
1198
1199 // This is called from .init_array and follows the platform, not Go, ABI.
1200 TEXT runtime·addmoduledata(SB),NOSPLIT,$0-0
1201         SUB     $0x10, RSP
1202         MOVD    R27, 8(RSP) // The access to global variables below implicitly uses R27, which is callee-save
1203         MOVD    runtime·lastmoduledatap(SB), R1
1204         MOVD    R0, moduledata_next(R1)
1205         MOVD    R0, runtime·lastmoduledatap(SB)
1206         MOVD    8(RSP), R27
1207         ADD     $0x10, RSP
1208         RET
1209
1210 TEXT ·checkASM(SB),NOSPLIT,$0-1
1211         MOVW    $1, R3
1212         MOVB    R3, ret+0(FP)
1213         RET
1214
1215 // gcWriteBarrier informs the GC about heap pointer writes.
1216 //
1217 // gcWriteBarrier does NOT follow the Go ABI. It accepts the
1218 // number of bytes of buffer needed in R25, and returns a pointer
1219 // to the buffer space in R25.
1220 // It clobbers condition codes.
1221 // It does not clobber any general-purpose registers except R27,
1222 // but may clobber others (e.g., floating point registers)
1223 // The act of CALLing gcWriteBarrier will clobber R30 (LR).
1224 TEXT gcWriteBarrier<>(SB),NOSPLIT,$200
1225         // Save the registers clobbered by the fast path.
1226         STP     (R0, R1), 184(RSP)
1227 retry:
1228         MOVD    g_m(g), R0
1229         MOVD    m_p(R0), R0
1230         MOVD    (p_wbBuf+wbBuf_next)(R0), R1
1231         MOVD    (p_wbBuf+wbBuf_end)(R0), R27
1232         // Increment wbBuf.next position.
1233         ADD     R25, R1
1234         // Is the buffer full?
1235         CMP     R27, R1
1236         BHI     flush
1237         // Commit to the larger buffer.
1238         MOVD    R1, (p_wbBuf+wbBuf_next)(R0)
1239         // Make return value (the original next position)
1240         SUB     R25, R1, R25
1241         // Restore registers.
1242         LDP     184(RSP), (R0, R1)
1243         RET
1244
1245 flush:
1246         // Save all general purpose registers since these could be
1247         // clobbered by wbBufFlush and were not saved by the caller.
1248         // R0 and R1 already saved
1249         STP     (R2, R3), 1*8(RSP)
1250         STP     (R4, R5), 3*8(RSP)
1251         STP     (R6, R7), 5*8(RSP)
1252         STP     (R8, R9), 7*8(RSP)
1253         STP     (R10, R11), 9*8(RSP)
1254         STP     (R12, R13), 11*8(RSP)
1255         STP     (R14, R15), 13*8(RSP)
1256         // R16, R17 may be clobbered by linker trampoline
1257         // R18 is unused.
1258         STP     (R19, R20), 15*8(RSP)
1259         STP     (R21, R22), 17*8(RSP)
1260         STP     (R23, R24), 19*8(RSP)
1261         STP     (R25, R26), 21*8(RSP)
1262         // R27 is temp register.
1263         // R28 is g.
1264         // R29 is frame pointer (unused).
1265         // R30 is LR, which was saved by the prologue.
1266         // R31 is SP.
1267
1268         CALL    runtime·wbBufFlush(SB)
1269         LDP     1*8(RSP), (R2, R3)
1270         LDP     3*8(RSP), (R4, R5)
1271         LDP     5*8(RSP), (R6, R7)
1272         LDP     7*8(RSP), (R8, R9)
1273         LDP     9*8(RSP), (R10, R11)
1274         LDP     11*8(RSP), (R12, R13)
1275         LDP     13*8(RSP), (R14, R15)
1276         LDP     15*8(RSP), (R19, R20)
1277         LDP     17*8(RSP), (R21, R22)
1278         LDP     19*8(RSP), (R23, R24)
1279         LDP     21*8(RSP), (R25, R26)
1280         JMP     retry
1281
1282 TEXT runtime·gcWriteBarrier1<ABIInternal>(SB),NOSPLIT,$0
1283         MOVD    $8, R25
1284         JMP     gcWriteBarrier<>(SB)
1285 TEXT runtime·gcWriteBarrier2<ABIInternal>(SB),NOSPLIT,$0
1286         MOVD    $16, R25
1287         JMP     gcWriteBarrier<>(SB)
1288 TEXT runtime·gcWriteBarrier3<ABIInternal>(SB),NOSPLIT,$0
1289         MOVD    $24, R25
1290         JMP     gcWriteBarrier<>(SB)
1291 TEXT runtime·gcWriteBarrier4<ABIInternal>(SB),NOSPLIT,$0
1292         MOVD    $32, R25
1293         JMP     gcWriteBarrier<>(SB)
1294 TEXT runtime·gcWriteBarrier5<ABIInternal>(SB),NOSPLIT,$0
1295         MOVD    $40, R25
1296         JMP     gcWriteBarrier<>(SB)
1297 TEXT runtime·gcWriteBarrier6<ABIInternal>(SB),NOSPLIT,$0
1298         MOVD    $48, R25
1299         JMP     gcWriteBarrier<>(SB)
1300 TEXT runtime·gcWriteBarrier7<ABIInternal>(SB),NOSPLIT,$0
1301         MOVD    $56, R25
1302         JMP     gcWriteBarrier<>(SB)
1303 TEXT runtime·gcWriteBarrier8<ABIInternal>(SB),NOSPLIT,$0
1304         MOVD    $64, R25
1305         JMP     gcWriteBarrier<>(SB)
1306
1307 DATA    debugCallFrameTooLarge<>+0x00(SB)/20, $"call frame too large"
1308 GLOBL   debugCallFrameTooLarge<>(SB), RODATA, $20       // Size duplicated below
1309
1310 // debugCallV2 is the entry point for debugger-injected function
1311 // calls on running goroutines. It informs the runtime that a
1312 // debug call has been injected and creates a call frame for the
1313 // debugger to fill in.
1314 //
1315 // To inject a function call, a debugger should:
1316 // 1. Check that the goroutine is in state _Grunning and that
1317 //    there are at least 288 bytes free on the stack.
1318 // 2. Set SP as SP-16.
1319 // 3. Store the current LR in (SP) (using the SP after step 2).
1320 // 4. Store the current PC in the LR register.
1321 // 5. Write the desired argument frame size at SP-16
1322 // 6. Save all machine registers (including flags and fpsimd registers)
1323 //    so they can be restored later by the debugger.
1324 // 7. Set the PC to debugCallV2 and resume execution.
1325 //
1326 // If the goroutine is in state _Grunnable, then it's not generally
1327 // safe to inject a call because it may return out via other runtime
1328 // operations. Instead, the debugger should unwind the stack to find
1329 // the return to non-runtime code, add a temporary breakpoint there,
1330 // and inject the call once that breakpoint is hit.
1331 //
1332 // If the goroutine is in any other state, it's not safe to inject a call.
1333 //
1334 // This function communicates back to the debugger by setting R20 and
1335 // invoking BRK to raise a breakpoint signal. Note that the signal PC of
1336 // the signal triggered by the BRK instruction is the PC where the signal
1337 // is trapped, not the next PC, so to resume execution, the debugger needs
1338 // to set the signal PC to PC+4. See the comments in the implementation for
1339 // the protocol the debugger is expected to follow. InjectDebugCall in the
1340 // runtime tests demonstrates this protocol.
1341 //
1342 // The debugger must ensure that any pointers passed to the function
1343 // obey escape analysis requirements. Specifically, it must not pass
1344 // a stack pointer to an escaping argument. debugCallV2 cannot check
1345 // this invariant.
1346 //
1347 // This is ABIInternal because Go code injects its PC directly into new
1348 // goroutine stacks.
1349 TEXT runtime·debugCallV2<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-0
1350         STP     (R29, R30), -280(RSP)
1351         SUB     $272, RSP, RSP
1352         SUB     $8, RSP, R29
1353         // Save all registers that may contain pointers so they can be
1354         // conservatively scanned.
1355         //
1356         // We can't do anything that might clobber any of these
1357         // registers before this.
1358         STP     (R27, g), (30*8)(RSP)
1359         STP     (R25, R26), (28*8)(RSP)
1360         STP     (R23, R24), (26*8)(RSP)
1361         STP     (R21, R22), (24*8)(RSP)
1362         STP     (R19, R20), (22*8)(RSP)
1363         STP     (R16, R17), (20*8)(RSP)
1364         STP     (R14, R15), (18*8)(RSP)
1365         STP     (R12, R13), (16*8)(RSP)
1366         STP     (R10, R11), (14*8)(RSP)
1367         STP     (R8, R9), (12*8)(RSP)
1368         STP     (R6, R7), (10*8)(RSP)
1369         STP     (R4, R5), (8*8)(RSP)
1370         STP     (R2, R3), (6*8)(RSP)
1371         STP     (R0, R1), (4*8)(RSP)
1372
1373         // Perform a safe-point check.
1374         MOVD    R30, 8(RSP) // Caller's PC
1375         CALL    runtime·debugCallCheck(SB)
1376         MOVD    16(RSP), R0
1377         CBZ     R0, good
1378
1379         // The safety check failed. Put the reason string at the top
1380         // of the stack.
1381         MOVD    R0, 8(RSP)
1382         MOVD    24(RSP), R0
1383         MOVD    R0, 16(RSP)
1384
1385         // Set R20 to 8 and invoke BRK. The debugger should get the
1386         // reason a call can't be injected from SP+8 and resume execution.
1387         MOVD    $8, R20
1388         BREAK
1389         JMP     restore
1390
1391 good:
1392         // Registers are saved and it's safe to make a call.
1393         // Open up a call frame, moving the stack if necessary.
1394         //
1395         // Once the frame is allocated, this will set R20 to 0 and
1396         // invoke BRK. The debugger should write the argument
1397         // frame for the call at SP+8, set up argument registers,
1398         // set the LR as the signal PC + 4, set the PC to the function
1399         // to call, set R26 to point to the closure (if a closure call),
1400         // and resume execution.
1401         //
1402         // If the function returns, this will set R20 to 1 and invoke
1403         // BRK. The debugger can then inspect any return value saved
1404         // on the stack at SP+8 and in registers. To resume execution,
1405         // the debugger should restore the LR from (SP).
1406         //
1407         // If the function panics, this will set R20 to 2 and invoke BRK.
1408         // The interface{} value of the panic will be at SP+8. The debugger
1409         // can inspect the panic value and resume execution again.
1410 #define DEBUG_CALL_DISPATCH(NAME,MAXSIZE)       \
1411         CMP     $MAXSIZE, R0;                   \
1412         BGT     5(PC);                          \
1413         MOVD    $NAME(SB), R0;                  \
1414         MOVD    R0, 8(RSP);                     \
1415         CALL    runtime·debugCallWrap(SB);     \
1416         JMP     restore
1417
1418         MOVD    256(RSP), R0 // the argument frame size
1419         DEBUG_CALL_DISPATCH(debugCall32<>, 32)
1420         DEBUG_CALL_DISPATCH(debugCall64<>, 64)
1421         DEBUG_CALL_DISPATCH(debugCall128<>, 128)
1422         DEBUG_CALL_DISPATCH(debugCall256<>, 256)
1423         DEBUG_CALL_DISPATCH(debugCall512<>, 512)
1424         DEBUG_CALL_DISPATCH(debugCall1024<>, 1024)
1425         DEBUG_CALL_DISPATCH(debugCall2048<>, 2048)
1426         DEBUG_CALL_DISPATCH(debugCall4096<>, 4096)
1427         DEBUG_CALL_DISPATCH(debugCall8192<>, 8192)
1428         DEBUG_CALL_DISPATCH(debugCall16384<>, 16384)
1429         DEBUG_CALL_DISPATCH(debugCall32768<>, 32768)
1430         DEBUG_CALL_DISPATCH(debugCall65536<>, 65536)
1431         // The frame size is too large. Report the error.
1432         MOVD    $debugCallFrameTooLarge<>(SB), R0
1433         MOVD    R0, 8(RSP)
1434         MOVD    $20, R0
1435         MOVD    R0, 16(RSP) // length of debugCallFrameTooLarge string
1436         MOVD    $8, R20
1437         BREAK
1438         JMP     restore
1439
1440 restore:
1441         // Calls and failures resume here.
1442         //
1443         // Set R20 to 16 and invoke BRK. The debugger should restore
1444         // all registers except for PC and RSP and resume execution.
1445         MOVD    $16, R20
1446         BREAK
1447         // We must not modify flags after this point.
1448
1449         // Restore pointer-containing registers, which may have been
1450         // modified from the debugger's copy by stack copying.
1451         LDP     (30*8)(RSP), (R27, g)
1452         LDP     (28*8)(RSP), (R25, R26)
1453         LDP     (26*8)(RSP), (R23, R24)
1454         LDP     (24*8)(RSP), (R21, R22)
1455         LDP     (22*8)(RSP), (R19, R20)
1456         LDP     (20*8)(RSP), (R16, R17)
1457         LDP     (18*8)(RSP), (R14, R15)
1458         LDP     (16*8)(RSP), (R12, R13)
1459         LDP     (14*8)(RSP), (R10, R11)
1460         LDP     (12*8)(RSP), (R8, R9)
1461         LDP     (10*8)(RSP), (R6, R7)
1462         LDP     (8*8)(RSP), (R4, R5)
1463         LDP     (6*8)(RSP), (R2, R3)
1464         LDP     (4*8)(RSP), (R0, R1)
1465
1466         LDP     -8(RSP), (R29, R27)
1467         ADD     $288, RSP, RSP // Add 16 more bytes, see saveSigContext
1468         MOVD    -16(RSP), R30 // restore old lr
1469         JMP     (R27)
1470
1471 // runtime.debugCallCheck assumes that functions defined with the
1472 // DEBUG_CALL_FN macro are safe points to inject calls.
1473 #define DEBUG_CALL_FN(NAME,MAXSIZE)             \
1474 TEXT NAME(SB),WRAPPER,$MAXSIZE-0;               \
1475         NO_LOCAL_POINTERS;              \
1476         MOVD    $0, R20;                \
1477         BREAK;          \
1478         MOVD    $1, R20;                \
1479         BREAK;          \
1480         RET
1481 DEBUG_CALL_FN(debugCall32<>, 32)
1482 DEBUG_CALL_FN(debugCall64<>, 64)
1483 DEBUG_CALL_FN(debugCall128<>, 128)
1484 DEBUG_CALL_FN(debugCall256<>, 256)
1485 DEBUG_CALL_FN(debugCall512<>, 512)
1486 DEBUG_CALL_FN(debugCall1024<>, 1024)
1487 DEBUG_CALL_FN(debugCall2048<>, 2048)
1488 DEBUG_CALL_FN(debugCall4096<>, 4096)
1489 DEBUG_CALL_FN(debugCall8192<>, 8192)
1490 DEBUG_CALL_FN(debugCall16384<>, 16384)
1491 DEBUG_CALL_FN(debugCall32768<>, 32768)
1492 DEBUG_CALL_FN(debugCall65536<>, 65536)
1493
1494 // func debugCallPanicked(val interface{})
1495 TEXT runtime·debugCallPanicked(SB),NOSPLIT,$16-16
1496         // Copy the panic value to the top of stack at SP+8.
1497         MOVD    val_type+0(FP), R0
1498         MOVD    R0, 8(RSP)
1499         MOVD    val_data+8(FP), R0
1500         MOVD    R0, 16(RSP)
1501         MOVD    $2, R20
1502         BREAK
1503         RET
1504
1505 // Note: these functions use a special calling convention to save generated code space.
1506 // Arguments are passed in registers, but the space for those arguments are allocated
1507 // in the caller's stack frame. These stubs write the args into that stack space and
1508 // then tail call to the corresponding runtime handler.
1509 // The tail call makes these stubs disappear in backtraces.
1510 //
1511 // Defined as ABIInternal since the compiler generates ABIInternal
1512 // calls to it directly and it does not use the stack-based Go ABI.
1513 TEXT runtime·panicIndex<ABIInternal>(SB),NOSPLIT,$0-16
1514         JMP     runtime·goPanicIndex<ABIInternal>(SB)
1515 TEXT runtime·panicIndexU<ABIInternal>(SB),NOSPLIT,$0-16
1516         JMP     runtime·goPanicIndexU<ABIInternal>(SB)
1517 TEXT runtime·panicSliceAlen<ABIInternal>(SB),NOSPLIT,$0-16
1518         MOVD    R1, R0
1519         MOVD    R2, R1
1520         JMP     runtime·goPanicSliceAlen<ABIInternal>(SB)
1521 TEXT runtime·panicSliceAlenU<ABIInternal>(SB),NOSPLIT,$0-16
1522         MOVD    R1, R0
1523         MOVD    R2, R1
1524         JMP     runtime·goPanicSliceAlenU<ABIInternal>(SB)
1525 TEXT runtime·panicSliceAcap<ABIInternal>(SB),NOSPLIT,$0-16
1526         MOVD    R1, R0
1527         MOVD    R2, R1
1528         JMP     runtime·goPanicSliceAcap<ABIInternal>(SB)
1529 TEXT runtime·panicSliceAcapU<ABIInternal>(SB),NOSPLIT,$0-16
1530         MOVD    R1, R0
1531         MOVD    R2, R1
1532         JMP     runtime·goPanicSliceAcapU<ABIInternal>(SB)
1533 TEXT runtime·panicSliceB<ABIInternal>(SB),NOSPLIT,$0-16
1534         JMP     runtime·goPanicSliceB<ABIInternal>(SB)
1535 TEXT runtime·panicSliceBU<ABIInternal>(SB),NOSPLIT,$0-16
1536         JMP     runtime·goPanicSliceBU<ABIInternal>(SB)
1537 TEXT runtime·panicSlice3Alen<ABIInternal>(SB),NOSPLIT,$0-16
1538         MOVD    R2, R0
1539         MOVD    R3, R1
1540         JMP     runtime·goPanicSlice3Alen<ABIInternal>(SB)
1541 TEXT runtime·panicSlice3AlenU<ABIInternal>(SB),NOSPLIT,$0-16
1542         MOVD    R2, R0
1543         MOVD    R3, R1
1544         JMP     runtime·goPanicSlice3AlenU<ABIInternal>(SB)
1545 TEXT runtime·panicSlice3Acap<ABIInternal>(SB),NOSPLIT,$0-16
1546         MOVD    R2, R0
1547         MOVD    R3, R1
1548         JMP     runtime·goPanicSlice3Acap<ABIInternal>(SB)
1549 TEXT runtime·panicSlice3AcapU<ABIInternal>(SB),NOSPLIT,$0-16
1550         MOVD    R2, R0
1551         MOVD    R3, R1
1552         JMP     runtime·goPanicSlice3AcapU<ABIInternal>(SB)
1553 TEXT runtime·panicSlice3B<ABIInternal>(SB),NOSPLIT,$0-16
1554         MOVD    R1, R0
1555         MOVD    R2, R1
1556         JMP     runtime·goPanicSlice3B<ABIInternal>(SB)
1557 TEXT runtime·panicSlice3BU<ABIInternal>(SB),NOSPLIT,$0-16
1558         MOVD    R1, R0
1559         MOVD    R2, R1
1560         JMP     runtime·goPanicSlice3BU<ABIInternal>(SB)
1561 TEXT runtime·panicSlice3C<ABIInternal>(SB),NOSPLIT,$0-16
1562         JMP     runtime·goPanicSlice3C<ABIInternal>(SB)
1563 TEXT runtime·panicSlice3CU<ABIInternal>(SB),NOSPLIT,$0-16
1564         JMP     runtime·goPanicSlice3CU<ABIInternal>(SB)
1565 TEXT runtime·panicSliceConvert<ABIInternal>(SB),NOSPLIT,$0-16
1566         MOVD    R2, R0
1567         MOVD    R3, R1
1568         JMP     runtime·goPanicSliceConvert<ABIInternal>(SB)
1569
1570 TEXT ·getcallerfp<ABIInternal>(SB),NOSPLIT|NOFRAME,$0
1571         MOVD R29, R0
1572         RET