Many of the Rust Compilers target definitions use "p270:32:32-p271:32:32-p272:64:64" inside the data-layout - what does it mean?

Viewed 156

A few days ago, the basic understanding of the data layout strings of Rust compiler, or to be more specific, the underlying LLVM, was already mostly resolved on Stack Overflow. Unfortunately, one thing is still unclear.

Many Rust compiler targets include p270:32:32-p271:32:32-p272:64:64 inside their data layout string. Examples are i686-unknown-uefi, x86_64-uwp_windows-msvc, x86_64-unknown-uefi, x86_64-unknown-linux_gnu, x86_64-fuchsia, or 86_64-apple-darwin.

(These targets can be found here https://github.com/rust-lang/rust/tree/1.52.1/compiler/rustc_target/src/spec.)

The LLVM Language Reference explains:

p[n]:<size>:<abi>:<pref>:<idx> This specifies the size of a pointer and its and erred alignments for address space n. The fourth parameter is a size of index that used for address calculation. If not specified, the default index size is equal to the pointer size. All sizes are in bits. The address space, n, is optional, and if not specified, denotes the default address space 0. The value of n must be in the range [1,2^23).

I don't understand this. What is so special about p270 to p272? To which "address space" are they referring to?

1 Answers

These data layout strings were commited to Rust on 2020-01-07. The commit message says "Update data layouts to include new X86 address spaces". After more research I found that the underlying functionality was merged into LLVM in 2019. These new address spaces are MSVC's __ptr32, __ptr64, __sptr, and __uptr extensions [1].

Quote from the LLVM discussion:

The numbers 270-272 are more or less arbitrary; I picked them because they're near 256-258, which are the current existing address spaces.

If you look into X86.h in LLVM's source code, one can see that this number is used as identifier and is chosen at will but not for technical reasons.

Related