i586 support - illegal hardware instruction

Is it true that i586 is not officially supported by Rust? When one runs the rustup.sh install script on i586 hardware it will fail. The installer does support i386, i486, i686, i786, serviced by the download of the i686 binaries.

I've heard that i586 is a superset of i386 and a subset of x86_64 so it's clearly a bit of an odd one, however I expected i386 binaries to work out fine. I edited the rustup.sh script to enable installing of i686 binaries on i586 and got them installed but sure it didn't work out; if I try to compile hello world with rustc on the i586 I get the error 'illegal hardware instruction'.

I've installed the rust i686 binaries to a VM emulation of i386 architecture and got the hello world to build fine. However when I run the compiled binary i see 'illegal hardware instruction' once again.

Can someone confirm whether i586 is supported? I assume it must be possible because Rust can run on bare metal, however I'm completely lost on getting a toolchain set up for building rust binaries to target the i586. Any guidance there would be great.

I could try and build rust sources on the target machine itself however it's only got 64mb RAM and Rust apparently takes 1.5gb to build. I could probably provide enough RAM as SWAP but given the vintage of the machine I expect compiling Rust would take a week so it's likely to be a last ditch attempt if I ever try that.

1 Like

Look at this link again: https://github.com/rust-lang/rust/blob/master/src/librustc_back/target/i686_unknown_linux_gnu.rs#L15-L19
LLVM is given the i686 target and the pentium4 CPU. I'd not expect the binary to work on i586. Now I'm not a cross-compiling expert but you could try tweaking this file and seeing if the build succeeds.

1 Like

As far as I understand it, those files are not involved when compiling the rust binaries (rustc, cargo etc). Those files define targets used by rustc to cross compile rust code. You can cross compile with rustc for additional targets without needing to add a new target definition to the rust source by supplying the additional configuration via a json file.

The Rust compiler also needs access to the rust standard library compiled against the target in order to cross compile which is where I'm at.

Some super useful information here - https://github.com/japaric/ruststrap/blob/master/1-how-to-cross-compile.md shows how easy it can be to get a set of rust tools for arm. However, substituting the target triple for relevant x86 targets isn't working out for me


$ ./configure --target=i586-unknown-linux-gnu
configure: error: unsupported target triples "i586-unknown-linux-gnu" found

I tried a bunch of different triples along the i586/i386 pc/unknown lines and nothing worked but I realised that these targets referred to makefiles in mk/cfg (here) and copied the i686-unknown-linux-gnu make file to i585-unknown-linux-gnu and edited the contents to use i585 triples instead of i686. Then issuing the above command worked.

However when I build the source it happily does it for a while (at least a couple of hours) before eventually failing

rustc: x86_64-unknown-linux-gnu/stage2/lib/rustlib/i586-unknown-linux-gnu/lib/libcore
error: Error loading target specification: Could not find specification for target "i586-unknown-linux-gnu"
make: *** [x86_64-unknown-linux-gnu/stage2/lib/rustlib/i586-unknown-linux-gnu/lib/stamp.core] Error 101

I'm missing something here, it should be as simple as supplying the right triple (as people have done for arm), unless i586 really isn't supported.

rustc knows the arm_unknown_linux_gnueabihf target. It doesn't know a i586-unknown-linux-gnu one.

Sorry I added an i586 target to that folder as well as adding a makefile. I still don't think those target files are used until rustc is cross compiling and it was only adding a new makefile that got me any progress.

[quote="rarefog, post:5, topic:2694"]
I added an i586 target to that folder
[/quote]Any chance you forgot to import the module?

Funnily enough I had been looking for some code to 'import' the targets when I found the make files. I've added the i586 triple to that list now so lets see what happens.

The problem is absolutely about P4==SSE2

See here:

or search github rust issues for sse2 illegal instruction.

I'm probably going to try building the i586 versions of rust tools (either the next stable or the current nightly) and having read a bit more on different memory allocators (jemalloc vs glibc) I'm not sure if using one or the other would be preferable on such an old linux target.

