1 /* 2 * Copyright (c) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef ECMASCRIPT_PLATFORM_ECMA_STRING_HASH_ARM64_H 17 #define ECMASCRIPT_PLATFORM_ECMA_STRING_HASH_ARM64_H 18 19 #include <cstdint> 20 21 #include <arm_neon.h> 22 23 #include "ecmascript/platform/ecma_string_hash.h" 24 25 namespace panda::ecmascript { 26 class EcmaStringHashInternal { 27 friend class EcmaStringHashHelper; 28 private: 29 template <typename T> ComputeHashForDataOfLongString(const T * data,size_t size,uint32_t hashSeed)30 static uint32_t ComputeHashForDataOfLongString(const T *data, size_t size, 31 uint32_t hashSeed) 32 { 33 constexpr uint32_t hashShift = static_cast<uint32_t>(EcmaStringHash::HASH_SHIFT); 34 constexpr uint32_t blockSize = static_cast<size_t>(EcmaStringHash::BLOCK_SIZE); 35 uint32_t hash[blockSize] = {0}; 36 uint32_t index = 0; 37 uint32x4_t hashVec = vld1q_u32(hash); 38 uint32x4_t multiplier_vec = vdupq_n_u32(static_cast<uint32_t>(EcmaStringHash::HASH_MULTIPLY)); 39 uint32x4_t dataVec; 40 for (; index + blockSize <= size; index += blockSize) { 41 dataVec[0] = data[index]; 42 dataVec[1] = data[index + 1]; // 1: the second element of the block 43 dataVec[2] = data[index + 2]; // 2: the third element of the block 44 dataVec[3] = data[index + 3]; // 3: the fourth element of the block 45 hashVec = vaddq_u32(vmulq_u32(hashVec, multiplier_vec), dataVec); 46 } 47 vst1q_u32(hash, hashVec); 48 for (; index < size; ++index) { 49 hash[0] = (hash[0] << hashShift) - hash[0] + data[index]; 50 } 51 uint32_t totalHash = hashSeed; 52 for (uint32_t i = 0; i < blockSize; ++i) { 53 totalHash = (totalHash << hashShift) - totalHash + hash[i]; 54 } 55 return totalHash; 56 } 57 }; 58 } // namespace panda::ecmascript 59 #endif // ECMASCRIPT_PLATFORM_ECMA_STRING_HASH_ARM64_H