[v2,2/2] sparc: Prevent stfsr from directly following floating-point instruction
Checks
Context |
Check |
Description |
redhat-pt-bot/TryBot-apply_patch |
success
|
Patch applied to master at the time it was sent
|
redhat-pt-bot/TryBot-32bit |
success
|
Build for i686
|
linaro-tcwg-bot/tcwg_glibc_build--master-aarch64 |
success
|
Testing passed
|
linaro-tcwg-bot/tcwg_glibc_check--master-aarch64 |
success
|
Testing passed
|
linaro-tcwg-bot/tcwg_glibc_build--master-arm |
success
|
Testing passed
|
linaro-tcwg-bot/tcwg_glibc_check--master-arm |
success
|
Testing passed
|
Commit Message
On LEON, if the stfsr instruction is immediately following a floating-point
operation instruction in a running program, with no other instruction in
between the two, the stfsr might behave as if the order was reversed
between the two instructions and the stfsr occurred before the
floating-point operation.
Add a nop instruction before the stfsr to prevent this from happening.
Signed-off-by: Daniel Cederman <cederman@gaisler.com>
---
sysdeps/sparc/fpu/fpu_control.h | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
Comments
On 15/01/24 11:53, Daniel Cederman wrote:
> On LEON, if the stfsr instruction is immediately following a floating-point
> operation instruction in a running program, with no other instruction in
> between the two, the stfsr might behave as if the order was reversed
> between the two instructions and the stfsr occurred before the
> floating-point operation.
>
> Add a nop instruction before the stfsr to prevent this from happening.
>
> Signed-off-by: Daniel Cederman <cederman@gaisler.com>
LGTM, thanks.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
> ---
> sysdeps/sparc/fpu/fpu_control.h | 7 ++++++-
> 1 file changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/sysdeps/sparc/fpu/fpu_control.h b/sysdeps/sparc/fpu/fpu_control.h
> index dd18789573..48368a7ce1 100644
> --- a/sysdeps/sparc/fpu/fpu_control.h
> +++ b/sysdeps/sparc/fpu/fpu_control.h
> @@ -61,7 +61,12 @@ typedef unsigned long int fpu_control_t;
> # define _FPU_GETCW(cw) __asm__ __volatile__ ("stx %%fsr,%0" : "=m" (*&cw))
> # define _FPU_SETCW(cw) __asm__ __volatile__ ("ldx %0,%%fsr" : : "m" (*&cw))
> #else
> -# define _FPU_GETCW(cw) __asm__ __volatile__ ("st %%fsr,%0" : "=m" (*&cw))
> +# ifdef __leon__
> + /* Prevent stfsr from being placed directly after other fp instruction. */
> +# define _FPU_GETCW(cw) __asm__ __volatile__ ("nop; st %%fsr,%0" : "=m" (*&cw))
> +# else
> +# define _FPU_GETCW(cw) __asm__ __volatile__ ("st %%fsr,%0" : "=m" (*&cw))
> +# endif
> # define _FPU_SETCW(cw) __asm__ __volatile__ ("ld %0,%%fsr" : : "m" (*&cw))
> #endif
>
@@ -61,7 +61,12 @@ typedef unsigned long int fpu_control_t;
# define _FPU_GETCW(cw) __asm__ __volatile__ ("stx %%fsr,%0" : "=m" (*&cw))
# define _FPU_SETCW(cw) __asm__ __volatile__ ("ldx %0,%%fsr" : : "m" (*&cw))
#else
-# define _FPU_GETCW(cw) __asm__ __volatile__ ("st %%fsr,%0" : "=m" (*&cw))
+# ifdef __leon__
+ /* Prevent stfsr from being placed directly after other fp instruction. */
+# define _FPU_GETCW(cw) __asm__ __volatile__ ("nop; st %%fsr,%0" : "=m" (*&cw))
+# else
+# define _FPU_GETCW(cw) __asm__ __volatile__ ("st %%fsr,%0" : "=m" (*&cw))
+# endif
# define _FPU_SETCW(cw) __asm__ __volatile__ ("ld %0,%%fsr" : : "m" (*&cw))
#endif