~ubuntu-branches/ubuntu/lucid/libatomic-ops/lucid

« back to all changes in this revision

Viewing changes to src/atomic_ops/sysdeps/gcc/x86.h

  • Committer: Bazaar Package Importer
  • Author(s): Ian Wienand
  • Date: 2006-10-16 09:45:29 UTC
  • mfrom: (2.1.4 dapper)
  • Revision ID: james.westby@ubuntu.com-20061016094529-r3bevpq5w6g3rv20
Tags: 1.1-4
* Closes: #322027, #338469 -- add 04_m68k.patch for M68K support, from
  Roman Zippel <zippel@linux-m68k.org>.  Add note in README.Debian about
  port.
* Change mainatiner address to my @debian.org

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
/* line options.                                                        */
22
22
/* We should perhaps test dynamically.                                  */
23
23
 
24
 
#include "../aligned_atomic_load_store.h"
 
24
#include "../all_aligned_atomic_load_store.h"
25
25
 
26
26
/* Real X86 implementations, except for some old WinChips, appear       */
27
27
/* to enforce ordering between memory operations, EXCEPT that a later   */
32
32
 
33
33
#include "../ordered_except_wr.h"
34
34
 
 
35
#include "../test_and_set_t_is_char.h"
 
36
 
 
37
#include "../standard_ao_double_t.h"
 
38
 
35
39
#if defined(AO_USE_PENTIUM4_INSTRS)
36
40
AO_INLINE void
37
41
AO_nop_full()
39
43
  __asm__ __volatile__("mfence" : : : "memory");
40
44
}
41
45
 
42
 
#define AO_HAVE_NOP_FULL
 
46
#define AO_HAVE_nop_full
43
47
 
44
48
#else
45
49
 
54
58
 
55
59
/* Really only works for 486 and later */
56
60
AO_INLINE AO_t
57
 
AO_fetch_and_add_full (volatile AO_t *p, long incr)
 
61
AO_fetch_and_add_full (volatile AO_t *p, AO_t incr)
58
62
{
59
 
  AO_t result = incr;
 
63
  AO_t result;
60
64
 
61
65
  __asm__ __volatile__ ("lock; xaddl %0, %1" :
62
 
                        "+r" (result), "+m" (*p) : : "memory");
 
66
                        "=r" (result), "=m" (*p) : "0" (incr), "m" (*p)
 
67
                        : "memory");
63
68
  return result;
64
69
}
65
70
 
66
71
#define AO_HAVE_fetch_and_add_full
67
72
 
 
73
AO_INLINE unsigned char
 
74
AO_char_fetch_and_add_full (volatile unsigned char *p, unsigned char incr)
 
75
{
 
76
  unsigned char result;
 
77
 
 
78
  __asm__ __volatile__ ("lock; xaddb %0, %1" :
 
79
                        "=r" (result), "=m" (*p) : "0" (incr), "m" (*p)
 
80
                        : "memory");
 
81
  return result;
 
82
}
 
83
 
 
84
#define AO_HAVE_char_fetch_and_add_full
 
85
 
 
86
AO_INLINE unsigned short
 
87
AO_short_fetch_and_add_full (volatile unsigned short *p, unsigned short incr)
 
88
{
 
89
  unsigned short result;
 
90
 
 
91
  __asm__ __volatile__ ("lock; xaddw %0, %1" :
 
92
                        "=r" (result), "=m" (*p) : "0" (incr), "m" (*p)
 
93
                        : "memory");
 
94
  return result;
 
95
}
 
96
 
 
97
#define AO_HAVE_short_fetch_and_add_full
 
98
 
68
99
/* Really only works for 486 and later */
69
100
AO_INLINE void
70
101
AO_or_full (volatile AO_t *p, AO_t incr)
71
102
{
72
103
  __asm__ __volatile__ ("lock; orl %1, %0" :
73
 
                        "+m" (*p) : "r" (incr) : "memory");
 
104
                        "=m" (*p) : "r" (incr), "m" (*p) : "memory");
74
105
}
75
106
 
76
107
#define AO_HAVE_or_full
77
108
 
78
 
AO_INLINE AO_TS_t
79
 
AO_test_and_set_full(volatile AO_t *addr)
 
109
AO_INLINE AO_TS_VAL_t
 
110
AO_test_and_set_full(volatile AO_TS_t *addr)
80
111
{
81
 
  AO_t oldval;
 
112
  unsigned char oldval;
82
113
  /* Note: the "xchg" instruction does not need a "lock" prefix */
83
 
  __asm__ __volatile__("xchgl %0, %1"
84
 
                : "=r"(oldval), "+m"(*(addr))
85
 
                : "0"(1) : "memory");
86
 
  return oldval;
 
114
  __asm__ __volatile__("xchgb %0, %1"
 
115
                : "=r"(oldval), "=m"(*addr)
 
116
                : "0"(0xff), "m"(*addr) : "memory");
 
117
  return (AO_TS_VAL_t)oldval;
87
118
}
88
119
 
89
120
#define AO_HAVE_test_and_set_full
94
125
                             AO_t old, AO_t new_val) 
95
126
{
96
127
  char result;
97
 
  __asm__ __volatile__("lock; cmpxchgl %2, %0; setz %1"
98
 
                       : "+m"(*(addr)), "=q"(result)
99
 
                       : "r" (new_val), "a"(old) : "memory");
 
128
  __asm__ __volatile__("lock; cmpxchgl %3, %0; setz %1"
 
129
                       : "=m"(*addr), "=q"(result)
 
130
                       : "m"(*addr), "r" (new_val), "a"(old) : "memory");
100
131
  return (int) result;
101
132
}
102
133
 
103
134
#define AO_HAVE_compare_and_swap_full
 
135
 
 
136
/* Returns nonzero if the comparison succeeded. */
 
137
/* Really requires at least a Pentium.          */
 
138
AO_INLINE int
 
139
AO_compare_double_and_swap_double_full(volatile AO_double_t *addr,
 
140
                                       AO_t old_val1, AO_t old_val2,
 
141
                                       AO_t new_val1, AO_t new_val2) 
 
142
{
 
143
  char result;
 
144
  __asm__ __volatile__("lock; cmpxchg8b %0; setz %1"
 
145
                       : "=m"(*addr), "=q"(result)
 
146
                       : "m"(*addr), "d" (old_val1), "a" (old_val2),
 
147
                         "c" (new_val1), "b" (new_val2) : "memory");
 
148
  return (int) result;
 
149
}
 
150
 
 
151
#define AO_HAVE_double_compare_and_swap_full
 
152
 
 
153
#include "../ao_t_is_int.h"