www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/1999/06/10/03:48:40

Date: Thu, 10 Jun 1999 10:45:48 +0300 (IDT)
From: Eli Zaretskii <eliz AT is DOT elta DOT co DOT il>
X-Sender: eliz AT is
To: djgpp-workers AT delorie DOT com
cc: Morten Welinder <terra AT diku DOT dk>
Subject: emu387.cc bug
Message-ID: <Pine.SUN.3.91.990610104418.17697B-100000@is>
MIME-Version: 1.0
Reply-To: djgpp-workers AT delorie DOT com

See the thread "Linking in the math library produces peculiar results"
on c.o.m.d., for the problem description.

This one was a bitch to debug (mainly because debuggers break programs
which use signals that are based on fake exceptions, like SIGFPE).  At
the end of the day, I can only reiterate what Morten said a long time
ago: mixing signed and unsigned int's is looking for trouble.  (The
`sigh' and `sigl' members of the structure used by the emulator are
declared unsigned, and the results of subtraction are tested for their
sign, see below.)

Finding such problems makes you wonder how many years can a serious
bug lie low without being fixed.  After all, addition, subtraction and
comparison, all affected by this problem, are somthing a typical FP
program does all the time, so how come this never came up?

*** src/libemu/src/emu387.c~1	Tue Jun  8 13:36:22 1999
--- src/libemu/src/emu387.cc	Wed Jun  9 19:06:00 1999
*************** static int compare(reg& a, reg& b)
*** 220,227 ****
      b.exp--;
    }
    int diff = a.exp - b.exp;
!   if (diff == 0) diff = a.sigh - b.sigh;
!   if (diff == 0) diff = a.sigl - b.sigl;
    if (a.sign == SIGN_NEG)
      diff = -diff;
    if (diff > 0) return COMP_A_GT_B;
--- 220,227 ----
      b.exp--;
    }
    int diff = a.exp - b.exp;
!   if (diff == 0) diff = a.sigh > b.sigh ? 1 : (a.sigh < b.sigh ? -1 : 0);
!   if (diff == 0) diff = a.sigl > b.sigl ? 1 : (a.sigl < b.sigl ? -1 : 0);
    if (a.sign == SIGN_NEG)
      diff = -diff;
    if (diff > 0) return COMP_A_GT_B;
*************** static void r_uadd(reg& a, reg& b, reg& 
*** 457,464 ****
  {
    reg t;
    int dif = a.exp - b.exp;
!   if (!dif) dif = a.sigh - b.sigh;
!   if (!dif) dif = a.sigl - b.sigl;
    if (dif > 0)
    {
      s = a;
--- 457,464 ----
  {
    reg t;
    int dif = a.exp - b.exp;
!   if (!dif) dif = a.sigh > b.sigh ? 1 : (a.sigh < b.sigh ? -1 : 0);
!   if (!dif) dif = a.sigl > b.sigl ? 1 : (a.sigl < b.sigl ? -1 : 0);
    if (dif > 0)
    {
      s = a;
*************** static void r_sub(reg& a, reg& b, reg& d
*** 583,591 ****
    int mdif;
    mdif = a.exp - b.exp;
    if (!mdif)
!     mdif = a.sigh - b.sigh;
    if (!mdif)
!     mdif = a.sigl - b.sigl;
  
    switch (a.sign*2 + b.sign)
    {
--- 583,591 ----
    int mdif;
    mdif = a.exp - b.exp;
    if (!mdif)
!     mdif = a.sigh > b.sigh ? 1 : (a.sigh < b.sigh ? -1 : 0);
    if (!mdif)
!     mdif = a.sigl > b.sigl ? 1 : (a.sigl < b.sigl ? -1 : 0);
  
    switch (a.sign*2 + b.sign)
    {

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019