* Copyright (c) 2026 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LINXKIT_STRING_H
#define LINXKIT_STRING_H
#include <stdint.h>
#include <stdio.h>
#include <stdbool.h>
#include "libpandabase/utils/span.h"
#include "ecmascript/platform/string_hash.h"
#ifdef __cplusplus
extern "C++" {
#endif
template <typename T>
uint32_t __attribute__((always_inline)) LinxkitComputeHashForData(const T *data, size_t size, uint32_t hashSeed)
{
if (size == 0) {
return hashSeed;
}
const uint16_t values[4] = {29791, 961, 31, 1};
if constexpr (sizeof(T) == 2) {
asm volatile(
"mov x3, %[data]\n"
"mov w4, %w[size]\n"
"mov w15, %w[hash]\n"
"ld1 {v0.4h}, [%[a]]\n"
"ldr w7, =923521\n"
"1:\n"
"cmp w4, #8\n"
"b.lt 2f\n"
"ldr q1, [x3], #16\n"
"umull v2.4s, v1.4h, v0.4h\n"
"ext v1.16b, v1.16b, v1.16b, #8\n"
"addv s2, v2.4s\n"
"umull v1.4s, v1.4h, v0.4h\n"
"fmov w11, s2\n"
"addv s1, v1.4s\n"
"madd w15, w15, w7, w11\n"
"fmov w12, s1\n"
"madd w15, w15, w7, w12\n"
"subs w4, w4, #8\n"
"cbz w4, 4f\n"
"b 1b\n"
"2:\n"
"cmp w4, #4\n"
"b.ge 3f\n"
"subs w4, w4, #1\n"
"mov w7, #31\n"
"ldrh w11, [x3]\n"
"madd w15, w15, w7, w11\n"
"cbz w4, 4f\n"
"subs w4, w4, #1\n"
"ldrh w11, [x3, #2]\n"
"madd w15, w15, w7, w11\n"
"cbz w4, 4f\n"
"ldrh w11, [x3, #4]\n"
"madd w15, w15, w7, w11\n"
"b 4f\n"
"3:\n"
"ld1 {v1.4h}, [x3], #8\n"
"umull v2.4s, v1.4h, v0.4h\n"
"addv s2, v2.4s\n"
"fmov w11, s2\n"
"madd w15, w15, w7, w11\n"
"subs w4, w4, #4\n"
"cbz w4, 4f\n"
"b 2b\n"
"4:\n"
"mov %w[hash], w15\n"
: [hash] "+r"(hashSeed)
: [size] "r"(size), [data] "r"(data), [a] "r"(values)
: "memory", "cc", "x3", "x4", "x7", "x11", "x12", "x15", "v0", "v1", "v2"
);
} else {
ASSERT(sizeof(T) == sizeof(uint8_t));
asm volatile(
"mov x3, %[data]\n"
"mov w4, %w[size]\n"
"mov w15, %w[hash]\n"
"ld1 {v0.4h}, [%[a]]\n"
"ldr w7, =923521\n"
"1:\n"
"cmp w4, #16\n"
"b.lt 2f\n"
"ldr q1, [x3], #16\n"
"ushll v2.8h, v1.8b, #0\n"
"ext v1.16b, v1.16b, v1.16b, #8\n"
"umull v3.4s, v2.4h, v0.4h\n"
"ext v2.16b, v2.16b, v2.16b, #8\n"
"ushll v1.8h, v1.8b, #0\n"
"addv s3, v3.4s\n"
"umull v2.4s, v2.4h, v0.4h\n"
"umull v4.4s, v1.4h, v0.4h\n"
"ext v1.16b, v1.16b, v1.16b, #8\n"
"fmov w14, s3\n"
"addv s2, v2.4s\n"
"addv s3, v4.4s\n"
"umull v1.4s, v1.4h, v0.4h\n"
"madd w15, w15, w7, w14\n"
"fmov w14, s2\n"
"madd w15, w15, w7, w14\n"
"fmov w14, s3\n"
"madd w15, w15, w7, w14\n"
"addv s1, v1.4s\n"
"fmov w14, s1\n"
"madd w15, w15, w7, w14\n"
"subs w4, w4, #16\n"
"cbz w4, 5f\n"
"b 1b\n"
"2:\n"
"cmp w4, #8\n"
"b.ge 4f\n"
"3:\n"
"mov w7, #31\n"
"ldrb w10, [x3], #1\n"
"madd w15, w15, w7, w10\n"
"subs w4, w4, #1\n"
"b.ne 3b\n"
"b 5f\n"
"4:\n"
"ld1 {v1.8b}, [x3], #8\n"
"uxtl v2.8h, v1.8b\n"
"umull v3.4s, v0.4h, v2.4h\n"
"addv s4, v3.4s\n"
"fmov w5, s4\n"
"madd w15, w15, w7, w5\n"
"ext v1.16b, v1.16b, v1.16b, #4\n"
"uxtl v2.8h, v1.8b\n"
"umull v3.4s, v0.4h, v2.4h\n"
"addv s4, v3.4s\n"
"fmov w5, s4\n"
"madd w15, w15, w7, w5\n"
"sub w4, w4, #8\n"
"cbnz w4, 3b\n"
"5:\n"
"mov %w[hash], w15\n"
: [hash] "+r"(hashSeed)
: [size] "r"(size), [data] "r"(data), [a] "r"(values)
: "memory", "cc", "x3", "x4", "x5", "x7", "x10", "x14", "x15", "v0", "v1", "v2", "v3", "v4"
);
}
return hashSeed;
}
#ifdef __cplusplus
}
#endif
#endif