about summary refs log tree commit diff
path: root/lib/systems/architectures.nix
blob: 9be8c80e3f117a2a3ff17c9b23814d7a47e77e32 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
{ lib }:

rec {
  # gcc.arch to its features (as in /proc/cpuinfo)
  features = {
    # x86_64 Generic
    # Spec: https://gitlab.com/x86-psABIs/x86-64-ABI/
    default        = [ ];
    x86-64         = [ ];
    x86-64-v2      = [ "sse3" "ssse3" "sse4_1" "sse4_2"                                                  ];
    x86-64-v3      = [ "sse3" "ssse3" "sse4_1" "sse4_2"               "avx" "avx2"          "fma"        ];
    x86-64-v4      = [ "sse3" "ssse3" "sse4_1" "sse4_2"               "avx" "avx2" "avx512" "fma"        ];
    # x86_64 Intel
    nehalem        = [ "sse3" "ssse3" "sse4_1" "sse4_2"         "aes"                                    ];
    westmere       = [ "sse3" "ssse3" "sse4_1" "sse4_2"         "aes"                                    ];
    sandybridge    = [ "sse3" "ssse3" "sse4_1" "sse4_2"         "aes" "avx"                              ];
    ivybridge      = [ "sse3" "ssse3" "sse4_1" "sse4_2"         "aes" "avx"                              ];
    haswell        = [ "sse3" "ssse3" "sse4_1" "sse4_2"         "aes" "avx" "avx2"          "fma"        ];
    broadwell      = [ "sse3" "ssse3" "sse4_1" "sse4_2"         "aes" "avx" "avx2"          "fma"        ];
    skylake        = [ "sse3" "ssse3" "sse4_1" "sse4_2"         "aes" "avx" "avx2"          "fma"        ];
    skylake-avx512 = [ "sse3" "ssse3" "sse4_1" "sse4_2"         "aes" "avx" "avx2" "avx512" "fma"        ];
    cannonlake     = [ "sse3" "ssse3" "sse4_1" "sse4_2"         "aes" "avx" "avx2" "avx512" "fma"        ];
    icelake-client = [ "sse3" "ssse3" "sse4_1" "sse4_2"         "aes" "avx" "avx2" "avx512" "fma"        ];
    icelake-server = [ "sse3" "ssse3" "sse4_1" "sse4_2"         "aes" "avx" "avx2" "avx512" "fma"        ];
    cascadelake    = [ "sse3" "ssse3" "sse4_1" "sse4_2"         "aes" "avx" "avx2" "avx512" "fma"        ];
    cooperlake     = [ "sse3" "ssse3" "sse4_1" "sse4_2"         "aes" "avx" "avx2" "avx512" "fma"        ];
    tigerlake      = [ "sse3" "ssse3" "sse4_1" "sse4_2"         "aes" "avx" "avx2" "avx512" "fma"        ];
    alderlake      = [ "sse3" "ssse3" "sse4_1" "sse4_2"         "aes" "avx" "avx2"          "fma"        ];
    # x86_64 AMD
    btver1         = [ "sse3" "ssse3" "sse4_1" "sse4_2"                                                  ];
    btver2         = [ "sse3" "ssse3" "sse4_1" "sse4_2"         "aes" "avx"                              ];
    bdver1         = [ "sse3" "ssse3" "sse4_1" "sse4_2" "sse4a" "aes" "avx"                 "fma" "fma4" ];
    bdver2         = [ "sse3" "ssse3" "sse4_1" "sse4_2" "sse4a" "aes" "avx"                 "fma" "fma4" ];
    bdver3         = [ "sse3" "ssse3" "sse4_1" "sse4_2" "sse4a" "aes" "avx"                 "fma" "fma4" ];
    bdver4         = [ "sse3" "ssse3" "sse4_1" "sse4_2" "sse4a" "aes" "avx" "avx2"          "fma" "fma4" ];
    znver1         = [ "sse3" "ssse3" "sse4_1" "sse4_2" "sse4a" "aes" "avx" "avx2"          "fma"        ];
    znver2         = [ "sse3" "ssse3" "sse4_1" "sse4_2" "sse4a" "aes" "avx" "avx2"          "fma"        ];
    znver3         = [ "sse3" "ssse3" "sse4_1" "sse4_2" "sse4a" "aes" "avx" "avx2"          "fma"        ];
    znver4         = [ "sse3" "ssse3" "sse4_1" "sse4_2" "sse4a" "aes" "avx" "avx2" "avx512" "fma"        ];
    # other
    armv5te        = [ ];
    armv6          = [ ];
    armv7-a        = [ ];
    armv8-a        = [ ];
    mips32         = [ ];
    loongson2f     = [ ];
  };

  # a superior CPU has all the features of an inferior and is able to build and test code for it
  inferiors = {
    # x86_64 Generic
    default   = [ ];
    x86-64    = [ ];
    x86-64-v2 = [ "x86-64"    ];
    x86-64-v3 = [ "x86-64-v2" ] ++ inferiors.x86-64-v2;
    x86-64-v4 = [ "x86-64-v3" ] ++ inferiors.x86-64-v3;

    # x86_64 Intel
    # https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html
    nehalem        = [ "x86-64-v2"   ] ++ inferiors.x86-64-v2;
    westmere       = [ "nehalem"     ] ++ inferiors.nehalem;
    sandybridge    = [ "westmere"    ] ++ inferiors.westmere;
    ivybridge      = [ "sandybridge" ] ++ inferiors.sandybridge;

    haswell        = lib.unique ([ "ivybridge" "x86-64-v3" ] ++ inferiors.ivybridge ++ inferiors.x86-64-v3);
    broadwell      = [ "haswell"   ] ++ inferiors.haswell;
    skylake        = [ "broadwell" ] ++ inferiors.broadwell;

    skylake-avx512 = lib.unique ([ "skylake" "x86-64-v4" ] ++ inferiors.skylake ++ inferiors.x86-64-v4);
    cannonlake     = [ "skylake-avx512" ] ++ inferiors.skylake-avx512;
    icelake-client = [ "cannonlake"     ] ++ inferiors.cannonlake;
    icelake-server = [ "icelake-client" ] ++ inferiors.icelake-client;
    cascadelake    = [ "cannonlake"     ] ++ inferiors.cannonlake;
    cooperlake     = [ "cascadelake"    ] ++ inferiors.cascadelake;
    tigerlake      = [ "icelake-server" ] ++ inferiors.icelake-server;

    # CX16 does not exist on alderlake, while it does on nearly all other intel CPUs
    alderlake      = [ ];

    # x86_64 AMD
    # TODO: fill this (need testing)
    btver1         = [ ];
    btver2         = [ ];
    bdver1         = [ ];
    bdver2         = [ ];
    bdver3         = [ ];
    bdver4         = [ ];
    # Regarding `skylake` as inferior of `znver1`, there are reports of
    # successful usage by Gentoo users and Phoronix benchmarking of different
    # `-march` targets.
    #
    # The GCC documentation on extensions used and wikichip documentation
    # regarding supperted extensions on znver1 and skylake was used to create
    # this partial order.
    #
    # Note:
    #
    # - The successors of `skylake` (`cannonlake`, `icelake`, etc) use `avx512`
    #   which no current AMD Zen michroarch support.
    # - `znver1` uses `ABM`, `CLZERO`, `CX16`, `MWAITX`, and `SSE4A` which no
    #   current Intel microarch support.
    #
    # https://www.phoronix.com/scan.php?page=article&item=amd-znver3-gcc11&num=1
    # https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html
    # https://en.wikichip.org/wiki/amd/microarchitectures/zen
    # https://en.wikichip.org/wiki/intel/microarchitectures/skylake
    znver1         = [ "skylake" ] ++ inferiors.skylake; # Includes haswell and x86-64-v3
    znver2         = [ "znver1"  ] ++ inferiors.znver1;
    znver3         = [ "znver2"  ] ++ inferiors.znver2;
    znver4         = lib.unique ([ "znver3" "x86-64-v4" ] ++ inferiors.znver3 ++ inferiors.x86-64-v4);

    # other
    armv5te        = [ ];
    armv6          = [ ];
    armv7-a        = [ ];
    armv8-a        = [ ];
    mips32         = [ ];
    loongson2f     = [ ];
  };

  predicates = let
    featureSupport = feature: x: builtins.elem feature features.${x} or [];
  in {
    sse3Support    = featureSupport "sse3";
    ssse3Support   = featureSupport "ssse3";
    sse4_1Support  = featureSupport "sse4_1";
    sse4_2Support  = featureSupport "sse4_2";
    sse4_aSupport  = featureSupport "sse4a";
    avxSupport     = featureSupport "avx";
    avx2Support    = featureSupport "avx2";
    avx512Support  = featureSupport "avx512";
    aesSupport     = featureSupport "aes";
    fmaSupport     = featureSupport "fma";
    fma4Support    = featureSupport "fma4";
  };
}