1*f51a2264SHeinrich Schuchardt // SPDX-License-Identifier: GPL-2.0+
2*f51a2264SHeinrich Schuchardt /*
3*f51a2264SHeinrich Schuchardt  * Library for freestanding binary
4*f51a2264SHeinrich Schuchardt  *
5*f51a2264SHeinrich Schuchardt  * Copyright 2019, Heinrich Schuchardt <xypron.glpk@gmx.de>
6*f51a2264SHeinrich Schuchardt  *
7*f51a2264SHeinrich Schuchardt  * GCC requires that freestanding programs provide memcpy(), memmove(),
8*f51a2264SHeinrich Schuchardt  * memset(), and memcmp().
9*f51a2264SHeinrich Schuchardt  */
10*f51a2264SHeinrich Schuchardt 
11*f51a2264SHeinrich Schuchardt #include <common.h>
12*f51a2264SHeinrich Schuchardt 
13*f51a2264SHeinrich Schuchardt /**
14*f51a2264SHeinrich Schuchardt  * memcmp() - compare memory areas
15*f51a2264SHeinrich Schuchardt  *
16*f51a2264SHeinrich Schuchardt  * @s1:		pointer to first area
17*f51a2264SHeinrich Schuchardt  * @s2:		pointer to second area
18*f51a2264SHeinrich Schuchardt  * @n:		number of bytes to compare
19*f51a2264SHeinrich Schuchardt  * Return:	0 if both memory areas are the same, otherwise the sign of the
20*f51a2264SHeinrich Schuchardt  *		result value is the same as the sign of the difference between
21*f51a2264SHeinrich Schuchardt  *		the first differing pair of bytes taken as u8.
22*f51a2264SHeinrich Schuchardt  */
memcmp(const void * s1,const void * s2,size_t n)23*f51a2264SHeinrich Schuchardt int memcmp(const void *s1, const void *s2, size_t n)
24*f51a2264SHeinrich Schuchardt {
25*f51a2264SHeinrich Schuchardt 	const u8 *pos1 = s1;
26*f51a2264SHeinrich Schuchardt 	const u8 *pos2 = s2;
27*f51a2264SHeinrich Schuchardt 
28*f51a2264SHeinrich Schuchardt 	for (; n; --n) {
29*f51a2264SHeinrich Schuchardt 		if (*pos1 != *pos2)
30*f51a2264SHeinrich Schuchardt 			return *pos1 - *pos2;
31*f51a2264SHeinrich Schuchardt 		++pos1;
32*f51a2264SHeinrich Schuchardt 		++pos2;
33*f51a2264SHeinrich Schuchardt 	}
34*f51a2264SHeinrich Schuchardt 	return 0;
35*f51a2264SHeinrich Schuchardt }
36*f51a2264SHeinrich Schuchardt 
37*f51a2264SHeinrich Schuchardt /**
38*f51a2264SHeinrich Schuchardt  * memcpy() - copy memory area
39*f51a2264SHeinrich Schuchardt  *
40*f51a2264SHeinrich Schuchardt  * @dest:	destination buffer
41*f51a2264SHeinrich Schuchardt  * @src:	source buffer
42*f51a2264SHeinrich Schuchardt  * @n:		number of bytes to copy
43*f51a2264SHeinrich Schuchardt  * Return:	pointer to destination buffer
44*f51a2264SHeinrich Schuchardt  */
memmove(void * dest,const void * src,size_t n)45*f51a2264SHeinrich Schuchardt void *memmove(void *dest, const void *src, size_t n)
46*f51a2264SHeinrich Schuchardt {
47*f51a2264SHeinrich Schuchardt 	u8 *d = dest;
48*f51a2264SHeinrich Schuchardt 	const u8 *s = src;
49*f51a2264SHeinrich Schuchardt 
50*f51a2264SHeinrich Schuchardt 	if (d >= s) {
51*f51a2264SHeinrich Schuchardt 		for (; n; --n)
52*f51a2264SHeinrich Schuchardt 			*d++ = *s++;
53*f51a2264SHeinrich Schuchardt 	} else {
54*f51a2264SHeinrich Schuchardt 		d += n;
55*f51a2264SHeinrich Schuchardt 		s += n;
56*f51a2264SHeinrich Schuchardt 		for (; n; --n)
57*f51a2264SHeinrich Schuchardt 			*--d = *--s;
58*f51a2264SHeinrich Schuchardt 	}
59*f51a2264SHeinrich Schuchardt 	return dest;
60*f51a2264SHeinrich Schuchardt }
61*f51a2264SHeinrich Schuchardt 
62*f51a2264SHeinrich Schuchardt /**
63*f51a2264SHeinrich Schuchardt  * memcpy() - copy memory area
64*f51a2264SHeinrich Schuchardt  *
65*f51a2264SHeinrich Schuchardt  * @dest:	destination buffer
66*f51a2264SHeinrich Schuchardt  * @src:	source buffer
67*f51a2264SHeinrich Schuchardt  * @n:		number of bytes to copy
68*f51a2264SHeinrich Schuchardt  * Return:	pointer to destination buffer
69*f51a2264SHeinrich Schuchardt  */
memcpy(void * dest,const void * src,size_t n)70*f51a2264SHeinrich Schuchardt void *memcpy(void *dest, const void *src, size_t n)
71*f51a2264SHeinrich Schuchardt {
72*f51a2264SHeinrich Schuchardt 	return memmove(dest, src, n);
73*f51a2264SHeinrich Schuchardt }
74*f51a2264SHeinrich Schuchardt 
75*f51a2264SHeinrich Schuchardt /**
76*f51a2264SHeinrich Schuchardt  * memset() - fill memory with a constant byte
77*f51a2264SHeinrich Schuchardt  *
78*f51a2264SHeinrich Schuchardt  * @s:		destination buffer
79*f51a2264SHeinrich Schuchardt  * @c:		byte value
80*f51a2264SHeinrich Schuchardt  * @n:		number of bytes to set
81*f51a2264SHeinrich Schuchardt  * Return:	pointer to destination buffer
82*f51a2264SHeinrich Schuchardt  */
memset(void * s,int c,size_t n)83*f51a2264SHeinrich Schuchardt void *memset(void *s, int c, size_t n)
84*f51a2264SHeinrich Schuchardt {
85*f51a2264SHeinrich Schuchardt 	u8 *d = s;
86*f51a2264SHeinrich Schuchardt 
87*f51a2264SHeinrich Schuchardt 	for (; n; --n)
88*f51a2264SHeinrich Schuchardt 		*d++ = c;
89*f51a2264SHeinrich Schuchardt 	return s;
90*f51a2264SHeinrich Schuchardt }
91