github.com/zxy12/go_duplicate_112_new@v0.0.0-20200807091221-747231827200/src/runtime/asm_mipsx.s (about) 1 // Copyright 2016 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 // +build mips mipsle 6 7 #include "go_asm.h" 8 #include "go_tls.h" 9 #include "funcdata.h" 10 #include "textflag.h" 11 12 #define REGCTXT R22 13 14 TEXT runtime·rt0_go(SB),NOSPLIT,$0 15 // R29 = stack; R4 = argc; R5 = argv 16 17 ADDU $-12, R29 18 MOVW R4, 4(R29) // argc 19 MOVW R5, 8(R29) // argv 20 21 // create istack out of the given (operating system) stack. 22 // _cgo_init may update stackguard. 23 MOVW $runtime·g0(SB), g 24 MOVW $(-64*1024), R23 25 ADD R23, R29, R1 26 MOVW R1, g_stackguard0(g) 27 MOVW R1, g_stackguard1(g) 28 MOVW R1, (g_stack+stack_lo)(g) 29 MOVW R29, (g_stack+stack_hi)(g) 30 31 // if there is a _cgo_init, call it using the gcc ABI. 32 MOVW _cgo_init(SB), R25 33 BEQ R25, nocgo 34 ADDU $-16, R29 35 MOVW R0, R7 // arg 3: not used 36 MOVW R0, R6 // arg 2: not used 37 MOVW $setg_gcc<>(SB), R5 // arg 1: setg 38 MOVW g, R4 // arg 0: G 39 JAL (R25) 40 ADDU $16, R29 41 42 nocgo: 43 // update stackguard after _cgo_init 44 MOVW (g_stack+stack_lo)(g), R1 45 ADD $const__StackGuard, R1 46 MOVW R1, g_stackguard0(g) 47 MOVW R1, g_stackguard1(g) 48 49 // set the per-goroutine and per-mach "registers" 50 MOVW $runtime·m0(SB), R1 51 52 // save m->g0 = g0 53 MOVW g, m_g0(R1) 54 // save m0 to g0->m 55 MOVW R1, g_m(g) 56 57 JAL runtime·check(SB) 58 59 // args are already prepared 60 JAL runtime·args(SB) 61 JAL runtime·osinit(SB) 62 JAL runtime·schedinit(SB) 63 64 // create a new goroutine to start program 65 MOVW $runtime·mainPC(SB), R1 // entry 66 ADDU $-12, R29 67 MOVW R1, 8(R29) 68 MOVW R0, 4(R29) 69 MOVW R0, 0(R29) 70 JAL runtime·newproc(SB) 71 ADDU $12, R29 72 73 // start this M 74 JAL runtime·mstart(SB) 75 76 UNDEF 77 RET 78 79 DATA runtime·mainPC+0(SB)/4,$runtime·main(SB) 80 GLOBL runtime·mainPC(SB),RODATA,$4 81 82 TEXT runtime·breakpoint(SB),NOSPLIT,$0-0 83 BREAK 84 RET 85 86 TEXT runtime·asminit(SB),NOSPLIT,$0-0 87 RET 88 89 /* 90 * go-routine 91 */ 92 93 // void gosave(Gobuf*) 94 // save state in Gobuf; setjmp 95 TEXT runtime·gosave(SB),NOSPLIT|NOFRAME,$0-4 96 MOVW buf+0(FP), R1 97 MOVW R29, gobuf_sp(R1) 98 MOVW R31, gobuf_pc(R1) 99 MOVW g, gobuf_g(R1) 100 MOVW R0, gobuf_lr(R1) 101 MOVW R0, gobuf_ret(R1) 102 // Assert ctxt is zero. See func save. 103 MOVW gobuf_ctxt(R1), R1 104 BEQ R1, 2(PC) 105 JAL runtime·badctxt(SB) 106 RET 107 108 // void gogo(Gobuf*) 109 // restore state from Gobuf; longjmp 110 TEXT runtime·gogo(SB),NOSPLIT,$8-4 111 MOVW buf+0(FP), R3 112 MOVW gobuf_g(R3), g // make sure g is not nil 113 JAL runtime·save_g(SB) 114 115 MOVW 0(g), R2 116 MOVW gobuf_sp(R3), R29 117 MOVW gobuf_lr(R3), R31 118 MOVW gobuf_ret(R3), R1 119 MOVW gobuf_ctxt(R3), REGCTXT 120 MOVW R0, gobuf_sp(R3) 121 MOVW R0, gobuf_ret(R3) 122 MOVW R0, gobuf_lr(R3) 123 MOVW R0, gobuf_ctxt(R3) 124 MOVW gobuf_pc(R3), R4 125 JMP (R4) 126 127 // void mcall(fn func(*g)) 128 // Switch to m->g0's stack, call fn(g). 129 // Fn must never return. It should gogo(&g->sched) 130 // to keep running g. 131 TEXT runtime·mcall(SB),NOSPLIT|NOFRAME,$0-4 132 // Save caller state in g->sched 133 MOVW R29, (g_sched+gobuf_sp)(g) 134 MOVW R31, (g_sched+gobuf_pc)(g) 135 MOVW R0, (g_sched+gobuf_lr)(g) 136 MOVW g, (g_sched+gobuf_g)(g) 137 138 // Switch to m->g0 & its stack, call fn. 139 MOVW g, R1 140 MOVW g_m(g), R3 141 MOVW m_g0(R3), g 142 JAL runtime·save_g(SB) 143 BNE g, R1, 2(PC) 144 JMP runtime·badmcall(SB) 145 MOVW fn+0(FP), REGCTXT // context 146 MOVW 0(REGCTXT), R4 // code pointer 147 MOVW (g_sched+gobuf_sp)(g), R29 // sp = m->g0->sched.sp 148 ADDU $-8, R29 // make room for 1 arg and fake LR 149 MOVW R1, 4(R29) 150 MOVW R0, 0(R29) 151 JAL (R4) 152 JMP runtime·badmcall2(SB) 153 154 // systemstack_switch is a dummy routine that systemstack leaves at the bottom 155 // of the G stack. We need to distinguish the routine that 156 // lives at the bottom of the G stack from the one that lives 157 // at the top of the system stack because the one at the top of 158 // the system stack terminates the stack walk (see topofstack()). 159 TEXT runtime·systemstack_switch(SB),NOSPLIT,$0-0 160 UNDEF 161 JAL (R31) // make sure this function is not leaf 162 RET 163 164 // func systemstack(fn func()) 165 TEXT runtime·systemstack(SB),NOSPLIT,$0-4 166 MOVW fn+0(FP), R1 // R1 = fn 167 MOVW R1, REGCTXT // context 168 MOVW g_m(g), R2 // R2 = m 169 170 MOVW m_gsignal(R2), R3 // R3 = gsignal 171 BEQ g, R3, noswitch 172 173 MOVW m_g0(R2), R3 // R3 = g0 174 BEQ g, R3, noswitch 175 176 MOVW m_curg(R2), R4 177 BEQ g, R4, switch 178 179 // Bad: g is not gsignal, not g0, not curg. What is it? 180 // Hide call from linker nosplit analysis. 181 MOVW $runtime·badsystemstack(SB), R4 182 JAL (R4) 183 JAL runtime·abort(SB) 184 185 switch: 186 // save our state in g->sched. Pretend to 187 // be systemstack_switch if the G stack is scanned. 188 MOVW $runtime·systemstack_switch(SB), R4 189 ADDU $8, R4 // get past prologue 190 MOVW R4, (g_sched+gobuf_pc)(g) 191 MOVW R29, (g_sched+gobuf_sp)(g) 192 MOVW R0, (g_sched+gobuf_lr)(g) 193 MOVW g, (g_sched+gobuf_g)(g) 194 195 // switch to g0 196 MOVW R3, g 197 JAL runtime·save_g(SB) 198 MOVW (g_sched+gobuf_sp)(g), R1 199 // make it look like mstart called systemstack on g0, to stop traceback 200 ADDU $-4, R1 201 MOVW $runtime·mstart(SB), R2 202 MOVW R2, 0(R1) 203 MOVW R1, R29 204 205 // call target function 206 MOVW 0(REGCTXT), R4 // code pointer 207 JAL (R4) 208 209 // switch back to g 210 MOVW g_m(g), R1 211 MOVW m_curg(R1), g 212 JAL runtime·save_g(SB) 213 MOVW (g_sched+gobuf_sp)(g), R29 214 MOVW R0, (g_sched+gobuf_sp)(g) 215 RET 216 217 noswitch: 218 // already on m stack, just call directly 219 // Using a tail call here cleans up tracebacks since we won't stop 220 // at an intermediate systemstack. 221 MOVW 0(REGCTXT), R4 // code pointer 222 MOVW 0(R29), R31 // restore LR 223 ADD $4, R29 224 JMP (R4) 225 226 /* 227 * support for morestack 228 */ 229 230 // Called during function prolog when more stack is needed. 231 // Caller has already loaded: 232 // R1: framesize, R2: argsize, R3: LR 233 // 234 // The traceback routines see morestack on a g0 as being 235 // the top of a stack (for example, morestack calling newstack 236 // calling the scheduler calling newm calling gc), so we must 237 // record an argument size. For that purpose, it has no arguments. 238 TEXT runtime·morestack(SB),NOSPLIT|NOFRAME,$0-0 239 // Cannot grow scheduler stack (m->g0). 240 MOVW g_m(g), R7 241 MOVW m_g0(R7), R8 242 BNE g, R8, 3(PC) 243 JAL runtime·badmorestackg0(SB) 244 JAL runtime·abort(SB) 245 246 // Cannot grow signal stack (m->gsignal). 247 MOVW m_gsignal(R7), R8 248 BNE g, R8, 3(PC) 249 JAL runtime·badmorestackgsignal(SB) 250 JAL runtime·abort(SB) 251 252 // Called from f. 253 // Set g->sched to context in f. 254 MOVW R29, (g_sched+gobuf_sp)(g) 255 MOVW R31, (g_sched+gobuf_pc)(g) 256 MOVW R3, (g_sched+gobuf_lr)(g) 257 MOVW REGCTXT, (g_sched+gobuf_ctxt)(g) 258 259 // Called from f. 260 // Set m->morebuf to f's caller. 261 MOVW R3, (m_morebuf+gobuf_pc)(R7) // f's caller's PC 262 MOVW R29, (m_morebuf+gobuf_sp)(R7) // f's caller's SP 263 MOVW g, (m_morebuf+gobuf_g)(R7) 264 265 // Call newstack on m->g0's stack. 266 MOVW m_g0(R7), g 267 JAL runtime·save_g(SB) 268 MOVW (g_sched+gobuf_sp)(g), R29 269 // Create a stack frame on g0 to call newstack. 270 MOVW R0, -4(R29) // Zero saved LR in frame 271 ADDU $-4, R29 272 JAL runtime·newstack(SB) 273 274 // Not reached, but make sure the return PC from the call to newstack 275 // is still in this function, and not the beginning of the next. 276 UNDEF 277 278 TEXT runtime·morestack_noctxt(SB),NOSPLIT,$0-0 279 MOVW R0, REGCTXT 280 JMP runtime·morestack(SB) 281 282 // reflectcall: call a function with the given argument list 283 // func call(argtype *_type, f *FuncVal, arg *byte, argsize, retoffset uint32). 284 // we don't have variable-sized frames, so we use a small number 285 // of constant-sized-frame functions to encode a few bits of size in the pc. 286 287 #define DISPATCH(NAME,MAXSIZE) \ 288 MOVW $MAXSIZE, R23; \ 289 SGTU R1, R23, R23; \ 290 BNE R23, 3(PC); \ 291 MOVW $NAME(SB), R4; \ 292 JMP (R4) 293 294 TEXT ·reflectcall(SB),NOSPLIT|NOFRAME,$0-20 295 MOVW argsize+12(FP), R1 296 297 DISPATCH(runtime·call16, 16) 298 DISPATCH(runtime·call32, 32) 299 DISPATCH(runtime·call64, 64) 300 DISPATCH(runtime·call128, 128) 301 DISPATCH(runtime·call256, 256) 302 DISPATCH(runtime·call512, 512) 303 DISPATCH(runtime·call1024, 1024) 304 DISPATCH(runtime·call2048, 2048) 305 DISPATCH(runtime·call4096, 4096) 306 DISPATCH(runtime·call8192, 8192) 307 DISPATCH(runtime·call16384, 16384) 308 DISPATCH(runtime·call32768, 32768) 309 DISPATCH(runtime·call65536, 65536) 310 DISPATCH(runtime·call131072, 131072) 311 DISPATCH(runtime·call262144, 262144) 312 DISPATCH(runtime·call524288, 524288) 313 DISPATCH(runtime·call1048576, 1048576) 314 DISPATCH(runtime·call2097152, 2097152) 315 DISPATCH(runtime·call4194304, 4194304) 316 DISPATCH(runtime·call8388608, 8388608) 317 DISPATCH(runtime·call16777216, 16777216) 318 DISPATCH(runtime·call33554432, 33554432) 319 DISPATCH(runtime·call67108864, 67108864) 320 DISPATCH(runtime·call134217728, 134217728) 321 DISPATCH(runtime·call268435456, 268435456) 322 DISPATCH(runtime·call536870912, 536870912) 323 DISPATCH(runtime·call1073741824, 1073741824) 324 MOVW $runtime·badreflectcall(SB), R4 325 JMP (R4) 326 327 #define CALLFN(NAME,MAXSIZE) \ 328 TEXT NAME(SB),WRAPPER,$MAXSIZE-20; \ 329 NO_LOCAL_POINTERS; \ 330 /* copy arguments to stack */ \ 331 MOVW arg+8(FP), R1; \ 332 MOVW argsize+12(FP), R2; \ 333 MOVW R29, R3; \ 334 ADDU $4, R3; \ 335 ADDU R3, R2; \ 336 BEQ R3, R2, 6(PC); \ 337 MOVBU (R1), R4; \ 338 ADDU $1, R1; \ 339 MOVBU R4, (R3); \ 340 ADDU $1, R3; \ 341 JMP -5(PC); \ 342 /* call function */ \ 343 MOVW f+4(FP), REGCTXT; \ 344 MOVW (REGCTXT), R4; \ 345 PCDATA $PCDATA_StackMapIndex, $0; \ 346 JAL (R4); \ 347 /* copy return values back */ \ 348 MOVW argtype+0(FP), R5; \ 349 MOVW arg+8(FP), R1; \ 350 MOVW n+12(FP), R2; \ 351 MOVW retoffset+16(FP), R4; \ 352 ADDU $4, R29, R3; \ 353 ADDU R4, R3; \ 354 ADDU R4, R1; \ 355 SUBU R4, R2; \ 356 JAL callRet<>(SB); \ 357 RET 358 359 // callRet copies return values back at the end of call*. This is a 360 // separate function so it can allocate stack space for the arguments 361 // to reflectcallmove. It does not follow the Go ABI; it expects its 362 // arguments in registers. 363 TEXT callRet<>(SB), NOSPLIT, $16-0 364 MOVW R5, 4(R29) 365 MOVW R1, 8(R29) 366 MOVW R3, 12(R29) 367 MOVW R2, 16(R29) 368 JAL runtime·reflectcallmove(SB) 369 RET 370 371 CALLFN(·call16, 16) 372 CALLFN(·call32, 32) 373 CALLFN(·call64, 64) 374 CALLFN(·call128, 128) 375 CALLFN(·call256, 256) 376 CALLFN(·call512, 512) 377 CALLFN(·call1024, 1024) 378 CALLFN(·call2048, 2048) 379 CALLFN(·call4096, 4096) 380 CALLFN(·call8192, 8192) 381 CALLFN(·call16384, 16384) 382 CALLFN(·call32768, 32768) 383 CALLFN(·call65536, 65536) 384 CALLFN(·call131072, 131072) 385 CALLFN(·call262144, 262144) 386 CALLFN(·call524288, 524288) 387 CALLFN(·call1048576, 1048576) 388 CALLFN(·call2097152, 2097152) 389 CALLFN(·call4194304, 4194304) 390 CALLFN(·call8388608, 8388608) 391 CALLFN(·call16777216, 16777216) 392 CALLFN(·call33554432, 33554432) 393 CALLFN(·call67108864, 67108864) 394 CALLFN(·call134217728, 134217728) 395 CALLFN(·call268435456, 268435456) 396 CALLFN(·call536870912, 536870912) 397 CALLFN(·call1073741824, 1073741824) 398 399 TEXT runtime·procyield(SB),NOSPLIT,$0-4 400 RET 401 402 // void jmpdefer(fv, sp); 403 // called from deferreturn. 404 // 1. grab stored LR for caller 405 // 2. sub 8 bytes to get back to JAL deferreturn 406 // 3. JMP to fn 407 TEXT runtime·jmpdefer(SB),NOSPLIT,$0-8 408 MOVW 0(R29), R31 409 ADDU $-8, R31 410 411 MOVW fv+0(FP), REGCTXT 412 MOVW argp+4(FP), R29 413 ADDU $-4, R29 414 NOR R0, R0 // prevent scheduling 415 MOVW 0(REGCTXT), R4 416 JMP (R4) 417 418 // Save state of caller into g->sched. Smashes R1. 419 TEXT gosave<>(SB),NOSPLIT|NOFRAME,$0 420 MOVW R31, (g_sched+gobuf_pc)(g) 421 MOVW R29, (g_sched+gobuf_sp)(g) 422 MOVW R0, (g_sched+gobuf_lr)(g) 423 MOVW R0, (g_sched+gobuf_ret)(g) 424 // Assert ctxt is zero. See func save. 425 MOVW (g_sched+gobuf_ctxt)(g), R1 426 BEQ R1, 2(PC) 427 JAL runtime·badctxt(SB) 428 RET 429 430 // func asmcgocall(fn, arg unsafe.Pointer) int32 431 // Call fn(arg) on the scheduler stack, 432 // aligned appropriately for the gcc ABI. 433 // See cgocall.go for more details. 434 TEXT ·asmcgocall(SB),NOSPLIT,$0-12 435 MOVW fn+0(FP), R25 436 MOVW arg+4(FP), R4 437 438 MOVW R29, R3 // save original stack pointer 439 MOVW g, R2 440 441 // Figure out if we need to switch to m->g0 stack. 442 // We get called to create new OS threads too, and those 443 // come in on the m->g0 stack already. 444 MOVW g_m(g), R5 445 MOVW m_g0(R5), R6 446 BEQ R6, g, g0 447 448 JAL gosave<>(SB) 449 MOVW R6, g 450 JAL runtime·save_g(SB) 451 MOVW (g_sched+gobuf_sp)(g), R29 452 453 // Now on a scheduling stack (a pthread-created stack). 454 g0: 455 // Save room for two of our pointers and O32 frame. 456 ADDU $-24, R29 457 AND $~7, R29 // O32 ABI expects 8-byte aligned stack on function entry 458 MOVW R2, 16(R29) // save old g on stack 459 MOVW (g_stack+stack_hi)(R2), R2 460 SUBU R3, R2 461 MOVW R2, 20(R29) // save depth in old g stack (can't just save SP, as stack might be copied during a callback) 462 JAL (R25) 463 464 // Restore g, stack pointer. R2 is return value. 465 MOVW 16(R29), g 466 JAL runtime·save_g(SB) 467 MOVW (g_stack+stack_hi)(g), R5 468 MOVW 20(R29), R6 469 SUBU R6, R5 470 MOVW R5, R29 471 472 MOVW R2, ret+8(FP) 473 RET 474 475 // cgocallback(void (*fn)(void*), void *frame, uintptr framesize) 476 // Turn the fn into a Go func (by taking its address) and call 477 // cgocallback_gofunc. 478 TEXT runtime·cgocallback(SB),NOSPLIT,$16-16 479 MOVW $fn+0(FP), R1 480 MOVW R1, 4(R29) 481 MOVW frame+4(FP), R1 482 MOVW R1, 8(R29) 483 MOVW framesize+8(FP), R1 484 MOVW R1, 12(R29) 485 MOVW ctxt+12(FP), R1 486 MOVW R1, 16(R29) 487 MOVW $runtime·cgocallback_gofunc(SB), R1 488 JAL (R1) 489 RET 490 491 // cgocallback_gofunc(FuncVal*, void *frame, uintptr framesize, uintptr ctxt) 492 // See cgocall.go for more details. 493 TEXT ·cgocallback_gofunc(SB),NOSPLIT,$8-16 494 NO_LOCAL_POINTERS 495 496 // Load m and g from thread-local storage. 497 MOVB runtime·iscgo(SB), R1 498 BEQ R1, nocgo 499 JAL runtime·load_g(SB) 500 nocgo: 501 502 // If g is nil, Go did not create the current thread. 503 // Call needm to obtain one for temporary use. 504 // In this case, we're running on the thread stack, so there's 505 // lots of space, but the linker doesn't know. Hide the call from 506 // the linker analysis by using an indirect call. 507 BEQ g, needm 508 509 MOVW g_m(g), R3 510 MOVW R3, savedm-4(SP) 511 JMP havem 512 513 needm: 514 MOVW g, savedm-4(SP) // g is zero, so is m. 515 MOVW $runtime·needm(SB), R4 516 JAL (R4) 517 518 // Set m->sched.sp = SP, so that if a panic happens 519 // during the function we are about to execute, it will 520 // have a valid SP to run on the g0 stack. 521 // The next few lines (after the havem label) 522 // will save this SP onto the stack and then write 523 // the same SP back to m->sched.sp. That seems redundant, 524 // but if an unrecovered panic happens, unwindm will 525 // restore the g->sched.sp from the stack location 526 // and then systemstack will try to use it. If we don't set it here, 527 // that restored SP will be uninitialized (typically 0) and 528 // will not be usable. 529 MOVW g_m(g), R3 530 MOVW m_g0(R3), R1 531 MOVW R29, (g_sched+gobuf_sp)(R1) 532 533 havem: 534 // Now there's a valid m, and we're running on its m->g0. 535 // Save current m->g0->sched.sp on stack and then set it to SP. 536 // Save current sp in m->g0->sched.sp in preparation for 537 // switch back to m->curg stack. 538 // NOTE: unwindm knows that the saved g->sched.sp is at 4(R29) aka savedsp-8(SP). 539 MOVW m_g0(R3), R1 540 MOVW (g_sched+gobuf_sp)(R1), R2 541 MOVW R2, savedsp-8(SP) 542 MOVW R29, (g_sched+gobuf_sp)(R1) 543 544 // Switch to m->curg stack and call runtime.cgocallbackg. 545 // Because we are taking over the execution of m->curg 546 // but *not* resuming what had been running, we need to 547 // save that information (m->curg->sched) so we can restore it. 548 // We can restore m->curg->sched.sp easily, because calling 549 // runtime.cgocallbackg leaves SP unchanged upon return. 550 // To save m->curg->sched.pc, we push it onto the stack. 551 // This has the added benefit that it looks to the traceback 552 // routine like cgocallbackg is going to return to that 553 // PC (because the frame we allocate below has the same 554 // size as cgocallback_gofunc's frame declared above) 555 // so that the traceback will seamlessly trace back into 556 // the earlier calls. 557 // 558 // In the new goroutine, -4(SP) is unused (where SP refers to 559 // m->curg's SP while we're setting it up, before we've adjusted it). 560 MOVW m_curg(R3), g 561 JAL runtime·save_g(SB) 562 MOVW (g_sched+gobuf_sp)(g), R2 // prepare stack as R2 563 MOVW (g_sched+gobuf_pc)(g), R4 564 MOVW R4, -12(R2) 565 MOVW ctxt+12(FP), R1 566 MOVW R1, -8(R2) 567 MOVW $-12(R2), R29 568 JAL runtime·cgocallbackg(SB) 569 570 // Restore g->sched (== m->curg->sched) from saved values. 571 MOVW 0(R29), R4 572 MOVW R4, (g_sched+gobuf_pc)(g) 573 MOVW $12(R29), R2 574 MOVW R2, (g_sched+gobuf_sp)(g) 575 576 // Switch back to m->g0's stack and restore m->g0->sched.sp. 577 // (Unlike m->curg, the g0 goroutine never uses sched.pc, 578 // so we do not have to restore it.) 579 MOVW g_m(g), R3 580 MOVW m_g0(R3), g 581 JAL runtime·save_g(SB) 582 MOVW (g_sched+gobuf_sp)(g), R29 583 MOVW savedsp-8(SP), R2 584 MOVW R2, (g_sched+gobuf_sp)(g) 585 586 // If the m on entry was nil, we called needm above to borrow an m 587 // for the duration of the call. Since the call is over, return it with dropm. 588 MOVW savedm-4(SP), R3 589 BNE R3, droppedm 590 MOVW $runtime·dropm(SB), R4 591 JAL (R4) 592 droppedm: 593 594 // Done! 595 RET 596 597 // void setg(G*); set g. for use by needm. 598 // This only happens if iscgo, so jump straight to save_g 599 TEXT runtime·setg(SB),NOSPLIT,$0-4 600 MOVW gg+0(FP), g 601 JAL runtime·save_g(SB) 602 RET 603 604 // void setg_gcc(G*); set g in C TLS. 605 // Must obey the gcc calling convention. 606 TEXT setg_gcc<>(SB),NOSPLIT,$0 607 MOVW R4, g 608 JAL runtime·save_g(SB) 609 RET 610 611 TEXT runtime·abort(SB),NOSPLIT,$0-0 612 UNDEF 613 614 // Not implemented. 615 TEXT runtime·aeshash(SB),NOSPLIT,$0 616 UNDEF 617 618 // Not implemented. 619 TEXT runtime·aeshash32(SB),NOSPLIT,$0 620 UNDEF 621 622 // Not implemented. 623 TEXT runtime·aeshash64(SB),NOSPLIT,$0 624 UNDEF 625 626 // Not implemented. 627 TEXT runtime·aeshashstr(SB),NOSPLIT,$0 628 UNDEF 629 630 TEXT runtime·return0(SB),NOSPLIT,$0 631 MOVW $0, R1 632 RET 633 634 // Called from cgo wrappers, this function returns g->m->curg.stack.hi. 635 // Must obey the gcc calling convention. 636 TEXT _cgo_topofstack(SB),NOSPLIT|NOFRAME,$0 637 // g (R30), R3 and REGTMP (R23) might be clobbered by load_g. R30 and R23 638 // are callee-save in the gcc calling convention, so save them. 639 MOVW R23, R8 640 MOVW g, R9 641 MOVW R31, R10 // this call frame does not save LR 642 643 JAL runtime·load_g(SB) 644 MOVW g_m(g), R1 645 MOVW m_curg(R1), R1 646 MOVW (g_stack+stack_hi)(R1), R2 // return value in R2 647 648 MOVW R8, R23 649 MOVW R9, g 650 MOVW R10, R31 651 652 RET 653 654 // The top-most function running on a goroutine 655 // returns to goexit+PCQuantum. 656 TEXT runtime·goexit(SB),NOSPLIT|NOFRAME,$0-0 657 NOR R0, R0 // NOP 658 JAL runtime·goexit1(SB) // does not return 659 // traceback from goexit1 must hit code range of goexit 660 NOR R0, R0 // NOP 661 662 TEXT ·checkASM(SB),NOSPLIT,$0-1 663 MOVW $1, R1 664 MOVB R1, ret+0(FP) 665 RET 666 667 // gcWriteBarrier performs a heap pointer write and informs the GC. 668 // 669 // gcWriteBarrier does NOT follow the Go ABI. It takes two arguments: 670 // - R20 is the destination of the write 671 // - R21 is the value being written at R20. 672 // It clobbers R23 (the linker temp register). 673 // The act of CALLing gcWriteBarrier will clobber R31 (LR). 674 // It does not clobber any other general-purpose registers, 675 // but may clobber others (e.g., floating point registers). 676 TEXT runtime·gcWriteBarrier(SB),NOSPLIT,$104 677 // Save the registers clobbered by the fast path. 678 MOVW R1, 100(R29) 679 MOVW R2, 104(R29) 680 MOVW g_m(g), R1 681 MOVW m_p(R1), R1 682 MOVW (p_wbBuf+wbBuf_next)(R1), R2 683 // Increment wbBuf.next position. 684 ADD $8, R2 685 MOVW R2, (p_wbBuf+wbBuf_next)(R1) 686 MOVW (p_wbBuf+wbBuf_end)(R1), R1 687 MOVW R1, R23 // R23 is linker temp register 688 // Record the write. 689 MOVW R21, -8(R2) // Record value 690 MOVW (R20), R1 // TODO: This turns bad writes into bad reads. 691 MOVW R1, -4(R2) // Record *slot 692 // Is the buffer full? 693 BEQ R2, R23, flush 694 ret: 695 MOVW 100(R29), R1 696 MOVW 104(R29), R2 697 // Do the write. 698 MOVW R21, (R20) 699 RET 700 701 flush: 702 // Save all general purpose registers since these could be 703 // clobbered by wbBufFlush and were not saved by the caller. 704 MOVW R20, 4(R29) // Also first argument to wbBufFlush 705 MOVW R21, 8(R29) // Also second argument to wbBufFlush 706 // R1 already saved 707 // R2 already saved 708 MOVW R3, 12(R29) 709 MOVW R4, 16(R29) 710 MOVW R5, 20(R29) 711 MOVW R6, 24(R29) 712 MOVW R7, 28(R29) 713 MOVW R8, 32(R29) 714 MOVW R9, 36(R29) 715 MOVW R10, 40(R29) 716 MOVW R11, 44(R29) 717 MOVW R12, 48(R29) 718 MOVW R13, 52(R29) 719 MOVW R14, 56(R29) 720 MOVW R15, 60(R29) 721 MOVW R16, 64(R29) 722 MOVW R17, 68(R29) 723 MOVW R18, 72(R29) 724 MOVW R19, 76(R29) 725 MOVW R20, 80(R29) 726 // R21 already saved 727 // R22 already saved. 728 MOVW R22, 84(R29) 729 // R23 is tmp register. 730 MOVW R24, 88(R29) 731 MOVW R25, 92(R29) 732 // R26 is reserved by kernel. 733 // R27 is reserved by kernel. 734 MOVW R28, 96(R29) 735 // R29 is SP. 736 // R30 is g. 737 // R31 is LR, which was saved by the prologue. 738 739 // This takes arguments R20 and R21. 740 CALL runtime·wbBufFlush(SB) 741 742 MOVW 4(R29), R20 743 MOVW 8(R29), R21 744 MOVW 12(R29), R3 745 MOVW 16(R29), R4 746 MOVW 20(R29), R5 747 MOVW 24(R29), R6 748 MOVW 28(R29), R7 749 MOVW 32(R29), R8 750 MOVW 36(R29), R9 751 MOVW 40(R29), R10 752 MOVW 44(R29), R11 753 MOVW 48(R29), R12 754 MOVW 52(R29), R13 755 MOVW 56(R29), R14 756 MOVW 60(R29), R15 757 MOVW 64(R29), R16 758 MOVW 68(R29), R17 759 MOVW 72(R29), R18 760 MOVW 76(R29), R19 761 MOVW 80(R29), R20 762 MOVW 84(R29), R22 763 MOVW 88(R29), R24 764 MOVW 92(R29), R25 765 MOVW 96(R29), R28 766 JMP ret