tcpdump mailing list archives
Re: [tcpdump] IEEE float decoded incorrectly(#333)
From: "David Laight" <David.Laight () ACULAB COM>
Date: Tue, 1 Oct 2013 10:03:34 +0100
from https://github.com/the-tcpdump-group/tcpdump/issues/333 details an issue where differences in arch and compiler result in different extractions of floating point objects in LMP packets. Guy discovers it has something to do with assumptions about x86 SSE. and I think we might find more expertise on the list.
You need to read the C standard as well.
The C standard certainly allows 'double' arithmetic to be done
using the 80bit x87 80bit registers without requiring that
intermediate values (even those assigned to (implicit) register
variables) being truncated to 64bits.
I suspect that is a general statement about floating point precision.
Either that or there is something that allows 'float' arithmetic be
performed as 'float' or by converting to 'double'.
This means that expression below can be calculated with 32bit, 64bit
or 80bit intermediaries depending on the whim of the implementation.
Passing an appropriate -march=xxx will allow 32bit code use SSE
instructions - but portable code shouldn't enforce it.
David
Date: Mon, 30 Sep 2013 16:31:47 -0700
Subject: Re: [tcpdump] IEEE float decoded incorrectly (#333)
So if I compile
float
xxx(float f)
{
return f*8/1000000;
}
with gcc -O2 -m32 -S, I get
xxx:
.LFB0:
.cfi_startproc
flds .LC0
fmuls 4(%esp)
fdivs .LC1
ret
.cfi_endproc
and if I compile it with gcc -O2 -S (64-bit), I get
xxx:
.LFB0:
.cfi_startproc
mulss .LC0(%rip), %xmm0
divss .LC1(%rip), %xmm0
ret
.cfi_endproc
So the 32-bit code is using the x87 instructions, using the 80-bit registers on
the stack, and doing 80-bit extended-precision arithmetic, and the 64-bit code
is using SSE instructions, and presumably doing 32-bit single-precision
arithmetic; the Intel manuals don't explicitly say that the single-precision
scalar floating point SSE instructions perform single-precision arithmetic on
their single-precision operands, but that's my guess - somebody more
knowledgable than I am about IEEE floating point could probably answer this,
and, even if it's double-precision, that's still different from
extended-precision.
I.e., it's a consequence of i686 not being guaranteed to have SSE (it was
introduced in the Pentium III, not the Pentium Pro), so that compiling for i686
means using the x86 instructions for floating point, and the x86 instructions
doing everything in 80-bit extended precision, not of the use of a union.
Sadly, the obvious choice of configuring with CFLAGS="-m32 -mfpmath=sse"
doesn't help - the compiler decides, for some reason, that I didn't really mean
-mfpmath=sse and says "hey, 32-bit x86 isn't guaranteed to have SSE, so I'm
just going to build with x86 instructions" (or, as it puts it, "warning: SSE
instruction set disabled, using 387 arithmetics [enabled by default]"), and
some other things I tried, such as -mtune=pentium3, didn't help. I'll leave it
to somebody more familiar with GCC-wrangling to figure out how to beat GCC into
producing 32-bit code that uses SSE rather than x87 floating-point
instructions, but I suspect that, if you build a 32-bit tcpdump with whatever
options those are, make check will succeed, at least on those tests.
(32-bit tcpdump is failing with some other problems as well; I'll check whether
they're also problems with 64-bit tcpdump, and see what's going on there.)
_______________________________________________
tcpdump-workers mailing list
tcpdump-workers () lists tcpdump org
https://lists.sandelman.ca/mailman/listinfo/tcpdump-workers
_______________________________________________ tcpdump-workers mailing list tcpdump-workers () lists tcpdump org https://lists.sandelman.ca/mailman/listinfo/tcpdump-workers
Current thread:
- Re: [tcpdump] IEEE float decoded incorrectly (#333) Michael Richardson (Sep 30)
- Re: [tcpdump] IEEE float decoded incorrectly(#333) David Laight (Oct 01)
- Re: [tcpdump] IEEE float decoded incorrectly (#333) Denis Ovsienko (Oct 11)
