|  | // Copyright 2014 The Chromium Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #include "base/cpu.h" | 
|  | #include "base/strings/string_piece.h" | 
|  | #include "base/strings/string_util.h" | 
|  | #include "build/build_config.h" | 
|  | #if defined(OS_WIN) | 
|  | #include "base/win/windows_version.h" | 
|  | #endif | 
|  |  | 
|  | namespace nacl { | 
|  |  | 
|  | const char* GetSandboxArch() { | 
|  | #if defined(ARCH_CPU_ARM_FAMILY) | 
|  | return "arm"; | 
|  | #elif defined(ARCH_CPU_MIPS_FAMILY) | 
|  | return "mips32"; | 
|  | #elif defined(ARCH_CPU_X86_FAMILY) | 
|  |  | 
|  | #if defined(OS_WIN) | 
|  | // We have to check the host architecture on Windows. | 
|  | // See sandbox_isa.h for an explanation why. | 
|  | if (base::win::OSInfo::GetArchitecture() == | 
|  | base::win::OSInfo::X64_ARCHITECTURE) { | 
|  | return "x86-64"; | 
|  | } | 
|  | return "x86-32"; | 
|  | #elif ARCH_CPU_64_BITS | 
|  | return "x86-64"; | 
|  | #else | 
|  | return "x86-32"; | 
|  | #endif  // defined(OS_WIN) | 
|  |  | 
|  | #else | 
|  | #error Architecture not supported. | 
|  | #endif | 
|  | } | 
|  |  | 
|  | std::string GetCpuFeatures() { | 
|  | // PNaCl's translator from pexe to nexe can be told exactly what | 
|  | // capabilities the user's machine has because the pexe to nexe | 
|  | // translation is specific to the machine, and CPU information goes | 
|  | // into the translation cache. This allows the translator to generate | 
|  | // faster code. | 
|  | // | 
|  | // Care must be taken to avoid instructions which aren't supported by | 
|  | // the NaCl sandbox. Ideally the translator would do this, but there's | 
|  | // no point in not doing the allowlist here. | 
|  | // | 
|  | // TODO(jfb) Some features are missing, either because the NaCl | 
|  | //           sandbox doesn't support them, because base::CPU doesn't | 
|  | //           detect them, or because they don't help vector shuffles | 
|  | //           (and we omit them because it simplifies testing). Add the | 
|  | //           other features. | 
|  | // | 
|  | // TODO(jfb) The following is x86-specific. The base::CPU class | 
|  | //           doesn't handle other architectures very well, and we | 
|  | //           should at least detect the presence of ARM's integer | 
|  | //           divide. | 
|  | std::vector<base::StringPiece> features; | 
|  | base::CPU cpu; | 
|  |  | 
|  | // On x86, SSE features are ordered: the most recent one implies the | 
|  | // others. Care is taken here to only specify the latest SSE version, | 
|  | // whereas non-SSE features don't follow this model: POPCNT is | 
|  | // effectively always implied by SSE4.2 but has to be specified | 
|  | // separately. | 
|  | // | 
|  | // TODO: AVX2, AVX, SSE 4.2. | 
|  | if (cpu.has_sse41()) features.push_back("+sse4.1"); | 
|  | // TODO: SSE 4A, SSE 4. | 
|  | else if (cpu.has_ssse3()) features.push_back("+ssse3"); | 
|  | // TODO: SSE 3 | 
|  | else if (cpu.has_sse2()) features.push_back("+sse2"); | 
|  |  | 
|  | if (cpu.has_popcnt()) features.push_back("+popcnt"); | 
|  |  | 
|  | // TODO: AES, LZCNT, ... | 
|  | return base::JoinString(features, ","); | 
|  | } | 
|  |  | 
|  | }  // namespace nacl |