Thread overview
GDC 11.3/12.1 -m32: Illegal instruction (core dumped) [SSE, Pentium III]
May 13, 2022
kdevel
May 13, 2022
rikki cattermole
May 13, 2022
kdevel
May 13, 2022
Iain Buclaw
May 13, 2022
kdevel
May 13, 2022
kdevel
May 13, 2022
max haughton
May 13, 2022

After I encountered illegal instruction signals whith dmd-generated code [1] I eventually bootstrapped GDC 11.3 and 12.1. Unfortunately the problem persists. A statically linked program receives SIGILL, as gdb says this happens here:

(gdb) bt
#0  0x080b7e8a in rt.minfo.ModuleGroup.__ctor() ()
#1  0x080b0095 in _d_dso_registry ()
#2  0x0805dbdc in gdc.dso_ctor ()
#3  0x08103290 in __libc_csu_init ()
#4  0x08102d34 in __libc_start_main ()
#5  0x0804c51d in _start ()
(gdb) disass
Dump of assembler code for function _D2rt5minfo11ModuleGroup6__ctorMFNbNcNiAyPS6object10ModuleInfoZSQCkQCkQCh:
   0x080b7e80 <+0>:	mov    0x4(%esp),%eax
   0x080b7e84 <+4>:	movq   0x8(%esp),%xmm0
=> 0x080b7e8a <+10>:	movq   %xmm0,(%eax)
   0x080b7e8e <+14>:	ret

I have checked the build log: The D runtime has been compiled with -m32. According to GCC's documentation [2] the option -m32 means “The -m32 option [...] generates code that runs on any i386 system.” Obviously this is not the case:

module structtest;

struct MyStruct {
   int [] i;
   this (int [] i)
   {
      this.i = i;
   }
}

compiling with gdc -m32 -O2 -c and inspecting the generated code with objdump gives this:

[...]
Disassembly of section .text.ref structtest.MyStruct structtest.MyStruct.__ctor(int[]):

00000000 <ref structtest.MyStruct structtest.MyStruct.__ctor(int[])>:
   0:   8b 44 24 04             mov    0x4(%esp),%eax
   4:   f3 0f 7e 44 24 08       movq   0x8(%esp),%xmm0
   a:   66 0f d6 00             movq   %xmm0,(%eax)
   e:   c3                      ret
[...]

Compiling with gdc -m32 -march=pentium3 -O2 -c generated the expected code:

00000080 <ref structtest.MyStruct structtest.MyStruct.__ctor(int[])>:
  80:   8b 44 24 04             mov    0x4(%esp),%eax
  84:   8b 54 24 08             mov    0x8(%esp),%edx
  88:   8b 4c 24 0c             mov    0xc(%esp),%ecx
  8c:   89 10                   mov    %edx,(%eax)
  8e:   89 48 04                mov    %ecx,0x4(%eax)
  91:   c3                      ret

But this does of course not change the code which is already compiled into libgphobos.a ...

[1] http://forum.dlang.org/thread/suwlbzlgqdylfauwgteu@forum.dlang.org
DMD 2.090.1: SIGILL, Illegal instruction on (ahem) intel Pentium III
[2] https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html

May 13, 2022
On 13/05/2022 3:33 PM, kdevel wrote:
> I have checked the build log: The D runtime has been compiled with `-m32`. According to GCC's documentation [2] the option `-m32` means “The -m32 option [...] generates code that runs on any i386 system.” Obviously this is not the case:

Newer x86 machines have the SSE2 extension.

Which was first introduced on Pentium 4's and has been in place on pretty much all x86 chips since 2003. So emitting it as a default is fine.

Unfortunately I think you're stuck building your own runtime (and possibly compiler) if you want D to run on such an old cpu like this (said by someone who has a P3 and a P4 sitting beside me).
May 13, 2022

On Friday, 13 May 2022 at 03:33:24 UTC, kdevel wrote:

>

After I encountered illegal instruction signals whith dmd-generated code [1] I eventually bootstrapped GDC 11.3 and 12.1. Unfortunately the problem persists. A statically linked program receives SIGILL, as gdb says this happens here:

[...]

Based on 30 seconds on compiler explorer it looks like GCC started emitting movq around GCC 10.1-ish

May 13, 2022
On Friday, 13 May 2022 at 04:13:44 UTC, rikki cattermole wrote:
[...]
> Unfortunately I think you're stuck building your own runtime (and possibly compiler) if you want D to run on such an old cpu like this (said by someone who has a P3 and a P4 sitting beside me).

I am rebuilding GCC with --with-arch_32=pentium3 now [3].

[3] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95661
    Bug 95661 - Code built with -m32 uses SSE2 instructions
May 13, 2022
On Friday, 13 May 2022 at 05:56:23 UTC, kdevel wrote:
> On Friday, 13 May 2022 at 04:13:44 UTC, rikki cattermole wrote:
> [...]
>> Unfortunately I think you're stuck building your own runtime (and possibly compiler) if you want D to run on such an old cpu like this (said by someone who has a P3 and a P4 sitting beside me).
>
> I am rebuilding GCC with --with-arch_32=pentium3 now [3].
>
> [3] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95661
>     Bug 95661 - Code built with -m32 uses SSE2 instructions

Reminds me of another GCC bug I encountered on Solaris/Pentium4 that appears to have been introduced around the 10.x development as well.

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103015
May 13, 2022
On Friday, 13 May 2022 at 05:56:23 UTC, kdevel wrote:
> [...]
>
> I am rebuilding GCC with --with-arch_32=pentium3 now [3].

The option is spelled

   --with-arch-32=pentium3

and the build compiler can be checked with

   $ gcc -m64 -Q --help=target |egrep -i 'math|arch'
     -march=                     		x86-64     <---
     -mfancy-math-387            		[enabled]
     -mfpmath=                   		sse
     -mno-fancy-math-387         		[disabled]
     Valid arguments to -mfpmath=:
     Known valid arguments for -march= option:

and

   $ gcc -m32 -Q --help=target |egrep -i 'math|arch'
     -march=                     		pentium3   <-----
     -mfancy-math-387            		[enabled]
     -mfpmath=                   		387
     -mno-fancy-math-387         		[disabled]
     Valid arguments to -mfpmath=:
     Known valid arguments for -march= option:


May 13, 2022
On Friday, 13 May 2022 at 09:22:40 UTC, Iain Buclaw wrote:
[...]
>> [3] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95661
>>     Bug 95661 - Code built with -m32 uses SSE2 instructions
>
> Reminds me of another GCC bug I encountered on Solaris/Pentium4 that appears to have been introduced around the 10.x development as well.
>
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103015

And this reminds me of

   https://issues.dlang.org/show_bug.cgi?id=12268
   Issue 12268 - full static linking does not work, unresolved __tls_get_addr
   (2014)

   http://forum.dlang.org/thread/vewesvrimtnmcrtygjam@forum.dlang.org
   dmd (v2.075.0): fully static linking: undefined reference to `__tls_get_addr'
   (2017)

I don't know if this is the right way to work around this issue:

   #define _GNU_SOURCE
   #include <dlfcn.h>

   __attribute__((force_align_arg_pointer)) void *__tls_get_addr (void *ti)
   {
      void *(*tga)(void*) = dlsym(RTLD_NEXT, "__tls_get_addr");
      if (! tga)
         return ti;
      return tga(ti);
   }