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

« back to all changes in this revision

Viewing changes to src/atomic_ops/sysdeps/gcc/x86_64.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
 
35
37
#if defined(AO_USE_PENTIUM4_INSTRS)
36
38
AO_INLINE void
37
39
AO_nop_full()
39
41
  __asm__ __volatile__("mfence" : : : "memory");
40
42
}
41
43
 
42
 
#define AO_HAVE_NOP_FULL
 
44
#define AO_HAVE_nop_full
43
45
 
44
46
#else
45
47
 
54
56
 
55
57
/* Really only works for 486 and later */
56
58
AO_INLINE AO_t
57
 
AO_fetch_and_add_full (volatile AO_t *p, long incr)
 
59
AO_fetch_and_add_full (volatile AO_t *p, AO_t incr)
58
60
{
59
 
  AO_t result = incr;
 
61
  AO_t result;
60
62
 
61
63
  __asm__ __volatile__ ("lock; xaddq %0, %1" :
62
 
                        "+r" (result), "+m" (*p) : : "memory");
 
64
                        "=r" (result), "=m" (*p) : "0" (incr), "m" (*p)
 
65
                        : "memory");
63
66
  return result;
64
67
}
65
68
 
66
69
#define AO_HAVE_fetch_and_add_full
67
70
 
 
71
AO_INLINE unsigned char
 
72
AO_char_fetch_and_add_full (volatile unsigned char *p, unsigned char incr)
 
73
{
 
74
  unsigned char result;
 
75
 
 
76
  __asm__ __volatile__ ("lock; xaddb %0, %1" :
 
77
                        "=r" (result), "=m" (*p) : "0" (incr), "m" (*p)
 
78
                        : "memory");
 
79
  return result;
 
80
}
 
81
 
 
82
#define AO_HAVE_char_fetch_and_add_full
 
83
 
 
84
AO_INLINE unsigned short
 
85
AO_short_fetch_and_add_full (volatile unsigned short *p, unsigned short incr)
 
86
{
 
87
  unsigned short result;
 
88
 
 
89
  __asm__ __volatile__ ("lock; xaddw %0, %1" :
 
90
                        "=r" (result), "=m" (*p) : "0" (incr), "m" (*p)
 
91
                        : "memory");
 
92
  return result;
 
93
}
 
94
 
 
95
#define AO_HAVE_short_fetch_and_add_full
 
96
 
 
97
AO_INLINE unsigned short
 
98
AO_int_fetch_and_add_full (volatile unsigned int *p, unsigned int incr)
 
99
{
 
100
  unsigned int result;
 
101
 
 
102
  __asm__ __volatile__ ("lock; xaddl %0, %1" :
 
103
                        "=r" (result), "=m" (*p) : "0" (incr), "m" (*p)
 
104
                        : "memory");
 
105
  return result;
 
106
}
 
107
 
 
108
#define AO_HAVE_int_fetch_and_add_full
 
109
 
68
110
/* Really only works for 486 and later */
69
111
AO_INLINE void
70
112
AO_or_full (volatile AO_t *p, AO_t incr)
71
113
{
72
114
  __asm__ __volatile__ ("lock; orq %1, %0" :
73
 
                        "+m" (*p) : "r" (incr) : "memory");
 
115
                        "=m" (*p) : "r" (incr), "m" (*p) : "memory");
74
116
}
75
117
 
76
118
#define AO_HAVE_or_full
77
119
 
78
 
AO_INLINE AO_TS_t
79
 
AO_test_and_set_full(volatile AO_t *addr)
 
120
AO_INLINE AO_TS_VAL_t
 
121
AO_test_and_set_full(volatile AO_TS_t *addr)
80
122
{
81
 
  AO_t oldval;
 
123
  unsigned char oldval;
82
124
  /* Note: the "xchg" instruction does not need a "lock" prefix */
83
 
  __asm__ __volatile__("xchgq %0, %1"
84
 
                : "=r"(oldval), "+m"(*(addr))
85
 
                : "0"(1) : "memory");
86
 
  return oldval;
 
125
  __asm__ __volatile__("xchgb %0, %1"
 
126
                : "=r"(oldval), "=m"(*addr)
 
127
                : "0"(0xff), "m"(*addr) : "memory");
 
128
  return (AO_TS_VAL_t)oldval;
87
129
}
88
130
 
89
131
#define AO_HAVE_test_and_set_full
94
136
                             AO_t old, AO_t new_val) 
95
137
{
96
138
  char result;
97
 
  __asm__ __volatile__("lock; cmpxchgq %2, %0; setz %1"
98
 
                       : "+m"(*(addr)), "=q"(result)
99
 
                       : "r" (new_val), "a"(old) : "memory");
 
139
  __asm__ __volatile__("lock; cmpxchgq %3, %0; setz %1"
 
140
                       : "=m"(*addr), "=q"(result)
 
141
                       : "m"(*addr), "r" (new_val), "a"(old) : "memory");
100
142
  return (int) result;
101
143
}
102
144
 
103
145
#define AO_HAVE_compare_and_swap_full
 
146
 
 
147
/* FIXME: The Intel version has a 16byte CAS instruction.       */