www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - DMD Backend: Deciding instructions to use/avoid?

reply "Nick Sabalausky" <a a.a> writes:
I'm working with Jacob to try to resolve an issue where D programs compiled 
on his Ubuntu box (in 32-bit/32-bit) error out on my Ubuntu box with 
"Illegal instruction". At first we thought it was because my OS was an older 
version than his. But he tried compiling on an older OS than mine and it 
still didn't work. So now I'm wondering if it may really be just like the 
message seems to imply: an illegal CPU instruction.

So my main question: Does DMD do anything like, say, detecting the CPU at 
compile time and then enabling instructions only available on that CPU and 
up? Or does it do anything like always assuming the target CPU has SSE2? 
Anything like that that could cause differences between our CPUs to result 
in object code that will work on one of the CPUs, but not the other? FWIW, 
the CPU on my linux box is i686, so it's not like I'm on some 
super-ultra-old i586, or anything like that. 
Jun 04 2011
next sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2011-06-04 11:36, Nick Sabalausky wrote:
 I'm working with Jacob to try to resolve an issue where D programs compiled
 on his Ubuntu box (in 32-bit/32-bit) error out on my Ubuntu box with
 "Illegal instruction". At first we thought it was because my OS was an older
 version than his. But he tried compiling on an older OS than mine and it
 still didn't work. So now I'm wondering if it may really be just like the
 message seems to imply: an illegal CPU instruction.

Actually, the Ubuntu 6.06 box is 64bit. Don't remember if I compiled with a 32bit or 64bit DMD. But anyway, it works on my Ubuntu 11.04 box that is 32bit.
 So my main question: Does DMD do anything like, say, detecting the CPU at
 compile time and then enabling instructions only available on that CPU and
 up? Or does it do anything like always assuming the target CPU has SSE2?
 Anything like that that could cause differences between our CPUs to result
 in object code that will work on one of the CPUs, but not the other? FWIW,
 the CPU on my linux box is i686, so it's not like I'm on some
 super-ultra-old i586, or anything like that.

I'm having an Intel Core 2 Duo. Don't know if it helps but when I run the pre-compiled DMD on the 6.06 box I get an errors message similar to: "Floating point exception". -- /Jacob Carlborg
Jun 04 2011
parent Dan Olson <zans.is.for.cans yahoo.com> writes:
Jacob Carlborg <doob me.com> writes:
 I'm having an Intel Core 2 Duo. Don't know if it helps but when I run
 the pre-compiled DMD on the 6.06 box I get an errors message similar
 to: "Floating point exception".

A long shot, but this sounds like a problem I hit trying to run some C code binaries on an older system. Try googling for FPE and gnuhash. When binaries are built with a newer ld option --hash-style=gnu, running on systems with an older loader with fail wth an FPE. For backwards compatability you have to use --hash-style=both or sysv. I don't use D on linux and don't know how it passes options to ld. You can use objdump to show if a .gnu.hash section is being used. And on older systems, the man page for ld won't list --hash-style. -- Dan
Jun 05 2011
prev sibling next sibling parent reply Bernard Helyer <b.helyer gmail.com> writes:
If you run the program in GDB, can you disassemble when the error is 
given? That may give you the instruction the kernel is assasinating your 
process for.
Jun 04 2011
next sibling parent "Nick Sabalausky" <a a.a> writes:
"Bernard Helyer" <b.helyer gmail.com> wrote in message 
news:isdgdc$m3a$1 digitalmars.com...
 If you run the program in GDB, can you disassemble when the error is
 given? That may give you the instruction the kernel is assasinating your
 process for.

I can try that if anyone can help walk me through it or at least point me to a good beginner's tutorial for gdb. I never use commandline debuggers, and I've never even touched gdb, so I don't have the slightest clue how to use it.
Jun 09 2011
prev sibling parent reply Andrew Wiley <wiley.andrew.j gmail.com> writes:
--0016369204b3accc3804a55711f8
Content-Type: text/plain; charset=ISO-8859-1

On Thu, Jun 9, 2011 at 5:58 PM, Nick Sabalausky <a a.a> wrote:

 "Bernard Helyer" <b.helyer gmail.com> wrote in message
 news:isdgdc$m3a$1 digitalmars.com...
 If you run the program in GDB, can you disassemble when the error is
 given? That may give you the instruction the kernel is assasinating your
 process for.

I can try that if anyone can help walk me through it or at least point me to a good beginner's tutorial for gdb. I never use commandline debuggers, and I've never even touched gdb, so I don't have the slightest clue how to use it. The short version is to run `gdb yourapp` which will get you into the GDB

