1 // Copyright 2014 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <string_view>
6
7 #include "base/strings/string_util.h"
8 #include "build/build_config.h"
9
10 #if defined(ARCH_CPU_X86_FAMILY)
11 #include "base/cpu.h"
12 #endif
13
14 namespace nacl {
15
GetSandboxArch()16 const char* GetSandboxArch() {
17 #if defined(ARCH_CPU_ARM_FAMILY)
18 return "arm";
19 #elif defined(ARCH_CPU_MIPS_FAMILY)
20 return "mips32";
21 #elif defined(ARCH_CPU_X86_FAMILY)
22
23 #if ARCH_CPU_64_BITS
24 return "x86-64";
25 #else
26 return "x86-32";
27 #endif // ARCH_CPU_64_BITS
28
29 #else
30 #error Architecture not supported.
31 #endif
32 }
33
GetCpuFeatures()34 std::string GetCpuFeatures() {
35 // PNaCl's translator from pexe to nexe can be told exactly what
36 // capabilities the user's machine has because the pexe to nexe
37 // translation is specific to the machine, and CPU information goes
38 // into the translation cache. This allows the translator to generate
39 // faster code.
40 //
41 // Care must be taken to avoid instructions which aren't supported by
42 // the NaCl sandbox. Ideally the translator would do this, but there's
43 // no point in not doing the allowlist here.
44 //
45 // TODO(jfb) Some features are missing, either because the NaCl
46 // sandbox doesn't support them, because base::CPU doesn't
47 // detect them, or because they don't help vector shuffles
48 // (and we omit them because it simplifies testing). Add the
49 // other features.
50 //
51 // TODO(jfb) The following is x86-specific. The base::CPU class
52 // doesn't handle other architectures very well, and we
53 // should at least detect the presence of ARM's integer
54 // divide.
55 std::vector<std::string_view> features;
56 #if defined(ARCH_CPU_X86_FAMILY)
57 base::CPU cpu;
58
59 // On x86, SSE features are ordered: the most recent one implies the
60 // others. Care is taken here to only specify the latest SSE version,
61 // whereas non-SSE features don't follow this model: POPCNT is
62 // effectively always implied by SSE4.2 but has to be specified
63 // separately.
64 //
65 // TODO: AVX2, AVX, SSE 4.2.
66 if (cpu.has_sse41()) features.push_back("+sse4.1");
67 // TODO: SSE 4A, SSE 4.
68 else if (cpu.has_ssse3()) features.push_back("+ssse3");
69 // TODO: SSE 3
70 else if (cpu.has_sse2()) features.push_back("+sse2");
71
72 if (cpu.has_popcnt()) features.push_back("+popcnt");
73
74 // TODO: AES, LZCNT, ...
75 #endif
76
77 return base::JoinString(features, ",");
78 }
79
80 } // namespace nacl
81