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).