github.com/stingnevermore/go@v0.0.0-20180120041312-3810f5bfed72/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 MOVV gobuf_g(R3), g // make sure g is not nil 112 JAL runtime·save_g(SB) 113 114 MOVV 0(g), R2 115 MOVV gobuf_sp(R3), R29 116 MOVV gobuf_lr(R3), R31 117 MOVV gobuf_ret(R3), R1 118 MOVV gobuf_ctxt(R3), REGCTXT 119 MOVV R0, gobuf_sp(R3) 120 MOVV R0, gobuf_ret(R3) 121 MOVV R0, gobuf_lr(R3) 122 MOVV R0, gobuf_ctxt(R3) 123 MOVV gobuf_pc(R3), R4 124 JMP (R4) 125 126 // void mcall(fn func(*g)) 127 // Switch to m->g0's stack, call fn(g). 128 // Fn must never return. It should gogo(&g->sched) 129 // to keep running g. 130 TEXT runtime·mcall(SB), NOSPLIT, $-8-8 131 // Save caller state in g->sched 132 MOVV R29, (g_sched+gobuf_sp)(g) 133 MOVV R31, (g_sched+gobuf_pc)(g) 134 MOVV R0, (g_sched+gobuf_lr)(g) 135 MOVV g, (g_sched+gobuf_g)(g) 136 137 // Switch to m->g0 & its stack, call fn. 138 MOVV g, R1 139 MOVV g_m(g), R3 140 MOVV m_g0(R3), g 141 JAL runtime·save_g(SB) 142 BNE g, R1, 2(PC) 143 JMP runtime·badmcall(SB) 144 MOVV fn+0(FP), REGCTXT // context 145 MOVV 0(REGCTXT), R4 // code pointer 146 MOVV (g_sched+gobuf_sp)(g), R29 // sp = m->g0->sched.sp 147 ADDV $-16, R29 148 MOVV R1, 8(R29) 149 MOVV R0, 0(R29) 150 JAL (R4) 151 JMP runtime·badmcall2(SB) 152 153 // systemstack_switch is a dummy routine that systemstack leaves at the bottom 154 // of the G stack. We need to distinguish the routine that 155 // lives at the bottom of the G stack from the one that lives 156 // at the top of the system stack because the one at the top of 157 // the system stack terminates the stack walk (see topofstack()). 158 TEXT runtime·systemstack_switch(SB), NOSPLIT, $0-0 159 UNDEF 160 JAL (R31) // make sure this function is not leaf 161 RET 162 163 // func systemstack(fn func()) 164 TEXT runtime·systemstack(SB), NOSPLIT, $0-8 165 MOVV fn+0(FP), R1 // R1 = fn 166 MOVV R1, REGCTXT // context 167 MOVV g_m(g), R2 // R2 = m 168 169 MOVV m_gsignal(R2), R3 // R3 = gsignal 170 BEQ g, R3, noswitch 171 172 MOVV m_g0(R2), R3 // R3 = g0 173 BEQ g, R3, noswitch 174 175 MOVV m_curg(R2), R4 176 BEQ g, R4, switch 177 178 // Bad: g is not gsignal, not g0, not curg. What is it? 179 // Hide call from linker nosplit analysis. 180 MOVV $runtime·badsystemstack(SB), R4 181 JAL (R4) 182 183 switch: 184 // save our state in g->sched. Pretend to 185 // be systemstack_switch if the G stack is scanned. 186 MOVV $runtime·systemstack_switch(SB), R4 187 ADDV $8, R4 // get past prologue 188 MOVV R4, (g_sched+gobuf_pc)(g) 189 MOVV R29, (g_sched+gobuf_sp)(g) 190 MOVV R0, (g_sched+gobuf_lr)(g) 191 MOVV g, (g_sched+gobuf_g)(g) 192 193 // switch to g0 194 MOVV R3, g 195 JAL runtime·save_g(SB) 196 MOVV (g_sched+gobuf_sp)(g), R1 197 // make it look like mstart called systemstack on g0, to stop traceback 198 ADDV $-8, R1 199 MOVV $runtime·mstart(SB), R2 200 MOVV R2, 0(R1) 201 MOVV R1, R29 202 203 // call target function 204 MOVV 0(REGCTXT), R4 // code pointer 205 JAL (R4) 206 207 // switch back to g 208 MOVV g_m(g), R1 209 MOVV m_curg(R1), g 210 JAL runtime·save_g(SB) 211 MOVV (g_sched+gobuf_sp)(g), R29 212 MOVV R0, (g_sched+gobuf_sp)(g) 213 RET 214 215 noswitch: 216 // already on m stack, just call directly 217 // Using a tail call here cleans up tracebacks since we won't stop 218 // at an intermediate systemstack. 219 MOVV 0(REGCTXT), R4 // code pointer 220 MOVV 0(R29), R31 // restore LR 221 ADDV $8, R29 222 JMP (R4) 223 224 /* 225 * support for morestack 226 */ 227 228 // Called during function prolog when more stack is needed. 229 // Caller has already loaded: 230 // R1: framesize, R2: argsize, R3: LR 231 // 232 // The traceback routines see morestack on a g0 as being 233 // the top of a stack (for example, morestack calling newstack 234 // calling the scheduler calling newm calling gc), so we must 235 // record an argument size. For that purpose, it has no arguments. 236 TEXT runtime·morestack(SB),NOSPLIT,$-8-0 237 // Cannot grow scheduler stack (m->g0). 238 MOVV g_m(g), R7 239 MOVV m_g0(R7), R8 240 BNE g, R8, 3(PC) 241 JAL runtime·badmorestackg0(SB) 242 JAL runtime·abort(SB) 243 244 // Cannot grow signal stack (m->gsignal). 245 MOVV m_gsignal(R7), R8 246 BNE g, R8, 3(PC) 247 JAL runtime·badmorestackgsignal(SB) 248 JAL runtime·abort(SB) 249 250 // Called from f. 251 // Set g->sched to context in f. 252 MOVV R29, (g_sched+gobuf_sp)(g) 253 MOVV R31, (g_sched+gobuf_pc)(g) 254 MOVV R3, (g_sched+gobuf_lr)(g) 255 MOVV REGCTXT, (g_sched+gobuf_ctxt)(g) 256 257 // Called from f. 258 // Set m->morebuf to f's caller. 259 MOVV R3, (m_morebuf+gobuf_pc)(R7) // f's caller's PC 260 MOVV R29, (m_morebuf+gobuf_sp)(R7) // f's caller's SP 261 MOVV g, (m_morebuf+gobuf_g)(R7) 262 263 // Call newstack on m->g0's stack. 264 MOVV m_g0(R7), g 265 JAL runtime·save_g(SB) 266 MOVV (g_sched+gobuf_sp)(g), R29 267 // Create a stack frame on g0 to call newstack. 268 MOVV R0, -8(R29) // Zero saved LR in frame 269 ADDV $-8, R29 270 JAL runtime·newstack(SB) 271 272 // Not reached, but make sure the return PC from the call to newstack 273 // is still in this function, and not the beginning of the next. 274 UNDEF 275 276 TEXT runtime·morestack_noctxt(SB),NOSPLIT,$-8-0 277 MOVV R0, REGCTXT 278 JMP runtime·morestack(SB) 279 280 // reflectcall: call a function with the given argument list 281 // func call(argtype *_type, f *FuncVal, arg *byte, argsize, retoffset uint32). 282 // we don't have variable-sized frames, so we use a small number 283 // of constant-sized-frame functions to encode a few bits of size in the pc. 284 // Caution: ugly multiline assembly macros in your future! 285 286 #define DISPATCH(NAME,MAXSIZE) \ 287 MOVV $MAXSIZE, R23; \ 288 SGTU R1, R23, R23; \ 289 BNE R23, 3(PC); \ 290 MOVV $NAME(SB), R4; \ 291 JMP (R4) 292 // Note: can't just "BR NAME(SB)" - bad inlining results. 293 294 TEXT reflect·call(SB), NOSPLIT, $0-0 295 JMP ·reflectcall(SB) 296 297 TEXT ·reflectcall(SB), NOSPLIT, $-8-32 298 MOVWU argsize+24(FP), R1 299 DISPATCH(runtime·call32, 32) 300 DISPATCH(runtime·call64, 64) 301 DISPATCH(runtime·call128, 128) 302 DISPATCH(runtime·call256, 256) 303 DISPATCH(runtime·call512, 512) 304 DISPATCH(runtime·call1024, 1024) 305 DISPATCH(runtime·call2048, 2048) 306 DISPATCH(runtime·call4096, 4096) 307 DISPATCH(runtime·call8192, 8192) 308 DISPATCH(runtime·call16384, 16384) 309 DISPATCH(runtime·call32768, 32768) 310 DISPATCH(runtime·call65536, 65536) 311 DISPATCH(runtime·call131072, 131072) 312 DISPATCH(runtime·call262144, 262144) 313 DISPATCH(runtime·call524288, 524288) 314 DISPATCH(runtime·call1048576, 1048576) 315 DISPATCH(runtime·call2097152, 2097152) 316 DISPATCH(runtime·call4194304, 4194304) 317 DISPATCH(runtime·call8388608, 8388608) 318 DISPATCH(runtime·call16777216, 16777216) 319 DISPATCH(runtime·call33554432, 33554432) 320 DISPATCH(runtime·call67108864, 67108864) 321 DISPATCH(runtime·call134217728, 134217728) 322 DISPATCH(runtime·call268435456, 268435456) 323 DISPATCH(runtime·call536870912, 536870912) 324 DISPATCH(runtime·call1073741824, 1073741824) 325 MOVV $runtime·badreflectcall(SB), R4 326 JMP (R4) 327 328 #define CALLFN(NAME,MAXSIZE) \ 329 TEXT NAME(SB), WRAPPER, $MAXSIZE-24; \ 330 NO_LOCAL_POINTERS; \ 331 /* copy arguments to stack */ \ 332 MOVV arg+16(FP), R1; \ 333 MOVWU argsize+24(FP), R2; \ 334 MOVV R29, R3; \ 335 ADDV $8, R3; \ 336 ADDV R3, R2; \ 337 BEQ R3, R2, 6(PC); \ 338 MOVBU (R1), R4; \ 339 ADDV $1, R1; \ 340 MOVBU R4, (R3); \ 341 ADDV $1, R3; \ 342 JMP -5(PC); \ 343 /* call function */ \ 344 MOVV f+8(FP), REGCTXT; \ 345 MOVV (REGCTXT), R4; \ 346 PCDATA $PCDATA_StackMapIndex, $0; \ 347 JAL (R4); \ 348 /* copy return values back */ \ 349 MOVV argtype+0(FP), R5; \ 350 MOVV arg+16(FP), R1; \ 351 MOVWU n+24(FP), R2; \ 352 MOVWU retoffset+28(FP), R4; \ 353 ADDV $8, R29, R3; \ 354 ADDV R4, R3; \ 355 ADDV R4, R1; \ 356 SUBVU R4, R2; \ 357 JAL callRet<>(SB); \ 358 RET 359 360 // callRet copies return values back at the end of call*. This is a 361 // separate function so it can allocate stack space for the arguments 362 // to reflectcallmove. It does not follow the Go ABI; it expects its 363 // arguments in registers. 364 TEXT callRet<>(SB), NOSPLIT, $32-0 365 MOVV R5, 8(R29) 366 MOVV R1, 16(R29) 367 MOVV R3, 24(R29) 368 MOVV R2, 32(R29) 369 JAL runtime·reflectcallmove(SB) 370 RET 371 372 CALLFN(·call16, 16) 373 CALLFN(·call32, 32) 374 CALLFN(·call64, 64) 375 CALLFN(·call128, 128) 376 CALLFN(·call256, 256) 377 CALLFN(·call512, 512) 378 CALLFN(·call1024, 1024) 379 CALLFN(·call2048, 2048) 380 CALLFN(·call4096, 4096) 381 CALLFN(·call8192, 8192) 382 CALLFN(·call16384, 16384) 383 CALLFN(·call32768, 32768) 384 CALLFN(·call65536, 65536) 385 CALLFN(·call131072, 131072) 386 CALLFN(·call262144, 262144) 387 CALLFN(·call524288, 524288) 388 CALLFN(·call1048576, 1048576) 389 CALLFN(·call2097152, 2097152) 390 CALLFN(·call4194304, 4194304) 391 CALLFN(·call8388608, 8388608) 392 CALLFN(·call16777216, 16777216) 393 CALLFN(·call33554432, 33554432) 394 CALLFN(·call67108864, 67108864) 395 CALLFN(·call134217728, 134217728) 396 CALLFN(·call268435456, 268435456) 397 CALLFN(·call536870912, 536870912) 398 CALLFN(·call1073741824, 1073741824) 399 400 TEXT runtime·procyield(SB),NOSPLIT,$0-0 401 RET 402 403 // void jmpdefer(fv, sp); 404 // called from deferreturn. 405 // 1. grab stored LR for caller 406 // 2. sub 8 bytes to get back to JAL deferreturn 407 // 3. JMP to fn 408 TEXT runtime·jmpdefer(SB), NOSPLIT, $-8-16 409 MOVV 0(R29), R31 410 ADDV $-8, R31 411 412 MOVV fv+0(FP), REGCTXT 413 MOVV argp+8(FP), R29 414 ADDV $-8, R29 415 NOR R0, R0 // prevent scheduling 416 MOVV 0(REGCTXT), R4 417 JMP (R4) 418 419 // Save state of caller into g->sched. Smashes R1. 420 TEXT gosave<>(SB),NOSPLIT,$-8 421 MOVV R31, (g_sched+gobuf_pc)(g) 422 MOVV R29, (g_sched+gobuf_sp)(g) 423 MOVV R0, (g_sched+gobuf_lr)(g) 424 MOVV R0, (g_sched+gobuf_ret)(g) 425 // Assert ctxt is zero. See func save. 426 MOVV (g_sched+gobuf_ctxt)(g), R1 427 BEQ R1, 2(PC) 428 JAL runtime·badctxt(SB) 429 RET 430 431 // func asmcgocall(fn, arg unsafe.Pointer) int32 432 // Call fn(arg) on the scheduler stack, 433 // aligned appropriately for the gcc ABI. 434 // See cgocall.go for more details. 435 TEXT ·asmcgocall(SB),NOSPLIT,$0-20 436 MOVV fn+0(FP), R25 437 MOVV arg+8(FP), R4 438 439 MOVV R29, R3 // save original stack pointer 440 MOVV g, R2 441 442 // Figure out if we need to switch to m->g0 stack. 443 // We get called to create new OS threads too, and those 444 // come in on the m->g0 stack already. 445 MOVV g_m(g), R5 446 MOVV m_g0(R5), R6 447 BEQ R6, g, g0 448 449 JAL gosave<>(SB) 450 MOVV R6, g 451 JAL runtime·save_g(SB) 452 MOVV (g_sched+gobuf_sp)(g), R29 453 454 // Now on a scheduling stack (a pthread-created stack). 455 g0: 456 // Save room for two of our pointers. 457 ADDV $-16, R29 458 MOVV R2, 0(R29) // save old g on stack 459 MOVV (g_stack+stack_hi)(R2), R2 460 SUBVU R3, R2 461 MOVV R2, 8(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 MOVV 0(R29), g 466 JAL runtime·save_g(SB) 467 MOVV (g_stack+stack_hi)(g), R5 468 MOVV 8(R29), R6 469 SUBVU R6, R5 470 MOVV R5, R29 471 472 MOVW R2, ret+16(FP) 473 RET 474 475 // cgocallback(void (*fn)(void*), void *frame, uintptr framesize, uintptr ctxt) 476 // Turn the fn into a Go func (by taking its address) and call 477 // cgocallback_gofunc. 478 TEXT runtime·cgocallback(SB),NOSPLIT,$32-32 479 MOVV $fn+0(FP), R1 480 MOVV R1, 8(R29) 481 MOVV frame+8(FP), R1 482 MOVV R1, 16(R29) 483 MOVV framesize+16(FP), R1 484 MOVV R1, 24(R29) 485 MOVV ctxt+24(FP), R1 486 MOVV R1, 32(R29) 487 MOVV $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,$16-32 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 MOVV g_m(g), R3 510 MOVV R3, savedm-8(SP) 511 JMP havem 512 513 needm: 514 MOVV g, savedm-8(SP) // g is zero, so is m. 515 MOVV $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 MOVV g_m(g), R3 530 MOVV m_g0(R3), R1 531 MOVV 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 8(R29) aka savedsp-16(SP). 539 MOVV m_g0(R3), R1 540 MOVV (g_sched+gobuf_sp)(R1), R2 541 MOVV R2, savedsp-16(SP) 542 MOVV 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, -8(SP) is unused (where SP refers to 559 // m->curg's SP while we're setting it up, before we've adjusted it). 560 MOVV m_curg(R3), g 561 JAL runtime·save_g(SB) 562 MOVV (g_sched+gobuf_sp)(g), R2 // prepare stack as R2 563 MOVV (g_sched+gobuf_pc)(g), R4 564 MOVV R4, -24(R2) 565 MOVV ctxt+24(FP), R1 566 MOVV R1, -16(R2) 567 MOVV $-24(R2), R29 568 JAL runtime·cgocallbackg(SB) 569 570 // Restore g->sched (== m->curg->sched) from saved values. 571 MOVV 0(R29), R4 572 MOVV R4, (g_sched+gobuf_pc)(g) 573 MOVV $24(R29), R2 574 MOVV 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 MOVV g_m(g), R3 580 MOVV m_g0(R3), g 581 JAL runtime·save_g(SB) 582 MOVV (g_sched+gobuf_sp)(g), R29 583 MOVV savedsp-16(SP), R2 584 MOVV 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 MOVV savedm-8(SP), R3 589 BNE R3, droppedm 590 MOVV $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 TEXT runtime·setg(SB), NOSPLIT, $0-8 599 MOVV gg+0(FP), g 600 // This only happens if iscgo, so jump straight to save_g 601 JAL runtime·save_g(SB) 602 RET 603 604 // void setg_gcc(G*); set g called from gcc with g in R1 605 TEXT setg_gcc<>(SB),NOSPLIT,$0-0 606 MOVV R1, g 607 JAL runtime·save_g(SB) 608 RET 609 610 TEXT runtime·getcallerpc(SB),NOSPLIT,$-8-8 611 MOVV 0(R29), R1 // LR saved by caller 612 MOVV R1, ret+0(FP) 613 RET 614 615 TEXT runtime·abort(SB),NOSPLIT,$-8-0 616 MOVW (R0), R0 617 UNDEF 618 619 // AES hashing not implemented for mips64 620 TEXT runtime·aeshash(SB),NOSPLIT,$-8-0 621 MOVW (R0), R1 622 TEXT runtime·aeshash32(SB),NOSPLIT,$-8-0 623 MOVW (R0), R1 624 TEXT runtime·aeshash64(SB),NOSPLIT,$-8-0 625 MOVW (R0), R1 626 TEXT runtime·aeshashstr(SB),NOSPLIT,$-8-0 627 MOVW (R0), R1 628 629 // memequal(p, q unsafe.Pointer, size uintptr) bool 630 TEXT runtime·memequal(SB),NOSPLIT,$-8-25 631 MOVV a+0(FP), R1 632 MOVV b+8(FP), R2 633 BEQ R1, R2, eq 634 MOVV size+16(FP), R3 635 ADDV R1, R3, R4 636 loop: 637 BNE R1, R4, test 638 MOVV $1, R1 639 MOVB R1, ret+24(FP) 640 RET 641 test: 642 MOVBU (R1), R6 643 ADDV $1, R1 644 MOVBU (R2), R7 645 ADDV $1, R2 646 BEQ R6, R7, loop 647 648 MOVB R0, ret+24(FP) 649 RET 650 eq: 651 MOVV $1, R1 652 MOVB R1, ret+24(FP) 653 RET 654 655 // memequal_varlen(a, b unsafe.Pointer) bool 656 TEXT runtime·memequal_varlen(SB),NOSPLIT,$40-17 657 MOVV a+0(FP), R1 658 MOVV b+8(FP), R2 659 BEQ R1, R2, eq 660 MOVV 8(REGCTXT), R3 // compiler stores size at offset 8 in the closure 661 MOVV R1, 8(R29) 662 MOVV R2, 16(R29) 663 MOVV R3, 24(R29) 664 JAL runtime·memequal(SB) 665 MOVBU 32(R29), R1 666 MOVB R1, ret+16(FP) 667 RET 668 eq: 669 MOVV $1, R1 670 MOVB R1, ret+16(FP) 671 RET 672 673 // TODO: share code with memequal? 674 TEXT bytes·Equal(SB),NOSPLIT,$0-49 675 MOVV a_len+8(FP), R3 676 MOVV b_len+32(FP), R4 677 BNE R3, R4, noteq // unequal lengths are not equal 678 679 MOVV a+0(FP), R1 680 MOVV b+24(FP), R2 681 ADDV R1, R3 // end 682 683 loop: 684 BEQ R1, R3, equal // reached the end 685 MOVBU (R1), R6 686 ADDV $1, R1 687 MOVBU (R2), R7 688 ADDV $1, R2 689 BEQ R6, R7, loop 690 691 noteq: 692 MOVB R0, ret+48(FP) 693 RET 694 695 equal: 696 MOVV $1, R1 697 MOVB R1, ret+48(FP) 698 RET 699 700 TEXT bytes·IndexByte(SB),NOSPLIT,$0-40 701 MOVV s+0(FP), R1 702 MOVV s_len+8(FP), R2 703 MOVBU c+24(FP), R3 // byte to find 704 MOVV R1, R4 // store base for later 705 ADDV R1, R2 // end 706 ADDV $-1, R1 707 708 loop: 709 ADDV $1, R1 710 BEQ R1, R2, notfound 711 MOVBU (R1), R5 712 BNE R3, R5, loop 713 714 SUBV R4, R1 // remove base 715 MOVV R1, ret+32(FP) 716 RET 717 718 notfound: 719 MOVV $-1, R1 720 MOVV R1, ret+32(FP) 721 RET 722 723 TEXT strings·IndexByte(SB),NOSPLIT,$0-32 724 MOVV p+0(FP), R1 725 MOVV b_len+8(FP), R2 726 MOVBU c+16(FP), R3 // byte to find 727 MOVV R1, R4 // store base for later 728 ADDV R1, R2 // end 729 ADDV $-1, R1 730 731 loop: 732 ADDV $1, R1 733 BEQ R1, R2, notfound 734 MOVBU (R1), R5 735 BNE R3, R5, loop 736 737 SUBV R4, R1 // remove base 738 MOVV R1, ret+24(FP) 739 RET 740 741 notfound: 742 MOVV $-1, R1 743 MOVV R1, ret+24(FP) 744 RET 745 746 TEXT runtime·return0(SB), NOSPLIT, $0 747 MOVW $0, R1 748 RET 749 750 // Called from cgo wrappers, this function returns g->m->curg.stack.hi. 751 // Must obey the gcc calling convention. 752 TEXT _cgo_topofstack(SB),NOSPLIT,$16 753 // g (R30) and REGTMP (R23) might be clobbered by load_g. They 754 // are callee-save in the gcc calling convention, so save them. 755 MOVV R23, savedR23-16(SP) 756 MOVV g, savedG-8(SP) 757 758 JAL runtime·load_g(SB) 759 MOVV g_m(g), R1 760 MOVV m_curg(R1), R1 761 MOVV (g_stack+stack_hi)(R1), R2 // return value in R2 762 763 MOVV savedG-8(SP), g 764 MOVV savedR23-16(SP), R23 765 RET 766 767 // The top-most function running on a goroutine 768 // returns to goexit+PCQuantum. 769 TEXT runtime·goexit(SB),NOSPLIT,$-8-0 770 NOR R0, R0 // NOP 771 JAL runtime·goexit1(SB) // does not return 772 // traceback from goexit1 must hit code range of goexit 773 NOR R0, R0 // NOP 774 775 TEXT ·checkASM(SB),NOSPLIT,$0-1 776 MOVW $1, R1 777 MOVB R1, ret+0(FP) 778 RET