floating point instruction anomaly — FLDZ malfunct

2019-07-13 11:40发布

问题:

I am trying to debug the problem I posted earlier here: C++ and pin tool -- very weird DOUBLE variable issue with IF statement. I tracked down the moment when the weird behavior occurred using gdb. What I found is shown in the figure below that shows the gdb screenshot displaying the disassembled code and floating pointer register values. (larger image here) Left-hand side image shows the screenshot before the highlighted FLDZ instruction is executed and the right-hand side image is after the instructions is executed. I looked up the x86 ISA and FLDZ is for loading +0.0 into ST(0). However, what I get is -nan instead of +0.0. Does anybody know why this happens? The system I am using is Intel xeon 5645 running 64-bit CentOS, but the target program I am trying to debug is 32-bit application. Also, as I mentioned in the earlier post, I tried two versions of gcc, 4.2.4 and 4.1.2 and observed the same problem. Thanks.

--added-- By the way, below is the source code.

void Router::Evaluate( )
{
  if (_id == 0) aaa++;

  if ( _partial_internal_cycles != 0 )
  {
    aaa += 12345;
    cout << "this is not a zero : " << endl;
    on = true;
  }

  _partial_internal_cycles += (double) 1.0;

  if ( _partial_internal_cycles >= (double)1.0 ) {
    _InternalStep( );
    _partial_internal_cycles -= (double)1.0;
  }

  if (GetSimTime() > 8646000 && _id == 0) cout << "aaa = " << aaa << endl;
  if ( on)
  {
    cout << "break. id = " << _id << endl;
    assert(false);
  }

}

回答1:

An exception was generated (notice the I bit is set in the stat field). As the documentation says:

If the ST(7) data register which would become the new ST(0) is not empty, both a Stack Fault and an Invalid operation exceptions are detected, setting both flags in the Status Word. The TOP register pointer in the Status Word would still be decremented and the new value in ST(0) would be the INDEFINITE NAN.

By the way, your underlying issue is because this is just the nature of floating point. It's not exact. See, for example, this gcc bug report -- and this one.



标签: c++ x87