200 lines
5.6 KiB
Perl
Executable File
200 lines
5.6 KiB
Perl
Executable File
#!/usr/bin/env perl
|
|
#############################################################################
|
|
##
|
|
## Copyright (C) 2018 Intel Corporation.
|
|
## Contact: https://www.qt.io/licensing/
|
|
##
|
|
## This file is part of the build configuration tools of the Qt Toolkit.
|
|
##
|
|
## $QT_BEGIN_LICENSE:MIT$
|
|
## Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
## of this software and associated documentation files (the "Software"), to deal
|
|
## in the Software without restriction, including without limitation the rights
|
|
## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
## copies of the Software, and to permit persons to whom the Software is
|
|
## furnished to do so, subject to the following conditions:
|
|
##
|
|
## The above copyright notice and this permission notice shall be included in
|
|
## all copies or substantial portions of the Software.
|
|
##
|
|
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
## AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
## THE SOFTWARE.
|
|
## $QT_END_LICENSE$
|
|
##
|
|
#############################################################################
|
|
|
|
use strict;
|
|
$\ = "\n";
|
|
$/ = "\n";
|
|
my %leaves = (
|
|
Leaf1EDX => "CPUID Leaf 1, EDX",
|
|
Leaf1ECX => "CPUID Leaf 1, ECX",
|
|
Leaf7_0EBX => "CPUID Leaf 7, Sub-leaf 0, EBX",
|
|
Leaf7_0ECX => "CPUID Leaf 7, Sub-leaf 0, ECX",
|
|
Leaf7_0EDX => "CPUID Leaf 7, Sub-leaf 0, EDX",
|
|
);
|
|
my @leafNames = sort keys %leaves;
|
|
|
|
# Read data from stdin
|
|
my $i = 1;
|
|
my @features;
|
|
while (<STDIN>) {
|
|
s/#.*$//;
|
|
chomp;
|
|
next if $_ eq "";
|
|
|
|
my ($name, $function, $bit, $depends) = split /\s+/;
|
|
die("Unknown CPUID function \"$function\"")
|
|
unless grep $function, @leafNames;
|
|
|
|
my $id = uc($name);
|
|
$id =~ s/[^A-Z0-9_]/_/g;
|
|
push @features,
|
|
{ name => $name, depends => $depends, id => $id, bit => $bit, leaf => $function };
|
|
++$i;
|
|
}
|
|
|
|
if (my $h = shift @ARGV) {
|
|
open HEADER, ">", $h;
|
|
select HEADER;
|
|
}
|
|
|
|
# Print the qsimd_x86_p.h output
|
|
print q{// This is a generated file. DO NOT EDIT.
|
|
// Please see util/x86simdgen/generate.pl";
|
|
#ifndef QSIMD_P_H
|
|
# error "Please include <private/qsimd_p.h> instead"
|
|
#endif
|
|
#ifndef QSIMD_X86_P_H
|
|
#define QSIMD_X86_P_H
|
|
|
|
#include "qsimd_p.h"
|
|
|
|
//
|
|
// W A R N I N G
|
|
// -------------
|
|
//
|
|
// This file is not part of the Qt API. It exists purely as an
|
|
// implementation detail. This header file may change from version to
|
|
// version without notice, or even be removed.
|
|
//
|
|
// We mean it.
|
|
//
|
|
|
|
QT_BEGIN_NAMESPACE
|
|
|
|
// used only to indicate that the CPU detection was initialized
|
|
#define QSimdInitialized (Q_UINT64_C(1) << 0)};
|
|
|
|
# Print the enum
|
|
my $lastleaf;
|
|
for (my $i = 0; $i < scalar @features; ++$i) {
|
|
my $feature = $features[$i];
|
|
# Leaf header:
|
|
printf "\n// in %s:\n", $leaves{$feature->{leaf}}
|
|
if $feature->{leaf} ne $lastleaf;
|
|
$lastleaf = $feature->{leaf};
|
|
|
|
# Feature
|
|
printf "#define CpuFeature%-33s (Q_UINT64_C(1) << %d)\n", $feature->{id}, $i + 1;
|
|
|
|
# Feature string names for Clang and GCC
|
|
my $str = $feature->{name};
|
|
$str .= ",$feature->{depends}" if defined($feature->{depends});
|
|
printf "#define QT_FUNCTION_TARGET_STRING_%-17s \"%s\"\n",
|
|
$feature->{id}, $str;
|
|
}
|
|
|
|
print q{
|
|
static const quint64 qCompilerCpuFeatures = 0};
|
|
|
|
# And print the compiler-enabled features part:
|
|
for (my $i = 0; $i < scalar @features; ++$i) {
|
|
my $feature = $features[$i];
|
|
printf
|
|
"#ifdef __%s__\n" .
|
|
" | CpuFeature%s\n" .
|
|
"#endif\n",
|
|
$feature->{id}, $feature->{id};
|
|
}
|
|
|
|
print q{ ;
|
|
|
|
QT_END_NAMESPACE
|
|
|
|
#endif // QSIMD_X86_P_H
|
|
};
|
|
|
|
if (my $cpp = shift @ARGV) {
|
|
open CPP, ">", $cpp;
|
|
select CPP;
|
|
} else {
|
|
print q{
|
|
|
|
---- cut here, paste the rest into qsimd_x86.cpp ---
|
|
|
|
|
|
};
|
|
};
|
|
|
|
print "// This is a generated file. DO NOT EDIT.";
|
|
print "// Please see util/x86simdgen/generate.pl";
|
|
print '#include "qsimd_p.h"';
|
|
print "";
|
|
|
|
# Now generate the string table and bit-location array
|
|
my $offset = 0;
|
|
my @offsets;
|
|
print "static const char features_string[] =";
|
|
for my $feature (@features) {
|
|
print " \" $feature->{name}\\0\"";
|
|
push @offsets, $offset;
|
|
$offset += 2 + length($feature->{name});
|
|
}
|
|
print " \"\\0\";";
|
|
|
|
# Print the string offset table
|
|
printf "\nstatic const %s features_indices[] = {\n %3d",
|
|
$offset > 255 ? "quint16" : "quint8", $offset;
|
|
for (my $j = 0; $j < scalar @offsets; ++$j) {
|
|
printf ",%s%3d",
|
|
($j + 1) % 8 ? " " : "\n ", $offsets[$j];
|
|
}
|
|
print "\n};";
|
|
|
|
# Print the locator enum and table
|
|
print "\nenum X86CpuidLeaves {";
|
|
map { print " $_," } @leafNames;
|
|
print " X86CpuidMaxLeaf\n};";
|
|
|
|
my $type = scalar %leaves > 8 ? "quint16" : "quint8";
|
|
printf "\nstatic const %s x86_locators[] = {",
|
|
$type, $type;
|
|
my $lastname;
|
|
for (my $j = 0; $j < scalar @features; ++$j) {
|
|
my $feature = $features[$j];
|
|
printf ", // %s", $lastname
|
|
if defined($lastname);
|
|
printf "\n %s*32 + %2d",
|
|
$feature->{leaf}, $feature->{bit};
|
|
$lastname = $feature->{name};
|
|
}
|
|
printf qq{ // $lastname
|
|
\};
|
|
|
|
// List of AVX512 features (see detectProcessorFeatures())
|
|
static const quint64 AllAVX512 = 0};
|
|
|
|
# Print AVX512 features
|
|
for (my $j = 0; $j < scalar @features; ++$j) {
|
|
my $feature = $features[$j];
|
|
$_ = $feature->{id};
|
|
printf "\n | CpuFeature%s", $_ if /AVX512/;
|
|
}
|
|
print ";";
|