summaryrefslogtreecommitdiffstats
path: root/util/x86simdgen
diff options
context:
space:
mode:
Diffstat (limited to 'util/x86simdgen')
-rwxr-xr-xutil/x86simdgen/generate.pl192
-rw-r--r--util/x86simdgen/simd.txt37
2 files changed, 229 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};";
diff --git a/util/x86simdgen/simd.txt b/util/x86simdgen/simd.txt
new file mode 100644
index 0000000000..1fce7b9497
--- /dev/null
+++ b/util/x86simdgen/simd.txt
@@ -0,0 +1,37 @@
+# Feature CPUID function Bit Required feature
+sse2 Leaf1EDX 26
+sse3 Leaf1ECX 0
+ssse3 Leaf1ECX 9
+fma Leaf1ECX 12
+sse4.1 Leaf1ECX 19
+sse4.2 Leaf1ECX 20
+movbe Leaf1ECX 22
+popcnt Leaf1ECX 23
+aes Leaf1ECX 25 sse4.2
+avx Leaf1ECX 28
+f16c Leaf1ECX 29
+rdrnd Leaf1ECX 30
+bmi Leaf7_0EBX 3
+hle Leaf7_0EBX 4
+avx2 Leaf7_0EBX 5
+bmi2 Leaf7_0EBX 8
+rtm Leaf7_0EBX 11
+avx512f Leaf7_0EBX 16
+avx512dq Leaf7_0EBX 17
+rdseed Leaf7_0EBX 18
+avx512ifma Leaf7_0EBX 21
+avx512pf Leaf7_0EBX 26
+avx512er Leaf7_0EBX 27
+avx512cd Leaf7_0EBX 28
+sha Leaf7_0EBX 29
+avx512bw Leaf7_0EBX 30
+avx512vl Leaf7_0EBX 31
+avx512vbmi Leaf7_0ECX 1
+avx512vbmi2 Leaf7_0ECX 6
+gfni Leaf7_0ECX 8
+vaes Leaf7_0ECX 9
+avx512vnni Leaf7_0ECX 11
+avx512bitalg Leaf7_0ECX 12
+avx512vpopcntdq Leaf7_0ECX 14
+avx5124nniw Leaf7_0EDX 2
+avx5124fmaps Leaf7_0EDX 3