More of the libc...

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22738 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
François Revol 2007-10-26 17:07:23 +00:00
parent 42a2db3602
commit dd68e9e8b4
17 changed files with 1000 additions and 8 deletions

View File

@ -0,0 +1,17 @@
SubDir HAIKU_TOP src system libroot posix arch m68k ;
local genericSources =
setjmp_save_sigs.c
longjmp_return.c
;
MergeObject posix_arch_$(TARGET_ARCH).o :
setjmp.S
sigsetjmp.S
siglongjmp.S
$(genericSources)
;
SEARCH on [ FGristFiles $(genericSources) ]
= [ FDirName $(SUBDIR) $(DOTDOT) generic ] ;

View File

@ -0,0 +1,20 @@
/*
* Copyright 2005, Ingo Weinhold <bonefish@cs.tu-berlin.de>. All rights
* reserved. Distributed under the terms of the Haiku License.
*/
#include "setjmp_internal.h"
/* int setjmp(jmp_buf buffer) */
FUNCTION(setjmp):
move.l (%a7)+,%a0
move.l (%a7)+,%d0
clr.l -(%a7) /* push 0 as 2nd arg */
move.l %d0,-(%a7)
move.l %a0,-(%a7)
// call __sigsetjmp with saveMask = 0
jmp __sigsetjmp
#pragma weak _setjmp=setjmp

View File

@ -0,0 +1,26 @@
/*
* Copyright 2005, Ingo Weinhold <bonefish@cs.tu-berlin.de>. All rights
* reserved. Distributed under the terms of the Haiku License.
*/
#ifndef SETJMP_INTERNAL_H
#define SETJMP_INTERNAL_H
/* M68K function call ABI register use:
d0 - return value
d1 - volatile (return value?)
d2-d7 - local vars
a0 - return value
a1 - volatile (return value?)
a2-a6 - local vars
a6 - (stack frame ?)
a7 - stack pointer
*/
/* These are the fields of the __jmp_regs structure */
#define JMP_REGS_D2 0
#define JMP_REGS_PC (4*(6+6))
#define JMP_REGS_CCR (4*(6+6)+4)
#define FUNCTION(x) .global x; .type x,@function; x
#endif /* SETJMP_INTERNAL_H */

View File

@ -0,0 +1,26 @@
/*
* Copyright 2005, Ingo Weinhold <bonefish@cs.tu-berlin.de>. All rights
* reserved. Distributed under the terms of the Haiku License.
*/
#include "setjmp_internal.h"
/* int __siglongjmp(jmp_buf buffer, int value) */
FUNCTION(siglongjmp):
FUNCTION(longjmp):
FUNCTION(_longjmp):
// a0: buffer, d0: saveMask
move.l (4,%a7),%a0
move.l (8,%a7),%d0
// restore non-volatile general purpose registers
movem.l (%a0),%d2-%d7/%a2-%a7
// restore special registers (link, condition)
move.w (JMP_REGS_CCR,%a0),%d0
move %d0,%ccr
move.l (JMP_REGS_PC,%a0),(%a7)
jmp __longjmp_return
#pragma weak longjmp=siglongjmp

View File

@ -0,0 +1,27 @@
/*
* Copyright 2005, Ingo Weinhold <bonefish@cs.tu-berlin.de>. All rights
* reserved. Distributed under the terms of the Haiku License.
*/
#include "setjmp_internal.h"
/* int sigsetjmp(jmp_buf buffer, int saveMask) */
FUNCTION(__sigsetjmp):
FUNCTION(sigsetjmp):
// a0: buffer, d0: saveMask
move.l (4,%a7),%a0
move.l (8,%a7),%d0
// store non-volatile general purpose registers
#warning M68K: do we want to save a7 there ??
movem.l %d2-%d7/%a2-%a7,(%a0)
// store special registers (link, condition)
clr.l %d0
move %ccr,%d0
move.w %d0,(JMP_REGS_CCR,%a0)
move.l (%a7),(JMP_REGS_PC,%a0)
#warning M68K: check this.
jmp __setjmp_save_sigs

View File

@ -0,0 +1,152 @@
/* Copyright (C) 1991, 1993, 1997, 2000 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Torbjorn Granlund (tege@sics.se),
with help from Dan Sahlin (dan@sics.se);
commentary by Jim Blandy (jimb@ai.mit.edu).
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. */
#include <string.h>
#include <stdlib.h>
#undef strlen
/* Return the length of the null-terminated string STR. Scan for
the null terminator quickly by testing four bytes at a time. */
size_t
strlen (str)
const char *str;
{
const char *char_ptr;
const unsigned long int *longword_ptr;
unsigned long int longword, magic_bits, himagic, lomagic;
/* Handle the first few characters by reading one character at a time.
Do this until CHAR_PTR is aligned on a longword boundary. */
for (char_ptr = str; ((unsigned long int) char_ptr
& (sizeof (longword) - 1)) != 0;
++char_ptr)
if (*char_ptr == '\0')
return char_ptr - str;
/* All these elucidatory comments refer to 4-byte longwords,
but the theory applies equally well to 8-byte longwords. */
longword_ptr = (unsigned long int *) char_ptr;
/* Bits 31, 24, 16, and 8 of this number are zero. Call these bits
the "holes." Note that there is a hole just to the left of
each byte, with an extra at the end:
bits: 01111110 11111110 11111110 11111111
bytes: AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD
The 1-bits make sure that carries propagate to the next 0-bit.
The 0-bits provide holes for carries to fall into. */
magic_bits = 0x7efefeffL;
himagic = 0x80808080L;
lomagic = 0x01010101L;
if (sizeof (longword) > 4)
{
/* 64-bit version of the magic. */
/* Do the shift in two steps to avoid a warning if long has 32 bits. */
magic_bits = ((0x7efefefeL << 16) << 16) | 0xfefefeffL;
himagic = ((himagic << 16) << 16) | himagic;
lomagic = ((lomagic << 16) << 16) | lomagic;
}
if (sizeof (longword) > 8)
abort ();
/* Instead of the traditional loop which tests each character,
we will test a longword at a time. The tricky part is testing
if *any of the four* bytes in the longword in question are zero. */
for (;;)
{
/* We tentatively exit the loop if adding MAGIC_BITS to
LONGWORD fails to change any of the hole bits of LONGWORD.
1) Is this safe? Will it catch all the zero bytes?
Suppose there is a byte with all zeros. Any carry bits
propagating from its left will fall into the hole at its
least significant bit and stop. Since there will be no
carry from its most significant bit, the LSB of the
byte to the left will be unchanged, and the zero will be
detected.
2) Is this worthwhile? Will it ignore everything except
zero bytes? Suppose every byte of LONGWORD has a bit set
somewhere. There will be a carry into bit 8. If bit 8
is set, this will carry into bit 16. If bit 8 is clear,
one of bits 9-15 must be set, so there will be a carry
into bit 16. Similarly, there will be a carry into bit
24. If one of bits 24-30 is set, there will be a carry
into bit 31, so all of the hole bits will be changed.
The one misfire occurs when bits 24-30 are clear and bit
31 is set; in this case, the hole at bit 31 is not
changed. If we had access to the processor carry flag,
we could close this loophole by putting the fourth hole
at bit 32!
So it ignores everything except 128's, when they're aligned
properly. */
longword = *longword_ptr++;
if (
#if 0
/* Add MAGIC_BITS to LONGWORD. */
(((longword + magic_bits)
/* Set those bits that were unchanged by the addition. */
^ ~longword)
/* Look at only the hole bits. If any of the hole bits
are unchanged, most likely one of the bytes was a
zero. */
& ~magic_bits)
#else
((longword - lomagic) & himagic)
#endif
!= 0)
{
/* Which of the bytes was the zero? If none of them were, it was
a misfire; continue the search. */
const char *cp = (const char *) (longword_ptr - 1);
if (cp[0] == 0)
return cp - str;
if (cp[1] == 0)
return cp - str + 1;
if (cp[2] == 0)
return cp - str + 2;
if (cp[3] == 0)
return cp - str + 3;
if (sizeof (longword) > 4)
{
if (cp[4] == 0)
return cp - str + 4;
if (cp[5] == 0)
return cp - str + 5;
if (cp[6] == 0)
return cp - str + 6;
if (cp[7] == 0)
return cp - str + 7;
}
}
}
}

View File

@ -20,6 +20,7 @@ if $(OPTIM) = -O0 {
DEBUG = 0 ;
SubDirCcFlags -D_GNU_SOURCE -D_IEEE_LIBM ;
SubDirAsFlags -DMOTOROLA_SYNTAX ;
# Note: There is no *l() support yet. Our compiler says sizeof(long double) = 8,
# while there are only 96 and 128 bit implementation in glibc.
@ -111,6 +112,9 @@ local genericSources =
w_remainder.c w_remainderf.c # w_remainderl.c
w_scalb.c w_scalbf.c # w_scalbl.c
w_sinh.c w_sinhf.c # w_sinhl.c
# no asm for m68k in glibc
strlen.c
w_sqrt.c w_sqrtf.c # w_sqrtl.c
;
MergeObject posix_gnu_arch_$(TARGET_ARCH)_generic.o :
@ -119,15 +123,15 @@ MergeObject posix_gnu_arch_$(TARGET_ARCH)_generic.o :
MergeObject posix_gnu_arch_$(TARGET_ARCH)_other.o :
# add_n.S
# addmul_1.S
add_n.S
addmul_1.S
feholdexcpt.c fraiseexcpt.c fesetenv.c fesetround.c ftestexcept.c
# ldbl2mpn.c
# lshift.S rshift.S
# mul_1.S
lshift.S rshift.S
mul_1.S
# strlen.S
# sub_n.S
# submul_1.S
sub_n.S
submul_1.S
#
# e_sqrt.c e_sqrtf.c # e_sqrtl.c
# s_copysign.S s_copysignf.S # s_copysignl.S

View File

@ -0,0 +1,76 @@
/* mc68020 __mpn_add_n -- Add two limb vectors of the same length > 0 and store
sum in a third limb vector.
Copyright (C) 1992, 1994, 1996, 1998 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP 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 MP 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 MP Library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA. */
/*
INPUT PARAMETERS
res_ptr (sp + 4)
s1_ptr (sp + 8)
s2_ptr (sp + 16)
size (sp + 12)
*/
#include "sysdep.h"
#include "asm-syntax.h"
TEXT
ENTRY(__mpn_add_n)
/* Save used registers on the stack. */
movel R(d2),MEM_PREDEC(sp)
movel R(a2),MEM_PREDEC(sp)
/* Copy the arguments to registers. Better use movem? */
movel MEM_DISP(sp,12),R(a2)
movel MEM_DISP(sp,16),R(a0)
movel MEM_DISP(sp,20),R(a1)
movel MEM_DISP(sp,24),R(d2)
eorw #1,R(d2)
lsrl #1,R(d2)
bcc L(L1)
subql #1,R(d2) /* clears cy as side effect */
L(Loop:)
movel MEM_POSTINC(a0),R(d0)
movel MEM_POSTINC(a1),R(d1)
addxl R(d1),R(d0)
movel R(d0),MEM_POSTINC(a2)
L(L1:) movel MEM_POSTINC(a0),R(d0)
movel MEM_POSTINC(a1),R(d1)
addxl R(d1),R(d0)
movel R(d0),MEM_POSTINC(a2)
dbf R(d2),L(Loop) /* loop until 16 lsb of %4 == -1 */
subxl R(d0),R(d0) /* d0 <= -cy; save cy as 0 or -1 in d0 */
subl #0x10000,R(d2)
bcs L(L2)
addl R(d0),R(d0) /* restore cy */
bra L(Loop)
L(L2:)
negl R(d0)
/* Restore used registers from stack frame. */
movel MEM_POSTINC(sp),R(a2)
movel MEM_POSTINC(sp),R(d2)
rts
END(__mpn_add_n)

View File

@ -0,0 +1,80 @@
/* mc68020 __mpn_addmul_1 -- Multiply a limb vector with a limb and add
the result to a second limb vector.
Copyright (C) 1992, 1994, 1996, 1998 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP 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 MP 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 MP Library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA. */
/*
INPUT PARAMETERS
res_ptr (sp + 4)
s1_ptr (sp + 8)
s1_size (sp + 12)
s2_limb (sp + 16)
*/
#include "sysdep.h"
#include "asm-syntax.h"
TEXT
ENTRY(__mpn_addmul_1)
#define res_ptr a0
#define s1_ptr a1
#define s1_size d2
#define s2_limb d4
/* Save used registers on the stack. */
moveml R(d2)-R(d5),MEM_PREDEC(sp)
/* Copy the arguments to registers. Better use movem? */
movel MEM_DISP(sp,20),R(res_ptr)
movel MEM_DISP(sp,24),R(s1_ptr)
movel MEM_DISP(sp,28),R(s1_size)
movel MEM_DISP(sp,32),R(s2_limb)
eorw #1,R(s1_size)
clrl R(d1)
clrl R(d5)
lsrl #1,R(s1_size)
bcc L(L1)
subql #1,R(s1_size)
subl R(d0),R(d0) /* (d0,cy) <= (0,0) */
L(Loop:)
movel MEM_POSTINC(s1_ptr),R(d3)
mulul R(s2_limb),R(d1):R(d3)
addxl R(d0),R(d3)
addxl R(d5),R(d1)
addl R(d3),MEM_POSTINC(res_ptr)
L(L1:) movel MEM_POSTINC(s1_ptr),R(d3)
mulul R(s2_limb),R(d0):R(d3)
addxl R(d1),R(d3)
addxl R(d5),R(d0)
addl R(d3),MEM_POSTINC(res_ptr)
dbf R(s1_size),L(Loop)
addxl R(d5),R(d0)
subl #0x10000,R(s1_size)
bcc L(Loop)
/* Restore used registers from stack frame. */
moveml MEM_POSTINC(sp),R(d2)-R(d5)
rts
END(__mpn_addmul_1)

View File

@ -0,0 +1,147 @@
/* mc68020 __mpn_lshift -- Shift left a low-level natural-number integer.
Copyright (C) 1996, 1998 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP 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 MP 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 MP Library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA. */
/*
INPUT PARAMETERS
res_ptr (sp + 4)
s_ptr (sp + 8)
s_size (sp + 16)
cnt (sp + 12)
*/
#include "sysdep.h"
#include "asm-syntax.h"
#define res_ptr a1
#define s_ptr a0
#define s_size d6
#define cnt d4
TEXT
ENTRY(__mpn_lshift)
/* Save used registers on the stack. */
moveml R(d2)-R(d6)/R(a2),MEM_PREDEC(sp)
/* Copy the arguments to registers. */
movel MEM_DISP(sp,28),R(res_ptr)
movel MEM_DISP(sp,32),R(s_ptr)
movel MEM_DISP(sp,36),R(s_size)
movel MEM_DISP(sp,40),R(cnt)
moveql #1,R(d5)
cmpl R(d5),R(cnt)
bne L(Lnormal)
cmpl R(s_ptr),R(res_ptr)
bls L(Lspecial) /* jump if s_ptr >= res_ptr */
#if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020))
lea MEM_INDX1(s_ptr,s_size,l,4),R(a2)
#else /* not mc68020 */
movel R(s_size),R(d0)
asll #2,R(d0)
lea MEM_INDX(s_ptr,d0,l),R(a2)
#endif
cmpl R(res_ptr),R(a2)
bls L(Lspecial) /* jump if res_ptr >= s_ptr + s_size */
L(Lnormal:)
moveql #32,R(d5)
subl R(cnt),R(d5)
#if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020))
lea MEM_INDX1(s_ptr,s_size,l,4),R(s_ptr)
lea MEM_INDX1(res_ptr,s_size,l,4),R(res_ptr)
#else /* not mc68000 */
movel R(s_size),R(d0)
asll #2,R(d0)
addl R(s_size),R(s_ptr)
addl R(s_size),R(res_ptr)
#endif
movel MEM_PREDEC(s_ptr),R(d2)
movel R(d2),R(d0)
lsrl R(d5),R(d0) /* compute carry limb */
lsll R(cnt),R(d2)
movel R(d2),R(d1)
subql #1,R(s_size)
beq L(Lend)
lsrl #1,R(s_size)
bcs L(L1)
subql #1,R(s_size)
L(Loop:)
movel MEM_PREDEC(s_ptr),R(d2)
movel R(d2),R(d3)
lsrl R(d5),R(d3)
orl R(d3),R(d1)
movel R(d1),MEM_PREDEC(res_ptr)
lsll R(cnt),R(d2)
L(L1:)
movel MEM_PREDEC(s_ptr),R(d1)
movel R(d1),R(d3)
lsrl R(d5),R(d3)
orl R(d3),R(d2)
movel R(d2),MEM_PREDEC(res_ptr)
lsll R(cnt),R(d1)
dbf R(s_size),L(Loop)
subl #0x10000,R(s_size)
bcc L(Loop)
L(Lend:)
movel R(d1),MEM_PREDEC(res_ptr) /* store least significant limb */
/* Restore used registers from stack frame. */
moveml MEM_POSTINC(sp),R(d2)-R(d6)/R(a2)
rts
/* We loop from least significant end of the arrays, which is only
permissible if the source and destination don't overlap, since the
function is documented to work for overlapping source and destination. */
L(Lspecial:)
clrl R(d0) /* initialize carry */
eorw #1,R(s_size)
lsrl #1,R(s_size)
bcc L(LL1)
subql #1,R(s_size)
L(LLoop:)
movel MEM_POSTINC(s_ptr),R(d2)
addxl R(d2),R(d2)
movel R(d2),MEM_POSTINC(res_ptr)
L(LL1:)
movel MEM_POSTINC(s_ptr),R(d2)
addxl R(d2),R(d2)
movel R(d2),MEM_POSTINC(res_ptr)
dbf R(s_size),L(LLoop)
addxl R(d0),R(d0) /* save cy in lsb */
subl #0x10000,R(s_size)
bcs L(LLend)
lsrl #1,R(d0) /* restore cy */
bra L(LLoop)
L(LLend:)
/* Restore used registers from stack frame. */
moveml MEM_POSTINC(sp),R(d2)-R(d6)/R(a2)
rts
END(__mpn_lshift)

View File

@ -0,0 +1,87 @@
/* mc68020 __mpn_mul_1 -- Multiply a limb vector with a limb and store
the result in a second limb vector.
Copyright (C) 1992, 1994, 1996, 1998 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP 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 MP 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 MP Library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA. */
/*
INPUT PARAMETERS
res_ptr (sp + 4)
s1_ptr (sp + 8)
s1_size (sp + 12)
s2_limb (sp + 16)
*/
#include "sysdep.h"
#include "asm-syntax.h"
TEXT
ENTRY(__mpn_mul_1)
#define res_ptr a0
#define s1_ptr a1
#define s1_size d2
#define s2_limb d4
/* Save used registers on the stack. */
moveml R(d2)-R(d4),MEM_PREDEC(sp)
#if 0
movel R(d2),MEM_PREDEC(sp)
movel R(d3),MEM_PREDEC(sp)
movel R(d4),MEM_PREDEC(sp)
#endif
/* Copy the arguments to registers. Better use movem? */
movel MEM_DISP(sp,16),R(res_ptr)
movel MEM_DISP(sp,20),R(s1_ptr)
movel MEM_DISP(sp,24),R(s1_size)
movel MEM_DISP(sp,28),R(s2_limb)
eorw #1,R(s1_size)
clrl R(d1)
lsrl #1,R(s1_size)
bcc L(L1)
subql #1,R(s1_size)
subl R(d0),R(d0) /* (d0,cy) <= (0,0) */
L(Loop:)
movel MEM_POSTINC(s1_ptr),R(d3)
mulul R(s2_limb),R(d1):R(d3)
addxl R(d0),R(d3)
movel R(d3),MEM_POSTINC(res_ptr)
L(L1:) movel MEM_POSTINC(s1_ptr),R(d3)
mulul R(s2_limb),R(d0):R(d3)
addxl R(d1),R(d3)
movel R(d3),MEM_POSTINC(res_ptr)
dbf R(s1_size),L(Loop)
clrl R(d3)
addxl R(d3),R(d0)
subl #0x10000,R(s1_size)
bcc L(Loop)
/* Restore used registers from stack frame. */
moveml MEM_POSTINC(sp),R(d2)-R(d4)
#if 0
movel MEM_POSTINC(sp),R(d4)
movel MEM_POSTINC(sp),R(d3)
movel MEM_POSTINC(sp),R(d2)
#endif
rts
END(__mpn_mul_1)

View File

@ -0,0 +1,146 @@
/* mc68020 __mpn_rshift -- Shift right a low-level natural-number integer.
Copyright (C) 1996, 1998 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP 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 MP 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 MP Library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA. */
/*
INPUT PARAMETERS
res_ptr (sp + 4)
s_ptr (sp + 8)
s_size (sp + 16)
cnt (sp + 12)
*/
#include "sysdep.h"
#include "asm-syntax.h"
#define res_ptr a1
#define s_ptr a0
#define s_size d6
#define cnt d4
TEXT
ENTRY(__mpn_rshift)
/* Save used registers on the stack. */
moveml R(d2)-R(d6)/R(a2),MEM_PREDEC(sp)
/* Copy the arguments to registers. */
movel MEM_DISP(sp,28),R(res_ptr)
movel MEM_DISP(sp,32),R(s_ptr)
movel MEM_DISP(sp,36),R(s_size)
movel MEM_DISP(sp,40),R(cnt)
moveql #1,R(d5)
cmpl R(d5),R(cnt)
bne L(Lnormal)
cmpl R(res_ptr),R(s_ptr)
bls L(Lspecial) /* jump if res_ptr >= s_ptr */
#if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020))
lea MEM_INDX1(res_ptr,s_size,l,4),R(a2)
#else /* not mc68020 */
movel R(s_size),R(d0)
asll #2,R(d0)
lea MEM_INDX(res_ptr,d0,l),R(a2)
#endif
cmpl R(s_ptr),R(a2)
bls L(Lspecial) /* jump if s_ptr >= res_ptr + s_size */
L(Lnormal:)
moveql #32,R(d5)
subl R(cnt),R(d5)
movel MEM_POSTINC(s_ptr),R(d2)
movel R(d2),R(d0)
lsll R(d5),R(d0) /* compute carry limb */
lsrl R(cnt),R(d2)
movel R(d2),R(d1)
subql #1,R(s_size)
beq L(Lend)
lsrl #1,R(s_size)
bcs L(L1)
subql #1,R(s_size)
L(Loop:)
movel MEM_POSTINC(s_ptr),R(d2)
movel R(d2),R(d3)
lsll R(d5),R(d3)
orl R(d3),R(d1)
movel R(d1),MEM_POSTINC(res_ptr)
lsrl R(cnt),R(d2)
L(L1:)
movel MEM_POSTINC(s_ptr),R(d1)
movel R(d1),R(d3)
lsll R(d5),R(d3)
orl R(d3),R(d2)
movel R(d2),MEM_POSTINC(res_ptr)
lsrl R(cnt),R(d1)
dbf R(s_size),L(Loop)
subl #0x10000,R(s_size)
bcc L(Loop)
L(Lend:)
movel R(d1),MEM(res_ptr) /* store most significant limb */
/* Restore used registers from stack frame. */
moveml MEM_POSTINC(sp),R(d2)-R(d6)/R(a2)
rts
/* We loop from most significant end of the arrays, which is only
permissible if the source and destination don't overlap, since the
function is documented to work for overlapping source and destination. */
L(Lspecial:)
#if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020))
lea MEM_INDX1(s_ptr,s_size,l,4),R(s_ptr)
lea MEM_INDX1(res_ptr,s_size,l,4),R(res_ptr)
#else /* not mc68000 */
movel R(s_size),R(d0)
asll #2,R(d0)
addl R(s_size),R(s_ptr)
addl R(s_size),R(res_ptr)
#endif
clrl R(d0) /* initialize carry */
eorw #1,R(s_size)
lsrl #1,R(s_size)
bcc L(LL1)
subql #1,R(s_size)
L(LLoop:)
movel MEM_PREDEC(s_ptr),R(d2)
roxrl #1,R(d2)
movel R(d2),MEM_PREDEC(res_ptr)
L(LL1:)
movel MEM_PREDEC(s_ptr),R(d2)
roxrl #1,R(d2)
movel R(d2),MEM_PREDEC(res_ptr)
dbf R(s_size),L(LLoop)
roxrl #1,R(d0) /* save cy in msb */
subl #0x10000,R(s_size)
bcs L(LLend)
addl R(d0),R(d0) /* restore cy */
bra L(LLoop)
L(LLend:)
/* Restore used registers from stack frame. */
moveml MEM_POSTINC(sp),R(d2)-R(d6)/R(a2)
rts
END(__mpn_rshift)

View File

@ -0,0 +1,76 @@
/* mc68020 __mpn_sub_n -- Subtract two limb vectors of the same length > 0 and
store difference in a third limb vector.
Copyright (C) 1992, 1994, 1996, 1998 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP 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 MP 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 MP Library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA. */
/*
INPUT PARAMETERS
res_ptr (sp + 4)
s1_ptr (sp + 8)
s2_ptr (sp + 16)
size (sp + 12)
*/
#include "sysdep.h"
#include "asm-syntax.h"
TEXT
ENTRY(__mpn_sub_n)
/* Save used registers on the stack. */
movel R(d2),MEM_PREDEC(sp)
movel R(a2),MEM_PREDEC(sp)
/* Copy the arguments to registers. Better use movem? */
movel MEM_DISP(sp,12),R(a2)
movel MEM_DISP(sp,16),R(a0)
movel MEM_DISP(sp,20),R(a1)
movel MEM_DISP(sp,24),R(d2)
eorw #1,R(d2)
lsrl #1,R(d2)
bcc L(L1)
subql #1,R(d2) /* clears cy as side effect */
L(Loop:)
movel MEM_POSTINC(a0),R(d0)
movel MEM_POSTINC(a1),R(d1)
subxl R(d1),R(d0)
movel R(d0),MEM_POSTINC(a2)
L(L1:) movel MEM_POSTINC(a0),R(d0)
movel MEM_POSTINC(a1),R(d1)
subxl R(d1),R(d0)
movel R(d0),MEM_POSTINC(a2)
dbf R(d2),L(Loop) /* loop until 16 lsb of %4 == -1 */
subxl R(d0),R(d0) /* d0 <= -cy; save cy as 0 or -1 in d0 */
subl #0x10000,R(d2)
bcs L(L2)
addl R(d0),R(d0) /* restore cy */
bra L(Loop)
L(L2:)
negl R(d0)
/* Restore used registers from stack frame. */
movel MEM_POSTINC(sp),R(a2)
movel MEM_POSTINC(sp),R(d2)
rts
END(__mpn_sub_n)

View File

@ -0,0 +1,80 @@
/* mc68020 __mpn_submul_1 -- Multiply a limb vector with a limb and subtract
the result from a second limb vector.
Copyright (C) 1992, 1994, 1996, 1998 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP 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 MP 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 MP Library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA. */
/*
INPUT PARAMETERS
res_ptr (sp + 4)
s1_ptr (sp + 8)
s1_size (sp + 12)
s2_limb (sp + 16)
*/
#include "sysdep.h"
#include "asm-syntax.h"
TEXT
ENTRY(__mpn_submul_1)
#define res_ptr a0
#define s1_ptr a1
#define s1_size d2
#define s2_limb d4
/* Save used registers on the stack. */
moveml R(d2)-R(d5),MEM_PREDEC(sp)
/* Copy the arguments to registers. Better use movem? */
movel MEM_DISP(sp,20),R(res_ptr)
movel MEM_DISP(sp,24),R(s1_ptr)
movel MEM_DISP(sp,28),R(s1_size)
movel MEM_DISP(sp,32),R(s2_limb)
eorw #1,R(s1_size)
clrl R(d1)
clrl R(d5)
lsrl #1,R(s1_size)
bcc L(L1)
subql #1,R(s1_size)
subl R(d0),R(d0) /* (d0,cy) <= (0,0) */
L(Loop:)
movel MEM_POSTINC(s1_ptr),R(d3)
mulul R(s2_limb),R(d1):R(d3)
addxl R(d0),R(d3)
addxl R(d5),R(d1)
subl R(d3),MEM_POSTINC(res_ptr)
L(L1:) movel MEM_POSTINC(s1_ptr),R(d3)
mulul R(s2_limb),R(d0):R(d3)
addxl R(d1),R(d3)
addxl R(d5),R(d0)
subl R(d3),MEM_POSTINC(res_ptr)
dbf R(s1_size),L(Loop)
addxl R(d5),R(d0)
subl #0x10000,R(s1_size)
bcc L(Loop)
/* Restore used registers from stack frame. */
moveml MEM_POSTINC(sp),R(d2)-R(d5)
rts
END(__mpn_submul_1)

View File

@ -17,7 +17,7 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <sysdeps/generic/sysdep.h>
#include_next <sysdep.h>
#ifdef __ASSEMBLER__

View File

@ -114,7 +114,8 @@
*/
#if defined(__i386__) || defined(__ia64__) || defined(__alpha__) || \
defined(__sparc64__) || defined(__powerpc__) || defined(__POWERPC__)
defined(__sparc64__) || defined(__powerpc__) || defined(__POWERPC__) || \
defined(__m68k__) || defined(__M68K__)
# include <sys/types.h>
# if BYTE_ORDER == BIG_ENDIAN
# define IEEE_BIG_ENDIAN

View File

@ -0,0 +1,27 @@
/*
** Copyright 2001, Travis Geiselbrecht. All rights reserved.
** Distributed under the terms of the NewOS License.
*/
#warning M68K: optimize memcpy
#if 0
#define FUNCTION(x) .global x; .type x,@function; x
/* that should be enough for now */
.align 4
FUNCTION(memcpy):
/* void *memcpy(void *dest, const void *src, size_t count) */
move.l (4,%a7),%a1
move.l (8,%a7),%a0
move.l (12,%a7),%d0
addi.l #-1,%d0
blt _memcpy_out
_memcpy_loop:
move.b (%a0)+,(%a1)+
dbf %d0,_memcpy_loop
_memcpy_out:
move.l (4,%a7),%a0
move.l %a0,%d0
rts
#endif