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