Page 1 of 1

All SSE2 instructions generate floating-point error

Posted: Sun Feb 07, 2016 11:13 am
by mariuszp
I initialise the FPU using the followig code on my OS:

Code: Select all

fpuInit:
	finit
	mov	rax,	cr0
	and	ax,	0xFFFB
	or	ax,	0x2
	mov	cr0,	rax
	mov	rax,	cr4
	or	ax,	(3 << 9)
	mov	cr4,	rax
	ret
This is based on the wiki page about SSE (http://wiki.osdev.org/SSE)

I use FXSAVE/FXRSTOR to preserve the state of FPU registers per-thread. All processes run as expected, until they try to use any SSE2 instruction. For example, the following C code:

Code: Select all

int main()
{
	float a = 0.5;
	float b = 0.4;
	float c = a + b / 0.2;
	printf("fpu OK\n");
	return 0;
};
does not print "fpu OK", but instead throws the SIMD floating-point exceptions (19), which causes my OS to send the SIGFPE signal to it.

This is running on x86_64. The relevant assembly produced by the compiler is as follows:

Code: Select all

	movss	-12(%rbp), %xmm1
	cvtps2pd	%xmm1, %xmm1
	movss	-8(%rbp), %xmm0
	cvtps2pd	%xmm0, %xmm0
	movsd	.LC2(%rip), %xmm2
	divsd	%xmm2, %xmm0
	addsd	%xmm1, %xmm0
	unpcklpd	%xmm0, %xmm0
	cvtpd2ps	%xmm0, %xmm3
	movss	%xmm3, -4(%rbp)
What could be causing this?

Re: All SSE2 instructions generate floating-point error

Posted: Sun Feb 07, 2016 11:37 am
by iansjack
What does the exception information tell you?

Re: All SSE2 instructions generate floating-point error

Posted: Sun Feb 07, 2016 12:16 pm
by mariuszp
In the MXCSR register, bit 5 ("Precision Flag") is set when the exception is received, and no other flags are set.
That is, the value is 0x20.

Re: All SSE2 instructions generate floating-point error

Posted: Sun Feb 07, 2016 12:29 pm
by stlw
What is the value of MXCSR, in particular exceptions mask bits.
Precision loss is very common and will fire you on almost every instruction unless masked.

Re: All SSE2 instructions generate floating-point error

Posted: Sun Feb 07, 2016 12:49 pm
by mariuszp
Ah, I got my C library to set the Flush To Zero and Precision Mask bits of the MXCSR and it all works now.