162306a36Sopenharmony_ci/*
262306a36Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public
362306a36Sopenharmony_ci * License.  See the file COPYING in the main directory of this archive
462306a36Sopenharmony_ci * for more details.
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#include <linux/module.h>
862306a36Sopenharmony_ci#include <linux/string.h>
962306a36Sopenharmony_ci
1062306a36Sopenharmony_civoid *memset(void *s, int c, size_t count)
1162306a36Sopenharmony_ci{
1262306a36Sopenharmony_ci	void *xs = s;
1362306a36Sopenharmony_ci	size_t temp;
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci	if (!count)
1662306a36Sopenharmony_ci		return xs;
1762306a36Sopenharmony_ci	c &= 0xff;
1862306a36Sopenharmony_ci	c |= c << 8;
1962306a36Sopenharmony_ci	c |= c << 16;
2062306a36Sopenharmony_ci	if ((long)s & 1) {
2162306a36Sopenharmony_ci		char *cs = s;
2262306a36Sopenharmony_ci		*cs++ = c;
2362306a36Sopenharmony_ci		s = cs;
2462306a36Sopenharmony_ci		count--;
2562306a36Sopenharmony_ci	}
2662306a36Sopenharmony_ci	if (count > 2 && (long)s & 2) {
2762306a36Sopenharmony_ci		short *ss = s;
2862306a36Sopenharmony_ci		*ss++ = c;
2962306a36Sopenharmony_ci		s = ss;
3062306a36Sopenharmony_ci		count -= 2;
3162306a36Sopenharmony_ci	}
3262306a36Sopenharmony_ci	temp = count >> 2;
3362306a36Sopenharmony_ci	if (temp) {
3462306a36Sopenharmony_ci		long *ls = s;
3562306a36Sopenharmony_ci#if defined(CONFIG_M68000) || defined(CONFIG_COLDFIRE)
3662306a36Sopenharmony_ci		for (; temp; temp--)
3762306a36Sopenharmony_ci			*ls++ = c;
3862306a36Sopenharmony_ci#else
3962306a36Sopenharmony_ci		size_t temp1;
4062306a36Sopenharmony_ci		asm volatile (
4162306a36Sopenharmony_ci			"	movel %1,%2\n"
4262306a36Sopenharmony_ci			"	andw  #7,%2\n"
4362306a36Sopenharmony_ci			"	lsrl  #3,%1\n"
4462306a36Sopenharmony_ci			"	negw  %2\n"
4562306a36Sopenharmony_ci			"	jmp   %%pc@(2f,%2:w:2)\n"
4662306a36Sopenharmony_ci			"1:	movel %3,%0@+\n"
4762306a36Sopenharmony_ci			"	movel %3,%0@+\n"
4862306a36Sopenharmony_ci			"	movel %3,%0@+\n"
4962306a36Sopenharmony_ci			"	movel %3,%0@+\n"
5062306a36Sopenharmony_ci			"	movel %3,%0@+\n"
5162306a36Sopenharmony_ci			"	movel %3,%0@+\n"
5262306a36Sopenharmony_ci			"	movel %3,%0@+\n"
5362306a36Sopenharmony_ci			"	movel %3,%0@+\n"
5462306a36Sopenharmony_ci			"2:	dbra  %1,1b\n"
5562306a36Sopenharmony_ci			"	clrw  %1\n"
5662306a36Sopenharmony_ci			"	subql #1,%1\n"
5762306a36Sopenharmony_ci			"	jpl   1b"
5862306a36Sopenharmony_ci			: "=a" (ls), "=d" (temp), "=&d" (temp1)
5962306a36Sopenharmony_ci			: "d" (c), "0" (ls), "1" (temp));
6062306a36Sopenharmony_ci#endif
6162306a36Sopenharmony_ci		s = ls;
6262306a36Sopenharmony_ci	}
6362306a36Sopenharmony_ci	if (count & 2) {
6462306a36Sopenharmony_ci		short *ss = s;
6562306a36Sopenharmony_ci		*ss++ = c;
6662306a36Sopenharmony_ci		s = ss;
6762306a36Sopenharmony_ci	}
6862306a36Sopenharmony_ci	if (count & 1) {
6962306a36Sopenharmony_ci		char *cs = s;
7062306a36Sopenharmony_ci		*cs = c;
7162306a36Sopenharmony_ci	}
7262306a36Sopenharmony_ci	return xs;
7362306a36Sopenharmony_ci}
7462306a36Sopenharmony_ciEXPORT_SYMBOL(memset);
75