github.com/riscv/riscv-go@v0.0.0-20200123204226-124ebd6fcc8e/src/runtime/asm_riscv.s (about) 1 // Copyright 2017 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 riscv 6 7 #include "go_asm.h" 8 #include "funcdata.h" 9 #include "textflag.h" 10 11 // func rt0_go() 12 TEXT runtime·rt0_go(SB),NOSPLIT,$0 13 // X2 = stack; A0 = argc; A1 = argv 14 15 ADD $-24, X2 16 MOV A0, 8(X2) // argc 17 MOV A1, 16(X2) // argv 18 19 // create istack out of the given (operating system) stack. 20 // _cgo_init may update stackguard. 21 MOV $runtime·g0(SB), g 22 MOV $(-64*1024), T0 23 ADD T0, X2, T1 24 MOV T1, g_stackguard0(g) 25 MOV T1, g_stackguard1(g) 26 MOV T1, (g_stack+stack_lo)(g) 27 MOV X2, (g_stack+stack_hi)(g) 28 29 // if there is a _cgo_init, call it using the gcc ABI. 30 MOV _cgo_init(SB), T0 31 BEQ T0, ZERO, nocgo 32 33 MOV ZERO, A3 // arg 3: not used 34 MOV ZERO, A2 // arg 2: not used 35 MOV $setg_gcc<>(SB), A1 // arg 1: setg 36 MOV g, A0 // arg 0: G 37 JALR RA, T0 38 39 nocgo: 40 // update stackguard after _cgo_init 41 MOV (g_stack+stack_lo)(g), T0 42 ADD $const__StackGuard, T0 43 MOV T0, g_stackguard0(g) 44 MOV T0, g_stackguard1(g) 45 46 // set the per-goroutine and per-mach "registers" 47 MOV $runtime·m0(SB), T0 48 49 // save m->g0 = g0 50 MOV g, m_g0(T0) 51 // save m0 to g0->m 52 MOV T0, g_m(g) 53 54 CALL runtime·check(SB) 55 56 // args are already prepared 57 CALL runtime·args(SB) 58 CALL runtime·osinit(SB) 59 CALL runtime·schedinit(SB) 60 61 // create a new goroutine to start program 62 MOV $runtime·mainPC(SB), T0 // entry 63 ADD $-24, X2 64 MOV T0, 16(X2) 65 MOV ZERO, 8(X2) 66 MOV ZERO, 0(X2) 67 CALL runtime·newproc(SB) 68 ADD $24, X2 69 70 // start this M 71 CALL runtime·mstart(SB) 72 73 WORD $0 // crash if reached 74 RET 75 76 // void setg_gcc(G*); set g called from gcc with g in A0 77 TEXT setg_gcc<>(SB),NOSPLIT,$0-0 78 MOV A0, g 79 CALL runtime·save_g(SB) 80 RET 81 82 // func cputicks() int64 83 TEXT runtime·cputicks(SB),NOSPLIT,$0-8 84 WORD $0xc0102573 // rdtime a0 85 MOV A0, ret+0(FP) 86 RET 87 88 // systemstack_switch is a dummy routine that systemstack leaves at the bottom 89 // of the G stack. We need to distinguish the routine that 90 // lives at the bottom of the G stack from the one that lives 91 // at the top of the system stack because the one at the top of 92 // the system stack terminates the stack walk (see topofstack()). 93 TEXT runtime·systemstack_switch(SB), NOSPLIT, $0-0 94 UNDEF 95 JALR RA, ZERO // make sure this function is not leaf 96 RET 97 98 // func systemstack(fn func()) 99 TEXT runtime·systemstack(SB), NOSPLIT, $0-8 100 MOV fn+0(FP), CTXT // CTXT = fn 101 MOV g_m(g), T0 // T0 = m 102 103 MOV m_gsignal(T0), T1 // T1 = gsignal 104 BEQ g, T1, noswitch 105 106 MOV m_g0(T0), T1 // T1 = g0 107 BEQ g, T1, noswitch 108 109 MOV m_curg(T0), T2 110 BEQ g, T2, switch 111 112 // Bad: g is not gsignal, not g0, not curg. What is it? 113 // Hide call from linker nosplit analysis. 114 MOV $runtime·badsystemstack(SB), T1 115 JALR RA, T1 116 117 switch: 118 // save our state in g->sched. Pretend to 119 // be systemstack_switch if the G stack is scanned. 120 MOV $runtime·systemstack_switch(SB), T2 121 ADD $8, T2 // get past prologue 122 MOV T2, (g_sched+gobuf_pc)(g) 123 MOV X2, (g_sched+gobuf_sp)(g) 124 MOV ZERO, (g_sched+gobuf_lr)(g) 125 MOV g, (g_sched+gobuf_g)(g) 126 127 // switch to g0 128 MOV T1, g 129 CALL runtime·save_g(SB) 130 MOV (g_sched+gobuf_sp)(g), T0 131 // make it look like mstart called systemstack on g0, to stop traceback 132 ADD $-16, T0 133 AND $~15, T0 134 MOV $runtime·mstart(SB), T1 135 MOV T1, 0(T0) 136 MOV T0, X2 137 138 // call target function 139 MOV 0(CTXT), T1 // code pointer 140 JALR RA, T1 141 142 // switch back to g 143 MOV g_m(g), T0 144 MOV m_curg(T0), g 145 CALL runtime·save_g(SB) 146 MOV (g_sched+gobuf_sp)(g), X2 147 MOV ZERO, (g_sched+gobuf_sp)(g) 148 RET 149 150 noswitch: 151 // already on m stack, just call directly 152 MOV 0(CTXT), T1 // code pointer 153 JALR RA, T1 154 RET 155 156 // func getcallerpc(argp unsafe.Pointer) uintptr 157 TEXT runtime·getcallerpc(SB),NOSPLIT,$8-16 158 MOV 16(X2), T0 // LR saved by caller 159 MOV runtime·stackBarrierPC(SB), T1 160 BNE T0, T1, nobar 161 // Get original return PC. 162 CALL runtime·nextBarrierPC(SB) 163 MOV 8(X2), T0 164 nobar: 165 MOV T0, ret+8(FP) 166 RET 167 168 // func fastrand() uint32 169 TEXT runtime·fastrand(SB),NOSPLIT,$0-4 170 MOV g_m(g), A2 171 MOVWU m_fastrand(A2), A1 172 ADD A1, A1 173 // TODO(sorear): Just use ADDW once an encoding is added 174 SLL $32, A1 175 SRA $32, A1 176 BGE A1, ZERO, noxor 177 MOV $0x88888eef - 1<<32, A0 178 XOR A0, A1 179 noxor: 180 MOVW A1, m_fastrand(A2) 181 MOVW A1, ret+0(FP) 182 RET 183 184 // eqstring tests whether two strings are equal. 185 // The compiler guarantees that strings passed 186 // to eqstring have equal length. 187 // See runtime_test.go:eqstring_generic for 188 // equivalent Go code. 189 190 // func eqstring(s1, s2 string) bool 191 TEXT runtime·eqstring(SB),NOSPLIT,$0-33 192 MOV s1_base+0(FP), T0 193 MOV s2_base+16(FP), T1 194 MOV $1, T2 195 MOVB T2, ret+32(FP) 196 BNE T0, T1, diff_len 197 RET 198 diff_len: 199 MOV s1_len+8(FP), T2 200 ADD T0, T2, T3 201 loop: 202 BNE T0, T3, 2(PC) 203 RET 204 MOVBU (T0), T5 205 ADD $1, T0 206 MOVBU (T1), T6 207 ADD $1, T1 208 BEQ T5, T6, loop 209 MOVB ZERO, ret+32(FP) 210 RET 211 212 /* 213 * support for morestack 214 */ 215 216 // Called during function prolog when more stack is needed. 217 // Caller has already loaded: 218 // R1: framesize, R2: argsize, R3: LR 219 // 220 // The traceback routines see morestack on a g0 as being 221 // the top of a stack (for example, morestack calling newstack 222 // calling the scheduler calling newm calling gc), so we must 223 // record an argument size. For that purpose, it has no arguments. 224 225 // func morestack() 226 TEXT runtime·morestack(SB),NOSPLIT,$-8-0 227 // Cannot grow scheduler stack (m->g0). 228 MOV g_m(g), A0 229 MOV m_g0(A0), A1 230 BNE g, A1, 3(PC) 231 CALL runtime·badmorestackg0(SB) 232 CALL runtime·abort(SB) 233 234 // Cannot grow signal stack (m->gsignal). 235 MOV m_gsignal(A0), A1 236 BNE g, A1, 3(PC) 237 CALL runtime·badmorestackgsignal(SB) 238 CALL runtime·abort(SB) 239 240 // Called from f. 241 // Set g->sched to context in f. 242 MOV X2, (g_sched+gobuf_sp)(g) 243 MOV T0, (g_sched+gobuf_pc)(g) 244 MOV RA, (g_sched+gobuf_lr)(g) 245 // newstack will fill gobuf.ctxt. 246 247 // Called from f. 248 // Set m->morebuf to f's caller. 249 MOV RA, (m_morebuf+gobuf_pc)(A0) // f's caller's PC 250 MOV X2, (m_morebuf+gobuf_sp)(A0) // f's caller's SP 251 MOV g, (m_morebuf+gobuf_g)(A0) 252 253 // Call newstack on m->g0's stack. 254 MOV m_g0(A0), g 255 CALL runtime·save_g(SB) 256 MOV (g_sched+gobuf_sp)(g), X2 257 // Create a stack frame on g0 to call newstack. 258 MOV ZERO, -16(X2) // Zero saved LR in frame 259 ADD $-16, X2 260 MOV CTXT, 8(X2) // ctxt argument 261 CALL runtime·newstack(SB) 262 263 // Not reached, but make sure the return PC from the call to newstack 264 // is still in this function, and not the beginning of the next. 265 UNDEF 266 267 // func morestack_noctxt() 268 TEXT runtime·morestack_noctxt(SB),NOSPLIT,$-8-0 269 MOV ZERO, CTXT 270 JMP runtime·morestack(SB) 271 272 // func return0() 273 TEXT runtime·return0(SB), NOSPLIT, $0 274 MOV $0, A0 275 RET 276 277 // func memequal(a, b unsafe.Pointer, size uintptr) bool 278 TEXT runtime·memequal(SB),NOSPLIT,$-8-25 279 MOV a+0(FP), A1 280 MOV b+8(FP), A2 281 BEQ A1, A2, eq 282 MOV size+16(FP), A3 283 ADD A1, A3, A4 284 loop: 285 BNE A1, A4, test 286 MOV $1, A1 287 MOVB A1, ret+24(FP) 288 RET 289 test: 290 MOVBU (A1), A6 291 ADD $1, A1 292 MOVBU (A2), A7 293 ADD $1, A2 294 BEQ A6, A7, loop 295 296 MOVB ZERO, ret+24(FP) 297 RET 298 eq: 299 MOV $1, A1 300 MOVB A1, ret+24(FP) 301 RET 302 303 // func memequal_varlen(a, b unsafe.Pointer) bool 304 TEXT runtime·memequal_varlen(SB),NOSPLIT,$40-17 305 MOV a+0(FP), A1 306 MOV b+8(FP), A2 307 BEQ A1, A2, eq 308 MOV 8(CTXT), A3 // compiler stores size at offset 8 in the closure 309 MOV A1, 8(X2) 310 MOV A2, 16(X2) 311 MOV A3, 24(X2) 312 CALL runtime·memequal(SB) 313 MOVBU 32(X2), A1 314 MOVB A1, ret+16(FP) 315 RET 316 eq: 317 MOV $1, A1 318 MOVB A1, ret+16(FP) 319 RET 320 321 // restore state from Gobuf; longjmp 322 323 // func gogo(buf *gobuf) 324 TEXT runtime·gogo(SB), NOSPLIT, $16-8 325 MOV buf+0(FP), T0 326 327 // If ctxt is not nil, invoke deletion barrier before overwriting. 328 MOV gobuf_ctxt(T0), T1 329 BEQ T1, ZERO, nilctxt 330 ADD $gobuf_ctxt, T0, T1 331 MOV T1, 8(X2) 332 MOV ZERO, 16(X2) 333 CALL runtime·writebarrierptr_prewrite(SB) 334 MOV buf+0(FP), T0 335 336 nilctxt: 337 MOV gobuf_g(T0), g // make sure g is not nil 338 CALL runtime·save_g(SB) 339 340 MOV (g), ZERO // make sure g is not nil 341 MOV gobuf_sp(T0), X2 342 MOV gobuf_lr(T0), RA 343 MOV gobuf_ret(T0), A0 344 MOV gobuf_ctxt(T0), CTXT 345 MOV ZERO, gobuf_sp(T0) 346 MOV ZERO, gobuf_ret(T0) 347 MOV ZERO, gobuf_lr(T0) 348 MOV ZERO, gobuf_ctxt(T0) 349 MOV gobuf_pc(T0), T0 350 JALR ZERO, T0 351 352 // func jmpdefer(fv *funcval, argp uintptr) 353 // called from deferreturn 354 // 1. grab stored return address from the caller's frame 355 // 2. sub 12 bytes to get back to JAL deferreturn 356 // 3. JMP to fn 357 // TODO(sorear): There are shorter jump sequences. This function will need to be updated when we use them. 358 TEXT runtime·jmpdefer(SB), NOSPLIT, $-8-16 359 MOV 0(X2), RA 360 ADD $-12, RA 361 362 MOV fv+0(FP), CTXT 363 MOV argp+8(FP), X2 364 ADD $-8, X2 365 MOV 0(CTXT), T0 366 JALR ZERO, T0 367 368 // func procyield(cycles uint32) 369 TEXT runtime·procyield(SB),NOSPLIT,$0-0 370 RET 371 372 // Switch to m->g0's stack, call fn(g). 373 // Fn must never return. It should gogo(&g->sched) 374 // to keep running g. 375 376 // func mcall(fn func(*g)) 377 TEXT runtime·mcall(SB), NOSPLIT, $-8-8 378 // Save caller state in g->sched 379 MOV X2, (g_sched+gobuf_sp)(g) 380 MOV RA, (g_sched+gobuf_pc)(g) 381 MOV ZERO, (g_sched+gobuf_lr)(g) 382 MOV g, (g_sched+gobuf_g)(g) 383 384 // Switch to m->g0 & its stack, call fn. 385 MOV g, T0 386 MOV g_m(g), T1 387 MOV m_g0(T1), g 388 CALL runtime·save_g(SB) 389 BNE g, T0, 2(PC) 390 JMP runtime·badmcall(SB) 391 MOV fn+0(FP), CTXT // context 392 MOV 0(CTXT), T1 // code pointer 393 MOV (g_sched+gobuf_sp)(g), X2 // sp = m->g0->sched.sp 394 ADD $-16, X2 395 MOV T0, 8(X2) 396 MOV ZERO, 0(X2) 397 JALR RA, T1 398 JMP runtime·badmcall2(SB) 399 400 // func gosave(buf *gobuf) 401 // save state in Gobuf; setjmp 402 TEXT runtime·gosave(SB), NOSPLIT, $-8-8 403 MOV buf+0(FP), T1 404 MOV X2, gobuf_sp(T1) 405 MOV RA, gobuf_pc(T1) 406 MOV g, gobuf_g(T1) 407 MOV ZERO, gobuf_lr(T1) 408 MOV ZERO, gobuf_ret(T1) 409 // Assert ctxt is zero. See func save. 410 MOV gobuf_ctxt(T1), T1 411 BEQ T1, ZERO, 2(PC) 412 CALL runtime·badctxt(SB) 413 RET 414 415 // func asmcgocall(fn, arg unsafe.Pointer) int32 416 TEXT ·asmcgocall(SB),NOSPLIT,$0-12 417 WORD $0 418 419 // redirects to memhash(p, h, size) using the size 420 // stored in the closure. 421 422 // func memhash_varlen(p unsafe.Pointer, h uintptr) uintptr 423 TEXT runtime·memhash_varlen(SB),NOSPLIT,$40-24 424 GO_ARGS 425 NO_LOCAL_POINTERS 426 MOV p+0(FP), A1 427 MOV h+8(FP), A2 428 MOV 8(CTXT), A3 429 MOV A1, 8(X2) 430 MOV A2, 16(X2) 431 MOV A3, 24(X2) 432 CALL runtime·memhash(SB) 433 MOV 32(X2), A1 434 MOV A1, ret+16(FP) 435 RET 436 437 // func asminit() 438 TEXT runtime·asminit(SB),NOSPLIT,$-8-0 439 RET 440 441 // reflectcall: call a function with the given argument list 442 // func call(argtype *_type, f *FuncVal, arg *byte, argsize, retoffset uint32). 443 // we don't have variable-sized frames, so we use a small number 444 // of constant-sized-frame functions to encode a few bits of size in the pc. 445 // Caution: ugly multiline assembly macros in your future! 446 447 #define DISPATCH(NAME,MAXSIZE) \ 448 MOV $MAXSIZE, T1 \ 449 BLTU T1, T0, 3(PC) \ 450 MOV $NAME(SB), T2; \ 451 JALR ZERO, T2 452 // Note: can't just "BR NAME(SB)" - bad inlining results. 453 454 // func call(argtype *rtype, fn, arg unsafe.Pointer, n uint32, retoffset uint32) 455 TEXT reflect·call(SB), NOSPLIT, $0-0 456 JMP ·reflectcall(SB) 457 458 // func reflectcall(argtype *_type, fn, arg unsafe.Pointer, argsize uint32, retoffset uint32) 459 TEXT ·reflectcall(SB), NOSPLIT, $-8-32 460 MOVWU argsize+24(FP), T0 461 DISPATCH(runtime·call32, 32) 462 DISPATCH(runtime·call64, 64) 463 DISPATCH(runtime·call128, 128) 464 DISPATCH(runtime·call256, 256) 465 DISPATCH(runtime·call512, 512) 466 DISPATCH(runtime·call1024, 1024) 467 DISPATCH(runtime·call2048, 2048) 468 DISPATCH(runtime·call4096, 4096) 469 DISPATCH(runtime·call8192, 8192) 470 DISPATCH(runtime·call16384, 16384) 471 DISPATCH(runtime·call32768, 32768) 472 DISPATCH(runtime·call65536, 65536) 473 DISPATCH(runtime·call131072, 131072) 474 DISPATCH(runtime·call262144, 262144) 475 DISPATCH(runtime·call524288, 524288) 476 DISPATCH(runtime·call1048576, 1048576) 477 DISPATCH(runtime·call2097152, 2097152) 478 DISPATCH(runtime·call4194304, 4194304) 479 DISPATCH(runtime·call8388608, 8388608) 480 DISPATCH(runtime·call16777216, 16777216) 481 DISPATCH(runtime·call33554432, 33554432) 482 DISPATCH(runtime·call67108864, 67108864) 483 DISPATCH(runtime·call134217728, 134217728) 484 DISPATCH(runtime·call268435456, 268435456) 485 DISPATCH(runtime·call536870912, 536870912) 486 DISPATCH(runtime·call1073741824, 1073741824) 487 MOV $runtime·badreflectcall(SB), T2 488 JALR ZERO, T2 489 490 #define CALLFN(NAME,MAXSIZE) \ 491 TEXT NAME(SB), WRAPPER, $MAXSIZE-24; \ 492 NO_LOCAL_POINTERS; \ 493 /* copy arguments to stack */ \ 494 MOV arg+16(FP), A1; \ 495 MOVWU argsize+24(FP), A2; \ 496 MOV X2, A3; \ 497 ADD $8, A3; \ 498 ADD A3, A2; \ 499 BEQ A3, A2, 6(PC); \ 500 MOVBU (A1), A4; \ 501 ADD $1, A1; \ 502 MOVB A4, (A3); \ 503 ADD $1, A3; \ 504 JMP -5(PC); \ 505 /* call function */ \ 506 MOV f+8(FP), CTXT; \ 507 MOV (CTXT), A4; \ 508 PCDATA $PCDATA_StackMapIndex, $0; \ 509 JALR RA, A4; \ 510 /* copy return values back */ \ 511 MOV argtype+0(FP), A5; \ 512 MOV arg+16(FP), A1; \ 513 MOVWU n+24(FP), A2; \ 514 MOVWU retoffset+28(FP), A4; \ 515 ADD $8, X2, A3; \ 516 ADD A4, A3; \ 517 ADD A4, A1; \ 518 SUB A4, A2; \ 519 CALL callRet<>(SB); \ 520 RET 521 522 // callRet copies return values back at the end of call*. This is a 523 // separate function so it can allocate stack space for the arguments 524 // to reflectcallmove. It does not follow the Go ABI; it expects its 525 // arguments in registers. 526 TEXT callRet<>(SB), NOSPLIT, $32-0 527 MOV A5, 8(X2) 528 MOV A1, 16(X2) 529 MOV A3, 24(X2) 530 MOV A2, 32(X2) 531 CALL runtime·reflectcallmove(SB) 532 RET 533 534 CALLFN(·call16, 16) 535 CALLFN(·call32, 32) 536 CALLFN(·call64, 64) 537 CALLFN(·call128, 128) 538 CALLFN(·call256, 256) 539 CALLFN(·call512, 512) 540 CALLFN(·call1024, 1024) 541 CALLFN(·call2048, 2048) 542 CALLFN(·call4096, 4096) 543 CALLFN(·call8192, 8192) 544 CALLFN(·call16384, 16384) 545 CALLFN(·call32768, 32768) 546 CALLFN(·call65536, 65536) 547 CALLFN(·call131072, 131072) 548 CALLFN(·call262144, 262144) 549 CALLFN(·call524288, 524288) 550 CALLFN(·call1048576, 1048576) 551 CALLFN(·call2097152, 2097152) 552 CALLFN(·call4194304, 4194304) 553 CALLFN(·call8388608, 8388608) 554 CALLFN(·call16777216, 16777216) 555 CALLFN(·call33554432, 33554432) 556 CALLFN(·call67108864, 67108864) 557 CALLFN(·call134217728, 134217728) 558 CALLFN(·call268435456, 268435456) 559 CALLFN(·call536870912, 536870912) 560 CALLFN(·call1073741824, 1073741824) 561 562 // func goexit(neverCallThisFunction) 563 // The top-most function running on a goroutine 564 // returns to goexit+PCQuantum. 565 TEXT runtime·goexit(SB),NOSPLIT,$-8-0 566 MOV ZERO, ZERO // NOP 567 CALL runtime·goexit1(SB) // does not return 568 // traceback from goexit1 must hit code range of goexit 569 MOV ZERO, ZERO // NOP 570 571 // func setcallerpc(argp unsafe.Pointer, pc uintptr) 572 TEXT runtime·setcallerpc(SB),NOSPLIT,$8-16 573 MOV pc+8(FP), A1 574 MOV 16(X2), A2 575 MOV runtime·stackBarrierPC(SB), A3 576 BEQ A2, A3, setbar 577 MOV A1, 16(X2) // set LR in caller 578 RET 579 setbar: 580 // Set the stack barrier return PC. 581 MOV A1, 8(X2) 582 CALL runtime·setNextBarrierPC(SB) 583 RET 584 585 // func IndexByte(s []byte, c byte) int 586 TEXT bytes·IndexByte(SB),NOSPLIT,$0-40 587 MOV s+0(FP), A1 588 MOV s_len+8(FP), A2 589 MOVBU c+24(FP), A3 // byte to find 590 MOV A1, A4 // store base for later 591 ADD A1, A2 // end 592 ADD $-1, A1 593 594 loop: 595 ADD $1, A1 596 BEQ A1, A2, notfound 597 MOVBU (A1), A5 598 BNE A3, A5, loop 599 600 SUB A4, A1 // remove base 601 MOV A1, ret+32(FP) 602 RET 603 604 notfound: 605 MOV $-1, A1 606 MOV A1, ret+32(FP) 607 RET 608 609 // func IndexByte(s string, c byte) int 610 TEXT strings·IndexByte(SB),NOSPLIT,$0-32 611 MOV p+0(FP), A1 612 MOV b_len+8(FP), A2 613 MOVBU c+16(FP), A3 // byte to find 614 MOV A1, A4 // store base for later 615 ADD A1, A2 // end 616 ADD $-1, A1 617 618 loop: 619 ADD $1, A1 620 BEQ A1, A2, notfound 621 MOVBU (A1), A5 622 BNE A3, A5, loop 623 624 SUB A4, A1 // remove base 625 MOV A1, ret+24(FP) 626 RET 627 628 notfound: 629 MOV $-1, A1 630 MOV A1, ret+24(FP) 631 RET 632 633 // TODO: share code with memequal? 634 // func Equal(a, b []byte) bool 635 TEXT bytes·Equal(SB),NOSPLIT,$0-49 636 MOV a_len+8(FP), A3 637 MOV b_len+32(FP), A4 638 BNE A3, A4, noteq // unequal lengths are not equal 639 640 MOV a+0(FP), A1 641 MOV b+24(FP), A2 642 ADD A1, A3 // end 643 644 loop: 645 BEQ A1, A3, equal // reached the end 646 MOVBU (A1), A6 647 ADD $1, A1 648 MOVBU (A2), A7 649 ADD $1, A2 650 BEQ A6, A7, loop 651 652 noteq: 653 MOVB ZERO, ret+48(FP) 654 RET 655 656 equal: 657 MOV $1, A1 658 MOVB A1, ret+48(FP) 659 RET 660 661 TEXT runtime·stackBarrier(SB),NOSPLIT,$0 662 WORD $0 663 664 // func cgocallback_gofunc(fv uintptr, frame uintptr, framesize, ctxt uintptr) 665 TEXT ·cgocallback_gofunc(SB),NOSPLIT,$24-32 666 WORD $0 667 668 TEXT runtime·prefetcht0(SB),NOSPLIT,$0-8 669 RET 670 671 TEXT runtime·prefetcht1(SB),NOSPLIT,$0-8 672 RET 673 674 TEXT runtime·prefetcht2(SB),NOSPLIT,$0-8 675 RET 676 677 TEXT runtime·prefetchnta(SB),NOSPLIT,$0-8 678 RET 679 680 TEXT runtime·breakpoint(SB),NOSPLIT,$-8-0 681 EBREAK 682 RET 683 684 TEXT runtime·abort(SB),NOSPLIT,$-8-0 685 EBREAK 686 RET 687 688 // void setg(G*); set g. for use by needm. 689 TEXT runtime·setg(SB), NOSPLIT, $0-8 690 MOV gg+0(FP), g 691 // This only happens if iscgo, so jump straight to save_g 692 CALL runtime·save_g(SB) 693 RET 694 695 TEXT ·checkASM(SB),NOSPLIT,$0-1 696 MOV $1, T0 697 MOV T0, ret+0(FP) 698 RET 699 700 DATA runtime·mainPC+0(SB)/8,$runtime·main(SB) 701 GLOBL runtime·mainPC(SB),RODATA,$8