https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119595

--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Created attachment 60964
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=60964&action=edit
gcc15-pr119595.patch

Here is my WIP, with emulation classes.
libgcobol still builds for 64-bit x86_64 and make check-cobol passes,
for 32-bit libgcobol there are still a few nits missing, conversion from int128
to float, _Float32 and _Float64 is missing (the last one can just use the
conversion to double already implemented) and conversions from at least
_Float128 to int128.

For the int128.h code itself I was using:
#include "int128.h"
#undef __int128
extern "C" int rand ();

uint128
getrand ()
{
  uint128 r;
  r.l = (rand () & 0xffffff) + ((rand () & 0xffffffULL) << 24) + ((rand () &
0xffffffULL) << 48);
  r.h = (rand () & 0xffffff) + ((rand () & 0xffffffULL) << 24) + ((rand () &
0xffffffULL) << 48);
  return r;
}

int
main ()
{
  for (int i = 0; i < 262072; ++i)
    {
      uint128 x = getrand ();
      uint128 y = getrand ();
      unsigned __int128 xa = x.l + (((unsigned __int128) x.h) << 64);
      unsigned __int128 ya = y.l + (((unsigned __int128) y.h) << 64);
      uint128 r = x + y;
      unsigned __int128 ra = xa + ya;
      if (r.l != (unsigned long long) ra
          || r.h != (unsigned long long) (ra >> 64))
        __builtin_abort ();
    }
  for (int i = 0; i < 262072; ++i)
    {
      uint128 x = getrand ();
      uint128 y = getrand ();
      unsigned __int128 xa = x.l + (((unsigned __int128) x.h) << 64);
      unsigned __int128 ya = y.l + (((unsigned __int128) y.h) << 64);
      uint128 r = x - y;
      unsigned __int128 ra = xa - ya;
      if (r.l != (unsigned long long) ra
          || r.h != (unsigned long long) (ra >> 64))
        __builtin_abort ();
    }
  for (int i = 0; i < 262072; ++i)
    {
      uint128 x = getrand ();
      uint128 y = getrand ();
      unsigned __int128 xa = x.l + (((unsigned __int128) x.h) << 64);
      unsigned __int128 ya = y.l + (((unsigned __int128) y.h) << 64);
      uint128 r = x * y;
      unsigned __int128 ra = xa * ya;
      if (r.l != (unsigned long long) ra
          || r.h != (unsigned long long) (ra >> 64))
        __builtin_abort ();
    }
  for (int i = 0; i < 262072; ++i)
    {
      uint128 x = getrand ();
      uint128 y = getrand ();
      switch (rand () & 7)
        {
        case 0:
        case 1:
        case 2:
        case 3: break;
        case 4: x.h = 0; break;
        case 5: y.h = 0; break;
        case 6: x.h = y.h = 0; break;
        case 7: y.h = 0; y.l = (unsigned) y.l; break;
        }
      if (y.h == 0 && y.l == 0)
        continue;
      unsigned __int128 xa = x.l + (((unsigned __int128) x.h) << 64);
      unsigned __int128 ya = y.l + (((unsigned __int128) y.h) << 64);
      uint128 r = x / y;
      unsigned __int128 ra = xa / ya;
      if (r.l != (unsigned long long) ra
          || r.h != (unsigned long long) (ra >> 64))
        __builtin_abort ();
    }
  for (int i = 0; i < 262072; ++i)
    {
      uint128 x = getrand ();
      uint128 y = getrand ();
      switch (rand () & 7)
        {
        case 0:
        case 1:
        case 2:
        case 3: break;
        case 4: x.h = 0; break;
        case 5: y.h = 0; break;
        case 6: x.h = y.h = 0; break;
        case 7: y.h = 0; y.l = (unsigned) y.l; break;
        }
      if (y.h == 0 && y.l == 0)
        continue;
      unsigned __int128 xa = x.l + (((unsigned __int128) x.h) << 64);
      unsigned __int128 ya = y.l + (((unsigned __int128) y.h) << 64);
      uint128 r = x % y;
      unsigned __int128 ra = xa % ya;
      if (r.l != (unsigned long long) ra
          || r.h != (unsigned long long) (ra >> 64))
        __builtin_abort ();
    }
  for (int i = 0; i < 262072; ++i)
    {
      uint128 x = getrand ();
      unsigned __int128 xa = x.l + (((unsigned __int128) x.h) << 64);
      uint128 r = ++x;
      unsigned __int128 ra = ++xa;
      if (r.l != (unsigned long long) ra
          || r.h != (unsigned long long) (ra >> 64))
        __builtin_abort ();
      if (x.l != (unsigned long long) xa
          || x.h != (unsigned long long) (xa >> 64))
        __builtin_abort ();
    }
  for (int i = 0; i < 262072; ++i)
    {
      uint128 x = getrand ();
      unsigned __int128 xa = x.l + (((unsigned __int128) x.h) << 64);
      uint128 r = --x;
      unsigned __int128 ra = --xa;
      if (r.l != (unsigned long long) ra
          || r.h != (unsigned long long) (ra >> 64))
        __builtin_abort ();
      if (x.l != (unsigned long long) xa
          || x.h != (unsigned long long) (xa >> 64))
        __builtin_abort ();
    }
  for (int i = 0; i < 262072; ++i)
    {
      uint128 x = getrand ();
      unsigned __int128 xa = x.l + (((unsigned __int128) x.h) << 64);
      uint128 r = x++;
      unsigned __int128 ra = xa++;
      if (r.l != (unsigned long long) ra
          || r.h != (unsigned long long) (ra >> 64))
        __builtin_abort ();
      if (x.l != (unsigned long long) xa
          || x.h != (unsigned long long) (xa >> 64))
        __builtin_abort ();
    }
  for (int i = 0; i < 262072; ++i)
    {
      uint128 x = getrand ();
      unsigned __int128 xa = x.l + (((unsigned __int128) x.h) << 64);
      uint128 r = x--;
      unsigned __int128 ra = xa--;
      if (r.l != (unsigned long long) ra
          || r.h != (unsigned long long) (ra >> 64))
        __builtin_abort ();
      if (x.l != (unsigned long long) xa
          || x.h != (unsigned long long) (xa >> 64))
        __builtin_abort ();
    }
  for (int i = 0; i < 262072; ++i)
    {
      uint128 x = getrand ();
      unsigned __int128 xa = x.l + (((unsigned __int128) x.h) << 64);
      uint128 r = -x;
      unsigned __int128 ra = -xa;
      if (r.l != (unsigned long long) ra
          || r.h != (unsigned long long) (ra >> 64))
        __builtin_abort ();
    }
  for (int i = 0; i < 262072; ++i)
    {
      uint128 x = getrand ();
      unsigned __int128 xa = x.l + (((unsigned __int128) x.h) << 64);
      uint128 r = ~x;
      unsigned __int128 ra = ~xa;
      if (r.l != (unsigned long long) ra
          || r.h != (unsigned long long) (ra >> 64))
        __builtin_abort ();
    }
  for (int i = 0; i < 262072; ++i)
    {
      uint128 x = getrand ();
      uint128 y = getrand ();
      unsigned __int128 xa = x.l + (((unsigned __int128) x.h) << 64);
      unsigned __int128 ya = y.l + (((unsigned __int128) y.h) << 64);
      uint128 r = x | y;
      unsigned __int128 ra = xa | ya;
      if (r.l != (unsigned long long) ra
          || r.h != (unsigned long long) (ra >> 64))
        __builtin_abort ();
    }
  for (int i = 0; i < 262072; ++i)
    {
      uint128 x = getrand ();
      uint128 y = getrand ();
      unsigned __int128 xa = x.l + (((unsigned __int128) x.h) << 64);
      unsigned __int128 ya = y.l + (((unsigned __int128) y.h) << 64);
      uint128 r = x & y;
      unsigned __int128 ra = xa & ya;
      if (r.l != (unsigned long long) ra
          || r.h != (unsigned long long) (ra >> 64))
        __builtin_abort ();
    }
  for (int i = 0; i < 262072; ++i)
    {
      uint128 x = getrand ();
      uint128 y = getrand ();
      unsigned __int128 xa = x.l + (((unsigned __int128) x.h) << 64);
      unsigned __int128 ya = y.l + (((unsigned __int128) y.h) << 64);
      uint128 r = x ^ y;
      unsigned __int128 ra = xa ^ ya;
      if (r.l != (unsigned long long) ra
          || r.h != (unsigned long long) (ra >> 64))
        __builtin_abort ();
    }
  for (int i = 0; i < 262072; ++i)
    {
      uint128 x = getrand ();
      int y = rand () & 127;
      unsigned __int128 xa = x.l + (((unsigned __int128) x.h) << 64);
      uint128 r = x << y;
      unsigned __int128 ra = xa << y;
      if (r.l != (unsigned long long) ra
          || r.h != (unsigned long long) (ra >> 64))
        __builtin_abort ();
    }
  for (int i = 0; i < 262072; ++i)
    {
      uint128 x = getrand ();
      int y = rand () & 127;
      unsigned __int128 xa = x.l + (((unsigned __int128) x.h) << 64);
      uint128 r = x >> y;
      unsigned __int128 ra = xa >> y;
      if (r.l != (unsigned long long) ra
          || r.h != (unsigned long long) (ra >> 64))
        __builtin_abort ();
    }
  for (int i = 0; i < 262072; ++i)
    {
      uint128 x = getrand ();
      unsigned __int128 xa = x.l + (((unsigned __int128) x.h) << 64);
      double r = (double) x;
      double ra = xa;
      if (r != ra)
        __builtin_abort ();
    }
  for (int i = 0; i < 262072; ++i)
    {
      uint128 x = getrand ();
      unsigned __int128 xa = x.l + (((unsigned __int128) x.h) << 64);
      _Float128 r = (_Float128) x;
      _Float128 ra = xa;
      if (r != ra)
        __builtin_abort ();
    }
  for (int i = 0; i < 262072; ++i)
    {
      int128 x = getrand ();
      int128 y = getrand ();
      __int128 xa = x.l + (((__int128) x.h) << 64);
      __int128 ya = y.l + (((__int128) y.h) << 64);
      int128 r = x + y;
      __int128 ra = xa + ya;
      if (r.l != (unsigned long long) ra
          || r.h != (unsigned long long) (ra >> 64))
        __builtin_abort ();
    }
  for (int i = 0; i < 262072; ++i)
    {
      int128 x = getrand ();
      int128 y = getrand ();
      __int128 xa = x.l + (((__int128) x.h) << 64);
      __int128 ya = y.l + (((__int128) y.h) << 64);
      int128 r = x - y;
      __int128 ra = xa - ya;
      if (r.l != (unsigned long long) ra
          || r.h != (unsigned long long) (ra >> 64))
        __builtin_abort ();
    }
  for (int i = 0; i < 262072; ++i)
    {
      int128 x = getrand ();
      int128 y = getrand ();
      __int128 xa = x.l + (((__int128) x.h) << 64);
      __int128 ya = y.l + (((__int128) y.h) << 64);
      int128 r = x * y;
      __int128 ra = xa * ya;
      if (r.l != (unsigned long long) ra
          || r.h != (unsigned long long) (ra >> 64))
        __builtin_abort ();
    }
  for (int i = 0; i < 262072; ++i)
    {
      int128 x = getrand ();
      int128 y = getrand ();
      switch (rand () & 15)
        {
        case 0:
        case 1:
        case 2:
        case 3:
        case 4:
        case 5:
        case 6:
        case 7: break;
        case 8: x.h = 0; break;
        case 9: x.h = -1; break;
        case 10: y.h = 0; break;
        case 11: y.h = -1; break;
        case 12: x.h = y.h = 0; break;
        case 13: x.h = y.h = -1; break;
        case 14: y.h = 0; y.l = (unsigned) y.l; break;
        case 15: y.l = (int) y.l; y.h = (long long) y.l < 0 ? -1 : 0; break;
        }
      if (y.h == 0 && y.l == 0)
        continue;
      __int128 xa = x.l + (((__int128) x.h) << 64);
      __int128 ya = y.l + (((__int128) y.h) << 64);
      int128 r = x / y;
      __int128 ra = xa / ya;
      if (r.l != (unsigned long long) ra
          || r.h != (unsigned long long) (ra >> 64))
        __builtin_abort ();
    }
  for (int i = 0; i < 262072; ++i)
    {
      int128 x = getrand ();
      int128 y = getrand ();
      switch (rand () & 15)
        {
        case 0:
        case 1:
        case 2:
        case 3:
        case 4:
        case 5:
        case 6:
        case 7: break;
        case 8: x.h = 0; break;
        case 9: x.h = -1; break;
        case 10: y.h = 0; break;
        case 11: y.h = -1; break;
        case 12: x.h = y.h = 0; break;
        case 13: x.h = y.h = -1; break;
        case 14: y.h = 0; y.l = (unsigned) y.l; break;
        case 15: y.l = (int) y.l; y.h = (long long) y.l < 0 ? -1 : 0; break;
        }
      if (y.h == 0 && y.l == 0)
        continue;
      __int128 xa = x.l + (((__int128) x.h) << 64);
      __int128 ya = y.l + (((__int128) y.h) << 64);
      int128 r = x % y;
      __int128 ra = xa % ya;
      if (r.l != (unsigned long long) ra
          || r.h != (unsigned long long) (ra >> 64))
        __builtin_abort ();
    }
  for (int i = 0; i < 262072; ++i)
    {
      int128 x = getrand ();
      __int128 xa = x.l + (((__int128) x.h) << 64);
      double r = (double) x;
      double ra = xa;
      if (r != ra)
        __builtin_abort ();
    }
  for (int i = 0; i < 262072; ++i)
    {
      int128 x = getrand ();
      __int128 xa = x.l + (((__int128) x.h) << 64);
      _Float128 r = (_Float128) x;
      _Float128 ra = xa;
      if (r != ra)
        __builtin_abort ();
    }
  for (int i = 0; i < 262072; ++i)
    {
      int128 x = getrand ();
      __int128 xa = x.l + (((__int128) x.h) << 64);
      int128 r = ++x;
      __int128 ra = ++xa;
      if (r.l != (unsigned long long) ra
          || r.h != (unsigned long long) (ra >> 64))
        __builtin_abort ();
      if (x.l != (unsigned long long) xa
          || x.h != (unsigned long long) (xa >> 64))
        __builtin_abort ();
    }
  for (int i = 0; i < 262072; ++i)
    {
      int128 x = getrand ();
      __int128 xa = x.l + (((__int128) x.h) << 64);
      int128 r = --x;
      __int128 ra = --xa;
      if (r.l != (unsigned long long) ra
          || r.h != (unsigned long long) (ra >> 64))
        __builtin_abort ();
      if (x.l != (unsigned long long) xa
          || x.h != (unsigned long long) (xa >> 64))
        __builtin_abort ();
    }
  for (int i = 0; i < 262072; ++i)
    {
      int128 x = getrand ();
      __int128 xa = x.l + (((__int128) x.h) << 64);
      int128 r = x++;
      __int128 ra = xa++;
      if (r.l != (unsigned long long) ra
          || r.h != (unsigned long long) (ra >> 64))
        __builtin_abort ();
      if (x.l != (unsigned long long) xa
          || x.h != (unsigned long long) (xa >> 64))
        __builtin_abort ();
    }
  for (int i = 0; i < 262072; ++i)
    {
      int128 x = getrand ();
      __int128 xa = x.l + (((__int128) x.h) << 64);
      int128 r = x--;
      __int128 ra = xa--;
      if (r.l != (unsigned long long) ra
          || r.h != (unsigned long long) (ra >> 64))
        __builtin_abort ();
      if (x.l != (unsigned long long) xa
          || x.h != (unsigned long long) (xa >> 64))
        __builtin_abort ();
    }
  for (int i = 0; i < 262072; ++i)
    {
      int128 x = getrand ();
      __int128 xa = x.l + (((__int128) x.h) << 64);
      int128 r = -x;
      __int128 ra = -xa;
      if (r.l != (unsigned long long) ra
          || r.h != (unsigned long long) (ra >> 64))
        __builtin_abort ();
    }
  for (int i = 0; i < 262072; ++i)
    {
      int128 x = getrand ();
      __int128 xa = x.l + (((__int128) x.h) << 64);
      int128 r = ~x;
      __int128 ra = ~xa;
      if (r.l != (unsigned long long) ra
          || r.h != (unsigned long long) (ra >> 64))
        __builtin_abort ();
    }
  for (int i = 0; i < 262072; ++i)
    {
      int128 x = getrand ();
      int128 y = getrand ();
      __int128 xa = x.l + (((__int128) x.h) << 64);
      __int128 ya = y.l + (((__int128) y.h) << 64);
      int128 r = x | y;
      __int128 ra = xa | ya;
      if (r.l != (unsigned long long) ra
          || r.h != (unsigned long long) (ra >> 64))
        __builtin_abort ();
    }
  for (int i = 0; i < 262072; ++i)
    {
      int128 x = getrand ();
      int128 y = getrand ();
      __int128 xa = x.l + (((__int128) x.h) << 64);
      __int128 ya = y.l + (((__int128) y.h) << 64);
      int128 r = x & y;
      __int128 ra = xa & ya;
      if (r.l != (unsigned long long) ra
          || r.h != (unsigned long long) (ra >> 64))
        __builtin_abort ();
    }
  for (int i = 0; i < 262072; ++i)
    {
      int128 x = getrand ();
      int128 y = getrand ();
      __int128 xa = x.l + (((__int128) x.h) << 64);
      __int128 ya = y.l + (((__int128) y.h) << 64);
      int128 r = x ^ y;
      __int128 ra = xa ^ ya;
      if (r.l != (unsigned long long) ra
          || r.h != (unsigned long long) (ra >> 64))
        __builtin_abort ();
    }
  for (int i = 0; i < 262072; ++i)
    {
      int128 x = getrand ();
      int y = rand () & 127;
      __int128 xa = x.l + (((__int128) x.h) << 64);
      int128 r = x << y;
      __int128 ra = xa << y;
      if (r.l != (unsigned long long) ra
          || r.h != (unsigned long long) (ra >> 64))
        __builtin_abort ();
    }
  for (int i = 0; i < 262072; ++i)
    {
      int128 x = getrand ();
      int y = rand () & 127;
      __int128 xa = x.l + (((__int128) x.h) << 64);
      int128 r = x >> y;
      __int128 ra = xa >> y;
      if (r.l != (unsigned long long) ra
          || r.h != (unsigned long long) (ra >> 64))
        __builtin_abort ();
    }
}

test program on x86_64 (i.e. comparing the emulation with __int128/unsigned
__int128 arithmetics).

Reply via email to