summaryrefslogtreecommitdiff
path: root/sys/lib/libkern
diff options
context:
space:
mode:
authorMichael Shalayeff <mickey@cvs.openbsd.org>1998-06-23 18:56:55 +0000
committerMichael Shalayeff <mickey@cvs.openbsd.org>1998-06-23 18:56:55 +0000
commit3eb962f33405f5d242202b0c16e31ce87c4b6537 (patch)
tree182734bab9c92f9dbb32d613e13728d11066c66d /sys/lib/libkern
parent1d6e6684a878474c571fc7313a9648765932986e (diff)
initial import
Diffstat (limited to 'sys/lib/libkern')
-rw-r--r--sys/lib/libkern/arch/hppa/Makefile.inc10
-rw-r--r--sys/lib/libkern/arch/hppa/bcopy.S252
-rw-r--r--sys/lib/libkern/arch/hppa/bzero.S115
-rw-r--r--sys/lib/libkern/arch/hppa/divI.S211
-rw-r--r--sys/lib/libkern/arch/hppa/divU.S199
-rw-r--r--sys/lib/libkern/arch/hppa/ffs.S52
-rw-r--r--sys/lib/libkern/arch/hppa/mulI.S480
-rw-r--r--sys/lib/libkern/arch/hppa/mulU.S131
-rw-r--r--sys/lib/libkern/arch/hppa/prefix.h87
-rw-r--r--sys/lib/libkern/arch/hppa/remI.S164
-rw-r--r--sys/lib/libkern/arch/hppa/remU.S152
11 files changed, 1853 insertions, 0 deletions
diff --git a/sys/lib/libkern/arch/hppa/Makefile.inc b/sys/lib/libkern/arch/hppa/Makefile.inc
new file mode 100644
index 00000000000..5364c28199b
--- /dev/null
+++ b/sys/lib/libkern/arch/hppa/Makefile.inc
@@ -0,0 +1,10 @@
+# $OpenBSD: Makefile.inc,v 1.1 1998/06/23 18:56:53 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
+
+# `source' files built from m4 source
+SRCS+= divU.S divI.S
+SRCS+= remU.S remI.S
+SRCS+= mulU.S mulI.S
+
diff --git a/sys/lib/libkern/arch/hppa/bcopy.S b/sys/lib/libkern/arch/hppa/bcopy.S
new file mode 100644
index 00000000000..18a632e1665
--- /dev/null
+++ b/sys/lib/libkern/arch/hppa/bcopy.S
@@ -0,0 +1,252 @@
+/* $OpenBSD: bcopy.S,v 1.1 1998/06/23 18:56:53 mickey Exp $ */
+
+/*
+ * (c) Copyright 1988 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+
+/*
+ * Copyright (c) 1990,1994 The University of Utah and
+ * the Computer Systems Laboratory (CSL). All rights reserved.
+ *
+ * THE UNIVERSITY OF UTAH AND CSL PROVIDE THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION, AND DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM ITS USE.
+ *
+ * CSL requests users of this software to return to csl-dist@cs.utah.edu any
+ * improvements that they make and grant CSL redistribution rights.
+ *
+ * Utah $Hdr: bcopy.s 1.10 94/12/14$
+ * Author: Bob Wheeler, University of Utah CSL
+ */
+
+#include <machine/asm.h>
+
+/*
+ * void
+ * memcpy(dst, src, count)
+ * vm_offset_t dst;
+ * vm_offset_t src;
+ * int count;
+ */
+ENTRY(memcpy)
+ copy arg0,arg3
+ copy arg1,arg0
+ copy arg3,arg1
+ /* And fall into.... */
+
+/*
+ * void
+ * bcopy(src, dst, count)
+ * vm_offset_t src;
+ * vm_offset_t dst;
+ * int count;
+ */
+ALTENTRY(bcopy)
+ comb,>=,n r0,arg2,$bcopy_exit
+
+ /*
+ * See if the source and destination are word aligned and if the count
+ * is an integer number of words. If so then we can use an optimized
+ * routine. If not then branch to bcopy_checkalign and see what we can
+ * do there.
+ */
+
+ or arg0,arg1,t1
+ or t1,arg2,t2
+ extru,= t2,31,2,r0
+ b,n $bcopy_checkalign
+
+ addib,<,n -16,arg2,$bcopy_movewords
+
+ /*
+ * We can move the data in 4 word moves. We'll use 4 registers to
+ * avoid interlock and pipeline stalls.
+ */
+
+$bcopy_loop16
+
+ ldwm 16(arg0),t1
+ ldw -12(arg0),t2
+ ldw -8(arg0),t3
+ ldw -4(arg0),t4
+ stwm t1,16(arg1)
+ stw t2,-12(arg1)
+ stw t3,-8(arg1)
+ addib,>= -16,arg2,$bcopy_loop16
+ stw t4,-4(arg1)
+
+
+ /*
+ * We have already decremented the count by 16, add 12 to it and then
+ * we can test if there is at least 1 word left to move.
+ */
+
+$bcopy_movewords
+ addib,<,n 12,arg2,$bcopy_exit
+
+ /*
+ * Clean up any remaining words that were not moved in the 16 byte
+ * moves
+ */
+
+$bcopy_loop4
+ ldwm 4(arg0),t1
+ addib,>= -4,arg2,$bcopy_loop4
+ stwm t1,4(arg1)
+
+ b,n $bcopy_exit
+
+
+$bcopy_checkalign
+
+ /*
+ * The source or destination is not word aligned or the count is not
+ * an integral number of words. If we are dealing with less than 16
+ * bytes then just do it byte by byte. Otherwise, see if the data has
+ * the same basic alignment. We will add in the byte offset to size to
+ * keep track of what we have to move even though the stbys instruction
+ * won't physically move it.
+ */
+
+ comib,>= 15,arg2,$bcopy_byte
+ extru arg0,31,2,t1
+ extru arg1,31,2,t2
+ add arg2,t2,arg2
+ comb,<> t2,t1,$bcopy_unaligned
+ dep 0,31,2,arg0
+
+ /*
+ * the source and destination have the same basic alignment. We will
+ * move the data in blocks of 16 bytes as long as we can and then
+ * we'll go to the 4 byte moves.
+ */
+
+ addib,<,n -16,arg2,$bcopy_aligned2
+
+$bcopy_loop_aligned4
+ ldwm 16(arg0),t1
+ ldw -12(arg0),t2
+ ldw -8(arg0),t3
+ ldw -4(arg0),t4
+ stbys,b,m t1,4(arg1)
+ stwm t2,4(arg1)
+ stwm t3,4(arg1)
+ addib,>= -16,arg2,$bcopy_loop_aligned4
+ stwm t4,4(arg1)
+
+ /*
+ * see if there is anything left that needs to be moved in a word move.
+ * Since the count was decremented by 16, add 12 to test if there are
+ * any full word moves left to do.
+ */
+
+$bcopy_aligned2
+ addib,<,n 12,arg2,$bcopy_cleanup
+
+$bcopy_loop_aligned2
+ ldws,ma 4(arg0),t1
+ addib,>= -4,arg2,$bcopy_loop_aligned2
+ stbys,b,m t1,4(arg1)
+
+ /*
+ * move the last bytes that may be unaligned on a word boundary
+ */
+
+$bcopy_cleanup
+ addib,=,n 4,arg2,$bcopy_exit
+ ldws 0(arg0),t1
+ add arg1,arg2,arg1
+ b $bcopy_exit
+ stbys,e t1,0(arg1)
+
+ /*
+ * The source and destination are not alligned on the same boundary
+ * types. We will have to shift the data around. Figure out the shift
+ * amount and load it into cr11.
+ */
+
+$bcopy_unaligned
+ sub,>= t2,t1,t3
+ ldwm 4(arg0),t1
+ zdep t3,28,29,t4
+ mtctl t4,11
+
+ /*
+ * see if we can do some of this work in blocks of 16 bytes
+ */
+
+ addib,<,n -16,arg2,$bcopy_unaligned_words
+
+$bcopy_unaligned4
+ ldwm 16(arg0),t2
+ ldw -12(arg0),t3
+ ldw -8(arg0),t4
+ ldw -4(arg0),r1
+ vshd t1,t2,r28
+ stbys,b,m r28,4(arg1)
+ vshd t2,t3,r28
+ stwm r28,4(arg1)
+ vshd t3,t4,r28
+ stwm r28,4(arg1)
+ vshd t4,r1,r28
+ stwm r28,4(arg1)
+ addib,>= -16,arg2,$bcopy_unaligned4
+ copy r1,t1
+
+ /*
+ * see if there is a full word that we can transfer
+ */
+
+$bcopy_unaligned_words
+ addib,<,n 12,arg2,$bcopy_unaligned_cleanup1
+
+$bcopy_unaligned_loop
+ ldwm 4(arg0),t2
+ vshd t1,t2,t3
+ addib,< -4,arg2,$bcopy_unaligned_cleanup2
+ stbys,b,m t3,4(arg1)
+
+ ldwm 4(arg0),t1
+ vshd t2,t1,t3
+ addib,>= -4,arg2,$bcopy_unaligned_loop
+ stbys,b,m t3,4(arg1)
+
+$bcopy_unaligned_cleanup1
+ copy t1,t2
+
+$bcopy_unaligned_cleanup2
+ addib,<=,n 4,arg2,$bcopy_exit
+ add arg1,arg2,arg1
+ mfctl sar,t3
+ extru t3,28,2,t3
+ sub,<= arg2,t3,r0
+ ldwm 4(arg0),t1
+ vshd t2,t1,t3
+ b $bcopy_exit
+ stbys,e t3,0(arg1)
+
+ /*
+ * move data one byte at a time
+ */
+
+$bcopy_byte
+ comb,>=,n r0,arg2,$bcopy_exit
+
+$bcopy_loop_byte
+ ldbs,ma 1(arg0),t1
+ addib,> -1,arg2,$bcopy_loop_byte
+ stbs,ma t1,1(arg1)
+
+$bcopy_exit
+EXIT(bcopy)
diff --git a/sys/lib/libkern/arch/hppa/bzero.S b/sys/lib/libkern/arch/hppa/bzero.S
new file mode 100644
index 00000000000..34a22fcf450
--- /dev/null
+++ b/sys/lib/libkern/arch/hppa/bzero.S
@@ -0,0 +1,115 @@
+/* $OpenBSD: bzero.S,v 1.1 1998/06/23 18:56:53 mickey Exp $ */
+
+/*
+ * (c) Copyright 1988 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+
+/*
+ * Copyright (c) 1990,1994 The University of Utah and
+ * the Computer Systems Laboratory (CSL). All rights reserved.
+ *
+ * THE UNIVERSITY OF UTAH AND CSL PROVIDE THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION, AND DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM ITS USE.
+ *
+ * CSL requests users of this software to return to csl-dist@cs.utah.edu any
+ * improvements that they make and grant CSL redistribution rights.
+ *
+ * Utah $Hdr: bzero.s 1.9 94/12/14$
+ * Author: Bob Wheeler, University of Utah CSL
+ */
+
+#include <machine/asm.h>
+
+/*
+ * void
+ * blkclr(dst, count)
+ * void *dst;
+ * u_int count;
+ */
+ENTRY(blkclr)
+
+/*
+ * void
+ * bzero(dst, count)
+ * vm_offset_t dst;
+ * int count;
+ */
+ALTENTRY(bzero)
+ comb,>=,n r0,arg1,$bzero_exit
+
+ /*
+ * If we need to clear less than a word do it a byte at a time
+ */
+
+ comib,>,n 4,arg1,$bzero_bytes
+
+ /*
+ * Since we are only clearing memory the alignment restrictions
+ * are simplified. Figure out how many "extra" bytes we need to
+ * store with stbys.
+ */
+
+ extru arg0,31,2,t2
+ add arg1,t2,arg1
+
+ /*
+ * We will zero the destination in blocks of 16 bytes as long as we
+ * can and then we'll go to the 4 byte moves.
+ */
+
+ addib,<,n -16,arg1,$bzero_word
+
+$bzero_loop_16
+ stbys,b,m r0,4(arg0)
+ stwm r0,4(arg0)
+ stwm r0,4(arg0)
+ addib,>= -16,arg1,$bzero_loop_16
+ stwm r0,4(arg0)
+
+ /*
+ * see if there is anything left that needs to be zeroed in a word
+ * move. Since the count was decremented by 16, add 12 to test if
+ * there are any full word moves left to do.
+ */
+
+$bzero_word
+ addib,<,n 12,arg1,$bzero_cleanup
+
+$bzero_loop_4
+ addib,>= -4,arg1,$bzero_loop_4
+ stbys,b,m r0,4(arg0)
+
+ /*
+ * zero the last bytes that may be unaligned on a word boundary
+ */
+
+$bzero_cleanup
+ addib,=,n 4,arg1,$bzero_exit
+ add arg0,arg1,arg0
+ b $bzero_exit
+ stbys,e r0,0(arg0)
+ b,n $bzero_exit
+
+
+ /*
+ * zero by bytes
+ */
+
+$bzero_bytes
+ addib,> -1,arg1,$bzero_bytes
+ stbs,ma r0,1(arg0)
+
+$bzero_exit
+EXIT(bzero)
diff --git a/sys/lib/libkern/arch/hppa/divI.S b/sys/lib/libkern/arch/hppa/divI.S
new file mode 100644
index 00000000000..62ff31a547a
--- /dev/null
+++ b/sys/lib/libkern/arch/hppa/divI.S
@@ -0,0 +1,211 @@
+/* $OpenBSD: divI.S,v 1.1 1998/06/23 18:56:53 mickey Exp $ */
+
+/*
+ * (c) Copyright 1985 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+
+#include "prefix.h"
+
+/*
+ *
+ * ROUTINES: $$divI, $$divoI
+ *
+ * Single precision divide for singed binary integers.
+ *
+ * The quotient is truncated towards zero.
+ * The sign of the quotient is the XOR of the signs of the dividend and
+ * divisor.
+ * Divide by zero is trapped.
+ * Divide of -2**31 by -1 is trapped for $$divoI but not for $$divI.
+ *
+ * INPUT REGISTERS:
+ * arg0 == dividend
+ * arg1 == divisor
+ * r31 == return pc
+ * sr0 == return space when called externally
+ *
+ * OUTPUT REGISTERS:
+ * arg0 = undefined
+ * arg1 = undefined
+ * ret1 = quotient
+ *
+ * OTHER REGISTERS AFFECTED:
+ * r1 = undefined
+ *
+ * SIDE EFFECTS:
+ * Causes a trap under the following conditions:
+ * divisor is zero (traps with ADDIT,= 0,25,0)
+ * dividend==-2**31 and divisor==-1 and routine is $$divoI
+ * (traps with ADDO 26,25,0)
+ * Changes memory at the following places:
+ * NONE
+ *
+ * PERMISSIBLE CONTEXT:
+ * Unwindable.
+ * Suitable for internal or external millicode.
+ * Assumes the special millicode register conventions.
+ *
+ * DISCUSSION:
+ * Branchs to other millicode routines using BE
+ * $$div_# for # being 2,3,4,5,6,7,8,9,10,12,14,15
+ *
+ * For selected divisors, calls a divide by constant routine written by
+ * Karl Pettis. Eligible divisors are 1..15 excluding 11 and 13.
+ *
+ * The only overflow case is -2**31 divided by -1.
+ * Both routines return -2**31 but only $$divoI traps.
+ */
+
+DEFINE(temp,r1)
+DEFINE(retreg,ret1) ; r29
+ .import $$divI_2,millicode
+ .import $$divI_3,millicode
+ .import $$divI_4,millicode
+ .import $$divI_5,millicode
+ .import $$divI_6,millicode
+ .import $$divI_7,millicode
+ .import $$divI_8,millicode
+ .import $$divI_9,millicode
+ .import $$divI_10,millicode
+ .import $$divI_12,millicode
+ .import $$divI_14,millicode
+ .import $$divI_15,millicode
+ .export $$divI,millicode
+ .export $$divoI,millicode
+ .proc
+ .callinfo millicode
+$$divoI
+ comib,=,n -1,arg1,negative1 ; when divisor == -1
+$$divI
+ comib,>>=,n 15,arg1,small_divisor
+ add,>= 0,arg0,retreg ; move dividend, if retreg < 0,
+normal
+ sub 0,retreg,retreg ; make it positive
+ sub 0,arg1,temp ; clear carry,
+ ; negate the divisor
+ ds 0,temp,0 ; set V-bit to the comple-
+ ; ment of the divisor sign
+ add retreg,retreg,retreg ; shift msb bit into carry
+ ds r0,arg1,temp ; 1st divide step, if no carry
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 2nd divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 3rd divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 4th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 5th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 6th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 7th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 8th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 9th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 10th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 11th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 12th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 13th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 14th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 15th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 16th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 17th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 18th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 19th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 20th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 21st divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 22nd divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 23rd divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 24th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 25th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 26th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 27th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 28th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 29th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 30th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 31st divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 32nd divide step,
+ addc retreg,retreg,retreg ; shift last retreg bit into retreg
+ xor,>= arg0,arg1,0 ; get correct sign of quotient
+ sub 0,retreg,retreg ; based on operand signs
+ MILLIRETN
+ nop
+;______________________________________________________________________
+small_divisor
+ blr,n arg1,r0
+ nop
+; table for divisor == 0,1, ... ,15
+ addit,= 0,arg1,r0 ; trap if divisor == 0
+ nop
+ MILLIRET ; divisor == 1
+ copy arg0,retreg
+ MILLI_BEN($$divI_2) ; divisor == 2
+ nop
+ MILLI_BEN($$divI_3) ; divisor == 3
+ nop
+ MILLI_BEN($$divI_4) ; divisor == 4
+ nop
+ MILLI_BEN($$divI_5) ; divisor == 5
+ nop
+ MILLI_BEN($$divI_6) ; divisor == 6
+ nop
+ MILLI_BEN($$divI_7) ; divisor == 7
+ nop
+ MILLI_BEN($$divI_8) ; divisor == 8
+ nop
+ MILLI_BEN($$divI_9) ; divisor == 9
+ nop
+ MILLI_BEN($$divI_10) ; divisor == 10
+ nop
+ b normal ; divisor == 11
+ add,>= 0,arg0,retreg
+ MILLI_BEN($$divI_12) ; divisor == 12
+ nop
+ b normal ; divisor == 13
+ add,>= 0,arg0,retreg
+ MILLI_BEN($$divI_14) ; divisor == 14
+ nop
+ MILLI_BEN($$divI_15) ; divisor == 15
+ nop
+;______________________________________________________________________
+negative1
+ sub 0,arg0,retreg ; result is negation of dividend
+ MILLIRET
+ addo arg0,arg1,r0 ; trap iff dividend==0x80000000 && divisor==-1
+ .procend
+ .end
diff --git a/sys/lib/libkern/arch/hppa/divU.S b/sys/lib/libkern/arch/hppa/divU.S
new file mode 100644
index 00000000000..025ce1bdf11
--- /dev/null
+++ b/sys/lib/libkern/arch/hppa/divU.S
@@ -0,0 +1,199 @@
+/* $OpenBSD: divU.S,v 1.1 1998/06/23 18:56:53 mickey Exp $ */
+
+/*
+ * (c) Copyright 1985 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+
+#include "prefix.h"
+
+/*
+ * ROUTINE: $$divU
+ *
+ * Single precision divide for unsigned integers.
+ *
+ * Quotient is truncated towards zero.
+ * Traps on divide by zero.
+ *
+ * INPUT REGISTERS:
+ * arg0 == dividend
+ * arg1 == divisor
+ * r31 == return pc
+ * sr0 == return space when called externally
+ *
+ * OUTPUT REGISTERS:
+ * arg0 = undefined
+ * arg1 = undefined
+ * ret1 = quotient
+ *
+ * OTHER REGISTERS AFFECTED:
+ * r1 = undefined
+ *
+ * SIDE EFFECTS:
+ * Causes a trap under the following conditions:
+ * divisor is zero
+ * Changes memory at the following places:
+ * NONE
+ *
+ * PERMISSIBLE CONTEXT:
+ * Unwindable.
+ * Does not create a stack frame.
+ * Suitable for internal or external millicode.
+ * Assumes the special millicode register conventions.
+ *
+ * DISCUSSION:
+ * Branchs to other millicode routines using BE:
+ * $$divU_# for 3,5,6,7,9,10,12,14,15
+ *
+ * For selected small divisors calls the special divide by constant
+ * routines written by Karl Pettis. These are: 3,5,6,7,9,10,12,14,15.
+ *
+ */
+
+DEFINE(temp,r1)
+DEFINE(retreg,ret1) ; r29
+ .subspa $MILLICODE$
+ .export $$divU,millicode
+ .import $$divU_3,millicode
+ .import $$divU_5,millicode
+ .import $$divU_6,millicode
+ .import $$divU_7,millicode
+ .import $$divU_9,millicode
+ .import $$divU_10,millicode
+ .import $$divU_12,millicode
+ .import $$divU_14,millicode
+ .import $$divU_15,millicode
+ .proc
+ .callinfo millicode
+$$divU
+; The subtract is not nullified since it does no harm and can be used
+; by the two cases that branch back to "normal".
+ comib,>= 15,arg1,special_divisor
+ sub r0,arg1,temp ; clear carry, negate the divisor
+ ds r0,temp,r0 ; set V-bit to 1
+normal
+ add arg0,arg0,retreg ; shift msb bit into carry
+ ds r0,arg1,temp ; 1st divide step, if no carry
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 2nd divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 3rd divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 4th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 5th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 6th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 7th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 8th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 9th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 10th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 11th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 12th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 13th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 14th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 15th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 16th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 17th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 18th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 19th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 20th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 21st divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 22nd divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 23rd divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 24th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 25th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 26th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 27th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 28th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 29th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 30th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 31st divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds temp,arg1,temp ; 32nd divide step,
+ MILLIRET
+ addc retreg,retreg,retreg ; shift last retreg bit into retreg
+;_____________________________________________________________________________
+; handle the cases where divisor is a small constant or has high bit on
+special_divisor
+ blr arg1,r0
+ comib,>,n 0,arg1,big_divisor ; nullify previous instruction
+zero_divisor ; this label is here to provide external visibility
+ addit,= 0,arg1,0 ; trap for zero dvr
+ nop
+ MILLIRET ; divisor == 1
+ copy arg0,retreg
+ MILLIRET ; divisor == 2
+ extru arg0,30,31,retreg
+ MILLI_BEN($$divU_3) ; divisor == 3
+ nop
+ MILLIRET ; divisor == 4
+ extru arg0,29,30,retreg
+ MILLI_BEN($$divU_5) ; divisor == 5
+ nop
+ MILLI_BEN($$divU_6) ; divisor == 6
+ nop
+ MILLI_BEN($$divU_7) ; divisor == 7
+ nop
+ MILLIRET ; divisor == 8
+ extru arg0,28,29,retreg
+ MILLI_BEN($$divU_9) ; divisor == 9
+ nop
+ MILLI_BEN($$divU_10) ; divisor == 10
+ nop
+ b normal ; divisor == 11
+ ds r0,temp,r0 ; set V-bit to 1
+ MILLI_BEN($$divU_12) ; divisor == 12
+ nop
+ b normal ; divisor == 13
+ ds r0,temp,r0 ; set V-bit to 1
+ MILLI_BEN($$divU_14) ; divisor == 14
+ nop
+ MILLI_BEN($$divU_15) ; divisor == 15
+ nop
+;_____________________________________________________________________________
+; Handle the case where the high bit is on in the divisor.
+; Compute: if( dividend>=divisor) quotient=1; else quotient=0;
+; Note: dividend>==divisor iff dividend-divisor does not borrow
+; and not borrow iff carry
+big_divisor
+ sub arg0,arg1,r0
+ MILLIRET
+ addc r0,r0,retreg
+ .procend
+ .end
diff --git a/sys/lib/libkern/arch/hppa/ffs.S b/sys/lib/libkern/arch/hppa/ffs.S
new file mode 100644
index 00000000000..df21ca06dc5
--- /dev/null
+++ b/sys/lib/libkern/arch/hppa/ffs.S
@@ -0,0 +1,52 @@
+/* $OpenBSD: ffs.S,v 1.1 1998/06/23 18:56:53 mickey Exp $ */
+
+/*
+ * Copyright (c) 1990, 1991, 1992, 1994, The University of Utah and
+ * the Computer Systems Laboratory at the University of Utah (CSL).
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS
+ * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF
+ * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * CSL requests users of this software to return to csl-dist@cs.utah.edu any
+ * improvements that they make and grant CSL redistribution rights.
+ *
+ */
+
+#include <machine/asm.h>
+
+/*
+ * ffs(bitmask)
+ *
+ * Return the position of the "most significant" bit in `bitmask'.
+ * Since this is similar to the VAX ffs instruction, bits in a word
+ * are numbered as "32, 31, ... 1", 0 is returned if no bits are set.
+ */
+
+ENTRY(ffs)
+ comb,= arg0,r0,ffsdone ; If arg0 is 0
+ or r0,r0,ret0 ; return 0
+ ldi 32,ret0 ; Set return to high bit
+ extru,= arg0,31,16,r0 ; If low 16 bits are non-zero
+ addi,tr -16,ret0,ret0 ; subtract 16 from bitpos
+ shd r0,arg0,16,arg0 ; else shift right 16 bits
+ extru,= arg0,31,8,r0 ; If low 8 bits are non-zero
+ addi,tr -8,ret0,ret0 ; subtract 8 from bitpos
+ shd r0,arg0,8,arg0 ; else shift right 8 bits
+ extru,= arg0,31,4,r0 ; If low 4 bits are non-zero
+ addi,tr -4,ret0,ret0 ; subtract 4 from bitpos
+ shd r0,arg0,4,arg0 ; else shift right 4 bits
+ extru,= arg0,31,2,r0 ; If low 2 bits are non-zero
+ addi,tr -2,ret0,ret0 ; subtract 2 from bitpos
+ shd r0,arg0,2,arg0 ; else shift right 2 bits
+ extru,= arg0,31,1,r0 ; If low bit is non-zero
+ addi -1,ret0,ret0 ; subtract 1 from bitpos
+ffsdone:
+EXIT(ffs)
diff --git a/sys/lib/libkern/arch/hppa/mulI.S b/sys/lib/libkern/arch/hppa/mulI.S
new file mode 100644
index 00000000000..3bf9c1d215b
--- /dev/null
+++ b/sys/lib/libkern/arch/hppa/mulI.S
@@ -0,0 +1,480 @@
+/* $OpenBSD: mulI.S,v 1.1 1998/06/23 18:56:54 mickey Exp $ */
+
+/*
+ * (c) Copyright 1985 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+
+#include "prefix.h"
+
+/*
+ * Author: Dan Zuras
+ * Editor: Pratap Subrahmanyam
+ *
+ * ROUTINE: $$mulI
+ *
+ *
+ * DESCRIPTION:
+ *
+ * $$mulI multiplies two single word integers, giving a single
+ * word result.
+ *
+ *
+ * INPUT REGISTERS:
+ *
+ * arg0 = Operand 1
+ * arg1 = Operand 2
+ * r31 == return pc
+ * sr0 == return space when called externally
+ *
+ *
+ * OUTPUT REGISTERS:
+ *
+ * arg0 = undefined
+ * arg1 = undefined
+ * ret1 = result
+ *
+ * OTHER REGISTERS AFFECTED:
+ *
+ * r1 = undefined
+ *
+ * SIDE EFFECTS:
+ *
+ * Causes a trap under the following conditions: NONE
+ * Changes memory at the following places: NONE
+ *
+ * PERMISSIBLE CONTEXT:
+ *
+ * Unwindable
+ * Does not create a stack frame
+ * Is usable for internal or external microcode
+ *
+ * DISCUSSION:
+ *
+ * Calls other millicode routines via r31: NONE
+ * Calls other millicode routines: NONE
+ *
+ */
+
+
+#define a0 %arg0
+#define a1 %arg1
+#define rtn %mrp
+#define t0 %r1
+#define r %ret1
+
+#define a0__128a0 zdep a0,24,25,a0
+#define a0__256a0 zdep a0,23,24,a0
+#define a1_ne_0_b_l0 comb,<> a1,0,l0
+#define a1_ne_0_b_l1 comb,<> a1,0,l1
+#define a1_ne_0_b_l2 comb,<> a1,0,l2
+#define b_n_ret_t0 b,n ret_t0
+#define b_e_shift b e_shift
+#define b_e_t0ma0 b e_t0ma0
+#define b_e_t0 b e_t0
+#define b_e_t0a0 b e_t0a0
+#define b_e_t02a0 b e_t02a0
+#define b_e_t04a0 b e_t04a0
+#define b_e_2t0 b e_2t0
+#define b_e_2t0a0 b e_2t0a0
+#define b_e_2t04a0 b e2t04a0
+#define b_e_3t0 b e_3t0
+#define b_e_4t0 b e_4t0
+#define b_e_4t0a0 b e_4t0a0
+#define b_e_4t08a0 b e4t08a0
+#define b_e_5t0 b e_5t0
+#define b_e_8t0 b e_8t0
+#define b_e_8t0a0 b e_8t0a0
+#define r__r_a0 add r,a0,r
+#define r__r_2a0 sh1add a0,r,r
+#define r__r_4a0 sh2add a0,r,r
+#define r__r_8a0 sh3add a0,r,r
+#define r__r_t0 add r,t0,r
+#define r__r_2t0 sh1add t0,r,r
+#define r__r_4t0 sh2add t0,r,r
+#define r__r_8t0 sh3add t0,r,r
+; Use MILLIRET and MILLIRETN instead.
+; #define return bv 0(rtn)
+; #define return_n bv,n 0(rtn)
+#define t0__3a0 sh1add a0,a0,t0
+#define t0__4a0 sh2add a0,0,t0
+#define t0__5a0 sh2add a0,a0,t0
+#define t0__8a0 sh3add a0,0,t0
+#define t0__9a0 sh3add a0,a0,t0
+#define t0__16a0 zdep a0,27,28,t0
+#define t0__32a0 zdep a0,26,27,t0
+#define t0__64a0 zdep a0,25,26,t0
+#define t0__128a0 zdep a0,24,25,t0
+#define t0__t0ma0 sub t0,a0,t0
+#define t0__t0_a0 add t0,a0,t0
+#define t0__t0_2a0 sh1add a0,t0,t0
+#define t0__t0_4a0 sh2add a0,t0,t0
+#define t0__t0_8a0 sh3add a0,t0,t0
+#define t0__2t0_a0 sh1add t0,a0,t0
+#define t0__3t0 sh1add t0,t0,t0
+#define t0__4t0 sh2add t0,0,t0
+#define t0__4t0_a0 sh2add t0,a0,t0
+#define t0__5t0 sh2add t0,t0,t0
+#define t0__8t0 sh3add t0,0,t0
+#define t0__8t0_a0 sh3add t0,a0,t0
+#define t0__9t0 sh3add t0,t0,t0
+#define t0__16t0 zdep t0,27,28,t0
+#define t0__32t0 zdep t0,26,27,t0
+#define t0__256a0 zdep a0,23,24,t0
+
+
+ .subspa $MILLICODE$
+ .align 16
+ .proc
+ .callinfo millicode
+ .export $$mulI, millicode
+$$mulI
+ combt,<<= a1,a0,l4 ; swap args if unsigned a1>a0
+ copy 0,r ; zero out the result
+ xor a0,a1,a0 ; swap a0 & a1 using the
+ xor a0,a1,a1 ; old xor trick
+ xor a0,a1,a0
+l4 combt,<= 0,a0,l3 ; if a0>=0 then proceed like unsigned
+ zdep a1,30,8,t0 ; t0 = (a1&0xff)<<1 *********
+ sub,> 0,a1,t0 ; otherwise negate both and
+ combt,<=,n a0,t0,l2 ; swap back if |a0|<|a1|
+ sub 0,a0,a1
+ movb,tr,n t0,a0,l2 ; 10th inst.
+
+l0 r__r_t0 ; add in this partial product
+l1 a0__256a0 ; a0 <<= 8 ******************
+l2 zdep a1,30,8,t0 ; t0 = (a1&0xff)<<1 *********
+l3 blr t0,0 ; case on these 8 bits ******
+ extru a1,23,24,a1 ; a1 >>= 8 ******************
+
+;16 insts before this.
+; a0 <<= 8 **************************
+x0 a1_ne_0_b_l2 ! a0__256a0 ! MILLIRETN ! nop
+x1 a1_ne_0_b_l1 ! r__r_a0 ! MILLIRETN ! nop
+x2 a1_ne_0_b_l1 ! r__r_2a0 ! MILLIRETN ! nop
+x3 a1_ne_0_b_l0 ! t0__3a0 ! MILLIRET ! r__r_t0
+x4 a1_ne_0_b_l1 ! r__r_4a0 ! MILLIRETN ! nop
+x5 a1_ne_0_b_l0 ! t0__5a0 ! MILLIRET ! r__r_t0
+x6 t0__3a0 ! a1_ne_0_b_l1 ! r__r_2t0 ! MILLIRETN
+x7 t0__3a0 ! a1_ne_0_b_l0 ! r__r_4a0 ! b_n_ret_t0
+x8 a1_ne_0_b_l1 ! r__r_8a0 ! MILLIRETN ! nop
+x9 a1_ne_0_b_l0 ! t0__9a0 ! MILLIRET ! r__r_t0
+x10 t0__5a0 ! a1_ne_0_b_l1 ! r__r_2t0 ! MILLIRETN
+x11 t0__3a0 ! a1_ne_0_b_l0 ! r__r_8a0 ! b_n_ret_t0
+x12 t0__3a0 ! a1_ne_0_b_l1 ! r__r_4t0 ! MILLIRETN
+x13 t0__5a0 ! a1_ne_0_b_l0 ! r__r_8a0 ! b_n_ret_t0
+x14 t0__3a0 ! t0__2t0_a0 ! b_e_shift ! r__r_2t0
+x15 t0__5a0 ! a1_ne_0_b_l0 ! t0__3t0 ! b_n_ret_t0
+x16 t0__16a0 ! a1_ne_0_b_l1 ! r__r_t0 ! MILLIRETN
+x17 t0__9a0 ! a1_ne_0_b_l0 ! t0__t0_8a0 ! b_n_ret_t0
+x18 t0__9a0 ! a1_ne_0_b_l1 ! r__r_2t0 ! MILLIRETN
+x19 t0__9a0 ! a1_ne_0_b_l0 ! t0__2t0_a0 ! b_n_ret_t0
+x20 t0__5a0 ! a1_ne_0_b_l1 ! r__r_4t0 ! MILLIRETN
+x21 t0__5a0 ! a1_ne_0_b_l0 ! t0__4t0_a0 ! b_n_ret_t0
+x22 t0__5a0 ! t0__2t0_a0 ! b_e_shift ! r__r_2t0
+x23 t0__5a0 ! t0__2t0_a0 ! b_e_t0 ! t0__2t0_a0
+x24 t0__3a0 ! a1_ne_0_b_l1 ! r__r_8t0 ! MILLIRETN
+x25 t0__5a0 ! a1_ne_0_b_l0 ! t0__5t0 ! b_n_ret_t0
+x26 t0__3a0 ! t0__4t0_a0 ! b_e_shift ! r__r_2t0
+x27 t0__3a0 ! a1_ne_0_b_l0 ! t0__9t0 ! b_n_ret_t0
+x28 t0__3a0 ! t0__2t0_a0 ! b_e_shift ! r__r_4t0
+x29 t0__3a0 ! t0__2t0_a0 ! b_e_t0 ! t0__4t0_a0
+x30 t0__5a0 ! t0__3t0 ! b_e_shift ! r__r_2t0
+x31 t0__32a0 ! a1_ne_0_b_l0 ! t0__t0ma0 ! b_n_ret_t0
+x32 t0__32a0 ! a1_ne_0_b_l1 ! r__r_t0 ! MILLIRETN
+x33 t0__8a0 ! a1_ne_0_b_l0 ! t0__4t0_a0 ! b_n_ret_t0
+x34 t0__16a0 ! t0__t0_a0 ! b_e_shift ! r__r_2t0
+x35 t0__9a0 ! t0__3t0 ! b_e_t0 ! t0__t0_8a0
+x36 t0__9a0 ! a1_ne_0_b_l1 ! r__r_4t0 ! MILLIRETN
+x37 t0__9a0 ! a1_ne_0_b_l0 ! t0__4t0_a0 ! b_n_ret_t0
+x38 t0__9a0 ! t0__2t0_a0 ! b_e_shift ! r__r_2t0
+x39 t0__9a0 ! t0__2t0_a0 ! b_e_t0 ! t0__2t0_a0
+x40 t0__5a0 ! a1_ne_0_b_l1 ! r__r_8t0 ! MILLIRETN
+x41 t0__5a0 ! a1_ne_0_b_l0 ! t0__8t0_a0 ! b_n_ret_t0
+x42 t0__5a0 ! t0__4t0_a0 ! b_e_shift ! r__r_2t0
+x43 t0__5a0 ! t0__4t0_a0 ! b_e_t0 ! t0__2t0_a0
+x44 t0__5a0 ! t0__2t0_a0 ! b_e_shift ! r__r_4t0
+x45 t0__9a0 ! a1_ne_0_b_l0 ! t0__5t0 ! b_n_ret_t0
+x46 t0__9a0 ! t0__5t0 ! b_e_t0 ! t0__t0_a0
+x47 t0__9a0 ! t0__5t0 ! b_e_t0 ! t0__t0_2a0
+x48 t0__3a0 ! a1_ne_0_b_l0 ! t0__16t0 ! b_n_ret_t0
+x49 t0__9a0 ! t0__5t0 ! b_e_t0 ! t0__t0_4a0
+x50 t0__5a0 ! t0__5t0 ! b_e_shift ! r__r_2t0
+x51 t0__9a0 ! t0__t0_8a0 ! b_e_t0 ! t0__3t0
+x52 t0__3a0 ! t0__4t0_a0 ! b_e_shift ! r__r_4t0
+x53 t0__3a0 ! t0__4t0_a0 ! b_e_t0 ! t0__4t0_a0
+x54 t0__9a0 ! t0__3t0 ! b_e_shift ! r__r_2t0
+x55 t0__9a0 ! t0__3t0 ! b_e_t0 ! t0__2t0_a0
+x56 t0__3a0 ! t0__2t0_a0 ! b_e_shift ! r__r_8t0
+x57 t0__9a0 ! t0__2t0_a0 ! b_e_t0 ! t0__3t0
+x58 t0__3a0 ! t0__2t0_a0 ! b_e_2t0 ! t0__4t0_a0
+x59 t0__9a0 ! t0__2t0_a0 ! b_e_t02a0 ! t0__3t0
+x60 t0__5a0 ! t0__3t0 ! b_e_shift ! r__r_4t0
+x61 t0__5a0 ! t0__3t0 ! b_e_t0 ! t0__4t0_a0
+x62 t0__32a0 ! t0__t0ma0 ! b_e_shift ! r__r_2t0
+x63 t0__64a0 ! a1_ne_0_b_l0 ! t0__t0ma0 ! b_n_ret_t0
+x64 t0__64a0 ! a1_ne_0_b_l1 ! r__r_t0 ! MILLIRETN
+x65 t0__8a0 ! a1_ne_0_b_l0 ! t0__8t0_a0 ! b_n_ret_t0
+x66 t0__32a0 ! t0__t0_a0 ! b_e_shift ! r__r_2t0
+x67 t0__8a0 ! t0__4t0_a0 ! b_e_t0 ! t0__2t0_a0
+x68 t0__8a0 ! t0__2t0_a0 ! b_e_shift ! r__r_4t0
+x69 t0__8a0 ! t0__2t0_a0 ! b_e_t0 ! t0__4t0_a0
+x70 t0__64a0 ! t0__t0_4a0 ! b_e_t0 ! t0__t0_2a0
+x71 t0__9a0 ! t0__8t0 ! b_e_t0 ! t0__t0ma0
+x72 t0__9a0 ! a1_ne_0_b_l1 ! r__r_8t0 ! MILLIRETN
+x73 t0__9a0 ! t0__8t0_a0 ! b_e_shift ! r__r_t0
+x74 t0__9a0 ! t0__4t0_a0 ! b_e_shift ! r__r_2t0
+x75 t0__9a0 ! t0__4t0_a0 ! b_e_t0 ! t0__2t0_a0
+x76 t0__9a0 ! t0__2t0_a0 ! b_e_shift ! r__r_4t0
+x77 t0__9a0 ! t0__2t0_a0 ! b_e_t0 ! t0__4t0_a0
+x78 t0__9a0 ! t0__2t0_a0 ! b_e_2t0 ! t0__2t0_a0
+x79 t0__16a0 ! t0__5t0 ! b_e_t0 ! t0__t0ma0
+x80 t0__16a0 ! t0__5t0 ! b_e_shift ! r__r_t0
+x81 t0__9a0 ! t0__9t0 ! b_e_shift ! r__r_t0
+x82 t0__5a0 ! t0__8t0_a0 ! b_e_shift ! r__r_2t0
+x83 t0__5a0 ! t0__8t0_a0 ! b_e_t0 ! t0__2t0_a0
+x84 t0__5a0 ! t0__4t0_a0 ! b_e_shift ! r__r_4t0
+x85 t0__8a0 ! t0__2t0_a0 ! b_e_t0 ! t0__5t0
+x86 t0__5a0 ! t0__4t0_a0 ! b_e_2t0 ! t0__2t0_a0
+x87 t0__9a0 ! t0__9t0 ! b_e_t02a0 ! t0__t0_4a0
+x88 t0__5a0 ! t0__2t0_a0 ! b_e_shift ! r__r_8t0
+x89 t0__5a0 ! t0__2t0_a0 ! b_e_t0 ! t0__8t0_a0
+x90 t0__9a0 ! t0__5t0 ! b_e_shift ! r__r_2t0
+x91 t0__9a0 ! t0__5t0 ! b_e_t0 ! t0__2t0_a0
+x92 t0__5a0 ! t0__2t0_a0 ! b_e_4t0 ! t0__2t0_a0
+x93 t0__32a0 ! t0__t0ma0 ! b_e_t0 ! t0__3t0
+x94 t0__9a0 ! t0__5t0 ! b_e_2t0 ! t0__t0_2a0
+x95 t0__9a0 ! t0__2t0_a0 ! b_e_t0 ! t0__5t0
+x96 t0__8a0 ! t0__3t0 ! b_e_shift ! r__r_4t0
+x97 t0__8a0 ! t0__3t0 ! b_e_t0 ! t0__4t0_a0
+x98 t0__32a0 ! t0__3t0 ! b_e_t0 ! t0__t0_2a0
+x99 t0__8a0 ! t0__4t0_a0 ! b_e_t0 ! t0__3t0
+x100 t0__5a0 ! t0__5t0 ! b_e_shift ! r__r_4t0
+x101 t0__5a0 ! t0__5t0 ! b_e_t0 ! t0__4t0_a0
+x102 t0__32a0 ! t0__t0_2a0 ! b_e_t0 ! t0__3t0
+x103 t0__5a0 ! t0__5t0 ! b_e_t02a0 ! t0__4t0_a0
+x104 t0__3a0 ! t0__4t0_a0 ! b_e_shift ! r__r_8t0
+x105 t0__5a0 ! t0__4t0_a0 ! b_e_t0 ! t0__5t0
+x106 t0__3a0 ! t0__4t0_a0 ! b_e_2t0 ! t0__4t0_a0
+x107 t0__9a0 ! t0__t0_4a0 ! b_e_t02a0 ! t0__8t0_a0
+x108 t0__9a0 ! t0__3t0 ! b_e_shift ! r__r_4t0
+x109 t0__9a0 ! t0__3t0 ! b_e_t0 ! t0__4t0_a0
+x110 t0__9a0 ! t0__3t0 ! b_e_2t0 ! t0__2t0_a0
+x111 t0__9a0 ! t0__4t0_a0 ! b_e_t0 ! t0__3t0
+x112 t0__3a0 ! t0__2t0_a0 ! b_e_t0 ! t0__16t0
+x113 t0__9a0 ! t0__4t0_a0 ! b_e_t02a0 ! t0__3t0
+x114 t0__9a0 ! t0__2t0_a0 ! b_e_2t0 ! t0__3t0
+x115 t0__9a0 ! t0__2t0_a0 ! b_e_2t0a0 ! t0__3t0
+x116 t0__3a0 ! t0__2t0_a0 ! b_e_4t0 ! t0__4t0_a0
+x117 t0__3a0 ! t0__4t0_a0 ! b_e_t0 ! t0__9t0
+x118 t0__3a0 ! t0__4t0_a0 ! b_e_t0a0 ! t0__9t0
+x119 t0__3a0 ! t0__4t0_a0 ! b_e_t02a0 ! t0__9t0
+x120 t0__5a0 ! t0__3t0 ! b_e_shift ! r__r_8t0
+x121 t0__5a0 ! t0__3t0 ! b_e_t0 ! t0__8t0_a0
+x122 t0__5a0 ! t0__3t0 ! b_e_2t0 ! t0__4t0_a0
+x123 t0__5a0 ! t0__8t0_a0 ! b_e_t0 ! t0__3t0
+x124 t0__32a0 ! t0__t0ma0 ! b_e_shift ! r__r_4t0
+x125 t0__5a0 ! t0__5t0 ! b_e_t0 ! t0__5t0
+x126 t0__64a0 ! t0__t0ma0 ! b_e_shift ! r__r_2t0
+x127 t0__128a0 ! a1_ne_0_b_l0 ! t0__t0ma0 ! b_n_ret_t0
+x128 t0__128a0 ! a1_ne_0_b_l1 ! r__r_t0 ! MILLIRETN
+x129 t0__128a0 ! a1_ne_0_b_l0 ! t0__t0_a0 ! b_n_ret_t0
+x130 t0__64a0 ! t0__t0_a0 ! b_e_shift ! r__r_2t0
+x131 t0__8a0 ! t0__8t0_a0 ! b_e_t0 ! t0__2t0_a0
+x132 t0__8a0 ! t0__4t0_a0 ! b_e_shift ! r__r_4t0
+x133 t0__8a0 ! t0__4t0_a0 ! b_e_t0 ! t0__4t0_a0
+x134 t0__8a0 ! t0__4t0_a0 ! b_e_2t0 ! t0__2t0_a0
+x135 t0__9a0 ! t0__5t0 ! b_e_t0 ! t0__3t0
+x136 t0__8a0 ! t0__2t0_a0 ! b_e_shift ! r__r_8t0
+x137 t0__8a0 ! t0__2t0_a0 ! b_e_t0 ! t0__8t0_a0
+x138 t0__8a0 ! t0__2t0_a0 ! b_e_2t0 ! t0__4t0_a0
+x139 t0__8a0 ! t0__2t0_a0 ! b_e_2t0a0 ! t0__4t0_a0
+x140 t0__3a0 ! t0__2t0_a0 ! b_e_4t0 ! t0__5t0
+x141 t0__8a0 ! t0__2t0_a0 ! b_e_4t0a0 ! t0__2t0_a0
+x142 t0__9a0 ! t0__8t0 ! b_e_2t0 ! t0__t0ma0
+x143 t0__16a0 ! t0__9t0 ! b_e_t0 ! t0__t0ma0
+x144 t0__9a0 ! t0__8t0 ! b_e_shift ! r__r_2t0
+x145 t0__9a0 ! t0__8t0 ! b_e_t0 ! t0__2t0_a0
+x146 t0__9a0 ! t0__8t0_a0 ! b_e_shift ! r__r_2t0
+x147 t0__9a0 ! t0__8t0_a0 ! b_e_t0 ! t0__2t0_a0
+x148 t0__9a0 ! t0__4t0_a0 ! b_e_shift ! r__r_4t0
+x149 t0__9a0 ! t0__4t0_a0 ! b_e_t0 ! t0__4t0_a0
+x150 t0__9a0 ! t0__4t0_a0 ! b_e_2t0 ! t0__2t0_a0
+x151 t0__9a0 ! t0__4t0_a0 ! b_e_2t0a0 ! t0__2t0_a0
+x152 t0__9a0 ! t0__2t0_a0 ! b_e_shift ! r__r_8t0
+x153 t0__9a0 ! t0__2t0_a0 ! b_e_t0 ! t0__8t0_a0
+x154 t0__9a0 ! t0__2t0_a0 ! b_e_2t0 ! t0__4t0_a0
+x155 t0__32a0 ! t0__t0ma0 ! b_e_t0 ! t0__5t0
+x156 t0__9a0 ! t0__2t0_a0 ! b_e_4t0 ! t0__2t0_a0
+x157 t0__32a0 ! t0__t0ma0 ! b_e_t02a0 ! t0__5t0
+x158 t0__16a0 ! t0__5t0 ! b_e_2t0 ! t0__t0ma0
+x159 t0__32a0 ! t0__5t0 ! b_e_t0 ! t0__t0ma0
+x160 t0__5a0 ! t0__4t0 ! b_e_shift ! r__r_8t0
+x161 t0__8a0 ! t0__5t0 ! b_e_t0 ! t0__4t0_a0
+x162 t0__9a0 ! t0__9t0 ! b_e_shift ! r__r_2t0
+x163 t0__9a0 ! t0__9t0 ! b_e_t0 ! t0__2t0_a0
+x164 t0__5a0 ! t0__8t0_a0 ! b_e_shift ! r__r_4t0
+x165 t0__8a0 ! t0__4t0_a0 ! b_e_t0 ! t0__5t0
+x166 t0__5a0 ! t0__8t0_a0 ! b_e_2t0 ! t0__2t0_a0
+x167 t0__5a0 ! t0__8t0_a0 ! b_e_2t0a0 ! t0__2t0_a0
+x168 t0__5a0 ! t0__4t0_a0 ! b_e_shift ! r__r_8t0
+x169 t0__5a0 ! t0__4t0_a0 ! b_e_t0 ! t0__8t0_a0
+x170 t0__32a0 ! t0__t0_2a0 ! b_e_t0 ! t0__5t0
+x171 t0__9a0 ! t0__2t0_a0 ! b_e_t0 ! t0__9t0
+x172 t0__5a0 ! t0__4t0_a0 ! b_e_4t0 ! t0__2t0_a0
+x173 t0__9a0 ! t0__2t0_a0 ! b_e_t02a0 ! t0__9t0
+x174 t0__32a0 ! t0__t0_2a0 ! b_e_t04a0 ! t0__5t0
+x175 t0__8a0 ! t0__2t0_a0 ! b_e_5t0 ! t0__2t0_a0
+x176 t0__5a0 ! t0__4t0_a0 ! b_e_8t0 ! t0__t0_a0
+x177 t0__5a0 ! t0__4t0_a0 ! b_e_8t0a0 ! t0__t0_a0
+x178 t0__5a0 ! t0__2t0_a0 ! b_e_2t0 ! t0__8t0_a0
+x179 t0__5a0 ! t0__2t0_a0 ! b_e_2t0a0 ! t0__8t0_a0
+x180 t0__9a0 ! t0__5t0 ! b_e_shift ! r__r_4t0
+x181 t0__9a0 ! t0__5t0 ! b_e_t0 ! t0__4t0_a0
+x182 t0__9a0 ! t0__5t0 ! b_e_2t0 ! t0__2t0_a0
+x183 t0__9a0 ! t0__5t0 ! b_e_2t0a0 ! t0__2t0_a0
+x184 t0__5a0 ! t0__9t0 ! b_e_4t0 ! t0__t0_a0
+x185 t0__9a0 ! t0__4t0_a0 ! b_e_t0 ! t0__5t0
+x186 t0__32a0 ! t0__t0ma0 ! b_e_2t0 ! t0__3t0
+x187 t0__9a0 ! t0__4t0_a0 ! b_e_t02a0 ! t0__5t0
+x188 t0__9a0 ! t0__5t0 ! b_e_4t0 ! t0__t0_2a0
+x189 t0__5a0 ! t0__4t0_a0 ! b_e_t0 ! t0__9t0
+x190 t0__9a0 ! t0__2t0_a0 ! b_e_2t0 ! t0__5t0
+x191 t0__64a0 ! t0__3t0 ! b_e_t0 ! t0__t0ma0
+x192 t0__8a0 ! t0__3t0 ! b_e_shift ! r__r_8t0
+x193 t0__8a0 ! t0__3t0 ! b_e_t0 ! t0__8t0_a0
+x194 t0__8a0 ! t0__3t0 ! b_e_2t0 ! t0__4t0_a0
+x195 t0__8a0 ! t0__8t0_a0 ! b_e_t0 ! t0__3t0
+x196 t0__8a0 ! t0__3t0 ! b_e_4t0 ! t0__2t0_a0
+x197 t0__8a0 ! t0__3t0 ! b_e_4t0a0 ! t0__2t0_a0
+x198 t0__64a0 ! t0__t0_2a0 ! b_e_t0 ! t0__3t0
+x199 t0__8a0 ! t0__4t0_a0 ! b_e_2t0a0 ! t0__3t0
+x200 t0__5a0 ! t0__5t0 ! b_e_shift ! r__r_8t0
+x201 t0__5a0 ! t0__5t0 ! b_e_t0 ! t0__8t0_a0
+x202 t0__5a0 ! t0__5t0 ! b_e_2t0 ! t0__4t0_a0
+x203 t0__5a0 ! t0__5t0 ! b_e_2t0a0 ! t0__4t0_a0
+x204 t0__8a0 ! t0__2t0_a0 ! b_e_4t0 ! t0__3t0
+x205 t0__5a0 ! t0__8t0_a0 ! b_e_t0 ! t0__5t0
+x206 t0__64a0 ! t0__t0_4a0 ! b_e_t02a0 ! t0__3t0
+x207 t0__8a0 ! t0__2t0_a0 ! b_e_3t0 ! t0__4t0_a0
+x208 t0__5a0 ! t0__5t0 ! b_e_8t0 ! t0__t0_a0
+x209 t0__5a0 ! t0__5t0 ! b_e_8t0a0 ! t0__t0_a0
+x210 t0__5a0 ! t0__4t0_a0 ! b_e_2t0 ! t0__5t0
+x211 t0__5a0 ! t0__4t0_a0 ! b_e_2t0a0 ! t0__5t0
+x212 t0__3a0 ! t0__4t0_a0 ! b_e_4t0 ! t0__4t0_a0
+x213 t0__3a0 ! t0__4t0_a0 ! b_e_4t0a0 ! t0__4t0_a0
+x214 t0__9a0 ! t0__t0_4a0 ! b_e_2t04a0 ! t0__8t0_a0
+x215 t0__5a0 ! t0__4t0_a0 ! b_e_5t0 ! t0__2t0_a0
+x216 t0__9a0 ! t0__3t0 ! b_e_shift ! r__r_8t0
+x217 t0__9a0 ! t0__3t0 ! b_e_t0 ! t0__8t0_a0
+x218 t0__9a0 ! t0__3t0 ! b_e_2t0 ! t0__4t0_a0
+x219 t0__9a0 ! t0__8t0_a0 ! b_e_t0 ! t0__3t0
+x220 t0__3a0 ! t0__9t0 ! b_e_4t0 ! t0__2t0_a0
+x221 t0__3a0 ! t0__9t0 ! b_e_4t0a0 ! t0__2t0_a0
+x222 t0__9a0 ! t0__4t0_a0 ! b_e_2t0 ! t0__3t0
+x223 t0__9a0 ! t0__4t0_a0 ! b_e_2t0a0 ! t0__3t0
+x224 t0__9a0 ! t0__3t0 ! b_e_8t0 ! t0__t0_a0
+x225 t0__9a0 ! t0__5t0 ! b_e_t0 ! t0__5t0
+x226 t0__3a0 ! t0__2t0_a0 ! b_e_t02a0 ! t0__32t0
+x227 t0__9a0 ! t0__5t0 ! b_e_t02a0 ! t0__5t0
+x228 t0__9a0 ! t0__2t0_a0 ! b_e_4t0 ! t0__3t0
+x229 t0__9a0 ! t0__2t0_a0 ! b_e_4t0a0 ! t0__3t0
+x230 t0__9a0 ! t0__5t0 ! b_e_5t0 ! t0__t0_a0
+x231 t0__9a0 ! t0__2t0_a0 ! b_e_3t0 ! t0__4t0_a0
+x232 t0__3a0 ! t0__2t0_a0 ! b_e_8t0 ! t0__4t0_a0
+x233 t0__3a0 ! t0__2t0_a0 ! b_e_8t0a0 ! t0__4t0_a0
+x234 t0__3a0 ! t0__4t0_a0 ! b_e_2t0 ! t0__9t0
+x235 t0__3a0 ! t0__4t0_a0 ! b_e_2t0a0 ! t0__9t0
+x236 t0__9a0 ! t0__2t0_a0 ! b_e_4t08a0 ! t0__3t0
+x237 t0__16a0 ! t0__5t0 ! b_e_3t0 ! t0__t0ma0
+x238 t0__3a0 ! t0__4t0_a0 ! b_e_2t04a0 ! t0__9t0
+x239 t0__16a0 ! t0__5t0 ! b_e_t0ma0 ! t0__3t0
+x240 t0__9a0 ! t0__t0_a0 ! b_e_8t0 ! t0__3t0
+x241 t0__9a0 ! t0__t0_a0 ! b_e_8t0a0 ! t0__3t0
+x242 t0__5a0 ! t0__3t0 ! b_e_2t0 ! t0__8t0_a0
+x243 t0__9a0 ! t0__9t0 ! b_e_t0 ! t0__3t0
+x244 t0__5a0 ! t0__3t0 ! b_e_4t0 ! t0__4t0_a0
+x245 t0__8a0 ! t0__3t0 ! b_e_5t0 ! t0__2t0_a0
+x246 t0__5a0 ! t0__8t0_a0 ! b_e_2t0 ! t0__3t0
+x247 t0__5a0 ! t0__8t0_a0 ! b_e_2t0a0 ! t0__3t0
+x248 t0__32a0 ! t0__t0ma0 ! b_e_shift ! r__r_8t0
+x249 t0__32a0 ! t0__t0ma0 ! b_e_t0 ! t0__8t0_a0
+x250 t0__5a0 ! t0__5t0 ! b_e_2t0 ! t0__5t0
+x251 t0__5a0 ! t0__5t0 ! b_e_2t0a0 ! t0__5t0
+x252 t0__64a0 ! t0__t0ma0 ! b_e_shift ! r__r_4t0
+x253 t0__64a0 ! t0__t0ma0 ! b_e_t0 ! t0__4t0_a0
+x254 t0__128a0 ! t0__t0ma0 ! b_e_shift ! r__r_2t0
+x255 t0__256a0 ! a1_ne_0_b_l0 ! t0__t0ma0 ! b_n_ret_t0
+;1040 insts before this.
+ret_t0 MILLIRET
+e_t0 r__r_t0
+e_shift a1_ne_0_b_l2
+ a0__256a0 ; a0 <<= 8 ***********
+ MILLIRETN
+e_t0ma0 a1_ne_0_b_l0
+ t0__t0ma0
+ MILLIRET
+ r__r_t0
+e_t0a0 a1_ne_0_b_l0
+ t0__t0_a0
+ MILLIRET
+ r__r_t0
+e_t02a0 a1_ne_0_b_l0
+ t0__t0_2a0
+ MILLIRET
+ r__r_t0
+e_t04a0 a1_ne_0_b_l0
+ t0__t0_4a0
+ MILLIRET
+ r__r_t0
+e_2t0 a1_ne_0_b_l1
+ r__r_2t0
+ MILLIRETN
+e_2t0a0 a1_ne_0_b_l0
+ t0__2t0_a0
+ MILLIRET
+ r__r_t0
+e2t04a0 t0__t0_2a0
+ a1_ne_0_b_l1
+ r__r_2t0
+ MILLIRETN
+e_3t0 a1_ne_0_b_l0
+ t0__3t0
+ MILLIRET
+ r__r_t0
+e_4t0 a1_ne_0_b_l1
+ r__r_4t0
+ MILLIRETN
+e_4t0a0 a1_ne_0_b_l0
+ t0__4t0_a0
+ MILLIRET
+ r__r_t0
+e4t08a0 t0__t0_2a0
+ a1_ne_0_b_l1
+ r__r_4t0
+ MILLIRETN
+e_5t0 a1_ne_0_b_l0
+ t0__5t0
+ MILLIRET
+ r__r_t0
+e_8t0 a1_ne_0_b_l1
+ r__r_8t0
+ MILLIRETN
+e_8t0a0 a1_ne_0_b_l0
+ t0__8t0_a0
+ MILLIRET
+ r__r_t0
+
+ .procend
+ .end
+
diff --git a/sys/lib/libkern/arch/hppa/mulU.S b/sys/lib/libkern/arch/hppa/mulU.S
new file mode 100644
index 00000000000..10147a8bb42
--- /dev/null
+++ b/sys/lib/libkern/arch/hppa/mulU.S
@@ -0,0 +1,131 @@
+/* $OpenBSD: mulU.S,v 1.1 1998/06/23 18:56:54 mickey Exp $ */
+
+/*
+ * (c) Copyright 1985 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+
+#include "prefix.h"
+
+/*
+ *
+ * Editor: Michael J. Eager
+ *
+ *
+ * ROUTINE: $$mulU
+ *
+ *
+ * DESCRIPTION:
+ *
+ * $$mulU multiplies two single word unsigned integers, giving a single
+ * word result.
+ *
+ *
+ * INPUT REGISTERS:
+ *
+ * arg0 = Operand 1
+ * arg1 = Operand 2
+ * r31 == return pc
+ * sr0 == return space when called externally
+ *
+ *
+ * OUTPUT REGISTERS:
+ *
+ * arg0 = undefined
+ * arg1 = undefined
+ * ret1 = result
+ *
+ * OTHER REGISTERS AFFECTED:
+ *
+ * r1 = undefined
+ *
+ * SIDE EFFECTS:
+ *
+ * Causes a trap under the following conditions: NONE
+ * Changes memory at the following places: NONE
+ *
+ * PERMISSIBLE CONTEXT:
+ *
+ * Unwindable
+ * Does not create a stack frame
+ * Is usable for internal or external microcode
+ *
+ * DISCUSSION:
+ *
+ * Calls other millicode routines via r31: NONE
+ * Calls other millicode routines: NONE
+ */
+
+DEFINE(tmp,r1)
+DEFINE(retreg,ret1)
+
+ .subspa $MILLICODE$
+ .proc
+ .callinfo millicode
+
+ .entry
+$$mulU
+ .export $$mulU,MILLICODE
+
+ combt,<<= arg1,arg0,$loop
+ add 0,0,retreg
+ add 0,arg1,tmp
+ add 0,arg0,arg1
+ add 0,tmp,arg0
+$loop extru arg1,31,4,tmp
+ blr tmp,0
+ extru arg1,27,28,arg1
+ comb,=,n arg1,0,$return
+ b,n $shmcand
+ movb,tr arg0,tmp,$addtmp
+ comb,= arg1,0,$return
+$two b $endloop
+ sh1add arg0,0,tmp
+ b $endloop
+ sh1add arg0,arg0,tmp
+ b $endloop
+ sh2add arg0,0,tmp
+ b $endloop
+ sh2add arg0,arg0,tmp
+ b $fiftnx
+ sh1add arg0,0,tmp
+ movb,tr arg0,tmp,$fiftnx
+ sh2add arg0,retreg,retreg
+ b $endloop
+ sh3add arg0,0,tmp
+ b $endloop
+ sh3add arg0,arg0,tmp
+ b $two
+ sh3add arg0,retreg,retreg
+ movb,tr arg0,tmp,$fiftnx
+ sh3add arg0,retreg,retreg
+ b $fiftnx
+ sh2add arg0,0,tmp
+ sh2add arg0,arg0,tmp
+ b $endloop
+ sh3add arg0,retreg,retreg
+ sh1add,tr arg0,0,tmp
+ sh2add arg0,arg0,tmp
+$fiftnx sh1add tmp,tmp,tmp
+$endloop comb,= arg1,0,$return
+$addtmp add tmp,retreg,retreg
+$shmcand addb,tr arg0,arg0,$loop
+ sh3add arg0,0,arg0
+ .exit
+$return MILLIRET
+ nop
+ .procend
+#ifdef milliext
+ .origin 0x00000100
+#endif
+ .end
diff --git a/sys/lib/libkern/arch/hppa/prefix.h b/sys/lib/libkern/arch/hppa/prefix.h
new file mode 100644
index 00000000000..442f1fd2ce0
--- /dev/null
+++ b/sys/lib/libkern/arch/hppa/prefix.h
@@ -0,0 +1,87 @@
+/* $OpenBSD: prefix.h,v 1.1 1998/06/23 18:56:54 mickey Exp $ */
+
+/*
+ * (c) Copyright 1985 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+
+/*
+ * STANDARD INCLUDE FILE FOR MILLICODE
+ * Every source file must include this file.
+ *
+ * Hardware General Registers
+ *
+ * Frame Offsets (millicode convention!)
+ * Used when calling other millicode routines.
+ * Stack unwinding is dependent upon these definitions.
+ * r31_slot .equ -20
+ * sr0_slot .equ -16
+ */
+
+#include <machine/asm.h>
+
+#define DEFINE(name, value)name: .EQU value
+#ifdef milliext
+#ifdef PIC
+#define MILLI_BE(lbl) \
+ BL .+8,r1\
+ ! ADDIL L%lbl-labl/**/lbl,r1\
+ ! .LABEL labl/**/lbl\
+ ! BE R%lbl-labl/**/lbl(sr7,r1)
+
+#define MILLI_BEN(lbl) \
+ BL .+8,r1\
+ ! ADDIL L%lbl-labl/**/lbl,r1\
+ ! .LABEL labl/**/lbl\
+ ! BE,N R%lbl-labl/**/lbl(sr7,r1)
+
+#define MILLI_BLE(lbl) \
+ BL .+8,r1\
+ ! ADDIL L%lbl-labl/**/lbl,r1\
+ ! .LABEL labl/**/lbl \
+ ! BLE R%lbl-labl/**/lbl(sr7,r1)
+
+#define MILLI_BLEN(lbl) \
+ BL .+8,r1\
+ ! ADDIL L%lbl-labl/**/lbl,r1\
+ ! .LABEL labl/**/lbl\
+ ! BLE,N R%lbl-labl/**/lbl(sr7,r1)
+#else
+#define MILLI_BE(lbl) BE lbl(sr7,r0)
+#define MILLI_BEN(lbl) BE,n lbl(sr7,r0)
+#define MILLI_BLE(lbl) BLE lbl(sr7,r0)
+#define MILLI_BLEN(lbl) BLE,n lbl(sr7,r0)
+#endif
+
+#define MILLIRETN BE,n 0(sr0,r31)
+#define MILLIRET BE 0(sr0,r31)
+#define MILLI_RETN BE,n 0(sr0,r31)
+#define MILLI_RET BE 0(sr0,r31)
+
+#else
+#define MILLI_BE(lbl) B lbl
+#define MILLI_BEN(lbl) B,n lbl
+#define MILLI_BLE(lbl) BL lbl,r31
+#define MILLI_BLEN(lbl) BL,n lbl,r31
+#define MILLIRETN BV,n 0(r31)
+#define MILLIRET BV 0(r31)
+#define MILLI_RETN BV,n 0(r31)
+#define MILLI_RET BV 0(r31)
+#endif
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ .SPACE $TEXT$
+ .subspa $MILLICODE$
+;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+; VERSION is used wherever ".version" can appear in a routine
+;#define VERSION .version
+#define VERSION ;
diff --git a/sys/lib/libkern/arch/hppa/remI.S b/sys/lib/libkern/arch/hppa/remI.S
new file mode 100644
index 00000000000..cc7b92f779f
--- /dev/null
+++ b/sys/lib/libkern/arch/hppa/remI.S
@@ -0,0 +1,164 @@
+/* $OpenBSD: remI.S,v 1.1 1998/06/23 18:56:54 mickey Exp $ */
+
+/*
+ * (c) Copyright 1985 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+
+#include "prefix.h"
+
+/*
+ *
+ * Editor: Michael J. Eager
+ *
+ *
+ * ROUTINE: $$remI
+ *
+ * DESCRIPTION:
+ *
+ * $$remI returns the remainder of the division of two signed 32-bit
+ * integers. The sign of the remainder is the same as the sign of
+ * the dividend.
+ *
+ *
+ * INPUT REGISTERS:
+ *
+ * arg0 == dividend
+ * arg1 == divisor
+ * r31 == return pc
+ * sr0 == return space when called externally
+ *
+ * OUTPUT REGISTERS:
+ *
+ * arg0 = destroyed
+ * arg1 = destroyed
+ * ret1 = remainder
+ *
+ * OTHER REGISTERS AFFECTED:
+ *
+ * r1 = undefined
+ *
+ * SIDE EFFECTS:
+ *
+ * Causes a trap under the following conditions: DIVIDE BY ZERO
+ * Changes memory at the following places: NONE
+ *
+ * PERMISSIBLE CONTEXT:
+ *
+ * Unwindable
+ * Does not create a stack frame
+ * Is usable for internal or external microcode
+ *
+ * DISCUSSION:
+ *
+ * Calls other millicode routines via r31: NONE
+ * Calls other millicode routines: NONE
+ */
+
+DEFINE(tmp,r1)
+DEFINE(retreg,ret1)
+
+ .subspa $MILLICODE$
+ .proc
+ .callinfo millicode
+ .entry
+$$remI
+ .export $$remI,MILLICODE
+ addit,= 0,arg1,0 ; trap if div by zero
+ add,>= 0,arg0,retreg ; move dividend, if retreg < 0,
+ sub 0,retreg,retreg ; make it positive
+ sub 0,arg1, tmp ; clear carry,
+ ; negate the divisor
+ ds 0, tmp,0 ; set V-bit to the comple-
+ ; ment of the divisor sign
+ or 0,0, tmp ; clear tmp
+ add retreg,retreg,retreg ; shift msb bit into carry
+ ds tmp,arg1, tmp ; 1st divide step, if no carry
+ ; out, msb of quotient = 0
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+tt1 ds tmp,arg1, tmp ; 2nd divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds tmp,arg1, tmp ; 3rd divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds tmp,arg1, tmp ; 4th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds tmp,arg1, tmp ; 5th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds tmp,arg1, tmp ; 6th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds tmp,arg1, tmp ; 7th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds tmp,arg1, tmp ; 8th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds tmp,arg1, tmp ; 9th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds tmp,arg1, tmp ; 10th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds tmp,arg1, tmp ; 11th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds tmp,arg1, tmp ; 12th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds tmp,arg1, tmp ; 13th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds tmp,arg1, tmp ; 14th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds tmp,arg1, tmp ; 15th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds tmp,arg1, tmp ; 16th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds tmp,arg1, tmp ; 17th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds tmp,arg1, tmp ; 18th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds tmp,arg1, tmp ; 19th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds tmp,arg1, tmp ; 20th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds tmp,arg1, tmp ; 21st divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds tmp,arg1, tmp ; 22nd divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds tmp,arg1, tmp ; 23rd divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds tmp,arg1, tmp ; 24th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds tmp,arg1, tmp ; 25th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds tmp,arg1, tmp ; 26th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds tmp,arg1, tmp ; 27th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds tmp,arg1, tmp ; 28th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds tmp,arg1, tmp ; 29th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds tmp,arg1, tmp ; 30th divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds tmp,arg1, tmp ; 31st divide step
+ addc retreg,retreg,retreg ; shift retreg with/into carry
+ ds tmp,arg1, tmp ; 32nd divide step,
+ addc retreg,retreg,retreg ; shift last bit into retreg
+ movb,>=,n tmp,retreg,finish ; branch if pos. tmp
+ add,< arg1,0,0 ; if arg1 > 0, add arg1
+ add,tr tmp,arg1,retreg ; for correcting remainder tmp
+ sub tmp,arg1,retreg ; else add absolute value arg1
+finish add,>= arg0,0,0 ; set sign of remainder
+ sub 0,retreg,retreg ; to sign of dividend
+ .exit
+ MILLIRET
+ nop
+ .procend
+#ifdef milliext
+ .origin 0x00000200
+#endif
+ .end
diff --git a/sys/lib/libkern/arch/hppa/remU.S b/sys/lib/libkern/arch/hppa/remU.S
new file mode 100644
index 00000000000..b347a6d49f0
--- /dev/null
+++ b/sys/lib/libkern/arch/hppa/remU.S
@@ -0,0 +1,152 @@
+/* $OpenBSD: remU.S,v 1.1 1998/06/23 18:56:54 mickey Exp $ */
+
+/*
+ * (c) Copyright 1985 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+
+#include "prefix.h"
+
+/*
+ * Author: Committee
+ *
+ *
+ * ROUTINE: $$remU
+ *
+ * Single precision divide for remainder with unsigned binary integers.
+ *
+ * The remainder must be dividend-(dividend/divisor)*divisor.
+ * Divide by zero is trapped.
+ *
+ * INPUT REGISTERS:
+ * arg0 == dividend
+ * arg1 == divisor
+ * r31 == return pc
+ * sr0 == return space when called externally
+ *
+ * OUTPUT REGISTERS:
+ * arg0 = undefined
+ * arg1 = undefined
+ * ret1 = remainder
+ *
+ * OTHER REGISTERS AFFECTED:
+ * r1 = undefined
+ *
+ * SIDE EFFECTS:
+ * Causes a trap under the following conditions: DIVIDE BY ZERO
+ * Changes memory at the following places: NONE
+ *
+ * PERMISSIBLE CONTEXT:
+ * Unwindable.
+ * Does not create a stack frame.
+ * Suitable for internal or external millicode.
+ * Assumes the special millicode register conventions.
+ *
+ * DISCUSSION:
+ * Calls other millicode routines using r31: NONE
+ * Calls other millicode routines: NONE
+ */
+
+DEFINE(temp,r1)
+DEFINE(rmndr,ret1) ; r29
+ .subspa $MILLICODE$
+ .export $$remU,millicode
+ .proc
+ .callinfo millicode
+
+ .entry
+$$remU
+
+ comib,>=,n 0,arg1,special_case
+ sub r0,arg1,rmndr ; clear carry, negate the divisor
+ ds r0,rmndr,r0 ; set V-bit to 1
+ add arg0,arg0,temp ; shift msb bit into carry
+ ds r0,arg1,rmndr ; 1st divide step, if no carry
+ addc temp,temp,temp ; shift temp with/into carry
+ ds rmndr,arg1,rmndr ; 2nd divide step
+ addc temp,temp,temp ; shift temp with/into carry
+ ds rmndr,arg1,rmndr ; 3rd divide step
+ addc temp,temp,temp ; shift temp with/into carry
+ ds rmndr,arg1,rmndr ; 4th divide step
+ addc temp,temp,temp ; shift temp with/into carry
+ ds rmndr,arg1,rmndr ; 5th divide step
+ addc temp,temp,temp ; shift temp with/into carry
+ ds rmndr,arg1,rmndr ; 6th divide step
+ addc temp,temp,temp ; shift temp with/into carry
+ ds rmndr,arg1,rmndr ; 7th divide step
+ addc temp,temp,temp ; shift temp with/into carry
+ ds rmndr,arg1,rmndr ; 8th divide step
+ addc temp,temp,temp ; shift temp with/into carry
+ ds rmndr,arg1,rmndr ; 9th divide step
+ addc temp,temp,temp ; shift temp with/into carry
+ ds rmndr,arg1,rmndr ; 10th divide step
+ addc temp,temp,temp ; shift temp with/into carry
+ ds rmndr,arg1,rmndr ; 11th divide step
+ addc temp,temp,temp ; shift temp with/into carry
+ ds rmndr,arg1,rmndr ; 12th divide step
+ addc temp,temp,temp ; shift temp with/into carry
+ ds rmndr,arg1,rmndr ; 13th divide step
+ addc temp,temp,temp ; shift temp with/into carry
+ ds rmndr,arg1,rmndr ; 14th divide step
+ addc temp,temp,temp ; shift temp with/into carry
+ ds rmndr,arg1,rmndr ; 15th divide step
+ addc temp,temp,temp ; shift temp with/into carry
+ ds rmndr,arg1,rmndr ; 16th divide step
+ addc temp,temp,temp ; shift temp with/into carry
+ ds rmndr,arg1,rmndr ; 17th divide step
+ addc temp,temp,temp ; shift temp with/into carry
+ ds rmndr,arg1,rmndr ; 18th divide step
+ addc temp,temp,temp ; shift temp with/into carry
+ ds rmndr,arg1,rmndr ; 19th divide step
+ addc temp,temp,temp ; shift temp with/into carry
+ ds rmndr,arg1,rmndr ; 20th divide step
+ addc temp,temp,temp ; shift temp with/into carry
+ ds rmndr,arg1,rmndr ; 21st divide step
+ addc temp,temp,temp ; shift temp with/into carry
+ ds rmndr,arg1,rmndr ; 22nd divide step
+ addc temp,temp,temp ; shift temp with/into carry
+ ds rmndr,arg1,rmndr ; 23rd divide step
+ addc temp,temp,temp ; shift temp with/into carry
+ ds rmndr,arg1,rmndr ; 24th divide step
+ addc temp,temp,temp ; shift temp with/into carry
+ ds rmndr,arg1,rmndr ; 25th divide step
+ addc temp,temp,temp ; shift temp with/into carry
+ ds rmndr,arg1,rmndr ; 26th divide step
+ addc temp,temp,temp ; shift temp with/into carry
+ ds rmndr,arg1,rmndr ; 27th divide step
+ addc temp,temp,temp ; shift temp with/into carry
+ ds rmndr,arg1,rmndr ; 28th divide step
+ addc temp,temp,temp ; shift temp with/into carry
+ ds rmndr,arg1,rmndr ; 29th divide step
+ addc temp,temp,temp ; shift temp with/into carry
+ ds rmndr,arg1,rmndr ; 30th divide step
+ addc temp,temp,temp ; shift temp with/into carry
+ ds rmndr,arg1,rmndr ; 31st divide step
+ addc temp,temp,temp ; shift temp with/into carry
+ ds rmndr,arg1,rmndr ; 32nd divide step,
+ comiclr,<= 0,rmndr,r0
+ add rmndr,arg1,rmndr ; correction
+ MILLIRETN
+ nop
+; Putting >= on the last DS and deleting COMICLR does not work!
+
+
+special_case
+ addit,= 0,arg1,r0 ; trap on div by zero
+ sub,>>= arg0,arg1,rmndr
+ copy arg0,rmndr
+ .exit
+ MILLIRETN
+ nop
+ .procend
+ .end