This patch adds a new target builtin, __builtin_cpu_is_amdfam15, to check for AMD Family 15h processors.
* i386-cpuinfo.c (__cpu_is_amdfam15): New member in __cpu_model struct. (get_amd_cpu): Check for family 15h processors. (cpu_indicator_init): Adjust model and family for AMD processors. Refactor code. * i386.c (IX86_BUILTIN_CPU_IS_AMDFAM15): New enum value. (fold_builtin_cpu): Process IX86_BUILTIN_CPU_IS_AMDFAM15. (ix86_init_platform_type_builtins): Make new builtin _builtin_cpu_is_amdfam15. (ix86_expand_builtin): Expand IX86_BUILTIN_CPU_IS_AMDFAM15. * testsuite/gcc.target/builtin_target.c (fn1): Call __builtin_cpu_is_amdfam15. Index: libgcc/config/i386/i386-cpuinfo.c =================================================================== --- libgcc/config/i386/i386-cpuinfo.c (revision 183073) +++ libgcc/config/i386/i386-cpuinfo.c (working copy) @@ -63,6 +63,7 @@ struct __processor_model unsigned int __cpu_is_amdfam10_barcelona : 1; unsigned int __cpu_is_amdfam10_shanghai : 1; unsigned int __cpu_is_amdfam10_istanbul : 1; + unsigned int __cpu_is_amdfam15 : 1; } __cpu_model; /* Get the specific type of AMD CPU. */ @@ -72,18 +73,22 @@ get_amd_cpu (unsigned int family, unsigned int mod { switch (family) { + /* AMD Family 10h. */ case 0x10: switch (model) { case 0x2: + /* Barcelona. */ __cpu_model.__cpu_is_amdfam10 = 1; __cpu_model.__cpu_is_amdfam10_barcelona = 1; break; case 0x4: + /* Shanghai. */ __cpu_model.__cpu_is_amdfam10 = 1; __cpu_model.__cpu_is_amdfam10_shanghai = 1; break; case 0x8: + /* Istanbul. */ __cpu_model.__cpu_is_amdfam10 = 1; __cpu_model.__cpu_is_amdfam10_istanbul = 1; break; @@ -91,6 +96,10 @@ get_amd_cpu (unsigned int family, unsigned int mod break; } break; + /* AMD Family 15h. */ + case 0x15: + __cpu_model.__cpu_is_amdfam15 = 1; + break; default: break; } @@ -223,6 +232,7 @@ __cpu_indicator_init (void) int max_level = 5; unsigned int vendor; unsigned int model, family, brand_id; + unsigned int extended_model, extended_family; static int called = 0; /* This function needs to run just once. */ @@ -247,14 +257,12 @@ __cpu_indicator_init (void) model = (eax >> 4) & 0x0f; family = (eax >> 8) & 0x0f; brand_id = ebx & 0xff; + extended_model = (eax >> 12) & 0xf0; + extended_family = (eax >> 20) & 0xff; - /* Adjust model and family for Intel CPUS. */ if (vendor == SIG_INTEL) { - unsigned int extended_model, extended_family; - - extended_model = (eax >> 12) & 0xf0; - extended_family = (eax >> 20) & 0xff; + /* Adjust model and family for Intel CPUS. */ if (family == 0x0f) { family += extended_family; @@ -262,20 +270,25 @@ __cpu_indicator_init (void) } else if (family == 0x06) model += extended_model; + + /* Get CPU type. */ + __cpu_model.__cpu_is_intel = 1; + get_intel_cpu (family, model, brand_id); } - /* Find CPU model. */ - if (vendor == SIG_AMD) { + /* Adjust model and family for AMD CPUS. */ + if (family == 0x0f) + { + family += extended_family; + model += (extended_model << 4); + } + + /* Get CPU type. */ __cpu_model.__cpu_is_amd = 1; get_amd_cpu (family, model); } - else if (vendor == SIG_INTEL) - { - __cpu_model.__cpu_is_intel = 1; - get_intel_cpu (family, model, brand_id); - } /* Find available features. */ get_available_features (ecx, edx); Index: gcc/testsuite/gcc.target/i386/builtin_target.c =================================================================== --- gcc/testsuite/gcc.target/i386/builtin_target.c (revision 183073) +++ gcc/testsuite/gcc.target/i386/builtin_target.c (working copy) @@ -47,6 +47,8 @@ fn1 () return -1; if (__builtin_cpu_is_amdfam10_istanbul () < 0) return -1; + if (__builtin_cpu_is_amdfam15 () < 0) + return -1; return 0; } Index: gcc/config/i386/i386.c =================================================================== --- gcc/config/i386/i386.c (revision 183073) +++ gcc/config/i386/i386.c (working copy) @@ -24545,6 +24545,7 @@ enum ix86_builtins IX86_BUILTIN_CPU_IS_AMDFAM10_BARCELONA, IX86_BUILTIN_CPU_IS_AMDFAM10_SHANGHAI, IX86_BUILTIN_CPU_IS_AMDFAM10_ISTANBUL, + IX86_BUILTIN_CPU_IS_AMDFAM15, IX86_BUILTIN_MAX }; @@ -26028,6 +26029,7 @@ fold_builtin_cpu (enum ix86_builtins fn_code) M_AMDFAM10_BARCELONA, M_AMDFAM10_SHANGHAI, M_AMDFAM10_ISTANBUL, + M_AMDFAM15, M_MAX }; @@ -26149,6 +26151,11 @@ fold_builtin_cpu (enum ix86_builtins fn_code) M_AMDFAM10_ISTANBUL); which_struct = __cpu_model_var; break; + case IX86_BUILTIN_CPU_IS_AMDFAM15: + field = get_field_from_struct (__processor_model_type, + M_AMDFAM15); + which_struct = __cpu_model_var; + break; default: return NULL_TREE; } @@ -26721,6 +26728,8 @@ ix86_init_platform_type_builtins (void) IX86_BUILTIN_CPU_IS_AMDFAM10_SHANGHAI, 1); make_platform_builtin ("__builtin_cpu_is_amdfam10_istanbul", IX86_BUILTIN_CPU_IS_AMDFAM10_ISTANBUL, 1); + make_platform_builtin ("__builtin_cpu_is_amdfam15", + IX86_BUILTIN_CPU_IS_AMDFAM15, 1); } /* Detect if this unaligned vectorizable load/stores should be @@ -28307,6 +28316,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx sub case IX86_BUILTIN_CPU_IS_AMDFAM10_BARCELONA: case IX86_BUILTIN_CPU_IS_AMDFAM10_SHANGHAI: case IX86_BUILTIN_CPU_IS_AMDFAM10_ISTANBUL: + case IX86_BUILTIN_CPU_IS_AMDFAM15: { tree fold_expr = fold_builtin_cpu ((enum ix86_builtins) fcode); gcc_assert (fold_expr != NULL_TREE); -- This patch is available for review at http://codereview.appspot.com/5535046