diff options
-rw-r--r-- | include/asm-mips/hazards.h | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/include/asm-mips/hazards.h b/include/asm-mips/hazards.h index 7517189e469f..2fc90632f88c 100644 --- a/include/asm-mips/hazards.h +++ b/include/asm-mips/hazards.h | |||
@@ -233,15 +233,25 @@ __asm__( | |||
233 | #endif | 233 | #endif |
234 | 234 | ||
235 | #ifdef CONFIG_CPU_MIPSR2 | 235 | #ifdef CONFIG_CPU_MIPSR2 |
236 | /* | ||
237 | * gcc has a tradition of misscompiling the previous construct using the | ||
238 | * address of a label as argument to inline assembler. Gas otoh has the | ||
239 | * annoying difference between la and dla which are only usable for 32-bit | ||
240 | * rsp. 64-bit code, so can't be used without conditional compilation. | ||
241 | * The alterantive is switching the assembler to 64-bit code which happens | ||
242 | * to work right even for 32-bit code ... | ||
243 | */ | ||
236 | #define instruction_hazard() \ | 244 | #define instruction_hazard() \ |
237 | do { \ | 245 | do { \ |
238 | __label__ __next; \ | 246 | unsigned long tmp; \ |
247 | \ | ||
239 | __asm__ __volatile__( \ | 248 | __asm__ __volatile__( \ |
249 | " .set mips64r2 \n" \ | ||
250 | " dla %0, 1f \n" \ | ||
240 | " jr.hb %0 \n" \ | 251 | " jr.hb %0 \n" \ |
241 | : \ | 252 | " .set mips0 \n" \ |
242 | : "r" (&&__next)); \ | 253 | "1: \n" \ |
243 | __next: \ | 254 | : "=r" (tmp)); \ |
244 | ; \ | ||
245 | } while (0) | 255 | } while (0) |
246 | 256 | ||
247 | #else | 257 | #else |