shell when it hits the bad instruction, and you should type `disass` to view the assembly code of the current function. There will be a pointer (->, I think) pointing to the current instruction in the listing. You can find GDB basics at http://www.cs.cmu.edu/~gilpin/tutorial/ although that tutorial doesn't include `disass`. I mostly learned it by firing it up and typing `help` :D --0016369204b3accc3804a55711f8 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable <div class=3D"gmail_quote">On Thu, Jun 9, 2011 at 5:58 PM, Nick Sabalausky = <span dir=3D"ltr">&lt;a a.a&gt;</span> wrote:<br><blockquote class=3D"gmail= _quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:= 1ex;"> &quot;Bernard Helyer&quot; &lt;<a href=3D"mailto:b.helyer gmail.com">b.hely= er gmail.com</a>&gt; wrote in message<br> news:isdgdc$m3a$1 digitalmars.com...<br> <div class=3D"im">&gt; If you run the program in GDB, can you disassemble w= hen the error is<br> &gt; given? That may give you the instruction the kernel is assasinating yo= ur<br> &gt; process for.<br> <br> </div>I can try that if anyone can help walk me through it or at least poin= t me to<br> a good beginner&#39;s tutorial for gdb. I never use commandline debuggers, = and<br> I&#39;ve never even touched gdb, so I don&#39;t have the slightest clue how= to use<br> it.<br> <br> <br> </blockquote></div>The short version is to run `gdb yourapp` which will get= you into the GDB shell. Then `run` to actually start the app. It will halt= and return to the shell when it hits the bad instruction, and you should t= ype `disass` to view the assembly code of the current function. There will = be a pointer (-&gt;, I think) pointing to the current instruction in the li= sting.<div> You can find GDB basics at=A0<a href=3D"http://www.cs.cmu.edu/~gilpin/tutor= ial/">http://www.cs.cmu.edu/~gilpin/tutorial/</a>=A0although that tutorial = doesn&#39;t include `disass`. I mostly learned it by firing it up and typin= g `help` =A0:D</div> --0016369204b3accc3804a55711f8--
Jun 10 2011
parent "Nick Sabalausky" <a a.a> writes:
"Andrew Wiley" <wiley.andrew.j gmail.com> wrote in message 
news:mailman.762.1307693296.14074.digitalmars-d-learn puremagic.com...
 On Thu, Jun 9, 2011 at 5:58 PM, Nick Sabalausky <a a.a> wrote:

 "Bernard Helyer" <b.helyer gmail.com> wrote in message
 news:isdgdc$m3a$1 digitalmars.com...
 If you run the program in GDB, can you disassemble when the error is
 given? That may give you the instruction the kernel is assasinating 
 your
 process for.

I can try that if anyone can help walk me through it or at least point me to a good beginner's tutorial for gdb. I never use commandline debuggers, and I've never even touched gdb, so I don't have the slightest clue how to use it. The short version is to run `gdb yourapp` which will get you into the GDB

the shell when it hits the bad instruction, and you should type `disass` to view the assembly code of the current function. There will be a pointer (->, I think) pointing to the current instruction in the listing. You can find GDB basics at http://www.cs.cmu.edu/~gilpin/tutorial/ although that tutorial doesn't include `disass`. I mostly learned it by firing it up and typing `help` :D

Thanks. This is what I get: $ gdb ./dvm-0.2.0-linux-32 GNU gdb (GDB) 7.1-ubuntu Copyright (C) 2010 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "i486-linux-gnu". For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>... Reading symbols from /home/nick/dev/d/tool/dvm-0.2.0-linux-32...(no debugging symbols found)...done. (gdb) run Starting program: /home/nick/dev/d/tool/dvm-0.2.0-linux-32 [Thread debugging using libthread_db enabled] Program received signal SIGILL, Illegal instruction. 0x080bccdb in _D5tango4core4sync6Atomic31__T13memoryBarrierVb1Vb0Vi0Vb0Z13memoryBarrierFZv () (gdb) disass Dump of assembler code for function _D5tango4core4sync6Atomic31__T13memoryBarrierVb1Vb0Vi0Vb0Z13memoryBarrierFZv: 0x080bccd8 <+0>: push %ebp 0x080bccd9 <+1>: mov %esp,%ebp => 0x080bccdb <+3>: lfence 0x080bccde <+6>: pop %ebp 0x080bccdf <+7>: ret End of assembler dump. (gdb) So apperently it's a memory fence instruction. I don't have a clue what my CPU supports in that area. Oh, and apperently it's inside Tango, so maybe I'll bring this up over there. But I have no idea if that's something that Tango has in common with druntime or not.
Jun 11 2011
prev sibling next sibling parent reply Don <nospam nospam.com> writes:
Nick Sabalausky wrote:
 So my main question: Does DMD do anything like, say, detecting the CPU at 
 compile time and then enabling instructions only available on that CPU and 
 up? Or does it do anything like always assuming the target CPU has SSE2? 
 Anything like that that could cause differences between our CPUs to result 
 in object code that will work on one of the CPUs, but not the other? FWIW, 
 the CPU on my linux box is i686, so it's not like I'm on some 
 super-ultra-old i586, or anything like that. 

