github.com/gidoBOSSftw5731/go/src@v0.0.0-20210226122457-d24b0edbf019/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|TOPFRAME,$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 TEXT runtime·mstart(SB),NOSPLIT|TOPFRAME,$0 90 JAL runtime·mstart0(SB) 91 RET // not reached 92 93 /* 94 * go-routine 95 */ 96 97 // void gogo(Gobuf*) 98 // restore state from Gobuf; longjmp 99 TEXT runtime·gogo(SB),NOSPLIT|NOFRAME,$0-4 100 MOVW buf+0(FP), R3 101 MOVW gobuf_g(R3), R4 102 MOVW 0(R4), R5 // make sure g != nil 103 JMP gogo<>(SB) 104 105 TEXT gogo<>(SB),NOSPLIT|NOFRAME,$0 106 MOVW R4, g 107 JAL runtime·save_g(SB) 108 MOVW gobuf_sp(R3), R29 109 MOVW gobuf_lr(R3), R31 110 MOVW gobuf_ret(R3), R1 111 MOVW gobuf_ctxt(R3), REGCTXT 112 MOVW R0, gobuf_sp(R3) 113 MOVW R0, gobuf_ret(R3) 114 MOVW R0, gobuf_lr(R3) 115 MOVW R0, gobuf_ctxt(R3) 116 MOVW gobuf_pc(R3), R4 117 JMP (R4) 118 119 // void mcall(fn func(*g)) 120 // Switch to m->g0's stack, call fn(g). 121 // Fn must never return. It should gogo(&g->sched) 122 // to keep running g. 123 TEXT runtime·mcall(SB),NOSPLIT|NOFRAME,$0-4 124 // Save caller state in g->sched 125 MOVW R29, (g_sched+gobuf_sp)(g) 126 MOVW R31, (g_sched+gobuf_pc)(g) 127 MOVW R0, (g_sched+gobuf_lr)(g) 128 129 // Switch to m->g0 & its stack, call fn. 130 MOVW g, R1 131 MOVW g_m(g), R3 132 MOVW m_g0(R3), g 133 JAL runtime·save_g(SB) 134 BNE g, R1, 2(PC) 135 JMP runtime·badmcall(SB) 136 MOVW fn+0(FP), REGCTXT // context 137 MOVW 0(REGCTXT), R4 // code pointer 138 MOVW (g_sched+gobuf_sp)(g), R29 // sp = m->g0->sched.sp 139 ADDU $-8, R29 // make room for 1 arg and fake LR 140 MOVW R1, 4(R29) 141 MOVW R0, 0(R29) 142 JAL (R4) 143 JMP runtime·badmcall2(SB) 144 145 // systemstack_switch is a dummy routine that systemstack leaves at the bottom 146 // of the G stack. We need to distinguish the routine that 147 // lives at the bottom of the G stack from the one that lives 148 // at the top of the system stack because the one at the top of 149 // the system stack terminates the stack walk (see topofstack()). 150 TEXT runtime·systemstack_switch(SB),NOSPLIT,$0-0 151 UNDEF 152 JAL (R31) // make sure this function is not leaf 153 RET 154 155 // func systemstack(fn func()) 156 TEXT runtime·systemstack(SB),NOSPLIT,$0-4 157 MOVW fn+0(FP), R1 // R1 = fn 158 MOVW R1, REGCTXT // context 159 MOVW g_m(g), R2 // R2 = m 160 161 MOVW m_gsignal(R2), R3 // R3 = gsignal 162 BEQ g, R3, noswitch 163 164 MOVW m_g0(R2), R3 // R3 = g0 165 BEQ g, R3, noswitch 166 167 MOVW m_curg(R2), R4 168 BEQ g, R4, switch 169 170 // Bad: g is not gsignal, not g0, not curg. What is it? 171 // Hide call from linker nosplit analysis. 172 MOVW $runtime·badsystemstack(SB), R4 173 JAL (R4) 174 JAL runtime·abort(SB) 175 176 switch: 177 // save our state in g->sched. Pretend to 178 // be systemstack_switch if the G stack is scanned. 179 JAL gosave_systemstack_switch<>(SB) 180 181 // switch to g0 182 MOVW R3, g 183 JAL runtime·save_g(SB) 184 MOVW (g_sched+gobuf_sp)(g), R1 185 MOVW R1, R29 186 187 // call target function 188 MOVW 0(REGCTXT), R4 // code pointer 189 JAL (R4) 190 191 // switch back to g 192 MOVW g_m(g), R1 193 MOVW m_curg(R1), g 194 JAL runtime·save_g(SB) 195 MOVW (g_sched+gobuf_sp)(g), R29 196 MOVW R0, (g_sched+gobuf_sp)(g) 197 RET 198 199 noswitch: 200 // already on m stack, just call directly 201 // Using a tail call here cleans up tracebacks since we won't stop 202 // at an intermediate systemstack. 203 MOVW 0(REGCTXT), R4 // code pointer 204 MOVW 0(R29), R31 // restore LR 205 ADD $4, R29 206 JMP (R4) 207 208 /* 209 * support for morestack 210 */ 211 212 // Called during function prolog when more stack is needed. 213 // Caller has already loaded: 214 // R1: framesize, R2: argsize, R3: LR 215 // 216 // The traceback routines see morestack on a g0 as being 217 // the top of a stack (for example, morestack calling newstack 218 // calling the scheduler calling newm calling gc), so we must 219 // record an argument size. For that purpose, it has no arguments. 220 TEXT runtime·morestack(SB),NOSPLIT|NOFRAME,$0-0 221 // Cannot grow scheduler stack (m->g0). 222 MOVW g_m(g), R7 223 MOVW m_g0(R7), R8 224 BNE g, R8, 3(PC) 225 JAL runtime·badmorestackg0(SB) 226 JAL runtime·abort(SB) 227 228 // Cannot grow signal stack (m->gsignal). 229 MOVW m_gsignal(R7), R8 230 BNE g, R8, 3(PC) 231 JAL runtime·badmorestackgsignal(SB) 232 JAL runtime·abort(SB) 233 234 // Called from f. 235 // Set g->sched to context in f. 236 MOVW R29, (g_sched+gobuf_sp)(g) 237 MOVW R31, (g_sched+gobuf_pc)(g) 238 MOVW R3, (g_sched+gobuf_lr)(g) 239 MOVW REGCTXT, (g_sched+gobuf_ctxt)(g) 240 241 // Called from f. 242 // Set m->morebuf to f's caller. 243 MOVW R3, (m_morebuf+gobuf_pc)(R7) // f's caller's PC 244 MOVW R29, (m_morebuf+gobuf_sp)(R7) // f's caller's SP 245 MOVW g, (m_morebuf+gobuf_g)(R7) 246 247 // Call newstack on m->g0's stack. 248 MOVW m_g0(R7), g 249 JAL runtime·save_g(SB) 250 MOVW (g_sched+gobuf_sp)(g), R29 251 // Create a stack frame on g0 to call newstack. 252 MOVW R0, -4(R29) // Zero saved LR in frame 253 ADDU $-4, R29 254 JAL runtime·newstack(SB) 255 256 // Not reached, but make sure the return PC from the call to newstack 257 // is still in this function, and not the beginning of the next. 258 UNDEF 259 260 TEXT runtime·morestack_noctxt(SB),NOSPLIT,$0-0 261 MOVW R0, REGCTXT 262 JMP runtime·morestack(SB) 263 264 // reflectcall: call a function with the given argument list 265 // func call(stackArgsType *_type, f *FuncVal, stackArgs *byte, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs). 266 // we don't have variable-sized frames, so we use a small number 267 // of constant-sized-frame functions to encode a few bits of size in the pc. 268 269 #define DISPATCH(NAME,MAXSIZE) \ 270 MOVW $MAXSIZE, R23; \ 271 SGTU R1, R23, R23; \ 272 BNE R23, 3(PC); \ 273 MOVW $NAME(SB), R4; \ 274 JMP (R4) 275 276 TEXT ·reflectcall(SB),NOSPLIT|NOFRAME,$0-28 277 MOVW frameSize+20(FP), R1 278 279 DISPATCH(runtime·call16, 16) 280 DISPATCH(runtime·call32, 32) 281 DISPATCH(runtime·call64, 64) 282 DISPATCH(runtime·call128, 128) 283 DISPATCH(runtime·call256, 256) 284 DISPATCH(runtime·call512, 512) 285 DISPATCH(runtime·call1024, 1024) 286 DISPATCH(runtime·call2048, 2048) 287 DISPATCH(runtime·call4096, 4096) 288 DISPATCH(runtime·call8192, 8192) 289 DISPATCH(runtime·call16384, 16384) 290 DISPATCH(runtime·call32768, 32768) 291 DISPATCH(runtime·call65536, 65536) 292 DISPATCH(runtime·call131072, 131072) 293 DISPATCH(runtime·call262144, 262144) 294 DISPATCH(runtime·call524288, 524288) 295 DISPATCH(runtime·call1048576, 1048576) 296 DISPATCH(runtime·call2097152, 2097152) 297 DISPATCH(runtime·call4194304, 4194304) 298 DISPATCH(runtime·call8388608, 8388608) 299 DISPATCH(runtime·call16777216, 16777216) 300 DISPATCH(runtime·call33554432, 33554432) 301 DISPATCH(runtime·call67108864, 67108864) 302 DISPATCH(runtime·call134217728, 134217728) 303 DISPATCH(runtime·call268435456, 268435456) 304 DISPATCH(runtime·call536870912, 536870912) 305 DISPATCH(runtime·call1073741824, 1073741824) 306 MOVW $runtime·badreflectcall(SB), R4 307 JMP (R4) 308 309 #define CALLFN(NAME,MAXSIZE) \ 310 TEXT NAME(SB),WRAPPER,$MAXSIZE-28; \ 311 NO_LOCAL_POINTERS; \ 312 /* copy arguments to stack */ \ 313 MOVW stackArgs+8(FP), R1; \ 314 MOVW stackArgsSize+12(FP), R2; \ 315 MOVW R29, R3; \ 316 ADDU $4, R3; \ 317 ADDU R3, R2; \ 318 BEQ R3, R2, 6(PC); \ 319 MOVBU (R1), R4; \ 320 ADDU $1, R1; \ 321 MOVBU R4, (R3); \ 322 ADDU $1, R3; \ 323 JMP -5(PC); \ 324 /* call function */ \ 325 MOVW f+4(FP), REGCTXT; \ 326 MOVW (REGCTXT), R4; \ 327 PCDATA $PCDATA_StackMapIndex, $0; \ 328 JAL (R4); \ 329 /* copy return values back */ \ 330 MOVW stackArgsType+0(FP), R5; \ 331 MOVW stackArgs+8(FP), R1; \ 332 MOVW stackArgsSize+12(FP), R2; \ 333 MOVW stackRetOffset+16(FP), R4; \ 334 ADDU $4, R29, R3; \ 335 ADDU R4, R3; \ 336 ADDU R4, R1; \ 337 SUBU R4, R2; \ 338 JAL callRet<>(SB); \ 339 RET 340 341 // callRet copies return values back at the end of call*. This is a 342 // separate function so it can allocate stack space for the arguments 343 // to reflectcallmove. It does not follow the Go ABI; it expects its 344 // arguments in registers. 345 TEXT callRet<>(SB), NOSPLIT, $20-0 346 MOVW R5, 4(R29) 347 MOVW R1, 8(R29) 348 MOVW R3, 12(R29) 349 MOVW R2, 16(R29) 350 MOVW $0, 20(R29) 351 JAL runtime·reflectcallmove(SB) 352 RET 353 354 CALLFN(·call16, 16) 355 CALLFN(·call32, 32) 356 CALLFN(·call64, 64) 357 CALLFN(·call128, 128) 358 CALLFN(·call256, 256) 359 CALLFN(·call512, 512) 360 CALLFN(·call1024, 1024) 361 CALLFN(·call2048, 2048) 362 CALLFN(·call4096, 4096) 363 CALLFN(·call8192, 8192) 364 CALLFN(·call16384, 16384) 365 CALLFN(·call32768, 32768) 366 CALLFN(·call65536, 65536) 367 CALLFN(·call131072, 131072) 368 CALLFN(·call262144, 262144) 369 CALLFN(·call524288, 524288) 370 CALLFN(·call1048576, 1048576) 371 CALLFN(·call2097152, 2097152) 372 CALLFN(·call4194304, 4194304) 373 CALLFN(·call8388608, 8388608) 374 CALLFN(·call16777216, 16777216) 375 CALLFN(·call33554432, 33554432) 376 CALLFN(·call67108864, 67108864) 377 CALLFN(·call134217728, 134217728) 378 CALLFN(·call268435456, 268435456) 379 CALLFN(·call536870912, 536870912) 380 CALLFN(·call1073741824, 1073741824) 381 382 TEXT runtime·procyield(SB),NOSPLIT,$0-4 383 RET 384 385 // void jmpdefer(fv, sp); 386 // called from deferreturn. 387 // 1. grab stored LR for caller 388 // 2. sub 8 bytes to get back to JAL deferreturn 389 // 3. JMP to fn 390 TEXT runtime·jmpdefer(SB),NOSPLIT,$0-8 391 MOVW 0(R29), R31 392 ADDU $-8, R31 393 394 MOVW fv+0(FP), REGCTXT 395 MOVW argp+4(FP), R29 396 ADDU $-4, R29 397 NOR R0, R0 // prevent scheduling 398 MOVW 0(REGCTXT), R4 399 JMP (R4) 400 401 // Save state of caller into g->sched, 402 // but using fake PC from systemstack_switch. 403 // Must only be called from functions with no locals ($0) 404 // or else unwinding from systemstack_switch is incorrect. 405 // Smashes R1. 406 TEXT gosave_systemstack_switch<>(SB),NOSPLIT|NOFRAME,$0 407 MOVW $runtime·systemstack_switch(SB), R1 408 ADDU $8, R1 // get past prologue 409 MOVW R1, (g_sched+gobuf_pc)(g) 410 MOVW R29, (g_sched+gobuf_sp)(g) 411 MOVW R0, (g_sched+gobuf_lr)(g) 412 MOVW R0, (g_sched+gobuf_ret)(g) 413 // Assert ctxt is zero. See func save. 414 MOVW (g_sched+gobuf_ctxt)(g), R1 415 BEQ R1, 2(PC) 416 JAL runtime·abort(SB) 417 RET 418 419 // func asmcgocall(fn, arg unsafe.Pointer) int32 420 // Call fn(arg) on the scheduler stack, 421 // aligned appropriately for the gcc ABI. 422 // See cgocall.go for more details. 423 TEXT ·asmcgocall(SB),NOSPLIT,$0-12 424 MOVW fn+0(FP), R25 425 MOVW arg+4(FP), R4 426 427 MOVW R29, R3 // save original stack pointer 428 MOVW g, R2 429 430 // Figure out if we need to switch to m->g0 stack. 431 // We get called to create new OS threads too, and those 432 // come in on the m->g0 stack already. 433 MOVW g_m(g), R5 434 MOVW m_g0(R5), R6 435 BEQ R6, g, g0 436 437 JAL gosave_systemstack_switch<>(SB) 438 MOVW R6, g 439 JAL runtime·save_g(SB) 440 MOVW (g_sched+gobuf_sp)(g), R29 441 442 // Now on a scheduling stack (a pthread-created stack). 443 g0: 444 // Save room for two of our pointers and O32 frame. 445 ADDU $-24, R29 446 AND $~7, R29 // O32 ABI expects 8-byte aligned stack on function entry 447 MOVW R2, 16(R29) // save old g on stack 448 MOVW (g_stack+stack_hi)(R2), R2 449 SUBU R3, R2 450 MOVW R2, 20(R29) // save depth in old g stack (can't just save SP, as stack might be copied during a callback) 451 JAL (R25) 452 453 // Restore g, stack pointer. R2 is return value. 454 MOVW 16(R29), g 455 JAL runtime·save_g(SB) 456 MOVW (g_stack+stack_hi)(g), R5 457 MOVW 20(R29), R6 458 SUBU R6, R5 459 MOVW R5, R29 460 461 MOVW R2, ret+8(FP) 462 RET 463 464 // cgocallback(fn, frame unsafe.Pointer, ctxt uintptr) 465 // See cgocall.go for more details. 466 TEXT ·cgocallback(SB),NOSPLIT,$12-12 467 NO_LOCAL_POINTERS 468 469 // Load m and g from thread-local storage. 470 MOVB runtime·iscgo(SB), R1 471 BEQ R1, nocgo 472 JAL runtime·load_g(SB) 473 nocgo: 474 475 // If g is nil, Go did not create the current thread. 476 // Call needm to obtain one for temporary use. 477 // In this case, we're running on the thread stack, so there's 478 // lots of space, but the linker doesn't know. Hide the call from 479 // the linker analysis by using an indirect call. 480 BEQ g, needm 481 482 MOVW g_m(g), R3 483 MOVW R3, savedm-4(SP) 484 JMP havem 485 486 needm: 487 MOVW g, savedm-4(SP) // g is zero, so is m. 488 MOVW $runtime·needm(SB), R4 489 JAL (R4) 490 491 // Set m->sched.sp = SP, so that if a panic happens 492 // during the function we are about to execute, it will 493 // have a valid SP to run on the g0 stack. 494 // The next few lines (after the havem label) 495 // will save this SP onto the stack and then write 496 // the same SP back to m->sched.sp. That seems redundant, 497 // but if an unrecovered panic happens, unwindm will 498 // restore the g->sched.sp from the stack location 499 // and then systemstack will try to use it. If we don't set it here, 500 // that restored SP will be uninitialized (typically 0) and 501 // will not be usable. 502 MOVW g_m(g), R3 503 MOVW m_g0(R3), R1 504 MOVW R29, (g_sched+gobuf_sp)(R1) 505 506 havem: 507 // Now there's a valid m, and we're running on its m->g0. 508 // Save current m->g0->sched.sp on stack and then set it to SP. 509 // Save current sp in m->g0->sched.sp in preparation for 510 // switch back to m->curg stack. 511 // NOTE: unwindm knows that the saved g->sched.sp is at 4(R29) aka savedsp-8(SP). 512 MOVW m_g0(R3), R1 513 MOVW (g_sched+gobuf_sp)(R1), R2 514 MOVW R2, savedsp-12(SP) // must match frame size 515 MOVW R29, (g_sched+gobuf_sp)(R1) 516 517 // Switch to m->curg stack and call runtime.cgocallbackg. 518 // Because we are taking over the execution of m->curg 519 // but *not* resuming what had been running, we need to 520 // save that information (m->curg->sched) so we can restore it. 521 // We can restore m->curg->sched.sp easily, because calling 522 // runtime.cgocallbackg leaves SP unchanged upon return. 523 // To save m->curg->sched.pc, we push it onto the curg stack and 524 // open a frame the same size as cgocallback's g0 frame. 525 // Once we switch to the curg stack, the pushed PC will appear 526 // to be the return PC of cgocallback, so that the traceback 527 // will seamlessly trace back into the earlier calls. 528 MOVW m_curg(R3), g 529 JAL runtime·save_g(SB) 530 MOVW (g_sched+gobuf_sp)(g), R2 // prepare stack as R2 531 MOVW (g_sched+gobuf_pc)(g), R4 532 MOVW R4, -(12+4)(R2) // "saved LR"; must match frame size 533 // Gather our arguments into registers. 534 MOVW fn+0(FP), R5 535 MOVW frame+4(FP), R6 536 MOVW ctxt+8(FP), R7 537 MOVW $-(12+4)(R2), R29 // switch stack; must match frame size 538 MOVW R5, 4(R29) 539 MOVW R6, 8(R29) 540 MOVW R7, 12(R29) 541 JAL runtime·cgocallbackg(SB) 542 543 // Restore g->sched (== m->curg->sched) from saved values. 544 MOVW 0(R29), R4 545 MOVW R4, (g_sched+gobuf_pc)(g) 546 MOVW $(12+4)(R29), R2 // must match frame size 547 MOVW R2, (g_sched+gobuf_sp)(g) 548 549 // Switch back to m->g0's stack and restore m->g0->sched.sp. 550 // (Unlike m->curg, the g0 goroutine never uses sched.pc, 551 // so we do not have to restore it.) 552 MOVW g_m(g), R3 553 MOVW m_g0(R3), g 554 JAL runtime·save_g(SB) 555 MOVW (g_sched+gobuf_sp)(g), R29 556 MOVW savedsp-12(SP), R2 // must match frame size 557 MOVW R2, (g_sched+gobuf_sp)(g) 558 559 // If the m on entry was nil, we called needm above to borrow an m 560 // for the duration of the call. Since the call is over, return it with dropm. 561 MOVW savedm-4(SP), R3 562 BNE R3, droppedm 563 MOVW $runtime·dropm(SB), R4 564 JAL (R4) 565 droppedm: 566 567 // Done! 568 RET 569 570 // void setg(G*); set g. for use by needm. 571 // This only happens if iscgo, so jump straight to save_g 572 TEXT runtime·setg(SB),NOSPLIT,$0-4 573 MOVW gg+0(FP), g 574 JAL runtime·save_g(SB) 575 RET 576 577 // void setg_gcc(G*); set g in C TLS. 578 // Must obey the gcc calling convention. 579 TEXT setg_gcc<>(SB),NOSPLIT,$0 580 MOVW R4, g 581 JAL runtime·save_g(SB) 582 RET 583 584 TEXT runtime·abort(SB),NOSPLIT,$0-0 585 UNDEF 586 587 // AES hashing not implemented for mips 588 TEXT runtime·memhash(SB),NOSPLIT|NOFRAME,$0-16 589 JMP runtime·memhashFallback(SB) 590 TEXT runtime·strhash(SB),NOSPLIT|NOFRAME,$0-12 591 JMP runtime·strhashFallback(SB) 592 TEXT runtime·memhash32(SB),NOSPLIT|NOFRAME,$0-12 593 JMP runtime·memhash32Fallback(SB) 594 TEXT runtime·memhash64(SB),NOSPLIT|NOFRAME,$0-12 595 JMP runtime·memhash64Fallback(SB) 596 597 TEXT runtime·return0(SB),NOSPLIT,$0 598 MOVW $0, R1 599 RET 600 601 // Called from cgo wrappers, this function returns g->m->curg.stack.hi. 602 // Must obey the gcc calling convention. 603 TEXT _cgo_topofstack(SB),NOSPLIT|NOFRAME,$0 604 // g (R30), R3 and REGTMP (R23) might be clobbered by load_g. R30 and R23 605 // are callee-save in the gcc calling convention, so save them. 606 MOVW R23, R8 607 MOVW g, R9 608 MOVW R31, R10 // this call frame does not save LR 609 610 JAL runtime·load_g(SB) 611 MOVW g_m(g), R1 612 MOVW m_curg(R1), R1 613 MOVW (g_stack+stack_hi)(R1), R2 // return value in R2 614 615 MOVW R8, R23 616 MOVW R9, g 617 MOVW R10, R31 618 619 RET 620 621 // The top-most function running on a goroutine 622 // returns to goexit+PCQuantum. 623 TEXT runtime·goexit(SB),NOSPLIT|NOFRAME|TOPFRAME,$0-0 624 NOR R0, R0 // NOP 625 JAL runtime·goexit1(SB) // does not return 626 // traceback from goexit1 must hit code range of goexit 627 NOR R0, R0 // NOP 628 629 TEXT ·checkASM(SB),NOSPLIT,$0-1 630 MOVW $1, R1 631 MOVB R1, ret+0(FP) 632 RET 633 634 // gcWriteBarrier performs a heap pointer write and informs the GC. 635 // 636 // gcWriteBarrier does NOT follow the Go ABI. It takes two arguments: 637 // - R20 is the destination of the write 638 // - R21 is the value being written at R20. 639 // It clobbers R23 (the linker temp register). 640 // The act of CALLing gcWriteBarrier will clobber R31 (LR). 641 // It does not clobber any other general-purpose registers, 642 // but may clobber others (e.g., floating point registers). 643 TEXT runtime·gcWriteBarrier(SB),NOSPLIT,$104 644 // Save the registers clobbered by the fast path. 645 MOVW R1, 100(R29) 646 MOVW R2, 104(R29) 647 MOVW g_m(g), R1 648 MOVW m_p(R1), R1 649 MOVW (p_wbBuf+wbBuf_next)(R1), R2 650 // Increment wbBuf.next position. 651 ADD $8, R2 652 MOVW R2, (p_wbBuf+wbBuf_next)(R1) 653 MOVW (p_wbBuf+wbBuf_end)(R1), R1 654 MOVW R1, R23 // R23 is linker temp register 655 // Record the write. 656 MOVW R21, -8(R2) // Record value 657 MOVW (R20), R1 // TODO: This turns bad writes into bad reads. 658 MOVW R1, -4(R2) // Record *slot 659 // Is the buffer full? 660 BEQ R2, R23, flush 661 ret: 662 MOVW 100(R29), R1 663 MOVW 104(R29), R2 664 // Do the write. 665 MOVW R21, (R20) 666 RET 667 668 flush: 669 // Save all general purpose registers since these could be 670 // clobbered by wbBufFlush and were not saved by the caller. 671 MOVW R20, 4(R29) // Also first argument to wbBufFlush 672 MOVW R21, 8(R29) // Also second argument to wbBufFlush 673 // R1 already saved 674 // R2 already saved 675 MOVW R3, 12(R29) 676 MOVW R4, 16(R29) 677 MOVW R5, 20(R29) 678 MOVW R6, 24(R29) 679 MOVW R7, 28(R29) 680 MOVW R8, 32(R29) 681 MOVW R9, 36(R29) 682 MOVW R10, 40(R29) 683 MOVW R11, 44(R29) 684 MOVW R12, 48(R29) 685 MOVW R13, 52(R29) 686 MOVW R14, 56(R29) 687 MOVW R15, 60(R29) 688 MOVW R16, 64(R29) 689 MOVW R17, 68(R29) 690 MOVW R18, 72(R29) 691 MOVW R19, 76(R29) 692 MOVW R20, 80(R29) 693 // R21 already saved 694 // R22 already saved. 695 MOVW R22, 84(R29) 696 // R23 is tmp register. 697 MOVW R24, 88(R29) 698 MOVW R25, 92(R29) 699 // R26 is reserved by kernel. 700 // R27 is reserved by kernel. 701 MOVW R28, 96(R29) 702 // R29 is SP. 703 // R30 is g. 704 // R31 is LR, which was saved by the prologue. 705 706 // This takes arguments R20 and R21. 707 CALL runtime·wbBufFlush(SB) 708 709 MOVW 4(R29), R20 710 MOVW 8(R29), R21 711 MOVW 12(R29), R3 712 MOVW 16(R29), R4 713 MOVW 20(R29), R5 714 MOVW 24(R29), R6 715 MOVW 28(R29), R7 716 MOVW 32(R29), R8 717 MOVW 36(R29), R9 718 MOVW 40(R29), R10 719 MOVW 44(R29), R11 720 MOVW 48(R29), R12 721 MOVW 52(R29), R13 722 MOVW 56(R29), R14 723 MOVW 60(R29), R15 724 MOVW 64(R29), R16 725 MOVW 68(R29), R17 726 MOVW 72(R29), R18 727 MOVW 76(R29), R19 728 MOVW 80(R29), R20 729 MOVW 84(R29), R22 730 MOVW 88(R29), R24 731 MOVW 92(R29), R25 732 MOVW 96(R29), R28 733 JMP ret 734 735 // Note: these functions use a special calling convention to save generated code space. 736 // Arguments are passed in registers, but the space for those arguments are allocated 737 // in the caller's stack frame. These stubs write the args into that stack space and 738 // then tail call to the corresponding runtime handler. 739 // The tail call makes these stubs disappear in backtraces. 740 TEXT runtime·panicIndex(SB),NOSPLIT,$0-8 741 MOVW R1, x+0(FP) 742 MOVW R2, y+4(FP) 743 JMP runtime·goPanicIndex(SB) 744 TEXT runtime·panicIndexU(SB),NOSPLIT,$0-8 745 MOVW R1, x+0(FP) 746 MOVW R2, y+4(FP) 747 JMP runtime·goPanicIndexU(SB) 748 TEXT runtime·panicSliceAlen(SB),NOSPLIT,$0-8 749 MOVW R2, x+0(FP) 750 MOVW R3, y+4(FP) 751 JMP runtime·goPanicSliceAlen(SB) 752 TEXT runtime·panicSliceAlenU(SB),NOSPLIT,$0-8 753 MOVW R2, x+0(FP) 754 MOVW R3, y+4(FP) 755 JMP runtime·goPanicSliceAlenU(SB) 756 TEXT runtime·panicSliceAcap(SB),NOSPLIT,$0-8 757 MOVW R2, x+0(FP) 758 MOVW R3, y+4(FP) 759 JMP runtime·goPanicSliceAcap(SB) 760 TEXT runtime·panicSliceAcapU(SB),NOSPLIT,$0-8 761 MOVW R2, x+0(FP) 762 MOVW R3, y+4(FP) 763 JMP runtime·goPanicSliceAcapU(SB) 764 TEXT runtime·panicSliceB(SB),NOSPLIT,$0-8 765 MOVW R1, x+0(FP) 766 MOVW R2, y+4(FP) 767 JMP runtime·goPanicSliceB(SB) 768 TEXT runtime·panicSliceBU(SB),NOSPLIT,$0-8 769 MOVW R1, x+0(FP) 770 MOVW R2, y+4(FP) 771 JMP runtime·goPanicSliceBU(SB) 772 TEXT runtime·panicSlice3Alen(SB),NOSPLIT,$0-8 773 MOVW R3, x+0(FP) 774 MOVW R4, y+4(FP) 775 JMP runtime·goPanicSlice3Alen(SB) 776 TEXT runtime·panicSlice3AlenU(SB),NOSPLIT,$0-8 777 MOVW R3, x+0(FP) 778 MOVW R4, y+4(FP) 779 JMP runtime·goPanicSlice3AlenU(SB) 780 TEXT runtime·panicSlice3Acap(SB),NOSPLIT,$0-8 781 MOVW R3, x+0(FP) 782 MOVW R4, y+4(FP) 783 JMP runtime·goPanicSlice3Acap(SB) 784 TEXT runtime·panicSlice3AcapU(SB),NOSPLIT,$0-8 785 MOVW R3, x+0(FP) 786 MOVW R4, y+4(FP) 787 JMP runtime·goPanicSlice3AcapU(SB) 788 TEXT runtime·panicSlice3B(SB),NOSPLIT,$0-8 789 MOVW R2, x+0(FP) 790 MOVW R3, y+4(FP) 791 JMP runtime·goPanicSlice3B(SB) 792 TEXT runtime·panicSlice3BU(SB),NOSPLIT,$0-8 793 MOVW R2, x+0(FP) 794 MOVW R3, y+4(FP) 795 JMP runtime·goPanicSlice3BU(SB) 796 TEXT runtime·panicSlice3C(SB),NOSPLIT,$0-8 797 MOVW R1, x+0(FP) 798 MOVW R2, y+4(FP) 799 JMP runtime·goPanicSlice3C(SB) 800 TEXT runtime·panicSlice3CU(SB),NOSPLIT,$0-8 801 MOVW R1, x+0(FP) 802 MOVW R2, y+4(FP) 803 JMP runtime·goPanicSlice3CU(SB) 804 805 // Extended versions for 64-bit indexes. 806 TEXT runtime·panicExtendIndex(SB),NOSPLIT,$0-12 807 MOVW R5, hi+0(FP) 808 MOVW R1, lo+4(FP) 809 MOVW R2, y+8(FP) 810 JMP runtime·goPanicExtendIndex(SB) 811 TEXT runtime·panicExtendIndexU(SB),NOSPLIT,$0-12 812 MOVW R5, hi+0(FP) 813 MOVW R1, lo+4(FP) 814 MOVW R2, y+8(FP) 815 JMP runtime·goPanicExtendIndexU(SB) 816 TEXT runtime·panicExtendSliceAlen(SB),NOSPLIT,$0-12 817 MOVW R5, hi+0(FP) 818 MOVW R2, lo+4(FP) 819 MOVW R3, y+8(FP) 820 JMP runtime·goPanicExtendSliceAlen(SB) 821 TEXT runtime·panicExtendSliceAlenU(SB),NOSPLIT,$0-12 822 MOVW R5, hi+0(FP) 823 MOVW R2, lo+4(FP) 824 MOVW R3, y+8(FP) 825 JMP runtime·goPanicExtendSliceAlenU(SB) 826 TEXT runtime·panicExtendSliceAcap(SB),NOSPLIT,$0-12 827 MOVW R5, hi+0(FP) 828 MOVW R2, lo+4(FP) 829 MOVW R3, y+8(FP) 830 JMP runtime·goPanicExtendSliceAcap(SB) 831 TEXT runtime·panicExtendSliceAcapU(SB),NOSPLIT,$0-12 832 MOVW R5, hi+0(FP) 833 MOVW R2, lo+4(FP) 834 MOVW R3, y+8(FP) 835 JMP runtime·goPanicExtendSliceAcapU(SB) 836 TEXT runtime·panicExtendSliceB(SB),NOSPLIT,$0-12 837 MOVW R5, hi+0(FP) 838 MOVW R1, lo+4(FP) 839 MOVW R2, y+8(FP) 840 JMP runtime·goPanicExtendSliceB(SB) 841 TEXT runtime·panicExtendSliceBU(SB),NOSPLIT,$0-12 842 MOVW R5, hi+0(FP) 843 MOVW R1, lo+4(FP) 844 MOVW R2, y+8(FP) 845 JMP runtime·goPanicExtendSliceBU(SB) 846 TEXT runtime·panicExtendSlice3Alen(SB),NOSPLIT,$0-12 847 MOVW R5, hi+0(FP) 848 MOVW R3, lo+4(FP) 849 MOVW R4, y+8(FP) 850 JMP runtime·goPanicExtendSlice3Alen(SB) 851 TEXT runtime·panicExtendSlice3AlenU(SB),NOSPLIT,$0-12 852 MOVW R5, hi+0(FP) 853 MOVW R3, lo+4(FP) 854 MOVW R4, y+8(FP) 855 JMP runtime·goPanicExtendSlice3AlenU(SB) 856 TEXT runtime·panicExtendSlice3Acap(SB),NOSPLIT,$0-12 857 MOVW R5, hi+0(FP) 858 MOVW R3, lo+4(FP) 859 MOVW R4, y+8(FP) 860 JMP runtime·goPanicExtendSlice3Acap(SB) 861 TEXT runtime·panicExtendSlice3AcapU(SB),NOSPLIT,$0-12 862 MOVW R5, hi+0(FP) 863 MOVW R3, lo+4(FP) 864 MOVW R4, y+8(FP) 865 JMP runtime·goPanicExtendSlice3AcapU(SB) 866 TEXT runtime·panicExtendSlice3B(SB),NOSPLIT,$0-12 867 MOVW R5, hi+0(FP) 868 MOVW R2, lo+4(FP) 869 MOVW R3, y+8(FP) 870 JMP runtime·goPanicExtendSlice3B(SB) 871 TEXT runtime·panicExtendSlice3BU(SB),NOSPLIT,$0-12 872 MOVW R5, hi+0(FP) 873 MOVW R2, lo+4(FP) 874 MOVW R3, y+8(FP) 875 JMP runtime·goPanicExtendSlice3BU(SB) 876 TEXT runtime·panicExtendSlice3C(SB),NOSPLIT,$0-12 877 MOVW R5, hi+0(FP) 878 MOVW R1, lo+4(FP) 879 MOVW R2, y+8(FP) 880 JMP runtime·goPanicExtendSlice3C(SB) 881 TEXT runtime·panicExtendSlice3CU(SB),NOSPLIT,$0-12 882 MOVW R5, hi+0(FP) 883 MOVW R1, lo+4(FP) 884 MOVW R2, y+8(FP) 885 JMP runtime·goPanicExtendSlice3CU(SB)