diff options
author | Daniel Jacobowitz <drow@false.org> | 2006-08-30 10:02:08 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2006-09-20 09:58:35 -0400 |
commit | 6a39dd6222dda5ee2414a1b42e8e62118742a49e (patch) | |
tree | 8c4eeeb2d48b583aed900f2a3e8c57f0536a0193 /arch/arm | |
parent | 681a4991f83742a0d2325afbf7b7f22045ad5b30 (diff) |
[ARM] 3759/2: Remove uses of %?
Patch from Daniel Jacobowitz
The ARM kernel has several uses of asm("foo%?"). %? is a GCC internal
modifier used to output conditional execution predicates. However, no
version of GCC supports conditionalizing asm statements. GCC 4.2 will
correctly expand %? to the empty string in user asms. Earlier versions may
reuse the condition from the previous instruction. In 'if (foo) asm
("bar%?");' this is somewhat likely to be right... but not reliable.
So, the only safe thing to do is to remove the uses of %?. I believe
the tlbflush.h occurances were supposed to be removed before, based
on the comment about %? not working at the top of that file.
Old versions of GCC could omit branches around user asms if the asm didn't
mark the condition codes as clobbered. This problem hasn't been seen on any
recent (3.x or 4.x) GCC, but it could theoretically happen. So, where
%? was removed a cc clobber was added.
Signed-off-by: Daniel Jacobowitz <dan@codesourcery.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/kernel/traps.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-footbridge/dc21285.c | 27 | ||||
-rw-r--r-- | arch/arm/vfp/vfpinstr.h | 8 |
3 files changed, 20 insertions, 17 deletions
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index aeeed806f991..bede380c07a9 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c | |||
@@ -191,7 +191,7 @@ void show_stack(struct task_struct *tsk, unsigned long *sp) | |||
191 | if (tsk != current) | 191 | if (tsk != current) |
192 | fp = thread_saved_fp(tsk); | 192 | fp = thread_saved_fp(tsk); |
193 | else | 193 | else |
194 | asm("mov%? %0, fp" : "=r" (fp)); | 194 | asm("mov %0, fp" : "=r" (fp) : : "cc"); |
195 | 195 | ||
196 | c_backtrace(fp, 0x10); | 196 | c_backtrace(fp, 0x10); |
197 | barrier(); | 197 | barrier(); |
diff --git a/arch/arm/mach-footbridge/dc21285.c b/arch/arm/mach-footbridge/dc21285.c index 823e25d4547e..a1ae49df5c3b 100644 --- a/arch/arm/mach-footbridge/dc21285.c +++ b/arch/arm/mach-footbridge/dc21285.c | |||
@@ -69,16 +69,16 @@ dc21285_read_config(struct pci_bus *bus, unsigned int devfn, int where, | |||
69 | if (addr) | 69 | if (addr) |
70 | switch (size) { | 70 | switch (size) { |
71 | case 1: | 71 | case 1: |
72 | asm("ldr%?b %0, [%1, %2]" | 72 | asm("ldrb %0, [%1, %2]" |
73 | : "=r" (v) : "r" (addr), "r" (where)); | 73 | : "=r" (v) : "r" (addr), "r" (where) : "cc"); |
74 | break; | 74 | break; |
75 | case 2: | 75 | case 2: |
76 | asm("ldr%?h %0, [%1, %2]" | 76 | asm("ldrh %0, [%1, %2]" |
77 | : "=r" (v) : "r" (addr), "r" (where)); | 77 | : "=r" (v) : "r" (addr), "r" (where) : "cc"); |
78 | break; | 78 | break; |
79 | case 4: | 79 | case 4: |
80 | asm("ldr%? %0, [%1, %2]" | 80 | asm("ldr %0, [%1, %2]" |
81 | : "=r" (v) : "r" (addr), "r" (where)); | 81 | : "=r" (v) : "r" (addr), "r" (where) : "cc"); |
82 | break; | 82 | break; |
83 | } | 83 | } |
84 | 84 | ||
@@ -103,16 +103,19 @@ dc21285_write_config(struct pci_bus *bus, unsigned int devfn, int where, | |||
103 | if (addr) | 103 | if (addr) |
104 | switch (size) { | 104 | switch (size) { |
105 | case 1: | 105 | case 1: |
106 | asm("str%?b %0, [%1, %2]" | 106 | asm("strb %0, [%1, %2]" |
107 | : : "r" (value), "r" (addr), "r" (where)); | 107 | : : "r" (value), "r" (addr), "r" (where) |
108 | : "cc"); | ||
108 | break; | 109 | break; |
109 | case 2: | 110 | case 2: |
110 | asm("str%?h %0, [%1, %2]" | 111 | asm("strh %0, [%1, %2]" |
111 | : : "r" (value), "r" (addr), "r" (where)); | 112 | : : "r" (value), "r" (addr), "r" (where) |
113 | : "cc"); | ||
112 | break; | 114 | break; |
113 | case 4: | 115 | case 4: |
114 | asm("str%? %0, [%1, %2]" | 116 | asm("str %0, [%1, %2]" |
115 | : : "r" (value), "r" (addr), "r" (where)); | 117 | : : "r" (value), "r" (addr), "r" (where) |
118 | : "cc"); | ||
116 | break; | 119 | break; |
117 | } | 120 | } |
118 | 121 | ||
diff --git a/arch/arm/vfp/vfpinstr.h b/arch/arm/vfp/vfpinstr.h index 6c819aeae006..7f343a4beca0 100644 --- a/arch/arm/vfp/vfpinstr.h +++ b/arch/arm/vfp/vfpinstr.h | |||
@@ -73,14 +73,14 @@ | |||
73 | 73 | ||
74 | #define fmrx(_vfp_) ({ \ | 74 | #define fmrx(_vfp_) ({ \ |
75 | u32 __v; \ | 75 | u32 __v; \ |
76 | asm("mrc%? p10, 7, %0, " vfpreg(_vfp_) ", cr0, 0 @ fmrx %0, " #_vfp_ \ | 76 | asm("mrc p10, 7, %0, " vfpreg(_vfp_) ", cr0, 0 @ fmrx %0, " #_vfp_ \ |
77 | : "=r" (__v)); \ | 77 | : "=r" (__v) : : "cc"); \ |
78 | __v; \ | 78 | __v; \ |
79 | }) | 79 | }) |
80 | 80 | ||
81 | #define fmxr(_vfp_,_var_) \ | 81 | #define fmxr(_vfp_,_var_) \ |
82 | asm("mcr%? p10, 7, %0, " vfpreg(_vfp_) ", cr0, 0 @ fmxr " #_vfp_ ", %0" \ | 82 | asm("mcr p10, 7, %0, " vfpreg(_vfp_) ", cr0, 0 @ fmxr " #_vfp_ ", %0" \ |
83 | : : "r" (_var_)) | 83 | : : "r" (_var_) : "cc") |
84 | 84 | ||
85 | u32 vfp_single_cpdo(u32 inst, u32 fpscr); | 85 | u32 vfp_single_cpdo(u32 inst, u32 fpscr); |
86 | u32 vfp_single_cprt(u32 inst, u32 fpscr, struct pt_regs *regs); | 86 | u32 vfp_single_cprt(u32 inst, u32 fpscr, struct pt_regs *regs); |