Or is jemalloc an obvious choice here?

In hindsight, going with jemalloc and nightly was probably right as the latter allows switching to system allocation with:


This one proved to be a lot harder but with previous experience it wasn't too difficult either.

The only practical obstacle is the fact the official stage0 binary doesn't know any targets apart from i686-unknown-linux-gnu.

I suggest making that an alias for i(3,4,5)86 as well meaning it would generate the same pentium4 code as before but could make stage0 completely painless. (not requiring json target specs or my workaround)

Right now, you need a new i586 target (renamed and modified i686 will do), modified (s/i686/i586/) mk and configure scripts as well as adding the new target to mod.rs (otherwise your stage1 rustc won't know about it).

Afterwards a wrapper script to tell the stage0 rustc to use the default i686 target (by sedding the target from i586 to i686) plus an additional -L flag telling the linker where to look for the generated rlibs. Once stage0 is through, the rest is completely standard and the i586 target builds natively from start to finish.

The compiler works flawlessly (tested with qemu including the resulting machine code), however as explained here, it's sometimes necessary to modify Cargo.toml of certain crates to manually add the new target.

Here's a 1.5.0 nightly from 20151007 (incl. today's cargo), meant to work on any Pentium class processor:

In my packaging thread on irlo I'm recommending teaching rustc about the i586 target, for linux at least.

1 Like

Great, i586 target being the least among the good stuff!

Interestingly, looks like the distros weren't too motivated to introduce rust sooner (cause it's perfectly clear now it's been possible all along). Some of their requirements are similar to Slackware's.

I especially like the part that could be summarised thus:

"if a working stable snapshot were provided this once it should be enough to compile the next stable and so on"


Great new Pete! I'm glad someone else is looking at this cos I really didn't know what I was doing. I ran out of steam from several days of trial and error with slow feedback since it takes so long to build rustc etc. As far as I can remember I eventually got the compiler and libstd built against i586 triple but something was still amiss. Unfortunately I can't remember what exactly I'd done as it was so long ago; I knew I would regret not posting my latest findings on here!

Anyway I'm going to try your nightly build right away on a real i586, will report back. Thanks so much!

OK so I'm having some trouble pointing the distributed rustc at the distributed i586 libraries.

As far as I know I can run the binary rustc from PeteVine's tar like so:

./rustc --sysroot /path/to/rustlib hello.rs


./rustc -L /path/to/rustlib hello.rs

However it's not working, I am told

./rustc: error while loading shared libraries: librustc_driver-bb943c5a.so: cannot open shared object file: No such file or directory

I've noticed there are several places that the libraries exist within the tar:




Have I got the right syntax and which directory should I use?

I'd start with (if DIST is where you've extracted the nigthly):

LD_LIBRARY_PATH=$DIST/lib $DIST/bin/rustc hello.rs

multirust can make this easier with

multirust update nightly-i586 --link-local $DIST

Yup, that worked! Great stuff. It takes [edit: approx 4 minutes] to compile the simple hello world on the laptop (I suspect it's the linker that is taking the most time). I'll try the binaries on a faster box later but for now I'm more than happy.

Thanks guys, you're awesome!

Yeah, nice - it was a team effort :smiling_imp:

BTW, you probably have too little memory to run bigger compilations on that box so setting up ZRAM swap plus some real disk swap might be the only way to even attempt them. (not that you should ever need to, now that, more importantly, it's possible to run rust programmes on i586)


To illustrate the problem with cargo and a custom x86 target like i586 here's a practical example building minesweeper-rs using that particular nightly.
The required changes being:

an addition of #![feature(core_intrinsics)] to lib.rs in


and changing the target.i686 part to target.i586 in the Cargo.toml from:


Thankfully this has to be done only once before reusing any problematic crates.

I'm pretty sure that's unrelated; try updating to gfx-0.7.2.

You're absolutely right, I didn't want to goad anyone into trying this and still not be able to compile! Using stable rustc also helps.