1 /* atomic/gcc_x86.c
2 * Copyright (C) 2006-2010, Parrot Foundation.
3 */
4
5 #include "parrot/parrot.h"
6 #include "parrot/atomic/gcc_x86.h"
7
8 /* HEADERIZER HFILE: include/parrot/atomic/gcc_x86.h */
9
10 /*
11
12 =head1 NAME
13
14 src/atomic/gcc_x86.c
15
16 =head1 DESCRIPTION
17
18 An implementation of atomic operations on x86 platforms with GCC-style inline
19 assembly suppport.
20
21 =head2 Functions
22
23 =over 4
24
25 =cut
26
27 */
28
29 /*
30 * if both I386 and X86_64 cmpxchg are defined, we are on x86_64 -
31 * reuse existing code
32 */
33 /*
34
35 =item C<void * parrot_i386_cmpxchg(void *volatile *ptr, void *expect, void
36 *update)>
37
38 The CMPXCHG assembly instruction is a single cycle x86 instruction
39 that compares C<expect> and C<*ptr>. If they are equal, sets
40 C<*ptr> to C<update>. Otherwise sets C<expect> to C<*ptr>.
41
42 =cut
43
44 */
45
46
47 PARROT_EXPORT
48 PARROT_CANNOT_RETURN_NULL
49 void *
parrot_i386_cmpxchg(ARGMOD (void * volatile * ptr),ARGIN_NULLOK (void * expect),ARGIN_NULLOK (void * update))50 parrot_i386_cmpxchg(ARGMOD(void *volatile *ptr), ARGIN_NULLOK(void *expect),
51 ARGIN_NULLOK(void *update))
52 {
53 ASSERT_ARGS(parrot_i386_cmpxchg)
54 #if defined(PARROT_HAS_AMD64_GCC_CMPXCHG)
55 __asm__ __volatile__("lock\n"
56 "cmpxchgq %1,%2":"=a"(expect):"q"(update), "m"(*ptr),
57 "0"(expect)
58 :"memory");
59 #elif defined(PARROT_HAS_I386_GCC_CMPXCHG)
60 __asm__ __volatile__("lock\n"
61 "cmpxchgl %1,%2":"=a"(expect):"q"(update), "m"(*ptr),
62 "0"(expect)
63 :"memory");
64 #endif
65 return expect;
66 }
67
68 /*
69
70 =item C<long parrot_i386_xadd(volatile long *l, long amount)>
71
72 C<xadd> is an x86 instruction that performs the following operation:
73 Temporary = C<result>;
74 C<result> = C<result> + C<l>;
75 C<l> = C<result>;
76
77 =cut
78
79 */
80
81
82 PARROT_EXPORT
83 long
parrot_i386_xadd(ARGIN (volatile long * l),long amount)84 parrot_i386_xadd(ARGIN(volatile long *l), long amount)
85 {
86 ASSERT_ARGS(parrot_i386_xadd)
87 long result = amount;
88 #if defined(PARROT_HAS_AMD64_GCC_CMPXCHG)
89 __asm__ __volatile__("lock\n" "xaddq %0, %1" : "=r"(result), "=m"(*l) :
90 "0"(result), "m"(*l));
91 #elif defined(PARROT_HAS_I386_GCC_CMPXCHG)
92 __asm__ __volatile__("lock\n" "xaddl %0, %1" : "=r"(result), "=m"(*l) :
93 "0"(result), "m"(*l));
94 #endif
95 return result + amount;
96 }
97
98 /*
99
100 =back
101
102 =cut
103
104 */
105
106 /*
107 * Local variables:
108 * c-file-style: "parrot"
109 * End:
110 * vim: expandtab shiftwidth=4 cinoptions='\:2=2' :
111 */
112