Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
ARCH(7) 		 Miscellaneous Information Manual		 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 architec-
     ture 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 13.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  mecha-
     nisms,  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., 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 currently
     supported CPU architectures along with the first FreeBSD release to support
     each architecture.

	   Architecture    Initial Release
	   aarch64	   11.0
	   amd64	   5.1
	   armv7	   12.0
	   powerpc64	   9.0
	   powerpc64le	   13.0
	   riscv64	   12.0

     Discontinued architectures are shown in the following table.

	   Architecture    Initial Release    Final Release
	   alpha	   3.2		      6.4
	   arm		   6.0		      12.4
	   armeb	   8.0		      11.4
	   armv6	   10.0 	      14.x
	   ia64 	   5.0		      10.4
	   i386 	   1.0		      14.x
	   mips 	   8.0		      13.5
	   mipsel	   9.0		      13.5
	   mipselhf	   12.0 	      13.5
	   mipshf	   12.0 	      13.5
	   mipsn32	   9.0		      13.5
	   mips64	   9.0		      13.5
	   mips64el	   9.0		      13.5
	   mips64elhf	   12.0 	      13.5
	   mips64hf	   12.0 	      13.5
	   pc98 	   2.2		      11.4
	   powerpc	   6.0		      14.x
	   powerpcspe	   12.0 	      14.x
	   riscv64sf	   12.0 	      13.5
	   sparc64	   5.0		      12.4

   Type sizes
     All FreeBSD  architectures  use  some  variant  of  the  ELF  (see  elf(5))
     Application  Binary  Interface  (ABI)  for the machine processor.	All sup-
     ported 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.

     Some  machines  support  more  than  one  FreeBSD ABI.  Typically these are
     64-bit machines, where the "native" LP64 execution environment is	accompa-
     nied  by  the  "legacy"  ILP32 environment, which was the historical 32-bit
     predecessor for 64-bit evolution.	Examples are:

	   LP64 	ILP32 counterpart
	   amd64	i386
	   powerpc64	powerpc
	   aarch64	armv7

     aarch64 will support execution of armv7  binaries	if  the  CPU  implements
     AArch32  execution  state.   Binaries  targeting  armv6  and earlier are no
     longer supported by FreeBSD.

     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 con-
     gruent  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
	   aarch64	   8	     16 	    8
	   amd64	   8	     16 	    8
	   armv7	   4	     8		    8
	   i386 	   4	     12 	    4
	   powerpc	   4	     8		    8
	   powerpcspe	   4	     8		    8
	   powerpc64	   8	     8		    8
	   powerpc64le	   8	     8		    8
	   riscv64	   8	     16 	    8

     time_t is 8 bytes on all supported architectures except i386.

   Endianness and Char Signedness
	   Architecture    Endianness	 char Signedness
	   aarch64	   little	 unsigned
	   amd64	   little	 signed
	   armv7	   little	 unsigned
	   i386 	   little	 signed
	   powerpc	   big		 unsigned
	   powerpcspe	   big		 unsigned
	   powerpc64	   big		 unsigned
	   powerpc64le	   little	 unsigned
	   riscv64	   little	 signed

   Page Size
	   Architecture    Page Sizes
	   aarch64	   4K, 64K, 2M, 1G
	   amd64	   4K, 2M, 1G
	   armv7	   4K, 1M
	   i386 	   4K, 2M (PAE), 4M
	   powerpc	   4K
	   powerpcspe	   4K
	   powerpc64	   4K
	   powerpc64le	   4K
	   riscv64	   4K, 2M, 1G

   User Address Space Layout
	   Architecture      Maximum Address	   Address Space Size
	   aarch64	     0x0001000000000000    256TiB
	   amd64 (LA48)      0x0000800000000000    128TiB
	   amd64 (LA57)      0x0100000000000000    64PiB
	   armv7	     0xbfc00000 	   3GiB
	   i386 	     0xffc00000 	   4GiB
	   powerpc	     0xfffff000 	   4GiB
	   powerpcspe	     0x7ffff000 	   2GiB
	   powerpc64	     0x000fffffc0000000    4PiB
	   powerpc64le	     0x000fffffc0000000    4PiB
	   riscv64 (Sv39)    0x0000004000000000    256GiB
	   riscv64 (Sv48)    0x0000800000000000    128TiB

     The  layout  of  a  process'  address  space  can	be   queried   via   the
     KERN_PROC_VM_LAYOUT sysctl(3) MIB.

     Historically,  amd64  CPUs  were limited to a 48-bit virtual address space.
     Newer CPUs support 5-level page tables, which extend the  significant  bits
     of  addresses  to	57 bits (LA57 mode).  The address space layout is deter-
     mined by the CPU's support for LA57.  Setting the vm.pmap.la57 tunable to 0
     forces the system into 4-level paging mode, even on hardware that	supports
     5-level  paging.	In  this mode, all processes get a 48-bit address space.
     The vm.pmap.prefer_la48_uva tunable determines whether processes running on
     a LA57 system are limited to a 48-bit address space by default.   Some  ap-
     plications  make use of unused upper bits in pointer values to store infor-
     mation, and thus implicitly assume they are running in LA48 mode.	To avoid
     breaking compatibility, all processes run in LA48	mode  by  default.   The
     elfctl(1) utility can be used to request LA48 or LA57 mode for specific ex-
     ecutables.   Similarly, proccontrol(1) can be used to configure the address
     space layout when executing a process.

     The RISC-V  specification	permits  3-level  (Sv39),  4-level  (Sv48),  and
     5-level  (Sv57)  page tables.  Hardware is only required to implement Sv39;
     implementations which support Sv48 must also support Sv39, and  implementa-
     tions  which support Sv57 must also support Sv48.	The vm.pmap.mode tunable
     can be used to select the layout.	FreeBSD currently supports Sv39 and Sv48
     and defaults to using Sv39.

   Floating Point
	   Architecture    float, double    long double
	   aarch64	   hard 	    soft, quad precision
	   amd64	   hard 	    hard, 80 bit
	   armv7	   hard 	    hard, double precision
	   i386 	   hard 	    hard, 80 bit
	   powerpc	   hard 	    hard, double precision
	   powerpcspe	   hard 	    hard, double precision
	   powerpc64	   hard 	    hard, double precision
	   powerpc64le	   hard 	    hard, double precision
	   riscv64	   hard 	    hard, quad precision

   Default Tool Chain
     FreeBSD uses clang(1) as the default compiler on all supported  CPU  archi-
     tectures, LLVM's ld.lld(1) as the default linker, and LLVM binary utilities
     such as objcopy(1) and readelf(1).

   MACHINE_ARCH vs MACHINE_CPUARCH vs MACHINE
     MACHINE_CPUARCH should be preferred in Makefiles when the generic architec-
     ture is being tested.  MACHINE_ARCH should be preferred when there is some-
     thing specific to a particular type of architecture where there is a choice
     of  many,	or could be a choice of many.  Use MACHINE when referring to the
     kernel, interfaces dependent on a specific type of kernel or similar things
     like boot sequences.

	   MACHINE	 MACHINE_CPUARCH       MACHINE_ARCH
	   arm64	 aarch64	       aarch64
	   amd64	 amd64		       amd64
	   arm		 arm		       armv7
	   i386 	 i386		       i386
	   powerpc	 powerpc	       powerpc,  powerpcspe,  powerpc64,
								  powerpc64le
	   riscv	 riscv		       riscv64

   Predefined Macros
     The compiler provides a number of predefined macros.  Some of these provide
     architecture-specific  details  and are explained below.  Other macros, in-
     cluding 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
	   aarch64	   __aarch64__
	   amd64	   __amd64__, __x86_64__
	   armv7	   __arm__, __ARM_ARCH >= 7
	   i386 	   __i386__
	   powerpc	   __powerpc__
	   powerpcspe	   __powerpc__, __SPE__
	   powerpc64	   __powerpc__, __powerpc64__
	   powerpc64le	   __powerpc__, __powerpc64__
	   riscv64	   __riscv, __riscv_xlen == 64

     Compilers	may  define additional variants of architecture-specific macros.
     The macros above are preferred for use in FreeBSD.

   Important make(1)variables
     Most of the externally settable variables are defined in the  build(7)  man
     page.   These  variables  are  not otherwise documented and are used exten-
     sively in the build system.

     MACHINE	      Represents the hardware platform.  This is the same as the
		      native platform's uname(1) -m output.  It defines both the
		      userland / kernel interface, as well as the  bootloader  /
		      kernel  interface.   It  should only be used in these con-
		      texts.  Each CPU architecture may have  multiple	hardware
		      platforms  it  supports  where MACHINE differs among them.
		      It is used to collect together all  the  files  from  con-
		      fig(8)  to  build  the  kernel.	It  is often the same as
		      MACHINE_ARCH just as one CPU architecture  can  be  imple-
		      mented  by many different hardware platforms, one hardware
		      platform may support multiple CPU architecture family mem-
		      bers,  though  with  different  binaries.   For	example,
		      MACHINE  of  i386  supported  the IBM-AT hardware platform
		      while the MACHINE of pc98 supported the  Japanese  company
		      NEC's  PC-9801  and  PC-9821  hardware platforms.  Both of
		      these hardware platforms supported only  the  MACHINE_ARCH
		      of i386 where they shared a common ABI, except for certain
		      kernel  / userland interfaces relating to underlying hard-
		      ware platform differences in bus architecture, device enu-
		      meration and boot interface.   Generally,  MACHINE  should
		      only be used in src/sys and src/stand or in system imagers
		      or installers.

     MACHINE_ARCH     Represents  the  CPU  processor architecture.  This is the
		      same as the native platforms uname(1) -p output.	 It  de-
		      fines  the  CPU instruction family supported.  It may also
		      encode a variation in the byte ordering of multi-byte  in-
		      tegers  (endian).   It  may also encode a variation in the
		      size of the integer or pointer.  It may also encode a  ISA
		      revision.   It  may  also encode hard versus soft floating
		      point ABI and usage.  It may also  encode  a  variant  ABI
		      when  the  other	factors  do not uniquely define the ABI.
		      It, along with MACHINE, defines the ABI used by  the  sys-
		      tem.   Generally,  the  plain  CPU name specifies the most
		      common (or at least first) variant of the  CPU.	This  is
		      why  powerpc  and powerpc64 imply 'big endian' while armv7
		      and aarch64 imply little endian.	If we ever were to  sup-
		      port  the  so-called x32 ABI (using 32-bit pointers on the
		      amd64 architecture), it would most likely  be  encoded  as
		      amd64-x32.   It  is  unfortunate	that amd64 specifies the
		      64-bit evolution of  the	x86  platform  (it  matches  the
		      'first  rule')  as almost everybody else uses x86_64.  The
		      FreeBSD port was so  early,  it  predated  processor  name
		      standardization  after  Intel  joined  the market.  At the
		      time, each OS selected  its  own	conventions.   Backwards
		      compatibility  means  it is not easy to change to the con-
		      sensus name.

     MACHINE_CPUARCH  Represents the source location for a  given  MACHINE_ARCH.
		      It is generally the common prefix for all the MACHINE_ARCH
		      that  share the same implementation, though 'riscv' breaks
		      this rule.  While amd64 and i386 are closely related,  MA-
		      CHINE_CPUARCH  is  not  x86  for them.  The FreeBSD source
		      base supports amd64 and  i386  with  two	distinct  source
		      bases  living  in  subdirectories  named	amd64  and  i386
		      (though behind the scenes there's some sharing  that  fits
		      into this framework).

     CPUTYPE	      Sets  the  flavor of MACHINE_ARCH to build.  It is used to
		      optimize the build for a specific CPU / core that the  bi-
		      naries  run  on.	Generally, this does not change the ABI,
		      though it can be a fine line between optimization for spe-
		      cific cases.

     TARGET	      Used to set MACHINE in the top level  Makefile  for  cross
		      building.  Unused outside of that scope.	It is not passed
		      down  to	the rest of the build.	Makefiles outside of the
		      top level should not use it at all (though some have their
		      own private copy for historical reasons).

     TARGET_ARCH      Used to set MACHINE_ARCH by the  top  level  Makefile  for
		      cross building.  Like TARGET, it is unused outside of that
		      scope.

SEE ALSO
     elfctl(1), proccontrol(1), sysctl(3), src.conf(5), build(7), simd(7)

HISTORY
     An arch manual page appeared in FreeBSD 11.1.

FreeBSD ports 15.quarterly	  July 14, 2025 			 ARCH(7)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=arch&manpath=FreeBSD+15.1-RELEASE+and+Ports.quarterly>

home | help