From 0a3c2fe2f3f60c15be0ade21f408c8052e89bb8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Sat, 8 Nov 2025 23:24:32 +0100 Subject: [PATCH 01/23] add workflow & skeleton generator --- .../actions/verify-generated-files/action.yml | 1 + .../download-bundled/make-workflow-file.php | 181 ++++++++++++++++++ .github/workflows/verify-bundled-files.yml | 4 +- 3 files changed, 184 insertions(+), 2 deletions(-) create mode 100644 .github/scripts/download-bundled/make-workflow-file.php diff --git a/.github/actions/verify-generated-files/action.yml b/.github/actions/verify-generated-files/action.yml index 79c49dbfcfffb..3f3dea73c4dcd 100644 --- a/.github/actions/verify-generated-files/action.yml +++ b/.github/actions/verify-generated-files/action.yml @@ -13,4 +13,5 @@ runs: ext/tokenizer/tokenizer_data_gen.php build/gen_stub.php -f --generate-optimizer-info --verify ext/phar/makestub.php + .github/scripts/download-bundled/make-workflow-file.php .github/scripts/test-directory-unchanged.sh . diff --git a/.github/scripts/download-bundled/make-workflow-file.php b/.github/scripts/download-bundled/make-workflow-file.php new file mode 100644 index 0000000000000..7f986f552af48 --- /dev/null +++ b/.github/scripts/download-bundled/make-workflow-file.php @@ -0,0 +1,181 @@ + $directories + */ + public function __construct( + public string $name, + public array $directories + ) {} + + public function getNameForPath(): string + { + return preg_replace('~\W+~', '-', strtolower($this->name)); + } +} + +class Generator +{ + /** + * @param list $bundles + */ + public function __construct( + public array $bundles + ) {} + + protected function getRepoDirectory(): string + { + return dirname(__DIR__, 3); + } + + protected function indentString(string $value, int $levels, bool $inclFirstLine): string + { + return preg_replace( + '~' . ($inclFirstLine ? '^|' : '') . '(?<=\n)~', + str_repeat(' ', $levels), + $value + ); + } + + /** + * @param mixed $data + */ + protected function encodeYml($data): string + { + if (is_array($data)) { + $isList = array_is_list($data); + $resParts = []; + foreach ($data as $k => $v) { + $kEncoded = $isList + ? '-' + : $this->encodeYml($k) . ':'; + $vEncoded = $this->encodeYml($v); + + $resParts[] = $kEncoded + . (!$isList && is_array($v) && $v !== [] ? "\n " : ' ') + . (is_array($v) ? $this->indentString($vEncoded, 1, false) : $vEncoded); + } + + return implode("\n", $resParts); + } + + if (preg_match('~^(\w+|\$\{\{[^\}]+\}\})$~', $data)) { + return $data; + } + + return strpos($data, "\n") !== false + ? '|' . "\n" . $this->indentString($data, 1, true) + : '\'' . str_replace('\'', '\'\'', $data) . '\''; + } + + public function makeWorkflowFile(): void + { + $content = <<<'EOD' + name: Verify Bundled Files + + on: + push: ~ + pull_request: ~ + schedule: + - cron: "0 1 * * *" + workflow_dispatch: ~ + + permissions: + contents: read + + jobs: + VERIFY_BUNDLED_FILES: + name: Verify Bundled Files + runs-on: ubuntu-24.04 + steps: + - name: git checkout + uses: actions/checkout@v5 + + - name: Detect changed files + uses: dorny/paths-filter@v3 + id: changes + with: + base: master + filters: %filters% + + %steps% + + EOD; + + $filters = []; + foreach ($this->bundles as $bundle) { + $filters[$bundle->getNameForPath()] = $this->makeDornyPathsFilterFilters($bundle); + } + $content = str_replace('%filters%', $this->indentString($this->encodeYml($this->encodeYml($filters)), 5, false), $content); + + $steps = []; + foreach ($this->bundles as $bundle) { + $steps[] = [ + 'name' => $bundle->name, + 'if' => '${{ !cancelled() && (steps.changes.outputs.pcre2 == \'true\' || github.event_name == \'schedule\' || github.event_name == \'workflow_dispatch\') }}', + 'run' => implode("\n", [ + 'echo "::group::Download"', + '.github/scripts/download-bundled/' . $bundle->getNameForPath() . '.sh', + 'echo "::endgroup::"', + 'echo "::group::Verify files"', + ...array_map(static fn ($v) => '.github/scripts/test-directory-unchanged.sh ' . escapeshellarg($v), $bundle->directories), + 'echo "::endgroup::"', + ]), + ]; + } + $content = str_replace('%steps%', $this->indentString($this->encodeYml($steps), 3, false), $content); + + file_put_contents($this->getRepoDirectory() . '/.github/workflows/verify-bundled-files.yml', $content); + } + + protected function makeDornyPathsFilterFilters(Bundle $bundle): array + { + return [ + '.github/scripts/download-bundled/' . $bundle->getNameForPath() . '.*', + ...array_map(static fn ($v) => $v . '/**', $bundle->directories), + ]; + } + + public function makeDownloadScriptHeaders(): void + { + foreach ($this->bundles as $bundle) { + $this->makeDownloadScriptHeader($bundle); + } + } + + protected function makeDownloadScriptHeader(Bundle $bundle): void + { + $scriptPath = $this->getRepoDirectory() . '/.github/scripts/download-bundled/' . $bundle->getNameForPath() . '.sh'; + + $content = !file_exists($scriptPath) + ? "# TODO\n" + : file_get_contents($scriptPath); + + $header = <<<'EOD' + #!/bin/sh + set -ex + cd "$(dirname "$0")/../../.." + + + EOD; + if (!str_starts_with($content, $header)) { + $content = $header . $content; + } + + file_put_contents($scriptPath, $content); + } +} + +$generator = new Generator($bundles); +$generator->makeWorkflowFile(); +$generator->makeDownloadScriptHeaders(); diff --git a/.github/workflows/verify-bundled-files.yml b/.github/workflows/verify-bundled-files.yml index e15fcb36a0e7a..bd3bc8ee53d25 100644 --- a/.github/workflows/verify-bundled-files.yml +++ b/.github/workflows/verify-bundled-files.yml @@ -29,7 +29,7 @@ jobs: base: master filters: | pcre2: - - '.github/scripts/download-bundled/pcre2.sh' + - '.github/scripts/download-bundled/pcre2.*' - 'ext/pcre/pcre2lib/**' - name: PCRE2 @@ -39,5 +39,5 @@ jobs: .github/scripts/download-bundled/pcre2.sh echo "::endgroup::" echo "::group::Verify files" - .github/scripts/test-directory-unchanged.sh ext/pcre/pcre2lib + .github/scripts/test-directory-unchanged.sh "ext/pcre/pcre2lib" echo "::endgroup::" From bcac56b72587df422e24945c690b235233107d83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Sat, 8 Nov 2025 23:37:18 +0100 Subject: [PATCH 02/23] add download for boost.context --- .../scripts/download-bundled/boost-context.sh | 38 +++++++++++++++++++ .../download-bundled/make-workflow-file.php | 1 + .github/workflows/verify-bundled-files.yml | 12 ++++++ 3 files changed, 51 insertions(+) create mode 100755 .github/scripts/download-bundled/boost-context.sh diff --git a/.github/scripts/download-bundled/boost-context.sh b/.github/scripts/download-bundled/boost-context.sh new file mode 100755 index 0000000000000..d92425df4cec3 --- /dev/null +++ b/.github/scripts/download-bundled/boost-context.sh @@ -0,0 +1,38 @@ +#!/bin/sh +set -ex +cd "$(dirname "$0")/../../.." + +revision=refs/tags/boost-1.86.0 + +git clone --depth 1 --revision="$revision" https://github.com/boostorg/context.git /tmp/php-src-bundled/boost-context + +rm -rf Zend/asm +cp -R /tmp/php-src-bundled/boost-context/src/asm Zend/asm + +cd Zend/asm + +# remove unneeded files +rm jump_arm_aapcs_pe_armasm.asm +rm jump_i386_ms_pe_clang_gas.S +rm jump_i386_ms_pe_gas.asm +rm jump_i386_x86_64_sysv_macho_gas.S +rm jump_ppc32_ppc64_sysv_macho_gas.S +rm jump_x86_64_ms_pe_clang_gas.S +rm make_arm_aapcs_pe_armasm.asm +rm make_i386_ms_pe_clang_gas.S +rm make_i386_ms_pe_gas.asm +rm make_i386_x86_64_sysv_macho_gas.S +rm make_ppc32_ppc64_sysv_macho_gas.S +rm make_x86_64_ms_pe_clang_gas.S +rm ontop_*.S +rm ontop_*.asm +rm tail_ontop_ppc32_sysv.cpp + +# move renamed files +# GH-13896 introduced these 2 files named as .S but since https://github.com/boostorg/context/pull/265 they are named as .asm +mv jump_x86_64_ms_pe_gas.asm jump_x86_64_ms_pe_gas.S +mv make_x86_64_ms_pe_gas.asm make_x86_64_ms_pe_gas.S + +# add extra files +git restore LICENSE +git restore save_xmm_x86_64_ms_masm.asm # added in GH-18352, not an upstream boost.context file diff --git a/.github/scripts/download-bundled/make-workflow-file.php b/.github/scripts/download-bundled/make-workflow-file.php index 7f986f552af48..43c4d707881c3 100644 --- a/.github/scripts/download-bundled/make-workflow-file.php +++ b/.github/scripts/download-bundled/make-workflow-file.php @@ -5,6 +5,7 @@ namespace Phpsrc\Ci\DownloadBundled; $bundles = [ + new Bundle('boost.context', ['Zend/asm']), new Bundle('PCRE2', ['ext/pcre/pcre2lib']), ]; diff --git a/.github/workflows/verify-bundled-files.yml b/.github/workflows/verify-bundled-files.yml index bd3bc8ee53d25..b1f0546b63049 100644 --- a/.github/workflows/verify-bundled-files.yml +++ b/.github/workflows/verify-bundled-files.yml @@ -28,10 +28,22 @@ jobs: with: base: master filters: | + 'boost-context': + - '.github/scripts/download-bundled/boost-context.*' + - 'Zend/asm/**' pcre2: - '.github/scripts/download-bundled/pcre2.*' - 'ext/pcre/pcre2lib/**' + - name: 'boost.context' + if: ${{ !cancelled() && (steps.changes.outputs.pcre2 == 'true' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') }} + run: | + echo "::group::Download" + .github/scripts/download-bundled/boost-context.sh + echo "::endgroup::" + echo "::group::Verify files" + .github/scripts/test-directory-unchanged.sh "Zend/asm" + echo "::endgroup::" - name: PCRE2 if: ${{ !cancelled() && (steps.changes.outputs.pcre2 == 'true' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') }} run: | From 38b674181f6be662189595ee3bcdee695450c9a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Mon, 10 Nov 2025 00:27:41 +0100 Subject: [PATCH 03/23] unify/generate tmp_dir --- .github/scripts/download-bundled/boost-context.sh | 7 +++++-- .github/scripts/download-bundled/make-workflow-file.php | 6 ++++++ .github/scripts/download-bundled/pcre2.sh | 7 +++++-- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/.github/scripts/download-bundled/boost-context.sh b/.github/scripts/download-bundled/boost-context.sh index d92425df4cec3..b1fd8708b85b6 100755 --- a/.github/scripts/download-bundled/boost-context.sh +++ b/.github/scripts/download-bundled/boost-context.sh @@ -2,12 +2,15 @@ set -ex cd "$(dirname "$0")/../../.." +tmp_dir=/tmp/php-src-download-bundled/boost-context +rm -rf "$tmp_dir" + revision=refs/tags/boost-1.86.0 -git clone --depth 1 --revision="$revision" https://github.com/boostorg/context.git /tmp/php-src-bundled/boost-context +git clone --depth 1 --revision="$revision" https://github.com/boostorg/context.git "$tmp_dir" rm -rf Zend/asm -cp -R /tmp/php-src-bundled/boost-context/src/asm Zend/asm +cp -R "$tmp_dir"/src/asm Zend/asm cd Zend/asm diff --git a/.github/scripts/download-bundled/make-workflow-file.php b/.github/scripts/download-bundled/make-workflow-file.php index 43c4d707881c3..f907bc663bbab 100644 --- a/.github/scripts/download-bundled/make-workflow-file.php +++ b/.github/scripts/download-bundled/make-workflow-file.php @@ -167,8 +167,14 @@ protected function makeDownloadScriptHeader(Bundle $bundle): void set -ex cd "$(dirname "$0")/../../.." + tmp_dir=%tmp_dir% + rm -rf "$tmp_dir" + EOD; + + $header = str_replace('%tmp_dir%', '/tmp/php-src-download-bundled/' . $bundle->getNameForPath(), $header); + if (!str_starts_with($content, $header)) { $content = $header . $content; } diff --git a/.github/scripts/download-bundled/pcre2.sh b/.github/scripts/download-bundled/pcre2.sh index b43554206c929..360cbb91db824 100755 --- a/.github/scripts/download-bundled/pcre2.sh +++ b/.github/scripts/download-bundled/pcre2.sh @@ -2,12 +2,15 @@ set -ex cd "$(dirname "$0")/../../.." +tmp_dir=/tmp/php-src-download-bundled/pcre2 +rm -rf "$tmp_dir" + revision=refs/tags/pcre2-10.44 -git clone --depth 1 --recurse-submodules --revision="$revision" https://github.com/PCRE2Project/pcre2.git /tmp/php-src-bundled/pcre2 +git clone --depth 1 --recurse-submodules --revision="$revision" https://github.com/PCRE2Project/pcre2.git "$tmp_dir" rm -rf ext/pcre/pcre2lib -cp -R /tmp/php-src-bundled/pcre2/src ext/pcre/pcre2lib +cp -R "$tmp_dir"/src ext/pcre/pcre2lib cd ext/pcre/pcre2lib From 20e42c1a199a3e66cae3d66f77380153a1fd4922 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Mon, 10 Nov 2025 00:41:30 +0100 Subject: [PATCH 04/23] add uriparser ci --- .../download-bundled/make-workflow-file.php | 1 + .github/scripts/download-bundled/uriparser.sh | 21 +++++++++++++++++++ .github/workflows/verify-bundled-files.yml | 12 +++++++++++ 3 files changed, 34 insertions(+) create mode 100755 .github/scripts/download-bundled/uriparser.sh diff --git a/.github/scripts/download-bundled/make-workflow-file.php b/.github/scripts/download-bundled/make-workflow-file.php index f907bc663bbab..ab89fac3d6f7c 100644 --- a/.github/scripts/download-bundled/make-workflow-file.php +++ b/.github/scripts/download-bundled/make-workflow-file.php @@ -7,6 +7,7 @@ $bundles = [ new Bundle('boost.context', ['Zend/asm']), new Bundle('PCRE2', ['ext/pcre/pcre2lib']), + new Bundle('uriparser', ['ext/uri/uriparser']), ]; class Bundle diff --git a/.github/scripts/download-bundled/uriparser.sh b/.github/scripts/download-bundled/uriparser.sh new file mode 100755 index 0000000000000..eea204aacd2fb --- /dev/null +++ b/.github/scripts/download-bundled/uriparser.sh @@ -0,0 +1,21 @@ +#!/bin/sh +set -ex +cd "$(dirname "$0")/../../.." + +tmp_dir=/tmp/php-src-download-bundled/uriparser +rm -rf "$tmp_dir" + +revision=c3b49569f1f25550a16d9a18207e498d77458b27 # refs/tags/uriparser-0.9.9 with https://github.com/uriparser/uriparser/pull/276 + +git clone --depth 1 --revision="$revision" https://github.com/uriparser/uriparser.git "$tmp_dir" + +rm -rf ext/uri/uriparser +mkdir ext/uri/uriparser +cp -R "$tmp_dir"/src ext/uri/uriparser +cp -R "$tmp_dir"/include ext/uri/uriparser +cp "$tmp_dir"/COPYING.BSD-3-Clause ext/uri/uriparser + +cd ext/uri/uriparser + +# move renamed files +mv src/UriConfig.h.in src/UriConfig.h diff --git a/.github/workflows/verify-bundled-files.yml b/.github/workflows/verify-bundled-files.yml index b1f0546b63049..a3b22088913e1 100644 --- a/.github/workflows/verify-bundled-files.yml +++ b/.github/workflows/verify-bundled-files.yml @@ -34,6 +34,9 @@ jobs: pcre2: - '.github/scripts/download-bundled/pcre2.*' - 'ext/pcre/pcre2lib/**' + uriparser: + - '.github/scripts/download-bundled/uriparser.*' + - 'ext/uri/uriparser/**' - name: 'boost.context' if: ${{ !cancelled() && (steps.changes.outputs.pcre2 == 'true' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') }} @@ -53,3 +56,12 @@ jobs: echo "::group::Verify files" .github/scripts/test-directory-unchanged.sh "ext/pcre/pcre2lib" echo "::endgroup::" + - name: uriparser + if: ${{ !cancelled() && (steps.changes.outputs.pcre2 == 'true' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') }} + run: | + echo "::group::Download" + .github/scripts/download-bundled/uriparser.sh + echo "::endgroup::" + echo "::group::Verify files" + .github/scripts/test-directory-unchanged.sh "ext/uri/uriparser" + echo "::endgroup::" From 287959445cb8a5bbdbd46c38e844d727b65c11a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Mon, 10 Nov 2025 00:48:44 +0100 Subject: [PATCH 05/23] rm original/duplicate src/UriConfig.h.in --- ext/uri/uriparser/src/UriConfig.h.in | 47 ---------------------------- 1 file changed, 47 deletions(-) delete mode 100644 ext/uri/uriparser/src/UriConfig.h.in diff --git a/ext/uri/uriparser/src/UriConfig.h.in b/ext/uri/uriparser/src/UriConfig.h.in deleted file mode 100644 index b9a85a8fe02af..0000000000000 --- a/ext/uri/uriparser/src/UriConfig.h.in +++ /dev/null @@ -1,47 +0,0 @@ -/* - * uriparser - RFC 3986 URI parsing library - * - * Copyright (C) 2018, Sebastian Pipping - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of - * its contributors may be used to endorse or promote products - * derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#if !defined(URI_CONFIG_H) -# define URI_CONFIG_H 1 - -# define PACKAGE_VERSION "@PROJECT_VERSION@" - -#cmakedefine HAVE_WPRINTF -#cmakedefine HAVE_REALLOCARRAY - -#endif /* !defined(URI_CONFIG_H) */ From 8b72e089abbd246cf2d9ce7de2f6243e17308b0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Mon, 10 Nov 2025 01:05:47 +0100 Subject: [PATCH 06/23] fix outdated config/comment --- ext/uri/uriparser/src/UriConfig.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/uri/uriparser/src/UriConfig.h b/ext/uri/uriparser/src/UriConfig.h index e265c0a9a1154..ab78b96cd808a 100644 --- a/ext/uri/uriparser/src/UriConfig.h +++ b/ext/uri/uriparser/src/UriConfig.h @@ -42,8 +42,8 @@ # define PACKAGE_VERSION "@PROJECT_VERSION@" /* -#define HAVE_WPRINTF -#define HAVE_REALLOCARRAY +#cmakedefine HAVE_WPRINTF +#cmakedefine HAVE_REALLOCARRAY */ #endif /* !defined(URI_CONFIG_H) */ From 323012a79cad75f97fcd2cb47140f5af3a909235 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Mon, 10 Nov 2025 01:01:58 +0100 Subject: [PATCH 07/23] patch config to minimize changes between the official config --- .github/scripts/download-bundled/.gitignore | 1 + .../download-bundled/uriparser.config.patch | 14 ++++++++++++++ .github/scripts/download-bundled/uriparser.sh | 3 +++ 3 files changed, 18 insertions(+) create mode 100644 .github/scripts/download-bundled/.gitignore create mode 100644 .github/scripts/download-bundled/uriparser.config.patch diff --git a/.github/scripts/download-bundled/.gitignore b/.github/scripts/download-bundled/.gitignore new file mode 100644 index 0000000000000..69f1bf4530957 --- /dev/null +++ b/.github/scripts/download-bundled/.gitignore @@ -0,0 +1 @@ +!*.patch diff --git a/.github/scripts/download-bundled/uriparser.config.patch b/.github/scripts/download-bundled/uriparser.config.patch new file mode 100644 index 0000000000000..9742154e5d7c5 --- /dev/null +++ b/.github/scripts/download-bundled/uriparser.config.patch @@ -0,0 +1,14 @@ +diff --git a/ext/uri/uriparser/src/UriConfig.h b/ext/uri/uriparser/src/UriConfig.h +index b9a85a8..ab78b96 100644 +--- a/ext/uri/uriparser/src/UriConfig.h ++++ b/ext/uri/uriparser/src/UriConfig.h +@@ -41,7 +41,9 @@ + + # define PACKAGE_VERSION "@PROJECT_VERSION@" + ++/* + #cmakedefine HAVE_WPRINTF + #cmakedefine HAVE_REALLOCARRAY ++*/ + + #endif /* !defined(URI_CONFIG_H) */ diff --git a/.github/scripts/download-bundled/uriparser.sh b/.github/scripts/download-bundled/uriparser.sh index eea204aacd2fb..7eb10965e9d76 100755 --- a/.github/scripts/download-bundled/uriparser.sh +++ b/.github/scripts/download-bundled/uriparser.sh @@ -19,3 +19,6 @@ cd ext/uri/uriparser # move renamed files mv src/UriConfig.h.in src/UriConfig.h + +# patch customized files +git apply -v ../../../.github/scripts/download-bundled/uriparser.config.patch From 623876d1e2fefffc5ccc8cd706892e9d42c0083c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Wed, 12 Nov 2025 18:55:18 +0100 Subject: [PATCH 08/23] adjust for rebase --- .../download-bundled/make-workflow-file.php | 21 +++++++++++++++++-- .github/workflows/verify-bundled-files.yml | 4 +++- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/.github/scripts/download-bundled/make-workflow-file.php b/.github/scripts/download-bundled/make-workflow-file.php index ab89fac3d6f7c..ce303f78eccc2 100644 --- a/.github/scripts/download-bundled/make-workflow-file.php +++ b/.github/scripts/download-bundled/make-workflow-file.php @@ -86,8 +86,11 @@ public function makeWorkflowFile(): void name: Verify Bundled Files on: - push: ~ - pull_request: ~ + push: + paths: &paths + %paths% + pull_request: + paths: *paths schedule: - cron: "0 1 * * *" workflow_dispatch: ~ @@ -114,6 +117,20 @@ public function makeWorkflowFile(): void EOD; + $paths = [ + '.github/scripts/download-bundled/**', + ]; + foreach ($this->bundles as $bundle) { + foreach ($this->makeDornyPathsFilterFilters($bundle) as $p) { + if (str_starts_with($p, '.github/scripts/download-bundled/')) { + continue; + } + + $paths[] = $p; + } + } + $content = str_replace('%paths%', $this->indentString($this->encodeYml($paths), 3, false), $content); + $filters = []; foreach ($this->bundles as $bundle) { $filters[$bundle->getNameForPath()] = $this->makeDornyPathsFilterFilters($bundle); diff --git a/.github/workflows/verify-bundled-files.yml b/.github/workflows/verify-bundled-files.yml index a3b22088913e1..c86b3f4e0dbd3 100644 --- a/.github/workflows/verify-bundled-files.yml +++ b/.github/workflows/verify-bundled-files.yml @@ -3,8 +3,10 @@ name: Verify Bundled Files on: push: paths: &paths - - '.github/scripts/download-bundled/pcre2.sh' + - '.github/scripts/download-bundled/**' + - 'Zend/asm/**' - 'ext/pcre/pcre2lib/**' + - 'ext/uri/uriparser/**' pull_request: paths: *paths schedule: From 653100d15fe6fc7f15741c8fe79a6882a07589e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Wed, 12 Nov 2025 19:20:08 +0100 Subject: [PATCH 09/23] "base" param for dorny/paths-filter is not used for PR --- .github/scripts/download-bundled/make-workflow-file.php | 1 - .github/workflows/verify-bundled-files.yml | 1 - 2 files changed, 2 deletions(-) diff --git a/.github/scripts/download-bundled/make-workflow-file.php b/.github/scripts/download-bundled/make-workflow-file.php index ce303f78eccc2..872959f018f86 100644 --- a/.github/scripts/download-bundled/make-workflow-file.php +++ b/.github/scripts/download-bundled/make-workflow-file.php @@ -110,7 +110,6 @@ public function makeWorkflowFile(): void uses: dorny/paths-filter@v3 id: changes with: - base: master filters: %filters% %steps% diff --git a/.github/workflows/verify-bundled-files.yml b/.github/workflows/verify-bundled-files.yml index c86b3f4e0dbd3..8835c4b9c3d40 100644 --- a/.github/workflows/verify-bundled-files.yml +++ b/.github/workflows/verify-bundled-files.yml @@ -28,7 +28,6 @@ jobs: uses: dorny/paths-filter@v3 id: changes with: - base: master filters: | 'boost-context': - '.github/scripts/download-bundled/boost-context.*' From 0a2d4f775fa2e2cfcdeb333a29a5a2900816e3bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Wed, 12 Nov 2025 20:08:10 +0100 Subject: [PATCH 10/23] make gen executable --- .github/scripts/download-bundled/make-workflow-file.php | 1 + 1 file changed, 1 insertion(+) mode change 100644 => 100755 .github/scripts/download-bundled/make-workflow-file.php diff --git a/.github/scripts/download-bundled/make-workflow-file.php b/.github/scripts/download-bundled/make-workflow-file.php old mode 100644 new mode 100755 index 872959f018f86..483897f0cca79 --- a/.github/scripts/download-bundled/make-workflow-file.php +++ b/.github/scripts/download-bundled/make-workflow-file.php @@ -1,3 +1,4 @@ +#!/usr/bin/env php Date: Thu, 13 Nov 2025 07:57:34 +0100 Subject: [PATCH 11/23] do not use "escapeshellarg" function as it generates different results on Windows vs. linux --- .github/scripts/download-bundled/make-workflow-file.php | 2 +- .github/workflows/verify-bundled-files.yml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/scripts/download-bundled/make-workflow-file.php b/.github/scripts/download-bundled/make-workflow-file.php index 483897f0cca79..a054d16c6d779 100755 --- a/.github/scripts/download-bundled/make-workflow-file.php +++ b/.github/scripts/download-bundled/make-workflow-file.php @@ -147,7 +147,7 @@ public function makeWorkflowFile(): void '.github/scripts/download-bundled/' . $bundle->getNameForPath() . '.sh', 'echo "::endgroup::"', 'echo "::group::Verify files"', - ...array_map(static fn ($v) => '.github/scripts/test-directory-unchanged.sh ' . escapeshellarg($v), $bundle->directories), + ...array_map(static fn ($v) => '.github/scripts/test-directory-unchanged.sh \'' . $v . '\'', $bundle->directories), 'echo "::endgroup::"', ]), ]; diff --git a/.github/workflows/verify-bundled-files.yml b/.github/workflows/verify-bundled-files.yml index 8835c4b9c3d40..822eef6d3b5d7 100644 --- a/.github/workflows/verify-bundled-files.yml +++ b/.github/workflows/verify-bundled-files.yml @@ -46,7 +46,7 @@ jobs: .github/scripts/download-bundled/boost-context.sh echo "::endgroup::" echo "::group::Verify files" - .github/scripts/test-directory-unchanged.sh "Zend/asm" + .github/scripts/test-directory-unchanged.sh 'Zend/asm' echo "::endgroup::" - name: PCRE2 if: ${{ !cancelled() && (steps.changes.outputs.pcre2 == 'true' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') }} @@ -55,7 +55,7 @@ jobs: .github/scripts/download-bundled/pcre2.sh echo "::endgroup::" echo "::group::Verify files" - .github/scripts/test-directory-unchanged.sh "ext/pcre/pcre2lib" + .github/scripts/test-directory-unchanged.sh 'ext/pcre/pcre2lib' echo "::endgroup::" - name: uriparser if: ${{ !cancelled() && (steps.changes.outputs.pcre2 == 'true' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') }} @@ -64,5 +64,5 @@ jobs: .github/scripts/download-bundled/uriparser.sh echo "::endgroup::" echo "::group::Verify files" - .github/scripts/test-directory-unchanged.sh "ext/uri/uriparser" + .github/scripts/test-directory-unchanged.sh 'ext/uri/uriparser' echo "::endgroup::" From dfe4c8de974e5eb4a77edfce8a90fdc46e0f4b14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Fri, 14 Nov 2025 12:47:09 +0100 Subject: [PATCH 12/23] always use topmost/repo's .git as "--git-dir" --- .github/scripts/test-directory-unchanged.sh | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/.github/scripts/test-directory-unchanged.sh b/.github/scripts/test-directory-unchanged.sh index 0ce7fd4cc4afd..20ca410e4ec9c 100755 --- a/.github/scripts/test-directory-unchanged.sh +++ b/.github/scripts/test-directory-unchanged.sh @@ -1,13 +1,16 @@ #!/bin/sh set -ex -cd "$(dirname "$0")/../../$1" +# use the repo root directory as "--git-dir" +cd "$(dirname "$0")/../.." + +dir="$1" # notify git about untracked (except ignored) files -git add -N . +git add -N "$dir" # display overview of changed files -git status . +git status "$dir" # display diff of working directory vs HEAD commit and set exit code -git diff -a --exit-code HEAD . +git diff -a --exit-code HEAD "$dir" From 9d633a216a7fe278dc1cc24f3de9e000e22b7414 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Fri, 14 Nov 2025 15:12:44 +0100 Subject: [PATCH 13/23] run "Detect changed files" step only for push/PR events --- .github/scripts/download-bundled/make-workflow-file.php | 1 + .github/workflows/verify-bundled-files.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/scripts/download-bundled/make-workflow-file.php b/.github/scripts/download-bundled/make-workflow-file.php index a054d16c6d779..d78bb6beca611 100755 --- a/.github/scripts/download-bundled/make-workflow-file.php +++ b/.github/scripts/download-bundled/make-workflow-file.php @@ -108,6 +108,7 @@ public function makeWorkflowFile(): void uses: actions/checkout@v5 - name: Detect changed files + if: ${{ github.event_name == 'push' || github.event_name == 'pull_request' }} uses: dorny/paths-filter@v3 id: changes with: diff --git a/.github/workflows/verify-bundled-files.yml b/.github/workflows/verify-bundled-files.yml index 822eef6d3b5d7..76fca1cba060d 100644 --- a/.github/workflows/verify-bundled-files.yml +++ b/.github/workflows/verify-bundled-files.yml @@ -25,6 +25,7 @@ jobs: uses: actions/checkout@v5 - name: Detect changed files + if: ${{ github.event_name == 'push' || github.event_name == 'pull_request' }} uses: dorny/paths-filter@v3 id: changes with: From 1698539e861b540cf6a48fce3711fb264be757a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Fri, 14 Nov 2025 13:08:58 +0100 Subject: [PATCH 14/23] download timelib lib --- .../download-bundled/make-workflow-file.php | 1 + .github/scripts/download-bundled/timelib.sh | 29 +++++++++++++++++++ .github/workflows/verify-bundled-files.yml | 13 +++++++++ 3 files changed, 43 insertions(+) create mode 100755 .github/scripts/download-bundled/timelib.sh diff --git a/.github/scripts/download-bundled/make-workflow-file.php b/.github/scripts/download-bundled/make-workflow-file.php index d78bb6beca611..235933a8b4e4b 100755 --- a/.github/scripts/download-bundled/make-workflow-file.php +++ b/.github/scripts/download-bundled/make-workflow-file.php @@ -7,6 +7,7 @@ $bundles = [ new Bundle('boost.context', ['Zend/asm']), + new Bundle('timelib', ['ext/date/lib']), new Bundle('PCRE2', ['ext/pcre/pcre2lib']), new Bundle('uriparser', ['ext/uri/uriparser']), ]; diff --git a/.github/scripts/download-bundled/timelib.sh b/.github/scripts/download-bundled/timelib.sh new file mode 100755 index 0000000000000..86823e4bc58bc --- /dev/null +++ b/.github/scripts/download-bundled/timelib.sh @@ -0,0 +1,29 @@ +#!/bin/sh +set -ex +cd "$(dirname "$0")/../../.." + +tmp_dir=/tmp/php-src-download-bundled/timelib +rm -rf "$tmp_dir" + +revision=refs/tags/2022.14 + +git clone --depth 1 --revision="$revision" https://github.com/derickr/timelib.git "$tmp_dir" + +rm -rf ext/date/lib +cp -R "$tmp_dir" ext/date/lib + +cd ext/date/lib + +# remove unneeded files +rm -r docs +rm -r tests +rm -r zones +rm .gitignore +rm gettzmapping.php +rm parse_zoneinfo.c +rm win_dirent.h + +# add extra files +rm -r .git +git restore parse_date.c +git restore parse_iso_intervals.c diff --git a/.github/workflows/verify-bundled-files.yml b/.github/workflows/verify-bundled-files.yml index 76fca1cba060d..b4084b37250fb 100644 --- a/.github/workflows/verify-bundled-files.yml +++ b/.github/workflows/verify-bundled-files.yml @@ -5,6 +5,7 @@ on: paths: &paths - '.github/scripts/download-bundled/**' - 'Zend/asm/**' + - 'ext/date/lib/**' - 'ext/pcre/pcre2lib/**' - 'ext/uri/uriparser/**' pull_request: @@ -33,6 +34,9 @@ jobs: 'boost-context': - '.github/scripts/download-bundled/boost-context.*' - 'Zend/asm/**' + timelib: + - '.github/scripts/download-bundled/timelib.*' + - 'ext/date/lib/**' pcre2: - '.github/scripts/download-bundled/pcre2.*' - 'ext/pcre/pcre2lib/**' @@ -49,6 +53,15 @@ jobs: echo "::group::Verify files" .github/scripts/test-directory-unchanged.sh 'Zend/asm' echo "::endgroup::" + - name: timelib + if: ${{ !cancelled() && (steps.changes.outputs.pcre2 == 'true' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') }} + run: | + echo "::group::Download" + .github/scripts/download-bundled/timelib.sh + echo "::endgroup::" + echo "::group::Verify files" + .github/scripts/test-directory-unchanged.sh 'ext/date/lib' + echo "::endgroup::" - name: PCRE2 if: ${{ !cancelled() && (steps.changes.outputs.pcre2 == 'true' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') }} run: | From 7b329ae43767480522e30a025869c340de1d02eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Fri, 14 Nov 2025 13:29:33 +0100 Subject: [PATCH 15/23] fix whitespaces non-synced changes --- ext/date/lib/parse_date.re | 2 +- ext/date/lib/timelib_private.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/ext/date/lib/parse_date.re b/ext/date/lib/parse_date.re index c40a5c07c9aa1..893ce162dbb6e 100644 --- a/ext/date/lib/parse_date.re +++ b/ext/date/lib/parse_date.re @@ -548,7 +548,6 @@ static timelib_ull timelib_get_signed_nr(Scanner *s, const char **ptr, int max_l int len = 0; /* Skip over non-numeric chars */ - while (((**ptr < '0') || (**ptr > '9')) && (**ptr != '+') && (**ptr != '-')) { if (**ptr == '\0') { add_error(s, TIMELIB_ERR_UNEXPECTED_DATA, "Found unexpected data"); @@ -562,6 +561,7 @@ static timelib_ull timelib_get_signed_nr(Scanner *s, const char **ptr, int max_l str[0] = '+'; /* First position is the sign */ str_ptr = str + 1; + while ((**ptr == '+') || (**ptr == '-')) { if (**ptr == '-') { str[0] = str[0] == '+' ? '-' : '+'; diff --git a/ext/date/lib/timelib_private.h b/ext/date/lib/timelib_private.h index 3c5f9b22147c0..23419c8f44193 100644 --- a/ext/date/lib/timelib_private.h +++ b/ext/date/lib/timelib_private.h @@ -135,6 +135,7 @@ #ifndef TIMELIB_HAVE_BUILTIN_SADDLL_OVERFLOW # define TIMELIB_HAVE_BUILTIN_SADDLL_OVERFLOW 0 #endif + struct _ttinfo { int32_t offset; From 928735c07d7f64003e34326d75d5ce6af38b7d20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Fri, 14 Nov 2025 13:32:13 +0100 Subject: [PATCH 16/23] apply valid difference using patch --- .../download-bundled/timelib.parse_date.patch | 12 ++++++++++++ .github/scripts/download-bundled/timelib.sh | 3 +++ 2 files changed, 15 insertions(+) create mode 100644 .github/scripts/download-bundled/timelib.parse_date.patch diff --git a/.github/scripts/download-bundled/timelib.parse_date.patch b/.github/scripts/download-bundled/timelib.parse_date.patch new file mode 100644 index 0000000000000..0df8503ae3923 --- /dev/null +++ b/.github/scripts/download-bundled/timelib.parse_date.patch @@ -0,0 +1,12 @@ +diff --git a/ext/date/lib/parse_date.re b/ext/date/lib/parse_date.re +index 2f05f03..893ce16 100644 +--- a/ext/date/lib/parse_date.re ++++ b/ext/date/lib/parse_date.re +@@ -1281,7 +1281,6 @@ weekdayof = (reltextnumber|reltexttext) space (dayfulls|dayfull|dayabbr) + DEBUG_OUTPUT("firstdayof | lastdayof"); + TIMELIB_INIT; + TIMELIB_HAVE_RELATIVE(); +- TIMELIB_UNHAVE_TIME(); // Don't merge into PHP + + /* skip "last day of" or "first day of" */ + if (*ptr == 'l' || *ptr == 'L') { diff --git a/.github/scripts/download-bundled/timelib.sh b/.github/scripts/download-bundled/timelib.sh index 86823e4bc58bc..c2e9a772b7889 100755 --- a/.github/scripts/download-bundled/timelib.sh +++ b/.github/scripts/download-bundled/timelib.sh @@ -27,3 +27,6 @@ rm win_dirent.h rm -r .git git restore parse_date.c git restore parse_iso_intervals.c + +# patch customized files +git apply -v ../../../.github/scripts/download-bundled/timelib.parse_date.patch From 9b20b0440e78717a9a7d2b357596c7b63dd53394 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Fri, 14 Nov 2025 14:06:23 +0100 Subject: [PATCH 17/23] impl UCD download --- .../download-bundled/make-workflow-file.php | 1 + .../unicode-character-database.sh | 19 +++++++++++++++++++ .github/workflows/verify-bundled-files.yml | 13 +++++++++++++ 3 files changed, 33 insertions(+) create mode 100755 .github/scripts/download-bundled/unicode-character-database.sh diff --git a/.github/scripts/download-bundled/make-workflow-file.php b/.github/scripts/download-bundled/make-workflow-file.php index 235933a8b4e4b..7256e2a5b3cd1 100755 --- a/.github/scripts/download-bundled/make-workflow-file.php +++ b/.github/scripts/download-bundled/make-workflow-file.php @@ -8,6 +8,7 @@ $bundles = [ new Bundle('boost.context', ['Zend/asm']), new Bundle('timelib', ['ext/date/lib']), + new Bundle('Unicode Character Database', ['ext/mbstring']), new Bundle('PCRE2', ['ext/pcre/pcre2lib']), new Bundle('uriparser', ['ext/uri/uriparser']), ]; diff --git a/.github/scripts/download-bundled/unicode-character-database.sh b/.github/scripts/download-bundled/unicode-character-database.sh new file mode 100755 index 0000000000000..59dfe2733fe1f --- /dev/null +++ b/.github/scripts/download-bundled/unicode-character-database.sh @@ -0,0 +1,19 @@ +#!/bin/sh +set -ex +cd "$(dirname "$0")/../../.." + +tmp_dir=/tmp/php-src-download-bundled/unicode-character-database +rm -rf "$tmp_dir" + +version=17.0.0 + +mkdir -p "$tmp_dir" +curl --fail https://www.unicode.org/Public/$version/ucd/UCD.zip -o "$tmp_dir/data.zip" +unzip "$tmp_dir/data.zip" -d "$tmp_dir" + +cd ext/mbstring + +rm libmbfl/mbfl/eaw_table.h +rm unicode_data.h + +./ucgendat/ucgendat.php "$tmp_dir" diff --git a/.github/workflows/verify-bundled-files.yml b/.github/workflows/verify-bundled-files.yml index b4084b37250fb..1f7a165647965 100644 --- a/.github/workflows/verify-bundled-files.yml +++ b/.github/workflows/verify-bundled-files.yml @@ -6,6 +6,7 @@ on: - '.github/scripts/download-bundled/**' - 'Zend/asm/**' - 'ext/date/lib/**' + - 'ext/mbstring/**' - 'ext/pcre/pcre2lib/**' - 'ext/uri/uriparser/**' pull_request: @@ -37,6 +38,9 @@ jobs: timelib: - '.github/scripts/download-bundled/timelib.*' - 'ext/date/lib/**' + 'unicode-character-database': + - '.github/scripts/download-bundled/unicode-character-database.*' + - 'ext/mbstring/**' pcre2: - '.github/scripts/download-bundled/pcre2.*' - 'ext/pcre/pcre2lib/**' @@ -62,6 +66,15 @@ jobs: echo "::group::Verify files" .github/scripts/test-directory-unchanged.sh 'ext/date/lib' echo "::endgroup::" + - name: 'Unicode Character Database' + if: ${{ !cancelled() && (steps.changes.outputs.pcre2 == 'true' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') }} + run: | + echo "::group::Download" + .github/scripts/download-bundled/unicode-character-database.sh + echo "::endgroup::" + echo "::group::Verify files" + .github/scripts/test-directory-unchanged.sh 'ext/mbstring' + echo "::endgroup::" - name: PCRE2 if: ${{ !cancelled() && (steps.changes.outputs.pcre2 == 'true' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') }} run: | From 4a60c1c545cba13fe76ea9f8f5bdbca291d21f57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Fri, 14 Nov 2025 14:18:01 +0100 Subject: [PATCH 18/23] IR download --- .github/scripts/download-bundled/ir.sh | 36 +++++++++++++++++++ .../download-bundled/make-workflow-file.php | 1 + .github/workflows/verify-bundled-files.yml | 13 +++++++ 3 files changed, 50 insertions(+) create mode 100755 .github/scripts/download-bundled/ir.sh diff --git a/.github/scripts/download-bundled/ir.sh b/.github/scripts/download-bundled/ir.sh new file mode 100755 index 0000000000000..6d5faf5b5d104 --- /dev/null +++ b/.github/scripts/download-bundled/ir.sh @@ -0,0 +1,36 @@ +#!/bin/sh +set -ex +cd "$(dirname "$0")/../../.." + +tmp_dir=/tmp/php-src-download-bundled/ir +rm -rf "$tmp_dir" + +revision=5a81104e650ebd7ac24eb63d4dff67db723a5278 + +git clone --depth 1 --revision="$revision" https://github.com/dstogov/ir.git "$tmp_dir" + +rm -rf ext/opcache/jit/ir +cp -R "$tmp_dir" ext/opcache/jit/ir + +cd ext/opcache/jit/ir + +# remove unneeded files +rm -r .git +rm -r .github +rm -r bench +rm -r examples +rm -r tests +rm -r tools +rm README.md +rm TODO +rm ir.g +rm ir_cpuinfo.c +rm ir_emit_c.c +rm ir_emit_llvm.c +rm ir_load.c +rm ir_load_llvm.c +rm ir_main.c +rm ir_mem2ssa.c + +# add extra files +git restore README diff --git a/.github/scripts/download-bundled/make-workflow-file.php b/.github/scripts/download-bundled/make-workflow-file.php index 7256e2a5b3cd1..9dcd47befa3b2 100755 --- a/.github/scripts/download-bundled/make-workflow-file.php +++ b/.github/scripts/download-bundled/make-workflow-file.php @@ -9,6 +9,7 @@ new Bundle('boost.context', ['Zend/asm']), new Bundle('timelib', ['ext/date/lib']), new Bundle('Unicode Character Database', ['ext/mbstring']), + new Bundle('IR', ['ext/opcache/jit/ir']), new Bundle('PCRE2', ['ext/pcre/pcre2lib']), new Bundle('uriparser', ['ext/uri/uriparser']), ]; diff --git a/.github/workflows/verify-bundled-files.yml b/.github/workflows/verify-bundled-files.yml index 1f7a165647965..992c7db96ebde 100644 --- a/.github/workflows/verify-bundled-files.yml +++ b/.github/workflows/verify-bundled-files.yml @@ -7,6 +7,7 @@ on: - 'Zend/asm/**' - 'ext/date/lib/**' - 'ext/mbstring/**' + - 'ext/opcache/jit/ir/**' - 'ext/pcre/pcre2lib/**' - 'ext/uri/uriparser/**' pull_request: @@ -41,6 +42,9 @@ jobs: 'unicode-character-database': - '.github/scripts/download-bundled/unicode-character-database.*' - 'ext/mbstring/**' + ir: + - '.github/scripts/download-bundled/ir.*' + - 'ext/opcache/jit/ir/**' pcre2: - '.github/scripts/download-bundled/pcre2.*' - 'ext/pcre/pcre2lib/**' @@ -75,6 +79,15 @@ jobs: echo "::group::Verify files" .github/scripts/test-directory-unchanged.sh 'ext/mbstring' echo "::endgroup::" + - name: IR + if: ${{ !cancelled() && (steps.changes.outputs.pcre2 == 'true' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') }} + run: | + echo "::group::Download" + .github/scripts/download-bundled/ir.sh + echo "::endgroup::" + echo "::group::Verify files" + .github/scripts/test-directory-unchanged.sh 'ext/opcache/jit/ir' + echo "::endgroup::" - name: PCRE2 if: ${{ !cancelled() && (steps.changes.outputs.pcre2 == 'true' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') }} run: | From d33eb7bdbbafc2d976f7afc2904816eb0e5b1f1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Fri, 14 Nov 2025 14:19:24 +0100 Subject: [PATCH 19/23] DEBUG faster debug --- .../scripts/download-bundled/make-workflow-file.php | 2 +- .github/workflows/verify-bundled-files.yml | 13 ------------- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/.github/scripts/download-bundled/make-workflow-file.php b/.github/scripts/download-bundled/make-workflow-file.php index 9dcd47befa3b2..d103aa6676843 100755 --- a/.github/scripts/download-bundled/make-workflow-file.php +++ b/.github/scripts/download-bundled/make-workflow-file.php @@ -8,7 +8,7 @@ $bundles = [ new Bundle('boost.context', ['Zend/asm']), new Bundle('timelib', ['ext/date/lib']), - new Bundle('Unicode Character Database', ['ext/mbstring']), + // new Bundle('Unicode Character Database', ['ext/mbstring']), new Bundle('IR', ['ext/opcache/jit/ir']), new Bundle('PCRE2', ['ext/pcre/pcre2lib']), new Bundle('uriparser', ['ext/uri/uriparser']), diff --git a/.github/workflows/verify-bundled-files.yml b/.github/workflows/verify-bundled-files.yml index 992c7db96ebde..c2d18a9802f2d 100644 --- a/.github/workflows/verify-bundled-files.yml +++ b/.github/workflows/verify-bundled-files.yml @@ -6,7 +6,6 @@ on: - '.github/scripts/download-bundled/**' - 'Zend/asm/**' - 'ext/date/lib/**' - - 'ext/mbstring/**' - 'ext/opcache/jit/ir/**' - 'ext/pcre/pcre2lib/**' - 'ext/uri/uriparser/**' @@ -39,9 +38,6 @@ jobs: timelib: - '.github/scripts/download-bundled/timelib.*' - 'ext/date/lib/**' - 'unicode-character-database': - - '.github/scripts/download-bundled/unicode-character-database.*' - - 'ext/mbstring/**' ir: - '.github/scripts/download-bundled/ir.*' - 'ext/opcache/jit/ir/**' @@ -70,15 +66,6 @@ jobs: echo "::group::Verify files" .github/scripts/test-directory-unchanged.sh 'ext/date/lib' echo "::endgroup::" - - name: 'Unicode Character Database' - if: ${{ !cancelled() && (steps.changes.outputs.pcre2 == 'true' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') }} - run: | - echo "::group::Download" - .github/scripts/download-bundled/unicode-character-database.sh - echo "::endgroup::" - echo "::group::Verify files" - .github/scripts/test-directory-unchanged.sh 'ext/mbstring' - echo "::endgroup::" - name: IR if: ${{ !cancelled() && (steps.changes.outputs.pcre2 == 'true' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') }} run: | From e8b9678cd1fd65cc6e4d27f03e855053f506df3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Fri, 14 Nov 2025 14:49:41 +0100 Subject: [PATCH 20/23] sync file whitespaces (PR 20486) --- Zend/zend_simd.h | 778 +++++++++++++++++++++++------------------------ 1 file changed, 389 insertions(+), 389 deletions(-) diff --git a/Zend/zend_simd.h b/Zend/zend_simd.h index 9bd16ce9e9afb..2f0df203733ca 100644 --- a/Zend/zend_simd.h +++ b/Zend/zend_simd.h @@ -1,17 +1,17 @@ /******************************************************************************** * MIT License * Copyright (c) 2025 Saki Takamachi - * + * * 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 @@ -22,389 +22,389 @@ *********************************************************************************/ - #ifndef XSSE_H - #define XSSE_H - - #define XSSE_VERSION 10000 - - #ifdef _MSC_VER - # define XSSE_FORCE_INLINE __forceinline - #elif defined(__GNUC__) || defined(__clang__) - # define XSSE_FORCE_INLINE inline __attribute__((always_inline)) - # define XSSE_HAS_MACRO_EXTENSION - #else - # define XSSE_FORCE_INLINE inline - #endif - - - #if defined(__SSE2__) || defined(_M_X64) || defined(_M_AMD64) - #include - #define XSSE2 - - - #elif defined(__aarch64__) || defined(_M_ARM64) - #include - #define XSSE2 - - typedef int8x16_t __m128i; - - - /***************************************************************************** - * Load / Store * - *****************************************************************************/ - - #define _mm_set_epi8(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15) \ - ((int8x16_t) { \ - (int8_t) (x15), (int8_t) (x14), (int8_t) (x13), (int8_t) (x12), \ - (int8_t) (x11), (int8_t) (x10), (int8_t) (x9), (int8_t) (x8), \ - (int8_t) (x7), (int8_t) (x6), (int8_t) (x5), (int8_t) (x4), \ - (int8_t) (x3), (int8_t) (x2), (int8_t) (x1), (int8_t) (x0) }) - #define _mm_set_epi16(x0, x1, x2, x3, x4, x5, x6, x7) \ - (vreinterpretq_s8_s16((int16x8_t) { \ - (int16_t) (x7), (int16_t) (x6), (int16_t) (x5), (int16_t) (x4), \ - (int16_t) (x3), (int16_t) (x2), (int16_t) (x1), (int16_t) (x0) })) - #define _mm_set_epi32(x0, x1, x2, x3) \ - (vreinterpretq_s8_s32((int32x4_t) { (int32_t) (x3), (int32_t) (x2), (int32_t) (x1), (int32_t) (x0) })) - #define _mm_set_epi64x(x0, x1) (vreinterpretq_s8_s64((int64x2_t) { (int64_t) (x1), (int64_t) (x0) })) - #define _mm_set1_epi8(x) (vdupq_n_s8((int8_t) (x))) - #define _mm_set1_epi16(x) (vreinterpretq_s8_s16(vdupq_n_s16((int16_t) (x)))) - #define _mm_set1_epi32(x) (vreinterpretq_s8_s32(vdupq_n_s32((int32_t) (x)))) - #define _mm_set1_epi64x(x) (vreinterpretq_s8_s64(vdupq_n_s64((int64_t) (x)))) - - #define _mm_setr_epi8(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15) \ - ((int8x16_t) { \ - (int8_t) (x0), (int8_t) (x1), (int8_t) (x2), (int8_t) (x3), \ - (int8_t) (x4), (int8_t) (x5), (int8_t) (x6), (int8_t) (x7), \ - (int8_t) (x8), (int8_t) (x9), (int8_t) (x10), (int8_t) (x11), \ - (int8_t) (x12), (int8_t) (x13), (int8_t) (x14), (int8_t) (x15) }) - #define _mm_setr_epi16(x0, x1, x2, x3, x4, x5, x6, x7) \ - (vreinterpretq_s8_s16((int16x8_t) { \ - (int16_t) (x0), (int16_t) (x1), (int16_t) (x2), (int16_t) (x3), \ - (int16_t) (x4), (int16_t) (x5), (int16_t) (x6), (int16_t) (x7) })) - #define _mm_setr_epi32(x0, x1, x2, x3) \ - (vreinterpretq_s8_s32((int32x4_t) { (int32_t) (x0), (int32_t) (x1), (int32_t) (x2), (int32_t) (x3) })) - - #define _mm_setzero_si128() (vdupq_n_s8(0)) - - #define _mm_load_si128(x) (vld1q_s8((const int8_t *) (x))) - #define _mm_loadu_si128(x) _mm_load_si128(x) - - #define _mm_store_si128(to, x) (vst1q_s8((int8_t *) (to), x)) - #define _mm_storeu_si128(to, x) _mm_store_si128(to, x) - #define _mm_stream_si128(to, x) _mm_store_si128(to, x) - #define _mm_stream_si32(to, x) (*(volatile int32_t *)(to) = (int32_t)(x)) - - - /***************************************************************************** - * Bit shift / Bit wise * - *****************************************************************************/ - - #define _mm_or_si128(a, b) (vorrq_s8((a), (b))) - #define _mm_xor_si128(a, b) (veorq_s8((a), (b))) - #define _mm_and_si128(a, b) (vandq_s8((a), (b))) - #define _mm_andnot_si128(a, b) (vbicq_s8((b), (a))) - - #define _mm_slli_epi16(x, count) (vreinterpretq_s8_u16(vshlq_n_u16(vreinterpretq_u16_s8(x), (count)))) - #define _mm_slli_epi32(x, count) (vreinterpretq_s8_u32(vshlq_n_u32(vreinterpretq_u32_s8(x), (count)))) - #define _mm_slli_epi64(x, count) (vreinterpretq_s8_u64(vshlq_n_u64(vreinterpretq_u64_s8(x), (count)))) - static XSSE_FORCE_INLINE __m128i _mm_sll_epi16(__m128i x, __m128i count) - { - uint16_t shift = (uint16_t) (vgetq_lane_s64(vreinterpretq_s64_s8(count), 0) & 0xFFFF); - return vreinterpretq_s8_u16( - vshlq_u16(vreinterpretq_u16_s8(x), vdupq_n_s16((int16_t) shift)) - ); - } - static XSSE_FORCE_INLINE __m128i _mm_sll_epi32(__m128i x, __m128i count) - { - uint32_t shift = (uint32_t) (vgetq_lane_s64(vreinterpretq_s64_s8(count), 0) & 0xFFFFFFFF); - return vreinterpretq_s8_u32( - vshlq_u32(vreinterpretq_u32_s8(x), vdupq_n_s32((int32_t) shift)) - ); - } - static XSSE_FORCE_INLINE __m128i _mm_sll_epi64(__m128i x, __m128i count) - { - uint64_t shift = (uint64_t) vgetq_lane_s64(vreinterpretq_s64_s8(count), 0); - return vreinterpretq_s8_u64( - vshlq_u64(vreinterpretq_u64_s8(x), vdupq_n_s64((int64_t) shift)) - ); - } - - #define _mm_slli_si128(x, imm) \ - ((imm) >= 16 ? vdupq_n_s8(0) : vreinterpretq_s8_u8(vextq_u8(vdupq_n_u8(0), vreinterpretq_u8_s8(x), 16 - (imm)))) - - #define _mm_srai_epi16(x, count) (vreinterpretq_s8_s16(vshrq_n_s16(vreinterpretq_s16_s8(x), (count)))) - #define _mm_srai_epi32(x, count) (vreinterpretq_s8_s32(vshrq_n_s32(vreinterpretq_s32_s8(x), (count)))) - static inline __m128i _mm_sra_epi16(__m128i x, __m128i count) - { - uint16_t shift = (uint16_t) (vgetq_lane_s64(vreinterpretq_s64_s8(count), 0) & 0xFFFF); - return vreinterpretq_s8_s16( - vshlq_s16(vreinterpretq_s16_s8(x), vdupq_n_s16(-(int16_t) shift)) - ); - } - static inline __m128i _mm_sra_epi32(__m128i x, __m128i count) - { - uint32_t shift = (uint32_t) (vgetq_lane_s64(vreinterpretq_s64_s8(count), 0) & 0xFFFFFFFF); - return vreinterpretq_s8_s32( - vshlq_s32(vreinterpretq_s32_s8(x), vdupq_n_s32(-(int32_t) shift)) - ); - } - - #define _mm_srli_epi16(x, count) (vreinterpretq_s8_u16(vshrq_n_u16(vreinterpretq_u16_s8(x), (count)))) - #define _mm_srli_epi32(x, count) (vreinterpretq_s8_u32(vshrq_n_u32(vreinterpretq_u32_s8(x), (count)))) - #define _mm_srli_epi64(x, count) (vreinterpretq_s8_u64(vshrq_n_u64(vreinterpretq_u64_s8(x), (count)))) - static XSSE_FORCE_INLINE __m128i _mm_srl_epi16(__m128i x, __m128i count) - { - uint16_t shift = (uint16_t) (vgetq_lane_s64(vreinterpretq_s64_s8(count), 0) & 0xFFFF); - return vreinterpretq_s8_u16( - vshlq_u16(vreinterpretq_u16_s8(x), vdupq_n_s16(-(int16_t) shift)) - ); - } - static XSSE_FORCE_INLINE __m128i _mm_srl_epi32(__m128i x, __m128i count) - { - uint32_t shift = (uint32_t) (vgetq_lane_s64(vreinterpretq_s64_s8(count), 0) & 0xFFFFFFFF); - return vreinterpretq_s8_u32( - vshlq_u32(vreinterpretq_u32_s8(x), vdupq_n_s32(-(int32_t) shift)) - ); - } - static XSSE_FORCE_INLINE __m128i _mm_srl_epi64(__m128i x, __m128i count) - { - uint64_t shift = (uint64_t) vgetq_lane_s64(vreinterpretq_s64_s8(count), 0); - return vreinterpretq_s8_u64( - vshlq_u64(vreinterpretq_u64_s8(x), vdupq_n_s64(-(int64_t) shift)) - ); - } - - #define _mm_srli_si128(x, imm) \ - ((imm) >= 16 ? vdupq_n_s8(0) : vreinterpretq_s8_u8(vextq_u8(vreinterpretq_u8_s8(x), vdupq_n_u8(0), (imm)))) - - - /***************************************************************************** - * Integer Arithmetic Operations * - *****************************************************************************/ - - /** - * In practice, there is no problem, but a runtime error for signed integer overflow is triggered by UBSAN, - * so perform the calculation as unsigned. Since it is optimized at compile time, there are no unnecessary casts at runtime. - */ - #define _mm_add_epi8(a, b) (vreinterpretq_s8_u8(vaddq_u8(vreinterpretq_u8_s8(a), vreinterpretq_u8_s8(b)))) - #define _mm_add_epi16(a, b) (vreinterpretq_s8_u16(vaddq_u16(vreinterpretq_u16_s8(a), vreinterpretq_u16_s8(b)))) - #define _mm_add_epi32(a, b) (vreinterpretq_s8_u32(vaddq_u32(vreinterpretq_u32_s8(a), vreinterpretq_u32_s8(b)))) - #define _mm_add_epi64(a, b) (vreinterpretq_s8_u64(vaddq_u64(vreinterpretq_u64_s8(a), vreinterpretq_u64_s8(b)))) - - #define _mm_adds_epi8(a, b) (vqaddq_s8((a), (b))) - #define _mm_adds_epi16(a, b) (vreinterpretq_s8_s16(vqaddq_s16(vreinterpretq_s16_s8(a), vreinterpretq_s16_s8(b)))) - #define _mm_adds_epu8(a, b) (vreinterpretq_s8_u8(vqaddq_u8(vreinterpretq_u8_s8(a), vreinterpretq_u8_s8(b)))) - #define _mm_adds_epu16(a, b) (vreinterpretq_s8_u16(vqaddq_u16(vreinterpretq_u16_s8(a), vreinterpretq_u16_s8(b)))) - - #define _mm_avg_epu8(a, b) (vreinterpretq_s8_u8(vrhaddq_u8(vreinterpretq_u8_s8(a), vreinterpretq_u8_s8(b)))) - #define _mm_avg_epu16(a, b) (vreinterpretq_s8_u16(vrhaddq_u16(vreinterpretq_u16_s8(a), vreinterpretq_u16_s8(b)))) - - static XSSE_FORCE_INLINE __m128i _mm_madd_epi16(__m128i a, __m128i b) - { - int32x4_t mul_lo = vmull_s16(vget_low_s16(vreinterpretq_s16_s8(a)), vget_low_s16(vreinterpretq_s16_s8(b))); - int32x4_t mul_hi = vmull_s16(vget_high_s16(vreinterpretq_s16_s8(a)), vget_high_s16(vreinterpretq_s16_s8(b))); - - return vreinterpretq_s8_s32(vcombine_s32( - vpadd_s32(vget_low_s32(mul_lo), vget_high_s32(mul_lo)), - vpadd_s32(vget_low_s32(mul_hi), vget_high_s32(mul_hi)) - )); - } - - #define _mm_max_epu8(a, b) (vreinterpretq_s8_u8(vmaxq_u8(vreinterpretq_u8_s8(a), vreinterpretq_u8_s8(b)))) - #define _mm_max_epi16(a, b) (vreinterpretq_s8_s16(vmaxq_s16(vreinterpretq_s16_s8(a), vreinterpretq_s16_s8(b)))) - #define _mm_min_epu8(a, b) (vreinterpretq_s8_u8(vminq_u8(vreinterpretq_u8_s8(a), vreinterpretq_u8_s8(b)))) - #define _mm_min_epi16(a, b) (vreinterpretq_s8_s16(vminq_s16(vreinterpretq_s16_s8(a), vreinterpretq_s16_s8(b)))) - - static XSSE_FORCE_INLINE __m128i _mm_mulhi_epi16(__m128i a, __m128i b) - { - int32x4_t lo = vmull_s16(vget_low_s16(vreinterpretq_s16_s8(a)), vget_low_s16(vreinterpretq_s16_s8(b))); - int32x4_t hi = vmull_s16(vget_high_s16(vreinterpretq_s16_s8(a)), vget_high_s16(vreinterpretq_s16_s8(b))); - return vreinterpretq_s8_s16(vcombine_s16(vshrn_n_s32(lo, 16), vshrn_n_s32(hi, 16))); - } - static XSSE_FORCE_INLINE __m128i _mm_mulhi_epu16(__m128i a, __m128i b) - { - uint32x4_t lo = vmull_u16(vget_low_u16(vreinterpretq_u16_s8(a)), vget_low_u16(vreinterpretq_u16_s8(b))); - uint32x4_t hi = vmull_u16(vget_high_u16(vreinterpretq_u16_s8(a)), vget_high_u16(vreinterpretq_u16_s8(b))); - return vreinterpretq_s8_u16(vcombine_u16(vshrn_n_u32(lo, 16), vshrn_n_u32(hi, 16))); - } - static XSSE_FORCE_INLINE __m128i _mm_mullo_epi16(__m128i a, __m128i b) - { - int32x4_t lo = vmull_s16(vget_low_s16(vreinterpretq_s16_s8(a)), vget_low_s16(vreinterpretq_s16_s8(b))); - int32x4_t hi = vmull_s16(vget_high_s16(vreinterpretq_s16_s8(a)), vget_high_s16(vreinterpretq_s16_s8(b))); - return vreinterpretq_s8_s16(vcombine_s16(vmovn_s32(lo), vmovn_s32(hi))); - } - static XSSE_FORCE_INLINE __m128i _mm_mul_epu32(__m128i a, __m128i b) - { - uint32x4_t evens = vuzpq_u32(vreinterpretq_u32_s8(a), vreinterpretq_u32_s8(b)).val[0]; - return vreinterpretq_s8_u64(vmull_u32(vget_low_u32(evens), vget_high_u32(evens))); - } - static XSSE_FORCE_INLINE __m128i _mm_sad_epu8(__m128i a, __m128i b) - { - uint16x8_t abs_diffs_16 = vpaddlq_u8(vabdq_u8(vreinterpretq_u8_s8(a), vreinterpretq_u8_s8(b))); - uint32x4_t abs_diffs_32 = vpaddlq_u16(abs_diffs_16); - uint64x2_t abs_diffs_64 = vpaddlq_u32(abs_diffs_32); - - return vreinterpretq_s8_u16((uint16x8_t) { - (int16_t) vgetq_lane_u64(abs_diffs_64, 0), 0, 0, 0, - (int16_t) vgetq_lane_u64(abs_diffs_64, 1), 0, 0, 0 - }); - } - - #define _mm_sub_epi8(a, b) (vreinterpretq_s8_u8(vsubq_u8(vreinterpretq_u8_s8(a), vreinterpretq_u8_s8(b)))) - #define _mm_sub_epi16(a, b) (vreinterpretq_s8_u16(vsubq_u16(vreinterpretq_u16_s8(a), vreinterpretq_u16_s8(b)))) - #define _mm_sub_epi32(a, b) (vreinterpretq_s8_u32(vsubq_u32(vreinterpretq_u32_s8(a), vreinterpretq_u32_s8(b)))) - #define _mm_sub_epi64(a, b) (vreinterpretq_s8_u64(vsubq_u64(vreinterpretq_u64_s8(a), vreinterpretq_u64_s8(b)))) - - #define _mm_subs_epi8(a, b) (vqsubq_s8((a), (b))) - #define _mm_subs_epi16(a, b) (vreinterpretq_s8_s16(vqsubq_s16(vreinterpretq_s16_s8(a), vreinterpretq_s16_s8(b)))) - #define _mm_subs_epu8(a, b) (vreinterpretq_s8_u8(vqsubq_u8(vreinterpretq_u8_s8(a), vreinterpretq_u8_s8(b)))) - #define _mm_subs_epu16(a, b) (vreinterpretq_s8_u16(vqsubq_u16(vreinterpretq_u16_s8(a), vreinterpretq_u16_s8(b)))) - - - /***************************************************************************** - * Comparison * - *****************************************************************************/ - - #define _mm_cmpeq_epi8(a, b) (vreinterpretq_s8_u8(vceqq_s8((a), (b)))) - #define _mm_cmpeq_epi16(a, b) (vreinterpretq_s8_u16(vceqq_s16(vreinterpretq_s16_s8(a), vreinterpretq_s16_s8(b)))) - #define _mm_cmpeq_epi32(a, b) (vreinterpretq_s8_u32(vceqq_s32(vreinterpretq_s32_s8(a), vreinterpretq_s32_s8(b)))) - - #define _mm_cmplt_epi8(a, b) (vreinterpretq_s8_u8(vcltq_s8((a), (b)))) - #define _mm_cmplt_epi16(a, b) (vreinterpretq_s8_u16(vcltq_s16(vreinterpretq_s16_s8(a), vreinterpretq_s16_s8(b)))) - #define _mm_cmplt_epi32(a, b) (vreinterpretq_s8_u32(vcltq_s32(vreinterpretq_s32_s8(a), vreinterpretq_s32_s8(b)))) - - #define _mm_cmpgt_epi8(a, b) (vreinterpretq_s8_u8(vcgtq_s8((a), (b)))) - #define _mm_cmpgt_epi16(a, b) (vreinterpretq_s8_u16(vcgtq_s16(vreinterpretq_s16_s8(a), vreinterpretq_s16_s8(b)))) - #define _mm_cmpgt_epi32(a, b) (vreinterpretq_s8_u32(vcgtq_s32(vreinterpretq_s32_s8(a), vreinterpretq_s32_s8(b)))) - - - /***************************************************************************** - * Convert * - *****************************************************************************/ - - #define _mm_cvtsi32_si128(x) (vreinterpretq_s8_s32((int32x4_t) { (int32_t) (x), 0, 0, 0 })) - #define _mm_cvtsi64_si128(x) (vreinterpretq_s8_s64((int64x2_t) { (int64_t) (x), 0 })) - #define _mm_cvtsi128_si32(x) (vgetq_lane_s32(vreinterpretq_s32_s8(x), 0)) - #define _mm_cvtsi128_si64(x) (vgetq_lane_s64(vreinterpretq_s64_s8(x), 0)) - - - /***************************************************************************** - * Others * - *****************************************************************************/ - - #define _mm_packs_epi16(a, b) (vcombine_s8(vqmovn_s16(vreinterpretq_s16_s8(a)), vqmovn_s16(vreinterpretq_s16_s8(b)))) - #define _mm_packs_epi32(a, b) \ - (vreinterpretq_s8_s16(vcombine_s16(vqmovn_s32(vreinterpretq_s32_s8(a)), vqmovn_s32(vreinterpretq_s32_s8(b))))) - #define _mm_packus_epi16(a, b) \ - (vreinterpretq_s8_u8(vcombine_u8(vqmovun_s16(vreinterpretq_s16_s8(a)), vqmovun_s16(vreinterpretq_s16_s8(b))))) - - #define _mm_extract_epi16(x, imm) (vgetq_lane_s16(vreinterpretq_s16_s8(x), (imm))) - #define _mm_insert_epi16(x, val, imm) (vreinterpretq_s8_s16(vsetq_lane_s16((int16_t) (val), vreinterpretq_s16_s8(x), (imm)))) - - static XSSE_FORCE_INLINE int _mm_movemask_epi8(__m128i x) - { - /** - * based on code from - * https://community.arm.com/arm-community-blogs/b/servers-and-cloud-computing-blog/posts/porting-x86-vector-bitmask-optimizations-to-arm-neon - */ - uint16x8_t high_bits = vreinterpretq_u16_u8(vshrq_n_u8(vreinterpretq_u8_s8(x), 7)); - uint32x4_t paired16 = vreinterpretq_u32_u16(vsraq_n_u16(high_bits, high_bits, 7)); - uint64x2_t paired32 = vreinterpretq_u64_u32(vsraq_n_u32(paired16, paired16, 14)); - uint8x16_t paired64 = vreinterpretq_u8_u64(vsraq_n_u64(paired32, paired32, 28)); - return vgetq_lane_u8(paired64, 0) | ((int) vgetq_lane_u8(paired64, 8) << 8); - } - - #define _MM_SHUFFLE(a, b, c, d) (((a) << 6) | ((b) << 4) | ((c) << 2) | (d)) - #ifdef XSSE_HAS_MACRO_EXTENSION - #define _mm_shuffle_epi32(x, imm) __extension__({ \ - int32x4_t __xsse_tmp = vreinterpretq_s32_s8(x); \ - vreinterpretq_s8_s32((int32x4_t) { \ - (int32_t) vgetq_lane_s32(__xsse_tmp, ((imm) >> 0) & 0x3), \ - (int32_t) vgetq_lane_s32(__xsse_tmp, ((imm) >> 2) & 0x3), \ - (int32_t) vgetq_lane_s32(__xsse_tmp, ((imm) >> 4) & 0x3), \ - (int32_t) vgetq_lane_s32(__xsse_tmp, ((imm) >> 6) & 0x3) \ - }); \ - }) - #define _mm_shufflehi_epi16(x, imm) __extension__({ \ - int16x8_t __xsse_tmp = vreinterpretq_s16_s8(x); \ - vreinterpretq_s8_s16(vcombine_s16( \ - vget_low_s16(__xsse_tmp), \ - (int16x4_t) { \ - (int16_t) vgetq_lane_s16(__xsse_tmp, (((imm) >> 0) & 0x3) + 4), \ - (int16_t) vgetq_lane_s16(__xsse_tmp, (((imm) >> 2) & 0x3) + 4), \ - (int16_t) vgetq_lane_s16(__xsse_tmp, (((imm) >> 4) & 0x3) + 4), \ - (int16_t) vgetq_lane_s16(__xsse_tmp, (((imm) >> 6) & 0x3) + 4) \ - } \ - )); \ - }) - #define _mm_shufflelo_epi16(x, imm) __extension__({ \ - int16x8_t __xsse_tmp = vreinterpretq_s16_s8(x); \ - vreinterpretq_s8_s16(vcombine_s16( \ - (int16x4_t) { \ - (int16_t) vgetq_lane_s16(__xsse_tmp, (((imm) >> 0) & 0x3)), \ - (int16_t) vgetq_lane_s16(__xsse_tmp, (((imm) >> 2) & 0x3)), \ - (int16_t) vgetq_lane_s16(__xsse_tmp, (((imm) >> 4) & 0x3)), \ - (int16_t) vgetq_lane_s16(__xsse_tmp, (((imm) >> 6) & 0x3)) \ - }, \ - vget_high_s16(__xsse_tmp) \ - )); \ - }) - #else - static XSSE_FORCE_INLINE __m128i _mm_shuffle_epi32(__m128i x, int imm) - { - int32x4_t vec = vreinterpretq_s32_s8(x); - int32_t arr[4]; - vst1q_s32(arr, vec); - - return vreinterpretq_s8_s32((int32x4_t) { - arr[(imm >> 0) & 0x3], - arr[(imm >> 2) & 0x3], - arr[(imm >> 4) & 0x3], - arr[(imm >> 6) & 0x3] - }); - } - static XSSE_FORCE_INLINE __m128i _mm_shufflehi_epi16(__m128i x, int imm) - { - int16x8_t vec = vreinterpretq_s16_s8(x); - int16_t arr[8]; - vst1q_s16(arr, vec); - - return vreinterpretq_s8_s16((int16x8_t) { - arr[0], arr[1], arr[2], arr[3], - arr[((imm >> 0) & 0x3) + 4], - arr[((imm >> 2) & 0x3) + 4], - arr[((imm >> 4) & 0x3) + 4], - arr[((imm >> 6) & 0x3) + 4] - }); - } - static XSSE_FORCE_INLINE __m128i _mm_shufflelo_epi16(__m128i x, int imm) - { - int16x8_t vec = vreinterpretq_s16_s8(x); - int16_t arr[8]; - vst1q_s16(arr, vec); - - return vreinterpretq_s8_s16((int16x8_t) { - arr[((imm >> 0) & 0x3)], - arr[((imm >> 2) & 0x3)], - arr[((imm >> 4) & 0x3)], - arr[((imm >> 6) & 0x3)], - arr[4], arr[5], arr[6], arr[7] - }); - } - #endif - - #define _mm_unpackhi_epi8(a, b) (vzip2q_s8((a), (b))) - #define _mm_unpackhi_epi16(a, b) (vreinterpretq_s8_s16(vzip2q_s16(vreinterpretq_s16_s8(a), vreinterpretq_s16_s8(b)))) - #define _mm_unpackhi_epi32(a, b) (vreinterpretq_s8_s32(vzip2q_s32(vreinterpretq_s32_s8(a), vreinterpretq_s32_s8(b)))) - #define _mm_unpackhi_epi64(a, b) (vreinterpretq_s8_s64(vzip2q_s64(vreinterpretq_s64_s8(a), vreinterpretq_s64_s8(b)))) - - #define _mm_unpacklo_epi8(a, b) (vzip1q_s8((a), (b))) - #define _mm_unpacklo_epi16(a, b) (vreinterpretq_s8_s16(vzip1q_s16(vreinterpretq_s16_s8(a), vreinterpretq_s16_s8(b)))) - #define _mm_unpacklo_epi32(a, b) (vreinterpretq_s8_s32(vzip1q_s32(vreinterpretq_s32_s8(a), vreinterpretq_s32_s8(b)))) - #define _mm_unpacklo_epi64(a, b) (vreinterpretq_s8_s64(vzip1q_s64(vreinterpretq_s64_s8(a), vreinterpretq_s64_s8(b)))) - - #define _mm_move_epi64(x) (vreinterpretq_s8_s64((int64x2_t) { vgetq_lane_s64(vreinterpretq_s64_s8(x), 0), 0 })) - - #endif - - #endif /* XSSE_H */ +#ifndef XSSE_H +#define XSSE_H + +#define XSSE_VERSION 10000 + +#ifdef _MSC_VER +# define XSSE_FORCE_INLINE __forceinline +#elif defined(__GNUC__) || defined(__clang__) +# define XSSE_FORCE_INLINE inline __attribute__((always_inline)) +# define XSSE_HAS_MACRO_EXTENSION +#else +# define XSSE_FORCE_INLINE inline +#endif + + +#if defined(__SSE2__) || defined(_M_X64) || defined(_M_AMD64) +#include +#define XSSE2 + + +#elif defined(__aarch64__) || defined(_M_ARM64) +#include +#define XSSE2 + +typedef int8x16_t __m128i; + + +/***************************************************************************** + * Load / Store * + *****************************************************************************/ + +#define _mm_set_epi8(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15) \ + ((int8x16_t) { \ + (int8_t) (x15), (int8_t) (x14), (int8_t) (x13), (int8_t) (x12), \ + (int8_t) (x11), (int8_t) (x10), (int8_t) (x9), (int8_t) (x8), \ + (int8_t) (x7), (int8_t) (x6), (int8_t) (x5), (int8_t) (x4), \ + (int8_t) (x3), (int8_t) (x2), (int8_t) (x1), (int8_t) (x0) }) +#define _mm_set_epi16(x0, x1, x2, x3, x4, x5, x6, x7) \ + (vreinterpretq_s8_s16((int16x8_t) { \ + (int16_t) (x7), (int16_t) (x6), (int16_t) (x5), (int16_t) (x4), \ + (int16_t) (x3), (int16_t) (x2), (int16_t) (x1), (int16_t) (x0) })) +#define _mm_set_epi32(x0, x1, x2, x3) \ + (vreinterpretq_s8_s32((int32x4_t) { (int32_t) (x3), (int32_t) (x2), (int32_t) (x1), (int32_t) (x0) })) +#define _mm_set_epi64x(x0, x1) (vreinterpretq_s8_s64((int64x2_t) { (int64_t) (x1), (int64_t) (x0) })) +#define _mm_set1_epi8(x) (vdupq_n_s8((int8_t) (x))) +#define _mm_set1_epi16(x) (vreinterpretq_s8_s16(vdupq_n_s16((int16_t) (x)))) +#define _mm_set1_epi32(x) (vreinterpretq_s8_s32(vdupq_n_s32((int32_t) (x)))) +#define _mm_set1_epi64x(x) (vreinterpretq_s8_s64(vdupq_n_s64((int64_t) (x)))) + +#define _mm_setr_epi8(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15) \ + ((int8x16_t) { \ + (int8_t) (x0), (int8_t) (x1), (int8_t) (x2), (int8_t) (x3), \ + (int8_t) (x4), (int8_t) (x5), (int8_t) (x6), (int8_t) (x7), \ + (int8_t) (x8), (int8_t) (x9), (int8_t) (x10), (int8_t) (x11), \ + (int8_t) (x12), (int8_t) (x13), (int8_t) (x14), (int8_t) (x15) }) +#define _mm_setr_epi16(x0, x1, x2, x3, x4, x5, x6, x7) \ + (vreinterpretq_s8_s16((int16x8_t) { \ + (int16_t) (x0), (int16_t) (x1), (int16_t) (x2), (int16_t) (x3), \ + (int16_t) (x4), (int16_t) (x5), (int16_t) (x6), (int16_t) (x7) })) +#define _mm_setr_epi32(x0, x1, x2, x3) \ + (vreinterpretq_s8_s32((int32x4_t) { (int32_t) (x0), (int32_t) (x1), (int32_t) (x2), (int32_t) (x3) })) + +#define _mm_setzero_si128() (vdupq_n_s8(0)) + +#define _mm_load_si128(x) (vld1q_s8((const int8_t *) (x))) +#define _mm_loadu_si128(x) _mm_load_si128(x) + +#define _mm_store_si128(to, x) (vst1q_s8((int8_t *) (to), x)) +#define _mm_storeu_si128(to, x) _mm_store_si128(to, x) +#define _mm_stream_si128(to, x) _mm_store_si128(to, x) +#define _mm_stream_si32(to, x) (*(volatile int32_t *)(to) = (int32_t)(x)) + + +/***************************************************************************** + * Bit shift / Bit wise * + *****************************************************************************/ + +#define _mm_or_si128(a, b) (vorrq_s8((a), (b))) +#define _mm_xor_si128(a, b) (veorq_s8((a), (b))) +#define _mm_and_si128(a, b) (vandq_s8((a), (b))) +#define _mm_andnot_si128(a, b) (vbicq_s8((b), (a))) + +#define _mm_slli_epi16(x, count) (vreinterpretq_s8_u16(vshlq_n_u16(vreinterpretq_u16_s8(x), (count)))) +#define _mm_slli_epi32(x, count) (vreinterpretq_s8_u32(vshlq_n_u32(vreinterpretq_u32_s8(x), (count)))) +#define _mm_slli_epi64(x, count) (vreinterpretq_s8_u64(vshlq_n_u64(vreinterpretq_u64_s8(x), (count)))) +static XSSE_FORCE_INLINE __m128i _mm_sll_epi16(__m128i x, __m128i count) +{ + uint16_t shift = (uint16_t) (vgetq_lane_s64(vreinterpretq_s64_s8(count), 0) & 0xFFFF); + return vreinterpretq_s8_u16( + vshlq_u16(vreinterpretq_u16_s8(x), vdupq_n_s16((int16_t) shift)) + ); +} +static XSSE_FORCE_INLINE __m128i _mm_sll_epi32(__m128i x, __m128i count) +{ + uint32_t shift = (uint32_t) (vgetq_lane_s64(vreinterpretq_s64_s8(count), 0) & 0xFFFFFFFF); + return vreinterpretq_s8_u32( + vshlq_u32(vreinterpretq_u32_s8(x), vdupq_n_s32((int32_t) shift)) + ); +} +static XSSE_FORCE_INLINE __m128i _mm_sll_epi64(__m128i x, __m128i count) +{ + uint64_t shift = (uint64_t) vgetq_lane_s64(vreinterpretq_s64_s8(count), 0); + return vreinterpretq_s8_u64( + vshlq_u64(vreinterpretq_u64_s8(x), vdupq_n_s64((int64_t) shift)) + ); +} + +#define _mm_slli_si128(x, imm) \ + ((imm) >= 16 ? vdupq_n_s8(0) : vreinterpretq_s8_u8(vextq_u8(vdupq_n_u8(0), vreinterpretq_u8_s8(x), 16 - (imm)))) + +#define _mm_srai_epi16(x, count) (vreinterpretq_s8_s16(vshrq_n_s16(vreinterpretq_s16_s8(x), (count)))) +#define _mm_srai_epi32(x, count) (vreinterpretq_s8_s32(vshrq_n_s32(vreinterpretq_s32_s8(x), (count)))) +static inline __m128i _mm_sra_epi16(__m128i x, __m128i count) +{ + uint16_t shift = (uint16_t) (vgetq_lane_s64(vreinterpretq_s64_s8(count), 0) & 0xFFFF); + return vreinterpretq_s8_s16( + vshlq_s16(vreinterpretq_s16_s8(x), vdupq_n_s16(-(int16_t) shift)) + ); +} +static inline __m128i _mm_sra_epi32(__m128i x, __m128i count) +{ + uint32_t shift = (uint32_t) (vgetq_lane_s64(vreinterpretq_s64_s8(count), 0) & 0xFFFFFFFF); + return vreinterpretq_s8_s32( + vshlq_s32(vreinterpretq_s32_s8(x), vdupq_n_s32(-(int32_t) shift)) + ); +} + +#define _mm_srli_epi16(x, count) (vreinterpretq_s8_u16(vshrq_n_u16(vreinterpretq_u16_s8(x), (count)))) +#define _mm_srli_epi32(x, count) (vreinterpretq_s8_u32(vshrq_n_u32(vreinterpretq_u32_s8(x), (count)))) +#define _mm_srli_epi64(x, count) (vreinterpretq_s8_u64(vshrq_n_u64(vreinterpretq_u64_s8(x), (count)))) +static XSSE_FORCE_INLINE __m128i _mm_srl_epi16(__m128i x, __m128i count) +{ + uint16_t shift = (uint16_t) (vgetq_lane_s64(vreinterpretq_s64_s8(count), 0) & 0xFFFF); + return vreinterpretq_s8_u16( + vshlq_u16(vreinterpretq_u16_s8(x), vdupq_n_s16(-(int16_t) shift)) + ); +} +static XSSE_FORCE_INLINE __m128i _mm_srl_epi32(__m128i x, __m128i count) +{ + uint32_t shift = (uint32_t) (vgetq_lane_s64(vreinterpretq_s64_s8(count), 0) & 0xFFFFFFFF); + return vreinterpretq_s8_u32( + vshlq_u32(vreinterpretq_u32_s8(x), vdupq_n_s32(-(int32_t) shift)) + ); +} +static XSSE_FORCE_INLINE __m128i _mm_srl_epi64(__m128i x, __m128i count) +{ + uint64_t shift = (uint64_t) vgetq_lane_s64(vreinterpretq_s64_s8(count), 0); + return vreinterpretq_s8_u64( + vshlq_u64(vreinterpretq_u64_s8(x), vdupq_n_s64(-(int64_t) shift)) + ); +} + +#define _mm_srli_si128(x, imm) \ + ((imm) >= 16 ? vdupq_n_s8(0) : vreinterpretq_s8_u8(vextq_u8(vreinterpretq_u8_s8(x), vdupq_n_u8(0), (imm)))) + + +/***************************************************************************** + * Integer Arithmetic Operations * + *****************************************************************************/ + +/** + * In practice, there is no problem, but a runtime error for signed integer overflow is triggered by UBSAN, + * so perform the calculation as unsigned. Since it is optimized at compile time, there are no unnecessary casts at runtime. + */ +#define _mm_add_epi8(a, b) (vreinterpretq_s8_u8(vaddq_u8(vreinterpretq_u8_s8(a), vreinterpretq_u8_s8(b)))) +#define _mm_add_epi16(a, b) (vreinterpretq_s8_u16(vaddq_u16(vreinterpretq_u16_s8(a), vreinterpretq_u16_s8(b)))) +#define _mm_add_epi32(a, b) (vreinterpretq_s8_u32(vaddq_u32(vreinterpretq_u32_s8(a), vreinterpretq_u32_s8(b)))) +#define _mm_add_epi64(a, b) (vreinterpretq_s8_u64(vaddq_u64(vreinterpretq_u64_s8(a), vreinterpretq_u64_s8(b)))) + +#define _mm_adds_epi8(a, b) (vqaddq_s8((a), (b))) +#define _mm_adds_epi16(a, b) (vreinterpretq_s8_s16(vqaddq_s16(vreinterpretq_s16_s8(a), vreinterpretq_s16_s8(b)))) +#define _mm_adds_epu8(a, b) (vreinterpretq_s8_u8(vqaddq_u8(vreinterpretq_u8_s8(a), vreinterpretq_u8_s8(b)))) +#define _mm_adds_epu16(a, b) (vreinterpretq_s8_u16(vqaddq_u16(vreinterpretq_u16_s8(a), vreinterpretq_u16_s8(b)))) + +#define _mm_avg_epu8(a, b) (vreinterpretq_s8_u8(vrhaddq_u8(vreinterpretq_u8_s8(a), vreinterpretq_u8_s8(b)))) +#define _mm_avg_epu16(a, b) (vreinterpretq_s8_u16(vrhaddq_u16(vreinterpretq_u16_s8(a), vreinterpretq_u16_s8(b)))) + +static XSSE_FORCE_INLINE __m128i _mm_madd_epi16(__m128i a, __m128i b) +{ + int32x4_t mul_lo = vmull_s16(vget_low_s16(vreinterpretq_s16_s8(a)), vget_low_s16(vreinterpretq_s16_s8(b))); + int32x4_t mul_hi = vmull_s16(vget_high_s16(vreinterpretq_s16_s8(a)), vget_high_s16(vreinterpretq_s16_s8(b))); + + return vreinterpretq_s8_s32(vcombine_s32( + vpadd_s32(vget_low_s32(mul_lo), vget_high_s32(mul_lo)), + vpadd_s32(vget_low_s32(mul_hi), vget_high_s32(mul_hi)) + )); +} + +#define _mm_max_epu8(a, b) (vreinterpretq_s8_u8(vmaxq_u8(vreinterpretq_u8_s8(a), vreinterpretq_u8_s8(b)))) +#define _mm_max_epi16(a, b) (vreinterpretq_s8_s16(vmaxq_s16(vreinterpretq_s16_s8(a), vreinterpretq_s16_s8(b)))) +#define _mm_min_epu8(a, b) (vreinterpretq_s8_u8(vminq_u8(vreinterpretq_u8_s8(a), vreinterpretq_u8_s8(b)))) +#define _mm_min_epi16(a, b) (vreinterpretq_s8_s16(vminq_s16(vreinterpretq_s16_s8(a), vreinterpretq_s16_s8(b)))) + +static XSSE_FORCE_INLINE __m128i _mm_mulhi_epi16(__m128i a, __m128i b) +{ + int32x4_t lo = vmull_s16(vget_low_s16(vreinterpretq_s16_s8(a)), vget_low_s16(vreinterpretq_s16_s8(b))); + int32x4_t hi = vmull_s16(vget_high_s16(vreinterpretq_s16_s8(a)), vget_high_s16(vreinterpretq_s16_s8(b))); + return vreinterpretq_s8_s16(vcombine_s16(vshrn_n_s32(lo, 16), vshrn_n_s32(hi, 16))); +} +static XSSE_FORCE_INLINE __m128i _mm_mulhi_epu16(__m128i a, __m128i b) +{ + uint32x4_t lo = vmull_u16(vget_low_u16(vreinterpretq_u16_s8(a)), vget_low_u16(vreinterpretq_u16_s8(b))); + uint32x4_t hi = vmull_u16(vget_high_u16(vreinterpretq_u16_s8(a)), vget_high_u16(vreinterpretq_u16_s8(b))); + return vreinterpretq_s8_u16(vcombine_u16(vshrn_n_u32(lo, 16), vshrn_n_u32(hi, 16))); +} +static XSSE_FORCE_INLINE __m128i _mm_mullo_epi16(__m128i a, __m128i b) +{ + int32x4_t lo = vmull_s16(vget_low_s16(vreinterpretq_s16_s8(a)), vget_low_s16(vreinterpretq_s16_s8(b))); + int32x4_t hi = vmull_s16(vget_high_s16(vreinterpretq_s16_s8(a)), vget_high_s16(vreinterpretq_s16_s8(b))); + return vreinterpretq_s8_s16(vcombine_s16(vmovn_s32(lo), vmovn_s32(hi))); +} +static XSSE_FORCE_INLINE __m128i _mm_mul_epu32(__m128i a, __m128i b) +{ + uint32x4_t evens = vuzpq_u32(vreinterpretq_u32_s8(a), vreinterpretq_u32_s8(b)).val[0]; + return vreinterpretq_s8_u64(vmull_u32(vget_low_u32(evens), vget_high_u32(evens))); +} +static XSSE_FORCE_INLINE __m128i _mm_sad_epu8(__m128i a, __m128i b) +{ + uint16x8_t abs_diffs_16 = vpaddlq_u8(vabdq_u8(vreinterpretq_u8_s8(a), vreinterpretq_u8_s8(b))); + uint32x4_t abs_diffs_32 = vpaddlq_u16(abs_diffs_16); + uint64x2_t abs_diffs_64 = vpaddlq_u32(abs_diffs_32); + + return vreinterpretq_s8_u16((uint16x8_t) { + (int16_t) vgetq_lane_u64(abs_diffs_64, 0), 0, 0, 0, + (int16_t) vgetq_lane_u64(abs_diffs_64, 1), 0, 0, 0 + }); +} + +#define _mm_sub_epi8(a, b) (vreinterpretq_s8_u8(vsubq_u8(vreinterpretq_u8_s8(a), vreinterpretq_u8_s8(b)))) +#define _mm_sub_epi16(a, b) (vreinterpretq_s8_u16(vsubq_u16(vreinterpretq_u16_s8(a), vreinterpretq_u16_s8(b)))) +#define _mm_sub_epi32(a, b) (vreinterpretq_s8_u32(vsubq_u32(vreinterpretq_u32_s8(a), vreinterpretq_u32_s8(b)))) +#define _mm_sub_epi64(a, b) (vreinterpretq_s8_u64(vsubq_u64(vreinterpretq_u64_s8(a), vreinterpretq_u64_s8(b)))) + +#define _mm_subs_epi8(a, b) (vqsubq_s8((a), (b))) +#define _mm_subs_epi16(a, b) (vreinterpretq_s8_s16(vqsubq_s16(vreinterpretq_s16_s8(a), vreinterpretq_s16_s8(b)))) +#define _mm_subs_epu8(a, b) (vreinterpretq_s8_u8(vqsubq_u8(vreinterpretq_u8_s8(a), vreinterpretq_u8_s8(b)))) +#define _mm_subs_epu16(a, b) (vreinterpretq_s8_u16(vqsubq_u16(vreinterpretq_u16_s8(a), vreinterpretq_u16_s8(b)))) + + +/***************************************************************************** + * Comparison * + *****************************************************************************/ + +#define _mm_cmpeq_epi8(a, b) (vreinterpretq_s8_u8(vceqq_s8((a), (b)))) +#define _mm_cmpeq_epi16(a, b) (vreinterpretq_s8_u16(vceqq_s16(vreinterpretq_s16_s8(a), vreinterpretq_s16_s8(b)))) +#define _mm_cmpeq_epi32(a, b) (vreinterpretq_s8_u32(vceqq_s32(vreinterpretq_s32_s8(a), vreinterpretq_s32_s8(b)))) + +#define _mm_cmplt_epi8(a, b) (vreinterpretq_s8_u8(vcltq_s8((a), (b)))) +#define _mm_cmplt_epi16(a, b) (vreinterpretq_s8_u16(vcltq_s16(vreinterpretq_s16_s8(a), vreinterpretq_s16_s8(b)))) +#define _mm_cmplt_epi32(a, b) (vreinterpretq_s8_u32(vcltq_s32(vreinterpretq_s32_s8(a), vreinterpretq_s32_s8(b)))) + +#define _mm_cmpgt_epi8(a, b) (vreinterpretq_s8_u8(vcgtq_s8((a), (b)))) +#define _mm_cmpgt_epi16(a, b) (vreinterpretq_s8_u16(vcgtq_s16(vreinterpretq_s16_s8(a), vreinterpretq_s16_s8(b)))) +#define _mm_cmpgt_epi32(a, b) (vreinterpretq_s8_u32(vcgtq_s32(vreinterpretq_s32_s8(a), vreinterpretq_s32_s8(b)))) + + +/***************************************************************************** + * Convert * + *****************************************************************************/ + +#define _mm_cvtsi32_si128(x) (vreinterpretq_s8_s32((int32x4_t) { (int32_t) (x), 0, 0, 0 })) +#define _mm_cvtsi64_si128(x) (vreinterpretq_s8_s64((int64x2_t) { (int64_t) (x), 0 })) +#define _mm_cvtsi128_si32(x) (vgetq_lane_s32(vreinterpretq_s32_s8(x), 0)) +#define _mm_cvtsi128_si64(x) (vgetq_lane_s64(vreinterpretq_s64_s8(x), 0)) + + +/***************************************************************************** + * Others * + *****************************************************************************/ + +#define _mm_packs_epi16(a, b) (vcombine_s8(vqmovn_s16(vreinterpretq_s16_s8(a)), vqmovn_s16(vreinterpretq_s16_s8(b)))) +#define _mm_packs_epi32(a, b) \ + (vreinterpretq_s8_s16(vcombine_s16(vqmovn_s32(vreinterpretq_s32_s8(a)), vqmovn_s32(vreinterpretq_s32_s8(b))))) +#define _mm_packus_epi16(a, b) \ + (vreinterpretq_s8_u8(vcombine_u8(vqmovun_s16(vreinterpretq_s16_s8(a)), vqmovun_s16(vreinterpretq_s16_s8(b))))) + +#define _mm_extract_epi16(x, imm) (vgetq_lane_s16(vreinterpretq_s16_s8(x), (imm))) +#define _mm_insert_epi16(x, val, imm) (vreinterpretq_s8_s16(vsetq_lane_s16((int16_t) (val), vreinterpretq_s16_s8(x), (imm)))) + +static XSSE_FORCE_INLINE int _mm_movemask_epi8(__m128i x) +{ + /** + * based on code from + * https://community.arm.com/arm-community-blogs/b/servers-and-cloud-computing-blog/posts/porting-x86-vector-bitmask-optimizations-to-arm-neon + */ + uint16x8_t high_bits = vreinterpretq_u16_u8(vshrq_n_u8(vreinterpretq_u8_s8(x), 7)); + uint32x4_t paired16 = vreinterpretq_u32_u16(vsraq_n_u16(high_bits, high_bits, 7)); + uint64x2_t paired32 = vreinterpretq_u64_u32(vsraq_n_u32(paired16, paired16, 14)); + uint8x16_t paired64 = vreinterpretq_u8_u64(vsraq_n_u64(paired32, paired32, 28)); + return vgetq_lane_u8(paired64, 0) | ((int) vgetq_lane_u8(paired64, 8) << 8); +} + +#define _MM_SHUFFLE(a, b, c, d) (((a) << 6) | ((b) << 4) | ((c) << 2) | (d)) +#ifdef XSSE_HAS_MACRO_EXTENSION +#define _mm_shuffle_epi32(x, imm) __extension__({ \ + int32x4_t __xsse_tmp = vreinterpretq_s32_s8(x); \ + vreinterpretq_s8_s32((int32x4_t) { \ + (int32_t) vgetq_lane_s32(__xsse_tmp, ((imm) >> 0) & 0x3), \ + (int32_t) vgetq_lane_s32(__xsse_tmp, ((imm) >> 2) & 0x3), \ + (int32_t) vgetq_lane_s32(__xsse_tmp, ((imm) >> 4) & 0x3), \ + (int32_t) vgetq_lane_s32(__xsse_tmp, ((imm) >> 6) & 0x3) \ + }); \ + }) +#define _mm_shufflehi_epi16(x, imm) __extension__({ \ + int16x8_t __xsse_tmp = vreinterpretq_s16_s8(x); \ + vreinterpretq_s8_s16(vcombine_s16( \ + vget_low_s16(__xsse_tmp), \ + (int16x4_t) { \ + (int16_t) vgetq_lane_s16(__xsse_tmp, (((imm) >> 0) & 0x3) + 4), \ + (int16_t) vgetq_lane_s16(__xsse_tmp, (((imm) >> 2) & 0x3) + 4), \ + (int16_t) vgetq_lane_s16(__xsse_tmp, (((imm) >> 4) & 0x3) + 4), \ + (int16_t) vgetq_lane_s16(__xsse_tmp, (((imm) >> 6) & 0x3) + 4) \ + } \ + )); \ + }) +#define _mm_shufflelo_epi16(x, imm) __extension__({ \ + int16x8_t __xsse_tmp = vreinterpretq_s16_s8(x); \ + vreinterpretq_s8_s16(vcombine_s16( \ + (int16x4_t) { \ + (int16_t) vgetq_lane_s16(__xsse_tmp, (((imm) >> 0) & 0x3)), \ + (int16_t) vgetq_lane_s16(__xsse_tmp, (((imm) >> 2) & 0x3)), \ + (int16_t) vgetq_lane_s16(__xsse_tmp, (((imm) >> 4) & 0x3)), \ + (int16_t) vgetq_lane_s16(__xsse_tmp, (((imm) >> 6) & 0x3)) \ + }, \ + vget_high_s16(__xsse_tmp) \ + )); \ + }) +#else +static XSSE_FORCE_INLINE __m128i _mm_shuffle_epi32(__m128i x, int imm) +{ + int32x4_t vec = vreinterpretq_s32_s8(x); + int32_t arr[4]; + vst1q_s32(arr, vec); + + return vreinterpretq_s8_s32((int32x4_t) { + arr[(imm >> 0) & 0x3], + arr[(imm >> 2) & 0x3], + arr[(imm >> 4) & 0x3], + arr[(imm >> 6) & 0x3] + }); +} +static XSSE_FORCE_INLINE __m128i _mm_shufflehi_epi16(__m128i x, int imm) +{ + int16x8_t vec = vreinterpretq_s16_s8(x); + int16_t arr[8]; + vst1q_s16(arr, vec); + + return vreinterpretq_s8_s16((int16x8_t) { + arr[0], arr[1], arr[2], arr[3], + arr[((imm >> 0) & 0x3) + 4], + arr[((imm >> 2) & 0x3) + 4], + arr[((imm >> 4) & 0x3) + 4], + arr[((imm >> 6) & 0x3) + 4] + }); +} +static XSSE_FORCE_INLINE __m128i _mm_shufflelo_epi16(__m128i x, int imm) +{ + int16x8_t vec = vreinterpretq_s16_s8(x); + int16_t arr[8]; + vst1q_s16(arr, vec); + + return vreinterpretq_s8_s16((int16x8_t) { + arr[((imm >> 0) & 0x3)], + arr[((imm >> 2) & 0x3)], + arr[((imm >> 4) & 0x3)], + arr[((imm >> 6) & 0x3)], + arr[4], arr[5], arr[6], arr[7] + }); +} +#endif + +#define _mm_unpackhi_epi8(a, b) (vzip2q_s8((a), (b))) +#define _mm_unpackhi_epi16(a, b) (vreinterpretq_s8_s16(vzip2q_s16(vreinterpretq_s16_s8(a), vreinterpretq_s16_s8(b)))) +#define _mm_unpackhi_epi32(a, b) (vreinterpretq_s8_s32(vzip2q_s32(vreinterpretq_s32_s8(a), vreinterpretq_s32_s8(b)))) +#define _mm_unpackhi_epi64(a, b) (vreinterpretq_s8_s64(vzip2q_s64(vreinterpretq_s64_s8(a), vreinterpretq_s64_s8(b)))) + +#define _mm_unpacklo_epi8(a, b) (vzip1q_s8((a), (b))) +#define _mm_unpacklo_epi16(a, b) (vreinterpretq_s8_s16(vzip1q_s16(vreinterpretq_s16_s8(a), vreinterpretq_s16_s8(b)))) +#define _mm_unpacklo_epi32(a, b) (vreinterpretq_s8_s32(vzip1q_s32(vreinterpretq_s32_s8(a), vreinterpretq_s32_s8(b)))) +#define _mm_unpacklo_epi64(a, b) (vreinterpretq_s8_s64(vzip1q_s64(vreinterpretq_s64_s8(a), vreinterpretq_s64_s8(b)))) + +#define _mm_move_epi64(x) (vreinterpretq_s8_s64((int64x2_t) { vgetq_lane_s64(vreinterpretq_s64_s8(x), 0), 0 })) + +#endif + +#endif /* XSSE_H */ From 41ddb86777afac4a98725131312ea2637cf20177 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Fri, 14 Nov 2025 14:59:44 +0100 Subject: [PATCH 21/23] xsse download --- .../scripts/download-bundled/make-workflow-file.php | 3 ++- .github/scripts/download-bundled/xsse.sh | 12 ++++++++++++ .github/workflows/verify-bundled-files.yml | 13 +++++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) create mode 100755 .github/scripts/download-bundled/xsse.sh diff --git a/.github/scripts/download-bundled/make-workflow-file.php b/.github/scripts/download-bundled/make-workflow-file.php index d103aa6676843..478bf02cf7639 100755 --- a/.github/scripts/download-bundled/make-workflow-file.php +++ b/.github/scripts/download-bundled/make-workflow-file.php @@ -7,6 +7,7 @@ $bundles = [ new Bundle('boost.context', ['Zend/asm']), + new Bundle('XSSE', ['Zend/zend_simd.h']), new Bundle('timelib', ['ext/date/lib']), // new Bundle('Unicode Character Database', ['ext/mbstring']), new Bundle('IR', ['ext/opcache/jit/ir']), @@ -165,7 +166,7 @@ protected function makeDornyPathsFilterFilters(Bundle $bundle): array { return [ '.github/scripts/download-bundled/' . $bundle->getNameForPath() . '.*', - ...array_map(static fn ($v) => $v . '/**', $bundle->directories), + ...array_map(fn ($v) => is_file($this->getRepoDirectory() . '/' . $v) ? $v : $v . '/**', $bundle->directories), ]; } diff --git a/.github/scripts/download-bundled/xsse.sh b/.github/scripts/download-bundled/xsse.sh new file mode 100755 index 0000000000000..1e2c94d9366f3 --- /dev/null +++ b/.github/scripts/download-bundled/xsse.sh @@ -0,0 +1,12 @@ +#!/bin/sh +set -ex +cd "$(dirname "$0")/../../.." + +tmp_dir=/tmp/php-src-download-bundled/xsse +rm -rf "$tmp_dir" + +revision=refs/tags/xsse-1.0.0 + +git clone --depth 1 --revision="$revision" https://github.com/SakiTakamachi/xsse.git "$tmp_dir" + +cp -f "$tmp_dir"/src/xsse.h Zend/zend_simd.h diff --git a/.github/workflows/verify-bundled-files.yml b/.github/workflows/verify-bundled-files.yml index c2d18a9802f2d..5b95482500def 100644 --- a/.github/workflows/verify-bundled-files.yml +++ b/.github/workflows/verify-bundled-files.yml @@ -5,6 +5,7 @@ on: paths: &paths - '.github/scripts/download-bundled/**' - 'Zend/asm/**' + - 'Zend/zend_simd.h' - 'ext/date/lib/**' - 'ext/opcache/jit/ir/**' - 'ext/pcre/pcre2lib/**' @@ -35,6 +36,9 @@ jobs: 'boost-context': - '.github/scripts/download-bundled/boost-context.*' - 'Zend/asm/**' + xsse: + - '.github/scripts/download-bundled/xsse.*' + - 'Zend/zend_simd.h' timelib: - '.github/scripts/download-bundled/timelib.*' - 'ext/date/lib/**' @@ -57,6 +61,15 @@ jobs: echo "::group::Verify files" .github/scripts/test-directory-unchanged.sh 'Zend/asm' echo "::endgroup::" + - name: XSSE + if: ${{ !cancelled() && (steps.changes.outputs.pcre2 == 'true' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') }} + run: | + echo "::group::Download" + .github/scripts/download-bundled/xsse.sh + echo "::endgroup::" + echo "::group::Verify files" + .github/scripts/test-directory-unchanged.sh 'Zend/zend_simd.h' + echo "::endgroup::" - name: timelib if: ${{ !cancelled() && (steps.changes.outputs.pcre2 == 'true' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') }} run: | From ef30ccfa7f4f35e4f30a96feb9576bb49a664bb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Fri, 14 Nov 2025 15:05:51 +0100 Subject: [PATCH 22/23] xxHash download --- .../scripts/download-bundled/make-workflow-file.php | 1 + .github/scripts/download-bundled/xxhash.sh | 12 ++++++++++++ .github/workflows/verify-bundled-files.yml | 13 +++++++++++++ 3 files changed, 26 insertions(+) create mode 100755 .github/scripts/download-bundled/xxhash.sh diff --git a/.github/scripts/download-bundled/make-workflow-file.php b/.github/scripts/download-bundled/make-workflow-file.php index 478bf02cf7639..15f2ef5907ad8 100755 --- a/.github/scripts/download-bundled/make-workflow-file.php +++ b/.github/scripts/download-bundled/make-workflow-file.php @@ -9,6 +9,7 @@ new Bundle('boost.context', ['Zend/asm']), new Bundle('XSSE', ['Zend/zend_simd.h']), new Bundle('timelib', ['ext/date/lib']), + new Bundle('xxHash', ['ext/hash/xxhash']), // new Bundle('Unicode Character Database', ['ext/mbstring']), new Bundle('IR', ['ext/opcache/jit/ir']), new Bundle('PCRE2', ['ext/pcre/pcre2lib']), diff --git a/.github/scripts/download-bundled/xxhash.sh b/.github/scripts/download-bundled/xxhash.sh new file mode 100755 index 0000000000000..fc0c7eb7b3029 --- /dev/null +++ b/.github/scripts/download-bundled/xxhash.sh @@ -0,0 +1,12 @@ +#!/bin/sh +set -ex +cd "$(dirname "$0")/../../.." + +tmp_dir=/tmp/php-src-download-bundled/xxhash +rm -rf "$tmp_dir" + +revision=refs/tags/v0.8.2 + +git clone --depth 1 --revision="$revision" https://github.com/Cyan4973/xxHash.git "$tmp_dir" + +cp -f "$tmp_dir"/xxhash.h ext/hash/xxhash/xxhash.h diff --git a/.github/workflows/verify-bundled-files.yml b/.github/workflows/verify-bundled-files.yml index 5b95482500def..03618f9f01ab4 100644 --- a/.github/workflows/verify-bundled-files.yml +++ b/.github/workflows/verify-bundled-files.yml @@ -7,6 +7,7 @@ on: - 'Zend/asm/**' - 'Zend/zend_simd.h' - 'ext/date/lib/**' + - 'ext/hash/xxhash/**' - 'ext/opcache/jit/ir/**' - 'ext/pcre/pcre2lib/**' - 'ext/uri/uriparser/**' @@ -42,6 +43,9 @@ jobs: timelib: - '.github/scripts/download-bundled/timelib.*' - 'ext/date/lib/**' + xxhash: + - '.github/scripts/download-bundled/xxhash.*' + - 'ext/hash/xxhash/**' ir: - '.github/scripts/download-bundled/ir.*' - 'ext/opcache/jit/ir/**' @@ -79,6 +83,15 @@ jobs: echo "::group::Verify files" .github/scripts/test-directory-unchanged.sh 'ext/date/lib' echo "::endgroup::" + - name: xxHash + if: ${{ !cancelled() && (steps.changes.outputs.pcre2 == 'true' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') }} + run: | + echo "::group::Download" + .github/scripts/download-bundled/xxhash.sh + echo "::endgroup::" + echo "::group::Verify files" + .github/scripts/test-directory-unchanged.sh 'ext/hash/xxhash' + echo "::endgroup::" - name: IR if: ${{ !cancelled() && (steps.changes.outputs.pcre2 == 'true' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') }} run: | From 04aa9a910a5b51e525592ed5be50af62bb1f4aca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Fri, 14 Nov 2025 15:08:09 +0100 Subject: [PATCH 23/23] VERIFY --- ext/hash/xxhash/xxhash.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/hash/xxhash/xxhash.h b/ext/hash/xxhash/xxhash.h index a18e8c762daaa..80c22bf823074 100644 --- a/ext/hash/xxhash/xxhash.h +++ b/ext/hash/xxhash/xxhash.h @@ -225,7 +225,7 @@ extern "C" { * #define XXH_INLINE_ALL * #include "xxhash.h" * @endcode - * Do not compile and link xxhash.o as a separate object, as it is not useful. + * Do not TEST and link xxhash.o as a separate object, as it is not useful. */ # define XXH_INLINE_ALL # undef XXH_INLINE_ALL