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.