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