/*
 * Copyright 2011 Tilera Corporation. All Rights Reserved.
 *
 *   This program is free software; you can redistribute it and/or
 *   modify it under the terms of the GNU General Public License
 *   as published by the Free Software Foundation, version 2.
 *
 *   This program is distributed in the hope that it will be useful, but
 *   WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
 *   NON INFRINGEMENT.  See the GNU General Public License for
 *   more details.
 */

#include <linux/types.h>
#include <linux/string.h>
#include <linux/module.h>
/* EXPORT_SYMBOL() is in arch/tile/lib/exports.c since this should be asm. */

/* Must be 8 bytes in size. */
#define word_t uint64_t

#if CHIP_L2_LINE_SIZE() != 64 && CHIP_L2_LINE_SIZE() != 128
#error "Assumes 64 or 128 byte line size"
#endif

/* How many cache lines ahead should we prefetch? */
#define PREFETCH_LINES_AHEAD 3

/*
 * Provide "base versions" of load and store for the normal code path.
 * The kernel provides other versions for userspace copies.
 */
#define ST(p, v) (*(p) = (v))
#define LD(p) (*(p))

#ifndef USERCOPY_FUNC
#define ST1 ST
#define ST2 ST
#define ST4 ST
#define ST8 ST
#define LD1 LD
#define LD2 LD
#define LD4 LD
#define LD8 LD
#define RETVAL dstv
void *memcpy(void *__restrict dstv, const void *__restrict srcv, size_t n)
#else
/*
 * Special kernel version will provide implementation of the LDn/STn
 * macros to return a count of uncopied bytes due to mm fault.
 */
#define RETVAL 0
int USERCOPY_FUNC(void *__restrict dstv, const void *__restrict srcv, size_t n)
#endif
{
	char *__restrict dst1 = (char *)dstv;
	const char *__restrict src1 = (const char *)srcv;
	const char *__restrict src1_end;
	const char *__restrict prefetch;
	word_t *__restrict dst8;    /* 8-byte pointer to destination memory. */
	word_t final; /* Final bytes to write to trailing word, if any */
	long i;

	if (n < 16) {
		for (; n; n--)
			ST1(dst1++, LD1(src1++));
		return RETVAL;
	}

	/*
	 * Locate the end of source memory we will copy.  Don't
	 * prefetch past this.
	 */
	src1_end = src1 + n - 1;

	/* Prefetch ahead a few cache lines, but not past the end. */
	prefetch = src1;
	for (i = 0; i < PREFETCH_LINES_AHEAD; i++) {
		__insn_prefetch(prefetch);
		prefetch += CHIP_L2_LINE_SIZE();
		prefetch = (prefetch > src1_end) ? prefetch : src1;
	}

	/* Copy bytes until dst is word-aligned. */
	for (; (uintptr_t)dst1 & (sizeof(word_t) - 1); n--)
		ST1(dst1++, LD1(src1++));

	/* 8-byte pointer to destination memory. */
	dst8 = (word_t *)dst1;

	if (__builtin_expect((uintptr_t)src1 & (sizeof(word_t) - 1), 0)) {
		/*
		 * Misaligned copy.  Copy 8 bytes at a time, but don't
		 * bother with other fanciness.
		 *
		 * TODO: Consider prefetching and using wh64 as well.
		 */

		/* Create an aligned src8. */
		const word_t *__restrict src8 =
			(const word_t *)((uintptr_t)src1 & -sizeof(word_t));
		word_t b;

		word_t a = LD8(src8++);
		for (; n >= sizeof(word_t); n -= sizeof(word_t)) {
			b = LD8(src8++);
			a = __insn_dblalign(a, b, src1);
			ST8(dst8++, a);
			a = b;
		}

		if (n == 0)
			return RETVAL;

		b = ((const char *)src8 <= src1_end) ? *src8 : 0;

		/*
		 * Final source bytes to write to trailing partial
		 * word, if any.
		 */
		final = __insn_dblalign(a, b, src1);
	} else {
		/* Aligned copy. */

		const word_t* __restrict src8 = (const word_t *)src1;

		/* src8 and dst8 are both word-aligned. */
		if (n >= CHIP_L2_LINE_SIZE()) {
			/* Copy until 'dst' is cache-line-aligned. */
			for (; (uintptr_t)dst8 & (CHIP_L2_LINE_SIZE() - 1);
			     n -= sizeof(word_t))
				ST8(dst8++, LD8(src8++));

			for (; n >= CHIP_L2_LINE_SIZE(); ) {
				__insn_wh64(dst8);

				/*
				 * Prefetch and advance to next line
				 * to prefetch, but don't go past the end
				 */
				__insn_prefetch(prefetch);
				prefetch += CHIP_L2_LINE_SIZE();
				prefetch = (prefetch > src1_end) ? prefetch :
					(const char *)src8;

				/*
				 * Copy an entire cache line.  Manually
				 * unrolled to avoid idiosyncracies of
				 * compiler unrolling.
				 */
#define COPY_WORD(offset) ({ ST8(dst8+offset, LD8(src8+offset)); n -= 8; })
				COPY_WORD(0);
				COPY_WORD(1);
				COPY_WORD(2);
				COPY_WORD(3);
				COPY_WORD(4);
				COPY_WORD(5);
				COPY_WORD(6);
				COPY_WORD(7);
#if CHIP_L2_LINE_SIZE() == 128
				COPY_WORD(8);
				COPY_WORD(9);
				COPY_WORD(10);
				COPY_WORD(11);
				COPY_WORD(12);
				COPY_WORD(13);
				COPY_WORD(14);
				COPY_WORD(15);
#elif CHIP_L2_LINE_SIZE() != 64
# error Fix code that assumes particular L2 cache line sizes
#endif

				dst8 += CHIP_L2_LINE_SIZE() / sizeof(word_t);
				src8 += CHIP_L2_LINE_SIZE() / sizeof(word_t);
			}
		}

		for (; n >= sizeof(word_t); n -= sizeof(word_t))
			ST8(dst8++, LD8(src8++));

		if (__builtin_expect(n == 0, 1))
			return RETVAL;

		final = LD8(src8);
	}

	/* n != 0 if we get here.  Write out any trailing bytes. */
	dst1 = (char *)dst8;
#ifndef __BIG_ENDIAN__
	if (n & 4) {
		ST4((uint32_t *)dst1, final);
		dst1 += 4;
		final >>= 32;
		n &= 3;
	}
	if (n & 2) {
		ST2((uint16_t *)dst1, final);
		dst1 += 2;
		final >>= 16;
		n &= 1;
	}
	if (n)
		ST1((uint8_t *)dst1, final);
#else
	if (n & 4) {
		ST4((uint32_t *)dst1, final >> 32);
		dst1 += 4;
        }
        else
        {
		final >>= 32;
        }
	if (n & 2) {
		ST2((uint16_t *)dst1, final >> 16);
		dst1 += 2;
        }
        else
        {
		final >>= 16;
        }
	if (n & 1)
		ST1((uint8_t *)dst1, final >> 8);
#endif

	return RETVAL;
}

#ifdef USERCOPY_FUNC
#undef ST1
#undef ST2
#undef ST4
#undef ST8
#undef LD1
#undef LD2
#undef LD4
#undef LD8
#undef USERCOPY_FUNC
#endif
