[parisc-linux-cvs] diff - add a faster memset
Paul Bame
bame@fc.hp.com
Tue, 04 Jun 2002 10:10:56 -0600
This is simply the glibc memset tweeked so it will compile for us. We
were using the generic memset in lib/string.c which is really slow.
Index: Makefile
===================================================================
RCS file: /var/cvs/linux/Makefile,v
retrieving revision 1.304
diff -u -r1.304 Makefile
--- Makefile 2002/06/01 01:06:31 1.304
+++ Makefile 2002/06/04 15:35:03
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 4
SUBLEVEL = 18
-EXTRAVERSION = -pa33
+EXTRAVERSION = -pa34
KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
Index: arch/parisc/lib/Makefile
===================================================================
RCS file: /var/cvs/linux/arch/parisc/lib/Makefile,v
retrieving revision 1.9
diff -u -r1.9 Makefile
--- arch/parisc/lib/Makefile 2001/04/11 19:12:50 1.9
+++ arch/parisc/lib/Makefile 2002/06/04 15:35:03
@@ -4,6 +4,6 @@
L_TARGET = lib.a
-obj-y := lusercopy.o bitops.o checksum.o io.o
+obj-y := lusercopy.o bitops.o checksum.o io.o memset.o
include $(TOPDIR)/Rules.make
Index: arch/parisc/lib/memset.c
===================================================================
RCS file: memset.c
diff -N memset.c
--- /dev/null Thu Nov 30 14:01:38 2000
+++ memset.c Tue Jun 4 09:35:03 2002
@@ -0,0 +1,91 @@
+/* Copyright (C) 1991, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Slight modifications for pa-risc linux - Paul Bame <bame@debian.org> */
+
+#include <linux/types.h>
+#include <asm/string.h>
+
+#define OPSIZ (BITS_PER_LONG/8)
+typedef unsigned long op_t;
+
+void *
+memset (void *dstpp, int sc, size_t len)
+{
+ unsigned int c = sc;
+ long int dstp = (long int) dstpp;
+
+ if (len >= 8)
+ {
+ size_t xlen;
+ op_t cccc;
+
+ cccc = (unsigned char) c;
+ cccc |= cccc << 8;
+ cccc |= cccc << 16;
+ if (OPSIZ > 4)
+ /* Do the shift in two steps to avoid warning if long has 32 bits. */
+ cccc |= (cccc << 16) << 16;
+
+ /* There are at least some bytes to set.
+ No need to test for LEN == 0 in this alignment loop. */
+ while (dstp % OPSIZ != 0)
+ {
+ ((unsigned char *) dstp)[0] = c;
+ dstp += 1;
+ len -= 1;
+ }
+
+ /* Write 8 `op_t' per iteration until less than 8 `op_t' remain. */
+ xlen = len / (OPSIZ * 8);
+ while (xlen > 0)
+ {
+ ((op_t *) dstp)[0] = cccc;
+ ((op_t *) dstp)[1] = cccc;
+ ((op_t *) dstp)[2] = cccc;
+ ((op_t *) dstp)[3] = cccc;
+ ((op_t *) dstp)[4] = cccc;
+ ((op_t *) dstp)[5] = cccc;
+ ((op_t *) dstp)[6] = cccc;
+ ((op_t *) dstp)[7] = cccc;
+ dstp += 8 * OPSIZ;
+ xlen -= 1;
+ }
+ len %= OPSIZ * 8;
+
+ /* Write 1 `op_t' per iteration until less than OPSIZ bytes remain. */
+ xlen = len / OPSIZ;
+ while (xlen > 0)
+ {
+ ((op_t *) dstp)[0] = cccc;
+ dstp += OPSIZ;
+ xlen -= 1;
+ }
+ len %= OPSIZ;
+ }
+
+ /* Write the last few bytes. */
+ while (len > 0)
+ {
+ ((unsigned char *) dstp)[0] = c;
+ dstp += 1;
+ len -= 1;
+ }
+
+ return dstpp;
+}
Index: include/asm-parisc/string.h
===================================================================
RCS file: /var/cvs/linux/include/asm-parisc/string.h,v
retrieving revision 1.1
diff -u -r1.1 string.h
--- include/asm-parisc/string.h 1999/12/24 17:05:04 1.1
+++ include/asm-parisc/string.h 2002/06/04 15:35:05
@@ -1,2 +1,3 @@
-/* This left blank until we do parisc optimizations */
+#define __HAVE_ARCH_MEMSET
+extern void * memset(void *, int, size_t);