Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
TEXT ainc(SB), 1, $-4				/* int ainc(int*); */
2
	MOVL	arg+0(FP), BX
3
	MOVL	$1, AX
4
	LOCK; BYTE $0x0f; BYTE $0xc1; BYTE $0x03/* XADDL AX, (BX) */
5
	ADDL	$1, AX				/* overflow if -ve or 0 */
6
	RET
7
 
8
TEXT adec(SB), 1, $-4				/* int adec(int*); */
9
	MOVL	arg+0(FP), BX
10
	MOVL	$-1, AX
11
	LOCK; BYTE $0x0f; BYTE $0xc1; BYTE $0x03/* XADDL AX, (BX) */
12
	SUBL	$1, AX				/* underflow if -ve */
13
	RET
14
 
15
/*
16
 * int cas32(u32int *p, u32int ov, u32int nv);
17
 * int cas(uint *p, int ov, int nv);
18
 * int casp(void **p, void *ov, void *nv);
19
 * int casl(ulong *p, ulong ov, ulong nv);
20
 */
21
 
22
/*
23
 * CMPXCHG (CX), DX: 0000 1111 1011 000w oorr rmmm,
24
 * mmm = CX = 001; rrr = DX = 010
25
 */
26
 
27
#define CMPXCHG		BYTE $0x0F; BYTE $0xB1; BYTE $0x11
28
 
29
TEXT	cas32+0(SB),0,$0
30
TEXT	cas+0(SB),0,$0
31
TEXT	casp+0(SB),0,$0
32
TEXT	casl+0(SB),0,$0
33
	MOVL	p+0(FP), CX
34
	MOVL	ov+4(FP), AX
35
	MOVL	nv+8(FP), DX
36
	LOCK
37
	CMPXCHG
38
	JNE	fail
39
	MOVL	$1,AX
40
	RET
41
fail:
42
	MOVL	$0,AX
43
	RET
44
 
45
/*
46
 * int cas64(u64int *p, u64int ov, u64int nv);
47
 */
48
 
49
/*
50
 * CMPXCHG64 (DI): 0000 1111 1100 0111 0000 1110,
51
 */
52
 
53
#define CMPXCHG64		BYTE $0x0F; BYTE $0xC7; BYTE $0x0F
54
 
55
TEXT	cas64+0(SB),0,$0
56
	MOVL	p+0(FP), DI
57
	MOVL	ov+0x4(FP), AX
58
	MOVL	ov+0x8(FP), DX
59
	MOVL	nv+0xc(FP), BX
60
	MOVL	nv+0x10(FP), CX
61
	LOCK
62
	CMPXCHG64
63
	JNE	fail
64
	MOVL	$1,AX
65
	RET
66
 
67
/*
68
 * Versions of compare-and-swap that return the old value
69
 * (i.e., the value of *p at the time of the operation
70
 * 	xcas(p, o, n) == o
71
 * yields the same value as
72
 *	cas(p, o, n)
73
 * xcas can be used in constructs like
74
 *	for(o = *p; (oo = xcas(p, o, o+1)) != o; o = oo)
75
 *		;
76
 * to avoid the extra dereference of *p (the example is a silly
77
 * way to increment *p atomically)
78
 *
79
 * u32int	xcas32(u32int *p, u32int ov, u32int nv);
80
 * u64int	xcas64(u64int *p, u64int ov, u64int nv);
81
 * int		xcas(int *p, int ov, int nv);
82
 * void*	xcasp(void **p, void *ov, void *nv);
83
 * ulong	xcasl(ulong *p, ulong ov, ulong nv);
84
 */
85
 
86
TEXT	xcas32+0(SB),0,$0
87
TEXT	xcas+0(SB),0,$0
88
TEXT	xcasp+0(SB),0,$0
89
TEXT	xcasl+0(SB),0,$0
90
	MOVL	p+0(FP), CX
91
	MOVL	ov+4(FP), AX	/* accumulator */
92
	MOVL	nv+8(FP), DX
93
	LOCK
94
	CMPXCHG
95
	RET
96
 
97
/*
98
 * The CMPXCHG8B instruction also requires three operands:
99
 * a 64-bit value in EDX:EAX, a 64-bit value in ECX:EBX,
100
 * and a destination operand in memory. The instruction compar
101
 * es the 64-bit value in the EDX:EAX registers with the
102
 * destination operand. If they are equal, the 64-bit value
103
 * in the ECX:EBX register is stored in the destination
104
 * operand. If the EDX:EAX register and the destination ar
105
 * e not equal, the destination is loaded in the EDX:EAX
106
 * register. The CMPXCHG8B instruction can be combined with
107
 * the LOCK prefix to perform the operation atomically
108
 */
109
 
110
TEXT	xcas64+0(SB),0,$0
111
	MOVL	p+4(FP), DI
112
	MOVL	ov+0x8(FP), AX
113
	MOVL	ov+0xc(FP), DX
114
	MOVL	nv+0x10(FP), BX
115
	MOVL	nv+0x14(FP), CX
116
	LOCK
117
	CMPXCHG64
118
	MOVL	.ret+0x0(FP),CX	/* pointer to return value */
119
	MOVL	AX,0x0(CX)
120
	MOVL	DX,0x4(CX)
121
	RET