aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/internal/atomic/asm_arm.s
blob: 12da22390d562663d3d6d1f7b74d2b5ea10f460c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#include "textflag.h"

// bool armcas(int32 *val, int32 old, int32 new)
// Atomically:
//	if(*val == old){
//		*val = new;
//		return 1;
//	}else
//		return 0;
//
// To implement runtime∕internal∕atomic·cas in sys_$GOOS_arm.s
// using the native instructions, use:
//
//	TEXT runtime∕internal∕atomic·cas(SB),NOSPLIT,$0
//		B	runtime∕internal∕atomic·armcas(SB)
//
TEXT runtimeinternalatomic·armcas(SB),NOSPLIT,$0-13
	MOVW	valptr+0(FP), R1
	MOVW	old+4(FP), R2
	MOVW	new+8(FP), R3
casl:
	LDREX	(R1), R0
	CMP	R0, R2
	BNE	casfail

	MOVB	runtime·goarm(SB), R11
	CMP	$7, R11
	BLT	2(PC)
	WORD	$0xf57ff05a	// dmb ishst

	STREX	R3, (R1), R0
	CMP	$0, R0
	BNE	casl
	MOVW	$1, R0

	MOVB	runtime·goarm(SB), R11
	CMP	$7, R11
	BLT	2(PC)
	WORD	$0xf57ff05b	// dmb ish

	MOVB	R0, ret+12(FP)
	RET
casfail:
	MOVW	$0, R0
	MOVB	R0, ret+12(FP)
	RET

TEXT runtimeinternalatomic·Casuintptr(SB),NOSPLIT,$0-13
	B	runtimeinternalatomic·Cas(SB)

TEXT runtimeinternalatomic·Loaduintptr(SB),NOSPLIT,$0-8
	B	runtimeinternalatomic·Load(SB)

TEXT runtimeinternalatomic·Loaduint(SB),NOSPLIT,$0-8
	B	runtimeinternalatomic·Load(SB)

TEXT runtimeinternalatomic·Storeuintptr(SB),NOSPLIT,$0-8
	B	runtimeinternalatomic·Store(SB)

TEXT runtimeinternalatomic·Xadduintptr(SB),NOSPLIT,$0-12
	B	runtimeinternalatomic·Xadd(SB)

TEXT runtimeinternalatomic·Loadint64(SB),NOSPLIT,$0-12
	B	runtimeinternalatomic·Load64(SB)

TEXT runtimeinternalatomic·Xaddint64(SB),NOSPLIT,$0-20
	B	runtimeinternalatomic·Xadd64(SB)