diff options
Diffstat (limited to 'util/x86simdgen/generate.pl')
-rwxr-xr-x | util/x86simdgen/generate.pl | 192 |
1 files changed, 192 insertions, 0 deletions
diff --git a/util/x86simdgen/generate.pl b/util/x86simdgen/generate.pl new file mode 100755 index 0000000000..572891d483 --- /dev/null +++ b/util/x86simdgen/generate.pl @@ -0,0 +1,192 @@ +#!/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 + +// Macros for QT_FUNCTION_TARGET (for Clang and GCC)}; + +# #Define the feature string names for Clang and GCC +for my $feature (@features) { + my $str = $feature->{name}; + $str .= ",$feature->{depends}" if defined($feature->{depends}); + printf "#define QT_FUNCTION_TARGET_STRING_%-17s \"%s\"\n", + $feature->{id}, $str; +} + +# Print the enum +printf "\nenum CPUFeatures {"; +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 " CpuFeature%-13s = %d,\n", $feature->{id}, $i + 1; +} + +print q{ + // used only to indicate that the CPU detection was initialized + QSimdInitialized = 1 +\}; + +static const quint64 qCompilerCpuFeatures = 0}; + +# And print the compiler-enabled features part: +for my $feature (@features) { + printf + "#ifdef __%s__\n" . + " | (Q_UINT64_C(1) << 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 <qglobal.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}; +} +print " // $lastname\n};"; |