/*
 * Original source code from PSXSDK, by Xavier Del Campo Romero.
 * Released under a weak copyleft-like license, pasted below:
 *
 * You can use this library for any project, commercial and non-commercial,
 * open-source and closed-source. But if you modify the library, you must
 * redistribute the source for the modifications you did to it.
 * Not doing that constitutes an infringement of this license.
 * You are not obliged to redistribute the source code of this library if it
 * was not modified at all by you or anyone related to you.
 *
 * There is no advertising clause; you aren't obliged to mention this library
 * in any documentation of your work using it; however, it would be a nice gesture
 * if you did so.
 *
 * These terms were written to not make people close this work which was released
 * for all to share. In fact, no use is otherwise restricted.
 */

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

void *memcpy(void *const dst, const void *const src, size_t n)
{
	union
	{
		const void *v;
		const unsigned char *c;
		const unsigned int *w;
	} srcl;

	union
	{
		void *v;
		unsigned char *c;
		unsigned int *w;
	} dstl;

	srcl.v = src;
	dstl.v = dst;

	/* Avoid unaligned access before doing word access. */
	while (n && (((ptrdiff_t)dstl.v & (sizeof (int) - 1))
		|| ((ptrdiff_t)srcl.v & (sizeof (int) - 1))))
	{
		*dstl.c++ = *srcl.c++;
		n--;
	}

	for (; n >= sizeof (int); n -= sizeof (int))
		*dstl.w++ = *srcl.w++;

	while (n--)
		*dstl.c++ = *srcl.c++;

	return dst;
}
