summaryrefslogtreecommitdiffstats
path: root/cpukit/score
diff options
context:
space:
mode:
authorMaksim E. Kozlov <maksim.e.kozlov@gmail.com>2019-06-05 22:22:36 +0300
committerSebastian Huber <sebastian.huber@embedded-brains.de>2019-06-06 08:40:47 +0200
commita38187051863cf4a423c4f00669c6786bc8ff60d (patch)
tree81e6089217b4802e70585f491f19707acecc3db8 /cpukit/score
parentsparc: Improve _CPU_Context_validate() (diff)
downloadrtems-a38187051863cf4a423c4f00669c6786bc8ff60d.tar.bz2
sparc: Fix missed restoring of PSR in syscall_lazy_fp_switch
It is needed to restore PSR just before return because condition codes are dirty after the CMP instructions and this may cause undefined program behavior after returning from the switching procedure (on following branch instruction, for example). Close #3756.
Diffstat (limited to 'cpukit/score')
-rw-r--r--cpukit/score/cpu/sparc/syscall.S11
1 files changed, 11 insertions, 0 deletions
diff --git a/cpukit/score/cpu/sparc/syscall.S b/cpukit/score/cpu/sparc/syscall.S
index 603ed7a738..4f4ef32c53 100644
--- a/cpukit/score/cpu/sparc/syscall.S
+++ b/cpukit/score/cpu/sparc/syscall.S
@@ -241,12 +241,23 @@ SYM(syscall_lazy_fp_switch):
.Lfp_restore_done:
+ /*
+ * Restore condition codes. PSR[EF] is 1 here. Take PSR write delay
+ * into account (maximum is three instructions).
+ */
+ mov %l0, %psr
+ nop
+
/* Now, retry the floating point instruction with PSR[EF] == 1 */
jmp %l1
rett %l2
.Lillegal_use_of_floating_point_unit:
+ /*
+ * There is no need to restore the condition codes here, since
+ * _Internal_error() does not return.
+ */
sethi %hi(_Internal_error), %l1
or %l1, %lo(_Internal_error), %l1
mov 38, %i0