diff options
Diffstat (limited to 'include/asm-mips/hazards.h')
| -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 |
