github.com/tcnksm/go@v0.0.0-20141208075154-439b32936367/src/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 // +build ppc64 ppc64le 6 7 #include "go_asm.h" 8 #include "go_tls.h" 9 #include "funcdata.h" 10 #include "textflag.h" 11 12 TEXT runtime·rt0_go(SB),NOSPLIT,$0 13 // initialize essential registers 14 BL runtime·reginit(SB) 15 16 SUB $24, R1 17 MOVW R3, 8(R1) // argc 18 MOVD R4, 16(R1) // argv 19 20 // create istack out of the given (operating system) stack. 21 // _cgo_init may update stackguard. 22 MOVD $runtime·g0(SB), g 23 MOVD $(-64*1024), R31 24 ADD R31, R1, R3 25 MOVD R3, g_stackguard0(g) 26 MOVD R3, g_stackguard1(g) 27 MOVD R3, (g_stack+stack_lo)(g) 28 MOVD R1, (g_stack+stack_hi)(g) 29 30 // TODO: if there is a _cgo_init, call it. 31 // TODO: add TLS 32 33 // set the per-goroutine and per-mach "registers" 34 MOVD $runtime·m0(SB), R3 35 36 // save m->g0 = g0 37 MOVD g, m_g0(R3) 38 // save m0 to g0->m 39 MOVD R3, g_m(g) 40 41 BL runtime·check(SB) 42 43 // args are already prepared 44 BL runtime·args(SB) 45 BL runtime·osinit(SB) 46 BL runtime·schedinit(SB) 47 48 // create a new goroutine to start program 49 MOVD $runtime·main·f(SB), R3 // entry 50 MOVDU R3, -8(R1) 51 MOVDU R0, -8(R1) 52 MOVDU R0, -8(R1) 53 BL runtime·newproc(SB) 54 ADD $24, R1 55 56 // start this M 57 BL runtime·mstart(SB) 58 59 MOVD R0, 1(R0) 60 RETURN 61 62 DATA runtime·main·f+0(SB)/8,$runtime·main(SB) 63 GLOBL runtime·main·f(SB),RODATA,$8 64 65 TEXT runtime·breakpoint(SB),NOSPLIT,$-8-0 66 MOVD R0, 2(R0) // TODO: TD 67 RETURN 68 69 TEXT runtime·asminit(SB),NOSPLIT,$-8-0 70 RETURN 71 72 TEXT runtime·reginit(SB),NOSPLIT,$-8-0 73 // set R0 to zero, it's expected by the toolchain 74 XOR R0, R0 75 // initialize essential FP registers 76 FMOVD $4503601774854144.0, F27 77 FMOVD $0.5, F29 78 FSUB F29, F29, F28 79 FADD F29, F29, F30 80 FADD F30, F30, F31 81 RETURN 82 83 /* 84 * go-routine 85 */ 86 87 // void gosave(Gobuf*) 88 // save state in Gobuf; setjmp 89 TEXT runtime·gosave(SB), NOSPLIT, $-8-8 90 MOVD buf+0(FP), R3 91 MOVD R1, gobuf_sp(R3) 92 MOVD LR, R31 93 MOVD R31, gobuf_pc(R3) 94 MOVD g, gobuf_g(R3) 95 MOVD R0, gobuf_lr(R3) 96 MOVD R0, gobuf_ret(R3) 97 MOVD R0, gobuf_ctxt(R3) 98 RETURN 99 100 // void gogo(Gobuf*) 101 // restore state from Gobuf; longjmp 102 TEXT runtime·gogo(SB), NOSPLIT, $-8-8 103 MOVD buf+0(FP), R5 104 MOVD gobuf_g(R5), g // make sure g is not nil 105 MOVD 0(g), R4 106 MOVD gobuf_sp(R5), R1 107 MOVD gobuf_lr(R5), R31 108 MOVD R31, LR 109 MOVD gobuf_ret(R5), R3 110 MOVD gobuf_ctxt(R5), R11 111 MOVD R0, gobuf_sp(R5) 112 MOVD R0, gobuf_ret(R5) 113 MOVD R0, gobuf_lr(R5) 114 MOVD R0, gobuf_ctxt(R5) 115 CMP R0, R0 // set condition codes for == test, needed by stack split 116 MOVD gobuf_pc(R5), R31 117 MOVD R31, CTR 118 BR (CTR) 119 120 // void mcall(fn func(*g)) 121 // Switch to m->g0's stack, call fn(g). 122 // Fn must never return. It should gogo(&g->sched) 123 // to keep running g. 124 TEXT runtime·mcall(SB), NOSPLIT, $-8-8 125 // Save caller state in g->sched 126 MOVD R1, (g_sched+gobuf_sp)(g) 127 MOVD LR, R31 128 MOVD R31, (g_sched+gobuf_pc)(g) 129 MOVD R0, (g_sched+gobuf_lr)(g) 130 MOVD g, (g_sched+gobuf_g)(g) 131 132 // Switch to m->g0 & its stack, call fn. 133 MOVD g, R3 134 MOVD g_m(g), R8 135 MOVD m_g0(R8), g 136 CMP g, R3 137 BNE 2(PC) 138 BR runtime·badmcall(SB) 139 MOVD fn+0(FP), R11 // context 140 MOVD 0(R11), R4 // code pointer 141 MOVD R4, CTR 142 MOVD (g_sched+gobuf_sp)(g), R1 // sp = m->g0->sched.sp 143 MOVDU R3, -8(R1) 144 MOVDU R0, -8(R1) 145 BL (CTR) 146 BR runtime·badmcall2(SB) 147 148 // systemstack_switch is a dummy routine that systemstack leaves at the bottom 149 // of the G stack. We need to distinguish the routine that 150 // lives at the bottom of the G stack from the one that lives 151 // at the top of the system stack because the one at the top of 152 // the system stack terminates the stack walk (see topofstack()). 153 TEXT runtime·systemstack_switch(SB), NOSPLIT, $0-0 154 UNDEF 155 BL (LR) // make sure this function is not leaf 156 RETURN 157 158 // func systemstack(fn func()) 159 TEXT runtime·systemstack(SB), NOSPLIT, $0-8 160 MOVD fn+0(FP), R3 // R3 = fn 161 MOVD R3, R11 // context 162 MOVD g_m(g), R4 // R4 = m 163 164 MOVD m_gsignal(R4), R5 // R5 = gsignal 165 CMP g, R5 166 BEQ noswitch 167 168 MOVD m_g0(R4), R5 // R5 = g0 169 CMP g, R5 170 BEQ noswitch 171 172 MOVD m_curg(R4), R6 173 CMP g, R6 174 BEQ switch 175 176 // Bad: g is not gsignal, not g0, not curg. What is it? 177 // Hide call from linker nosplit analysis. 178 MOVD $runtime·badsystemstack(SB), R3 179 MOVD R3, CTR 180 BL (CTR) 181 182 switch: 183 // save our state in g->sched. Pretend to 184 // be systemstack_switch if the G stack is scanned. 185 MOVD $runtime·systemstack_switch(SB), R6 186 ADD $8, R6 // get past prologue 187 MOVD R6, (g_sched+gobuf_pc)(g) 188 MOVD R1, (g_sched+gobuf_sp)(g) 189 MOVD R0, (g_sched+gobuf_lr)(g) 190 MOVD g, (g_sched+gobuf_g)(g) 191 192 // switch to g0 193 MOVD R5, g 194 MOVD (g_sched+gobuf_sp)(g), R3 195 // make it look like mstart called systemstack on g0, to stop traceback 196 SUB $8, R3 197 MOVD $runtime·mstart(SB), R4 198 MOVD R4, 0(R3) 199 MOVD R3, R1 200 201 // call target function 202 MOVD 0(R11), R3 // code pointer 203 MOVD R3, CTR 204 BL (CTR) 205 206 // switch back to g 207 MOVD g_m(g), R3 208 MOVD m_curg(R3), g 209 MOVD (g_sched+gobuf_sp)(g), R1 210 MOVD R0, (g_sched+gobuf_sp)(g) 211 RETURN 212 213 noswitch: 214 // already on m stack, just call directly 215 MOVD 0(R11), R3 // code pointer 216 MOVD R3, CTR 217 BL (CTR) 218 RETURN 219 220 /* 221 * support for morestack 222 */ 223 224 // Called during function prolog when more stack is needed. 225 // Caller has already loaded: 226 // R3: framesize, R4: argsize, R5: LR 227 // 228 // The traceback routines see morestack on a g0 as being 229 // the top of a stack (for example, morestack calling newstack 230 // calling the scheduler calling newm calling gc), so we must 231 // record an argument size. For that purpose, it has no arguments. 232 TEXT runtime·morestack(SB),NOSPLIT,$-8-0 233 // Cannot grow scheduler stack (m->g0). 234 MOVD g_m(g), R7 235 MOVD m_g0(R7), R8 236 CMP g, R8 237 BNE 2(PC) 238 BL runtime·abort(SB) 239 240 // Cannot grow signal stack (m->gsignal). 241 MOVD m_gsignal(R7), R8 242 CMP g, R8 243 BNE 2(PC) 244 BL runtime·abort(SB) 245 246 // Called from f. 247 // Set g->sched to context in f. 248 MOVD R11, (g_sched+gobuf_ctxt)(g) 249 MOVD R1, (g_sched+gobuf_sp)(g) 250 MOVD LR, R8 251 MOVD R8, (g_sched+gobuf_pc)(g) 252 MOVD R5, (g_sched+gobuf_lr)(g) 253 254 // Called from f. 255 // Set m->morebuf to f's caller. 256 MOVD R5, (m_morebuf+gobuf_pc)(R7) // f's caller's PC 257 MOVD R1, (m_morebuf+gobuf_sp)(R7) // f's caller's SP 258 MOVD g, (m_morebuf+gobuf_g)(R7) 259 260 // Call newstack on m->g0's stack. 261 MOVD m_g0(R7), g 262 MOVD (g_sched+gobuf_sp)(g), R1 263 BL runtime·newstack(SB) 264 265 // Not reached, but make sure the return PC from the call to newstack 266 // is still in this function, and not the beginning of the next. 267 UNDEF 268 269 TEXT runtime·morestack_noctxt(SB),NOSPLIT,$-8-0 270 MOVD R0, R11 271 BR runtime·morestack(SB) 272 273 // reflectcall: call a function with the given argument list 274 // func call(f *FuncVal, arg *byte, argsize, retoffset uint32). 275 // we don't have variable-sized frames, so we use a small number 276 // of constant-sized-frame functions to encode a few bits of size in the pc. 277 // Caution: ugly multiline assembly macros in your future! 278 279 #define DISPATCH(NAME,MAXSIZE) \ 280 MOVD $MAXSIZE, R31; \ 281 CMP R3, R31; \ 282 BGT 4(PC); \ 283 MOVD $NAME(SB), R31; \ 284 MOVD R31, CTR; \ 285 BR (CTR) 286 // Note: can't just "BR NAME(SB)" - bad inlining results. 287 288 TEXT ·reflectcall(SB), NOSPLIT, $-8-24 289 MOVWZ n+16(FP), R3 290 DISPATCH(runtime·call16, 16) 291 DISPATCH(runtime·call32, 32) 292 DISPATCH(runtime·call64, 64) 293 DISPATCH(runtime·call128, 128) 294 DISPATCH(runtime·call256, 256) 295 DISPATCH(runtime·call512, 512) 296 DISPATCH(runtime·call1024, 1024) 297 DISPATCH(runtime·call2048, 2048) 298 DISPATCH(runtime·call4096, 4096) 299 DISPATCH(runtime·call8192, 8192) 300 DISPATCH(runtime·call16384, 16384) 301 DISPATCH(runtime·call32768, 32768) 302 DISPATCH(runtime·call65536, 65536) 303 DISPATCH(runtime·call131072, 131072) 304 DISPATCH(runtime·call262144, 262144) 305 DISPATCH(runtime·call524288, 524288) 306 DISPATCH(runtime·call1048576, 1048576) 307 DISPATCH(runtime·call2097152, 2097152) 308 DISPATCH(runtime·call4194304, 4194304) 309 DISPATCH(runtime·call8388608, 8388608) 310 DISPATCH(runtime·call16777216, 16777216) 311 DISPATCH(runtime·call33554432, 33554432) 312 DISPATCH(runtime·call67108864, 67108864) 313 DISPATCH(runtime·call134217728, 134217728) 314 DISPATCH(runtime·call268435456, 268435456) 315 DISPATCH(runtime·call536870912, 536870912) 316 DISPATCH(runtime·call1073741824, 1073741824) 317 MOVD $runtime·badreflectcall(SB), R31 318 MOVD R31, CTR 319 BR (CTR) 320 321 #define CALLFN(NAME,MAXSIZE) \ 322 TEXT NAME(SB), WRAPPER, $MAXSIZE-24; \ 323 NO_LOCAL_POINTERS; \ 324 /* copy arguments to stack */ \ 325 MOVD arg+8(FP), R3; \ 326 MOVWZ n+16(FP), R4; \ 327 MOVD R1, R5; \ 328 ADD $(8-1), R5; \ 329 SUB $1, R3; \ 330 ADD R5, R4; \ 331 CMP R5, R4; \ 332 BEQ 4(PC); \ 333 MOVBZU 1(R3), R6; \ 334 MOVBZU R6, 1(R5); \ 335 BR -4(PC); \ 336 /* call function */ \ 337 MOVD f+0(FP), R11; \ 338 MOVD (R11), R31; \ 339 MOVD R31, CTR; \ 340 PCDATA $PCDATA_StackMapIndex, $0; \ 341 BL (CTR); \ 342 /* copy return values back */ \ 343 MOVD arg+8(FP), R3; \ 344 MOVWZ n+16(FP), R4; \ 345 MOVWZ retoffset+20(FP), R6; \ 346 MOVD R1, R5; \ 347 ADD R6, R5; \ 348 ADD R6, R3; \ 349 SUB R6, R4; \ 350 ADD $(8-1), R5; \ 351 SUB $1, R3; \ 352 ADD R5, R4; \ 353 CMP R5, R4; \ 354 BEQ 4(PC); \ 355 MOVBZU 1(R5), R6; \ 356 MOVBZU R6, 1(R3); \ 357 BR -4(PC); \ 358 RETURN 359 360 CALLFN(·call16, 16) 361 CALLFN(·call32, 32) 362 CALLFN(·call64, 64) 363 CALLFN(·call128, 128) 364 CALLFN(·call256, 256) 365 CALLFN(·call512, 512) 366 CALLFN(·call1024, 1024) 367 CALLFN(·call2048, 2048) 368 CALLFN(·call4096, 4096) 369 CALLFN(·call8192, 8192) 370 CALLFN(·call16384, 16384) 371 CALLFN(·call32768, 32768) 372 CALLFN(·call65536, 65536) 373 CALLFN(·call131072, 131072) 374 CALLFN(·call262144, 262144) 375 CALLFN(·call524288, 524288) 376 CALLFN(·call1048576, 1048576) 377 CALLFN(·call2097152, 2097152) 378 CALLFN(·call4194304, 4194304) 379 CALLFN(·call8388608, 8388608) 380 CALLFN(·call16777216, 16777216) 381 CALLFN(·call33554432, 33554432) 382 CALLFN(·call67108864, 67108864) 383 CALLFN(·call134217728, 134217728) 384 CALLFN(·call268435456, 268435456) 385 CALLFN(·call536870912, 536870912) 386 CALLFN(·call1073741824, 1073741824) 387 388 // bool cas(uint32 *ptr, uint32 old, uint32 new) 389 // Atomically: 390 // if(*val == old){ 391 // *val = new; 392 // return 1; 393 // } else 394 // return 0; 395 TEXT runtime·cas(SB), NOSPLIT, $0-17 396 MOVD ptr+0(FP), R3 397 MOVWZ old+8(FP), R4 398 MOVWZ new+12(FP), R5 399 cas_again: 400 SYNC 401 LWAR (R3), R6 402 CMPW R6, R4 403 BNE cas_fail 404 STWCCC R5, (R3) 405 BNE cas_again 406 MOVD $1, R3 407 SYNC 408 ISYNC 409 MOVB R3, ret+16(FP) 410 RETURN 411 cas_fail: 412 MOVD $0, R3 413 BR -5(PC) 414 415 // bool runtime·cas64(uint64 *ptr, uint64 old, uint64 new) 416 // Atomically: 417 // if(*val == *old){ 418 // *val = new; 419 // return 1; 420 // } else { 421 // return 0; 422 // } 423 TEXT runtime·cas64(SB), NOSPLIT, $0-25 424 MOVD ptr+0(FP), R3 425 MOVD old+8(FP), R4 426 MOVD new+16(FP), R5 427 cas64_again: 428 SYNC 429 LDAR (R3), R6 430 CMP R6, R4 431 BNE cas64_fail 432 STDCCC R5, (R3) 433 BNE cas64_again 434 MOVD $1, R3 435 SYNC 436 ISYNC 437 MOVB R3, ret+24(FP) 438 RETURN 439 cas64_fail: 440 MOVD $0, R3 441 BR -5(PC) 442 443 TEXT runtime·casuintptr(SB), NOSPLIT, $0-25 444 BR runtime·cas64(SB) 445 446 TEXT runtime·atomicloaduintptr(SB), NOSPLIT, $-8-16 447 BR runtime·atomicload64(SB) 448 449 TEXT runtime·atomicloaduint(SB), NOSPLIT, $-8-16 450 BR runtime·atomicload64(SB) 451 452 TEXT runtime·atomicstoreuintptr(SB), NOSPLIT, $0-16 453 BR runtime·atomicstore64(SB) 454 455 // bool casp(void **val, void *old, void *new) 456 // Atomically: 457 // if(*val == old){ 458 // *val = new; 459 // return 1; 460 // } else 461 // return 0; 462 TEXT runtime·casp1(SB), NOSPLIT, $0-25 463 BR runtime·cas64(SB) 464 465 // uint32 xadd(uint32 volatile *ptr, int32 delta) 466 // Atomically: 467 // *val += delta; 468 // return *val; 469 TEXT runtime·xadd(SB), NOSPLIT, $0-20 470 MOVD ptr+0(FP), R4 471 MOVW delta+8(FP), R5 472 SYNC 473 LWAR (R4), R3 474 ADD R5, R3 475 STWCCC R3, (R4) 476 BNE -4(PC) 477 SYNC 478 ISYNC 479 MOVW R3, ret+16(FP) 480 RETURN 481 482 TEXT runtime·xadd64(SB), NOSPLIT, $0-24 483 MOVD ptr+0(FP), R4 484 MOVD delta+8(FP), R5 485 SYNC 486 LDAR (R4), R3 487 ADD R5, R3 488 STDCCC R3, (R4) 489 BNE -4(PC) 490 SYNC 491 ISYNC 492 MOVD R3, ret+16(FP) 493 RETURN 494 495 TEXT runtime·xchg(SB), NOSPLIT, $0-20 496 MOVD ptr+0(FP), R4 497 MOVW new+8(FP), R5 498 SYNC 499 LWAR (R4), R3 500 STWCCC R5, (R4) 501 BNE -3(PC) 502 SYNC 503 ISYNC 504 MOVW R3, ret+16(FP) 505 RETURN 506 507 TEXT runtime·xchg64(SB), NOSPLIT, $0-24 508 MOVD ptr+0(FP), R4 509 MOVD new+8(FP), R5 510 SYNC 511 LDAR (R4), R3 512 STDCCC R5, (R4) 513 BNE -3(PC) 514 SYNC 515 ISYNC 516 MOVD R3, ret+16(FP) 517 RETURN 518 519 TEXT runtime·xchgp1(SB), NOSPLIT, $0-24 520 BR runtime·xchg64(SB) 521 522 TEXT runtime·xchguintptr(SB), NOSPLIT, $0-24 523 BR runtime·xchg64(SB) 524 525 TEXT runtime·procyield(SB),NOSPLIT,$0-0 526 RETURN 527 528 TEXT runtime·atomicstorep1(SB), NOSPLIT, $0-16 529 BR runtime·atomicstore64(SB) 530 531 TEXT runtime·atomicstore(SB), NOSPLIT, $0-12 532 MOVD ptr+0(FP), R3 533 MOVW val+8(FP), R4 534 SYNC 535 MOVW R4, 0(R3) 536 RETURN 537 538 TEXT runtime·atomicstore64(SB), NOSPLIT, $0-16 539 MOVD ptr+0(FP), R3 540 MOVD val+8(FP), R4 541 SYNC 542 MOVD R4, 0(R3) 543 RETURN 544 545 // void runtime·atomicor8(byte volatile*, byte); 546 TEXT runtime·atomicor8(SB), NOSPLIT, $0-9 547 MOVD ptr+0(FP), R3 548 MOVBZ val+8(FP), R4 549 // Align ptr down to 4 bytes so we can use 32-bit load/store. 550 // R5 = (R3 << 0) & ~3 551 RLDCR $0, R3, $~3, R5 552 // Compute val shift. 553 #ifdef GOARCH_ppc64 554 // Big endian. ptr = ptr ^ 3 555 XOR $3, R3 556 #endif 557 // R6 = ((ptr & 3) * 8) = (ptr << 3) & (3*8) 558 RLDC $3, R3, $(3*8), R6 559 // Shift val for aligned ptr. R4 = val << R6 560 SLD R6, R4, R4 561 562 atomicor8_again: 563 SYNC 564 LWAR (R5), R6 565 OR R4, R6 566 STWCCC R6, (R5) 567 BNE atomicor8_again 568 SYNC 569 ISYNC 570 RETURN 571 572 // void jmpdefer(fv, sp); 573 // called from deferreturn. 574 // 1. grab stored LR for caller 575 // 2. sub 4 bytes to get back to BL deferreturn 576 // 3. BR to fn 577 TEXT runtime·jmpdefer(SB), NOSPLIT, $-8-16 578 MOVD 0(R1), R31 579 SUB $4, R31 580 MOVD R31, LR 581 582 MOVD fv+0(FP), R11 583 MOVD argp+8(FP), R1 584 SUB $8, R1 585 MOVD 0(R11), R3 586 MOVD R3, CTR 587 BR (CTR) 588 589 // Save state of caller into g->sched. Smashes R31. 590 TEXT gosave<>(SB),NOSPLIT,$-8 591 MOVD LR, R31 592 MOVD R31, (g_sched+gobuf_pc)(g) 593 MOVD R1, (g_sched+gobuf_sp)(g) 594 MOVD R0, (g_sched+gobuf_lr)(g) 595 MOVD R0, (g_sched+gobuf_ret)(g) 596 MOVD R0, (g_sched+gobuf_ctxt)(g) 597 RETURN 598 599 // asmcgocall(void(*fn)(void*), void *arg) 600 // Call fn(arg) on the scheduler stack, 601 // aligned appropriately for the gcc ABI. 602 // See cgocall.c for more details. 603 TEXT ·asmcgocall(SB),NOSPLIT,$0-16 604 MOVD R0, 21(R0) 605 606 // cgocallback(void (*fn)(void*), void *frame, uintptr framesize) 607 // Turn the fn into a Go func (by taking its address) and call 608 // cgocallback_gofunc. 609 TEXT runtime·cgocallback(SB),NOSPLIT,$24-24 610 MOVD R0, 22(R0) 611 612 // cgocallback_gofunc(FuncVal*, void *frame, uintptr framesize) 613 // See cgocall.c for more details. 614 TEXT ·cgocallback_gofunc(SB),NOSPLIT,$8-24 615 MOVD R0, 23(R0) 616 617 // void setg(G*); set g. for use by needm. 618 TEXT runtime·setg(SB), NOSPLIT, $0-8 619 MOVD R0, 24(R0) 620 621 // void setg_gcc(G*); set g called from gcc. 622 TEXT setg_gcc<>(SB),NOSPLIT,$0 623 MOVD R0, 25(R0) 624 625 TEXT runtime·getcallerpc(SB),NOSPLIT,$-8-16 626 MOVD 0(R1), R3 627 MOVD R3, ret+8(FP) 628 RETURN 629 630 TEXT runtime·gogetcallerpc(SB),NOSPLIT,$-8-16 631 MOVD 0(R1), R3 632 MOVD R3,ret+8(FP) 633 RETURN 634 635 TEXT runtime·setcallerpc(SB),NOSPLIT,$-8-16 636 MOVD pc+8(FP), R3 637 MOVD R3, 0(R1) // set calling pc 638 RETURN 639 640 TEXT runtime·getcallersp(SB),NOSPLIT,$0-16 641 MOVD argp+0(FP), R3 642 SUB $8, R3 643 MOVD R3, ret+8(FP) 644 RETURN 645 646 // func gogetcallersp(p unsafe.Pointer) uintptr 647 TEXT runtime·gogetcallersp(SB),NOSPLIT,$0-16 648 MOVD sp+0(FP), R3 649 SUB $8, R3 650 MOVD R3,ret+8(FP) 651 RETURN 652 653 TEXT runtime·abort(SB),NOSPLIT,$-8-0 654 MOVW (R0), R0 655 UNDEF 656 657 #define TBRL 268 658 #define TBRU 269 /* Time base Upper/Lower */ 659 660 // int64 runtime·cputicks(void) 661 TEXT runtime·cputicks(SB),NOSPLIT,$0-8 662 MOVW SPR(TBRU), R4 663 MOVW SPR(TBRL), R3 664 MOVW SPR(TBRU), R5 665 CMPW R4, R5 666 BNE -4(PC) 667 SLD $32, R5 668 OR R5, R3 669 MOVD R3, ret+0(FP) 670 RETURN 671 672 // AES hashing not implemented for ppc64 673 TEXT runtime·aeshash(SB),NOSPLIT,$-8-0 674 MOVW (R0), R1 675 TEXT runtime·aeshash32(SB),NOSPLIT,$-8-0 676 MOVW (R0), R1 677 TEXT runtime·aeshash64(SB),NOSPLIT,$-8-0 678 MOVW (R0), R1 679 TEXT runtime·aeshashstr(SB),NOSPLIT,$-8-0 680 MOVW (R0), R1 681 682 TEXT runtime·memeq(SB),NOSPLIT,$-8-25 683 MOVD a+0(FP), R3 684 MOVD b+8(FP), R4 685 MOVD size+16(FP), R5 686 SUB $1, R3 687 SUB $1, R4 688 ADD R3, R5, R8 689 loop: 690 CMP R3, R8 691 BNE test 692 MOVD $1, R3 693 MOVB R3, ret+24(FP) 694 RETURN 695 test: 696 MOVBZU 1(R3), R6 697 MOVBZU 1(R4), R7 698 CMP R6, R7 699 BEQ loop 700 701 MOVB R0, ret+24(FP) 702 RETURN 703 704 // eqstring tests whether two strings are equal. 705 // See runtime_test.go:eqstring_generic for 706 // equivalent Go code. 707 TEXT runtime·eqstring(SB),NOSPLIT,$0-33 708 MOVD s1len+8(FP), R4 709 MOVD s2len+24(FP), R5 710 CMP R4, R5 711 BNE noteq 712 713 MOVD s1str+0(FP), R3 714 MOVD s2str+16(FP), R4 715 SUB $1, R3 716 SUB $1, R4 717 ADD R3, R5, R8 718 loop: 719 CMP R3, R8 720 BNE 4(PC) 721 MOVD $1, R3 722 MOVB R3, ret+32(FP) 723 RETURN 724 MOVBZU 1(R3), R6 725 MOVBZU 1(R4), R7 726 CMP R6, R7 727 BEQ loop 728 noteq: 729 MOVB R0, ret+32(FP) 730 RETURN 731 732 // TODO: share code with memeq? 733 TEXT bytes·Equal(SB),NOSPLIT,$0-49 734 MOVD a_len+8(FP), R3 735 MOVD b_len+32(FP), R4 736 737 CMP R3, R4 // unequal lengths are not equal 738 BNE noteq 739 740 MOVD a+0(FP), R5 741 MOVD b+24(FP), R6 742 SUB $1, R5 743 SUB $1, R6 744 ADD R5, R3 // end-1 745 746 loop: 747 CMP R5, R3 748 BEQ equal // reached the end 749 MOVBZU 1(R5), R4 750 MOVBZU 1(R6), R7 751 CMP R4, R7 752 BEQ loop 753 754 noteq: 755 MOVBZ R0, ret+48(FP) 756 RETURN 757 758 equal: 759 MOVD $1, R3 760 MOVBZ R3, ret+48(FP) 761 RETURN 762 763 TEXT bytes·IndexByte(SB),NOSPLIT,$0-40 764 MOVD s+0(FP), R3 765 MOVD s_len+8(FP), R4 766 MOVBZ c+24(FP), R5 // byte to find 767 MOVD R3, R6 // store base for later 768 SUB $1, R3 769 ADD R3, R4 // end-1 770 771 loop: 772 CMP R3, R4 773 BEQ notfound 774 MOVBZU 1(R3), R7 775 CMP R7, R5 776 BNE loop 777 778 SUB R6, R3 // remove base 779 MOVD R3, ret+32(FP) 780 RETURN 781 782 notfound: 783 MOVD $-1, R3 784 MOVD R3, ret+32(FP) 785 RETURN 786 787 TEXT strings·IndexByte(SB),NOSPLIT,$0 788 MOVD p+0(FP), R3 789 MOVD b_len+8(FP), R4 790 MOVBZ c+16(FP), R5 // byte to find 791 MOVD R3, R6 // store base for later 792 SUB $1, R3 793 ADD R3, R4 // end-1 794 795 loop: 796 CMP R3, R4 797 BEQ notfound 798 MOVBZU 1(R3), R7 799 CMP R7, R5 800 BNE loop 801 802 SUB R6, R3 // remove base 803 MOVD R3, ret+24(FP) 804 RETURN 805 806 notfound: 807 MOVD $-1, R3 808 MOVD R3, ret+24(FP) 809 RETURN 810 811 812 // A Duff's device for zeroing memory. 813 // The compiler jumps to computed addresses within 814 // this routine to zero chunks of memory. Do not 815 // change this code without also changing the code 816 // in ../../cmd/9g/ggen.c:/^clearfat. 817 // R0: always zero 818 // R3 (aka REGRT1): ptr to memory to be zeroed - 8 819 // On return, R3 points to the last zeroed dword. 820 TEXT runtime·duffzero(SB), NOSPLIT, $-8-0 821 MOVDU R0, 8(R3) 822 MOVDU R0, 8(R3) 823 MOVDU R0, 8(R3) 824 MOVDU R0, 8(R3) 825 MOVDU R0, 8(R3) 826 MOVDU R0, 8(R3) 827 MOVDU R0, 8(R3) 828 MOVDU R0, 8(R3) 829 MOVDU R0, 8(R3) 830 MOVDU R0, 8(R3) 831 MOVDU R0, 8(R3) 832 MOVDU R0, 8(R3) 833 MOVDU R0, 8(R3) 834 MOVDU R0, 8(R3) 835 MOVDU R0, 8(R3) 836 MOVDU R0, 8(R3) 837 MOVDU R0, 8(R3) 838 MOVDU R0, 8(R3) 839 MOVDU R0, 8(R3) 840 MOVDU R0, 8(R3) 841 MOVDU R0, 8(R3) 842 MOVDU R0, 8(R3) 843 MOVDU R0, 8(R3) 844 MOVDU R0, 8(R3) 845 MOVDU R0, 8(R3) 846 MOVDU R0, 8(R3) 847 MOVDU R0, 8(R3) 848 MOVDU R0, 8(R3) 849 MOVDU R0, 8(R3) 850 MOVDU R0, 8(R3) 851 MOVDU R0, 8(R3) 852 MOVDU R0, 8(R3) 853 MOVDU R0, 8(R3) 854 MOVDU R0, 8(R3) 855 MOVDU R0, 8(R3) 856 MOVDU R0, 8(R3) 857 MOVDU R0, 8(R3) 858 MOVDU R0, 8(R3) 859 MOVDU R0, 8(R3) 860 MOVDU R0, 8(R3) 861 MOVDU R0, 8(R3) 862 MOVDU R0, 8(R3) 863 MOVDU R0, 8(R3) 864 MOVDU R0, 8(R3) 865 MOVDU R0, 8(R3) 866 MOVDU R0, 8(R3) 867 MOVDU R0, 8(R3) 868 MOVDU R0, 8(R3) 869 MOVDU R0, 8(R3) 870 MOVDU R0, 8(R3) 871 MOVDU R0, 8(R3) 872 MOVDU R0, 8(R3) 873 MOVDU R0, 8(R3) 874 MOVDU R0, 8(R3) 875 MOVDU R0, 8(R3) 876 MOVDU R0, 8(R3) 877 MOVDU R0, 8(R3) 878 MOVDU R0, 8(R3) 879 MOVDU R0, 8(R3) 880 MOVDU R0, 8(R3) 881 MOVDU R0, 8(R3) 882 MOVDU R0, 8(R3) 883 MOVDU R0, 8(R3) 884 MOVDU R0, 8(R3) 885 MOVDU R0, 8(R3) 886 MOVDU R0, 8(R3) 887 MOVDU R0, 8(R3) 888 MOVDU R0, 8(R3) 889 MOVDU R0, 8(R3) 890 MOVDU R0, 8(R3) 891 MOVDU R0, 8(R3) 892 MOVDU R0, 8(R3) 893 MOVDU R0, 8(R3) 894 MOVDU R0, 8(R3) 895 MOVDU R0, 8(R3) 896 MOVDU R0, 8(R3) 897 MOVDU R0, 8(R3) 898 MOVDU R0, 8(R3) 899 MOVDU R0, 8(R3) 900 MOVDU R0, 8(R3) 901 MOVDU R0, 8(R3) 902 MOVDU R0, 8(R3) 903 MOVDU R0, 8(R3) 904 MOVDU R0, 8(R3) 905 MOVDU R0, 8(R3) 906 MOVDU R0, 8(R3) 907 MOVDU R0, 8(R3) 908 MOVDU R0, 8(R3) 909 MOVDU R0, 8(R3) 910 MOVDU R0, 8(R3) 911 MOVDU R0, 8(R3) 912 MOVDU R0, 8(R3) 913 MOVDU R0, 8(R3) 914 MOVDU R0, 8(R3) 915 MOVDU R0, 8(R3) 916 MOVDU R0, 8(R3) 917 MOVDU R0, 8(R3) 918 MOVDU R0, 8(R3) 919 MOVDU R0, 8(R3) 920 MOVDU R0, 8(R3) 921 MOVDU R0, 8(R3) 922 MOVDU R0, 8(R3) 923 MOVDU R0, 8(R3) 924 MOVDU R0, 8(R3) 925 MOVDU R0, 8(R3) 926 MOVDU R0, 8(R3) 927 MOVDU R0, 8(R3) 928 MOVDU R0, 8(R3) 929 MOVDU R0, 8(R3) 930 MOVDU R0, 8(R3) 931 MOVDU R0, 8(R3) 932 MOVDU R0, 8(R3) 933 MOVDU R0, 8(R3) 934 MOVDU R0, 8(R3) 935 MOVDU R0, 8(R3) 936 MOVDU R0, 8(R3) 937 MOVDU R0, 8(R3) 938 MOVDU R0, 8(R3) 939 MOVDU R0, 8(R3) 940 MOVDU R0, 8(R3) 941 MOVDU R0, 8(R3) 942 MOVDU R0, 8(R3) 943 MOVDU R0, 8(R3) 944 MOVDU R0, 8(R3) 945 MOVDU R0, 8(R3) 946 MOVDU R0, 8(R3) 947 MOVDU R0, 8(R3) 948 MOVDU R0, 8(R3) 949 RETURN 950 951 TEXT runtime·fastrand1(SB), NOSPLIT, $0-4 952 MOVD g_m(g), R4 953 MOVWZ m_fastrand(R4), R3 954 ADD R3, R3 955 CMPW R3, $0 956 BGE 2(PC) 957 XOR $0x88888eef, R3 958 MOVW R3, m_fastrand(R4) 959 MOVW R3, ret+0(FP) 960 RETURN 961 962 TEXT runtime·return0(SB), NOSPLIT, $0 963 MOVW $0, R3 964 RETURN 965 966 // Called from cgo wrappers, this function returns g->m->curg.stack.hi. 967 // Must obey the gcc calling convention. 968 TEXT _cgo_topofstack(SB),NOSPLIT,$0 969 MOVD R0, 26(R0) 970 971 // The top-most function running on a goroutine 972 // returns to goexit+PCQuantum. 973 TEXT runtime·goexit(SB),NOSPLIT,$-8-0 974 MOVD R0, R0 // NOP 975 BL runtime·goexit1(SB) // does not return 976 977 TEXT runtime·getg(SB),NOSPLIT,$-8-8 978 MOVD g, ret+0(FP) 979 RETURN 980 981 TEXT runtime·prefetcht0(SB),NOSPLIT,$0-8 982 RETURN 983 984 TEXT runtime·prefetcht1(SB),NOSPLIT,$0-8 985 RETURN 986 987 TEXT runtime·prefetcht2(SB),NOSPLIT,$0-8 988 RETURN 989 990 TEXT runtime·prefetchnta(SB),NOSPLIT,$0-8 991 RETURN