18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu>
38c2ecf20Sopenharmony_ci * Copyright (C) 2008-2009 PetaLogix
48c2ecf20Sopenharmony_ci * Copyright (C) 2007 John Williams
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci * Reasonably optimised generic C-code for memset on Microblaze
78c2ecf20Sopenharmony_ci * This is generic C code to do efficient, alignment-aware memcpy.
88c2ecf20Sopenharmony_ci *
98c2ecf20Sopenharmony_ci * It is based on demo code originally Copyright 2001 by Intel Corp, taken from
108c2ecf20Sopenharmony_ci * http://www.embedded.com/showArticle.jhtml?articleID=19205567
118c2ecf20Sopenharmony_ci *
128c2ecf20Sopenharmony_ci * Attempts were made, unsuccessfully, to contact the original
138c2ecf20Sopenharmony_ci * author of this code (Michael Morrow, Intel).  Below is the original
148c2ecf20Sopenharmony_ci * copyright notice.
158c2ecf20Sopenharmony_ci *
168c2ecf20Sopenharmony_ci * This software has been developed by Intel Corporation.
178c2ecf20Sopenharmony_ci * Intel specifically disclaims all warranties, express or
188c2ecf20Sopenharmony_ci * implied, and all liability, including consequential and
198c2ecf20Sopenharmony_ci * other indirect damages, for the use of this program, including
208c2ecf20Sopenharmony_ci * liability for infringement of any proprietary rights,
218c2ecf20Sopenharmony_ci * and including the warranties of merchantability and fitness
228c2ecf20Sopenharmony_ci * for a particular purpose. Intel does not assume any
238c2ecf20Sopenharmony_ci * responsibility for and errors which may appear in this program
248c2ecf20Sopenharmony_ci * not any responsibility to update it.
258c2ecf20Sopenharmony_ci */
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_ci#include <linux/export.h>
288c2ecf20Sopenharmony_ci#include <linux/types.h>
298c2ecf20Sopenharmony_ci#include <linux/stddef.h>
308c2ecf20Sopenharmony_ci#include <linux/compiler.h>
318c2ecf20Sopenharmony_ci#include <linux/string.h>
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ci#ifdef __HAVE_ARCH_MEMSET
348c2ecf20Sopenharmony_ci#ifndef CONFIG_OPT_LIB_FUNCTION
358c2ecf20Sopenharmony_civoid *memset(void *v_src, int c, __kernel_size_t n)
368c2ecf20Sopenharmony_ci{
378c2ecf20Sopenharmony_ci	char *src = v_src;
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci	/* Truncate c to 8 bits */
408c2ecf20Sopenharmony_ci	c = (c & 0xFF);
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci	/* Simple, byte oriented memset or the rest of count. */
438c2ecf20Sopenharmony_ci	while (n--)
448c2ecf20Sopenharmony_ci		*src++ = c;
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci	return v_src;
478c2ecf20Sopenharmony_ci}
488c2ecf20Sopenharmony_ci#else /* CONFIG_OPT_LIB_FUNCTION */
498c2ecf20Sopenharmony_civoid *memset(void *v_src, int c, __kernel_size_t n)
508c2ecf20Sopenharmony_ci{
518c2ecf20Sopenharmony_ci	char *src = v_src;
528c2ecf20Sopenharmony_ci	uint32_t *i_src;
538c2ecf20Sopenharmony_ci	uint32_t w32 = 0;
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci	/* Truncate c to 8 bits */
568c2ecf20Sopenharmony_ci	c = (c & 0xFF);
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_ci	if (unlikely(c)) {
598c2ecf20Sopenharmony_ci		/* Make a repeating word out of it */
608c2ecf20Sopenharmony_ci		w32 = c;
618c2ecf20Sopenharmony_ci		w32 |= w32 << 8;
628c2ecf20Sopenharmony_ci		w32 |= w32 << 16;
638c2ecf20Sopenharmony_ci	}
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci	if (likely(n >= 4)) {
668c2ecf20Sopenharmony_ci		/* Align the destination to a word boundary */
678c2ecf20Sopenharmony_ci		/* This is done in an endian independent manner */
688c2ecf20Sopenharmony_ci		switch ((unsigned) src & 3) {
698c2ecf20Sopenharmony_ci		case 1:
708c2ecf20Sopenharmony_ci			*src++ = c;
718c2ecf20Sopenharmony_ci			--n;
728c2ecf20Sopenharmony_ci		case 2:
738c2ecf20Sopenharmony_ci			*src++ = c;
748c2ecf20Sopenharmony_ci			--n;
758c2ecf20Sopenharmony_ci		case 3:
768c2ecf20Sopenharmony_ci			*src++ = c;
778c2ecf20Sopenharmony_ci			--n;
788c2ecf20Sopenharmony_ci		}
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_ci		i_src  = (void *)src;
818c2ecf20Sopenharmony_ci
828c2ecf20Sopenharmony_ci		/* Do as many full-word copies as we can */
838c2ecf20Sopenharmony_ci		for (; n >= 4; n -= 4)
848c2ecf20Sopenharmony_ci			*i_src++ = w32;
858c2ecf20Sopenharmony_ci
868c2ecf20Sopenharmony_ci		src  = (void *)i_src;
878c2ecf20Sopenharmony_ci	}
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_ci	/* Simple, byte oriented memset or the rest of count. */
908c2ecf20Sopenharmony_ci	while (n--)
918c2ecf20Sopenharmony_ci		*src++ = c;
928c2ecf20Sopenharmony_ci
938c2ecf20Sopenharmony_ci	return v_src;
948c2ecf20Sopenharmony_ci}
958c2ecf20Sopenharmony_ci#endif /* CONFIG_OPT_LIB_FUNCTION */
968c2ecf20Sopenharmony_ciEXPORT_SYMBOL(memset);
978c2ecf20Sopenharmony_ci#endif /* __HAVE_ARCH_MEMSET */
98