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