DMD itself doesn't, but the array operations do. The DMD backend is ancient, and generates code for original Pentiums (+ 64 bit equivalents of the same instructions).
Jun 08 2011
parent reply "Nick Sabalausky" <a a.a> writes:
"Don" <nospam nospam.com> wrote in message 
news:isoh6c$15jb$1 digitalmars.com...
 Nick Sabalausky wrote:
 So my main question: Does DMD do anything like, say, detecting the CPU at 
 compile time and then enabling instructions only available on that CPU 
 and up? Or does it do anything like always assuming the target CPU has 
 SSE2? Anything like that that could cause differences between our CPUs to 
 result in object code that will work on one of the CPUs, but not the 
 other? FWIW, the CPU on my linux box is i686, so it's not like I'm on 
 some super-ultra-old i586, or anything like that.

DMD itself doesn't, but the array operations do. The DMD backend is ancient, and generates code for original Pentiums (+ 64 bit equivalents of the same instructions).

Is there any way to force the array operations down to a certain level? Or even better yet, have them detect the CPU at startup and then use the appropriate version?
Jun 08 2011
parent reply "Nick Sabalausky" <a a.a> writes:
"Nick Sabalausky" <a a.a> wrote in message 
news:isoltk$1ehd$1 digitalmars.com...
 "Don" <nospam nospam.com> wrote in message 
 news:isoh6c$15jb$1 digitalmars.com...
 Nick Sabalausky wrote:
 So my main question: Does DMD do anything like, say, detecting the CPU 
 at compile time and then enabling instructions only available on that 
 CPU and up? Or does it do anything like always assuming the target CPU 
 has SSE2? Anything like that that could cause differences between our 
 CPUs to result in object code that will work on one of the CPUs, but not 
 the other? FWIW, the CPU on my linux box is i686, so it's not like I'm 
 on some super-ultra-old i586, or anything like that.

DMD itself doesn't, but the array operations do. The DMD backend is ancient, and generates code for original Pentiums (+ 64 bit equivalents of the same instructions).

Is there any way to force the array operations down to a certain level? Or even better yet, have them detect the CPU at startup and then use the appropriate version?

It would be a bad thing if we can't use an SSE2 CPU to compile a binary that'll work on a non-SSE2 machine.
Jun 09 2011
parent Don <nospam nospam.com> writes:
Nick Sabalausky wrote:
 "Nick Sabalausky" <a a.a> wrote in message 
 news:isoltk$1ehd$1 digitalmars.com...
 "Don" <nospam nospam.com> wrote in message 
 news:isoh6c$15jb$1 digitalmars.com...
 Nick Sabalausky wrote:
 So my main question: Does DMD do anything like, say, detecting the CPU 
 at compile time and then enabling instructions only available on that 
 CPU and up? Or does it do anything like always assuming the target CPU 
 has SSE2? Anything like that that could cause differences between our 
 CPUs to result in object code that will work on one of the CPUs, but not 
 the other? FWIW, the CPU on my linux box is i686, so it's not like I'm 
 on some super-ultra-old i586, or anything like that.

ancient, and generates code for original Pentiums (+ 64 bit equivalents of the same instructions).

even better yet, have them detect the CPU at startup and then use the appropriate version?


The runtime detects the CPU type at startup, and uses SSE/SSE2 if available, otherwise falls back to x87. The 64-bit DMD doesn't use SSE2 at all, yet.
 It would be a bad thing if we can't use an SSE2 CPU to compile a binary 
 that'll work on a non-SSE2 machine.

Jun 10 2011
prev sibling parent Johann MacDonagh <johann.macdonagh..no spam..gmail.com> writes:
On 6/4/2011 5:36 AM, Nick Sabalausky wrote:
 I'm working with Jacob to try to resolve an issue where D programs compiled
 on his Ubuntu box (in 32-bit/32-bit) error out on my Ubuntu box with
 "Illegal instruction". At first we thought it was because my OS was an older
 version than his. But he tried compiling on an older OS than mine and it
 still didn't work. So now I'm wondering if it may really be just like the
 message seems to imply: an illegal CPU instruction.

 So my main question: Does DMD do anything like, say, detecting the CPU at
 compile time and then enabling instructions only available on that CPU and
 up? Or does it do anything like always assuming the target CPU has SSE2?
 Anything like that that could cause differences between our CPUs to result
 in object code that will work on one of the CPUs, but not the other? FWIW,
 the CPU on my linux box is i686, so it's not like I'm on some
 super-ultra-old i586, or anything like that.

Couldn't you run it in GDB and find the instruction it doesn't like? I'm assuming it's a FPU instruction. Might help you discover where the missing check should be.
Jun 08 2011