[libc] Add memcmp implementation.

Reviewed By: gchatelet

Differential Revision: https://reviews.llvm.org/D93009
This commit is contained in:
Cheng Wang 2020-12-04 18:21:48 +08:00
parent 57a3d9ec4a
commit af68c3b892
7 changed files with 101 additions and 0 deletions

View File

@ -26,6 +26,7 @@ set(TARGET_LIBC_ENTRYPOINTS
# string.h entrypoints
libc.src.string.bzero
libc.src.string.memchr
libc.src.string.memcmp
libc.src.string.memcpy
libc.src.string.memset
libc.src.string.memrchr

View File

@ -48,6 +48,7 @@ set(TARGET_LIBC_ENTRYPOINTS
# string.h entrypoints
libc.src.string.bzero
libc.src.string.memchr
libc.src.string.memcmp
libc.src.string.memcpy
libc.src.string.memrchr
libc.src.string.memset

View File

@ -58,6 +58,14 @@ add_entrypoint_object(
.string_utils
)
add_entrypoint_object(
memcmp
SRCS
memcmp.cpp
HDRS
memcmp.h
)
add_entrypoint_object(
strchr
SRCS

View File

@ -0,0 +1,27 @@
//===-- Implementation of memcmp ------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "src/string/memcmp.h"
#include "src/__support/common.h"
#include <stddef.h> // size_t
namespace __llvm_libc {
// TODO: It is a simple implementation, an optimized version is preparing.
int LLVM_LIBC_ENTRYPOINT(memcmp)(const void *lhs, const void *rhs,
size_t count) {
const unsigned char *_lhs = reinterpret_cast<const unsigned char *>(lhs);
const unsigned char *_rhs = reinterpret_cast<const unsigned char *>(rhs);
for (size_t i = 0; i < count; ++i)
if (_lhs[i] != _rhs[i])
return _lhs[i] - _rhs[i];
// count is 0 or _lhs and _rhs are the same.
return 0;
}
} // namespace __llvm_libc

20
libc/src/string/memcmp.h Normal file
View File

@ -0,0 +1,20 @@
//===-- Implementation header for memcmp ------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SRC_STRING_MEMCMP_H
#define LLVM_LIBC_SRC_STRING_MEMCMP_H
#include <stddef.h> // size_t
namespace __llvm_libc {
int memcmp(const void *lhs, const void *rhs, size_t count);
} // namespace __llvm_libc
#endif // LLVM_LIBC_SRC_STRING_MEMCMP_H

View File

@ -52,6 +52,16 @@ add_libc_unittest(
libc.src.string.memchr
)
add_libc_unittest(
memcmp_test
SUITE
libc_string_unittests
SRCS
memcmp_test.cpp
DEPENDS
libc.src.string.memcmp
)
add_libc_unittest(
strchr_test
SUITE

View File

@ -0,0 +1,34 @@
//===-- Unittests for memcmp ----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "src/string/memcmp.h"
#include "utils/UnitTest/Test.h"
TEST(MemcmpTest, CmpZeroByte) {
const char *lhs = "ab";
const char *rhs = "bc";
EXPECT_EQ(__llvm_libc::memcmp(lhs, rhs, 0), 0);
}
TEST(MemcmpTest, LhsRhsAreTheSame) {
const char *lhs = "ab";
const char *rhs = "ab";
EXPECT_EQ(__llvm_libc::memcmp(lhs, rhs, 2), 0);
}
TEST(MemcmpTest, LhsBeforeRhsLexically) {
const char *lhs = "ab";
const char *rhs = "ac";
EXPECT_EQ(__llvm_libc::memcmp(lhs, rhs, 2), -1);
}
TEST(MemcmpTest, LhsAfterRhsLexically) {
const char *lhs = "ac";
const char *rhs = "ab";
EXPECT_EQ(__llvm_libc::memcmp(lhs, rhs, 2), 1);
}