github.com/ice-blockchain/go/src@v0.0.0-20240403114104-1564d284e521/runtime/asm_ppc64x.s (about) 1 // Copyright 2014 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 //go:build ppc64 || ppc64le 6 7 #include "go_asm.h" 8 #include "go_tls.h" 9 #include "funcdata.h" 10 #include "textflag.h" 11 #include "asm_ppc64x.h" 12 13 #ifdef GOOS_aix 14 #define cgoCalleeStackSize 48 15 #else 16 #define cgoCalleeStackSize 32 17 #endif 18 19 TEXT runtime·rt0_go(SB),NOSPLIT|TOPFRAME,$0 20 // R1 = stack; R3 = argc; R4 = argv; R13 = C TLS base pointer 21 22 // initialize essential registers 23 BL runtime·reginit(SB) 24 25 SUB $(FIXED_FRAME+16), R1 26 MOVD R2, 24(R1) // stash the TOC pointer away again now we've created a new frame 27 MOVW R3, FIXED_FRAME+0(R1) // argc 28 MOVD R4, FIXED_FRAME+8(R1) // argv 29 30 // create istack out of the given (operating system) stack. 31 // _cgo_init may update stackguard. 32 MOVD $runtime·g0(SB), g 33 BL runtime·save_g(SB) 34 MOVD $(-64*1024), R31 35 ADD R31, R1, R3 36 MOVD R3, g_stackguard0(g) 37 MOVD R3, g_stackguard1(g) 38 MOVD R3, (g_stack+stack_lo)(g) 39 MOVD R1, (g_stack+stack_hi)(g) 40 41 // If there is a _cgo_init, call it using the gcc ABI. 42 MOVD _cgo_init(SB), R12 43 CMP R0, R12 44 BEQ nocgo 45 46 #ifdef GO_PPC64X_HAS_FUNCDESC 47 // Load the real entry address from the first slot of the function descriptor. 48 MOVD 8(R12), R2 49 MOVD (R12), R12 50 #endif 51 MOVD R12, CTR // r12 = "global function entry point" 52 MOVD R13, R5 // arg 2: TLS base pointer 53 MOVD $setg_gcc<>(SB), R4 // arg 1: setg 54 MOVD g, R3 // arg 0: G 55 // C functions expect 32 (48 for AIX) bytes of space on caller 56 // stack frame and a 16-byte aligned R1 57 MOVD R1, R14 // save current stack 58 SUB $cgoCalleeStackSize, R1 // reserve the callee area 59 RLDCR $0, R1, $~15, R1 // 16-byte align 60 BL (CTR) // may clobber R0, R3-R12 61 MOVD R14, R1 // restore stack 62 #ifndef GOOS_aix 63 MOVD 24(R1), R2 64 #endif 65 XOR R0, R0 // fix R0 66 67 nocgo: 68 // update stackguard after _cgo_init 69 MOVD (g_stack+stack_lo)(g), R3 70 ADD $const_stackGuard, R3 71 MOVD R3, g_stackguard0(g) 72 MOVD R3, g_stackguard1(g) 73 74 // set the per-goroutine and per-mach "registers" 75 MOVD $runtime·m0(SB), R3 76 77 // save m->g0 = g0 78 MOVD g, m_g0(R3) 79 // save m0 to g0->m 80 MOVD R3, g_m(g) 81 82 BL runtime·check(SB) 83 84 // args are already prepared 85 BL runtime·args(SB) 86 BL runtime·osinit(SB) 87 BL runtime·schedinit(SB) 88 89 // create a new goroutine to start program 90 MOVD $runtime·mainPC(SB), R3 // entry 91 MOVDU R3, -8(R1) 92 MOVDU R0, -8(R1) 93 MOVDU R0, -8(R1) 94 MOVDU R0, -8(R1) 95 MOVDU R0, -8(R1) 96 BL runtime·newproc(SB) 97 ADD $(8+FIXED_FRAME), R1 98 99 // start this M 100 BL runtime·mstart(SB) 101 // Prevent dead-code elimination of debugCallV2, which is 102 // intended to be called by debuggers. 103 #ifdef GOARCH_ppc64le 104 MOVD $runtime·debugCallV2<ABIInternal>(SB), R31 105 #endif 106 MOVD R0, 0(R0) 107 RET 108 109 DATA runtime·mainPC+0(SB)/8,$runtime·main<ABIInternal>(SB) 110 GLOBL runtime·mainPC(SB),RODATA,$8 111 112 TEXT runtime·breakpoint(SB),NOSPLIT|NOFRAME,$0-0 113 TW $31, R0, R0 114 RET 115 116 TEXT runtime·asminit(SB),NOSPLIT|NOFRAME,$0-0 117 RET 118 119 // Any changes must be reflected to runtime/cgo/gcc_aix_ppc64.S:.crosscall_ppc64 120 TEXT _cgo_reginit(SB),NOSPLIT|NOFRAME,$0-0 121 // crosscall_ppc64 and crosscall2 need to reginit, but can't 122 // get at the 'runtime.reginit' symbol. 123 BR runtime·reginit(SB) 124 125 TEXT runtime·reginit(SB),NOSPLIT|NOFRAME,$0-0 126 // set R0 to zero, it's expected by the toolchain 127 XOR R0, R0 128 RET 129 130 TEXT runtime·mstart(SB),NOSPLIT|TOPFRAME,$0 131 BL runtime·mstart0(SB) 132 RET // not reached 133 134 /* 135 * go-routine 136 */ 137 138 // void gogo(Gobuf*) 139 // restore state from Gobuf; longjmp 140 TEXT runtime·gogo(SB), NOSPLIT|NOFRAME, $0-8 141 MOVD buf+0(FP), R5 142 MOVD gobuf_g(R5), R6 143 MOVD 0(R6), R4 // make sure g != nil 144 BR gogo<>(SB) 145 146 TEXT gogo<>(SB), NOSPLIT|NOFRAME, $0 147 MOVD R6, g 148 BL runtime·save_g(SB) 149 150 MOVD gobuf_sp(R5), R1 151 MOVD gobuf_lr(R5), R31 152 #ifndef GOOS_aix 153 MOVD 24(R1), R2 // restore R2 154 #endif 155 MOVD R31, LR 156 MOVD gobuf_ret(R5), R3 157 MOVD gobuf_ctxt(R5), R11 158 MOVD R0, gobuf_sp(R5) 159 MOVD R0, gobuf_ret(R5) 160 MOVD R0, gobuf_lr(R5) 161 MOVD R0, gobuf_ctxt(R5) 162 CMP R0, R0 // set condition codes for == test, needed by stack split 163 MOVD gobuf_pc(R5), R12 164 MOVD R12, CTR 165 BR (CTR) 166 167 // void mcall(fn func(*g)) 168 // Switch to m->g0's stack, call fn(g). 169 // Fn must never return. It should gogo(&g->sched) 170 // to keep running g. 171 TEXT runtime·mcall<ABIInternal>(SB), NOSPLIT|NOFRAME, $0-8 172 // Save caller state in g->sched 173 // R11 should be safe across save_g?? 174 MOVD R3, R11 175 MOVD R1, (g_sched+gobuf_sp)(g) 176 MOVD LR, R31 177 MOVD R31, (g_sched+gobuf_pc)(g) 178 MOVD R0, (g_sched+gobuf_lr)(g) 179 180 // Switch to m->g0 & its stack, call fn. 181 MOVD g, R3 182 MOVD g_m(g), R8 183 MOVD m_g0(R8), g 184 BL runtime·save_g(SB) 185 CMP g, R3 186 BNE 2(PC) 187 BR runtime·badmcall(SB) 188 MOVD 0(R11), R12 // code pointer 189 MOVD R12, CTR 190 MOVD (g_sched+gobuf_sp)(g), R1 // sp = m->g0->sched.sp 191 // Don't need to do anything special for regabiargs here 192 // R3 is g; stack is set anyway 193 MOVDU R3, -8(R1) 194 MOVDU R0, -8(R1) 195 MOVDU R0, -8(R1) 196 MOVDU R0, -8(R1) 197 MOVDU R0, -8(R1) 198 BL (CTR) 199 MOVD 24(R1), R2 200 BR runtime·badmcall2(SB) 201 202 // systemstack_switch is a dummy routine that systemstack leaves at the bottom 203 // of the G stack. We need to distinguish the routine that 204 // lives at the bottom of the G stack from the one that lives 205 // at the top of the system stack because the one at the top of 206 // the system stack terminates the stack walk (see topofstack()). 207 TEXT runtime·systemstack_switch(SB), NOSPLIT, $0-0 208 // We have several undefs here so that 16 bytes past 209 // $runtime·systemstack_switch lies within them whether or not the 210 // instructions that derive r2 from r12 are there. 211 UNDEF 212 UNDEF 213 UNDEF 214 BL (LR) // make sure this function is not leaf 215 RET 216 217 // func systemstack(fn func()) 218 TEXT runtime·systemstack(SB), NOSPLIT, $0-8 219 MOVD fn+0(FP), R3 // R3 = fn 220 MOVD R3, R11 // context 221 MOVD g_m(g), R4 // R4 = m 222 223 MOVD m_gsignal(R4), R5 // R5 = gsignal 224 CMP g, R5 225 BEQ noswitch 226 227 MOVD m_g0(R4), R5 // R5 = g0 228 CMP g, R5 229 BEQ noswitch 230 231 MOVD m_curg(R4), R6 232 CMP g, R6 233 BEQ switch 234 235 // Bad: g is not gsignal, not g0, not curg. What is it? 236 // Hide call from linker nosplit analysis. 237 MOVD $runtime·badsystemstack(SB), R12 238 MOVD R12, CTR 239 BL (CTR) 240 BL runtime·abort(SB) 241 242 switch: 243 // save our state in g->sched. Pretend to 244 // be systemstack_switch if the G stack is scanned. 245 BL gosave_systemstack_switch<>(SB) 246 247 // switch to g0 248 MOVD R5, g 249 BL runtime·save_g(SB) 250 MOVD (g_sched+gobuf_sp)(g), R1 251 252 // call target function 253 MOVD 0(R11), R12 // code pointer 254 MOVD R12, CTR 255 BL (CTR) 256 257 // restore TOC pointer. It seems unlikely that we will use systemstack 258 // to call a function defined in another module, but the results of 259 // doing so would be so confusing that it's worth doing this. 260 MOVD g_m(g), R3 261 MOVD m_curg(R3), g 262 MOVD (g_sched+gobuf_sp)(g), R3 263 #ifndef GOOS_aix 264 MOVD 24(R3), R2 265 #endif 266 // switch back to g 267 MOVD g_m(g), R3 268 MOVD m_curg(R3), g 269 BL runtime·save_g(SB) 270 MOVD (g_sched+gobuf_sp)(g), R1 271 MOVD R0, (g_sched+gobuf_sp)(g) 272 RET 273 274 noswitch: 275 // already on m stack, just call directly 276 // On other arches we do a tail call here, but it appears to be 277 // impossible to tail call a function pointer in shared mode on 278 // ppc64 because the caller is responsible for restoring the TOC. 279 MOVD 0(R11), R12 // code pointer 280 MOVD R12, CTR 281 BL (CTR) 282 #ifndef GOOS_aix 283 MOVD 24(R1), R2 284 #endif 285 RET 286 287 // func switchToCrashStack0(fn func()) 288 TEXT runtime·switchToCrashStack0<ABIInternal>(SB), NOSPLIT, $0-8 289 MOVD R3, R11 // context register 290 MOVD g_m(g), R3 // curm 291 292 // set g to gcrash 293 MOVD $runtime·gcrash(SB), g // g = &gcrash 294 CALL runtime·save_g(SB) // clobbers R31 295 MOVD R3, g_m(g) // g.m = curm 296 MOVD g, m_g0(R3) // curm.g0 = g 297 298 // switch to crashstack 299 MOVD (g_stack+stack_hi)(g), R3 300 SUB $(4*8), R3 301 MOVD R3, R1 302 303 // call target function 304 MOVD 0(R11), R12 // code pointer 305 MOVD R12, CTR 306 BL (CTR) 307 308 // should never return 309 CALL runtime·abort(SB) 310 UNDEF 311 312 /* 313 * support for morestack 314 */ 315 316 // Called during function prolog when more stack is needed. 317 // Caller has already loaded: 318 // R3: framesize, R4: argsize, R5: LR 319 // 320 // The traceback routines see morestack on a g0 as being 321 // the top of a stack (for example, morestack calling newstack 322 // calling the scheduler calling newm calling gc), so we must 323 // record an argument size. For that purpose, it has no arguments. 324 TEXT runtime·morestack(SB),NOSPLIT|NOFRAME,$0-0 325 // Called from f. 326 // Set g->sched to context in f. 327 MOVD R1, (g_sched+gobuf_sp)(g) 328 MOVD LR, R8 329 MOVD R8, (g_sched+gobuf_pc)(g) 330 MOVD R5, (g_sched+gobuf_lr)(g) 331 MOVD R11, (g_sched+gobuf_ctxt)(g) 332 333 // Cannot grow scheduler stack (m->g0). 334 MOVD g_m(g), R7 335 MOVD m_g0(R7), R8 336 CMP g, R8 337 BNE 3(PC) 338 BL runtime·badmorestackg0(SB) 339 BL runtime·abort(SB) 340 341 // Cannot grow signal stack (m->gsignal). 342 MOVD m_gsignal(R7), R8 343 CMP g, R8 344 BNE 3(PC) 345 BL runtime·badmorestackgsignal(SB) 346 BL runtime·abort(SB) 347 348 // Called from f. 349 // Set m->morebuf to f's caller. 350 MOVD R5, (m_morebuf+gobuf_pc)(R7) // f's caller's PC 351 MOVD R1, (m_morebuf+gobuf_sp)(R7) // f's caller's SP 352 MOVD g, (m_morebuf+gobuf_g)(R7) 353 354 // Call newstack on m->g0's stack. 355 MOVD m_g0(R7), g 356 BL runtime·save_g(SB) 357 MOVD (g_sched+gobuf_sp)(g), R1 358 MOVDU R0, -(FIXED_FRAME+0)(R1) // create a call frame on g0 359 BL runtime·newstack(SB) 360 361 // Not reached, but make sure the return PC from the call to newstack 362 // is still in this function, and not the beginning of the next. 363 UNDEF 364 365 TEXT runtime·morestack_noctxt(SB),NOSPLIT|NOFRAME,$0-0 366 // Force SPWRITE. This function doesn't actually write SP, 367 // but it is called with a special calling convention where 368 // the caller doesn't save LR on stack but passes it as a 369 // register (R5), and the unwinder currently doesn't understand. 370 // Make it SPWRITE to stop unwinding. (See issue 54332) 371 // Use OR R0, R1 instead of MOVD R1, R1 as the MOVD instruction 372 // has a special affect on Power8,9,10 by lowering the thread 373 // priority and causing a slowdown in execution time 374 375 OR R0, R1 376 MOVD R0, R11 377 BR runtime·morestack(SB) 378 379 // reflectcall: call a function with the given argument list 380 // func call(stackArgsType *_type, f *FuncVal, stackArgs *byte, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs). 381 // we don't have variable-sized frames, so we use a small number 382 // of constant-sized-frame functions to encode a few bits of size in the pc. 383 // Caution: ugly multiline assembly macros in your future! 384 385 #define DISPATCH(NAME,MAXSIZE) \ 386 MOVD $MAXSIZE, R31; \ 387 CMP R3, R31; \ 388 BGT 4(PC); \ 389 MOVD $NAME(SB), R12; \ 390 MOVD R12, CTR; \ 391 BR (CTR) 392 // Note: can't just "BR NAME(SB)" - bad inlining results. 393 394 TEXT ·reflectcall(SB), NOSPLIT|NOFRAME, $0-48 395 MOVWZ frameSize+32(FP), R3 396 DISPATCH(runtime·call16, 16) 397 DISPATCH(runtime·call32, 32) 398 DISPATCH(runtime·call64, 64) 399 DISPATCH(runtime·call128, 128) 400 DISPATCH(runtime·call256, 256) 401 DISPATCH(runtime·call512, 512) 402 DISPATCH(runtime·call1024, 1024) 403 DISPATCH(runtime·call2048, 2048) 404 DISPATCH(runtime·call4096, 4096) 405 DISPATCH(runtime·call8192, 8192) 406 DISPATCH(runtime·call16384, 16384) 407 DISPATCH(runtime·call32768, 32768) 408 DISPATCH(runtime·call65536, 65536) 409 DISPATCH(runtime·call131072, 131072) 410 DISPATCH(runtime·call262144, 262144) 411 DISPATCH(runtime·call524288, 524288) 412 DISPATCH(runtime·call1048576, 1048576) 413 DISPATCH(runtime·call2097152, 2097152) 414 DISPATCH(runtime·call4194304, 4194304) 415 DISPATCH(runtime·call8388608, 8388608) 416 DISPATCH(runtime·call16777216, 16777216) 417 DISPATCH(runtime·call33554432, 33554432) 418 DISPATCH(runtime·call67108864, 67108864) 419 DISPATCH(runtime·call134217728, 134217728) 420 DISPATCH(runtime·call268435456, 268435456) 421 DISPATCH(runtime·call536870912, 536870912) 422 DISPATCH(runtime·call1073741824, 1073741824) 423 MOVD $runtime·badreflectcall(SB), R12 424 MOVD R12, CTR 425 BR (CTR) 426 427 #define CALLFN(NAME,MAXSIZE) \ 428 TEXT NAME(SB), WRAPPER, $MAXSIZE-48; \ 429 NO_LOCAL_POINTERS; \ 430 /* copy arguments to stack */ \ 431 MOVD stackArgs+16(FP), R3; \ 432 MOVWZ stackArgsSize+24(FP), R4; \ 433 MOVD R1, R5; \ 434 CMP R4, $8; \ 435 BLT tailsetup; \ 436 /* copy 8 at a time if possible */ \ 437 ADD $(FIXED_FRAME-8), R5; \ 438 SUB $8, R3; \ 439 top: \ 440 MOVDU 8(R3), R7; \ 441 MOVDU R7, 8(R5); \ 442 SUB $8, R4; \ 443 CMP R4, $8; \ 444 BGE top; \ 445 /* handle remaining bytes */ \ 446 CMP $0, R4; \ 447 BEQ callfn; \ 448 ADD $7, R3; \ 449 ADD $7, R5; \ 450 BR tail; \ 451 tailsetup: \ 452 CMP $0, R4; \ 453 BEQ callfn; \ 454 ADD $(FIXED_FRAME-1), R5; \ 455 SUB $1, R3; \ 456 tail: \ 457 MOVBU 1(R3), R6; \ 458 MOVBU R6, 1(R5); \ 459 SUB $1, R4; \ 460 CMP $0, R4; \ 461 BGT tail; \ 462 callfn: \ 463 /* call function */ \ 464 MOVD f+8(FP), R11; \ 465 #ifdef GOOS_aix \ 466 /* AIX won't trigger a SIGSEGV if R11 = nil */ \ 467 /* So it manually triggers it */ \ 468 CMP R0, R11 \ 469 BNE 2(PC) \ 470 MOVD R0, 0(R0) \ 471 #endif \ 472 MOVD regArgs+40(FP), R20; \ 473 BL runtime·unspillArgs(SB); \ 474 MOVD (R11), R12; \ 475 MOVD R12, CTR; \ 476 PCDATA $PCDATA_StackMapIndex, $0; \ 477 BL (CTR); \ 478 #ifndef GOOS_aix \ 479 MOVD 24(R1), R2; \ 480 #endif \ 481 /* copy return values back */ \ 482 MOVD regArgs+40(FP), R20; \ 483 BL runtime·spillArgs(SB); \ 484 MOVD stackArgsType+0(FP), R7; \ 485 MOVD stackArgs+16(FP), R3; \ 486 MOVWZ stackArgsSize+24(FP), R4; \ 487 MOVWZ stackRetOffset+28(FP), R6; \ 488 ADD $FIXED_FRAME, R1, R5; \ 489 ADD R6, R5; \ 490 ADD R6, R3; \ 491 SUB R6, R4; \ 492 BL callRet<>(SB); \ 493 RET 494 495 // callRet copies return values back at the end of call*. This is a 496 // separate function so it can allocate stack space for the arguments 497 // to reflectcallmove. It does not follow the Go ABI; it expects its 498 // arguments in registers. 499 TEXT callRet<>(SB), NOSPLIT, $40-0 500 NO_LOCAL_POINTERS 501 MOVD R7, FIXED_FRAME+0(R1) 502 MOVD R3, FIXED_FRAME+8(R1) 503 MOVD R5, FIXED_FRAME+16(R1) 504 MOVD R4, FIXED_FRAME+24(R1) 505 MOVD R20, FIXED_FRAME+32(R1) 506 BL runtime·reflectcallmove(SB) 507 RET 508 509 CALLFN(·call16, 16) 510 CALLFN(·call32, 32) 511 CALLFN(·call64, 64) 512 CALLFN(·call128, 128) 513 CALLFN(·call256, 256) 514 CALLFN(·call512, 512) 515 CALLFN(·call1024, 1024) 516 CALLFN(·call2048, 2048) 517 CALLFN(·call4096, 4096) 518 CALLFN(·call8192, 8192) 519 CALLFN(·call16384, 16384) 520 CALLFN(·call32768, 32768) 521 CALLFN(·call65536, 65536) 522 CALLFN(·call131072, 131072) 523 CALLFN(·call262144, 262144) 524 CALLFN(·call524288, 524288) 525 CALLFN(·call1048576, 1048576) 526 CALLFN(·call2097152, 2097152) 527 CALLFN(·call4194304, 4194304) 528 CALLFN(·call8388608, 8388608) 529 CALLFN(·call16777216, 16777216) 530 CALLFN(·call33554432, 33554432) 531 CALLFN(·call67108864, 67108864) 532 CALLFN(·call134217728, 134217728) 533 CALLFN(·call268435456, 268435456) 534 CALLFN(·call536870912, 536870912) 535 CALLFN(·call1073741824, 1073741824) 536 537 TEXT runtime·procyield(SB),NOSPLIT|NOFRAME,$0-4 538 MOVW cycles+0(FP), R7 539 // POWER does not have a pause/yield instruction equivalent. 540 // Instead, we can lower the program priority by setting the 541 // Program Priority Register prior to the wait loop and set it 542 // back to default afterwards. On Linux, the default priority is 543 // medium-low. For details, see page 837 of the ISA 3.0. 544 OR R1, R1, R1 // Set PPR priority to low 545 again: 546 SUB $1, R7 547 CMP $0, R7 548 BNE again 549 OR R6, R6, R6 // Set PPR priority back to medium-low 550 RET 551 552 // Save state of caller into g->sched, 553 // but using fake PC from systemstack_switch. 554 // Must only be called from functions with no locals ($0) 555 // or else unwinding from systemstack_switch is incorrect. 556 // Smashes R31. 557 TEXT gosave_systemstack_switch<>(SB),NOSPLIT|NOFRAME,$0 558 MOVD $runtime·systemstack_switch(SB), R31 559 ADD $16, R31 // get past prologue (including r2-setting instructions when they're there) 560 MOVD R31, (g_sched+gobuf_pc)(g) 561 MOVD R1, (g_sched+gobuf_sp)(g) 562 MOVD R0, (g_sched+gobuf_lr)(g) 563 MOVD R0, (g_sched+gobuf_ret)(g) 564 // Assert ctxt is zero. See func save. 565 MOVD (g_sched+gobuf_ctxt)(g), R31 566 CMP R0, R31 567 BEQ 2(PC) 568 BL runtime·abort(SB) 569 RET 570 571 #ifdef GOOS_aix 572 #define asmcgocallSaveOffset cgoCalleeStackSize + 8 573 #else 574 #define asmcgocallSaveOffset cgoCalleeStackSize 575 #endif 576 577 // func asmcgocall_no_g(fn, arg unsafe.Pointer) 578 // Call fn(arg) aligned appropriately for the gcc ABI. 579 // Called on a system stack, and there may be no g yet (during needm). 580 TEXT ·asmcgocall_no_g(SB),NOSPLIT,$0-16 581 MOVD fn+0(FP), R3 582 MOVD arg+8(FP), R4 583 584 MOVD R1, R15 585 SUB $(asmcgocallSaveOffset+8), R1 586 RLDCR $0, R1, $~15, R1 // 16-byte alignment for gcc ABI 587 MOVD R15, asmcgocallSaveOffset(R1) 588 589 MOVD R0, 0(R1) // clear back chain pointer (TODO can we give it real back trace information?) 590 591 // This is a "global call", so put the global entry point in r12 592 MOVD R3, R12 593 594 #ifdef GO_PPC64X_HAS_FUNCDESC 595 // Load the real entry address from the first slot of the function descriptor. 596 MOVD 8(R12), R2 597 MOVD (R12), R12 598 #endif 599 MOVD R12, CTR 600 MOVD R4, R3 // arg in r3 601 BL (CTR) 602 603 // C code can clobber R0, so set it back to 0. F27-F31 are 604 // callee save, so we don't need to recover those. 605 XOR R0, R0 606 607 MOVD asmcgocallSaveOffset(R1), R1 // Restore stack pointer. 608 #ifndef GOOS_aix 609 MOVD 24(R1), R2 610 #endif 611 612 RET 613 614 // func asmcgocall(fn, arg unsafe.Pointer) int32 615 // Call fn(arg) on the scheduler stack, 616 // aligned appropriately for the gcc ABI. 617 // See cgocall.go for more details. 618 TEXT ·asmcgocall(SB),NOSPLIT,$0-20 619 MOVD fn+0(FP), R3 620 MOVD arg+8(FP), R4 621 622 MOVD R1, R7 // save original stack pointer 623 CMP $0, g 624 BEQ nosave 625 MOVD g, R5 626 627 // Figure out if we need to switch to m->g0 stack. 628 // We get called to create new OS threads too, and those 629 // come in on the m->g0 stack already. Or we might already 630 // be on the m->gsignal stack. 631 MOVD g_m(g), R8 632 MOVD m_gsignal(R8), R6 633 CMP R6, g 634 BEQ nosave 635 MOVD m_g0(R8), R6 636 CMP R6, g 637 BEQ nosave 638 639 BL gosave_systemstack_switch<>(SB) 640 MOVD R6, g 641 BL runtime·save_g(SB) 642 MOVD (g_sched+gobuf_sp)(g), R1 643 644 // Now on a scheduling stack (a pthread-created stack). 645 #ifdef GOOS_aix 646 // Create a fake LR to improve backtrace. 647 MOVD $runtime·asmcgocall(SB), R6 648 MOVD R6, 16(R1) 649 // AIX also saves one argument on the stack. 650 SUB $8, R1 651 #endif 652 // Save room for two of our pointers, plus the callee 653 // save area that lives on the caller stack. 654 SUB $(asmcgocallSaveOffset+16), R1 655 RLDCR $0, R1, $~15, R1 // 16-byte alignment for gcc ABI 656 MOVD R5, (asmcgocallSaveOffset+8)(R1) // save old g on stack 657 MOVD (g_stack+stack_hi)(R5), R5 658 SUB R7, R5 659 MOVD R5, asmcgocallSaveOffset(R1) // save depth in old g stack (can't just save SP, as stack might be copied during a callback) 660 #ifdef GOOS_aix 661 MOVD R7, 0(R1) // Save frame pointer to allow manual backtrace with gdb 662 #else 663 MOVD R0, 0(R1) // clear back chain pointer (TODO can we give it real back trace information?) 664 #endif 665 // This is a "global call", so put the global entry point in r12 666 MOVD R3, R12 667 668 #ifdef GO_PPC64X_HAS_FUNCDESC 669 // Load the real entry address from the first slot of the function descriptor. 670 MOVD 8(R12), R2 671 MOVD (R12), R12 672 #endif 673 MOVD R12, CTR 674 MOVD R4, R3 // arg in r3 675 BL (CTR) 676 677 // Reinitialise zero value register. 678 XOR R0, R0 679 680 // Restore g, stack pointer, toc pointer. 681 // R3 is errno, so don't touch it 682 MOVD (asmcgocallSaveOffset+8)(R1), g 683 MOVD (g_stack+stack_hi)(g), R5 684 MOVD asmcgocallSaveOffset(R1), R6 685 SUB R6, R5 686 #ifndef GOOS_aix 687 MOVD 24(R5), R2 688 #endif 689 MOVD R5, R1 690 BL runtime·save_g(SB) 691 692 MOVW R3, ret+16(FP) 693 RET 694 695 nosave: 696 // Running on a system stack, perhaps even without a g. 697 // Having no g can happen during thread creation or thread teardown. 698 // This code is like the above sequence but without saving/restoring g 699 // and without worrying about the stack moving out from under us 700 // (because we're on a system stack, not a goroutine stack). 701 // The above code could be used directly if already on a system stack, 702 // but then the only path through this code would be a rare case. 703 // Using this code for all "already on system stack" calls exercises it more, 704 // which should help keep it correct. 705 706 SUB $(asmcgocallSaveOffset+8), R1 707 RLDCR $0, R1, $~15, R1 // 16-byte alignment for gcc ABI 708 MOVD R7, asmcgocallSaveOffset(R1) // Save original stack pointer. 709 710 MOVD R3, R12 // fn 711 #ifdef GO_PPC64X_HAS_FUNCDESC 712 // Load the real entry address from the first slot of the function descriptor. 713 MOVD 8(R12), R2 714 MOVD (R12), R12 715 #endif 716 MOVD R12, CTR 717 MOVD R4, R3 // arg 718 BL (CTR) 719 720 // Reinitialise zero value register. 721 XOR R0, R0 722 723 MOVD asmcgocallSaveOffset(R1), R1 // Restore stack pointer. 724 #ifndef GOOS_aix 725 MOVD 24(R1), R2 726 #endif 727 MOVW R3, ret+16(FP) 728 RET 729 730 // func cgocallback(fn, frame unsafe.Pointer, ctxt uintptr) 731 // See cgocall.go for more details. 732 TEXT ·cgocallback(SB),NOSPLIT,$24-24 733 NO_LOCAL_POINTERS 734 735 // Skip cgocallbackg, just dropm when fn is nil, and frame is the saved g. 736 // It is used to dropm while thread is exiting. 737 MOVD fn+0(FP), R5 738 CMP R5, $0 739 BNE loadg 740 // Restore the g from frame. 741 MOVD frame+8(FP), g 742 BR dropm 743 744 loadg: 745 // Load m and g from thread-local storage. 746 #ifndef GOOS_openbsd 747 MOVBZ runtime·iscgo(SB), R3 748 CMP R3, $0 749 BEQ nocgo 750 #endif 751 BL runtime·load_g(SB) 752 nocgo: 753 754 // If g is nil, Go did not create the current thread, 755 // or if this thread never called into Go on pthread platforms. 756 // Call needm to obtain one for temporary use. 757 // In this case, we're running on the thread stack, so there's 758 // lots of space, but the linker doesn't know. Hide the call from 759 // the linker analysis by using an indirect call. 760 CMP g, $0 761 BEQ needm 762 763 MOVD g_m(g), R8 764 MOVD R8, savedm-8(SP) 765 BR havem 766 767 needm: 768 MOVD g, savedm-8(SP) // g is zero, so is m. 769 MOVD $runtime·needAndBindM(SB), R12 770 MOVD R12, CTR 771 BL (CTR) 772 773 // Set m->sched.sp = SP, so that if a panic happens 774 // during the function we are about to execute, it will 775 // have a valid SP to run on the g0 stack. 776 // The next few lines (after the havem label) 777 // will save this SP onto the stack and then write 778 // the same SP back to m->sched.sp. That seems redundant, 779 // but if an unrecovered panic happens, unwindm will 780 // restore the g->sched.sp from the stack location 781 // and then systemstack will try to use it. If we don't set it here, 782 // that restored SP will be uninitialized (typically 0) and 783 // will not be usable. 784 MOVD g_m(g), R8 785 MOVD m_g0(R8), R3 786 MOVD R1, (g_sched+gobuf_sp)(R3) 787 788 havem: 789 // Now there's a valid m, and we're running on its m->g0. 790 // Save current m->g0->sched.sp on stack and then set it to SP. 791 // Save current sp in m->g0->sched.sp in preparation for 792 // switch back to m->curg stack. 793 // NOTE: unwindm knows that the saved g->sched.sp is at 8(R1) aka savedsp-16(SP). 794 MOVD m_g0(R8), R3 795 MOVD (g_sched+gobuf_sp)(R3), R4 796 MOVD R4, savedsp-24(SP) // must match frame size 797 MOVD R1, (g_sched+gobuf_sp)(R3) 798 799 // Switch to m->curg stack and call runtime.cgocallbackg. 800 // Because we are taking over the execution of m->curg 801 // but *not* resuming what had been running, we need to 802 // save that information (m->curg->sched) so we can restore it. 803 // We can restore m->curg->sched.sp easily, because calling 804 // runtime.cgocallbackg leaves SP unchanged upon return. 805 // To save m->curg->sched.pc, we push it onto the curg stack and 806 // open a frame the same size as cgocallback's g0 frame. 807 // Once we switch to the curg stack, the pushed PC will appear 808 // to be the return PC of cgocallback, so that the traceback 809 // will seamlessly trace back into the earlier calls. 810 MOVD m_curg(R8), g 811 BL runtime·save_g(SB) 812 MOVD (g_sched+gobuf_sp)(g), R4 // prepare stack as R4 813 MOVD (g_sched+gobuf_pc)(g), R5 814 MOVD R5, -(24+FIXED_FRAME)(R4) // "saved LR"; must match frame size 815 // Gather our arguments into registers. 816 MOVD fn+0(FP), R5 817 MOVD frame+8(FP), R6 818 MOVD ctxt+16(FP), R7 819 MOVD $-(24+FIXED_FRAME)(R4), R1 // switch stack; must match frame size 820 MOVD R5, FIXED_FRAME+0(R1) 821 MOVD R6, FIXED_FRAME+8(R1) 822 MOVD R7, FIXED_FRAME+16(R1) 823 824 MOVD $runtime·cgocallbackg(SB), R12 825 MOVD R12, CTR 826 CALL (CTR) // indirect call to bypass nosplit check. We're on a different stack now. 827 828 // Restore g->sched (== m->curg->sched) from saved values. 829 MOVD 0(R1), R5 830 MOVD R5, (g_sched+gobuf_pc)(g) 831 MOVD $(24+FIXED_FRAME)(R1), R4 // must match frame size 832 MOVD R4, (g_sched+gobuf_sp)(g) 833 834 // Switch back to m->g0's stack and restore m->g0->sched.sp. 835 // (Unlike m->curg, the g0 goroutine never uses sched.pc, 836 // so we do not have to restore it.) 837 MOVD g_m(g), R8 838 MOVD m_g0(R8), g 839 BL runtime·save_g(SB) 840 MOVD (g_sched+gobuf_sp)(g), R1 841 MOVD savedsp-24(SP), R4 // must match frame size 842 MOVD R4, (g_sched+gobuf_sp)(g) 843 844 // If the m on entry was nil, we called needm above to borrow an m, 845 // 1. for the duration of the call on non-pthread platforms, 846 // 2. or the duration of the C thread alive on pthread platforms. 847 // If the m on entry wasn't nil, 848 // 1. the thread might be a Go thread, 849 // 2. or it wasn't the first call from a C thread on pthread platforms, 850 // since then we skip dropm to reuse the m in the first call. 851 MOVD savedm-8(SP), R6 852 CMP R6, $0 853 BNE droppedm 854 855 // Skip dropm to reuse it in the next call, when a pthread key has been created. 856 MOVD _cgo_pthread_key_created(SB), R6 857 // It means cgo is disabled when _cgo_pthread_key_created is a nil pointer, need dropm. 858 CMP R6, $0 859 BEQ dropm 860 MOVD (R6), R6 861 CMP R6, $0 862 BNE droppedm 863 864 dropm: 865 MOVD $runtime·dropm(SB), R12 866 MOVD R12, CTR 867 BL (CTR) 868 droppedm: 869 870 // Done! 871 RET 872 873 // void setg(G*); set g. for use by needm. 874 TEXT runtime·setg(SB), NOSPLIT, $0-8 875 MOVD gg+0(FP), g 876 // This only happens if iscgo, so jump straight to save_g 877 BL runtime·save_g(SB) 878 RET 879 880 #ifdef GO_PPC64X_HAS_FUNCDESC 881 DEFINE_PPC64X_FUNCDESC(setg_gcc<>, _setg_gcc<>) 882 TEXT _setg_gcc<>(SB),NOSPLIT|NOFRAME,$0-0 883 #else 884 TEXT setg_gcc<>(SB),NOSPLIT|NOFRAME,$0-0 885 #endif 886 // The standard prologue clobbers R31, which is callee-save in 887 // the C ABI, so we have to use $-8-0 and save LR ourselves. 888 MOVD LR, R4 889 // Also save g and R31, since they're callee-save in C ABI 890 MOVD R31, R5 891 MOVD g, R6 892 893 MOVD R3, g 894 BL runtime·save_g(SB) 895 896 MOVD R6, g 897 MOVD R5, R31 898 MOVD R4, LR 899 RET 900 901 TEXT runtime·abort(SB),NOSPLIT|NOFRAME,$0-0 902 MOVW (R0), R0 903 UNDEF 904 905 #define TBR 268 906 907 // int64 runtime·cputicks(void) 908 TEXT runtime·cputicks(SB),NOSPLIT,$0-8 909 MOVD SPR(TBR), R3 910 MOVD R3, ret+0(FP) 911 RET 912 913 // spillArgs stores return values from registers to a *internal/abi.RegArgs in R20. 914 TEXT runtime·spillArgs(SB),NOSPLIT,$0-0 915 MOVD R3, 0(R20) 916 MOVD R4, 8(R20) 917 MOVD R5, 16(R20) 918 MOVD R6, 24(R20) 919 MOVD R7, 32(R20) 920 MOVD R8, 40(R20) 921 MOVD R9, 48(R20) 922 MOVD R10, 56(R20) 923 MOVD R14, 64(R20) 924 MOVD R15, 72(R20) 925 MOVD R16, 80(R20) 926 MOVD R17, 88(R20) 927 FMOVD F1, 96(R20) 928 FMOVD F2, 104(R20) 929 FMOVD F3, 112(R20) 930 FMOVD F4, 120(R20) 931 FMOVD F5, 128(R20) 932 FMOVD F6, 136(R20) 933 FMOVD F7, 144(R20) 934 FMOVD F8, 152(R20) 935 FMOVD F9, 160(R20) 936 FMOVD F10, 168(R20) 937 FMOVD F11, 176(R20) 938 FMOVD F12, 184(R20) 939 RET 940 941 // unspillArgs loads args into registers from a *internal/abi.RegArgs in R20. 942 TEXT runtime·unspillArgs(SB),NOSPLIT,$0-0 943 MOVD 0(R20), R3 944 MOVD 8(R20), R4 945 MOVD 16(R20), R5 946 MOVD 24(R20), R6 947 MOVD 32(R20), R7 948 MOVD 40(R20), R8 949 MOVD 48(R20), R9 950 MOVD 56(R20), R10 951 MOVD 64(R20), R14 952 MOVD 72(R20), R15 953 MOVD 80(R20), R16 954 MOVD 88(R20), R17 955 FMOVD 96(R20), F1 956 FMOVD 104(R20), F2 957 FMOVD 112(R20), F3 958 FMOVD 120(R20), F4 959 FMOVD 128(R20), F5 960 FMOVD 136(R20), F6 961 FMOVD 144(R20), F7 962 FMOVD 152(R20), F8 963 FMOVD 160(R20), F9 964 FMOVD 168(R20), F10 965 FMOVD 176(R20), F11 966 FMOVD 184(R20), F12 967 RET 968 969 // AES hashing not implemented for ppc64 970 TEXT runtime·memhash<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-32 971 JMP runtime·memhashFallback<ABIInternal>(SB) 972 TEXT runtime·strhash<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-24 973 JMP runtime·strhashFallback<ABIInternal>(SB) 974 TEXT runtime·memhash32<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-24 975 JMP runtime·memhash32Fallback<ABIInternal>(SB) 976 TEXT runtime·memhash64<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-24 977 JMP runtime·memhash64Fallback<ABIInternal>(SB) 978 979 TEXT runtime·return0(SB), NOSPLIT, $0 980 MOVW $0, R3 981 RET 982 983 // Called from cgo wrappers, this function returns g->m->curg.stack.hi. 984 // Must obey the gcc calling convention. 985 #ifdef GOOS_aix 986 // On AIX, _cgo_topofstack is defined in runtime/cgo, because it must 987 // be a longcall in order to prevent trampolines from ld. 988 TEXT __cgo_topofstack(SB),NOSPLIT|NOFRAME,$0 989 #else 990 TEXT _cgo_topofstack(SB),NOSPLIT|NOFRAME,$0 991 #endif 992 // g (R30) and R31 are callee-save in the C ABI, so save them 993 MOVD g, R4 994 MOVD R31, R5 995 MOVD LR, R6 996 997 BL runtime·load_g(SB) // clobbers g (R30), R31 998 MOVD g_m(g), R3 999 MOVD m_curg(R3), R3 1000 MOVD (g_stack+stack_hi)(R3), R3 1001 1002 MOVD R4, g 1003 MOVD R5, R31 1004 MOVD R6, LR 1005 RET 1006 1007 // The top-most function running on a goroutine 1008 // returns to goexit+PCQuantum. 1009 // 1010 // When dynamically linking Go, it can be returned to from a function 1011 // implemented in a different module and so needs to reload the TOC pointer 1012 // from the stack (although this function declares that it does not set up x-a 1013 // frame, newproc1 does in fact allocate one for goexit and saves the TOC 1014 // pointer in the correct place). 1015 // goexit+_PCQuantum is halfway through the usual global entry point prologue 1016 // that derives r2 from r12 which is a bit silly, but not harmful. 1017 TEXT runtime·goexit(SB),NOSPLIT|NOFRAME|TOPFRAME,$0-0 1018 MOVD 24(R1), R2 1019 BL runtime·goexit1(SB) // does not return 1020 // traceback from goexit1 must hit code range of goexit 1021 MOVD R0, R0 // NOP 1022 1023 // prepGoExitFrame saves the current TOC pointer (i.e. the TOC pointer for the 1024 // module containing runtime) to the frame that goexit will execute in when 1025 // the goroutine exits. It's implemented in assembly mainly because that's the 1026 // easiest way to get access to R2. 1027 TEXT runtime·prepGoExitFrame(SB),NOSPLIT,$0-8 1028 MOVD sp+0(FP), R3 1029 MOVD R2, 24(R3) 1030 RET 1031 1032 TEXT runtime·addmoduledata(SB),NOSPLIT|NOFRAME,$0-0 1033 ADD $-8, R1 1034 MOVD R31, 0(R1) 1035 MOVD runtime·lastmoduledatap(SB), R4 1036 MOVD R3, moduledata_next(R4) 1037 MOVD R3, runtime·lastmoduledatap(SB) 1038 MOVD 0(R1), R31 1039 ADD $8, R1 1040 RET 1041 1042 TEXT ·checkASM(SB),NOSPLIT,$0-1 1043 MOVW $1, R3 1044 MOVB R3, ret+0(FP) 1045 RET 1046 1047 // gcWriteBarrier informs the GC about heap pointer writes. 1048 // 1049 // gcWriteBarrier does NOT follow the Go ABI. It accepts the 1050 // number of bytes of buffer needed in R29, and returns a pointer 1051 // to the buffer space in R29. 1052 // It clobbers condition codes. 1053 // It does not clobber R0 through R17 (except special registers), 1054 // but may clobber any other register, *including* R31. 1055 TEXT gcWriteBarrier<>(SB),NOSPLIT,$120 1056 // The standard prologue clobbers R31. 1057 // We use R18, R19, and R31 as scratch registers. 1058 retry: 1059 MOVD g_m(g), R18 1060 MOVD m_p(R18), R18 1061 MOVD (p_wbBuf+wbBuf_next)(R18), R19 1062 MOVD (p_wbBuf+wbBuf_end)(R18), R31 1063 // Increment wbBuf.next position. 1064 ADD R29, R19 1065 // Is the buffer full? 1066 CMPU R31, R19 1067 BLT flush 1068 // Commit to the larger buffer. 1069 MOVD R19, (p_wbBuf+wbBuf_next)(R18) 1070 // Make return value (the original next position) 1071 SUB R29, R19, R29 1072 RET 1073 1074 flush: 1075 // Save registers R0 through R15 since these were not saved by the caller. 1076 // We don't save all registers on ppc64 because it takes too much space. 1077 MOVD R20, (FIXED_FRAME+0)(R1) 1078 MOVD R21, (FIXED_FRAME+8)(R1) 1079 // R0 is always 0, so no need to spill. 1080 // R1 is SP. 1081 // R2 is SB. 1082 MOVD R3, (FIXED_FRAME+16)(R1) 1083 MOVD R4, (FIXED_FRAME+24)(R1) 1084 MOVD R5, (FIXED_FRAME+32)(R1) 1085 MOVD R6, (FIXED_FRAME+40)(R1) 1086 MOVD R7, (FIXED_FRAME+48)(R1) 1087 MOVD R8, (FIXED_FRAME+56)(R1) 1088 MOVD R9, (FIXED_FRAME+64)(R1) 1089 MOVD R10, (FIXED_FRAME+72)(R1) 1090 // R11, R12 may be clobbered by external-linker-inserted trampoline 1091 // R13 is REGTLS 1092 MOVD R14, (FIXED_FRAME+80)(R1) 1093 MOVD R15, (FIXED_FRAME+88)(R1) 1094 MOVD R16, (FIXED_FRAME+96)(R1) 1095 MOVD R17, (FIXED_FRAME+104)(R1) 1096 MOVD R29, (FIXED_FRAME+112)(R1) 1097 1098 CALL runtime·wbBufFlush(SB) 1099 1100 MOVD (FIXED_FRAME+0)(R1), R20 1101 MOVD (FIXED_FRAME+8)(R1), R21 1102 MOVD (FIXED_FRAME+16)(R1), R3 1103 MOVD (FIXED_FRAME+24)(R1), R4 1104 MOVD (FIXED_FRAME+32)(R1), R5 1105 MOVD (FIXED_FRAME+40)(R1), R6 1106 MOVD (FIXED_FRAME+48)(R1), R7 1107 MOVD (FIXED_FRAME+56)(R1), R8 1108 MOVD (FIXED_FRAME+64)(R1), R9 1109 MOVD (FIXED_FRAME+72)(R1), R10 1110 MOVD (FIXED_FRAME+80)(R1), R14 1111 MOVD (FIXED_FRAME+88)(R1), R15 1112 MOVD (FIXED_FRAME+96)(R1), R16 1113 MOVD (FIXED_FRAME+104)(R1), R17 1114 MOVD (FIXED_FRAME+112)(R1), R29 1115 JMP retry 1116 1117 TEXT runtime·gcWriteBarrier1<ABIInternal>(SB),NOSPLIT,$0 1118 MOVD $8, R29 1119 JMP gcWriteBarrier<>(SB) 1120 TEXT runtime·gcWriteBarrier2<ABIInternal>(SB),NOSPLIT,$0 1121 MOVD $16, R29 1122 JMP gcWriteBarrier<>(SB) 1123 TEXT runtime·gcWriteBarrier3<ABIInternal>(SB),NOSPLIT,$0 1124 MOVD $24, R29 1125 JMP gcWriteBarrier<>(SB) 1126 TEXT runtime·gcWriteBarrier4<ABIInternal>(SB),NOSPLIT,$0 1127 MOVD $32, R29 1128 JMP gcWriteBarrier<>(SB) 1129 TEXT runtime·gcWriteBarrier5<ABIInternal>(SB),NOSPLIT,$0 1130 MOVD $40, R29 1131 JMP gcWriteBarrier<>(SB) 1132 TEXT runtime·gcWriteBarrier6<ABIInternal>(SB),NOSPLIT,$0 1133 MOVD $48, R29 1134 JMP gcWriteBarrier<>(SB) 1135 TEXT runtime·gcWriteBarrier7<ABIInternal>(SB),NOSPLIT,$0 1136 MOVD $56, R29 1137 JMP gcWriteBarrier<>(SB) 1138 TEXT runtime·gcWriteBarrier8<ABIInternal>(SB),NOSPLIT,$0 1139 MOVD $64, R29 1140 JMP gcWriteBarrier<>(SB) 1141 1142 DATA debugCallFrameTooLarge<>+0x00(SB)/20, $"call frame too large" 1143 GLOBL debugCallFrameTooLarge<>(SB), RODATA, $20 // Size duplicated below 1144 1145 // debugCallV2 is the entry point for debugger-injected function 1146 // calls on running goroutines. It informs the runtime that a 1147 // debug call has been injected and creates a call frame for the 1148 // debugger to fill in. 1149 // 1150 // To inject a function call, a debugger should: 1151 // 1. Check that the goroutine is in state _Grunning and that 1152 // there are at least 320 bytes free on the stack. 1153 // 2. Set SP as SP-32. 1154 // 3. Store the current LR in (SP) (using the SP after step 2). 1155 // 4. Store the current PC in the LR register. 1156 // 5. Write the desired argument frame size at SP-32 1157 // 6. Save all machine registers (including flags and floating point registers) 1158 // so they can be restored later by the debugger. 1159 // 7. Set the PC to debugCallV2 and resume execution. 1160 // 1161 // If the goroutine is in state _Grunnable, then it's not generally 1162 // safe to inject a call because it may return out via other runtime 1163 // operations. Instead, the debugger should unwind the stack to find 1164 // the return to non-runtime code, add a temporary breakpoint there, 1165 // and inject the call once that breakpoint is hit. 1166 // 1167 // If the goroutine is in any other state, it's not safe to inject a call. 1168 // 1169 // This function communicates back to the debugger by setting R20 and 1170 // invoking TW to raise a breakpoint signal. Note that the signal PC of 1171 // the signal triggered by the TW instruction is the PC where the signal 1172 // is trapped, not the next PC, so to resume execution, the debugger needs 1173 // to set the signal PC to PC+4. See the comments in the implementation for 1174 // the protocol the debugger is expected to follow. InjectDebugCall in the 1175 // runtime tests demonstrates this protocol. 1176 // The debugger must ensure that any pointers passed to the function 1177 // obey escape analysis requirements. Specifically, it must not pass 1178 // a stack pointer to an escaping argument. debugCallV2 cannot check 1179 // this invariant. 1180 // 1181 // This is ABIInternal because Go code injects its PC directly into new 1182 // goroutine stacks. 1183 #ifdef GOARCH_ppc64le 1184 TEXT runtime·debugCallV2<ABIInternal>(SB), NOSPLIT|NOFRAME, $0-0 1185 // save scratch register R31 first 1186 MOVD R31, -184(R1) 1187 MOVD 0(R1), R31 1188 // save caller LR 1189 MOVD R31, -304(R1) 1190 MOVD -32(R1), R31 1191 // save argument frame size 1192 MOVD R31, -192(R1) 1193 MOVD LR, R31 1194 MOVD R31, -320(R1) 1195 ADD $-320, R1 1196 // save all registers that can contain pointers 1197 // and the CR register 1198 MOVW CR, R31 1199 MOVD R31, 8(R1) 1200 MOVD R2, 24(R1) 1201 MOVD R3, 56(R1) 1202 MOVD R4, 64(R1) 1203 MOVD R5, 72(R1) 1204 MOVD R6, 80(R1) 1205 MOVD R7, 88(R1) 1206 MOVD R8, 96(R1) 1207 MOVD R9, 104(R1) 1208 MOVD R10, 112(R1) 1209 MOVD R11, 120(R1) 1210 MOVD R12, 144(R1) 1211 MOVD R13, 152(R1) 1212 MOVD R14, 160(R1) 1213 MOVD R15, 168(R1) 1214 MOVD R16, 176(R1) 1215 MOVD R17, 184(R1) 1216 MOVD R18, 192(R1) 1217 MOVD R19, 200(R1) 1218 MOVD R20, 208(R1) 1219 MOVD R21, 216(R1) 1220 MOVD R22, 224(R1) 1221 MOVD R23, 232(R1) 1222 MOVD R24, 240(R1) 1223 MOVD R25, 248(R1) 1224 MOVD R26, 256(R1) 1225 MOVD R27, 264(R1) 1226 MOVD R28, 272(R1) 1227 MOVD R29, 280(R1) 1228 MOVD g, 288(R1) 1229 MOVD LR, R31 1230 MOVD R31, 32(R1) 1231 CALL runtime·debugCallCheck(SB) 1232 MOVD 40(R1), R22 1233 XOR R0, R0 1234 CMP R22, R0 1235 BEQ good 1236 MOVD 48(R1), R22 1237 MOVD $8, R20 1238 TW $31, R0, R0 1239 1240 BR restore 1241 1242 good: 1243 #define DEBUG_CALL_DISPATCH(NAME,MAXSIZE) \ 1244 MOVD $MAXSIZE, R23; \ 1245 CMP R26, R23; \ 1246 BGT 5(PC); \ 1247 MOVD $NAME(SB), R26; \ 1248 MOVD R26, 32(R1); \ 1249 CALL runtime·debugCallWrap(SB); \ 1250 BR restore 1251 1252 // the argument frame size 1253 MOVD 128(R1), R26 1254 1255 DEBUG_CALL_DISPATCH(debugCall32<>, 32) 1256 DEBUG_CALL_DISPATCH(debugCall64<>, 64) 1257 DEBUG_CALL_DISPATCH(debugCall128<>, 128) 1258 DEBUG_CALL_DISPATCH(debugCall256<>, 256) 1259 DEBUG_CALL_DISPATCH(debugCall512<>, 512) 1260 DEBUG_CALL_DISPATCH(debugCall1024<>, 1024) 1261 DEBUG_CALL_DISPATCH(debugCall2048<>, 2048) 1262 DEBUG_CALL_DISPATCH(debugCall4096<>, 4096) 1263 DEBUG_CALL_DISPATCH(debugCall8192<>, 8192) 1264 DEBUG_CALL_DISPATCH(debugCall16384<>, 16384) 1265 DEBUG_CALL_DISPATCH(debugCall32768<>, 32768) 1266 DEBUG_CALL_DISPATCH(debugCall65536<>, 65536) 1267 // The frame size is too large. Report the error. 1268 MOVD $debugCallFrameTooLarge<>(SB), R22 1269 MOVD R22, 32(R1) 1270 MOVD $20, R22 1271 // length of debugCallFrameTooLarge string 1272 MOVD R22, 40(R1) 1273 MOVD $8, R20 1274 TW $31, R0, R0 1275 BR restore 1276 restore: 1277 MOVD $16, R20 1278 TW $31, R0, R0 1279 // restore all registers that can contain 1280 // pointers including CR 1281 MOVD 8(R1), R31 1282 MOVW R31, CR 1283 MOVD 24(R1), R2 1284 MOVD 56(R1), R3 1285 MOVD 64(R1), R4 1286 MOVD 72(R1), R5 1287 MOVD 80(R1), R6 1288 MOVD 88(R1), R7 1289 MOVD 96(R1), R8 1290 MOVD 104(R1), R9 1291 MOVD 112(R1), R10 1292 MOVD 120(R1), R11 1293 MOVD 144(R1), R12 1294 MOVD 152(R1), R13 1295 MOVD 160(R1), R14 1296 MOVD 168(R1), R15 1297 MOVD 176(R1), R16 1298 MOVD 184(R1), R17 1299 MOVD 192(R1), R18 1300 MOVD 200(R1), R19 1301 MOVD 208(R1), R20 1302 MOVD 216(R1), R21 1303 MOVD 224(R1), R22 1304 MOVD 232(R1), R23 1305 MOVD 240(R1), R24 1306 MOVD 248(R1), R25 1307 MOVD 256(R1), R26 1308 MOVD 264(R1), R27 1309 MOVD 272(R1), R28 1310 MOVD 280(R1), R29 1311 MOVD 288(R1), g 1312 MOVD 16(R1), R31 1313 // restore old LR 1314 MOVD R31, LR 1315 // restore caller PC 1316 MOVD 0(R1), CTR 1317 MOVD 136(R1), R31 1318 // Add 32 bytes more to compensate for SP change in saveSigContext 1319 ADD $352, R1 1320 JMP (CTR) 1321 #endif 1322 #define DEBUG_CALL_FN(NAME,MAXSIZE) \ 1323 TEXT NAME(SB),WRAPPER,$MAXSIZE-0; \ 1324 NO_LOCAL_POINTERS; \ 1325 MOVD $0, R20; \ 1326 TW $31, R0, R0 \ 1327 MOVD $1, R20; \ 1328 TW $31, R0, R0 \ 1329 RET 1330 DEBUG_CALL_FN(debugCall32<>, 32) 1331 DEBUG_CALL_FN(debugCall64<>, 64) 1332 DEBUG_CALL_FN(debugCall128<>, 128) 1333 DEBUG_CALL_FN(debugCall256<>, 256) 1334 DEBUG_CALL_FN(debugCall512<>, 512) 1335 DEBUG_CALL_FN(debugCall1024<>, 1024) 1336 DEBUG_CALL_FN(debugCall2048<>, 2048) 1337 DEBUG_CALL_FN(debugCall4096<>, 4096) 1338 DEBUG_CALL_FN(debugCall8192<>, 8192) 1339 DEBUG_CALL_FN(debugCall16384<>, 16384) 1340 DEBUG_CALL_FN(debugCall32768<>, 32768) 1341 DEBUG_CALL_FN(debugCall65536<>, 65536) 1342 1343 #ifdef GOARCH_ppc64le 1344 // func debugCallPanicked(val interface{}) 1345 TEXT runtime·debugCallPanicked(SB),NOSPLIT,$32-16 1346 // Copy the panic value to the top of stack at SP+32. 1347 MOVD val_type+0(FP), R31 1348 MOVD R31, 32(R1) 1349 MOVD val_data+8(FP), R31 1350 MOVD R31, 40(R1) 1351 MOVD $2, R20 1352 TW $31, R0, R0 1353 RET 1354 #endif 1355 // Note: these functions use a special calling convention to save generated code space. 1356 // Arguments are passed in registers, but the space for those arguments are allocated 1357 // in the caller's stack frame. These stubs write the args into that stack space and 1358 // then tail call to the corresponding runtime handler. 1359 // The tail call makes these stubs disappear in backtraces. 1360 TEXT runtime·panicIndex<ABIInternal>(SB),NOSPLIT,$0-16 1361 JMP runtime·goPanicIndex<ABIInternal>(SB) 1362 TEXT runtime·panicIndexU<ABIInternal>(SB),NOSPLIT,$0-16 1363 JMP runtime·goPanicIndexU<ABIInternal>(SB) 1364 TEXT runtime·panicSliceAlen<ABIInternal>(SB),NOSPLIT,$0-16 1365 MOVD R4, R3 1366 MOVD R5, R4 1367 JMP runtime·goPanicSliceAlen<ABIInternal>(SB) 1368 TEXT runtime·panicSliceAlenU<ABIInternal>(SB),NOSPLIT,$0-16 1369 MOVD R4, R3 1370 MOVD R5, R4 1371 JMP runtime·goPanicSliceAlenU<ABIInternal>(SB) 1372 TEXT runtime·panicSliceAcap<ABIInternal>(SB),NOSPLIT,$0-16 1373 MOVD R4, R3 1374 MOVD R5, R4 1375 JMP runtime·goPanicSliceAcap<ABIInternal>(SB) 1376 TEXT runtime·panicSliceAcapU<ABIInternal>(SB),NOSPLIT,$0-16 1377 MOVD R4, R3 1378 MOVD R5, R4 1379 JMP runtime·goPanicSliceAcapU<ABIInternal>(SB) 1380 TEXT runtime·panicSliceB<ABIInternal>(SB),NOSPLIT,$0-16 1381 JMP runtime·goPanicSliceB<ABIInternal>(SB) 1382 TEXT runtime·panicSliceBU<ABIInternal>(SB),NOSPLIT,$0-16 1383 JMP runtime·goPanicSliceBU<ABIInternal>(SB) 1384 TEXT runtime·panicSlice3Alen<ABIInternal>(SB),NOSPLIT,$0-16 1385 MOVD R5, R3 1386 MOVD R6, R4 1387 JMP runtime·goPanicSlice3Alen<ABIInternal>(SB) 1388 TEXT runtime·panicSlice3AlenU<ABIInternal>(SB),NOSPLIT,$0-16 1389 MOVD R5, R3 1390 MOVD R6, R4 1391 JMP runtime·goPanicSlice3AlenU<ABIInternal>(SB) 1392 TEXT runtime·panicSlice3Acap<ABIInternal>(SB),NOSPLIT,$0-16 1393 MOVD R5, R3 1394 MOVD R6, R4 1395 JMP runtime·goPanicSlice3Acap<ABIInternal>(SB) 1396 TEXT runtime·panicSlice3AcapU<ABIInternal>(SB),NOSPLIT,$0-16 1397 MOVD R5, R3 1398 MOVD R6, R4 1399 JMP runtime·goPanicSlice3AcapU<ABIInternal>(SB) 1400 TEXT runtime·panicSlice3B<ABIInternal>(SB),NOSPLIT,$0-16 1401 MOVD R4, R3 1402 MOVD R5, R4 1403 JMP runtime·goPanicSlice3B<ABIInternal>(SB) 1404 TEXT runtime·panicSlice3BU<ABIInternal>(SB),NOSPLIT,$0-16 1405 MOVD R4, R3 1406 MOVD R5, R4 1407 JMP runtime·goPanicSlice3BU<ABIInternal>(SB) 1408 TEXT runtime·panicSlice3C<ABIInternal>(SB),NOSPLIT,$0-16 1409 JMP runtime·goPanicSlice3C<ABIInternal>(SB) 1410 TEXT runtime·panicSlice3CU<ABIInternal>(SB),NOSPLIT,$0-16 1411 JMP runtime·goPanicSlice3CU<ABIInternal>(SB) 1412 TEXT runtime·panicSliceConvert<ABIInternal>(SB),NOSPLIT,$0-16 1413 MOVD R5, R3 1414 MOVD R6, R4 1415 JMP runtime·goPanicSliceConvert<ABIInternal>(SB) 1416 1417 // These functions are used when internal linking cgo with external 1418 // objects compiled with the -Os on gcc. They reduce prologue/epilogue 1419 // size by deferring preservation of callee-save registers to a shared 1420 // function. These are defined in PPC64 ELFv2 2.3.3 (but also present 1421 // in ELFv1) 1422 // 1423 // These appear unused, but the linker will redirect calls to functions 1424 // like _savegpr0_14 or _restgpr1_14 to runtime.elf_savegpr0 or 1425 // runtime.elf_restgpr1 with an appropriate offset based on the number 1426 // register operations required when linking external objects which 1427 // make these calls. For GPR/FPR saves, the minimum register value is 1428 // 14, for VR it is 20. 1429 // 1430 // These are only used when linking such cgo code internally. Note, R12 1431 // and R0 may be used in different ways than regular ELF compliant 1432 // functions. 1433 TEXT runtime·elf_savegpr0(SB),NOSPLIT|NOFRAME,$0 1434 // R0 holds the LR of the caller's caller, R1 holds save location 1435 MOVD R14, -144(R1) 1436 MOVD R15, -136(R1) 1437 MOVD R16, -128(R1) 1438 MOVD R17, -120(R1) 1439 MOVD R18, -112(R1) 1440 MOVD R19, -104(R1) 1441 MOVD R20, -96(R1) 1442 MOVD R21, -88(R1) 1443 MOVD R22, -80(R1) 1444 MOVD R23, -72(R1) 1445 MOVD R24, -64(R1) 1446 MOVD R25, -56(R1) 1447 MOVD R26, -48(R1) 1448 MOVD R27, -40(R1) 1449 MOVD R28, -32(R1) 1450 MOVD R29, -24(R1) 1451 MOVD g, -16(R1) 1452 MOVD R31, -8(R1) 1453 MOVD R0, 16(R1) 1454 RET 1455 TEXT runtime·elf_restgpr0(SB),NOSPLIT|NOFRAME,$0 1456 // R1 holds save location. This returns to the LR saved on stack (bypassing the caller) 1457 MOVD -144(R1), R14 1458 MOVD -136(R1), R15 1459 MOVD -128(R1), R16 1460 MOVD -120(R1), R17 1461 MOVD -112(R1), R18 1462 MOVD -104(R1), R19 1463 MOVD -96(R1), R20 1464 MOVD -88(R1), R21 1465 MOVD -80(R1), R22 1466 MOVD -72(R1), R23 1467 MOVD -64(R1), R24 1468 MOVD -56(R1), R25 1469 MOVD -48(R1), R26 1470 MOVD -40(R1), R27 1471 MOVD -32(R1), R28 1472 MOVD -24(R1), R29 1473 MOVD -16(R1), g 1474 MOVD -8(R1), R31 1475 MOVD 16(R1), R0 // Load and return to saved LR 1476 MOVD R0, LR 1477 RET 1478 TEXT runtime·elf_savegpr1(SB),NOSPLIT|NOFRAME,$0 1479 // R12 holds the save location 1480 MOVD R14, -144(R12) 1481 MOVD R15, -136(R12) 1482 MOVD R16, -128(R12) 1483 MOVD R17, -120(R12) 1484 MOVD R18, -112(R12) 1485 MOVD R19, -104(R12) 1486 MOVD R20, -96(R12) 1487 MOVD R21, -88(R12) 1488 MOVD R22, -80(R12) 1489 MOVD R23, -72(R12) 1490 MOVD R24, -64(R12) 1491 MOVD R25, -56(R12) 1492 MOVD R26, -48(R12) 1493 MOVD R27, -40(R12) 1494 MOVD R28, -32(R12) 1495 MOVD R29, -24(R12) 1496 MOVD g, -16(R12) 1497 MOVD R31, -8(R12) 1498 RET 1499 TEXT runtime·elf_restgpr1(SB),NOSPLIT|NOFRAME,$0 1500 // R12 holds the save location 1501 MOVD -144(R12), R14 1502 MOVD -136(R12), R15 1503 MOVD -128(R12), R16 1504 MOVD -120(R12), R17 1505 MOVD -112(R12), R18 1506 MOVD -104(R12), R19 1507 MOVD -96(R12), R20 1508 MOVD -88(R12), R21 1509 MOVD -80(R12), R22 1510 MOVD -72(R12), R23 1511 MOVD -64(R12), R24 1512 MOVD -56(R12), R25 1513 MOVD -48(R12), R26 1514 MOVD -40(R12), R27 1515 MOVD -32(R12), R28 1516 MOVD -24(R12), R29 1517 MOVD -16(R12), g 1518 MOVD -8(R12), R31 1519 RET 1520 TEXT runtime·elf_savefpr(SB),NOSPLIT|NOFRAME,$0 1521 // R0 holds the LR of the caller's caller, R1 holds save location 1522 FMOVD F14, -144(R1) 1523 FMOVD F15, -136(R1) 1524 FMOVD F16, -128(R1) 1525 FMOVD F17, -120(R1) 1526 FMOVD F18, -112(R1) 1527 FMOVD F19, -104(R1) 1528 FMOVD F20, -96(R1) 1529 FMOVD F21, -88(R1) 1530 FMOVD F22, -80(R1) 1531 FMOVD F23, -72(R1) 1532 FMOVD F24, -64(R1) 1533 FMOVD F25, -56(R1) 1534 FMOVD F26, -48(R1) 1535 FMOVD F27, -40(R1) 1536 FMOVD F28, -32(R1) 1537 FMOVD F29, -24(R1) 1538 FMOVD F30, -16(R1) 1539 FMOVD F31, -8(R1) 1540 MOVD R0, 16(R1) 1541 RET 1542 TEXT runtime·elf_restfpr(SB),NOSPLIT|NOFRAME,$0 1543 // R1 holds save location. This returns to the LR saved on stack (bypassing the caller) 1544 FMOVD -144(R1), F14 1545 FMOVD -136(R1), F15 1546 FMOVD -128(R1), F16 1547 FMOVD -120(R1), F17 1548 FMOVD -112(R1), F18 1549 FMOVD -104(R1), F19 1550 FMOVD -96(R1), F20 1551 FMOVD -88(R1), F21 1552 FMOVD -80(R1), F22 1553 FMOVD -72(R1), F23 1554 FMOVD -64(R1), F24 1555 FMOVD -56(R1), F25 1556 FMOVD -48(R1), F26 1557 FMOVD -40(R1), F27 1558 FMOVD -32(R1), F28 1559 FMOVD -24(R1), F29 1560 FMOVD -16(R1), F30 1561 FMOVD -8(R1), F31 1562 MOVD 16(R1), R0 // Load and return to saved LR 1563 MOVD R0, LR 1564 RET 1565 TEXT runtime·elf_savevr(SB),NOSPLIT|NOFRAME,$0 1566 // R0 holds the save location, R12 is clobbered 1567 MOVD $-192, R12 1568 STVX V20, (R0+R12) 1569 MOVD $-176, R12 1570 STVX V21, (R0+R12) 1571 MOVD $-160, R12 1572 STVX V22, (R0+R12) 1573 MOVD $-144, R12 1574 STVX V23, (R0+R12) 1575 MOVD $-128, R12 1576 STVX V24, (R0+R12) 1577 MOVD $-112, R12 1578 STVX V25, (R0+R12) 1579 MOVD $-96, R12 1580 STVX V26, (R0+R12) 1581 MOVD $-80, R12 1582 STVX V27, (R0+R12) 1583 MOVD $-64, R12 1584 STVX V28, (R0+R12) 1585 MOVD $-48, R12 1586 STVX V29, (R0+R12) 1587 MOVD $-32, R12 1588 STVX V30, (R0+R12) 1589 MOVD $-16, R12 1590 STVX V31, (R0+R12) 1591 RET 1592 TEXT runtime·elf_restvr(SB),NOSPLIT|NOFRAME,$0 1593 // R0 holds the save location, R12 is clobbered 1594 MOVD $-192, R12 1595 LVX (R0+R12), V20 1596 MOVD $-176, R12 1597 LVX (R0+R12), V21 1598 MOVD $-160, R12 1599 LVX (R0+R12), V22 1600 MOVD $-144, R12 1601 LVX (R0+R12), V23 1602 MOVD $-128, R12 1603 LVX (R0+R12), V24 1604 MOVD $-112, R12 1605 LVX (R0+R12), V25 1606 MOVD $-96, R12 1607 LVX (R0+R12), V26 1608 MOVD $-80, R12 1609 LVX (R0+R12), V27 1610 MOVD $-64, R12 1611 LVX (R0+R12), V28 1612 MOVD $-48, R12 1613 LVX (R0+R12), V29 1614 MOVD $-32, R12 1615 LVX (R0+R12), V30 1616 MOVD $-16, R12 1617 LVX (R0+R12), V31 1618 RET