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