AX_GCC_ARCHFLAG x86 rewrite details (2014-08-16...2014-11-02)
This is a memo which may (or may not) help reading/writing new versions of AX_GCC_ARCHFLAG Autoconf macro.
UPDATE: The proposed patch of mine was applied to the latest version of autoconf-archive and new version (based on my new CPUID research) will be pull-requested.
CPUID Pattern Simplifications
There are some notable changes regarding pattern simplifications.
- Some CPUID patterns for K7 and K8-based AMD processors were "too fine" and there's no need to test because most of compilers merge support for minor differences.
- Removed distinct CPUID patterns for "too fine" cases. Most of compilers MERGE AND IGNORE support for minor differences (except microprocessor and specification changes). For instance, all athlon64, opteron and k8 options are used to specify K8-based processors (without SSE3 support) but frequently used versions of GCC, Clang and Open64 handle them equivalently. Even if we have differences, they are no longer significant.
- K7 (Palomino and later) : athlon-4 and athlon-fx
- K8 (before SSE3 support) : k8, athlon64 and opteron
- K8 (after SSE3 support) : k8-sse3, athlon64-sse3 and opteron-sse3
- Removed L2 size test (for Palomino-based K7 processors) because of the reason described above.
- Removed distinct CPUID patterns for "too fine" cases. Most of compilers MERGE AND IGNORE support for minor differences (except microprocessor and specification changes). For instance, all athlon64, opteron and k8 options are used to specify K8-based processors (without SSE3 support) but frequently used versions of GCC, Clang and Open64 handle them equivalently. Even if we have differences, they are no longer significant.
- Removed $host_cpu test for "nocona" and "prescott" because all Nocona is 64-bit Prescott-based architecture option (strictly, "prescott" option is a 32-bit variant of "nocona" in GCC) and thus we can simplify the test by testing both "nocona" and "prescott" without testing the architecture.
- Removed "too fine" CPUID test for Intel family 06 model 0A. The original version tested additional bits to identify unknown Pentium II-based processors. Although they might be engineering sample versions of "Pentium II Xeon" but THEY ARE NEVER RELEASED. So we can handle Intel family 06 model 0A as "Pentium III Xeon" as documented in the Intel's CPUID specification.
CPU Architectures and Compiler Flags
Older versions of this page contained complete list of CPUIDs used. Now it has been moved to another page (x86 Families and Models) and "architecture" choices list is minimized. See corresponding "architecture name" in x86 Families and Models page.
Vendor | Architecture | Choices |
Intel | 486 | |
Intel | Quark | |
Intel | Pentium | pentium |
Intel | Pentium MMX | pentium-mmx |
Intel | Pentium Pro | pentiumpro |
Intel | Pentium II | pentium2 |
Intel | Pentium III | pentium3 |
Intel | Pentium 4 | pentium4 |
Intel | Nocona / Prescott | nocona / prescott |
Intel | Pentium M | pentium-m |
Intel | Core (Yonah) | yonah / pentium-m |
Intel | Core 2 | core2 |
Intel | Core 2 (Penryn) | penryn / core2 |
Intel | Nehalem | nehalem / corei7 |
Intel | Westmere | westmere / corei7 |
Intel | Sandy Bridge | sandybridge / corei7-avx |
Intel | Ivy Bridge | ivybridge / core-avx-i |
Intel | Haswell | haswell / core-avx2 |
Intel | Broadwell | broadwell / core-avx2 |
Intel | Bonnell | bonnell / atom |
Intel | Silvermont | silvermont / slm / atom |
AMD | Am486 | |
AMD | Am5x86 | |
AMD | K5 | |
AMD | K6 | k6 |
AMD | K6-2 | k6-2 |
AMD | K6-3 | k6-3 |
AMD | K7 | athlon |
AMD | K7 (Thunderbird) | athlon-tbird |
AMD | K7 (Palomino+) | athlon-xp |
AMD | K8 | athlon64 |
AMD | K8 (rev.E+) | athlon64-sse3 |
AMD | K10 | barcelona / amdfam10 |
AMD | Bulldozer | bdver1 |
AMD | Piledriver | bdver2 |
AMD | Steamroller | bdver3 |
AMD | Bobcat | btver1 |
AMD | Jaguar | btver2 |
Centaur | WinChip C6 | winchip-c6 |
Centaur | WinChip 2 | winchip2 |
Centaur | WinChip 3 | winchip2 |
Centaur | WinChip-based | winchip2 |
Centaur | C3 | winchip2 |
Centaur | C3-2 | c3-2 |
Centaur | C7 | c3-2 |
Centaur | Isaiah | c3-2 |
CPU Models: Cannot be Confirmed
These patterns are removed from the original version of AX_GCC_ARCHFLAG macro. If "Remove All?" column is no, some of (not all) patterns are removed from the original version.
Vendor | Family (hex) | Model (hex) | Remove All? | Arch | Brand names | Choices |
Intel | 06 | 04 | Yes | |||
Intel | 06 | 0A | No | Pentium III | See corresponding paragraph for details | pentium3 |
AMD | 06 | 00 | Yes |
Pattern Generator Code
The following code is used to generate pattern. This will work on Arch Linux + Python3. The license of this script is the ISC License (a variant of 2-clause BSD License).
#! /usr/bin/env python
#
#
# CPUID pattern generator
#
# Copyright (C) 2014 Tsukasa OI.
#
# Permission to use, copy, modify, and/or distribute this software for
# any purpose with or without fee is hereby granted, provided that the
# above copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
#
import sys
import re
# pattern to simplify:
# - O (oh) : reserved bits as prefixes
# - 0 (zero) : zero
# - ? : reserved or "any"
# - 1-9a-f : corresponding hex representation
def simplify_pattern(pattern):
pattern = re.sub('^([O]+[?]*|[O]*[?]+)', '*', pattern)
return subsimplify_pattern(pattern)
def subsimplify_pattern(pattern):
if (pattern.startswith('*0') or pattern.startswith('?0')) \
and pattern != '*0' and pattern != '?0':
return pattern + '|' + subsimplify_pattern(re.sub('^..', '', pattern))
if pattern.startswith('0') and pattern != '0':
return subsimplify_pattern(pattern[1:])
if pattern.startswith('?') and pattern != '?':
return pattern + '|' + subsimplify_pattern(pattern[1:])
return pattern
def identify_intel(args):
display_family = int(args[0], 16)
display_model = int(args[1], 16) if len(args) > 1 else '??'
print('Identification for Intel:')
print('\tDisplay Family : {:02x}'.format(display_family))
if display_model == '??':
print('\tDisplay Model : ??')
else:
print('\tDisplay Model : {:02x}'.format(display_model))
if display_family >= 0x0f:
family_0 = 'f'
family_1 = '{:02x}'.format(display_family - 0x0f)
else:
family_0 = '{:01x}'.format(display_family)
family_1 = 'OO'
if display_model == '??':
model_1 = '?'
model_0 = '?'
elif display_family >= 0x0f or display_family == 0x06:
model_1 = '{:01x}'.format(display_model >> 4)
model_0 = '{:01x}'.format(display_model & 0x0f)
else:
if display_model >= 0x10:
raise ValueError()
model_1 = 'O'
model_0 = '{:01x}'.format(display_model)
pattern = 'O{}{}?{}{}?'.format(family_1, model_1, family_0, model_0)
print('\tPattern : {}'.format(pattern))
print('\tPatterns simpl : {}'.format(simplify_pattern(pattern)))
def identify_amd(args):
display_family = int(args[0], 16)
display_model = int(args[1], 16) if len(args) > 1 else '??'
print('Identification for AMD:')
print('\tDisplay Family : {:02x}'.format(display_family))
if display_model == '??':
print('\tDisplay Model : ??')
else:
print('\tDisplay Model : {:02x}'.format(display_model))
if display_family >= 0x0f:
family_0 = 'f'
family_1 = '{:02x}'.format(display_family - 0x0f)
else:
family_0 = '{:01x}'.format(display_family)
family_1 = 'OO'
if display_model == '??':
model_1 = '?'
model_0 = '?'
elif display_family >= 0x0f:
model_1 = '{:01x}'.format(display_model >> 4)
model_0 = '{:01x}'.format(display_model & 0x0f)
else:
if display_model >= 0x10:
raise ValueError()
model_1 = 'O'
model_0 = '{:01x}'.format(display_model)
pattern = 'O{}{}?{}{}?'.format(family_1, model_1, family_0, model_0)
print('\tPattern : {}'.format(pattern))
print('\tPatterns simpl : {}'.format(simplify_pattern(pattern)))
def identify_other_x86(args):
display_family = int(args[0], 16)
display_model = int(args[1], 16) if len(args) > 1 else '?'
print('Identification for VIA and other processors without extended family/model:')
print('\tDisplay Family : {:01x}'.format(display_family))
if display_model == '?':
print('\tDisplay Model : ?')
else:
print('\tDisplay Model : {:01x}'.format(display_model))
if display_family >= 0x10:
raise ValueError()
if display_model >= 0x10:
raise ValueError()
pattern = 'OOO?{:01x}{}?'.format(display_family, '?' if display_model == '?' else '{:01x}'.format(display_model))
print('\tPattern : {}'.format(pattern))
print('\tPatterns simpl : {}'.format(simplify_pattern(pattern)))
def identify_bitmask(hexsize, args):
bitpos = int(args[0])
bitval = 1
if len(args) > 1:
bitval = int(args[1])
hexpos = bitpos % 4
hexary = []
print('Identification for {}-bit mask:'.format(hexsize*4))
for i in range(16):
if (i & (1 << hexpos)) == (bitval << hexpos):
hexary.append('{:01x}'.format(i))
for x in hexary:
print('\tPattern : {}'.format(simplify_pattern((hexsize - 1 - bitpos//4) * 'O' + x + (bitpos//4) * '?')))
if sys.argv[1] == 'intel':
identify_intel(sys.argv[2:])
elif sys.argv[1] == 'amd':
identify_amd(sys.argv[2:])
elif sys.argv[1] == 'other':
identify_other_x86(sys.argv[2:])
elif sys.argv[1] == '32bit':
identify_bitmask(8, sys.argv[2:])