Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/lib/libkern/arch/hppa Added hppa support to libkern.
details: https://anonhg.NetBSD.org/src/rev/56ef93045d91
branches: trunk
changeset: 532394:56ef93045d91
user: fredette <fredette%NetBSD.org@localhost>
date: Thu Jun 06 20:03:37 2002 +0000
description:
Added hppa support to libkern.
diffstat:
sys/lib/libkern/arch/hppa/Makefile.inc | 22 +
sys/lib/libkern/arch/hppa/bcopy.S | 618 ++++++++++
sys/lib/libkern/arch/hppa/memcpy.S | 4 +
sys/lib/libkern/arch/hppa/memmove.S | 4 +
sys/lib/libkern/arch/hppa/milli.S | 1814 ++++++++++++++++++++++++++++++++
sys/lib/libkern/arch/hppa/prefix.h | 85 +
sys/lib/libkern/arch/hppa/spcopy.S | 4 +
sys/lib/libkern/arch/hppa/strlcpy.S | 70 +
8 files changed, 2621 insertions(+), 0 deletions(-)
diffs (truncated from 2653 to 300 lines):
diff -r 969cc81e3e20 -r 56ef93045d91 sys/lib/libkern/arch/hppa/Makefile.inc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/lib/libkern/arch/hppa/Makefile.inc Thu Jun 06 20:03:37 2002 +0000
@@ -0,0 +1,22 @@
+# $NetBSD: Makefile.inc,v 1.1 2002/06/06 20:03:37 fredette Exp $
+
+# $OpenBSD: Makefile.inc,v 1.14 2000/12/29 19:04:41 mickey Exp $
+
+SRCS+= __main.c imax.c imin.c lmax.c lmin.c max.c min.c ulmax.c ulmin.c \
+ random.c ashrdi3.c divdi3.c strncpy.c strncmp.c strcmp.c memchr.c \
+ memcmp.c memset.c strlen.c strcpy.c \
+ strcat.c skpc.c strncasecmp.c \
+ bcmp.c scanc.c ffs.c
+SRCS+= __assert.c
+
+SRCS+= milli.S strlcpy.S
+OBJS+= bzero.o
+
+SRCS+= bcopy.S spcopy.S memcpy.S memmove.S
+CLEANFILES+= bzero.o
+
+bzero.o: ${KERNDIR}/memset.c
+ @echo "${COMPILE.c} -DBZERO ${KERNDIR}/memset.c -o ${.TARGET}"
+ @${COMPILE.c} -DBZERO ${KERNDIR}/memset.c -o ${.TARGET}.o
+ @${LD} -x -r ${.TARGET}.o -o ${.TARGET}
+ @rm -f ${.TARGET}.o
diff -r 969cc81e3e20 -r 56ef93045d91 sys/lib/libkern/arch/hppa/bcopy.S
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/lib/libkern/arch/hppa/bcopy.S Thu Jun 06 20:03:37 2002 +0000
@@ -0,0 +1,618 @@
+/* $NetBSD: bcopy.S,v 1.1 2002/06/06 20:03:38 fredette Exp $ */
+
+/*
+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Matthew Fredette.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Copy routines for NetBSD/hppa.
+ */
+
+#undef _LOCORE
+#define _LOCORE /* XXX fredette - unfortunate */
+#include <machine/asm.h>
+#include <machine/frame.h>
+
+#if defined(LIBC_SCCS) && !defined(lint)
+ RCSID("$NetBSD: bcopy.S,v 1.1 2002/06/06 20:03:38 fredette Exp $")
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * The stbys instruction is a little asymmetric. When (%r2 & 3)
+ * is zero, stbys,b,m %r1, 4(%r2) works like stws,ma. You
+ * might then wish that when (%r2 & 3) == 0, stbys,e,m %r1, -4(%r2)
+ * worked like stws,mb. But it doesn't.
+ *
+ * This macro works around this problem. It requires that %t2
+ * hold the number of bytes that will be written by this store
+ * (meaning that it ranges from one to four).
+ *
+ * Watch the delay-slot trickery here. The comib is used to set
+ * up which instruction, either the stws or the stbys, is run
+ * in the delay slot of the b instruction.
+ */
+#define _STBYS_E_M(r, dst_spc, dst_off) \
+ comib,<> 4, t2, 4 ! \
+ b 4 ! \
+ stws,mb r, -4(dst_spc, dst_off) ! \
+ stbys,e,m r, 0(dst_spc, dst_off)
+
+/*
+ * This macro does a bulk copy with no shifting. cmplt and m are
+ * the completer and displacement multiplier, respectively, for
+ * the load and store instructions.
+ */
+#define _COPY(src_spc, src_off, dst_spc, dst_off, count, cmplt, m) \
+ ! \
+ /* ! \
+ * Loop storing 16 bytes at a time. Since count ! \
+ * may be > INT_MAX, we have to be careful and ! \
+ * avoid comparisons that treat it as a signed ! \
+ * quantity, until after this loop, when count ! \
+ * is guaranteed to be less than 16. ! \
+ */ ! \
+ comib,>>=,n 15, count, _LABEL(_skip16) ! \
+.label _LABEL(_loop16) ! \
+ addi -16, count, count ! \
+ ldws,cmplt m*4(src_spc, src_off), t1 ! \
+ ldws,cmplt m*4(src_spc, src_off), t2 ! \
+ ldws,cmplt m*4(src_spc, src_off), t3 ! \
+ ldws,cmplt m*4(src_spc, src_off), t4 ! \
+ stws,cmplt t1, m*4(dst_spc, dst_off) ! \
+ stws,cmplt t2, m*4(dst_spc, dst_off) ! \
+ stws,cmplt t3, m*4(dst_spc, dst_off) ! \
+ comib,<< 15, count, _LABEL(_loop16) ! \
+ stws,cmplt t4, m*4(dst_spc, dst_off) ! \
+.label _LABEL(_skip16) ! \
+ ! \
+ /* Loop storing 4 bytes at a time. */ ! \
+ addib,<,n -4, count, _LABEL(_skip4) ! \
+.label _LABEL(_loop4) ! \
+ ldws,cmplt m*4(src_spc, src_off), t1 ! \
+ addib,>= -4, count, _LABEL(_loop4) ! \
+ stws,cmplt t1, m*4(dst_spc, dst_off) ! \
+.label _LABEL(_skip4) ! \
+ /* Restore the correct count. */ ! \
+ addi 4, count, count ! \
+ ! \
+.label _LABEL(_do1) ! \
+ ! \
+ /* Loop storing 1 byte at a time. */ ! \
+ addib,<,n -1, count, _LABEL(_skip1) ! \
+.label _LABEL(_loop1) ! \
+ ldbs,cmplt m*1(src_spc, src_off), t1 ! \
+ addib,>= -1, count, _LABEL(_loop1) ! \
+ stbs,cmplt t1, m*1(dst_spc, dst_off) ! \
+.label _LABEL(_skip1) ! \
+ /* Restore the correct count. */ ! \
+ b _LABEL(_done) ! \
+ addi 1, count, count
+
+/*
+ * This macro is definitely strange. It exists purely to
+ * allow the _COPYS macro to be reused, but because it
+ * requires this long attempt to explain it, I'm starting
+ * to doubt the value of that.
+ *
+ * Part of the expansion of the _COPYS macro below are loops
+ * that copy four words or one word at a time, performing shifts
+ * to get data to line up correctly in the destination buffer.
+ *
+ * The _COPYS macro is used when copying backwards, as well
+ * as forwards. The 4-word loop always loads into t1, t2, t3,
+ * and t4 in that order. This means that when copying forward,
+ * t1 will have the word from the lowest address, and t4 will
+ * have the word from the highest address. When copying
+ * backwards, the opposite is true.
+ *
+ * The shift instructions need pairs of registers with adjacent
+ * words, with the register containing the word from the lowest
+ * address *always* coming first. It is this assymetry that
+ * gives rise to this macro - depending on which direction
+ * we're copying in, these ordered pairs are different.
+ *
+ * Fortunately, we can compute those register numbers at compile
+ * time, and assemble them manually into a shift instruction.
+ * That's what this macro does.
+ *
+ * This macro takes two arguments. n ranges from 0 to 3 and
+ * is the "shift number", i.e., n = 0 means we're doing the
+ * shift for what will be the first store.
+ *
+ * m is the displacement multiplier from the _COPYS macro call.
+ * This is 1 for a forward copy and -1 for a backwards copy.
+ * So, the ((m + 1) / 2) term yields 0 for a backwards copy and
+ * 1 for a forward copy, and the ((m - 1) / 2) term yields
+ * 0 for a forward copy, and -1 for a backwards copy.
+ * These terms are used to discriminate the register computations
+ * below.
+ *
+ * When copying forward, then, the first register used with
+ * the first vshd will be 19 + (3 - ((0 - 1) & 3)), or t4,
+ * which matches _COPYS' requirement that the word last loaded
+ * be in t4. The first register used for the second vshd
+ * will then "wrap" around to 19 + (3 - ((1 - 1) & 3)), or t1.
+ * And so on to t2 and t3.
+ *
+ * When copying forward, the second register used with the first
+ * vshd will be (19 + (3 - ((n + 0) & 3)), or t1. It will
+ * continue to be t2, then t3, and finally t4.
+ *
+ * When copying backwards, the values for the first and second
+ * register for each vshd are reversed from the forwards case.
+ * (Symmetry reclaimed!) Proving this is "left as an exercise
+ * for the reader" (remember the different discriminating values!)
+ */
+#define _VSHD(n, m, t) \
+ .word (0xd0000000 | \
+ ((19 + (3 - ((n - 1 * ((m + 1) / 2)) & 3))) << 16) | \
+ ((19 + (3 - ((n + 1 * ((m - 1) / 2)) & 3))) << 21) | \
+ (t))
+
+/*
+ * This macro does a bulk copy with shifting. cmplt and m are
+ * the completer and displacement multiplier, respectively, for
+ * the load and store instructions. It is assumed that the
+ * word last loaded is already in t4.
+ */
+#define _COPYS(src_spc, src_off, dst_spc, dst_off, count, cmplt, m) \
+ ! \
+ /* ! \
+ * Loop storing 16 bytes at a time. Since count ! \
+ * may be > INT_MAX, we have to be careful and ! \
+ * avoid comparisons that treat it as a signed ! \
+ * quantity, until after this loop, when count ! \
+ * is guaranteed to be less than 16. ! \
+ */ ! \
+ comib,>>=,n 15, count, _LABEL(S_skip16) ! \
+.label _LABEL(S_loop16) ! \
+ addi -16, count, count ! \
+ ldws,cmplt m*4(src_spc, src_off), t1 ! \
+ ldws,cmplt m*4(src_spc, src_off), t2 ! \
+ ldws,cmplt m*4(src_spc, src_off), t3 ! \
+ _VSHD(0, m, 1) /* vshd t4, t1, %r1 */ ! \
+ ldws,cmplt m*4(src_spc, src_off), t4 ! \
+ _VSHD(1, m, 22) /* vshd t1, t2, t1 */ ! \
+ _VSHD(2, m, 21) /* vshd t2, t3, t2 */ ! \
+ _VSHD(3, m, 20) /* vshd t3, t4, t3 */ ! \
+ stws,cmplt %r1, m*4(dst_spc, dst_off) ! \
+ stws,cmplt t1, m*4(dst_spc, dst_off) ! \
+ stws,cmplt t2, m*4(dst_spc, dst_off) ! \
+ comib,<< 15, count, _LABEL(S_loop16) ! \
+ stws,cmplt t3, m*4(dst_spc, dst_off) ! \
+.label _LABEL(S_skip16) ! \
+ ! \
+ /* Loop storing 4 bytes at a time. */ ! \
+ addib,<,n -4, count, _LABEL(S_skip4) ! \
+.label _LABEL(S_loop4) ! \
+ ldws,cmplt m*4(src_spc, src_off), t1 ! \
+ _VSHD(0, m, 1) /* into r1 (1) */ ! \
+ copy t1, t4 ! \
+ addib,>= -4, count, _LABEL(S_loop4) ! \
+ stws,cmplt %r1, m*4(dst_spc, dst_off) ! \
+.label _LABEL(S_skip4) ! \
+ ! \
+ /* ! \
+ * We now need to "back up" src_off by the ! \
+ * number of bytes remaining in the FIFO ! \
+ * (i.e., the number of bytes remaining in t4), ! \
+ * because (the correct) count still includes ! \
+ * these bytes, and we intent to keep it that ! \
+ * way, and finish with the single-byte copier. ! \
+ * ! \
+ * The number of bytes remaining in the FIFO is ! \
+ * related to the shift count, so recover it, ! \
+ * restoring the correct count at the same time. ! \
+ */ ! \
+ mfctl %cr11, t1 ! \
+ addi 4, count, count ! \
+ shd %r0, t1, 3, t1 ! \
+ ! \
+ /* ! \
+ * If we're copying forward, the shift count ! \
+ * is the number of bytes remaining in the ! \
+ * FIFO, and we want to subtract it from src_off. ! \
+ * If we're copying backwards, (4 - shift count) ! \
+ * is the number of bytes remaining in the FIFO, ! \
+ * and we want to add it to src_off. ! \
+ * ! \
+ * We observe that x + (4 - y) = x - (y - 4), ! \
+ * and introduce this instruction to add -4 when ! \
+ * m is -1, although this does mean one extra ! \
+ * instruction in the forward case. ! \
+ */ ! \
+ addi 4*((m - 1) / 2), t1, t1 ! \
+ ! \
+ /* Now branch to the byte-at-a-time loop. */ ! \
+ b _LABEL(_do1) ! \
+ sub src_off, t1, src_off
+
+/*
+ * This macro copies a region in the forward direction.
+ */
+#define _COPY_FORWARD(src_spc, src_off, dst_spc, dst_off, count) \
+ ! \
+ /* ! \
+ * Since in the shifting-left case we will ! \
+ * load 8 bytes before checking count, to ! \
+ * keep things simple, branch to the byte ! \
Home |
Main Index |
Thread Index |
Old Index