Two FP-related setjmp/longjmp changes:
1. Save and restore the control part of the MXCSR in addition to the i387 control word to ensure that the two are consistent. Note that standards don't require longjmp to restore either control word, and none of Linux, MacOS X 10.3 and earlier, NetBSD, OpenBSD, or Solaris do it. However, it is historical FreeBSD behavior, and bde points out that it is needed to make longjmping out of a signal handler work properly, given the way FreeBSD clobbers the FPU state on signal handler entry. 2. Don't clobber the FPU exception flags in longjmp. C99 requires them to remain unchanged.
This commit is contained in:
parent
b370e2cfea
commit
64c2e46650
@ -58,6 +58,7 @@ ENTRY(_setjmp)
|
||||
movq %r14,48(%rax) /* 6; r14 */
|
||||
movq %r15,56(%rax) /* 7; r15 */
|
||||
fnstcw 64(%rax) /* 8; fpu cw */
|
||||
stmxcsr 68(%rax) /* and mxcsr */
|
||||
xorq %rax,%rax
|
||||
ret
|
||||
|
||||
@ -65,6 +66,15 @@ ENTRY(_setjmp)
|
||||
.set CNAME(_longjmp),CNAME(___longjmp)
|
||||
ENTRY(___longjmp)
|
||||
movq %rdi,%rdx
|
||||
/* Restore the mxcsr, but leave exception flags intact. */
|
||||
stmxcsr -4(%rsp)
|
||||
movl 68(%rdx),%eax
|
||||
andl $0xffffffc0,%eax
|
||||
movl -4(%rsp),%edi
|
||||
andl $0x3f,%edi
|
||||
xorl %eax,%edi
|
||||
movl %edi,-4(%rsp)
|
||||
ldmxcsr -4(%rsp)
|
||||
movq %rsi,%rax /* retval */
|
||||
movq 0(%rdx),%rcx
|
||||
movq 8(%rdx),%rbx
|
||||
@ -74,7 +84,6 @@ ENTRY(___longjmp)
|
||||
movq 40(%rdx),%r13
|
||||
movq 48(%rdx),%r14
|
||||
movq 56(%rdx),%r15
|
||||
fninit
|
||||
fldcw 64(%rdx)
|
||||
testq %rax,%rax
|
||||
jnz 1f
|
||||
|
@ -67,6 +67,7 @@ ENTRY(setjmp)
|
||||
movq %r14,48(%rcx) /* 6; r14 */
|
||||
movq %r15,56(%rcx) /* 7; r15 */
|
||||
fnstcw 64(%rcx) /* 8; fpu cw */
|
||||
stmxcsr 68(%rcx) /* and mxcsr */
|
||||
xorq %rax,%rax
|
||||
ret
|
||||
|
||||
@ -83,6 +84,15 @@ ENTRY(__longjmp)
|
||||
popq %rsi
|
||||
popq %rdi /* jmpbuf */
|
||||
movq %rdi,%rdx
|
||||
/* Restore the mxcsr, but leave exception flags intact. */
|
||||
stmxcsr -4(%rsp)
|
||||
movl 68(%rdx),%eax
|
||||
andl $0xffffffc0,%eax
|
||||
movl -4(%rsp),%edi
|
||||
andl $0x3f,%edi
|
||||
xorl %eax,%edi
|
||||
movl %edi,-4(%rsp)
|
||||
ldmxcsr -4(%rsp)
|
||||
movq %rsi,%rax /* retval */
|
||||
movq 0(%rdx),%rcx
|
||||
movq 8(%rdx),%rbx
|
||||
@ -92,7 +102,6 @@ ENTRY(__longjmp)
|
||||
movq 40(%rdx),%r13
|
||||
movq 48(%rdx),%r14
|
||||
movq 56(%rdx),%r15
|
||||
fninit
|
||||
fldcw 64(%rdx)
|
||||
testq %rax,%rax
|
||||
jnz 1f
|
||||
|
Loading…
Reference in New Issue
Block a user