Text file
src/runtime/sys_linux_arm.s
1 // Copyright 2009 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 //
6 // System calls and other sys.stuff for arm, Linux
7 //
8
9 #include "go_asm.h"
10 #include "go_tls.h"
11 #include "textflag.h"
12
13 #define CLOCK_REALTIME 0
14 #define CLOCK_MONOTONIC 1
15
16 // for EABI, as we don't support OABI
17 #define SYS_BASE 0x0
18
19 #define SYS_exit (SYS_BASE + 1)
20 #define SYS_read (SYS_BASE + 3)
21 #define SYS_write (SYS_BASE + 4)
22 #define SYS_open (SYS_BASE + 5)
23 #define SYS_close (SYS_BASE + 6)
24 #define SYS_getpid (SYS_BASE + 20)
25 #define SYS_kill (SYS_BASE + 37)
26 #define SYS_clone (SYS_BASE + 120)
27 #define SYS_rt_sigreturn (SYS_BASE + 173)
28 #define SYS_rt_sigaction (SYS_BASE + 174)
29 #define SYS_rt_sigprocmask (SYS_BASE + 175)
30 #define SYS_sigaltstack (SYS_BASE + 186)
31 #define SYS_mmap2 (SYS_BASE + 192)
32 #define SYS_futex (SYS_BASE + 240)
33 #define SYS_futex_time64 (SYS_BASE + 422)
34 #define SYS_exit_group (SYS_BASE + 248)
35 #define SYS_munmap (SYS_BASE + 91)
36 #define SYS_madvise (SYS_BASE + 220)
37 #define SYS_setitimer (SYS_BASE + 104)
38 #define SYS_mincore (SYS_BASE + 219)
39 #define SYS_gettid (SYS_BASE + 224)
40 #define SYS_tgkill (SYS_BASE + 268)
41 #define SYS_sched_yield (SYS_BASE + 158)
42 #define SYS_nanosleep (SYS_BASE + 162)
43 #define SYS_sched_getaffinity (SYS_BASE + 242)
44 #define SYS_clock_gettime (SYS_BASE + 263)
45 #define SYS_timer_create (SYS_BASE + 257)
46 #define SYS_timer_settime (SYS_BASE + 258)
47 #define SYS_timer_settime64 (SYS_BASE + 409)
48 #define SYS_timer_delete (SYS_BASE + 261)
49 #define SYS_pipe2 (SYS_BASE + 359)
50 #define SYS_access (SYS_BASE + 33)
51 #define SYS_connect (SYS_BASE + 283)
52 #define SYS_socket (SYS_BASE + 281)
53 #define SYS_brk (SYS_BASE + 45)
54
55 #define ARM_BASE (SYS_BASE + 0x0f0000)
56
57 TEXT runtime·open(SB),NOSPLIT,$0
58 MOVW name+0(FP), R0
59 MOVW mode+4(FP), R1
60 MOVW perm+8(FP), R2
61 MOVW $SYS_open, R7
62 SWI $0
63 MOVW $0xfffff001, R1
64 CMP R1, R0
65 MOVW.HI $-1, R0
66 MOVW R0, ret+12(FP)
67 RET
68
69 TEXT runtime·closefd(SB),NOSPLIT,$0
70 MOVW fd+0(FP), R0
71 MOVW $SYS_close, R7
72 SWI $0
73 MOVW $0xfffff001, R1
74 CMP R1, R0
75 MOVW.HI $-1, R0
76 MOVW R0, ret+4(FP)
77 RET
78
79 TEXT runtime·write1(SB),NOSPLIT,$0
80 MOVW fd+0(FP), R0
81 MOVW p+4(FP), R1
82 MOVW n+8(FP), R2
83 MOVW $SYS_write, R7
84 SWI $0
85 MOVW R0, ret+12(FP)
86 RET
87
88 TEXT runtime·read(SB),NOSPLIT,$0
89 MOVW fd+0(FP), R0
90 MOVW p+4(FP), R1
91 MOVW n+8(FP), R2
92 MOVW $SYS_read, R7
93 SWI $0
94 MOVW R0, ret+12(FP)
95 RET
96
97 // func pipe2(flags int32) (r, w int32, errno int32)
98 TEXT runtime·pipe2(SB),NOSPLIT,$0-16
99 MOVW $r+4(FP), R0
100 MOVW flags+0(FP), R1
101 MOVW $SYS_pipe2, R7
102 SWI $0
103 MOVW R0, errno+12(FP)
104 RET
105
106 TEXT runtime·exit(SB),NOSPLIT|NOFRAME,$0
107 MOVW code+0(FP), R0
108 MOVW $SYS_exit_group, R7
109 SWI $0
110 MOVW $1234, R0
111 MOVW $1002, R1
112 MOVW R0, (R1) // fail hard
113
114 TEXT exit1<>(SB),NOSPLIT|NOFRAME,$0
115 MOVW code+0(FP), R0
116 MOVW $SYS_exit, R7
117 SWI $0
118 MOVW $1234, R0
119 MOVW $1003, R1
120 MOVW R0, (R1) // fail hard
121
122 // func exitThread(wait *atomic.Uint32)
123 TEXT runtime·exitThread(SB),NOSPLIT|NOFRAME,$0-4
124 MOVW wait+0(FP), R0
125 // We're done using the stack.
126 // Alas, there's no reliable way to make this write atomic
127 // without potentially using the stack. So it goes.
128 MOVW $0, R1
129 MOVW R1, (R0)
130 MOVW $0, R0 // exit code
131 MOVW $SYS_exit, R7
132 SWI $0
133 MOVW $1234, R0
134 MOVW $1004, R1
135 MOVW R0, (R1) // fail hard
136 JMP 0(PC)
137
138 TEXT runtime·gettid(SB),NOSPLIT,$0-4
139 MOVW $SYS_gettid, R7
140 SWI $0
141 MOVW R0, ret+0(FP)
142 RET
143
144 TEXT runtime·raise(SB),NOSPLIT|NOFRAME,$0
145 MOVW $SYS_getpid, R7
146 SWI $0
147 MOVW R0, R4
148 MOVW $SYS_gettid, R7
149 SWI $0
150 MOVW R0, R1 // arg 2 tid
151 MOVW R4, R0 // arg 1 pid
152 MOVW sig+0(FP), R2 // arg 3
153 MOVW $SYS_tgkill, R7
154 SWI $0
155 RET
156
157 TEXT runtime·raiseproc(SB),NOSPLIT|NOFRAME,$0
158 MOVW $SYS_getpid, R7
159 SWI $0
160 // arg 1 tid already in R0 from getpid
161 MOVW sig+0(FP), R1 // arg 2 - signal
162 MOVW $SYS_kill, R7
163 SWI $0
164 RET
165
166 TEXT ·getpid(SB),NOSPLIT,$0-4
167 MOVW $SYS_getpid, R7
168 SWI $0
169 MOVW R0, ret+0(FP)
170 RET
171
172 TEXT ·tgkill(SB),NOSPLIT,$0-12
173 MOVW tgid+0(FP), R0
174 MOVW tid+4(FP), R1
175 MOVW sig+8(FP), R2
176 MOVW $SYS_tgkill, R7
177 SWI $0
178 RET
179
180 TEXT runtime·mmap(SB),NOSPLIT,$0
181 MOVW addr+0(FP), R0
182 MOVW n+4(FP), R1
183 MOVW prot+8(FP), R2
184 MOVW flags+12(FP), R3
185 MOVW fd+16(FP), R4
186 MOVW off+20(FP), R5
187 MOVW $SYS_mmap2, R7
188 SWI $0
189 MOVW $0xfffff001, R6
190 CMP R6, R0
191 MOVW $0, R1
192 RSB.HI $0, R0
193 MOVW.HI R0, R1 // if error, put in R1
194 MOVW.HI $0, R0
195 MOVW R0, p+24(FP)
196 MOVW R1, err+28(FP)
197 RET
198
199 TEXT runtime·munmap(SB),NOSPLIT,$0
200 MOVW addr+0(FP), R0
201 MOVW n+4(FP), R1
202 MOVW $SYS_munmap, R7
203 SWI $0
204 MOVW $0xfffff001, R6
205 CMP R6, R0
206 MOVW.HI $0, R8 // crash on syscall failure
207 MOVW.HI R8, (R8)
208 RET
209
210 TEXT runtime·madvise(SB),NOSPLIT,$0
211 MOVW addr+0(FP), R0
212 MOVW n+4(FP), R1
213 MOVW flags+8(FP), R2
214 MOVW $SYS_madvise, R7
215 SWI $0
216 MOVW R0, ret+12(FP)
217 RET
218
219 TEXT runtime·setitimer(SB),NOSPLIT,$0
220 MOVW mode+0(FP), R0
221 MOVW new+4(FP), R1
222 MOVW old+8(FP), R2
223 MOVW $SYS_setitimer, R7
224 SWI $0
225 RET
226
227 TEXT runtime·timer_create(SB),NOSPLIT,$0-16
228 MOVW clockid+0(FP), R0
229 MOVW sevp+4(FP), R1
230 MOVW timerid+8(FP), R2
231 MOVW $SYS_timer_create, R7
232 SWI $0
233 MOVW R0, ret+12(FP)
234 RET
235 // Linux: kernel/time/posix-timer.c, requiring COMPAT_32BIT_TIME.
236 TEXT runtime·timer_settime32(SB),NOSPLIT,$0-20
237 MOVW timerid+0(FP), R0
238 MOVW flags+4(FP), R1
239 MOVW new+8(FP), R2
240 MOVW old+12(FP), R3
241 MOVW $SYS_timer_settime, R7
242 SWI $0
243 MOVW R0, ret+16(FP)
244 RET
245
246 TEXT runtime·timer_settime64(SB),NOSPLIT,$0-20
247 MOVW timerid+0(FP), R0
248 MOVW flags+4(FP), R1
249 MOVW new+8(FP), R2
250 MOVW old+12(FP), R3
251 MOVW $SYS_timer_settime64, R7
252 SWI $0
253 MOVW R0, ret+16(FP)
254 RET
255
256 TEXT runtime·timer_delete(SB),NOSPLIT,$0-8
257 MOVW timerid+0(FP), R0
258 MOVW $SYS_timer_delete, R7
259 SWI $0
260 MOVW R0, ret+4(FP)
261 RET
262
263 TEXT runtime·mincore(SB),NOSPLIT,$0
264 MOVW addr+0(FP), R0
265 MOVW n+4(FP), R1
266 MOVW dst+8(FP), R2
267 MOVW $SYS_mincore, R7
268 SWI $0
269 MOVW R0, ret+12(FP)
270 RET
271
272 // Call a VDSO function.
273 //
274 // R0-R3: arguments to VDSO function (C calling convention)
275 // R4: uintptr function to call
276 //
277 // There is no return value.
278 TEXT runtime·vdsoCall(SB),NOSPLIT,$8-0
279 // R0-R3 may be arguments to fn, do not touch.
280 // R4 is function to call.
281 // R5-R9 are available as locals. They are unchanged by the C call
282 // (callee-save).
283
284 // We don't know how much stack space the VDSO code will need,
285 // so switch to g0.
286
287 // Save old SP. Use R13 instead of SP to avoid linker rewriting the offsets.
288 MOVW R13, R5
289
290 MOVW g_m(g), R6
291
292 // Set vdsoPC and vdsoSP for SIGPROF traceback.
293 // Save the old values on stack and restore them on exit,
294 // so this function is reentrant.
295 MOVW m_vdsoPC(R6), R7
296 MOVW m_vdsoSP(R6), R8
297 MOVW R7, 4(R13)
298 MOVW R8, 8(R13)
299
300 MOVW $sp-4(FP), R7 // caller's SP
301 MOVW LR, m_vdsoPC(R6)
302 MOVW R7, m_vdsoSP(R6)
303
304 MOVW m_curg(R6), R7
305
306 CMP g, R7 // Only switch if on curg.
307 B.NE noswitch
308
309 MOVW m_g0(R6), R7
310 MOVW (g_sched+gobuf_sp)(R7), R13 // Set SP to g0 stack
311
312 noswitch:
313 BIC $0x7, R13 // Align for C code
314
315 // Store g on gsignal's stack, so if we receive a signal
316 // during VDSO code we can find the g.
317
318 // When using cgo, we already saved g on TLS, also don't save g here.
319 MOVB runtime·iscgo(SB), R7
320 CMP $0, R7
321 BNE nosaveg
322 // If we don't have a signal stack, we won't receive signal, so don't
323 // bother saving g.
324 MOVW m_gsignal(R6), R7 // g.m.gsignal
325 CMP $0, R7
326 BEQ nosaveg
327 // Don't save g if we are already on the signal stack, as we won't get
328 // a nested signal.
329 CMP g, R7
330 BEQ nosaveg
331 // If we don't have a signal stack, we won't receive signal, so don't
332 // bother saving g.
333 MOVW (g_stack+stack_lo)(R7), R7 // g.m.gsignal.stack.lo
334 CMP $0, R7
335 BEQ nosaveg
336 MOVW g, (R7)
337
338 BL (R4)
339
340 MOVW $0, R8
341 MOVW R8, (R7) // clear g slot
342
343 JMP finish
344
345 nosaveg:
346 BL (R4)
347
348 finish:
349 MOVW R5, R13 // Restore real SP
350 // Restore vdsoPC, vdsoSP
351 // We don't worry about being signaled between the two stores.
352 // If we are not in a signal handler, we'll restore vdsoSP to 0,
353 // and no one will care about vdsoPC. If we are in a signal handler,
354 // we cannot receive another signal.
355 MOVW 8(R13), R7
356 MOVW R7, m_vdsoSP(R6)
357 MOVW 4(R13), R7
358 MOVW R7, m_vdsoPC(R6)
359 RET
360
361 TEXT runtime·walltime(SB),NOSPLIT,$12-12
362 MOVW $CLOCK_REALTIME, R0
363 MOVW $spec-12(SP), R1 // timespec
364
365 MOVW runtime·vdsoClockgettimeSym(SB), R4
366 CMP $0, R4
367 B.EQ fallback
368
369 BL runtime·vdsoCall(SB)
370
371 JMP finish
372
373 fallback:
374 MOVW $SYS_clock_gettime, R7
375 SWI $0
376
377 finish:
378 MOVW sec-12(SP), R0 // sec
379 MOVW nsec-8(SP), R2 // nsec
380
381 MOVW R0, sec_lo+0(FP)
382 MOVW $0, R1
383 MOVW R1, sec_hi+4(FP)
384 MOVW R2, nsec+8(FP)
385 RET
386
387 // func nanotime1() int64
388 TEXT runtime·nanotime1(SB),NOSPLIT,$12-8
389 MOVW $CLOCK_MONOTONIC, R0
390 MOVW $spec-12(SP), R1 // timespec
391
392 MOVW runtime·vdsoClockgettimeSym(SB), R4
393 CMP $0, R4
394 B.EQ fallback
395
396 BL runtime·vdsoCall(SB)
397
398 JMP finish
399
400 fallback:
401 MOVW $SYS_clock_gettime, R7
402 SWI $0
403
404 finish:
405 MOVW sec-12(SP), R0 // sec
406 MOVW nsec-8(SP), R2 // nsec
407
408 MOVW $1000000000, R3
409 MULLU R0, R3, (R1, R0)
410 ADD.S R2, R0
411 ADC $0, R1 // Add carry bit to upper half.
412
413 MOVW R0, ret_lo+0(FP)
414 MOVW R1, ret_hi+4(FP)
415
416 RET
417
418 // Linux: kernel/futex/syscalls.c, requiring COMPAT_32BIT_TIME
419 // int32 futex(int32 *uaddr, int32 op, int32 val,
420 // struct old_timespec32 *timeout, int32 *uaddr2, int32 val2);
421 TEXT runtime·futex_time32(SB),NOSPLIT,$0
422 MOVW addr+0(FP), R0
423 MOVW op+4(FP), R1
424 MOVW val+8(FP), R2
425 MOVW ts+12(FP), R3
426 MOVW addr2+16(FP), R4
427 MOVW val3+20(FP), R5
428 MOVW $SYS_futex, R7
429 SWI $0
430 MOVW R0, ret+24(FP)
431 RET
432
433 // Linux: kernel/futex/syscalls.c
434 // int32 futex(int32 *uaddr, int32 op, int32 val,
435 // struct timespec *timeout, int32 *uaddr2, int32 val2);
436 TEXT runtime·futex_time64(SB),NOSPLIT,$0
437 MOVW addr+0(FP), R0
438 MOVW op+4(FP), R1
439 MOVW val+8(FP), R2
440 MOVW ts+12(FP), R3
441 MOVW addr2+16(FP), R4
442 MOVW val3+20(FP), R5
443 MOVW $SYS_futex_time64, R7
444 SWI $0
445 MOVW R0, ret+24(FP)
446 RET
447
448 // int32 clone(int32 flags, void *stack, M *mp, G *gp, void (*fn)(void));
449 TEXT runtime·clone(SB),NOSPLIT,$0
450 MOVW flags+0(FP), R0
451 MOVW stk+4(FP), R1
452 MOVW $0, R2 // parent tid ptr
453 MOVW $0, R3 // tls_val
454 MOVW $0, R4 // child tid ptr
455 MOVW $0, R5
456
457 // Copy mp, gp, fn off parent stack for use by child.
458 MOVW $-16(R1), R1
459 MOVW mp+8(FP), R6
460 MOVW R6, 0(R1)
461 MOVW gp+12(FP), R6
462 MOVW R6, 4(R1)
463 MOVW fn+16(FP), R6
464 MOVW R6, 8(R1)
465 MOVW $1234, R6
466 MOVW R6, 12(R1)
467
468 MOVW $SYS_clone, R7
469 SWI $0
470
471 // In parent, return.
472 CMP $0, R0
473 BEQ 3(PC)
474 MOVW R0, ret+20(FP)
475 RET
476
477 // Paranoia: check that SP is as we expect. Use R13 to avoid linker 'fixup'
478 NOP R13 // tell vet SP/R13 changed - stop checking offsets
479 MOVW 12(R13), R0
480 MOVW $1234, R1
481 CMP R0, R1
482 BEQ 2(PC)
483 BL runtime·abort(SB)
484
485 MOVW 0(R13), R8 // m
486 MOVW 4(R13), R0 // g
487
488 CMP $0, R8
489 BEQ nog
490 CMP $0, R0
491 BEQ nog
492
493 MOVW R0, g
494 MOVW R8, g_m(g)
495
496 // paranoia; check they are not nil
497 MOVW 0(R8), R0
498 MOVW 0(g), R0
499
500 BL runtime·emptyfunc(SB) // fault if stack check is wrong
501
502 // Initialize m->procid to Linux tid
503 MOVW $SYS_gettid, R7
504 SWI $0
505 MOVW g_m(g), R8
506 MOVW R0, m_procid(R8)
507
508 nog:
509 // Call fn
510 MOVW 8(R13), R0
511 MOVW $16(R13), R13
512 BL (R0)
513
514 // It shouldn't return. If it does, exit that thread.
515 SUB $16, R13 // restore the stack pointer to avoid memory corruption
516 MOVW $0, R0
517 MOVW R0, 4(R13)
518 BL exit1<>(SB)
519
520 MOVW $1234, R0
521 MOVW $1005, R1
522 MOVW R0, (R1)
523
524 TEXT runtime·sigaltstack(SB),NOSPLIT,$0
525 MOVW new+0(FP), R0
526 MOVW old+4(FP), R1
527 MOVW $SYS_sigaltstack, R7
528 SWI $0
529 MOVW $0xfffff001, R6
530 CMP R6, R0
531 MOVW.HI $0, R8 // crash on syscall failure
532 MOVW.HI R8, (R8)
533 RET
534
535 TEXT runtime·sigfwd(SB),NOSPLIT,$0-16
536 MOVW sig+4(FP), R0
537 MOVW info+8(FP), R1
538 MOVW ctx+12(FP), R2
539 MOVW fn+0(FP), R11
540 MOVW R13, R4
541 SUB $24, R13
542 BIC $0x7, R13 // alignment for ELF ABI
543 BL (R11)
544 MOVW R4, R13
545 RET
546
547 TEXT runtime·sigtramp(SB),NOSPLIT|TOPFRAME,$0
548 // Reserve space for callee-save registers and arguments.
549 MOVM.DB.W [R4-R11], (R13)
550 SUB $16, R13
551
552 // this might be called in external code context,
553 // where g is not set.
554 // first save R0, because runtime·load_g will clobber it
555 MOVW R0, 4(R13)
556 MOVB runtime·iscgo(SB), R0
557 CMP $0, R0
558 BL.NE runtime·load_g(SB)
559
560 MOVW R1, 8(R13)
561 MOVW R2, 12(R13)
562 MOVW $runtime·sigtrampgo(SB), R11
563 BL (R11)
564
565 // Restore callee-save registers.
566 ADD $16, R13
567 MOVM.IA.W (R13), [R4-R11]
568
569 RET
570
571 TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
572 MOVW $runtime·sigtramp(SB), R11
573 B (R11)
574
575 TEXT runtime·rtsigprocmask(SB),NOSPLIT,$0
576 MOVW how+0(FP), R0
577 MOVW new+4(FP), R1
578 MOVW old+8(FP), R2
579 MOVW size+12(FP), R3
580 MOVW $SYS_rt_sigprocmask, R7
581 SWI $0
582 RET
583
584 TEXT runtime·rt_sigaction(SB),NOSPLIT,$0
585 MOVW sig+0(FP), R0
586 MOVW new+4(FP), R1
587 MOVW old+8(FP), R2
588 MOVW size+12(FP), R3
589 MOVW $SYS_rt_sigaction, R7
590 SWI $0
591 MOVW R0, ret+16(FP)
592 RET
593
594 TEXT runtime·usleep(SB),NOSPLIT,$12
595 MOVW usec+0(FP), R0
596 CALL runtime·usplitR0(SB)
597 MOVW R0, 4(R13)
598 MOVW $1000, R0 // usec to nsec
599 MUL R0, R1
600 MOVW R1, 8(R13)
601 MOVW $4(R13), R0
602 MOVW $0, R1
603 MOVW $SYS_nanosleep, R7
604 SWI $0
605 RET
606
607 // As for cas, memory barriers are complicated on ARM, but the kernel
608 // provides a user helper. ARMv5 does not support SMP and has no
609 // memory barrier instruction at all. ARMv6 added SMP support and has
610 // a memory barrier, but it requires writing to a coprocessor
611 // register. ARMv7 introduced the DMB instruction, but it's expensive
612 // even on single-core devices. The kernel helper takes care of all of
613 // this for us.
614
615 TEXT kernelPublicationBarrier<>(SB),NOSPLIT,$0
616 // void __kuser_memory_barrier(void);
617 MOVW $0xffff0fa0, R11
618 CALL (R11)
619 RET
620
621 TEXT ·publicationBarrier(SB),NOSPLIT,$0
622 MOVB ·goarm(SB), R11
623 CMP $7, R11
624 BLT 2(PC)
625 JMP ·armPublicationBarrier(SB)
626 JMP kernelPublicationBarrier<>(SB) // extra layer so this function is leaf and no SP adjustment on GOARM=7
627
628 TEXT runtime·osyield(SB),NOSPLIT,$0
629 MOVW $SYS_sched_yield, R7
630 SWI $0
631 RET
632
633 TEXT runtime·sched_getaffinity(SB),NOSPLIT,$0
634 MOVW pid+0(FP), R0
635 MOVW len+4(FP), R1
636 MOVW buf+8(FP), R2
637 MOVW $SYS_sched_getaffinity, R7
638 SWI $0
639 MOVW R0, ret+12(FP)
640 RET
641
642 // b __kuser_get_tls @ 0xffff0fe0
643 TEXT runtime·read_tls_fallback(SB),NOSPLIT|NOFRAME,$0
644 MOVW $0xffff0fe0, R0
645 B (R0)
646
647 TEXT runtime·access(SB),NOSPLIT,$0
648 MOVW name+0(FP), R0
649 MOVW mode+4(FP), R1
650 MOVW $SYS_access, R7
651 SWI $0
652 MOVW R0, ret+8(FP)
653 RET
654
655 TEXT runtime·connect(SB),NOSPLIT,$0
656 MOVW fd+0(FP), R0
657 MOVW addr+4(FP), R1
658 MOVW len+8(FP), R2
659 MOVW $SYS_connect, R7
660 SWI $0
661 MOVW R0, ret+12(FP)
662 RET
663
664 TEXT runtime·socket(SB),NOSPLIT,$0
665 MOVW domain+0(FP), R0
666 MOVW typ+4(FP), R1
667 MOVW prot+8(FP), R2
668 MOVW $SYS_socket, R7
669 SWI $0
670 MOVW R0, ret+12(FP)
671 RET
672
673 // func sbrk0() uintptr
674 TEXT runtime·sbrk0(SB),NOSPLIT,$0-4
675 // Implemented as brk(NULL).
676 MOVW $0, R0
677 MOVW $SYS_brk, R7
678 SWI $0
679 MOVW R0, ret+0(FP)
680 RET
681
View as plain text