X32 ABI support


I am working on x32 ABI support, which gives access to 16 registers of x86_64 architecture (compared to 8 registers of i386) while keeping the pointer size as 32 bits, saving memory. Is anyone interested?

I will write my progress on this RFC issue.


Wouldn’t it make more sense to reduce the size of (some) Rust pointers instead, so that the binaries still use the x86_64 ABI (which is much more widely supported than x32), but avoid most of the memory bloat from general 64-bit pointers?

This is what OpenJDK does.


The Oracle JVM uses shortened 32 bit indexes instead of 64 bit pointers in several cases, to reduce the size of pointer-heavy data structures, this allows to pack more data in memory and speeds up the programs a little ( https://wiki.openjdk.java.net/display/HotSpot/CompressedOops ). But doing this transparently in a system language could be harder.


Happy to help landing this target in-tree (i.e. make it a built-in target) by providing advice on how to proceed. I meant to write a guide about this topic and post it to the forge but haven’t had a chance yet. This post may help in the meantime though.


Am I right in thinking that a musl-libc based x32 Rust executable would run on any Linux kernel that has had syscall.x32=y set on boot? That makes it pretty useful for some use-cases even where there isn’t x32 support from distributions.


I don’t think so. x32 musl will still depend on x32 system calls. Also, musl support for x32 seems to be experimental.


The kernel needs CONFIG_X86_X32=y to have the syscalls.


And CONFIG_X86_X32_DISABLED=n or syscall.x32=y on the cmdline.


not related to X32, but a similar motivation - X32 is potentially interesting to me for the same reason that I want this;

in the transition from 32-64bits, we have the same issues as historically in the transition from 16 to 32 bits: an intermediate range where doubling the everywhere bits is overkill.

e.g. working on a 16mb machine, with vectors of 4 byte elements, 32bit indices are sufficient. (infact it is very unlikely any real application would fill the entirety of 16mb with a char array.)

This doesn’t achieve the pointer-compression suggested above, but is very much in the same spirit; I am trying to point out there is a case where you want 64bit addressing/64bit ALU, but 32bit indices (which, with some alignment scaling, are going to achieve sufficient range).

Also I would definitely be interested in compressed pointers for the same purpose.

But doing this transparently in a system language could be harder.

indeed it would not be as transparent as Java; but the advertisement as “A systems language” includes domains where the user is very likely to have to think about this crossover size issue, whether its the 8mb game console target, or some tiny embedded controller. Perhaps without needing ‘compressed pointers’ across the board, a lot of cases could be covered by extending the standard library collections (Vec, HashMap etc) to handling 32 or 64bit indices (default to the address size, but offer the option to over-ride). “i want a hash map, but I know upfront there wont be more than 2^32 entries”. There are even use cases for 16bit indices IMO (much of what I did in real world projects has involved clustering mesh such that 16 or 8bit indices could be within cache-sized chunks despite it being a 32bit target)