11c814c99SGuillaume Chatelet //===-- RISC-V implementation of memory function building blocks ----------===// 21c814c99SGuillaume Chatelet // 31c814c99SGuillaume Chatelet // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 41c814c99SGuillaume Chatelet // See https://llvm.org/LICENSE.txt for license information. 51c814c99SGuillaume Chatelet // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 61c814c99SGuillaume Chatelet // 71c814c99SGuillaume Chatelet //===----------------------------------------------------------------------===// 81c814c99SGuillaume Chatelet // 91c814c99SGuillaume Chatelet // This file provides x86 specific building blocks to compose memory functions. 101c814c99SGuillaume Chatelet // 111c814c99SGuillaume Chatelet //===----------------------------------------------------------------------===// 121c814c99SGuillaume Chatelet #ifndef LLVM_LIBC_SRC_STRING_MEMORY_UTILS_OP_RISCV_H 131c814c99SGuillaume Chatelet #define LLVM_LIBC_SRC_STRING_MEMORY_UTILS_OP_RISCV_H 141c814c99SGuillaume Chatelet 15*5ff3ff33SPetr Hosek #include "src/__support/macros/config.h" 161c814c99SGuillaume Chatelet #include "src/__support/macros/properties/architectures.h" 171c814c99SGuillaume Chatelet 181c814c99SGuillaume Chatelet #if defined(LIBC_TARGET_ARCH_IS_ANY_RISCV) 191c814c99SGuillaume Chatelet 201c814c99SGuillaume Chatelet #include "src/__support/common.h" 211c814c99SGuillaume Chatelet #include "src/string/memory_utils/op_generic.h" 221c814c99SGuillaume Chatelet 23*5ff3ff33SPetr Hosek namespace LIBC_NAMESPACE_DECL { 24*5ff3ff33SPetr Hosek namespace generic { 251c814c99SGuillaume Chatelet 261c814c99SGuillaume Chatelet /////////////////////////////////////////////////////////////////////////////// 271c814c99SGuillaume Chatelet // Specializations for uint16_t 281c814c99SGuillaume Chatelet template <> struct cmp_is_expensive<uint16_t> : public cpp::false_type {}; 291c814c99SGuillaume Chatelet template <> LIBC_INLINE bool eq<uint16_t>(CPtr p1, CPtr p2, size_t offset) { 301c814c99SGuillaume Chatelet return load<uint16_t>(p1, offset) == load<uint16_t>(p2, offset); 311c814c99SGuillaume Chatelet } 321c814c99SGuillaume Chatelet template <> 331c814c99SGuillaume Chatelet LIBC_INLINE uint32_t neq<uint16_t>(CPtr p1, CPtr p2, size_t offset) { 341c814c99SGuillaume Chatelet return load<uint16_t>(p1, offset) ^ load<uint16_t>(p2, offset); 351c814c99SGuillaume Chatelet } 361c814c99SGuillaume Chatelet template <> 371c814c99SGuillaume Chatelet LIBC_INLINE MemcmpReturnType cmp<uint16_t>(CPtr p1, CPtr p2, size_t offset) { 381c814c99SGuillaume Chatelet return static_cast<int32_t>(load_be<uint16_t>(p1, offset)) - 391c814c99SGuillaume Chatelet static_cast<int32_t>(load_be<uint16_t>(p2, offset)); 401c814c99SGuillaume Chatelet } 411c814c99SGuillaume Chatelet template <> 421c814c99SGuillaume Chatelet LIBC_INLINE MemcmpReturnType cmp_neq<uint16_t>(CPtr p1, CPtr p2, size_t offset); 431c814c99SGuillaume Chatelet 441c814c99SGuillaume Chatelet /////////////////////////////////////////////////////////////////////////////// 451c814c99SGuillaume Chatelet // Specializations for uint32_t 461c814c99SGuillaume Chatelet template <> struct cmp_is_expensive<uint32_t> : public cpp::false_type {}; 471c814c99SGuillaume Chatelet template <> LIBC_INLINE bool eq<uint32_t>(CPtr p1, CPtr p2, size_t offset) { 481c814c99SGuillaume Chatelet return load<uint32_t>(p1, offset) == load<uint32_t>(p2, offset); 491c814c99SGuillaume Chatelet } 501c814c99SGuillaume Chatelet template <> 511c814c99SGuillaume Chatelet LIBC_INLINE uint32_t neq<uint32_t>(CPtr p1, CPtr p2, size_t offset) { 521c814c99SGuillaume Chatelet return load<uint32_t>(p1, offset) ^ load<uint32_t>(p2, offset); 531c814c99SGuillaume Chatelet } 541c814c99SGuillaume Chatelet template <> 551c814c99SGuillaume Chatelet LIBC_INLINE MemcmpReturnType cmp<uint32_t>(CPtr p1, CPtr p2, size_t offset) { 561c814c99SGuillaume Chatelet const auto a = load_be<uint32_t>(p1, offset); 571c814c99SGuillaume Chatelet const auto b = load_be<uint32_t>(p2, offset); 581c814c99SGuillaume Chatelet return cmp_uint32_t(a, b); 591c814c99SGuillaume Chatelet } 601c814c99SGuillaume Chatelet template <> 611c814c99SGuillaume Chatelet LIBC_INLINE MemcmpReturnType cmp_neq<uint32_t>(CPtr p1, CPtr p2, size_t offset); 621c814c99SGuillaume Chatelet 631c814c99SGuillaume Chatelet /////////////////////////////////////////////////////////////////////////////// 641c814c99SGuillaume Chatelet // Specializations for uint64_t 651c814c99SGuillaume Chatelet template <> struct cmp_is_expensive<uint64_t> : public cpp::true_type {}; 661c814c99SGuillaume Chatelet template <> LIBC_INLINE bool eq<uint64_t>(CPtr p1, CPtr p2, size_t offset) { 671c814c99SGuillaume Chatelet return load<uint64_t>(p1, offset) == load<uint64_t>(p2, offset); 681c814c99SGuillaume Chatelet } 691c814c99SGuillaume Chatelet template <> 701c814c99SGuillaume Chatelet LIBC_INLINE uint32_t neq<uint64_t>(CPtr p1, CPtr p2, size_t offset) { 711c814c99SGuillaume Chatelet return !eq<uint64_t>(p1, p2, offset); 721c814c99SGuillaume Chatelet } 731c814c99SGuillaume Chatelet template <> 741c814c99SGuillaume Chatelet LIBC_INLINE MemcmpReturnType cmp<uint64_t>(CPtr p1, CPtr p2, size_t offset); 751c814c99SGuillaume Chatelet template <> 761c814c99SGuillaume Chatelet LIBC_INLINE MemcmpReturnType cmp_neq<uint64_t>(CPtr p1, CPtr p2, 771c814c99SGuillaume Chatelet size_t offset) { 781c814c99SGuillaume Chatelet const auto a = load_be<uint64_t>(p1, offset); 791c814c99SGuillaume Chatelet const auto b = load_be<uint64_t>(p2, offset); 801c814c99SGuillaume Chatelet return cmp_neq_uint64_t(a, b); 811c814c99SGuillaume Chatelet } 821c814c99SGuillaume Chatelet 83*5ff3ff33SPetr Hosek } // namespace generic 84*5ff3ff33SPetr Hosek } // namespace LIBC_NAMESPACE_DECL 851c814c99SGuillaume Chatelet 861c814c99SGuillaume Chatelet #endif // LIBC_TARGET_ARCH_IS_ANY_RISCV 871c814c99SGuillaume Chatelet #endif // LLVM_LIBC_SRC_STRING_MEMORY_UTILS_OP_RISCV_H 88