/*
 * It has originally been taken from the HelenOS project
 * (http://www.helenos.eu), and slightly modified for our purposes.
 *
 * Copyright (c) 2005 Martin Decky
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 * - The name of the author may not be used to endorse or promote products
 *   derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <stddef.h>
#include <string.h>

static void *default_memset(void *s, int c, size_t n)
{
	size_t i;
	void *ret = s;
	unsigned long w = c & 0xff;

	for (i = 1; i < sizeof(unsigned long); i <<= 1)
		w = (w << (i * 8)) | w;

	for (i = 0; i < n / sizeof(unsigned long); i++)
		((unsigned long *)s)[i] = w;

	s += i * sizeof(unsigned long);

	for (i = 0; i < n % sizeof(unsigned long); i++)
		((uint8_t *)s)[i] = (uint8_t)c;

	return ret;
}

void *memset(void *s, int c, size_t n)
	__attribute__((weak, alias("default_memset")));

static void *default_memcpy(void *dst, const void *src, size_t n)
{
	size_t i;
	void *ret = dst;

	for(i = 0; i < n / sizeof(unsigned long); i++)
		((unsigned long *)dst)[i] = ((unsigned long *)src)[i];

	src += i * sizeof(unsigned long);
	dst += i * sizeof(unsigned long);

	for(i = 0; i < n % sizeof(unsigned long); i++)
		((uint8_t *)dst)[i] = ((uint8_t *)src)[i];

	return ret;
}

void *memcpy(void *dst, const void *src, size_t n)
	__attribute__((weak, alias("default_memcpy")));

static void *default_memmove(void *dst, const void *src, size_t n)
{
	size_t i, offs;

	if (src > dst)
		return memcpy(dst, src, n);

	offs = n - (n % sizeof(unsigned long));

	for (i = (n % sizeof(unsigned long)) - 1; i >= 0; i--)
		((uint8_t *)dst)[i + offs] = ((uint8_t *)src)[i + offs];

	for (i = n / sizeof(unsigned long) - 1; i >= 0; i--)
		((unsigned long *)dst)[i] = ((unsigned long *)src)[i];

	return dst;
}

void *memmove(void *dst, const void *src, size_t n)
	__attribute__((weak, alias("default_memmove")));

/**
 * Compare two memory areas.
 *
 * @param s1 Pointer to the first area to compare.
 * @param s2 Pointer to the second area to compare.
 * @param n Size of the first area in bytes (both must have the same length).
 * @return If n is 0, return zero. Otherwise, return a value less than, equal
 * 	   to, or greater than zero if s1 is found less than, equal to, or
 * 	   greater than s2 respectively.
 */

static int default_memcmp(const void *s1, const void *s2, size_t n)
{
	size_t i;

	for (i = 0; i < n / sizeof(unsigned long); i++)
		if (((unsigned long *)s1)[i] != ((unsigned long *)s2)[i])
			break;	/* fall through to find differing byte */

	for (i *= sizeof(unsigned long); i < n; i++)
		if (((uint8_t *)s1)[i] != ((uint8_t *)s2)[i])
			return ((uint8_t *)s1)[i] - ((uint8_t *)s2)[i];

	return 0;
}

int memcmp(const void *s1, const void *s2, size_t n)
	__attribute__((weak, alias("default_memcmp")));
