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