github.com/akaros/go-akaros@v0.0.0-20181004170632-85005d477eab/src/runtime/asm_arm.s (about) 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 #include "zasm_GOOS_GOARCH.h" 6 #include "funcdata.h" 7 #include "textflag.h" 8 9 // using frame size $-4 means do not save LR on stack. 10 TEXT runtime·rt0_go(SB),NOSPLIT,$-4 11 MOVW $0xcafebabe, R12 12 13 // copy arguments forward on an even stack 14 // use R13 instead of SP to avoid linker rewriting the offsets 15 MOVW 0(R13), R0 // argc 16 MOVW 4(R13), R1 // argv 17 SUB $64, R13 // plenty of scratch 18 AND $~7, R13 19 MOVW R0, 60(R13) // save argc, argv away 20 MOVW R1, 64(R13) 21 22 // set up g register 23 // g is R10 24 MOVW $runtime·g0(SB), g 25 MOVW $runtime·m0(SB), R8 26 27 // save m->g0 = g0 28 MOVW g, m_g0(R8) 29 // save g->m = m0 30 MOVW R8, g_m(g) 31 32 // create istack out of the OS stack 33 MOVW $(-8192+104)(R13), R0 34 MOVW R0, g_stackguard0(g) 35 MOVW R0, g_stackguard1(g) 36 MOVW R0, (g_stack+stack_lo)(g) 37 MOVW R13, (g_stack+stack_hi)(g) 38 39 BL runtime·emptyfunc(SB) // fault if stack check is wrong 40 41 #ifndef GOOS_nacl 42 // if there is an _cgo_init, call it. 43 MOVW _cgo_init(SB), R4 44 CMP $0, R4 45 B.EQ nocgo 46 MRC 15, 0, R0, C13, C0, 3 // load TLS base pointer 47 MOVW R0, R3 // arg 3: TLS base pointer 48 MOVW $runtime·tlsg(SB), R2 // arg 2: tlsg 49 MOVW $setg_gcc<>(SB), R1 // arg 1: setg 50 MOVW g, R0 // arg 0: G 51 BL (R4) // will clobber R0-R3 52 #endif 53 54 nocgo: 55 // update stackguard after _cgo_init 56 MOVW (g_stack+stack_lo)(g), R0 57 ADD $const_StackGuard, R0 58 MOVW R0, g_stackguard0(g) 59 MOVW R0, g_stackguard1(g) 60 61 BL runtime·checkgoarm(SB) 62 BL runtime·check(SB) 63 64 // saved argc, argv 65 MOVW 60(R13), R0 66 MOVW R0, 4(R13) 67 MOVW 64(R13), R1 68 MOVW R1, 8(R13) 69 BL runtime·args(SB) 70 BL runtime·osinit(SB) 71 BL runtime·schedinit(SB) 72 73 // create a new goroutine to start program 74 MOVW $runtime·main·f(SB), R0 75 MOVW.W R0, -4(R13) 76 MOVW $8, R0 77 MOVW.W R0, -4(R13) 78 MOVW $0, R0 79 MOVW.W R0, -4(R13) // push $0 as guard 80 BL runtime·newproc(SB) 81 MOVW $12(R13), R13 // pop args and LR 82 83 // start this M 84 BL runtime·mstart(SB) 85 86 MOVW $1234, R0 87 MOVW $1000, R1 88 MOVW R0, (R1) // fail hard 89 90 DATA runtime·main·f+0(SB)/4,$runtime·main(SB) 91 GLOBL runtime·main·f(SB),RODATA,$4 92 93 TEXT runtime·breakpoint(SB),NOSPLIT,$0-0 94 // gdb won't skip this breakpoint instruction automatically, 95 // so you must manually "set $pc+=4" to skip it and continue. 96 #ifdef GOOS_nacl 97 WORD $0xe125be7f // BKPT 0x5bef, NACL_INSTR_ARM_BREAKPOINT 98 #else 99 WORD $0xe7f001f0 // undefined instruction that gdb understands is a software breakpoint 100 #endif 101 RET 102 103 TEXT runtime·asminit(SB),NOSPLIT,$0-0 104 // disable runfast (flush-to-zero) mode of vfp if runtime.goarm > 5 105 MOVB runtime·goarm(SB), R11 106 CMP $5, R11 107 BLE 4(PC) 108 WORD $0xeef1ba10 // vmrs r11, fpscr 109 BIC $(1<<24), R11 110 WORD $0xeee1ba10 // vmsr fpscr, r11 111 RET 112 113 /* 114 * go-routine 115 */ 116 117 // void gosave(Gobuf*) 118 // save state in Gobuf; setjmp 119 TEXT runtime·gosave(SB),NOSPLIT,$-4-4 120 MOVW 0(FP), R0 // gobuf 121 MOVW SP, gobuf_sp(R0) 122 MOVW LR, gobuf_pc(R0) 123 MOVW g, gobuf_g(R0) 124 MOVW $0, R11 125 MOVW R11, gobuf_lr(R0) 126 MOVW R11, gobuf_ret(R0) 127 MOVW R11, gobuf_ctxt(R0) 128 RET 129 130 // void gogo(Gobuf*) 131 // restore state from Gobuf; longjmp 132 TEXT runtime·gogo(SB),NOSPLIT,$-4-4 133 MOVW 0(FP), R1 // gobuf 134 MOVW gobuf_g(R1), R0 135 BL setg<>(SB) 136 137 // NOTE: We updated g above, and we are about to update SP. 138 // Until LR and PC are also updated, the g/SP/LR/PC quadruple 139 // are out of sync and must not be used as the basis of a traceback. 140 // Sigprof skips the traceback when SP is not within g's bounds, 141 // and when the PC is inside this function, runtime.gogo. 142 // Since we are about to update SP, until we complete runtime.gogo 143 // we must not leave this function. In particular, no calls 144 // after this point: it must be straight-line code until the 145 // final B instruction. 146 // See large comment in sigprof for more details. 147 MOVW gobuf_sp(R1), SP // restore SP 148 MOVW gobuf_lr(R1), LR 149 MOVW gobuf_ret(R1), R0 150 MOVW gobuf_ctxt(R1), R7 151 MOVW $0, R11 152 MOVW R11, gobuf_sp(R1) // clear to help garbage collector 153 MOVW R11, gobuf_ret(R1) 154 MOVW R11, gobuf_lr(R1) 155 MOVW R11, gobuf_ctxt(R1) 156 MOVW gobuf_pc(R1), R11 157 CMP R11, R11 // set condition codes for == test, needed by stack split 158 B (R11) 159 160 // func mcall(fn func(*g)) 161 // Switch to m->g0's stack, call fn(g). 162 // Fn must never return. It should gogo(&g->sched) 163 // to keep running g. 164 TEXT runtime·mcall(SB),NOSPLIT,$-4-4 165 // Save caller state in g->sched. 166 MOVW SP, (g_sched+gobuf_sp)(g) 167 MOVW LR, (g_sched+gobuf_pc)(g) 168 MOVW $0, R11 169 MOVW R11, (g_sched+gobuf_lr)(g) 170 MOVW g, (g_sched+gobuf_g)(g) 171 172 // Switch to m->g0 & its stack, call fn. 173 MOVW g, R1 174 MOVW g_m(g), R8 175 MOVW m_g0(R8), R0 176 BL setg<>(SB) 177 CMP g, R1 178 B.NE 2(PC) 179 B runtime·badmcall(SB) 180 MOVB runtime·iscgo(SB), R11 181 CMP $0, R11 182 BL.NE runtime·save_g(SB) 183 MOVW fn+0(FP), R0 184 MOVW (g_sched+gobuf_sp)(g), SP 185 SUB $8, SP 186 MOVW R1, 4(SP) 187 MOVW R0, R7 188 MOVW 0(R0), R0 189 BL (R0) 190 B runtime·badmcall2(SB) 191 RET 192 193 // switchtoM is a dummy routine that onM leaves at the bottom 194 // of the G stack. We need to distinguish the routine that 195 // lives at the bottom of the G stack from the one that lives 196 // at the top of the M stack because the one at the top of 197 // the M stack terminates the stack walk (see topofstack()). 198 TEXT runtime·switchtoM(SB),NOSPLIT,$0-0 199 MOVW $0, R0 200 BL (R0) // clobber lr to ensure push {lr} is kept 201 RET 202 203 // func onM_signalok(fn func()) 204 TEXT runtime·onM_signalok(SB), NOSPLIT, $-4-4 205 MOVW g_m(g), R1 206 MOVW m_gsignal(R1), R2 207 CMP g, R2 208 B.EQ ongsignal 209 B runtime·onM(SB) 210 211 ongsignal: 212 MOVW fn+0(FP), R0 213 MOVW R0, R7 214 MOVW 0(R0), R0 215 BL (R0) 216 RET 217 218 // func onM(fn func()) 219 TEXT runtime·onM(SB),NOSPLIT,$0-4 220 MOVW fn+0(FP), R0 // R0 = fn 221 MOVW g_m(g), R1 // R1 = m 222 223 MOVW m_g0(R1), R2 // R2 = g0 224 CMP g, R2 225 B.EQ onm 226 227 MOVW m_curg(R1), R3 228 CMP g, R3 229 B.EQ oncurg 230 231 // Not g0, not curg. Must be gsignal, but that's not allowed. 232 // Hide call from linker nosplit analysis. 233 MOVW $runtime·badonm(SB), R0 234 BL (R0) 235 236 oncurg: 237 // save our state in g->sched. Pretend to 238 // be switchtoM if the G stack is scanned. 239 MOVW $runtime·switchtoM(SB), R3 240 ADD $4, R3, R3 // get past push {lr} 241 MOVW R3, (g_sched+gobuf_pc)(g) 242 MOVW SP, (g_sched+gobuf_sp)(g) 243 MOVW LR, (g_sched+gobuf_lr)(g) 244 MOVW g, (g_sched+gobuf_g)(g) 245 246 // switch to g0 247 MOVW R0, R5 248 MOVW R2, R0 249 BL setg<>(SB) 250 MOVW R5, R0 251 MOVW (g_sched+gobuf_sp)(R2), R3 252 // make it look like mstart called onM on g0, to stop traceback 253 SUB $4, R3, R3 254 MOVW $runtime·mstart(SB), R4 255 MOVW R4, 0(R3) 256 MOVW R3, SP 257 258 // call target function 259 MOVW R0, R7 260 MOVW 0(R0), R0 261 BL (R0) 262 263 // switch back to g 264 MOVW g_m(g), R1 265 MOVW m_curg(R1), R0 266 BL setg<>(SB) 267 MOVW (g_sched+gobuf_sp)(g), SP 268 MOVW $0, R3 269 MOVW R3, (g_sched+gobuf_sp)(g) 270 RET 271 272 onm: 273 MOVW R0, R7 274 MOVW 0(R0), R0 275 BL (R0) 276 RET 277 278 /* 279 * support for morestack 280 */ 281 282 // Called during function prolog when more stack is needed. 283 // R1 frame size 284 // R2 arg size 285 // R3 prolog's LR 286 // NB. we do not save R0 because we've forced 5c to pass all arguments 287 // on the stack. 288 // using frame size $-4 means do not save LR on stack. 289 // 290 // The traceback routines see morestack on a g0 as being 291 // the top of a stack (for example, morestack calling newstack 292 // calling the scheduler calling newm calling gc), so we must 293 // record an argument size. For that purpose, it has no arguments. 294 TEXT runtime·morestack(SB),NOSPLIT,$-4-0 295 // Cannot grow scheduler stack (m->g0). 296 MOVW g_m(g), R8 297 MOVW m_g0(R8), R4 298 CMP g, R4 299 BL.EQ runtime·abort(SB) 300 301 // Cannot grow signal stack (m->gsignal). 302 MOVW m_gsignal(R8), R4 303 CMP g, R4 304 BL.EQ runtime·abort(SB) 305 306 // Called from f. 307 // Set g->sched to context in f. 308 MOVW R7, (g_sched+gobuf_ctxt)(g) 309 MOVW SP, (g_sched+gobuf_sp)(g) 310 MOVW LR, (g_sched+gobuf_pc)(g) 311 MOVW R3, (g_sched+gobuf_lr)(g) 312 313 // Called from f. 314 // Set m->morebuf to f's caller. 315 MOVW R3, (m_morebuf+gobuf_pc)(R8) // f's caller's PC 316 MOVW SP, (m_morebuf+gobuf_sp)(R8) // f's caller's SP 317 MOVW $4(SP), R3 // f's argument pointer 318 MOVW g, (m_morebuf+gobuf_g)(R8) 319 320 // Call newstack on m->g0's stack. 321 MOVW m_g0(R8), R0 322 BL setg<>(SB) 323 MOVW (g_sched+gobuf_sp)(g), SP 324 BL runtime·newstack(SB) 325 326 // Not reached, but make sure the return PC from the call to newstack 327 // is still in this function, and not the beginning of the next. 328 RET 329 330 TEXT runtime·morestack_noctxt(SB),NOSPLIT,$-4-0 331 MOVW $0, R7 332 B runtime·morestack(SB) 333 334 // reflectcall: call a function with the given argument list 335 // func call(f *FuncVal, arg *byte, argsize, retoffset uint32). 336 // we don't have variable-sized frames, so we use a small number 337 // of constant-sized-frame functions to encode a few bits of size in the pc. 338 // Caution: ugly multiline assembly macros in your future! 339 340 #define DISPATCH(NAME,MAXSIZE) \ 341 CMP $MAXSIZE, R0; \ 342 B.HI 3(PC); \ 343 MOVW $NAME(SB), R1; \ 344 B (R1) 345 346 TEXT ·reflectcall(SB),NOSPLIT,$-4-16 347 MOVW argsize+8(FP), R0 348 DISPATCH(runtime·call16, 16) 349 DISPATCH(runtime·call32, 32) 350 DISPATCH(runtime·call64, 64) 351 DISPATCH(runtime·call128, 128) 352 DISPATCH(runtime·call256, 256) 353 DISPATCH(runtime·call512, 512) 354 DISPATCH(runtime·call1024, 1024) 355 DISPATCH(runtime·call2048, 2048) 356 DISPATCH(runtime·call4096, 4096) 357 DISPATCH(runtime·call8192, 8192) 358 DISPATCH(runtime·call16384, 16384) 359 DISPATCH(runtime·call32768, 32768) 360 DISPATCH(runtime·call65536, 65536) 361 DISPATCH(runtime·call131072, 131072) 362 DISPATCH(runtime·call262144, 262144) 363 DISPATCH(runtime·call524288, 524288) 364 DISPATCH(runtime·call1048576, 1048576) 365 DISPATCH(runtime·call2097152, 2097152) 366 DISPATCH(runtime·call4194304, 4194304) 367 DISPATCH(runtime·call8388608, 8388608) 368 DISPATCH(runtime·call16777216, 16777216) 369 DISPATCH(runtime·call33554432, 33554432) 370 DISPATCH(runtime·call67108864, 67108864) 371 DISPATCH(runtime·call134217728, 134217728) 372 DISPATCH(runtime·call268435456, 268435456) 373 DISPATCH(runtime·call536870912, 536870912) 374 DISPATCH(runtime·call1073741824, 1073741824) 375 MOVW $runtime·badreflectcall(SB), R1 376 B (R1) 377 378 #define CALLFN(NAME,MAXSIZE) \ 379 TEXT NAME(SB), WRAPPER, $MAXSIZE-16; \ 380 NO_LOCAL_POINTERS; \ 381 /* copy arguments to stack */ \ 382 MOVW argptr+4(FP), R0; \ 383 MOVW argsize+8(FP), R2; \ 384 ADD $4, SP, R1; \ 385 CMP $0, R2; \ 386 B.EQ 5(PC); \ 387 MOVBU.P 1(R0), R5; \ 388 MOVBU.P R5, 1(R1); \ 389 SUB $1, R2, R2; \ 390 B -5(PC); \ 391 /* call function */ \ 392 MOVW f+0(FP), R7; \ 393 MOVW (R7), R0; \ 394 PCDATA $PCDATA_StackMapIndex, $0; \ 395 BL (R0); \ 396 /* copy return values back */ \ 397 MOVW argptr+4(FP), R0; \ 398 MOVW argsize+8(FP), R2; \ 399 MOVW retoffset+12(FP), R3; \ 400 ADD $4, SP, R1; \ 401 ADD R3, R1; \ 402 ADD R3, R0; \ 403 SUB R3, R2; \ 404 CMP $0, R2; \ 405 RET.EQ ; \ 406 MOVBU.P 1(R1), R5; \ 407 MOVBU.P R5, 1(R0); \ 408 SUB $1, R2, R2; \ 409 B -5(PC) \ 410 411 CALLFN(·call16, 16) 412 CALLFN(·call32, 32) 413 CALLFN(·call64, 64) 414 CALLFN(·call128, 128) 415 CALLFN(·call256, 256) 416 CALLFN(·call512, 512) 417 CALLFN(·call1024, 1024) 418 CALLFN(·call2048, 2048) 419 CALLFN(·call4096, 4096) 420 CALLFN(·call8192, 8192) 421 CALLFN(·call16384, 16384) 422 CALLFN(·call32768, 32768) 423 CALLFN(·call65536, 65536) 424 CALLFN(·call131072, 131072) 425 CALLFN(·call262144, 262144) 426 CALLFN(·call524288, 524288) 427 CALLFN(·call1048576, 1048576) 428 CALLFN(·call2097152, 2097152) 429 CALLFN(·call4194304, 4194304) 430 CALLFN(·call8388608, 8388608) 431 CALLFN(·call16777216, 16777216) 432 CALLFN(·call33554432, 33554432) 433 CALLFN(·call67108864, 67108864) 434 CALLFN(·call134217728, 134217728) 435 CALLFN(·call268435456, 268435456) 436 CALLFN(·call536870912, 536870912) 437 CALLFN(·call1073741824, 1073741824) 438 439 // void jmpdefer(fn, sp); 440 // called from deferreturn. 441 // 1. grab stored LR for caller 442 // 2. sub 4 bytes to get back to BL deferreturn 443 // 3. B to fn 444 // TODO(rsc): Push things on stack and then use pop 445 // to load all registers simultaneously, so that a profiling 446 // interrupt can never see mismatched SP/LR/PC. 447 // (And double-check that pop is atomic in that way.) 448 TEXT runtime·jmpdefer(SB),NOSPLIT,$0-8 449 MOVW 0(SP), LR 450 MOVW $-4(LR), LR // BL deferreturn 451 MOVW fv+0(FP), R7 452 MOVW argp+4(FP), SP 453 MOVW $-4(SP), SP // SP is 4 below argp, due to saved LR 454 MOVW 0(R7), R1 455 B (R1) 456 457 // Save state of caller into g->sched. Smashes R11. 458 TEXT gosave<>(SB),NOSPLIT,$0 459 MOVW LR, (g_sched+gobuf_pc)(g) 460 MOVW R13, (g_sched+gobuf_sp)(g) 461 MOVW $0, R11 462 MOVW R11, (g_sched+gobuf_lr)(g) 463 MOVW R11, (g_sched+gobuf_ret)(g) 464 MOVW R11, (g_sched+gobuf_ctxt)(g) 465 RET 466 467 // asmcgocall(void(*fn)(void*), void *arg) 468 // Call fn(arg) on the scheduler stack, 469 // aligned appropriately for the gcc ABI. 470 // See cgocall.c for more details. 471 TEXT ·asmcgocall(SB),NOSPLIT,$0-8 472 MOVW fn+0(FP), R1 473 MOVW arg+4(FP), R0 474 BL asmcgocall<>(SB) 475 RET 476 477 TEXT ·asmcgocall_errno(SB),NOSPLIT,$0-12 478 MOVW fn+0(FP), R1 479 MOVW arg+4(FP), R0 480 BL asmcgocall<>(SB) 481 MOVW R0, ret+8(FP) 482 RET 483 484 TEXT asmcgocall<>(SB),NOSPLIT,$0-0 485 // fn in R1, arg in R0. 486 MOVW R13, R2 487 MOVW g, R4 488 489 // Figure out if we need to switch to m->g0 stack. 490 // We get called to create new OS threads too, and those 491 // come in on the m->g0 stack already. 492 MOVW g_m(g), R8 493 MOVW m_g0(R8), R3 494 CMP R3, g 495 BEQ asmcgocall_g0 496 BL gosave<>(SB) 497 MOVW R0, R5 498 MOVW R3, R0 499 BL setg<>(SB) 500 MOVW R5, R0 501 MOVW (g_sched+gobuf_sp)(g), R13 502 503 // Now on a scheduling stack (a pthread-created stack). 504 asmcgocall_g0: 505 SUB $24, R13 506 BIC $0x7, R13 // alignment for gcc ABI 507 MOVW R4, 20(R13) // save old g 508 MOVW (g_stack+stack_hi)(R4), R4 509 SUB R2, R4 510 MOVW R4, 16(R13) // save depth in stack (can't just save SP, as stack might be copied during a callback) 511 BL (R1) 512 513 // Restore registers, g, stack pointer. 514 MOVW R0, R5 515 MOVW 20(R13), R0 516 BL setg<>(SB) 517 MOVW (g_stack+stack_hi)(g), R1 518 MOVW 16(R13), R2 519 SUB R2, R1 520 MOVW R5, R0 521 MOVW R1, R13 522 RET 523 524 // cgocallback(void (*fn)(void*), void *frame, uintptr framesize) 525 // Turn the fn into a Go func (by taking its address) and call 526 // cgocallback_gofunc. 527 TEXT runtime·cgocallback(SB),NOSPLIT,$12-12 528 MOVW $fn+0(FP), R0 529 MOVW R0, 4(R13) 530 MOVW frame+4(FP), R0 531 MOVW R0, 8(R13) 532 MOVW framesize+8(FP), R0 533 MOVW R0, 12(R13) 534 MOVW $runtime·cgocallback_gofunc(SB), R0 535 BL (R0) 536 RET 537 538 // cgocallback_gofunc(void (*fn)(void*), void *frame, uintptr framesize) 539 // See cgocall.c for more details. 540 TEXT ·cgocallback_gofunc(SB),NOSPLIT,$8-12 541 NO_LOCAL_POINTERS 542 543 // Load m and g from thread-local storage. 544 MOVB runtime·iscgo(SB), R0 545 CMP $0, R0 546 BL.NE runtime·load_g(SB) 547 548 // If g is nil, Go did not create the current thread. 549 // Call needm to obtain one for temporary use. 550 // In this case, we're running on the thread stack, so there's 551 // lots of space, but the linker doesn't know. Hide the call from 552 // the linker analysis by using an indirect call. 553 CMP $0, g 554 B.NE havem 555 MOVW g, savedm-4(SP) // g is zero, so is m. 556 MOVW $runtime·needm(SB), R0 557 BL (R0) 558 559 // Set m->sched.sp = SP, so that if a panic happens 560 // during the function we are about to execute, it will 561 // have a valid SP to run on the g0 stack. 562 // The next few lines (after the havem label) 563 // will save this SP onto the stack and then write 564 // the same SP back to m->sched.sp. That seems redundant, 565 // but if an unrecovered panic happens, unwindm will 566 // restore the g->sched.sp from the stack location 567 // and then onM will try to use it. If we don't set it here, 568 // that restored SP will be uninitialized (typically 0) and 569 // will not be usable. 570 MOVW g_m(g), R8 571 MOVW m_g0(R8), R3 572 MOVW R13, (g_sched+gobuf_sp)(R3) 573 574 havem: 575 MOVW g_m(g), R8 576 MOVW R8, savedm-4(SP) 577 // Now there's a valid m, and we're running on its m->g0. 578 // Save current m->g0->sched.sp on stack and then set it to SP. 579 // Save current sp in m->g0->sched.sp in preparation for 580 // switch back to m->curg stack. 581 // NOTE: unwindm knows that the saved g->sched.sp is at 4(R13) aka savedsp-8(SP). 582 MOVW m_g0(R8), R3 583 MOVW (g_sched+gobuf_sp)(R3), R4 584 MOVW R4, savedsp-8(SP) 585 MOVW R13, (g_sched+gobuf_sp)(R3) 586 587 // Switch to m->curg stack and call runtime.cgocallbackg. 588 // Because we are taking over the execution of m->curg 589 // but *not* resuming what had been running, we need to 590 // save that information (m->curg->sched) so we can restore it. 591 // We can restore m->curg->sched.sp easily, because calling 592 // runtime.cgocallbackg leaves SP unchanged upon return. 593 // To save m->curg->sched.pc, we push it onto the stack. 594 // This has the added benefit that it looks to the traceback 595 // routine like cgocallbackg is going to return to that 596 // PC (because the frame we allocate below has the same 597 // size as cgocallback_gofunc's frame declared above) 598 // so that the traceback will seamlessly trace back into 599 // the earlier calls. 600 // 601 // In the new goroutine, -8(SP) and -4(SP) are unused. 602 MOVW m_curg(R8), R0 603 BL setg<>(SB) 604 MOVW (g_sched+gobuf_sp)(g), R4 // prepare stack as R4 605 MOVW (g_sched+gobuf_pc)(g), R5 606 MOVW R5, -12(R4) 607 MOVW $-12(R4), R13 608 BL runtime·cgocallbackg(SB) 609 610 // Restore g->sched (== m->curg->sched) from saved values. 611 MOVW 0(R13), R5 612 MOVW R5, (g_sched+gobuf_pc)(g) 613 MOVW $12(R13), R4 614 MOVW R4, (g_sched+gobuf_sp)(g) 615 616 // Switch back to m->g0's stack and restore m->g0->sched.sp. 617 // (Unlike m->curg, the g0 goroutine never uses sched.pc, 618 // so we do not have to restore it.) 619 MOVW g_m(g), R8 620 MOVW m_g0(R8), R0 621 BL setg<>(SB) 622 MOVW (g_sched+gobuf_sp)(g), R13 623 MOVW savedsp-8(SP), R4 624 MOVW R4, (g_sched+gobuf_sp)(g) 625 626 // If the m on entry was nil, we called needm above to borrow an m 627 // for the duration of the call. Since the call is over, return it with dropm. 628 MOVW savedm-4(SP), R6 629 CMP $0, R6 630 B.NE 3(PC) 631 MOVW $runtime·dropm(SB), R0 632 BL (R0) 633 634 // Done! 635 RET 636 637 // void setg(G*); set g. for use by needm. 638 TEXT runtime·setg(SB),NOSPLIT,$-4-4 639 MOVW gg+0(FP), R0 640 B setg<>(SB) 641 642 TEXT setg<>(SB),NOSPLIT,$-4-0 643 MOVW R0, g 644 645 // Save g to thread-local storage. 646 MOVB runtime·iscgo(SB), R0 647 CMP $0, R0 648 B.EQ 2(PC) 649 B runtime·save_g(SB) 650 651 MOVW g, R0 652 RET 653 654 TEXT runtime·getcallerpc(SB),NOSPLIT,$-4-4 655 MOVW 0(SP), R0 656 MOVW R0, ret+4(FP) 657 RET 658 659 TEXT runtime·gogetcallerpc(SB),NOSPLIT,$-4-8 660 MOVW R14, ret+4(FP) 661 RET 662 663 TEXT runtime·setcallerpc(SB),NOSPLIT,$-4-8 664 MOVW pc+4(FP), R0 665 MOVW R0, 0(SP) 666 RET 667 668 TEXT runtime·getcallersp(SB),NOSPLIT,$-4-4 669 MOVW 0(FP), R0 670 MOVW $-4(R0), R0 671 MOVW R0, ret+4(FP) 672 RET 673 674 // func gogetcallersp(p unsafe.Pointer) uintptr 675 TEXT runtime·gogetcallersp(SB),NOSPLIT,$-4-8 676 MOVW 0(FP), R0 677 MOVW $-4(R0), R0 678 MOVW R0, ret+4(FP) 679 RET 680 681 TEXT runtime·emptyfunc(SB),0,$0-0 682 RET 683 684 TEXT runtime·abort(SB),NOSPLIT,$-4-0 685 MOVW $0, R0 686 MOVW (R0), R1 687 688 // bool armcas(int32 *val, int32 old, int32 new) 689 // Atomically: 690 // if(*val == old){ 691 // *val = new; 692 // return 1; 693 // }else 694 // return 0; 695 // 696 // To implement runtime·cas in sys_$GOOS_arm.s 697 // using the native instructions, use: 698 // 699 // TEXT runtime·cas(SB),NOSPLIT,$0 700 // B runtime·armcas(SB) 701 // 702 TEXT runtime·armcas(SB),NOSPLIT,$0-13 703 MOVW valptr+0(FP), R1 704 MOVW old+4(FP), R2 705 MOVW new+8(FP), R3 706 casl: 707 LDREX (R1), R0 708 CMP R0, R2 709 BNE casfail 710 STREX R3, (R1), R0 711 CMP $0, R0 712 BNE casl 713 MOVW $1, R0 714 MOVB R0, ret+12(FP) 715 RET 716 casfail: 717 MOVW $0, R0 718 MOVB R0, ret+12(FP) 719 RET 720 721 TEXT runtime·casuintptr(SB),NOSPLIT,$0-13 722 B runtime·cas(SB) 723 724 TEXT runtime·atomicloaduintptr(SB),NOSPLIT,$0-8 725 B runtime·atomicload(SB) 726 727 TEXT runtime·atomicloaduint(SB),NOSPLIT,$0-8 728 B runtime·atomicload(SB) 729 730 TEXT runtime·atomicstoreuintptr(SB),NOSPLIT,$0-8 731 B runtime·atomicstore(SB) 732 733 // AES hashing not implemented for ARM 734 TEXT runtime·aeshash(SB),NOSPLIT,$-4-0 735 MOVW $0, R0 736 MOVW (R0), R1 737 TEXT runtime·aeshash32(SB),NOSPLIT,$-4-0 738 MOVW $0, R0 739 MOVW (R0), R1 740 TEXT runtime·aeshash64(SB),NOSPLIT,$-4-0 741 MOVW $0, R0 742 MOVW (R0), R1 743 TEXT runtime·aeshashstr(SB),NOSPLIT,$-4-0 744 MOVW $0, R0 745 MOVW (R0), R1 746 747 TEXT runtime·memeq(SB),NOSPLIT,$-4-13 748 MOVW a+0(FP), R1 749 MOVW b+4(FP), R2 750 MOVW size+8(FP), R3 751 ADD R1, R3, R6 752 MOVW $1, R0 753 MOVB R0, ret+12(FP) 754 _next2: 755 CMP R1, R6 756 RET.EQ 757 MOVBU.P 1(R1), R4 758 MOVBU.P 1(R2), R5 759 CMP R4, R5 760 BEQ _next2 761 762 MOVW $0, R0 763 MOVB R0, ret+12(FP) 764 RET 765 766 // eqstring tests whether two strings are equal. 767 // See runtime_test.go:eqstring_generic for 768 // equivalent Go code. 769 TEXT runtime·eqstring(SB),NOSPLIT,$-4-17 770 MOVW s1len+4(FP), R0 771 MOVW s2len+12(FP), R1 772 MOVW $0, R7 773 CMP R0, R1 774 MOVB.NE R7, v+16(FP) 775 RET.NE 776 MOVW s1str+0(FP), R2 777 MOVW s2str+8(FP), R3 778 MOVW $1, R8 779 MOVB R8, v+16(FP) 780 CMP R2, R3 781 RET.EQ 782 ADD R2, R0, R6 783 _eqnext: 784 CMP R2, R6 785 RET.EQ 786 MOVBU.P 1(R2), R4 787 MOVBU.P 1(R3), R5 788 CMP R4, R5 789 BEQ _eqnext 790 MOVB R7, v+16(FP) 791 RET 792 793 // void setg_gcc(G*); set g called from gcc. 794 TEXT setg_gcc<>(SB),NOSPLIT,$0 795 MOVW R0, g 796 B runtime·save_g(SB) 797 798 // TODO: share code with memeq? 799 TEXT bytes·Equal(SB),NOSPLIT,$0 800 MOVW a_len+4(FP), R1 801 MOVW b_len+16(FP), R3 802 803 CMP R1, R3 // unequal lengths are not equal 804 B.NE _notequal 805 806 MOVW a+0(FP), R0 807 MOVW b+12(FP), R2 808 ADD R0, R1 // end 809 810 _byteseq_next: 811 CMP R0, R1 812 B.EQ _equal // reached the end 813 MOVBU.P 1(R0), R4 814 MOVBU.P 1(R2), R5 815 CMP R4, R5 816 B.EQ _byteseq_next 817 818 _notequal: 819 MOVW $0, R0 820 MOVBU R0, ret+24(FP) 821 RET 822 823 _equal: 824 MOVW $1, R0 825 MOVBU R0, ret+24(FP) 826 RET 827 828 TEXT bytes·IndexByte(SB),NOSPLIT,$0 829 MOVW s+0(FP), R0 830 MOVW s_len+4(FP), R1 831 MOVBU c+12(FP), R2 // byte to find 832 MOVW R0, R4 // store base for later 833 ADD R0, R1 // end 834 835 _loop: 836 CMP R0, R1 837 B.EQ _notfound 838 MOVBU.P 1(R0), R3 839 CMP R2, R3 840 B.NE _loop 841 842 SUB $1, R0 // R0 will be one beyond the position we want 843 SUB R4, R0 // remove base 844 MOVW R0, ret+16(FP) 845 RET 846 847 _notfound: 848 MOVW $-1, R0 849 MOVW R0, ret+16(FP) 850 RET 851 852 TEXT strings·IndexByte(SB),NOSPLIT,$0 853 MOVW s+0(FP), R0 854 MOVW s_len+4(FP), R1 855 MOVBU c+8(FP), R2 // byte to find 856 MOVW R0, R4 // store base for later 857 ADD R0, R1 // end 858 859 _sib_loop: 860 CMP R0, R1 861 B.EQ _sib_notfound 862 MOVBU.P 1(R0), R3 863 CMP R2, R3 864 B.NE _sib_loop 865 866 SUB $1, R0 // R0 will be one beyond the position we want 867 SUB R4, R0 // remove base 868 MOVW R0, ret+12(FP) 869 RET 870 871 _sib_notfound: 872 MOVW $-1, R0 873 MOVW R0, ret+12(FP) 874 RET 875 876 // A Duff's device for zeroing memory. 877 // The compiler jumps to computed addresses within 878 // this routine to zero chunks of memory. Do not 879 // change this code without also changing the code 880 // in ../../cmd/5g/ggen.c:clearfat. 881 // R0: zero 882 // R1: ptr to memory to be zeroed 883 // R1 is updated as a side effect. 884 TEXT runtime·duffzero(SB),NOSPLIT,$0-0 885 MOVW.P R0, 4(R1) 886 MOVW.P R0, 4(R1) 887 MOVW.P R0, 4(R1) 888 MOVW.P R0, 4(R1) 889 MOVW.P R0, 4(R1) 890 MOVW.P R0, 4(R1) 891 MOVW.P R0, 4(R1) 892 MOVW.P R0, 4(R1) 893 MOVW.P R0, 4(R1) 894 MOVW.P R0, 4(R1) 895 MOVW.P R0, 4(R1) 896 MOVW.P R0, 4(R1) 897 MOVW.P R0, 4(R1) 898 MOVW.P R0, 4(R1) 899 MOVW.P R0, 4(R1) 900 MOVW.P R0, 4(R1) 901 MOVW.P R0, 4(R1) 902 MOVW.P R0, 4(R1) 903 MOVW.P R0, 4(R1) 904 MOVW.P R0, 4(R1) 905 MOVW.P R0, 4(R1) 906 MOVW.P R0, 4(R1) 907 MOVW.P R0, 4(R1) 908 MOVW.P R0, 4(R1) 909 MOVW.P R0, 4(R1) 910 MOVW.P R0, 4(R1) 911 MOVW.P R0, 4(R1) 912 MOVW.P R0, 4(R1) 913 MOVW.P R0, 4(R1) 914 MOVW.P R0, 4(R1) 915 MOVW.P R0, 4(R1) 916 MOVW.P R0, 4(R1) 917 MOVW.P R0, 4(R1) 918 MOVW.P R0, 4(R1) 919 MOVW.P R0, 4(R1) 920 MOVW.P R0, 4(R1) 921 MOVW.P R0, 4(R1) 922 MOVW.P R0, 4(R1) 923 MOVW.P R0, 4(R1) 924 MOVW.P R0, 4(R1) 925 MOVW.P R0, 4(R1) 926 MOVW.P R0, 4(R1) 927 MOVW.P R0, 4(R1) 928 MOVW.P R0, 4(R1) 929 MOVW.P R0, 4(R1) 930 MOVW.P R0, 4(R1) 931 MOVW.P R0, 4(R1) 932 MOVW.P R0, 4(R1) 933 MOVW.P R0, 4(R1) 934 MOVW.P R0, 4(R1) 935 MOVW.P R0, 4(R1) 936 MOVW.P R0, 4(R1) 937 MOVW.P R0, 4(R1) 938 MOVW.P R0, 4(R1) 939 MOVW.P R0, 4(R1) 940 MOVW.P R0, 4(R1) 941 MOVW.P R0, 4(R1) 942 MOVW.P R0, 4(R1) 943 MOVW.P R0, 4(R1) 944 MOVW.P R0, 4(R1) 945 MOVW.P R0, 4(R1) 946 MOVW.P R0, 4(R1) 947 MOVW.P R0, 4(R1) 948 MOVW.P R0, 4(R1) 949 MOVW.P R0, 4(R1) 950 MOVW.P R0, 4(R1) 951 MOVW.P R0, 4(R1) 952 MOVW.P R0, 4(R1) 953 MOVW.P R0, 4(R1) 954 MOVW.P R0, 4(R1) 955 MOVW.P R0, 4(R1) 956 MOVW.P R0, 4(R1) 957 MOVW.P R0, 4(R1) 958 MOVW.P R0, 4(R1) 959 MOVW.P R0, 4(R1) 960 MOVW.P R0, 4(R1) 961 MOVW.P R0, 4(R1) 962 MOVW.P R0, 4(R1) 963 MOVW.P R0, 4(R1) 964 MOVW.P R0, 4(R1) 965 MOVW.P R0, 4(R1) 966 MOVW.P R0, 4(R1) 967 MOVW.P R0, 4(R1) 968 MOVW.P R0, 4(R1) 969 MOVW.P R0, 4(R1) 970 MOVW.P R0, 4(R1) 971 MOVW.P R0, 4(R1) 972 MOVW.P R0, 4(R1) 973 MOVW.P R0, 4(R1) 974 MOVW.P R0, 4(R1) 975 MOVW.P R0, 4(R1) 976 MOVW.P R0, 4(R1) 977 MOVW.P R0, 4(R1) 978 MOVW.P R0, 4(R1) 979 MOVW.P R0, 4(R1) 980 MOVW.P R0, 4(R1) 981 MOVW.P R0, 4(R1) 982 MOVW.P R0, 4(R1) 983 MOVW.P R0, 4(R1) 984 MOVW.P R0, 4(R1) 985 MOVW.P R0, 4(R1) 986 MOVW.P R0, 4(R1) 987 MOVW.P R0, 4(R1) 988 MOVW.P R0, 4(R1) 989 MOVW.P R0, 4(R1) 990 MOVW.P R0, 4(R1) 991 MOVW.P R0, 4(R1) 992 MOVW.P R0, 4(R1) 993 MOVW.P R0, 4(R1) 994 MOVW.P R0, 4(R1) 995 MOVW.P R0, 4(R1) 996 MOVW.P R0, 4(R1) 997 MOVW.P R0, 4(R1) 998 MOVW.P R0, 4(R1) 999 MOVW.P R0, 4(R1) 1000 MOVW.P R0, 4(R1) 1001 MOVW.P R0, 4(R1) 1002 MOVW.P R0, 4(R1) 1003 MOVW.P R0, 4(R1) 1004 MOVW.P R0, 4(R1) 1005 MOVW.P R0, 4(R1) 1006 MOVW.P R0, 4(R1) 1007 MOVW.P R0, 4(R1) 1008 MOVW.P R0, 4(R1) 1009 MOVW.P R0, 4(R1) 1010 MOVW.P R0, 4(R1) 1011 MOVW.P R0, 4(R1) 1012 MOVW.P R0, 4(R1) 1013 RET 1014 1015 // A Duff's device for copying memory. 1016 // The compiler jumps to computed addresses within 1017 // this routine to copy chunks of memory. Source 1018 // and destination must not overlap. Do not 1019 // change this code without also changing the code 1020 // in ../../cmd/5g/cgen.c:sgen. 1021 // R0: scratch space 1022 // R1: ptr to source memory 1023 // R2: ptr to destination memory 1024 // R1 and R2 are updated as a side effect 1025 TEXT runtime·duffcopy(SB),NOSPLIT,$0-0 1026 MOVW.P 4(R1), R0 1027 MOVW.P R0, 4(R2) 1028 MOVW.P 4(R1), R0 1029 MOVW.P R0, 4(R2) 1030 MOVW.P 4(R1), R0 1031 MOVW.P R0, 4(R2) 1032 MOVW.P 4(R1), R0 1033 MOVW.P R0, 4(R2) 1034 MOVW.P 4(R1), R0 1035 MOVW.P R0, 4(R2) 1036 MOVW.P 4(R1), R0 1037 MOVW.P R0, 4(R2) 1038 MOVW.P 4(R1), R0 1039 MOVW.P R0, 4(R2) 1040 MOVW.P 4(R1), R0 1041 MOVW.P R0, 4(R2) 1042 MOVW.P 4(R1), R0 1043 MOVW.P R0, 4(R2) 1044 MOVW.P 4(R1), R0 1045 MOVW.P R0, 4(R2) 1046 MOVW.P 4(R1), R0 1047 MOVW.P R0, 4(R2) 1048 MOVW.P 4(R1), R0 1049 MOVW.P R0, 4(R2) 1050 MOVW.P 4(R1), R0 1051 MOVW.P R0, 4(R2) 1052 MOVW.P 4(R1), R0 1053 MOVW.P R0, 4(R2) 1054 MOVW.P 4(R1), R0 1055 MOVW.P R0, 4(R2) 1056 MOVW.P 4(R1), R0 1057 MOVW.P R0, 4(R2) 1058 MOVW.P 4(R1), R0 1059 MOVW.P R0, 4(R2) 1060 MOVW.P 4(R1), R0 1061 MOVW.P R0, 4(R2) 1062 MOVW.P 4(R1), R0 1063 MOVW.P R0, 4(R2) 1064 MOVW.P 4(R1), R0 1065 MOVW.P R0, 4(R2) 1066 MOVW.P 4(R1), R0 1067 MOVW.P R0, 4(R2) 1068 MOVW.P 4(R1), R0 1069 MOVW.P R0, 4(R2) 1070 MOVW.P 4(R1), R0 1071 MOVW.P R0, 4(R2) 1072 MOVW.P 4(R1), R0 1073 MOVW.P R0, 4(R2) 1074 MOVW.P 4(R1), R0 1075 MOVW.P R0, 4(R2) 1076 MOVW.P 4(R1), R0 1077 MOVW.P R0, 4(R2) 1078 MOVW.P 4(R1), R0 1079 MOVW.P R0, 4(R2) 1080 MOVW.P 4(R1), R0 1081 MOVW.P R0, 4(R2) 1082 MOVW.P 4(R1), R0 1083 MOVW.P R0, 4(R2) 1084 MOVW.P 4(R1), R0 1085 MOVW.P R0, 4(R2) 1086 MOVW.P 4(R1), R0 1087 MOVW.P R0, 4(R2) 1088 MOVW.P 4(R1), R0 1089 MOVW.P R0, 4(R2) 1090 MOVW.P 4(R1), R0 1091 MOVW.P R0, 4(R2) 1092 MOVW.P 4(R1), R0 1093 MOVW.P R0, 4(R2) 1094 MOVW.P 4(R1), R0 1095 MOVW.P R0, 4(R2) 1096 MOVW.P 4(R1), R0 1097 MOVW.P R0, 4(R2) 1098 MOVW.P 4(R1), R0 1099 MOVW.P R0, 4(R2) 1100 MOVW.P 4(R1), R0 1101 MOVW.P R0, 4(R2) 1102 MOVW.P 4(R1), R0 1103 MOVW.P R0, 4(R2) 1104 MOVW.P 4(R1), R0 1105 MOVW.P R0, 4(R2) 1106 MOVW.P 4(R1), R0 1107 MOVW.P R0, 4(R2) 1108 MOVW.P 4(R1), R0 1109 MOVW.P R0, 4(R2) 1110 MOVW.P 4(R1), R0 1111 MOVW.P R0, 4(R2) 1112 MOVW.P 4(R1), R0 1113 MOVW.P R0, 4(R2) 1114 MOVW.P 4(R1), R0 1115 MOVW.P R0, 4(R2) 1116 MOVW.P 4(R1), R0 1117 MOVW.P R0, 4(R2) 1118 MOVW.P 4(R1), R0 1119 MOVW.P R0, 4(R2) 1120 MOVW.P 4(R1), R0 1121 MOVW.P R0, 4(R2) 1122 MOVW.P 4(R1), R0 1123 MOVW.P R0, 4(R2) 1124 MOVW.P 4(R1), R0 1125 MOVW.P R0, 4(R2) 1126 MOVW.P 4(R1), R0 1127 MOVW.P R0, 4(R2) 1128 MOVW.P 4(R1), R0 1129 MOVW.P R0, 4(R2) 1130 MOVW.P 4(R1), R0 1131 MOVW.P R0, 4(R2) 1132 MOVW.P 4(R1), R0 1133 MOVW.P R0, 4(R2) 1134 MOVW.P 4(R1), R0 1135 MOVW.P R0, 4(R2) 1136 MOVW.P 4(R1), R0 1137 MOVW.P R0, 4(R2) 1138 MOVW.P 4(R1), R0 1139 MOVW.P R0, 4(R2) 1140 MOVW.P 4(R1), R0 1141 MOVW.P R0, 4(R2) 1142 MOVW.P 4(R1), R0 1143 MOVW.P R0, 4(R2) 1144 MOVW.P 4(R1), R0 1145 MOVW.P R0, 4(R2) 1146 MOVW.P 4(R1), R0 1147 MOVW.P R0, 4(R2) 1148 MOVW.P 4(R1), R0 1149 MOVW.P R0, 4(R2) 1150 MOVW.P 4(R1), R0 1151 MOVW.P R0, 4(R2) 1152 MOVW.P 4(R1), R0 1153 MOVW.P R0, 4(R2) 1154 MOVW.P 4(R1), R0 1155 MOVW.P R0, 4(R2) 1156 MOVW.P 4(R1), R0 1157 MOVW.P R0, 4(R2) 1158 MOVW.P 4(R1), R0 1159 MOVW.P R0, 4(R2) 1160 MOVW.P 4(R1), R0 1161 MOVW.P R0, 4(R2) 1162 MOVW.P 4(R1), R0 1163 MOVW.P R0, 4(R2) 1164 MOVW.P 4(R1), R0 1165 MOVW.P R0, 4(R2) 1166 MOVW.P 4(R1), R0 1167 MOVW.P R0, 4(R2) 1168 MOVW.P 4(R1), R0 1169 MOVW.P R0, 4(R2) 1170 MOVW.P 4(R1), R0 1171 MOVW.P R0, 4(R2) 1172 MOVW.P 4(R1), R0 1173 MOVW.P R0, 4(R2) 1174 MOVW.P 4(R1), R0 1175 MOVW.P R0, 4(R2) 1176 MOVW.P 4(R1), R0 1177 MOVW.P R0, 4(R2) 1178 MOVW.P 4(R1), R0 1179 MOVW.P R0, 4(R2) 1180 MOVW.P 4(R1), R0 1181 MOVW.P R0, 4(R2) 1182 MOVW.P 4(R1), R0 1183 MOVW.P R0, 4(R2) 1184 MOVW.P 4(R1), R0 1185 MOVW.P R0, 4(R2) 1186 MOVW.P 4(R1), R0 1187 MOVW.P R0, 4(R2) 1188 MOVW.P 4(R1), R0 1189 MOVW.P R0, 4(R2) 1190 MOVW.P 4(R1), R0 1191 MOVW.P R0, 4(R2) 1192 MOVW.P 4(R1), R0 1193 MOVW.P R0, 4(R2) 1194 MOVW.P 4(R1), R0 1195 MOVW.P R0, 4(R2) 1196 MOVW.P 4(R1), R0 1197 MOVW.P R0, 4(R2) 1198 MOVW.P 4(R1), R0 1199 MOVW.P R0, 4(R2) 1200 MOVW.P 4(R1), R0 1201 MOVW.P R0, 4(R2) 1202 MOVW.P 4(R1), R0 1203 MOVW.P R0, 4(R2) 1204 MOVW.P 4(R1), R0 1205 MOVW.P R0, 4(R2) 1206 MOVW.P 4(R1), R0 1207 MOVW.P R0, 4(R2) 1208 MOVW.P 4(R1), R0 1209 MOVW.P R0, 4(R2) 1210 MOVW.P 4(R1), R0 1211 MOVW.P R0, 4(R2) 1212 MOVW.P 4(R1), R0 1213 MOVW.P R0, 4(R2) 1214 MOVW.P 4(R1), R0 1215 MOVW.P R0, 4(R2) 1216 MOVW.P 4(R1), R0 1217 MOVW.P R0, 4(R2) 1218 MOVW.P 4(R1), R0 1219 MOVW.P R0, 4(R2) 1220 MOVW.P 4(R1), R0 1221 MOVW.P R0, 4(R2) 1222 MOVW.P 4(R1), R0 1223 MOVW.P R0, 4(R2) 1224 MOVW.P 4(R1), R0 1225 MOVW.P R0, 4(R2) 1226 MOVW.P 4(R1), R0 1227 MOVW.P R0, 4(R2) 1228 MOVW.P 4(R1), R0 1229 MOVW.P R0, 4(R2) 1230 MOVW.P 4(R1), R0 1231 MOVW.P R0, 4(R2) 1232 MOVW.P 4(R1), R0 1233 MOVW.P R0, 4(R2) 1234 MOVW.P 4(R1), R0 1235 MOVW.P R0, 4(R2) 1236 MOVW.P 4(R1), R0 1237 MOVW.P R0, 4(R2) 1238 MOVW.P 4(R1), R0 1239 MOVW.P R0, 4(R2) 1240 MOVW.P 4(R1), R0 1241 MOVW.P R0, 4(R2) 1242 MOVW.P 4(R1), R0 1243 MOVW.P R0, 4(R2) 1244 MOVW.P 4(R1), R0 1245 MOVW.P R0, 4(R2) 1246 MOVW.P 4(R1), R0 1247 MOVW.P R0, 4(R2) 1248 MOVW.P 4(R1), R0 1249 MOVW.P R0, 4(R2) 1250 MOVW.P 4(R1), R0 1251 MOVW.P R0, 4(R2) 1252 MOVW.P 4(R1), R0 1253 MOVW.P R0, 4(R2) 1254 MOVW.P 4(R1), R0 1255 MOVW.P R0, 4(R2) 1256 MOVW.P 4(R1), R0 1257 MOVW.P R0, 4(R2) 1258 MOVW.P 4(R1), R0 1259 MOVW.P R0, 4(R2) 1260 MOVW.P 4(R1), R0 1261 MOVW.P R0, 4(R2) 1262 MOVW.P 4(R1), R0 1263 MOVW.P R0, 4(R2) 1264 MOVW.P 4(R1), R0 1265 MOVW.P R0, 4(R2) 1266 MOVW.P 4(R1), R0 1267 MOVW.P R0, 4(R2) 1268 MOVW.P 4(R1), R0 1269 MOVW.P R0, 4(R2) 1270 MOVW.P 4(R1), R0 1271 MOVW.P R0, 4(R2) 1272 MOVW.P 4(R1), R0 1273 MOVW.P R0, 4(R2) 1274 MOVW.P 4(R1), R0 1275 MOVW.P R0, 4(R2) 1276 MOVW.P 4(R1), R0 1277 MOVW.P R0, 4(R2) 1278 MOVW.P 4(R1), R0 1279 MOVW.P R0, 4(R2) 1280 MOVW.P 4(R1), R0 1281 MOVW.P R0, 4(R2) 1282 RET 1283 1284 TEXT runtime·fastrand1(SB),NOSPLIT,$-4-4 1285 MOVW g_m(g), R1 1286 MOVW m_fastrand(R1), R0 1287 ADD.S R0, R0 1288 EOR.MI $0x88888eef, R0 1289 MOVW R0, m_fastrand(R1) 1290 MOVW R0, ret+0(FP) 1291 RET 1292 1293 TEXT runtime·return0(SB),NOSPLIT,$0 1294 MOVW $0, R0 1295 RET 1296 1297 TEXT runtime·procyield(SB),NOSPLIT,$-4 1298 MOVW cycles+0(FP), R1 1299 MOVW $0, R0 1300 yieldloop: 1301 CMP R0, R1 1302 B.NE 2(PC) 1303 RET 1304 SUB $1, R1 1305 B yieldloop 1306 1307 // Called from cgo wrappers, this function returns g->m->curg.stack.hi. 1308 // Must obey the gcc calling convention. 1309 TEXT _cgo_topofstack(SB),NOSPLIT,$8 1310 // R11 and g register are clobbered by load_g. They are 1311 // callee-save in the gcc calling convention, so save them here. 1312 MOVW R11, saveR11-4(SP) 1313 MOVW g, saveG-8(SP) 1314 1315 BL runtime·load_g(SB) 1316 MOVW g_m(g), R0 1317 MOVW m_curg(R0), R0 1318 MOVW (g_stack+stack_hi)(R0), R0 1319 1320 MOVW saveG-8(SP), g 1321 MOVW saveR11-4(SP), R11 1322 RET 1323 1324 // The top-most function running on a goroutine 1325 // returns to goexit+PCQuantum. 1326 TEXT runtime·goexit(SB),NOSPLIT,$-4-0 1327 MOVW R0, R0 // NOP 1328 BL runtime·goexit1(SB) // does not return