From patchwork Tue Jun 5 22:00:28 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Sriraman Tallam X-Patchwork-Id: 163180 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 49EBDB6F13 for ; Wed, 6 Jun 2012 08:00:58 +1000 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1339538459; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: MIME-Version:Received:Received:In-Reply-To:References:Date: Message-ID:Subject:From:To:Cc:Content-Type:Mailing-List: Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:Sender:Delivered-To; bh=ctK0gH4x4voSiqXYBwHUx7H0Ul0=; b=be9q+aBUn4Y9aieYc7oxV075cnk/WFGFXto3DB32iklUkST6vCiyQUT01cpZAW /tEdhyGT/ukGvEMl9cDJaokFrVZfcnzjrcaZ32om56OAaMa1P2i/L87RUFHqaqT7 Lfi2hT5UoXcyFAJUVyPEQTnuziTxWom2kXWL61hqegc44= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:X-Google-DKIM-Signature:Received:MIME-Version:Received:Received:In-Reply-To:References:Date:Message-ID:Subject:From:To:Cc:Content-Type:X-System-Of-Record:X-Gm-Message-State:X-IsSubscribed:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=YWM37QipHu2vqmbJRwbhTWNssdOxL3SsxVlh2DtQPvJOaly53+2PTiPY28/QUN WK/64h9Jv0zIHLIvwpSsxp3ejW8f1/xfkQX6kif/U0C8bjKu1vH+qm7AgCwVG1ue hwpstgtJEGvkT6pltlyu+ssuHd/JS+6cJqJUnYXq3LdJQ=; Received: (qmail 11495 invoked by alias); 5 Jun 2012 22:00:49 -0000 Received: (qmail 11459 invoked by uid 22791); 5 Jun 2012 22:00:44 -0000 X-SWARE-Spam-Status: No, hits=-5.3 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, KHOP_RCVD_TRUST, KHOP_THREADED, RCVD_IN_DNSWL_LOW, RCVD_IN_HOSTKARMA_YE, TW_AV, TW_EB, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mail-ob0-f175.google.com (HELO mail-ob0-f175.google.com) (209.85.214.175) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 05 Jun 2012 22:00:29 +0000 Received: by obhx4 with SMTP id x4so10444440obh.20 for ; Tue, 05 Jun 2012 15:00:29 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type:x-system-of-record:x-gm-message-state; bh=jXMpLDLiPLvBpIao06ZxYcPctSZ2EwTQLNhWfp6IMnA=; b=k7DX4ePORoE1/8V/5p2vHOqgadjfVmiUFBtmejr8hhT5JGjxcGuq5nOvTkOaIAyAbg P2D5wbQ95d2Xlclq/sSALiYrAc4r68FtjEBhxs6uuISZx3K8CsFU2lt6MDhff1Eihd0E HT2vtbZjOXnic+ipR9pdbLNDb6Xd7WCAswf5eGuld+HMAH/vXaFGvcyQMmdDnKZYkFsX FAaBmkQNdPa45bnSE6TadeD4Iqv9rDfn3Drg2OsPrzlEvSEE12JgzcvtTagu8h0B2Cc5 EdvxRJat9klVw9GRR47YBlWTZc5HuXCtyAjokjolxM983jS3lssR1nxT+XjknW5zPBEU Po2Q== Received: by 10.182.187.42 with SMTP id fp10mr18389211obc.30.1338933629052; Tue, 05 Jun 2012 15:00:29 -0700 (PDT) MIME-Version: 1.0 Received: by 10.182.187.42 with SMTP id fp10mr18389195obc.30.1338933628909; Tue, 05 Jun 2012 15:00:28 -0700 (PDT) Received: by 10.182.101.202 with HTTP; Tue, 5 Jun 2012 15:00:28 -0700 (PDT) In-Reply-To: References: <20120330001021.9E30EB2086@azwildcat.mtv.corp.google.com> Date: Tue, 5 Jun 2012 15:00:28 -0700 Message-ID: Subject: Re: Support for Runtime CPU type detection via builtins (issue5754058) From: Sriraman Tallam To: "H.J. Lu" Cc: Uros Bizjak , Richard Guenther , Michael Matz , reply@codereview.appspotmail.com, gcc-patches@gcc.gnu.org, Richard Henderson , Jan Hubicka X-System-Of-Record: true X-Gm-Message-State: ALoCoQky91UiVy4qpJPh23/wtx/7UQUBTt7NxFUpgXYt3GV/OWfxJFoViHu9F3RuH2yPmhzEUDSbbANAThqCoJawAIM5KExI+a8khbrxWeLEcwvLJh9GWU3961u5Rg4FMYLXg7NLEb/X8q1j/PfAIC0OoV7r1c0rmw== X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Hi H.J., I am attaching a patch to add __cpu_indicator_init to the list of symbols to be versioned and exported in libgcc_s.so. Also, updating builtin_target.c test to explicitly do a CPUID and check if the features are identified correctly like you had suggested earlier. Patch ok? * config/i386/libgcc-bsd.ver: Version symbol __cpu_indicator_init. * config/i386/libgcc-sol2.ver: Ditto. * config/i386/libgcc-glibc.ver: Ditto. * gcc.target/i386/builtin_target.c (vendor_signatures): New enum. (check_intel_cpu_model): New function. (check_amd_cpu_model): New function. (check_features): New function. (__get_cpuid_output): New function. (check_detailed): New function. (fn1): Rename to quick_check. (main): Update to call quick_check and call check_detailed. Thanks, -Sri. On Wed, Apr 25, 2012 at 5:52 PM, Sriraman Tallam wrote: > Patch committed. > > Thanks, > -Sri. > > On Wed, Apr 25, 2012 at 4:52 PM, H.J. Lu wrote: >> On Wed, Apr 25, 2012 at 4:38 PM, Sriraman Tallam wrote: >>> Hi H.J, >>> >>>   Could you please review this patch for AVX2 check? >>> >>>        * config/i386/i386-cpuinfo.c (FEATURE_AVX2): New enum value. >>>        (get_available_features): New argument. Check for AVX2. >>>        (__cpu_indicator_init): Modify call to get_available_features >>> . >>>        * doc/extend.texi: Document avx2 support. >>>        * testsuite/gcc.target/i386/builtin_target.c: Check avx2. >>>        * config/i386/i386.c (fold_builtin_cpu): Add avx2. >>> >> >> It looks good to me. >> >> Thanks. >> >> -- >> H.J. Index: libgcc/config/i386/libgcc-bsd.ver =================================================================== --- libgcc/config/i386/libgcc-bsd.ver (revision 188246) +++ libgcc/config/i386/libgcc-bsd.ver (working copy) @@ -109,4 +109,5 @@ GCC_4.6.0 { GCC_4.8.0 { __cpu_model + __cpu_indicator_init } Index: libgcc/config/i386/libgcc-sol2.ver =================================================================== --- libgcc/config/i386/libgcc-sol2.ver (revision 188246) +++ libgcc/config/i386/libgcc-sol2.ver (working copy) @@ -109,4 +109,5 @@ GCC_4.5.0 { GCC_4.8.0 { __cpu_model + __cpu_indicator_init } Index: libgcc/config/i386/libgcc-glibc.ver =================================================================== --- libgcc/config/i386/libgcc-glibc.ver (revision 188246) +++ libgcc/config/i386/libgcc-glibc.ver (working copy) @@ -150,6 +150,7 @@ GCC_4.3.0 { GCC_4.8.0 { __cpu_model + __cpu_indicator_init } %else GCC_4.4.0 { @@ -190,5 +191,6 @@ GCC_4.5.0 { GCC_4.8.0 { __cpu_model + __cpu_indicator_init } %endif Index: gcc/testsuite/gcc.target/i386/builtin_target.c =================================================================== --- gcc/testsuite/gcc.target/i386/builtin_target.c (revision 188246) +++ gcc/testsuite/gcc.target/i386/builtin_target.c (working copy) @@ -1,13 +1,229 @@ /* This test checks if the __builtin_cpu_is and __builtin_cpu_supports calls - are recognized. */ + are recognized. It also independently uses CPUID to get cpu type and + features supported and checks if the builtins correctly identify the + platform. The code to do the identification is adapted from + libgcc/config/i386/cpuinfo.c. */ /* { dg-do run } */ #include +#include "cpuid.h" -int -fn1 () +enum vendor_signatures { + SIG_INTEL = 0x756e6547 /* Genu */, + SIG_AMD = 0x68747541 /* Auth */ +}; + +/* Check if the Intel CPU model and sub-model are identified. */ +static void +check_intel_cpu_model (unsigned int family, unsigned int model, + unsigned int brand_id) +{ + /* Parse family and model only if brand ID is 0. */ + if (brand_id == 0) + { + switch (family) + { + case 0x5: + /* Pentium. */ + break; + case 0x6: + switch (model) + { + case 0x1c: + case 0x26: + /* Atom. */ + assert (__builtin_cpu_is ("atom")); + break; + case 0x1a: + case 0x1e: + case 0x1f: + case 0x2e: + /* Nehalem. */ + assert (__builtin_cpu_is ("corei7")); + assert (__builtin_cpu_is ("nehalem")); + break; + case 0x25: + case 0x2c: + case 0x2f: + /* Westmere. */ + assert (__builtin_cpu_is ("corei7")); + assert (__builtin_cpu_is ("westmere")); + break; + case 0x2a: + /* Sandy Bridge. */ + assert (__builtin_cpu_is ("corei7")); + assert (__builtin_cpu_is ("sandybridge")); + break; + case 0x17: + case 0x1d: + /* Penryn. */ + case 0x0f: + /* Merom. */ + assert (__builtin_cpu_is ("core2")); + break; + default: + break; + } + break; + default: + /* We have no idea. */ + break; + } + } +} + +/* Check if the AMD CPU model and sub-model are identified. */ +static void +check_amd_cpu_model (unsigned int family, unsigned int model) +{ + switch (family) + { + /* AMD Family 10h. */ + case 0x10: + switch (model) + { + case 0x2: + /* Barcelona. */ + assert (__builtin_cpu_is ("amdfam10h")); + assert (__builtin_cpu_is ("barcelona")); + break; + case 0x4: + /* Shanghai. */ + assert (__builtin_cpu_is ("amdfam10h")); + assert (__builtin_cpu_is ("shanghai")); + break; + case 0x8: + /* Istanbul. */ + assert (__builtin_cpu_is ("amdfam10h")); + assert (__builtin_cpu_is ("istanbul")); + break; + default: + break; + } + break; + /* AMD Family 15h. */ + case 0x15: + assert (__builtin_cpu_is ("amdfam15h")); + /* Bulldozer version 1. */ + if ( model <= 0xf) + assert (__builtin_cpu_is ("bdver1")); + /* Bulldozer version 2. */ + if (model >= 0x10 && model <= 0x1f) + assert (__builtin_cpu_is ("bdver2")); + break; + default: + break; + } +} + +/* Check if the ISA features are identified. */ +static void +check_features (unsigned int ecx, unsigned int edx, + int max_cpuid_level) +{ + if (edx & bit_CMOV) + assert (__builtin_cpu_supports ("cmov")); + if (edx & bit_MMX) + assert (__builtin_cpu_supports ("mmx")); + if (edx & bit_SSE) + assert (__builtin_cpu_supports ("sse")); + if (edx & bit_SSE2) + assert (__builtin_cpu_supports ("sse2")); + if (ecx & bit_POPCNT) + assert (__builtin_cpu_supports ("popcnt")); + if (ecx & bit_SSE3) + assert (__builtin_cpu_supports ("sse3")); + if (ecx & bit_SSSE3) + assert (__builtin_cpu_supports ("ssse3")); + if (ecx & bit_SSE4_1) + assert (__builtin_cpu_supports ("sse4.1")); + if (ecx & bit_SSE4_2) + assert (__builtin_cpu_supports ("sse4.2")); + if (ecx & bit_AVX) + assert (__builtin_cpu_supports ("avx")); + + /* Get advanced features at level 7 (eax = 7, ecx = 0). */ + if (max_cpuid_level >= 7) + { + unsigned int eax, ebx, ecx, edx; + __cpuid_count (7, 0, eax, ebx, ecx, edx); + if (ebx & bit_AVX2) + assert (__builtin_cpu_supports ("avx2")); + } +} + +static int __attribute__ ((noinline)) +__get_cpuid_output (unsigned int __level, + unsigned int *__eax, unsigned int *__ebx, + unsigned int *__ecx, unsigned int *__edx) +{ + return __get_cpuid (__level, __eax, __ebx, __ecx, __edx); +} + +static int +check_detailed () +{ + unsigned int eax, ebx, ecx, edx; + + int max_level; + unsigned int vendor; + unsigned int model, family, brand_id; + unsigned int extended_model, extended_family; + + /* Assume cpuid insn present. Run in level 0 to get vendor id. */ + if (!__get_cpuid_output (0, &eax, &ebx, &ecx, &edx)) + return 0; + + vendor = ebx; + max_level = eax; + + if (max_level < 1) + return 0; + + if (!__get_cpuid_output (1, &eax, &ebx, &ecx, &edx)) + return 0; + + model = (eax >> 4) & 0x0f; + family = (eax >> 8) & 0x0f; + brand_id = ebx & 0xff; + extended_model = (eax >> 12) & 0xf0; + extended_family = (eax >> 20) & 0xff; + + if (vendor == SIG_INTEL) + { + assert (__builtin_cpu_is ("intel")); + /* Adjust family and model for Intel CPUs. */ + if (family == 0x0f) + { + family += extended_family; + model += extended_model; + } + else if (family == 0x06) + model += extended_model; + check_intel_cpu_model (family, model, brand_id); + check_features (ecx, edx, max_level); + } + else if (vendor == SIG_AMD) + { + assert (__builtin_cpu_is ("amd")); + /* Adjust model and family for AMD CPUS. */ + if (family == 0x0f) + { + family += extended_family; + model += (extended_model << 4); + } + check_amd_cpu_model (family, model); + check_features (ecx, edx, max_level); + } + + return 0; +} + +static int +quick_check () +{ /* Check CPU Features. */ assert (__builtin_cpu_supports ("cmov") >= 0); @@ -68,5 +284,7 @@ int main () { __builtin_cpu_init (); - return fn1 (); + quick_check (); + check_detailed (); + return 0; }