1d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers/* 2d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers * Copyright (C) 2014 The Android Open Source Project 3d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers * 4d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers * Licensed under the Apache License, Version 2.0 (the "License"); 5d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers * you may not use this file except in compliance with the License. 6d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers * You may obtain a copy of the License at 7d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers * 8d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers * http://www.apache.org/licenses/LICENSE-2.0 9d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers * 10d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers * Unless required by applicable law or agreed to in writing, software 11d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers * distributed under the License is distributed on an "AS IS" BASIS, 12d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers * See the License for the specific language governing permissions and 14d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers * limitations under the License. 15d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers */ 16d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 17d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#include "instruction_set_features_x86.h" 18d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 19d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#include <fstream> 20d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#include <sstream> 21d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 22d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#include "arch/x86_64/instruction_set_features_x86_64.h" 23d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#include "base/stringprintf.h" 24d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#include "utils.h" // For Trim. 25d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 26d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersnamespace art { 27d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 2824a05f449a6b4b0e4944c2055f0c7490d6a09861Andreas Gampe// Feature-support arrays. 2924a05f449a6b4b0e4944c2055f0c7490d6a09861Andreas Gampe 3024a05f449a6b4b0e4944c2055f0c7490d6a09861Andreas Gampestatic constexpr const char* x86_known_variants[] = { 3124a05f449a6b4b0e4944c2055f0c7490d6a09861Andreas Gampe "atom", 3224a05f449a6b4b0e4944c2055f0c7490d6a09861Andreas Gampe "silvermont", 3324a05f449a6b4b0e4944c2055f0c7490d6a09861Andreas Gampe}; 3424a05f449a6b4b0e4944c2055f0c7490d6a09861Andreas Gampe 3524a05f449a6b4b0e4944c2055f0c7490d6a09861Andreas Gampestatic constexpr const char* x86_variants_with_ssse3[] = { 3624a05f449a6b4b0e4944c2055f0c7490d6a09861Andreas Gampe "atom", 3724a05f449a6b4b0e4944c2055f0c7490d6a09861Andreas Gampe "silvermont", 3824a05f449a6b4b0e4944c2055f0c7490d6a09861Andreas Gampe}; 3924a05f449a6b4b0e4944c2055f0c7490d6a09861Andreas Gampe 4024a05f449a6b4b0e4944c2055f0c7490d6a09861Andreas Gampestatic constexpr const char* x86_variants_with_sse4_1[] = { 4124a05f449a6b4b0e4944c2055f0c7490d6a09861Andreas Gampe "silvermont", 4224a05f449a6b4b0e4944c2055f0c7490d6a09861Andreas Gampe}; 4324a05f449a6b4b0e4944c2055f0c7490d6a09861Andreas Gampe 4424a05f449a6b4b0e4944c2055f0c7490d6a09861Andreas Gampestatic constexpr const char* x86_variants_with_sse4_2[] = { 4524a05f449a6b4b0e4944c2055f0c7490d6a09861Andreas Gampe "silvermont", 4624a05f449a6b4b0e4944c2055f0c7490d6a09861Andreas Gampe}; 4724a05f449a6b4b0e4944c2055f0c7490d6a09861Andreas Gampe 4817077d888a6752a2e5f8161eee1b2c3285783d12Mark P Mendellstatic constexpr const char* x86_variants_prefer_locked_add_sync[] = { 4917077d888a6752a2e5f8161eee1b2c3285783d12Mark P Mendell "atom", 5017077d888a6752a2e5f8161eee1b2c3285783d12Mark P Mendell "silvermont", 5117077d888a6752a2e5f8161eee1b2c3285783d12Mark P Mendell}; 5217077d888a6752a2e5f8161eee1b2c3285783d12Mark P Mendell 533f67e692860d281858485d48a4f1f81b907f1444Aart Bikstatic constexpr const char* x86_variants_with_popcnt[] = { 543f67e692860d281858485d48a4f1f81b907f1444Aart Bik "silvermont", 553f67e692860d281858485d48a4f1f81b907f1444Aart Bik}; 563f67e692860d281858485d48a4f1f81b907f1444Aart Bik 57d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersconst X86InstructionSetFeatures* X86InstructionSetFeatures::FromVariant( 58ca71458862be8505330b7fd5649a062f31d143dcAndreas Gampe const std::string& variant, std::string* error_msg ATTRIBUTE_UNUSED, 59d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers bool x86_64) { 60d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers bool smp = true; // Conservative default. 61d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers bool has_SSSE3 = FindVariantInArray(x86_variants_with_ssse3, arraysize(x86_variants_with_ssse3), 62d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers variant); 6324a05f449a6b4b0e4944c2055f0c7490d6a09861Andreas Gampe bool has_SSE4_1 = FindVariantInArray(x86_variants_with_sse4_1, 6424a05f449a6b4b0e4944c2055f0c7490d6a09861Andreas Gampe arraysize(x86_variants_with_sse4_1), 6524a05f449a6b4b0e4944c2055f0c7490d6a09861Andreas Gampe variant); 6624a05f449a6b4b0e4944c2055f0c7490d6a09861Andreas Gampe bool has_SSE4_2 = FindVariantInArray(x86_variants_with_sse4_2, 6724a05f449a6b4b0e4944c2055f0c7490d6a09861Andreas Gampe arraysize(x86_variants_with_sse4_2), 6824a05f449a6b4b0e4944c2055f0c7490d6a09861Andreas Gampe variant); 69d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers bool has_AVX = false; 70d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers bool has_AVX2 = false; 7124a05f449a6b4b0e4944c2055f0c7490d6a09861Andreas Gampe 7217077d888a6752a2e5f8161eee1b2c3285783d12Mark P Mendell bool prefers_locked_add = FindVariantInArray(x86_variants_prefer_locked_add_sync, 7317077d888a6752a2e5f8161eee1b2c3285783d12Mark P Mendell arraysize(x86_variants_prefer_locked_add_sync), 7417077d888a6752a2e5f8161eee1b2c3285783d12Mark P Mendell variant); 7517077d888a6752a2e5f8161eee1b2c3285783d12Mark P Mendell 763f67e692860d281858485d48a4f1f81b907f1444Aart Bik bool has_POPCNT = FindVariantInArray(x86_variants_with_popcnt, 773f67e692860d281858485d48a4f1f81b907f1444Aart Bik arraysize(x86_variants_with_popcnt), 783f67e692860d281858485d48a4f1f81b907f1444Aart Bik variant); 793f67e692860d281858485d48a4f1f81b907f1444Aart Bik 803f67e692860d281858485d48a4f1f81b907f1444Aart Bik // Verify that variant is known. 8124a05f449a6b4b0e4944c2055f0c7490d6a09861Andreas Gampe bool known_variant = FindVariantInArray(x86_known_variants, arraysize(x86_known_variants), 8224a05f449a6b4b0e4944c2055f0c7490d6a09861Andreas Gampe variant); 83d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers if (!known_variant && variant != "default") { 84d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers LOG(WARNING) << "Unexpected CPU variant for X86 using defaults: " << variant; 85d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } 86d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 87d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers if (x86_64) { 88d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers return new X86_64InstructionSetFeatures(smp, has_SSSE3, has_SSE4_1, has_SSE4_2, has_AVX, 893f67e692860d281858485d48a4f1f81b907f1444Aart Bik has_AVX2, prefers_locked_add, has_POPCNT); 90d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } else { 91d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers return new X86InstructionSetFeatures(smp, has_SSSE3, has_SSE4_1, has_SSE4_2, has_AVX, 923f67e692860d281858485d48a4f1f81b907f1444Aart Bik has_AVX2, prefers_locked_add, has_POPCNT); 93d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } 94d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers} 95d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 96d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersconst X86InstructionSetFeatures* X86InstructionSetFeatures::FromBitmap(uint32_t bitmap, 97d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers bool x86_64) { 98d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers bool smp = (bitmap & kSmpBitfield) != 0; 99d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers bool has_SSSE3 = (bitmap & kSsse3Bitfield) != 0; 100d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers bool has_SSE4_1 = (bitmap & kSse4_1Bitfield) != 0; 101d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers bool has_SSE4_2 = (bitmap & kSse4_2Bitfield) != 0; 102d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers bool has_AVX = (bitmap & kAvxBitfield) != 0; 103d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers bool has_AVX2 = (bitmap & kAvxBitfield) != 0; 10417077d888a6752a2e5f8161eee1b2c3285783d12Mark P Mendell bool prefers_locked_add = (bitmap & kPrefersLockedAdd) != 0; 1053f67e692860d281858485d48a4f1f81b907f1444Aart Bik bool has_POPCNT = (bitmap & kPopCntBitfield) != 0; 106d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers if (x86_64) { 10717077d888a6752a2e5f8161eee1b2c3285783d12Mark P Mendell return new X86_64InstructionSetFeatures(smp, has_SSSE3, has_SSE4_1, has_SSE4_2, 1083f67e692860d281858485d48a4f1f81b907f1444Aart Bik has_AVX, has_AVX2, prefers_locked_add, 1093f67e692860d281858485d48a4f1f81b907f1444Aart Bik has_POPCNT); 110d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } else { 11117077d888a6752a2e5f8161eee1b2c3285783d12Mark P Mendell return new X86InstructionSetFeatures(smp, has_SSSE3, has_SSE4_1, has_SSE4_2, 1123f67e692860d281858485d48a4f1f81b907f1444Aart Bik has_AVX, has_AVX2, prefers_locked_add, 1133f67e692860d281858485d48a4f1f81b907f1444Aart Bik has_POPCNT); 114d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } 115d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers} 116d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 117d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersconst X86InstructionSetFeatures* X86InstructionSetFeatures::FromCppDefines(bool x86_64) { 118d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers const bool smp = true; 119d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 120d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#ifndef __SSSE3__ 121d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers const bool has_SSSE3 = false; 122d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#else 123d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers const bool has_SSSE3 = true; 124d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#endif 125d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 126d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#ifndef __SSE4_1__ 127d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers const bool has_SSE4_1 = false; 128d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#else 129d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers const bool has_SSE4_1 = true; 130d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#endif 131d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 132d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#ifndef __SSE4_2__ 133d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers const bool has_SSE4_2 = false; 134d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#else 135d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers const bool has_SSE4_2 = true; 136d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#endif 137d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 138d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#ifndef __AVX__ 139d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers const bool has_AVX = false; 140d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#else 141d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers const bool has_AVX = true; 142d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#endif 143d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 144d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#ifndef __AVX2__ 145d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers const bool has_AVX2 = false; 146d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#else 147d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers const bool has_AVX2 = true; 148d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#endif 149d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 15017077d888a6752a2e5f8161eee1b2c3285783d12Mark P Mendell // No #define for memory synchronization preference. 15117077d888a6752a2e5f8161eee1b2c3285783d12Mark P Mendell const bool prefers_locked_add = false; 15217077d888a6752a2e5f8161eee1b2c3285783d12Mark P Mendell 153715d06b4498af3d4661e0090d606641d65040a08Aart Bik#ifndef __POPCNT__ 1543f67e692860d281858485d48a4f1f81b907f1444Aart Bik const bool has_POPCNT = false; 155715d06b4498af3d4661e0090d606641d65040a08Aart Bik#else 156715d06b4498af3d4661e0090d606641d65040a08Aart Bik const bool has_POPCNT = true; 157715d06b4498af3d4661e0090d606641d65040a08Aart Bik#endif 1583f67e692860d281858485d48a4f1f81b907f1444Aart Bik 159d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers if (x86_64) { 16017077d888a6752a2e5f8161eee1b2c3285783d12Mark P Mendell return new X86_64InstructionSetFeatures(smp, has_SSSE3, has_SSE4_1, has_SSE4_2, has_AVX, 1613f67e692860d281858485d48a4f1f81b907f1444Aart Bik has_AVX2, prefers_locked_add, has_POPCNT); 162d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } else { 163d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers return new X86InstructionSetFeatures(smp, has_SSSE3, has_SSE4_1, has_SSE4_2, has_AVX, 1643f67e692860d281858485d48a4f1f81b907f1444Aart Bik has_AVX2, prefers_locked_add, has_POPCNT); 165d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } 166d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers} 167d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 168d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersconst X86InstructionSetFeatures* X86InstructionSetFeatures::FromCpuInfo(bool x86_64) { 169d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers // Look in /proc/cpuinfo for features we need. Only use this when we can guarantee that 170d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers // the kernel puts the appropriate feature flags in here. Sometimes it doesn't. 171d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers bool smp = false; 172d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers bool has_SSSE3 = false; 173d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers bool has_SSE4_1 = false; 174d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers bool has_SSE4_2 = false; 175d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers bool has_AVX = false; 176d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers bool has_AVX2 = false; 17717077d888a6752a2e5f8161eee1b2c3285783d12Mark P Mendell // No cpuinfo for memory synchronization preference. 17817077d888a6752a2e5f8161eee1b2c3285783d12Mark P Mendell const bool prefers_locked_add = false; 1793f67e692860d281858485d48a4f1f81b907f1444Aart Bik bool has_POPCNT = false; 180d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 181d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers std::ifstream in("/proc/cpuinfo"); 182d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers if (!in.fail()) { 183d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers while (!in.eof()) { 184d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers std::string line; 185d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers std::getline(in, line); 186d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers if (!in.eof()) { 187d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers LOG(INFO) << "cpuinfo line: " << line; 188d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers if (line.find("flags") != std::string::npos) { 189d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers LOG(INFO) << "found flags"; 190d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers if (line.find("ssse3") != std::string::npos) { 191d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers has_SSSE3 = true; 192d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } 193d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers if (line.find("sse4_1") != std::string::npos) { 194d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers has_SSE4_1 = true; 195d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } 196d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers if (line.find("sse4_2") != std::string::npos) { 197d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers has_SSE4_2 = true; 198d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } 199d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers if (line.find("avx") != std::string::npos) { 200d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers has_AVX = true; 201d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } 202d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers if (line.find("avx2") != std::string::npos) { 203d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers has_AVX2 = true; 204d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } 2053f67e692860d281858485d48a4f1f81b907f1444Aart Bik if (line.find("popcnt") != std::string::npos) { 2063f67e692860d281858485d48a4f1f81b907f1444Aart Bik has_POPCNT = true; 2073f67e692860d281858485d48a4f1f81b907f1444Aart Bik } 208d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } else if (line.find("processor") != std::string::npos && 209d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers line.find(": 1") != std::string::npos) { 210d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers smp = true; 211d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } 212d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } 213d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } 214d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers in.close(); 215d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } else { 216d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers LOG(ERROR) << "Failed to open /proc/cpuinfo"; 217d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } 218d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers if (x86_64) { 21917077d888a6752a2e5f8161eee1b2c3285783d12Mark P Mendell return new X86_64InstructionSetFeatures(smp, has_SSSE3, has_SSE4_1, has_SSE4_2, has_AVX, 2203f67e692860d281858485d48a4f1f81b907f1444Aart Bik has_AVX2, prefers_locked_add, has_POPCNT); 221d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } else { 222d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers return new X86InstructionSetFeatures(smp, has_SSSE3, has_SSE4_1, has_SSE4_2, has_AVX, 2233f67e692860d281858485d48a4f1f81b907f1444Aart Bik has_AVX2, prefers_locked_add, has_POPCNT); 224d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } 225d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers} 226d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 227d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersconst X86InstructionSetFeatures* X86InstructionSetFeatures::FromHwcap(bool x86_64) { 228d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers UNIMPLEMENTED(WARNING); 229d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers return FromCppDefines(x86_64); 230d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers} 231d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 232d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersconst X86InstructionSetFeatures* X86InstructionSetFeatures::FromAssembly(bool x86_64) { 233d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers UNIMPLEMENTED(WARNING); 234d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers return FromCppDefines(x86_64); 235d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers} 236d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 237d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersbool X86InstructionSetFeatures::Equals(const InstructionSetFeatures* other) const { 238d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers if (GetInstructionSet() != other->GetInstructionSet()) { 239d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers return false; 240d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } 241d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers const X86InstructionSetFeatures* other_as_x86 = other->AsX86InstructionSetFeatures(); 242d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers return (IsSmp() == other->IsSmp()) && 243d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers (has_SSSE3_ == other_as_x86->has_SSSE3_) && 244d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers (has_SSE4_1_ == other_as_x86->has_SSE4_1_) && 245d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers (has_SSE4_2_ == other_as_x86->has_SSE4_2_) && 246d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers (has_AVX_ == other_as_x86->has_AVX_) && 24717077d888a6752a2e5f8161eee1b2c3285783d12Mark P Mendell (has_AVX2_ == other_as_x86->has_AVX2_) && 2483f67e692860d281858485d48a4f1f81b907f1444Aart Bik (prefers_locked_add_ == other_as_x86->prefers_locked_add_) && 2493f67e692860d281858485d48a4f1f81b907f1444Aart Bik (has_POPCNT_ == other_as_x86->has_POPCNT_); 250d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers} 251d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 252d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersuint32_t X86InstructionSetFeatures::AsBitmap() const { 253d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers return (IsSmp() ? kSmpBitfield : 0) | 254d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers (has_SSSE3_ ? kSsse3Bitfield : 0) | 255d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers (has_SSE4_1_ ? kSse4_1Bitfield : 0) | 256d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers (has_SSE4_2_ ? kSse4_2Bitfield : 0) | 257d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers (has_AVX_ ? kAvxBitfield : 0) | 25817077d888a6752a2e5f8161eee1b2c3285783d12Mark P Mendell (has_AVX2_ ? kAvx2Bitfield : 0) | 2593f67e692860d281858485d48a4f1f81b907f1444Aart Bik (prefers_locked_add_ ? kPrefersLockedAdd : 0) | 2603f67e692860d281858485d48a4f1f81b907f1444Aart Bik (has_POPCNT_ ? kPopCntBitfield : 0); 261d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers} 262d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 263d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersstd::string X86InstructionSetFeatures::GetFeatureString() const { 264d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers std::string result; 265d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers if (IsSmp()) { 266d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers result += "smp"; 267d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } else { 268d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers result += "-smp"; 269d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } 270d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers if (has_SSSE3_) { 271d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers result += ",ssse3"; 272d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } else { 273d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers result += ",-ssse3"; 274d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } 275d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers if (has_SSE4_1_) { 276d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers result += ",sse4.1"; 277d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } else { 278d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers result += ",-sse4.1"; 279d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } 280d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers if (has_SSE4_2_) { 281d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers result += ",sse4.2"; 282d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } else { 283d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers result += ",-sse4.2"; 284d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } 285d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers if (has_AVX_) { 286d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers result += ",avx"; 287d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } else { 288d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers result += ",-avx"; 289d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } 290d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers if (has_AVX2_) { 291d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers result += ",avx2"; 292d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } else { 293d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers result += ",-avx2"; 294d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } 29517077d888a6752a2e5f8161eee1b2c3285783d12Mark P Mendell if (prefers_locked_add_) { 29617077d888a6752a2e5f8161eee1b2c3285783d12Mark P Mendell result += ",lock_add"; 29717077d888a6752a2e5f8161eee1b2c3285783d12Mark P Mendell } else { 29817077d888a6752a2e5f8161eee1b2c3285783d12Mark P Mendell result += ",-lock_add"; 29917077d888a6752a2e5f8161eee1b2c3285783d12Mark P Mendell } 3003f67e692860d281858485d48a4f1f81b907f1444Aart Bik if (has_POPCNT_) { 3013f67e692860d281858485d48a4f1f81b907f1444Aart Bik result += ",popcnt"; 3023f67e692860d281858485d48a4f1f81b907f1444Aart Bik } else { 3033f67e692860d281858485d48a4f1f81b907f1444Aart Bik result += ",-popcnt"; 3043f67e692860d281858485d48a4f1f81b907f1444Aart Bik } 305d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers return result; 306d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers} 307d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 308d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogersconst InstructionSetFeatures* X86InstructionSetFeatures::AddFeaturesFromSplitString( 309d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers const bool smp, const std::vector<std::string>& features, bool x86_64, 310d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers std::string* error_msg) const { 311d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers bool has_SSSE3 = has_SSSE3_; 312d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers bool has_SSE4_1 = has_SSE4_1_; 313d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers bool has_SSE4_2 = has_SSE4_2_; 314d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers bool has_AVX = has_AVX_; 315d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers bool has_AVX2 = has_AVX2_; 31617077d888a6752a2e5f8161eee1b2c3285783d12Mark P Mendell bool prefers_locked_add = prefers_locked_add_; 3173f67e692860d281858485d48a4f1f81b907f1444Aart Bik bool has_POPCNT = has_POPCNT_; 318d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers for (auto i = features.begin(); i != features.end(); i++) { 319d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers std::string feature = Trim(*i); 320d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers if (feature == "ssse3") { 321d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers has_SSSE3 = true; 322d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } else if (feature == "-ssse3") { 323d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers has_SSSE3 = false; 324d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } else if (feature == "sse4.1") { 325d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers has_SSE4_1 = true; 326d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } else if (feature == "-sse4.1") { 327d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers has_SSE4_1 = false; 328d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } else if (feature == "sse4.2") { 329d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers has_SSE4_2 = true; 330d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } else if (feature == "-sse4.2") { 331d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers has_SSE4_2 = false; 332d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } else if (feature == "avx") { 333d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers has_AVX = true; 334d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } else if (feature == "-avx") { 335d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers has_AVX = false; 336d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } else if (feature == "avx2") { 337d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers has_AVX2 = true; 338d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } else if (feature == "-avx2") { 339d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers has_AVX2 = false; 34017077d888a6752a2e5f8161eee1b2c3285783d12Mark P Mendell } else if (feature == "lock_add") { 34117077d888a6752a2e5f8161eee1b2c3285783d12Mark P Mendell prefers_locked_add = true; 34217077d888a6752a2e5f8161eee1b2c3285783d12Mark P Mendell } else if (feature == "-lock_add") { 34317077d888a6752a2e5f8161eee1b2c3285783d12Mark P Mendell prefers_locked_add = false; 3443f67e692860d281858485d48a4f1f81b907f1444Aart Bik } else if (feature == "popcnt") { 3453f67e692860d281858485d48a4f1f81b907f1444Aart Bik has_POPCNT = true; 3463f67e692860d281858485d48a4f1f81b907f1444Aart Bik } else if (feature == "-popcnt") { 3473f67e692860d281858485d48a4f1f81b907f1444Aart Bik has_POPCNT = false; 348d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } else { 349d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers *error_msg = StringPrintf("Unknown instruction set feature: '%s'", feature.c_str()); 350d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers return nullptr; 351d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } 352d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } 353d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers if (x86_64) { 354d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers return new X86_64InstructionSetFeatures(smp, has_SSSE3, has_SSE4_1, has_SSE4_2, has_AVX, 3553f67e692860d281858485d48a4f1f81b907f1444Aart Bik has_AVX2, prefers_locked_add, has_POPCNT); 356d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } else { 357d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers return new X86InstructionSetFeatures(smp, has_SSSE3, has_SSE4_1, has_SSE4_2, has_AVX, 3583f67e692860d281858485d48a4f1f81b907f1444Aart Bik has_AVX2, prefers_locked_add, has_POPCNT); 359d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers } 360d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers} 361d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 362d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers} // namespace art 363