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.

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

Reply via email to