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