github.com/corona10/go@v0.0.0-20180224231303-7a218942be57/src/runtime/internal/atomic/sys_linux_arm.s (about) 1 // Copyright 2015 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 #include "textflag.h" 6 7 // Use kernel version instead of native armcas in asm_arm.s. 8 // See ../../../sync/atomic/asm_linux_arm.s for details. 9 TEXT cas<>(SB),NOSPLIT,$0 10 MOVW $0xffff0fc0, R15 // R15 is hardware PC. 11 12 TEXT runtime∕internal∕atomic·Cas(SB),NOSPLIT,$0 13 MOVW ptr+0(FP), R2 14 // trigger potential paging fault here, 15 // because we don't know how to traceback through __kuser_cmpxchg 16 MOVW (R2), R0 17 MOVW old+4(FP), R0 18 loop: 19 MOVW new+8(FP), R1 20 BL cas<>(SB) 21 BCC check 22 MOVW $1, R0 23 MOVB R0, ret+12(FP) 24 RET 25 check: 26 // Kernel lies; double-check. 27 MOVW ptr+0(FP), R2 28 MOVW old+4(FP), R0 29 MOVW 0(R2), R3 30 CMP R0, R3 31 BEQ loop 32 MOVW $0, R0 33 MOVB R0, ret+12(FP) 34 RET 35 36 TEXT runtime∕internal∕atomic·Casp1(SB),NOSPLIT,$0 37 B runtime∕internal∕atomic·Cas(SB) 38 39 // As for cas, memory barriers are complicated on ARM, but the kernel 40 // provides a user helper. ARMv5 does not support SMP and has no 41 // memory barrier instruction at all. ARMv6 added SMP support and has 42 // a memory barrier, but it requires writing to a coprocessor 43 // register. ARMv7 introduced the DMB instruction, but it's expensive 44 // even on single-core devices. The kernel helper takes care of all of 45 // this for us.