aarch64 ilp32

ilp32 is an ABI to run on v8 64-bit-only cores. Thus it has the same basic properties as aarch32 or armv7 code (ints, long and pointers are 32bit), but only uses the armv8 A64 instruction set. It is exactly the same concept as x32on the x86 architecture.


The main reason why this is useful is different from x86. On x86 there are noticeable performance improvements from having many more registers available, as well as reduced memory consumption from halving the pointer size. On 64-bit arm whilst there are more registers in aarch64-ilp32, there wasn't massive starvation in aarch32/armv7 so it doesn't really make much difference. There is a reduced memory footprint in pointer-heavy applications, which can produce faster code due to cache alignment/moving less data. Aarch32 and ilp32 should be the same in this regard, but not much testing has been done.

The most prominent use-case is enabling the running of existing 32-bit codebases on 64-bit only hardware, without making any changes to the code to properly deal with the different type sizes. This is a very weak reason for a whole new ABI, but it is technically possible if people wish to do the work. (Sadly there is proprietary software like this where making a whole new ABI is easier than fixing the codebase).

Names and configs

GNU name ('triplet'):

(Early patches used aarch64_ilp32-linux-gnu but that is now deprecated)

Debian architecture name:


Loader path:

A big-endian variant has:

GNU name:

(Early patches used aarch64_be-linux-gnu_ilp32, which is now deprecated)

Loader path:


(Last updated 2017-07-07)

Patches exist for core components (binutils, gcc, glibc, kernel, llvm, gdb), and are upstreamed for binutils and gcc, but upstream configury only works for building an lp64 binutils/gcc/glibc, with an ilp32 multilib (except binutils which can now build proper ilp32-only as well). gcc and glibc configury updates are below. glibc upstreaming is dependent on kernel support being upstreamed. The arm64 kernel maintainer is not convinced ILP32 is worth merging and maintaining, so it is currently on-hold to see how much real-world usage materialises.

There is an openSuse build for the old triplet: http://download.opensuse.org/ports/update/13.2/aarch64_ilp32/

There is a Debian repository (final triplet) containing a cross-toolchain and base image packages (for Debian 9/stretch). This is not yet complete, containing 35 packages . https://wiki.debian.org/Arm64ilp32Port







Obsolete patches:

kernel recipie

git clone https://github.com/norov/linux.git cd linux/ git checkout ilp32-4.12 # bd1f3da26a9c73fe537490e6faeb96ccf3bf7b2c

make ARCH=arm64 defconfig echo CONFIG_ARM64_ILP32=y >> .config make ARCH=arm64 olddefconfig make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j16 Image.gz

qemu test

qemu-system-aarch64 \

$ arch-test arm64 arm64ilp32 armel armhf

OpenEmbedded ILP32 build

Continous Integration

Pre-Built Images

The platform images linked below are engineering builds, meant for interested developers to evaluate, and for continuous integration purposes.


Build from Source

git clone https://git.linaro.org/openembedded/jenkins-setup.git
cd jenkins-setup
MACHINE=hikey-ilp32 bash -x init-and-build.sh -a armv8 -g 7.1 linaro-image-minimal-ltp

Note: For reference, CI job configuration can be found here: https://git.linaro.org/ci/job/configs.git/tree/openembedded-armv8-ilp32.yaml

LEAP ILP32 (Centos-based) build


Platform/arm64-ilp32 (last modified 2017-09-21 07:47:14)