Commit fa352240 authored by Haavard Skinnemoen's avatar Haavard Skinnemoen Committed by Linus Torvalds

[PATCH] AVR32: Fix oversize immediates in atomic.h

When calling e.g. atomic_sub_return with a large constant, the
compiler may output an immediate that is too large for the sub
instruction in the middle of the loop.

Fix this by explicitly specifying the number of bits allowed in the
constraint. Also stop atomic_add_return() and friends from falling
back to their respective "sub" variants if the constant is too large
to fit in an immediate.
Signed-off-by: default avatarHaavard Skinnemoen <hskinnemoen@atmel.com>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent bee8ce80
...@@ -41,7 +41,7 @@ static inline int atomic_sub_return(int i, atomic_t *v) ...@@ -41,7 +41,7 @@ static inline int atomic_sub_return(int i, atomic_t *v)
" stcond %1, %0\n" " stcond %1, %0\n"
" brne 1b" " brne 1b"
: "=&r"(result), "=o"(v->counter) : "=&r"(result), "=o"(v->counter)
: "m"(v->counter), "ir"(i) : "m"(v->counter), "rKs21"(i)
: "cc"); : "cc");
return result; return result;
...@@ -58,7 +58,7 @@ static inline int atomic_add_return(int i, atomic_t *v) ...@@ -58,7 +58,7 @@ static inline int atomic_add_return(int i, atomic_t *v)
{ {
int result; int result;
if (__builtin_constant_p(i)) if (__builtin_constant_p(i) && (i >= -1048575) && (i <= 1048576))
result = atomic_sub_return(-i, v); result = atomic_sub_return(-i, v);
else else
asm volatile( asm volatile(
...@@ -101,7 +101,7 @@ static inline int atomic_sub_unless(atomic_t *v, int a, int u) ...@@ -101,7 +101,7 @@ static inline int atomic_sub_unless(atomic_t *v, int a, int u)
" mov %1, 1\n" " mov %1, 1\n"
"1:" "1:"
: "=&r"(tmp), "=&r"(result), "=o"(v->counter) : "=&r"(tmp), "=&r"(result), "=o"(v->counter)
: "m"(v->counter), "ir"(a), "ir"(u) : "m"(v->counter), "rKs21"(a), "rKs21"(u)
: "cc", "memory"); : "cc", "memory");
return result; return result;
...@@ -121,7 +121,7 @@ static inline int atomic_add_unless(atomic_t *v, int a, int u) ...@@ -121,7 +121,7 @@ static inline int atomic_add_unless(atomic_t *v, int a, int u)
{ {
int tmp, result; int tmp, result;
if (__builtin_constant_p(a)) if (__builtin_constant_p(a) && (a >= -1048575) && (a <= 1048576))
result = atomic_sub_unless(v, -a, u); result = atomic_sub_unless(v, -a, u);
else { else {
result = 0; result = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment