diff options
Diffstat (limited to 'sys/lib')
| -rw-r--r-- | sys/lib/libkern/arch/m68k/divsi3.S | 71 | ||||
| -rw-r--r-- | sys/lib/libkern/arch/m68k/modsi3.S | 77 | ||||
| -rw-r--r-- | sys/lib/libkern/arch/m68k/udivsi3.S | 130 | ||||
| -rw-r--r-- | sys/lib/libkern/arch/m68k/umodsi3.S | 68 |
4 files changed, 346 insertions, 0 deletions
diff --git a/sys/lib/libkern/arch/m68k/divsi3.S b/sys/lib/libkern/arch/m68k/divsi3.S new file mode 100644 index 00000000000..9d21a894a25 --- /dev/null +++ b/sys/lib/libkern/arch/m68k/divsi3.S @@ -0,0 +1,71 @@ +/* $NetBSD: divsi3.S,v 1.3 2020/04/22 11:58:26 rin Exp $ */ + +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * the Systems Programming Group of the University of Utah Computer + * Science Department. + * + * 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. Neither the name of the University 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 REGENTS 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 REGENTS 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. + */ + +#include <machine/asm.h> + +#if defined(LIBC_SCCS) && !defined(lint) +#if 0 + RCSID("from: @(#)divsi3.s 5.1 (Berkeley) 6/7/90") +#else + RCSID("$NetBSD: divsi3.S,v 1.3 2020/04/22 11:58:26 rin Exp $") +#endif +#endif /* LIBC_SCCS and not lint */ + +/* int / int */ +#ifndef __mc68010__ +#error +ENTRY(__divsi3) + movel 4(%sp),%d0 + divsl 8(%sp),%d0 + rts +END(__divsi3) +#else +ENTRY(__divsi3) +| NB: this requires that __udivsi3 preserve %a0: + movel 4(%sp), %d1 | load the dividend + bpl 1f + negl 4(%sp) | store abs(dividend) +1: movel 8(%sp), %d0 | load the divisor + bpl 2f + negl 8(%sp) | store abs(divisor) +2: eorl %d1, %d0 + bpl 3f | branch if sgn(divisor) == sgn(dividend) + movel (%sp)+, %a0 | pop return address + pea (.Lret,%pc) | push our return address +3: jmp _C_LABEL(__udivsi3) +.Lret: negl %d0 | negate quotient + jmp (%a0) +END(__divsi3) +#endif /* __mc68010__ */ diff --git a/sys/lib/libkern/arch/m68k/modsi3.S b/sys/lib/libkern/arch/m68k/modsi3.S new file mode 100644 index 00000000000..ed55a45eaea --- /dev/null +++ b/sys/lib/libkern/arch/m68k/modsi3.S @@ -0,0 +1,77 @@ +/* $NetBSD: modsi3.S,v 1.3 2020/04/22 11:58:26 rin Exp $ */ + +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * the Systems Programming Group of the University of Utah Computer + * Science Department. + * + * 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. Neither the name of the University 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 REGENTS 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 REGENTS 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. + */ + +#include <machine/asm.h> + +#if defined(LIBC_SCCS) && !defined(lint) +#if 0 + RCSID("from: @(#)modsi3.s 5.1 (Berkeley) 6/7/90") +#else + RCSID("$NetBSD: modsi3.S,v 1.3 2020/04/22 11:58:26 rin Exp $") +#endif +#endif /* LIBC_SCCS and not lint */ + +/* int % int */ +#ifndef __mc68010__ +#error +ENTRY(__modsi3) + movel 4(%sp),%d1 +#ifdef __mcoldfire__ + remsl 8(%sp),%d0:%d1 + divsl 8(%sp),%d1 +#else + divsll 8(%sp),%d0:%d1 +#endif + rts +END(__modsi3) +#else +ENTRY(__modsi3) +| NB: this requires that __udivsi3 preserve %a0 and return +| the modulus in %d1: + movel (%sp)+, %a0 | pop return address + movel 4(%sp), %d1 | load the divisor + bpl 1f + negl 4(%sp) | store abs(divisor) +1: movel (%sp), %d0 | load the dividend + pea (.Lret,%pc) | push our return address + bpl 2f + negl 4(%sp) | store abs(dividend) + subql #2, (%sp) | adjust return address +2: jmp _C_LABEL(__udivsi3) + negl %d1 | negate modulus +.Lret: movl %d1, %d0 | move modulus into %d0 + jmp (%a0) +END(__modsi3) +#endif /* __mc68010__ */ diff --git a/sys/lib/libkern/arch/m68k/udivsi3.S b/sys/lib/libkern/arch/m68k/udivsi3.S new file mode 100644 index 00000000000..ef458f65ac8 --- /dev/null +++ b/sys/lib/libkern/arch/m68k/udivsi3.S @@ -0,0 +1,130 @@ +/* $NetBSD: udivsi3.S,v 1.5 2020/04/22 11:58:26 rin Exp $ */ + +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * the Systems Programming Group of the University of Utah Computer + * Science Department. + * + * 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. Neither the name of the University 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 REGENTS 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 REGENTS 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. + */ + +#include <machine/asm.h> + +#if defined(LIBC_SCCS) && !defined(lint) +#if 0 + RCSID("from: @(#)udivsi3.s 5.1 (Berkeley) 6/7/90") +#else + RCSID("$NetBSD: udivsi3.S,v 1.5 2020/04/22 11:58:26 rin Exp $") +#endif +#endif /* LIBC_SCCS and not lint */ + +/* unsigned / unsigned */ +#ifndef __mc68010__ +#error +ENTRY(__udivsi3) + movel 4(%sp),%d0 + divul 8(%sp),%d0 + rts +END(__udivsi3) +#else +ENTRY(__udivsi3) + movel %d2, -(%sp) | save %d2 + movel 12(%sp), %d0 | load divisor + movel 8(%sp), %d1 | load dividend + +| first, we divide the divisor and dividend by two until +| the divisor fits into 16 bits: +1: cmpil #0x10000, %d0 + bcs 2f + lsrl #1, %d0 + lsrl #1, %d1 + bra 1b +2: + +| now we can do the divide. to avoid overflow, we have to +| do the divide in two parts, high and low, and add the +| results together: + movew %d1, %d2 | save low(dividend) + clrw %d1 + swap %d1 | %d1 = dividend >> 16 + divuw %d0, %d1 | do the high divide + moveal %d1, %a1 | save high divide result + movew %d2, %d1 | concat(remainder, low(dividend)) + divuw %d0, %d1 | do the low divide + movel %a1, %d0 | recover high divide result + swap %d0 + clrw %d0 | %d0 = finished high divide result + andil #0xffff, %d1 | %d1 = finished low divide result + addl %d1, %d0 | %d0 = quotient guess + +| the quotient we have so far is only a guess. the divide we +| did above was really the divide of some dividendB by some +| divisorB, where the following hold: +| +| (dividend - divisor) <= dividendB <= dividend +| (divisor / 2) < divisorB <= divisor +| +| so our guess quotient cannot be less than our real desired +| quotient. however, it might be one too big. +| +| to adjust this quotient, we multiply it by the original +| divisor and subtract the result from the original dividend. +| if the result is nonnegative, our guessed quotient was +| correct, and the subtraction result is our remainder. +| if the result is negative, our guessed quotient was one +| too big, and the subtraction result plus the original +| divisor is our remainder. +| +| as in mulsi3, we have to do the multiply in stages to avoid +| overflow: + + movel 12(%sp), %d2 | load divisor + swap %d2 + movel %d0, %d1 + muluw %d2, %d1 | high(divisor) * low(guess) + moveal %d1, %a1 | save high(divisor) * low(guess) + swap %d2 + movel %d0, %d1 + swap %d1 + muluw %d2, %d1 | low(divisor) * high(guess) + addl %a1, %d1 + swap %d1 + clrw %d1 | %d1 = finished high multiply result + moveal %d2, %a1 | save original divisor + muluw %d0, %d2 | low(guess) * low(divisor) + addl %d1, %d2 | %d2 = guess * divisor + + movel 8(%sp), %d1 | load original dividend + subl %d2, %d1 | subtract + bcc 3f + subql #1, %d0 | adjust quotient + addl %a1, %d1 | adjust remainder +3: movel (%sp)+, %d2 | restore %d2 + rts +END(__udivsi3) +#endif /* __mc68010__ */ diff --git a/sys/lib/libkern/arch/m68k/umodsi3.S b/sys/lib/libkern/arch/m68k/umodsi3.S new file mode 100644 index 00000000000..66598938e4c --- /dev/null +++ b/sys/lib/libkern/arch/m68k/umodsi3.S @@ -0,0 +1,68 @@ +/* $NetBSD: umodsi3.S,v 1.3 2020/04/22 11:58:26 rin Exp $ */ + +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * the Systems Programming Group of the University of Utah Computer + * Science Department. + * + * 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. Neither the name of the University 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 REGENTS 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 REGENTS 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. + */ + +#include <machine/asm.h> + +#if defined(LIBC_SCCS) && !defined(lint) +#if 0 + RCSID("from: @(#)umodsi3.s 5.1 (Berkeley) 6/7/90")( +#else + RCSID("$NetBSD: umodsi3.S,v 1.3 2020/04/22 11:58:26 rin Exp $") +#endif +#endif /* LIBC_SCCS and not lint */ + +/* unsigned % unsigned */ +#ifndef __mc68010__ +#error +ENTRY(__umodsi3) + movel 4(%sp),%d1 +#ifdef __mcoldfire__ + remul 8(%sp),%d0:%d1 + divul 8(%sp),%d1 +#else + divull 8(%sp),%d0:%d1 +#endif + rts +END(__umodsi3) +#else +ENTRY(__umodsi3) +| NB: this requires that __udivsi3 preserve the %a0 +| register, and that it returns the modulus in %d1: + movel (%sp)+, %a0 | pop the return address + jsr _C_LABEL(__udivsi3) + movel %d1, %d0 | move the modulus into %d0 + jmp (%a0) | return +END(__umodsi3) +#endif /* __mc68010__ */ |
