1/*
2 * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <stddef.h> /* size_t */
8
9/*
10 * Fill @count bytes of memory pointed to by @dst with @val
11 */
12void *memset(void *dst, int val, size_t count)
13{
14	char *ptr = dst;
15
16	while (count--)
17		*ptr++ = val;
18
19	return dst;
20}
21
22/*
23 * Compare @len bytes of @s1 and @s2
24 */
25int memcmp(const void *s1, const void *s2, size_t len)
26{
27	const unsigned char *s = s1;
28	const unsigned char *d = s2;
29	unsigned char sc;
30	unsigned char dc;
31
32	while (len--) {
33		sc = *s++;
34		dc = *d++;
35		if (sc - dc)
36			return (sc - dc);
37	}
38
39	return 0;
40}
41
42/*
43 * Copy @len bytes from @src to @dst
44 */
45void *memcpy(void *dst, const void *src, size_t len)
46{
47	const char *s = src;
48	char *d = dst;
49
50	while (len--)
51		*d++ = *s++;
52
53	return dst;
54}
55
56/*
57 * Move @len bytes from @src to @dst
58 */
59void *memmove(void *dst, const void *src, size_t len)
60{
61	/*
62	 * The following test makes use of unsigned arithmetic overflow to
63	 * more efficiently test the condition !(src <= dst && dst < str+len).
64	 * It also avoids the situation where the more explicit test would give
65	 * incorrect results were the calculation str+len to overflow (though
66	 * that issue is probably moot as such usage is probably undefined
67	 * behaviour and a bug anyway.
68	 */
69	if ((size_t)dst - (size_t)src >= len) {
70		/* destination not in source data, so can safely use memcpy */
71		return memcpy(dst, src, len);
72	} else {
73		/* copy backwards... */
74		const char *end = dst;
75		const char *s = (const char *)src + len;
76		char *d = (char *)dst + len;
77		while (d != end)
78			*--d = *--s;
79	}
80	return dst;
81}
82
83/*
84 * Scan @len bytes of @src for value @c
85 */
86void *memchr(const void *src, int c, size_t len)
87{
88	const char *s = src;
89
90	while (len--) {
91		if (*s == c)
92			return (void *) s;
93		s++;
94	}
95
96	return NULL;
97}
98