ARCH(7)

NAME
arch - Architecture-specific details

DESCRIPTION
Differences between CPU architectures and platforms supported by FreeBSD.

  Introduction
This document is a quick reference of key ABI details of FreeBSD architecture ports. For full details consult the processor-specific ABI supplement documentation.

If not explicitly mentioned, sizes are in bytes. The architecture details in this document apply to FreeBSD 10.0 and later, unless otherwise noted.

FreeBSD uses a flat address space. Variables of types unsigned long, uintptr_t, and size_t and pointers all have the same representation.

In order to maximize compatibility with future pointer integrity mechanisms, manipulations of pointers as integers should be performed via uintptr_t or intptr_t and no other types. In particular, long and ptrdiff_t should be avoided.

On some architectures, e.g. sparc64, powerpc and AIM variants of powerpc64, the kernel uses a separate address space. On other architectures, kernel and a user mode process share a single address space. The kernel is located at the highest addresses.

On each architecture, the main user mode thread's stack starts near the highest user address and grows down.

FreeBSD architecture support varies by release. This table shows the first FreeBSD release to support each architecture, and, for discontinued architectures, the final release.

Architecture | Initial Release | Final Release
alpha | 3.2 | 6.4
amd64 | 5.1
arm | 6.0
armeb | 8.0
armv6 | 10.0
arm64 | 11.0
ia64 | 5.0 | 10.x
i386 | 1.0
mips | 8.0
mipsel | 9.0
mipselhf | 12.0
mipshf | 12.0
mipsn32 | 9.0
mips64 | 9.0
mips64el | 9.0
mips64elhf | 12.0
mips64hf | 12.0
pc98 | 2.2 | 11.x
powerpc | 6.0
powerpcspe | 12.0
powerpc64 | 6.0
riscv64 | 12.0
riscv64sf | 12.0
sparc64 | 5.0

  Type sizes
All FreeBSD architectures use some variant of the ELF (see elf(5)) Application Binary Interface (ABI) for the machine processor. All supported ABIs can be divided into two groups:

ILP32
    int, long, void * types machine representations all have 4-byte size.

LP64
    int type machine representation uses 4 bytes, while long and void * are 8 bytes.
Compilers define the _LP64 symbol when compiling for an LP64 ABI.

Some machines support more that one FreeBSD ABI. Typically these are 64-bit machines, where the “native” LP64 execution environment is accompanied by the “legacy” ILP32 environment, which was historical 32-bit predecessor for 64-bit evolution. Examples are:
LP64 | ILP32 counterpart
amd64 | i386
powerpc64 | powerpc
mips64* | mips*
arm64 currently does not support execution of armv6 binaries, even if the CPU implements AArch32 execution state.

On all supported architectures:
Type | Size
short | 2
int | 4
long | sizeof(void*)
long long | 8
float | 4
double | 8
Integers are represented in two's complement. Alignment of integer and pointer types is natural, that is, the address of the variable must be congruent to zero modulo the type size. Most ILP32 ABIs, except arm, require only 4-byte alignment for 64-bit integers.

Machine-dependent type sizes:
Architecture | void * | long double | time_t
amd64 | 8 | 16 | 8
arm | 4 | 8 | 8
armeb | 4 | 8 | 8
armv6 | 4 | 8 | 8
arm64 | 8 | 16 | 8
i386 | 4 | 12 | 4
mips | 4 | 8 | 8
mipsel | 4 | 8 | 8
mipselhf | 4 | 8 | 8
mipshf | 4 | 8 | 8
mipsn32 | 4 | 8 | 8
mips64 | 8 | 8 | 8
mips64el | 8 | 8 | 8
mips64elhf | 8 | 8 | 8
mips64hf | 8 | 8 | 8
powerpc | 4 | 8 | 4
powerpcspe | 4 | 8 | 4
powerpc64 | 8 | 8 | 8
riscv64 | 8 | 16 | 8
riscv64sf | 8 | 16 | 8
sparc64 | 8 | 16 | 8

