github.com/geraldss/go/src@v0.0.0-20210511222824-ac7d0ebfc235/runtime/asm_mipsx.s (about) 1 // Copyright 2016 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 mips mipsle 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 ADDU $-12, R29 18 MOVW R4, 4(R29) // argc 19 MOVW R5, 8(R29) // argv 20 21 // create istack out of the given (operating system) stack. 22 // _cgo_init may update stackguard. 23 MOVW $runtime·g0(SB), g 24 MOVW $(-64*1024), R23 25 ADD R23, R29, R1 26 MOVW R1, g_stackguard0(g) 27 MOVW R1, g_stackguard1(g) 28 MOVW R1, (g_stack+stack_lo)(g) 29 MOVW R29, (g_stack+stack_hi)(g) 30 31 // if there is a _cgo_init, call it using the gcc ABI. 32 MOVW _cgo_init(SB), R25 33 BEQ R25, nocgo 34 ADDU $-16, R29 35 MOVW R0, R7 // arg 3: not used 36 MOVW R0, R6 // arg 2: not used 37 MOVW $setg_gcc<>(SB), R5 // arg 1: setg 38 MOVW g, R4 // arg 0: G 39 JAL (R25) 40 ADDU $16, R29 41 42 nocgo: 43 // update stackguard after _cgo_init 44 MOVW (g_stack+stack_lo)(g), R1 45 ADD $const__StackGuard, R1 46 MOVW R1, g_stackguard0(g) 47 MOVW R1, g_stackguard1(g) 48 49 // set the per-goroutine and per-mach "registers" 50 MOVW $runtime·m0(SB), R1 51 52 // save m->g0 = g0 53 MOVW g, m_g0(R1) 54 // save m0 to g0->m 55 MOVW R1, g_m(g) 56 57 JAL runtime·check(SB) 58 59 // args are already prepared 60 JAL runtime·args(SB) 61 JAL runtime·osinit(SB) 62 JAL runtime·schedinit(SB) 63 64 // create a new goroutine to start program 65 MOVW $runtime·mainPC(SB), R1 // entry 66 ADDU $-12, R29 67 MOVW R1, 8(R29) 68 MOVW R0, 4(R29) 69 MOVW R0, 0(R29) 70 JAL runtime·newproc(SB) 71 ADDU $12, R29 72 73 // start this M 74 JAL runtime·mstart(SB) 75 76 UNDEF 77 RET 78 79 DATA runtime·mainPC+0(SB)/4,$runtime·main(SB) 80 GLOBL runtime·mainPC(SB),RODATA,$4 81 82 TEXT runtime·breakpoint(SB),NOSPLIT,$0-0 83 BREAK 84 RET 85 86 TEXT runtime·asminit(SB),NOSPLIT,$0-0 87 RET 88 89 /* 90 * go-routine 91 */ 92 93 // void gosave(Gobuf*) 94 // save state in Gobuf; setjmp 95 TEXT runtime·gosave(SB),NOSPLIT|NOFRAME,$0-4 96 MOVW buf+0(FP), R1 97 MOVW R29, gobuf_sp(R1) 98 MOVW R31, gobuf_pc(R1) 99 MOVW g, gobuf_g(R1) 100 MOVW R0, gobuf_lr(R1) 101 MOVW R0, gobuf_ret(R1) 102 // Assert ctxt is zero. See func save. 103 MOVW gobuf_ctxt(R1), R1 104 BEQ R1, 2(PC) 105 JAL runtime·badctxt(SB) 106 RET 107 108 // void gogo(Gobuf*) 109 // restore state from Gobuf; longjmp 110 TEXT runtime·gogo(SB),NOSPLIT,$8-4 111 MOVW buf+0(FP), R3 112 MOVW gobuf_g(R3), g // make sure g is not nil 113 JAL runtime·save_g(SB) 114 115 MOVW 0(g), R2 116 MOVW gobuf_sp(R3), R29 117 MOVW gobuf_lr(R3), R31 118 MOVW gobuf_ret(R3), R1 119 MOVW gobuf_ctxt(R3), REGCTXT 120 MOVW R0, gobuf_sp(R3) 121 MOVW R0, gobuf_ret(R3) 122 MOVW R0, gobuf_lr(R3) 123 MOVW R0, gobuf_ctxt(R3) 124 MOVW gobuf_pc(R3), R4 125 JMP (R4) 126 127 // void mcall(fn func(*g)) 128 // Switch to m->g0's stack, call fn(g). 129 // Fn must never return. It should gogo(&g->sched) 130 // to keep running g. 131 TEXT runtime·mcall(SB),NOSPLIT|NOFRAME,$0-4 132 // Save caller state in g->sched 133 MOVW R29, (g_sched+gobuf_sp)(g) 134 MOVW R31, (g_sched+gobuf_pc)(g) 135 MOVW R0, (g_sched+gobuf_lr)(g) 136 MOVW g, (g_sched+gobuf_g)(g) 137 138 // Switch to m->g0 & its stack, call fn. 139 MOVW g, R1 140 MOVW g_m(g), R3 141 MOVW m_g0(R3), g 142 JAL runtime·save_g(SB) 143 BNE g, R1, 2(PC) 144 JMP runtime·badmcall(SB) 145 MOVW fn+0(FP), REGCTXT // context 146 MOVW 0(REGCTXT), R4 // code pointer 147 MOVW (g_sched+gobuf_sp)(g), R29 // sp = m->g0->sched.sp 148 ADDU $-8, R29 // make room for 1 arg and fake LR 149 MOVW R1, 4(R29) 150 MOVW R0, 0(R29) 151 JAL (R4) 152 JMP runtime·badmcall2(SB) 153 154 // systemstack_switch is a dummy routine that systemstack leaves at the bottom 155 // of the G stack. We need to distinguish the routine that 156 // lives at the bottom of the G stack from the one that lives 157 // at the top of the system stack because the one at the top of 158 // the system stack terminates the stack walk (see topofstack()). 159 TEXT runtime·systemstack_switch(SB),NOSPLIT,$0-0 160 UNDEF 161 JAL (R31) // make sure this function is not leaf 162 RET 163 164 // func systemstack(fn func()) 165 TEXT runtime·systemstack(SB),NOSPLIT,$0-4 166 MOVW fn+0(FP), R1 // R1 = fn 167 MOVW R1, REGCTXT // context 168 MOVW g_m(g), R2 // R2 = m 169 170 MOVW m_gsignal(R2), R3 // R3 = gsignal 171 BEQ g, R3, noswitch 172 173 MOVW m_g0(R2), R3 // R3 = g0 174 BEQ g, R3, noswitch 175 176 MOVW m_curg(R2), R4 177 BEQ g, R4, switch 178 179 // Bad: g is not gsignal, not g0, not curg. What is it? 180 // Hide call from linker nosplit analysis. 181 MOVW $runtime·badsystemstack(SB), R4 182 JAL (R4) 183 JAL runtime·abort(SB) 184 185 switch: 186 // save our state in g->sched. Pretend to 187 // be systemstack_switch if the G stack is scanned. 188 MOVW $runtime·systemstack_switch(SB), R4 189 ADDU $8, R4 // get past prologue 190 MOVW R4, (g_sched+gobuf_pc)(g) 191 MOVW R29, (g_sched+gobuf_sp)(g) 192 MOVW R0, (g_sched+gobuf_lr)(g) 193 MOVW g, (g_sched+gobuf_g)(g) 194 195 // switch to g0 196 MOVW R3, g 197 JAL runtime·save_g(SB) 198 MOVW (g_sched+gobuf_sp)(g), R1 199 // make it look like mstart called systemstack on g0, to stop traceback 200 ADDU $-4, R1 201 MOVW $runtime·mstart(SB), R2 202 MOVW R2, 0(R1) 203 MOVW R1, R29 204 205 // call target function 206 MOVW 0(REGCTXT), R4 // code pointer 207 JAL (R4) 208 209 // switch back to g 210 MOVW g_m(g), R1 211 MOVW m_curg(R1), g 212 JAL runtime·save_g(SB) 213 MOVW (g_sched+gobuf_sp)(g), R29 214 MOVW R0, (g_sched+gobuf_sp)(g) 215 RET 216 217 noswitch: 218 // already on m stack, just call directly 219 // Using a tail call here cleans up tracebacks since we won't stop 220 // at an intermediate systemstack. 221 MOVW 0(REGCTXT), R4 // code pointer 222 MOVW 0(R29), R31 // restore LR 223 ADD $4, R29 224 JMP (R4) 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|NOFRAME,$0-0 239 // Cannot grow scheduler stack (m->g0). 240 MOVW g_m(g), R7 241 MOVW m_g0(R7), R8 242 BNE g, R8, 3(PC) 243 JAL runtime·badmorestackg0(SB) 244 JAL runtime·abort(SB) 245 246 // Cannot grow signal stack (m->gsignal). 247 MOVW m_gsignal(R7), R8 248 BNE g, R8, 3(PC) 249 JAL runtime·badmorestackgsignal(SB) 250 JAL runtime·abort(SB) 251 252 // Called from f. 253 // Set g->sched to context in f. 254 MOVW R29, (g_sched+gobuf_sp)(g) 255 MOVW R31, (g_sched+gobuf_pc)(g) 256 MOVW R3, (g_sched+gobuf_lr)(g) 257 MOVW REGCTXT, (g_sched+gobuf_ctxt)(g) 258 259 // Called from f. 260 // Set m->morebuf to f's caller. 261 MOVW R3, (m_morebuf+gobuf_pc)(R7) // f's caller's PC 262 MOVW R29, (m_morebuf+gobuf_sp)(R7) // f's caller's SP 263 MOVW g, (m_morebuf+gobuf_g)(R7) 264 265 // Call newstack on m->g0's stack. 266 MOVW m_g0(R7), g 267 JAL runtime·save_g(SB) 268 MOVW (g_sched+gobuf_sp)(g), R29 269 // Create a stack frame on g0 to call newstack. 270 MOVW R0, -4(R29) // Zero saved LR in frame 271 ADDU $-4, R29 272 JAL runtime·newstack(SB) 273 274 // Not reached, but make sure the return PC from the call to newstack 275 // is still in this function, and not the beginning of the next. 276 UNDEF 277 278 TEXT runtime·morestack_noctxt(SB),NOSPLIT,$0-0 279 MOVW R0, REGCTXT 280 JMP runtime·morestack(SB) 281 282 // reflectcall: call a function with the given argument list 283 // func call(argtype *_type, f *FuncVal, arg *byte, argsize, retoffset uint32). 284 // we don't have variable-sized frames, so we use a small number 285 // of constant-sized-frame functions to encode a few bits of size in the pc. 286 287 #define DISPATCH(NAME,MAXSIZE) \ 288 MOVW $MAXSIZE, R23; \ 289 SGTU R1, R23, R23; \ 290 BNE R23, 3(PC); \ 291 MOVW $NAME(SB), R4; \ 292 JMP (R4) 293 294 TEXT ·reflectcall(SB),NOSPLIT|NOFRAME,$0-20 295 MOVW argsize+12(FP), R1 296 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 MOVW $runtime·badreflectcall(SB), R4 325 JMP (R4) 326 327 #define CALLFN(NAME,MAXSIZE) \ 328 TEXT NAME(SB),WRAPPER,$MAXSIZE-20; \ 329 NO_LOCAL_POINTERS; \ 330 /* copy arguments to stack */ \ 331 MOVW arg+8(FP), R1; \ 332 MOVW argsize+12(FP), R2; \ 333 MOVW R29, R3; \ 334 ADDU $4, R3; \ 335 ADDU R3, R2; \ 336 BEQ R3, R2, 6(PC); \ 337 MOVBU (R1), R4; \ 338 ADDU $1, R1; \ 339 MOVBU R4, (R3); \ 340 ADDU $1, R3; \ 341 JMP -5(PC); \ 342 /* call function */ \ 343 MOVW f+4(FP), REGCTXT; \ 344 MOVW (REGCTXT), R4; \ 345 PCDATA $PCDATA_StackMapIndex, $0; \ 346 JAL (R4); \ 347 /* copy return values back */ \ 348 MOVW argtype+0(FP), R5; \ 349 MOVW arg+8(FP), R1; \ 350 MOVW n+12(FP), R2; \ 351 MOVW retoffset+16(FP), R4; \ 352 ADDU $4, R29, R3; \ 353 ADDU R4, R3; \ 354 ADDU R4, R1; \ 355 SUBU 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, $16-0 364 MOVW R5, 4(R29) 365 MOVW R1, 8(R29) 366 MOVW R3, 12(R29) 367 MOVW R2, 16(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-4 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,$0-8 408 MOVW 0(R29), R31 409 ADDU $-8, R31 410 411 MOVW fv+0(FP), REGCTXT 412 MOVW argp+4(FP), R29 413 ADDU $-4, R29 414 NOR R0, R0 // prevent scheduling 415 MOVW 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 MOVW R31, (g_sched+gobuf_pc)(g) 421 MOVW R29, (g_sched+gobuf_sp)(g) 422 MOVW R0, (g_sched+gobuf_lr)(g) 423 MOVW R0, (g_sched+gobuf_ret)(g) 424 // Assert ctxt is zero. See func save. 425 MOVW (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-12 435 MOVW fn+0(FP), R25 436 MOVW arg+4(FP), R4 437 438 MOVW R29, R3 // save original stack pointer 439 MOVW 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 MOVW g_m(g), R5 445 MOVW m_g0(R5), R6 446 BEQ R6, g, g0 447 448 JAL gosave<>(SB) 449 MOVW R6, g 450 JAL runtime·save_g(SB) 451 MOVW (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 and O32 frame. 456 ADDU $-24, R29 457 AND $~7, R29 // O32 ABI expects 8-byte aligned stack on function entry 458 MOVW R2, 16(R29) // save old g on stack 459 MOVW (g_stack+stack_hi)(R2), R2 460 SUBU R3, R2 461 MOVW R2, 20(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 MOVW 16(R29), g 466 JAL runtime·save_g(SB) 467 MOVW (g_stack+stack_hi)(g), R5 468 MOVW 20(R29), R6 469 SUBU R6, R5 470 MOVW R5, R29 471 472 MOVW R2, ret+8(FP) 473 RET 474 475 // cgocallback(fn, frame unsafe.Pointer, ctxt uintptr) 476 // See cgocall.go for more details. 477 TEXT ·cgocallback(SB),NOSPLIT,$12-12 478 NO_LOCAL_POINTERS 479 480 // Load m and g from thread-local storage. 481 MOVB runtime·iscgo(SB), R1 482 BEQ R1, nocgo 483 JAL runtime·load_g(SB) 484 nocgo: 485 486 // If g is nil, Go did not create the current thread. 487 // Call needm to obtain one for temporary use. 488 // In this case, we're running on the thread stack, so there's 489 // lots of space, but the linker doesn't know. Hide the call from 490 // the linker analysis by using an indirect call. 491 BEQ g, needm 492 493 MOVW g_m(g), R3 494 MOVW R3, savedm-4(SP) 495 JMP havem 496 497 needm: 498 MOVW g, savedm-4(SP) // g is zero, so is m. 499 MOVW $runtime·needm(SB), R4 500 JAL (R4) 501 502 // Set m->sched.sp = SP, so that if a panic happens 503 // during the function we are about to execute, it will 504 // have a valid SP to run on the g0 stack. 505 // The next few lines (after the havem label) 506 // will save this SP onto the stack and then write 507 // the same SP back to m->sched.sp. That seems redundant, 508 // but if an unrecovered panic happens, unwindm will 509 // restore the g->sched.sp from the stack location 510 // and then systemstack will try to use it. If we don't set it here, 511 // that restored SP will be uninitialized (typically 0) and 512 // will not be usable. 513 MOVW g_m(g), R3 514 MOVW m_g0(R3), R1 515 MOVW R29, (g_sched+gobuf_sp)(R1) 516 517 havem: 518 // Now there's a valid m, and we're running on its m->g0. 519 // Save current m->g0->sched.sp on stack and then set it to SP. 520 // Save current sp in m->g0->sched.sp in preparation for 521 // switch back to m->curg stack. 522 // NOTE: unwindm knows that the saved g->sched.sp is at 4(R29) aka savedsp-8(SP). 523 MOVW m_g0(R3), R1 524 MOVW (g_sched+gobuf_sp)(R1), R2 525 MOVW R2, savedsp-12(SP) // must match frame size 526 MOVW R29, (g_sched+gobuf_sp)(R1) 527 528 // Switch to m->curg stack and call runtime.cgocallbackg. 529 // Because we are taking over the execution of m->curg 530 // but *not* resuming what had been running, we need to 531 // save that information (m->curg->sched) so we can restore it. 532 // We can restore m->curg->sched.sp easily, because calling 533 // runtime.cgocallbackg leaves SP unchanged upon return. 534 // To save m->curg->sched.pc, we push it onto the curg stack and 535 // open a frame the same size as cgocallback's g0 frame. 536 // Once we switch to the curg stack, the pushed PC will appear 537 // to be the return PC of cgocallback, so that the traceback 538 // will seamlessly trace back into the earlier calls. 539 MOVW m_curg(R3), g 540 JAL runtime·save_g(SB) 541 MOVW (g_sched+gobuf_sp)(g), R2 // prepare stack as R2 542 MOVW (g_sched+gobuf_pc)(g), R4 543 MOVW R4, -(12+4)(R2) // "saved LR"; must match frame size 544 // Gather our arguments into registers. 545 MOVW fn+0(FP), R5 546 MOVW frame+4(FP), R6 547 MOVW ctxt+8(FP), R7 548 MOVW $-(12+4)(R2), R29 // switch stack; must match frame size 549 MOVW R5, 4(R29) 550 MOVW R6, 8(R29) 551 MOVW R7, 12(R29) 552 JAL runtime·cgocallbackg(SB) 553 554 // Restore g->sched (== m->curg->sched) from saved values. 555 MOVW 0(R29), R4 556 MOVW R4, (g_sched+gobuf_pc)(g) 557 MOVW $(12+4)(R29), R2 // must match frame size 558 MOVW R2, (g_sched+gobuf_sp)(g) 559 560 // Switch back to m->g0's stack and restore m->g0->sched.sp. 561 // (Unlike m->curg, the g0 goroutine never uses sched.pc, 562 // so we do not have to restore it.) 563 MOVW g_m(g), R3 564 MOVW m_g0(R3), g 565 JAL runtime·save_g(SB) 566 MOVW (g_sched+gobuf_sp)(g), R29 567 MOVW savedsp-12(SP), R2 // must match frame size 568 MOVW R2, (g_sched+gobuf_sp)(g) 569 570 // If the m on entry was nil, we called needm above to borrow an m 571 // for the duration of the call. Since the call is over, return it with dropm. 572 MOVW savedm-4(SP), R3 573 BNE R3, droppedm 574 MOVW $runtime·dropm(SB), R4 575 JAL (R4) 576 droppedm: 577 578 // Done! 579 RET 580 581 // void setg(G*); set g. for use by needm. 582 // This only happens if iscgo, so jump straight to save_g 583 TEXT runtime·setg(SB),NOSPLIT,$0-4 584 MOVW gg+0(FP), g 585 JAL runtime·save_g(SB) 586 RET 587 588 // void setg_gcc(G*); set g in C TLS. 589 // Must obey the gcc calling convention. 590 TEXT setg_gcc<>(SB),NOSPLIT,$0 591 MOVW R4, g 592 JAL runtime·save_g(SB) 593 RET 594 595 TEXT runtime·abort(SB),NOSPLIT,$0-0 596 UNDEF 597 598 // AES hashing not implemented for mips 599 TEXT runtime·memhash(SB),NOSPLIT|NOFRAME,$0-16 600 JMP runtime·memhashFallback(SB) 601 TEXT runtime·strhash(SB),NOSPLIT|NOFRAME,$0-12 602 JMP runtime·strhashFallback(SB) 603 TEXT runtime·memhash32(SB),NOSPLIT|NOFRAME,$0-12 604 JMP runtime·memhash32Fallback(SB) 605 TEXT runtime·memhash64(SB),NOSPLIT|NOFRAME,$0-12 606 JMP runtime·memhash64Fallback(SB) 607 608 TEXT runtime·return0(SB),NOSPLIT,$0 609 MOVW $0, R1 610 RET 611 612 // Called from cgo wrappers, this function returns g->m->curg.stack.hi. 613 // Must obey the gcc calling convention. 614 TEXT _cgo_topofstack(SB),NOSPLIT|NOFRAME,$0 615 // g (R30), R3 and REGTMP (R23) might be clobbered by load_g. R30 and R23 616 // are callee-save in the gcc calling convention, so save them. 617 MOVW R23, R8 618 MOVW g, R9 619 MOVW R31, R10 // this call frame does not save LR 620 621 JAL runtime·load_g(SB) 622 MOVW g_m(g), R1 623 MOVW m_curg(R1), R1 624 MOVW (g_stack+stack_hi)(R1), R2 // return value in R2 625 626 MOVW R8, R23 627 MOVW R9, g 628 MOVW R10, R31 629 630 RET 631 632 // The top-most function running on a goroutine 633 // returns to goexit+PCQuantum. 634 TEXT runtime·goexit(SB),NOSPLIT|NOFRAME|TOPFRAME,$0-0 635 NOR R0, R0 // NOP 636 JAL runtime·goexit1(SB) // does not return 637 // traceback from goexit1 must hit code range of goexit 638 NOR R0, R0 // NOP 639 640 TEXT ·checkASM(SB),NOSPLIT,$0-1 641 MOVW $1, R1 642 MOVB R1, ret+0(FP) 643 RET 644 645 // gcWriteBarrier performs a heap pointer write and informs the GC. 646 // 647 // gcWriteBarrier does NOT follow the Go ABI. It takes two arguments: 648 // - R20 is the destination of the write 649 // - R21 is the value being written at R20. 650 // It clobbers R23 (the linker temp register). 651 // The act of CALLing gcWriteBarrier will clobber R31 (LR). 652 // It does not clobber any other general-purpose registers, 653 // but may clobber others (e.g., floating point registers). 654 TEXT runtime·gcWriteBarrier(SB),NOSPLIT,$104 655 // Save the registers clobbered by the fast path. 656 MOVW R1, 100(R29) 657 MOVW R2, 104(R29) 658 MOVW g_m(g), R1 659 MOVW m_p(R1), R1 660 MOVW (p_wbBuf+wbBuf_next)(R1), R2 661 // Increment wbBuf.next position. 662 ADD $8, R2 663 MOVW R2, (p_wbBuf+wbBuf_next)(R1) 664 MOVW (p_wbBuf+wbBuf_end)(R1), R1 665 MOVW R1, R23 // R23 is linker temp register 666 // Record the write. 667 MOVW R21, -8(R2) // Record value 668 MOVW (R20), R1 // TODO: This turns bad writes into bad reads. 669 MOVW R1, -4(R2) // Record *slot 670 // Is the buffer full? 671 BEQ R2, R23, flush 672 ret: 673 MOVW 100(R29), R1 674 MOVW 104(R29), R2 675 // Do the write. 676 MOVW R21, (R20) 677 RET 678 679 flush: 680 // Save all general purpose registers since these could be 681 // clobbered by wbBufFlush and were not saved by the caller. 682 MOVW R20, 4(R29) // Also first argument to wbBufFlush 683 MOVW R21, 8(R29) // Also second argument to wbBufFlush 684 // R1 already saved 685 // R2 already saved 686 MOVW R3, 12(R29) 687 MOVW R4, 16(R29) 688 MOVW R5, 20(R29) 689 MOVW R6, 24(R29) 690 MOVW R7, 28(R29) 691 MOVW R8, 32(R29) 692 MOVW R9, 36(R29) 693 MOVW R10, 40(R29) 694 MOVW R11, 44(R29) 695 MOVW R12, 48(R29) 696 MOVW R13, 52(R29) 697 MOVW R14, 56(R29) 698 MOVW R15, 60(R29) 699 MOVW R16, 64(R29) 700 MOVW R17, 68(R29) 701 MOVW R18, 72(R29) 702 MOVW R19, 76(R29) 703 MOVW R20, 80(R29) 704 // R21 already saved 705 // R22 already saved. 706 MOVW R22, 84(R29) 707 // R23 is tmp register. 708 MOVW R24, 88(R29) 709 MOVW R25, 92(R29) 710 // R26 is reserved by kernel. 711 // R27 is reserved by kernel. 712 MOVW R28, 96(R29) 713 // R29 is SP. 714 // R30 is g. 715 // R31 is LR, which was saved by the prologue. 716 717 // This takes arguments R20 and R21. 718 CALL runtime·wbBufFlush(SB) 719 720 MOVW 4(R29), R20 721 MOVW 8(R29), R21 722 MOVW 12(R29), R3 723 MOVW 16(R29), R4 724 MOVW 20(R29), R5 725 MOVW 24(R29), R6 726 MOVW 28(R29), R7 727 MOVW 32(R29), R8 728 MOVW 36(R29), R9 729 MOVW 40(R29), R10 730 MOVW 44(R29), R11 731 MOVW 48(R29), R12 732 MOVW 52(R29), R13 733 MOVW 56(R29), R14 734 MOVW 60(R29), R15 735 MOVW 64(R29), R16 736 MOVW 68(R29), R17 737 MOVW 72(R29), R18 738 MOVW 76(R29), R19 739 MOVW 80(R29), R20 740 MOVW 84(R29), R22 741 MOVW 88(R29), R24 742 MOVW 92(R29), R25 743 MOVW 96(R29), R28 744 JMP ret 745 746 // Note: these functions use a special calling convention to save generated code space. 747 // Arguments are passed in registers, but the space for those arguments are allocated 748 // in the caller's stack frame. These stubs write the args into that stack space and 749 // then tail call to the corresponding runtime handler. 750 // The tail call makes these stubs disappear in backtraces. 751 TEXT runtime·panicIndex(SB),NOSPLIT,$0-8 752 MOVW R1, x+0(FP) 753 MOVW R2, y+4(FP) 754 JMP runtime·goPanicIndex(SB) 755 TEXT runtime·panicIndexU(SB),NOSPLIT,$0-8 756 MOVW R1, x+0(FP) 757 MOVW R2, y+4(FP) 758 JMP runtime·goPanicIndexU(SB) 759 TEXT runtime·panicSliceAlen(SB),NOSPLIT,$0-8 760 MOVW R2, x+0(FP) 761 MOVW R3, y+4(FP) 762 JMP runtime·goPanicSliceAlen(SB) 763 TEXT runtime·panicSliceAlenU(SB),NOSPLIT,$0-8 764 MOVW R2, x+0(FP) 765 MOVW R3, y+4(FP) 766 JMP runtime·goPanicSliceAlenU(SB) 767 TEXT runtime·panicSliceAcap(SB),NOSPLIT,$0-8 768 MOVW R2, x+0(FP) 769 MOVW R3, y+4(FP) 770 JMP runtime·goPanicSliceAcap(SB) 771 TEXT runtime·panicSliceAcapU(SB),NOSPLIT,$0-8 772 MOVW R2, x+0(FP) 773 MOVW R3, y+4(FP) 774 JMP runtime·goPanicSliceAcapU(SB) 775 TEXT runtime·panicSliceB(SB),NOSPLIT,$0-8 776 MOVW R1, x+0(FP) 777 MOVW R2, y+4(FP) 778 JMP runtime·goPanicSliceB(SB) 779 TEXT runtime·panicSliceBU(SB),NOSPLIT,$0-8 780 MOVW R1, x+0(FP) 781 MOVW R2, y+4(FP) 782 JMP runtime·goPanicSliceBU(SB) 783 TEXT runtime·panicSlice3Alen(SB),NOSPLIT,$0-8 784 MOVW R3, x+0(FP) 785 MOVW R4, y+4(FP) 786 JMP runtime·goPanicSlice3Alen(SB) 787 TEXT runtime·panicSlice3AlenU(SB),NOSPLIT,$0-8 788 MOVW R3, x+0(FP) 789 MOVW R4, y+4(FP) 790 JMP runtime·goPanicSlice3AlenU(SB) 791 TEXT runtime·panicSlice3Acap(SB),NOSPLIT,$0-8 792 MOVW R3, x+0(FP) 793 MOVW R4, y+4(FP) 794 JMP runtime·goPanicSlice3Acap(SB) 795 TEXT runtime·panicSlice3AcapU(SB),NOSPLIT,$0-8 796 MOVW R3, x+0(FP) 797 MOVW R4, y+4(FP) 798 JMP runtime·goPanicSlice3AcapU(SB) 799 TEXT runtime·panicSlice3B(SB),NOSPLIT,$0-8 800 MOVW R2, x+0(FP) 801 MOVW R3, y+4(FP) 802 JMP runtime·goPanicSlice3B(SB) 803 TEXT runtime·panicSlice3BU(SB),NOSPLIT,$0-8 804 MOVW R2, x+0(FP) 805 MOVW R3, y+4(FP) 806 JMP runtime·goPanicSlice3BU(SB) 807 TEXT runtime·panicSlice3C(SB),NOSPLIT,$0-8 808 MOVW R1, x+0(FP) 809 MOVW R2, y+4(FP) 810 JMP runtime·goPanicSlice3C(SB) 811 TEXT runtime·panicSlice3CU(SB),NOSPLIT,$0-8 812 MOVW R1, x+0(FP) 813 MOVW R2, y+4(FP) 814 JMP runtime·goPanicSlice3CU(SB) 815 816 // Extended versions for 64-bit indexes. 817 TEXT runtime·panicExtendIndex(SB),NOSPLIT,$0-12 818 MOVW R5, hi+0(FP) 819 MOVW R1, lo+4(FP) 820 MOVW R2, y+8(FP) 821 JMP runtime·goPanicExtendIndex(SB) 822 TEXT runtime·panicExtendIndexU(SB),NOSPLIT,$0-12 823 MOVW R5, hi+0(FP) 824 MOVW R1, lo+4(FP) 825 MOVW R2, y+8(FP) 826 JMP runtime·goPanicExtendIndexU(SB) 827 TEXT runtime·panicExtendSliceAlen(SB),NOSPLIT,$0-12 828 MOVW R5, hi+0(FP) 829 MOVW R2, lo+4(FP) 830 MOVW R3, y+8(FP) 831 JMP runtime·goPanicExtendSliceAlen(SB) 832 TEXT runtime·panicExtendSliceAlenU(SB),NOSPLIT,$0-12 833 MOVW R5, hi+0(FP) 834 MOVW R2, lo+4(FP) 835 MOVW R3, y+8(FP) 836 JMP runtime·goPanicExtendSliceAlenU(SB) 837 TEXT runtime·panicExtendSliceAcap(SB),NOSPLIT,$0-12 838 MOVW R5, hi+0(FP) 839 MOVW R2, lo+4(FP) 840 MOVW R3, y+8(FP) 841 JMP runtime·goPanicExtendSliceAcap(SB) 842 TEXT runtime·panicExtendSliceAcapU(SB),NOSPLIT,$0-12 843 MOVW R5, hi+0(FP) 844 MOVW R2, lo+4(FP) 845 MOVW R3, y+8(FP) 846 JMP runtime·goPanicExtendSliceAcapU(SB) 847 TEXT runtime·panicExtendSliceB(SB),NOSPLIT,$0-12 848 MOVW R5, hi+0(FP) 849 MOVW R1, lo+4(FP) 850 MOVW R2, y+8(FP) 851 JMP runtime·goPanicExtendSliceB(SB) 852 TEXT runtime·panicExtendSliceBU(SB),NOSPLIT,$0-12 853 MOVW R5, hi+0(FP) 854 MOVW R1, lo+4(FP) 855 MOVW R2, y+8(FP) 856 JMP runtime·goPanicExtendSliceBU(SB) 857 TEXT runtime·panicExtendSlice3Alen(SB),NOSPLIT,$0-12 858 MOVW R5, hi+0(FP) 859 MOVW R3, lo+4(FP) 860 MOVW R4, y+8(FP) 861 JMP runtime·goPanicExtendSlice3Alen(SB) 862 TEXT runtime·panicExtendSlice3AlenU(SB),NOSPLIT,$0-12 863 MOVW R5, hi+0(FP) 864 MOVW R3, lo+4(FP) 865 MOVW R4, y+8(FP) 866 JMP runtime·goPanicExtendSlice3AlenU(SB) 867 TEXT runtime·panicExtendSlice3Acap(SB),NOSPLIT,$0-12 868 MOVW R5, hi+0(FP) 869 MOVW R3, lo+4(FP) 870 MOVW R4, y+8(FP) 871 JMP runtime·goPanicExtendSlice3Acap(SB) 872 TEXT runtime·panicExtendSlice3AcapU(SB),NOSPLIT,$0-12 873 MOVW R5, hi+0(FP) 874 MOVW R3, lo+4(FP) 875 MOVW R4, y+8(FP) 876 JMP runtime·goPanicExtendSlice3AcapU(SB) 877 TEXT runtime·panicExtendSlice3B(SB),NOSPLIT,$0-12 878 MOVW R5, hi+0(FP) 879 MOVW R2, lo+4(FP) 880 MOVW R3, y+8(FP) 881 JMP runtime·goPanicExtendSlice3B(SB) 882 TEXT runtime·panicExtendSlice3BU(SB),NOSPLIT,$0-12 883 MOVW R5, hi+0(FP) 884 MOVW R2, lo+4(FP) 885 MOVW R3, y+8(FP) 886 JMP runtime·goPanicExtendSlice3BU(SB) 887 TEXT runtime·panicExtendSlice3C(SB),NOSPLIT,$0-12 888 MOVW R5, hi+0(FP) 889 MOVW R1, lo+4(FP) 890 MOVW R2, y+8(FP) 891 JMP runtime·goPanicExtendSlice3C(SB) 892 TEXT runtime·panicExtendSlice3CU(SB),NOSPLIT,$0-12 893 MOVW R5, hi+0(FP) 894 MOVW R1, lo+4(FP) 895 MOVW R2, y+8(FP) 896 JMP runtime·goPanicExtendSlice3CU(SB)