diff options
| author | John David Anglin <dave.anglin@bell.net> | 2014-12-14 10:49:11 -0500 |
|---|---|---|
| committer | Helge Deller <deller@gmx.de> | 2014-12-26 11:47:01 -0500 |
| commit | 45db07382a5c78b0c43b3b0002b63757fb60e873 (patch) | |
| tree | 63d86170ec09f9d9181f40dd6caa091271b5116d | |
| parent | b2776bf7149bddd1f4161f14f79520f17fc1d71d (diff) | |
parisc: fix out-of-register compiler error in ldcw inline assembler function
The __ldcw macro has a problem when its argument needs to be reloaded from
memory. The output memory operand and the input register operand both need to
be reloaded using a register in class R1_REGS when generating 64-bit code.
This fails because there's only a single register in the class. Instead, use a
memory clobber. This also makes the __ldcw macro a compiler memory barrier.
Signed-off-by: John David Anglin <dave.anglin@bell.net>
Cc: <stable@vger.kernel.org> [3.13+]
Signed-off-by: Helge Deller <deller@gmx.de>
| -rw-r--r-- | arch/parisc/include/asm/ldcw.h | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/arch/parisc/include/asm/ldcw.h b/arch/parisc/include/asm/ldcw.h index d2d11b7055ba..8121aa6db2ff 100644 --- a/arch/parisc/include/asm/ldcw.h +++ b/arch/parisc/include/asm/ldcw.h | |||
| @@ -33,11 +33,18 @@ | |||
| 33 | 33 | ||
| 34 | #endif /*!CONFIG_PA20*/ | 34 | #endif /*!CONFIG_PA20*/ |
| 35 | 35 | ||
| 36 | /* LDCW, the only atomic read-write operation PA-RISC has. *sigh*. */ | 36 | /* LDCW, the only atomic read-write operation PA-RISC has. *sigh*. |
| 37 | We don't explicitly expose that "*a" may be written as reload | ||
| 38 | fails to find a register in class R1_REGS when "a" needs to be | ||
| 39 | reloaded when generating 64-bit PIC code. Instead, we clobber | ||
| 40 | memory to indicate to the compiler that the assembly code reads | ||
| 41 | or writes to items other than those listed in the input and output | ||
| 42 | operands. This may pessimize the code somewhat but __ldcw is | ||
| 43 | usually used within code blocks surrounded by memory barriors. */ | ||
| 37 | #define __ldcw(a) ({ \ | 44 | #define __ldcw(a) ({ \ |
| 38 | unsigned __ret; \ | 45 | unsigned __ret; \ |
| 39 | __asm__ __volatile__(__LDCW " 0(%2),%0" \ | 46 | __asm__ __volatile__(__LDCW " 0(%1),%0" \ |
| 40 | : "=r" (__ret), "+m" (*(a)) : "r" (a)); \ | 47 | : "=r" (__ret) : "r" (a) : "memory"); \ |
| 41 | __ret; \ | 48 | __ret; \ |
| 42 | }) | 49 | }) |
| 43 | 50 | ||
