[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: Haavard Skinnemoen <hskinnemoen@atmel.com>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
diff --git a/include/asm-avr32/atomic.h b/include/asm-avr32/atomic.h
index e0b9c44..c40b603 100644
--- a/include/asm-avr32/atomic.h
+++ b/include/asm-avr32/atomic.h
@@ -41,7 +41,7 @@
" stcond %1, %0\n"
" brne 1b"
: "=&r"(result), "=o"(v->counter)
- : "m"(v->counter), "ir"(i)
+ : "m"(v->counter), "rKs21"(i)
: "cc");
return result;
@@ -58,7 +58,7 @@
{
int result;
- if (__builtin_constant_p(i))
+ if (__builtin_constant_p(i) && (i >= -1048575) && (i <= 1048576))
result = atomic_sub_return(-i, v);
else
asm volatile(
@@ -101,7 +101,7 @@
" mov %1, 1\n"
"1:"
: "=&r"(tmp), "=&r"(result), "=o"(v->counter)
- : "m"(v->counter), "ir"(a), "ir"(u)
+ : "m"(v->counter), "rKs21"(a), "rKs21"(u)
: "cc", "memory");
return result;
@@ -121,7 +121,7 @@
{
int tmp, result;
- if (__builtin_constant_p(a))
+ if (__builtin_constant_p(a) && (a >= -1048575) && (a <= 1048576))
result = atomic_sub_unless(v, -a, u);
else {
result = 0;