about summary refs log tree commit diff
path: root/lib/systems/parse.nix
diff options
context:
space:
mode:
Diffstat (limited to 'lib/systems/parse.nix')
-rw-r--r--lib/systems/parse.nix123
1 files changed, 104 insertions, 19 deletions
diff --git a/lib/systems/parse.nix b/lib/systems/parse.nix
index a20b334311efa..0c42689a9b137 100644
--- a/lib/systems/parse.nix
+++ b/lib/systems/parse.nix
@@ -69,24 +69,24 @@ rec {
 
   cpuTypes = with significantBytes; setTypes types.openCpuType {
     arm      = { bits = 32; significantByte = littleEndian; family = "arm"; };
-    armv5tel = { bits = 32; significantByte = littleEndian; family = "arm"; version = "5"; };
-    armv6m   = { bits = 32; significantByte = littleEndian; family = "arm"; version = "6"; };
-    armv6l   = { bits = 32; significantByte = littleEndian; family = "arm"; version = "6"; };
-    armv7a   = { bits = 32; significantByte = littleEndian; family = "arm"; version = "7"; };
-    armv7r   = { bits = 32; significantByte = littleEndian; family = "arm"; version = "7"; };
-    armv7m   = { bits = 32; significantByte = littleEndian; family = "arm"; version = "7"; };
-    armv7l   = { bits = 32; significantByte = littleEndian; family = "arm"; version = "7"; };
-    armv8a   = { bits = 32; significantByte = littleEndian; family = "arm"; version = "8"; };
-    armv8r   = { bits = 32; significantByte = littleEndian; family = "arm"; version = "8"; };
-    armv8m   = { bits = 32; significantByte = littleEndian; family = "arm"; version = "8"; };
-    aarch64  = { bits = 64; significantByte = littleEndian; family = "arm"; version = "8"; };
-    aarch64_be = { bits = 64; significantByte = bigEndian; family = "arm"; version = "8"; };
-
-    i386     = { bits = 32; significantByte = littleEndian; family = "x86"; };
-    i486     = { bits = 32; significantByte = littleEndian; family = "x86"; };
-    i586     = { bits = 32; significantByte = littleEndian; family = "x86"; };
-    i686     = { bits = 32; significantByte = littleEndian; family = "x86"; };
-    x86_64   = { bits = 64; significantByte = littleEndian; family = "x86"; };
+    armv5tel = { bits = 32; significantByte = littleEndian; family = "arm"; version = "5"; arch = "armv5t"; };
+    armv6m   = { bits = 32; significantByte = littleEndian; family = "arm"; version = "6"; arch = "armv6-m"; };
+    armv6l   = { bits = 32; significantByte = littleEndian; family = "arm"; version = "6"; arch = "armv6"; };
+    armv7a   = { bits = 32; significantByte = littleEndian; family = "arm"; version = "7"; arch = "armv7-a"; };
+    armv7r   = { bits = 32; significantByte = littleEndian; family = "arm"; version = "7"; arch = "armv7-r"; };
+    armv7m   = { bits = 32; significantByte = littleEndian; family = "arm"; version = "7"; arch = "armv7-m"; };
+    armv7l   = { bits = 32; significantByte = littleEndian; family = "arm"; version = "7"; arch = "armv7"; };
+    armv8a   = { bits = 32; significantByte = littleEndian; family = "arm"; version = "8"; arch = "armv8-a"; };
+    armv8r   = { bits = 32; significantByte = littleEndian; family = "arm"; version = "8"; arch = "armv8-a"; };
+    armv8m   = { bits = 32; significantByte = littleEndian; family = "arm"; version = "8"; arch = "armv8-m"; };
+    aarch64  = { bits = 64; significantByte = littleEndian; family = "arm"; version = "8"; arch = "armv8-a"; };
+    aarch64_be = { bits = 64; significantByte = bigEndian; family = "arm"; version = "8";  arch = "armv8-a"; };
+
+    i386     = { bits = 32; significantByte = littleEndian; family = "x86"; arch = "i386"; };
+    i486     = { bits = 32; significantByte = littleEndian; family = "x86"; arch = "i486"; };
+    i586     = { bits = 32; significantByte = littleEndian; family = "x86"; arch = "i586"; };
+    i686     = { bits = 32; significantByte = littleEndian; family = "x86"; arch = "i686"; };
+    x86_64   = { bits = 64; significantByte = littleEndian; family = "x86"; arch = "x86-64"; };
 
     mips     = { bits = 32; significantByte = bigEndian;    family = "mips"; };
     mipsel   = { bits = 32; significantByte = littleEndian; family = "mips"; };
@@ -109,11 +109,92 @@ rec {
 
     alpha    = { bits = 64; significantByte = littleEndian; family = "alpha"; };
 
+    msp430   = { bits = 16; significantByte = littleEndian; family = "msp430"; };
     avr      = { bits = 8; family = "avr"; };
 
     js       = { bits = 32; significantByte = littleEndian; family = "js"; };
   };
 
+  # Determine where two CPUs are compatible with each other. That is,
+  # can we run code built for system b on system a? For that to
+  # happen, then the set of all possible possible programs that system
+  # b accepts must be a subset of the set of all programs that system
+  # a accepts. This compatibility relation forms a category where each
+  # CPU is an object and each arrow from a to b represents
+  # compatibility. CPUs with multiple modes of Endianness are
+  # isomorphic while all CPUs are endomorphic because any program
+  # built for a CPU can run on that CPU.
+  isCompatible = a: b: with cpuTypes; lib.any lib.id [
+    # x86
+    (b == i386 && isCompatible a i486)
+    (b == i486 && isCompatible a i586)
+    (b == i586 && isCompatible a i686)
+
+    # XXX: Not true in some cases. Like in WSL mode.
+    (b == i686 && isCompatible a x86_64)
+
+    # ARMv4
+    (b == arm && isCompatible a armv5tel)
+
+    # ARMv5
+    (b == armv5tel && isCompatible a armv6l)
+
+    # ARMv6
+    (b == armv6l && isCompatible a armv6m)
+    (b == armv6m && isCompatible a armv7l)
+
+    # ARMv7
+    (b == armv7l && isCompatible a armv7a)
+    (b == armv7l && isCompatible a armv7r)
+    (b == armv7l && isCompatible a armv7m)
+    (b == armv7a && isCompatible a armv8a)
+    (b == armv7r && isCompatible a armv8a)
+    (b == armv7m && isCompatible a armv8a)
+    (b == armv7a && isCompatible a armv8r)
+    (b == armv7r && isCompatible a armv8r)
+    (b == armv7m && isCompatible a armv8r)
+    (b == armv7a && isCompatible a armv8m)
+    (b == armv7r && isCompatible a armv8m)
+    (b == armv7m && isCompatible a armv8m)
+
+    # ARMv8
+    (b == armv8r && isCompatible a armv8a)
+    (b == armv8m && isCompatible a armv8a)
+
+    # XXX: not always true! Some arm64 cpus don’t support arm32 mode.
+    (b == aarch64 && a == armv8a)
+    (b == armv8a && isCompatible a aarch64)
+
+    (b == aarch64 && a == aarch64_be)
+    (b == aarch64_be && isCompatible a aarch64)
+
+    # PowerPC
+    (b == powerpc && isCompatible a powerpc64)
+    (b == powerpcle && isCompatible a powerpc)
+    (b == powerpc && a == powerpcle)
+    (b == powerpc64le && isCompatible a powerpc64)
+    (b == powerpc64 && a == powerpc64le)
+
+    # MIPS
+    (b == mips && isCompatible a mips64)
+    (b == mips && a == mipsel)
+    (b == mipsel && isCompatible a mips)
+    (b == mips64 && a == mips64el)
+    (b == mips64el && isCompatible a mips64)
+
+    # RISCV
+    (b == riscv32 && isCompatible a riscv64)
+
+    # SPARC
+    (b == sparc && isCompatible a sparc64)
+
+    # WASM
+    (b == wasm32 && isCompatible a wasm64)
+
+    # identity
+    (b == a)
+  ];
+
   ################################################################################
 
   types.openVendor = mkOptionType {
@@ -147,6 +228,7 @@ rec {
     elf = {};
     macho = {};
     pe = {};
+    wasm = {};
 
     unknown = {};
   };
@@ -189,6 +271,7 @@ rec {
     none    = { execFormat = unknown; families = { }; };
     openbsd = { execFormat = elf;     families = { inherit bsd; }; };
     solaris = { execFormat = elf;     families = { }; };
+    wasi    = { execFormat = wasm;    families = { }; };
     windows = { execFormat = pe;      families = { }; };
     ghcjs   = { execFormat = unknown; families = { }; };
   } // { # aliases
@@ -298,6 +381,8 @@ rec {
         then { cpu = elemAt l 0;                      kernel = elemAt l 1; abi = elemAt l 2; }
       else if (elemAt l 2 == "mingw32") # autotools breaks on -gnu for window
         then { cpu = elemAt l 0; vendor = elemAt l 1; kernel = "windows";                    }
+      else if (elemAt l 2 == "wasi")
+        then { cpu = elemAt l 0; vendor = elemAt l 1; kernel = "wasi";                       }
       else if hasPrefix "netbsd" (elemAt l 2)
         then { cpu = elemAt l 0; vendor = elemAt l 1;    kernel = elemAt l 2;                }
       else if (elem (elemAt l 2) ["eabi" "eabihf" "elf"])
@@ -348,7 +433,7 @@ rec {
 
   mkSystemFromString = s: mkSystemFromSkeleton (mkSkeletonFromList (lib.splitString "-" s));
 
-  doubleFromSystem = { cpu, vendor, kernel, abi, ... }:
+  doubleFromSystem = { cpu, kernel, abi, ... }:
     /**/ if abi == abis.cygnus       then "${cpu.name}-cygwin"
     else if kernel.families ? darwin then "${cpu.name}-darwin"
     else "${cpu.name}-${kernel.name}";