time_t is 8 bytes on all supported architectures except i386 and 32-bit variants of powerpc.

  Endianness and Char Signedness
Architecture | Endianness | char Signedness
amd64 | little | signed
arm | little | unsigned
armeb | big | unsigned
armv6 | little | unsigned
arm64 | little | unsigned
i386 | little | signed
mips | big | signed
mipsel | little | signed
mipselhf | little | signed
mipshf | big | signed
mipsn32 | big | signed
mips64 | big | signed
mips64el | little | signed
mips64elhf | little | signed
mips64hf | big | signed
powerpc | big | unsigned
powerpcspe | big | unsigned
powerpc64 | big | unsigned
riscv64 | little | signed
riscv64sf | little | signed
sparc64 | big | signed

  Page Size
Architecture | Page Sizes
amd64 | 4K, 2M, 1G
arm | 4K
armeb | 4K
armv6 | 4K, 1M
arm64 | 4K, 2M, 1G
i386 | 4K, 2M (PAE), 4M
mips | 4K
mipsel | 4K
mipselhf | 4K
mipshf | 4K
mipsn32 | 4K
mips64 | 4K
mips64el | 4K
mips64elhf | 4K
mips64hf | 4K
powerpc | 4K
powerpcspe | 4K
powerpc64 | 4K
riscv64 | 4K
riscv64sf | 4K
sparc64 | 8K

  Floating Point
Architecture | float, double | long double
amd64 | hard | hard, 80 bit
arm | soft | soft, double precision
armeb | soft | soft, double precision
armv6 | hard(1) | hard, double precision
arm64 | hard | soft, quad precision
i386 | hard | hard, 80 bit
mips | soft | identical to double
mipsel | soft | identical to double
mipselhf | hard | identical to double
mipshf | hard | identical to double
mipsn32 | soft | identical to double
mips64 | soft | identical to double
mips64el | soft | identical to double
mips64elhf | hard | identical to double
mips64hf | hard | identical to double
powerpc | hard | hard, double precision
powerpcspe | hard | hard, double precision
powerpc64 | hard | hard, double precision
riscv64 | hard | hard, double precision
riscv64sf | soft | soft, double precision
sparc64 | hard | hard, quad precision

(1) Prior to FreeBSD 11.0, armv6 used the softfp ABI even though it supported only processors with a floating point unit.

  Predefined Macros
The compiler provides a number of predefined macros. Some of these provide architecture-specific details and are explained below. Other macros, including those required by the language standard, are not included here.

The full set of predefined macros can be obtained with this command:

    cc -x c -dM -E /dev/null

Common type size and endianness macros:
Macro | Meaning
__LP64__ | 64-bit (8-byte) long and pointer, 32-bit (4-byte) int
__ILP32__ | 32-bit (4-byte) int, long and pointer
BYTE_ORDER | Either BIG_ENDIAN or LITTLE_ENDIAN.
PDP11_ENDIAN is not used on FreeBSD.

Architecture-specific macros:
Architecture | Predefined macros
amd64 | __amd64__, __x86_64__
arm | __arm__
armeb | __arm__
armv6 | __arm__, __ARM_ARCH >= 6
arm64 | __aarch64__
i386 | __i386__
mips | __mips__, __MIPSEB__, __mips_o32
mipsel | __mips__, __mips_o32
mipselhf | __mips__, __mips_o32
mipshf | __mips__, __MIPSEB__, __mips_o32
mipsn32 | __mips__, __MIPSEB__, __mips_n32
mips64 | __mips__, __MIPSEB__, __mips_n64
mips64el | __mips__, __mips_n64
mips64elhf | __mips__, __mips_n64
mips64hf | __mips__, __MIPSEB__, __mips_n64
powerpc | __powerpc__
powerpcspe | __powerpc__, __SPE__
powerpc64 | __powerpc__, __powerpc64__
riscv64 | __riscv__, __riscv64
riscv64sf | __riscv__, __riscv64
sparc64 | __sparc64__

SEE ALSO
src.conf(5), build(7)

HISTORY
An arch manual page appeared in FreeBSD 12.