github.com/epfl-dcsl/gotee@v0.0.0-20200909122901-014b35f5e5e9/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  	MOVW	old+4(FP), R0
    15  loop:
    16  	MOVW	new+8(FP), R1
    17  	BL	cas<>(SB)
    18  	BCC	check
    19  	MOVW	$1, R0
    20  	MOVB	R0, ret+12(FP)
    21  	RET
    22  check:
    23  	// Kernel lies; double-check.
    24  	MOVW	ptr+0(FP), R2
    25  	MOVW	old+4(FP), R0
    26  	MOVW	0(R2), R3
    27  	CMP	R0, R3
    28  	BEQ	loop
    29  	MOVW	$0, R0
    30  	MOVB	R0, ret+12(FP)
    31  	RET
    32  
    33  TEXT runtime∕internal∕atomic·Casp1(SB),NOSPLIT,$0
    34  	B	runtime∕internal∕atomic·Cas(SB)
    35  
    36  // As for cas, memory barriers are complicated on ARM, but the kernel
    37  // provides a user helper. ARMv5 does not support SMP and has no
    38  // memory barrier instruction at all. ARMv6 added SMP support and has
    39  // a memory barrier, but it requires writing to a coprocessor
    40  // register. ARMv7 introduced the DMB instruction, but it's expensive
    41  // even on single-core devices. The kernel helper takes care of all of
    42  // this for us.