1 //===-- RISC-V implementation of memory function building blocks ----------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file provides x86 specific building blocks to compose memory functions.
11 //===----------------------------------------------------------------------===//
12 #ifndef LLVM_LIBC_SRC_STRING_MEMORY_UTILS_OP_RISCV_H
13 #define LLVM_LIBC_SRC_STRING_MEMORY_UTILS_OP_RISCV_H
15 #include "src/__support/macros/properties/architectures.h"
17 #if defined(LIBC_TARGET_ARCH_IS_ANY_RISCV)
19 #include "src/__support/common.h"
20 #include "src/string/memory_utils/op_generic.h"
22 namespace LIBC_NAMESPACE::generic
{
24 ///////////////////////////////////////////////////////////////////////////////
25 // Specializations for uint16_t
26 template <> struct cmp_is_expensive
<uint16_t> : public cpp::false_type
{};
27 template <> LIBC_INLINE
bool eq
<uint16_t>(CPtr p1
, CPtr p2
, size_t offset
) {
28 return load
<uint16_t>(p1
, offset
) == load
<uint16_t>(p2
, offset
);
31 LIBC_INLINE
uint32_t neq
<uint16_t>(CPtr p1
, CPtr p2
, size_t offset
) {
32 return load
<uint16_t>(p1
, offset
) ^ load
<uint16_t>(p2
, offset
);
35 LIBC_INLINE MemcmpReturnType cmp
<uint16_t>(CPtr p1
, CPtr p2
, size_t offset
) {
36 return static_cast<int32_t>(load_be
<uint16_t>(p1
, offset
)) -
37 static_cast<int32_t>(load_be
<uint16_t>(p2
, offset
));
40 LIBC_INLINE MemcmpReturnType cmp_neq
<uint16_t>(CPtr p1
, CPtr p2
, size_t offset
);
42 ///////////////////////////////////////////////////////////////////////////////
43 // Specializations for uint32_t
44 template <> struct cmp_is_expensive
<uint32_t> : public cpp::false_type
{};
45 template <> LIBC_INLINE
bool eq
<uint32_t>(CPtr p1
, CPtr p2
, size_t offset
) {
46 return load
<uint32_t>(p1
, offset
) == load
<uint32_t>(p2
, offset
);
49 LIBC_INLINE
uint32_t neq
<uint32_t>(CPtr p1
, CPtr p2
, size_t offset
) {
50 return load
<uint32_t>(p1
, offset
) ^ load
<uint32_t>(p2
, offset
);
53 LIBC_INLINE MemcmpReturnType cmp
<uint32_t>(CPtr p1
, CPtr p2
, size_t offset
) {
54 const auto a
= load_be
<uint32_t>(p1
, offset
);
55 const auto b
= load_be
<uint32_t>(p2
, offset
);
56 return cmp_uint32_t(a
, b
);
59 LIBC_INLINE MemcmpReturnType cmp_neq
<uint32_t>(CPtr p1
, CPtr p2
, size_t offset
);
61 ///////////////////////////////////////////////////////////////////////////////
62 // Specializations for uint64_t
63 template <> struct cmp_is_expensive
<uint64_t> : public cpp::true_type
{};
64 template <> LIBC_INLINE
bool eq
<uint64_t>(CPtr p1
, CPtr p2
, size_t offset
) {
65 return load
<uint64_t>(p1
, offset
) == load
<uint64_t>(p2
, offset
);
68 LIBC_INLINE
uint32_t neq
<uint64_t>(CPtr p1
, CPtr p2
, size_t offset
) {
69 return !eq
<uint64_t>(p1
, p2
, offset
);
72 LIBC_INLINE MemcmpReturnType cmp
<uint64_t>(CPtr p1
, CPtr p2
, size_t offset
);
74 LIBC_INLINE MemcmpReturnType cmp_neq
<uint64_t>(CPtr p1
, CPtr p2
,
76 const auto a
= load_be
<uint64_t>(p1
, offset
);
77 const auto b
= load_be
<uint64_t>(p2
, offset
);
78 return cmp_neq_uint64_t(a
, b
);
81 } // namespace LIBC_NAMESPACE::generic
83 #endif // LIBC_TARGET_ARCH_IS_ANY_RISCV
84 #endif // LLVM_LIBC_SRC_STRING_MEMORY_UTILS_OP_RISCV_H