Fixes bug in x86 atomics
authorBarret Rhoden <brho@cs.berkeley.edu>
Wed, 7 Apr 2010 05:13:18 +0000 (22:13 -0700)
committerKevin Klues <klueska@cs.berkeley.edu>
Thu, 3 Nov 2011 00:35:41 +0000 (17:35 -0700)
Can't use an "r" on the register constraints when the register will be
used in a byte operation (movb) on 32 bit x86.  Use "q" instead.

kern/arch/i686/atomic.h
user/include/i686/atomic.h

index 14bfe65..34bcae6 100644 (file)
@@ -83,14 +83,18 @@ static inline bool atomic_comp_swap(uint32_t *addr, uint32_t exp_val,
        return exp_val;
 }
 
+/* Be sure to use "q" for byte operations (compared to longs), since this
+ * constrains the asm to use e{a,b,c,d}x instead of esi and edi.  32 bit x86
+ * cannot access the lower parts of esi or edi (will get warnings like "no such
+ * register %sil or %dil." */
 static inline void atomic_andb(volatile uint8_t RACY*number, uint8_t mask)
 {
-       asm volatile("lock andb %1,%0" : "=m"(*number) : "r"(mask) : "cc");
+       asm volatile("lock andb %1,%0" : "=m"(*number) : "q"(mask) : "cc");
 }
 
 static inline void atomic_orb(volatile uint8_t RACY*number, uint8_t mask)
 {
-       asm volatile("lock orb %1,%0" : "=m"(*number) : "r"(mask) : "cc");
+       asm volatile("lock orb %1,%0" : "=m"(*number) : "q"(mask) : "cc");
 }
 
 static inline uint32_t spin_locked(spinlock_t *SAFE lock)
index 5cc5437..e32ab6b 100644 (file)
@@ -68,12 +68,12 @@ static inline bool atomic_comp_swap(uint32_t *addr, uint32_t exp_val,
 
 static inline void atomic_andb(volatile uint8_t RACY*number, uint8_t mask)
 {
-       asm volatile("lock andb %1,%0" : "=m"(*number) : "r"(mask) : "cc");
+       asm volatile("lock andb %1,%0" : "=m"(*number) : "q"(mask) : "cc");
 }
 
 static inline void atomic_orb(volatile uint8_t RACY*number, uint8_t mask)
 {
-       asm volatile("lock orb %1,%0" : "=m"(*number) : "r"(mask) : "cc");
+       asm volatile("lock orb %1,%0" : "=m"(*number) : "q"(mask) : "cc");
 }
 
 #endif /* !PARLIB_ATOMIC_H */