about summary refs log tree commit diff
path: root/sysdeps/i386
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>1995-02-18 01:27:10 +0000
committerRoland McGrath <roland@gnu.org>1995-02-18 01:27:10 +0000
commit28f540f45bbacd939bfd07f213bcad2bf730b1bf (patch)
tree15f07c4c43d635959c6afee96bde71fb1b3614ee /sysdeps/i386
downloadglibc-28f540f45bbacd939bfd07f213bcad2bf730b1bf.tar.gz
glibc-28f540f45bbacd939bfd07f213bcad2bf730b1bf.tar.xz
glibc-28f540f45bbacd939bfd07f213bcad2bf730b1bf.zip
initial import
Diffstat (limited to 'sysdeps/i386')
-rw-r--r--sysdeps/i386/Implies1
-rw-r--r--sysdeps/i386/Makefile3
-rw-r--r--sysdeps/i386/__longjmp.c66
-rw-r--r--sysdeps/i386/abort.c28
-rw-r--r--sysdeps/i386/add_n.S94
-rw-r--r--sysdeps/i386/addmul_1.S75
-rw-r--r--sysdeps/i386/asm-syntax.h64
-rw-r--r--sysdeps/i386/bsd-_setjmp.S32
-rw-r--r--sysdeps/i386/bsd-setjmp.S32
-rw-r--r--sysdeps/i386/bytesex.h3
-rw-r--r--sysdeps/i386/bzero.c81
-rw-r--r--sysdeps/i386/ffs.c45
-rw-r--r--sysdeps/i386/i586/memcopy.h94
-rw-r--r--sysdeps/i386/jmp_buf.h9
-rw-r--r--sysdeps/i386/lshift.S84
-rw-r--r--sysdeps/i386/memchr.c48
-rw-r--r--sysdeps/i386/memcopy.h86
-rw-r--r--sysdeps/i386/memset.c83
-rw-r--r--sysdeps/i386/mul_1.S74
-rw-r--r--sysdeps/i386/rshift.S86
-rw-r--r--sysdeps/i386/setjmp.c55
-rw-r--r--sysdeps/i386/strlen.c36
-rw-r--r--sysdeps/i386/sub_n.S94
-rw-r--r--sysdeps/i386/submul_1.S75
24 files changed, 1348 insertions, 0 deletions
diff --git a/sysdeps/i386/Implies b/sysdeps/i386/Implies
new file mode 100644
index 0000000000..1610bfdc5b
--- /dev/null
+++ b/sysdeps/i386/Implies
@@ -0,0 +1 @@
+ieee754
diff --git a/sysdeps/i386/Makefile b/sysdeps/i386/Makefile
new file mode 100644
index 0000000000..29676784a2
--- /dev/null
+++ b/sysdeps/i386/Makefile
@@ -0,0 +1,3 @@
+# The mpn functions need a #define for asm syntax flavor.
+# Every i386 port in use uses gas syntax (I think).
+asm-CPPFLAGS := $(asm-CPPFLAGS) -DGAS_SYNTAX
diff --git a/sysdeps/i386/__longjmp.c b/sysdeps/i386/__longjmp.c
new file mode 100644
index 0000000000..65d6ec18ec
--- /dev/null
+++ b/sysdeps/i386/__longjmp.c
@@ -0,0 +1,66 @@
+/* Copyright (C) 1991, 1992, 1994, 1995 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#ifndef	__GNUC__
+  #error This file uses GNU C extensions; you must compile with GCC.
+#endif
+
+/* Put these global register declarations first, because we get an error if
+   they come after any function definition, including inlines which might
+   be in some header.  */
+
+#define REGS \
+  REG (bx);\
+  REG (si);\
+  REG (di);\
+  REG (bp);\
+  REG (sp)
+
+#define REG(xx) register long int xx asm (#xx)
+REGS;
+#undef	REG
+
+#include <ansidecl.h>
+#include <errno.h>
+#include <setjmp.h>
+#include <stdlib.h>
+
+/* Jump to the position specified by ENV, causing the
+   setjmp call there to return VAL, or 1 if VAL is 0.  */
+void
+DEFUN(__longjmp, (env, val),
+      __jmp_buf env AND int val)
+{
+  /* We specify explicit registers because, when not optimizing,
+     the compiler will generate code that uses the frame pointer
+     after it's been munged.  */
+
+  register CONST __typeof (env[0]) *e asm ("cx");
+  register int v asm ("ax");
+
+  e = env;
+  v = val == 0 ? 1 : val;
+
+#define	REG(xx)	xx = (long int) e->__##xx
+  REGS;
+
+  asm volatile ("jmp %*%0" : : "g" (e->__pc), "a" (v));
+
+  /* NOTREACHED */
+  abort ();
+}
diff --git a/sysdeps/i386/abort.c b/sysdeps/i386/abort.c
new file mode 100644
index 0000000000..28513fd1ec
--- /dev/null
+++ b/sysdeps/i386/abort.c
@@ -0,0 +1,28 @@
+/* Copyright (C) 1993, 1995 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <stdlib.h>
+
+/* Cause an abnormal program termination with core-dump.  */
+void
+DEFUN_VOID(abort)
+{
+  while (1)
+    asm ("hlt");
+}
diff --git a/sysdeps/i386/add_n.S b/sysdeps/i386/add_n.S
new file mode 100644
index 0000000000..f528976866
--- /dev/null
+++ b/sysdeps/i386/add_n.S
@@ -0,0 +1,94 @@
+/* i80386 __mpn_add_n -- Add two limb vectors of the same length > 0 and store
+sum in a third limb vector.
+
+Copyright (C) 1992, 1994 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 Library General Public License as published by
+the Free Software Foundation; either version 2 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 Library General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
+the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/*
+  INPUT PARAMETERS
+  res_ptr	(sp + 4)
+  s1_ptr	(sp + 8)
+  s2_ptr	(sp + 12)
+  size		(sp + 16)
+*/
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+.text
+	ALIGN (3)
+	.globl C_SYMBOL_NAME(__mpn_add_n)
+C_SYMBOL_NAME(__mpn_add_n:)
+	pushl %edi
+	pushl %esi
+
+	movl 12(%esp),%edi		/* res_ptr */
+	movl 16(%esp),%esi		/* s1_ptr */
+	movl 20(%esp),%edx		/* s2_ptr */
+	movl 24(%esp),%ecx		/* size */
+
+	movl	%ecx,%eax
+	shrl	$3,%ecx			/* compute count for unrolled loop */
+	negl	%eax
+	andl	$7,%eax			/* get index where to start loop */
+	jz	Loop			/* necessary special case for 0 */
+	incl	%ecx			/* adjust loop count */
+	shll	$2,%eax			/* adjustment for pointers... */
+	subl	%eax,%edi		/* ... since they are offset ... */
+	subl	%eax,%esi		/* ... by a constant when we ... */
+	subl	%eax,%edx		/* ... enter the loop */
+	shrl	$2,%eax			/* restore previous value */
+	leal	(Loop - 3)(%eax,%eax,8),%eax	/* calc start addr in loop */
+	jmp	*%eax			/* jump into loop */
+	ALIGN (3)
+Loop:	movl	(%esi),%eax
+	adcl	(%edx),%eax
+	movl	%eax,(%edi)
+	movl	4(%esi),%eax
+	adcl	4(%edx),%eax
+	movl	%eax,4(%edi)
+	movl	8(%esi),%eax
+	adcl	8(%edx),%eax
+	movl	%eax,8(%edi)
+	movl	12(%esi),%eax
+	adcl	12(%edx),%eax
+	movl	%eax,12(%edi)
+	movl	16(%esi),%eax
+	adcl	16(%edx),%eax
+	movl	%eax,16(%edi)
+	movl	20(%esi),%eax
+	adcl	20(%edx),%eax
+	movl	%eax,20(%edi)
+	movl	24(%esi),%eax
+	adcl	24(%edx),%eax
+	movl	%eax,24(%edi)
+	movl	28(%esi),%eax
+	adcl	28(%edx),%eax
+	movl	%eax,28(%edi)
+	leal	32(%edi),%edi
+	leal	32(%esi),%esi
+	leal	32(%edx),%edx
+	decl	%ecx
+	jnz	Loop
+
+	sbbl	%eax,%eax
+	negl	%eax
+
+	popl %esi
+	popl %edi
+	ret
diff --git a/sysdeps/i386/addmul_1.S b/sysdeps/i386/addmul_1.S
new file mode 100644
index 0000000000..3e166ec38b
--- /dev/null
+++ b/sysdeps/i386/addmul_1.S
@@ -0,0 +1,75 @@
+/* i80386 __mpn_addmul_1 -- Multiply a limb vector with a limb and add
+   the result to a second limb vector.
+
+Copyright (C) 1992, 1994 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 Library General Public License as published by
+the Free Software Foundation; either version 2 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 Library General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
+the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/*
+   INPUT PARAMETERS
+   res_ptr	(sp + 4)
+   s1_ptr	(sp + 8)
+   size		(sp + 12)
+   s2_limb	(sp + 16)
+*/
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+#define res_ptr edi
+#define s1_ptr esi
+#define size ecx
+#define s2_limb ebp
+
+	TEXT
+	ALIGN (3)
+	GLOBL	C_SYMBOL_NAME(__mpn_addmul_1)
+C_SYMBOL_NAME(__mpn_addmul_1:)
+
+	INSN1(push,l	,R(edi))
+	INSN1(push,l	,R(esi))
+	INSN1(push,l	,R(ebx))
+	INSN1(push,l	,R(ebp))
+
+	INSN2(mov,l	,R(res_ptr),MEM_DISP(esp,20))
+	INSN2(mov,l	,R(s1_ptr),MEM_DISP(esp,24))
+	INSN2(mov,l	,R(size),MEM_DISP(esp,28))
+	INSN2(mov,l	,R(s2_limb),MEM_DISP(esp,32))
+
+	INSN2(lea,l	,R(res_ptr),MEM_INDEX(res_ptr,size,4))
+	INSN2(lea,l	,R(s1_ptr),MEM_INDEX(s1_ptr,size,4))
+	INSN1(neg,l	,R(size))
+	INSN2(xor,l	,R(ebx),R(ebx))
+	ALIGN (3)
+Loop:
+	INSN2(mov,l	,R(eax),MEM_INDEX(s1_ptr,size,4))
+	INSN1(mul,l	,R(s2_limb))
+	INSN2(add,l	,R(eax),R(ebx))
+	INSN2(adc,l	,R(edx),$0)
+	INSN2(add,l	,MEM_INDEX(res_ptr,size,4),R(eax))
+	INSN2(adc,l	,R(edx),$0)
+	INSN2(mov,l	,R(ebx),R(edx))
+
+	INSN1(inc,l	,R(size))
+	INSN1(jnz,	,Loop)
+	INSN2(mov,l	,R(eax),R(ebx))
+
+	INSN1(pop,l	,R(ebp))
+	INSN1(pop,l	,R(ebx))
+	INSN1(pop,l	,R(esi))
+	INSN1(pop,l	,R(edi))
+	ret
diff --git a/sysdeps/i386/asm-syntax.h b/sysdeps/i386/asm-syntax.h
new file mode 100644
index 0000000000..6e287764dc
--- /dev/null
+++ b/sysdeps/i386/asm-syntax.h
@@ -0,0 +1,64 @@
+/* asm.h -- Definitions for x86 syntax variations.
+
+Copyright (C) 1992, 1994, 1995 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 Library General Public License as published by
+the Free Software Foundation; either version 2 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 Library General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
+the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#undef ALIGN
+
+#ifdef GAS_SYNTAX
+#define R(r) %r
+#define MEM(base)(base)
+#define MEM_DISP(base,displacement)displacement(R(base))
+#define MEM_INDEX(base,index,size)(R(base),R(index),size)
+#ifdef __STDC__
+#define INSN1(mnemonic,size_suffix,dst)mnemonic##size_suffix dst
+#define INSN2(mnemonic,size_suffix,dst,src)mnemonic##size_suffix src,dst
+#else
+#define INSN1(mnemonic,size_suffix,dst)mnemonic/**/size_suffix dst
+#define INSN2(mnemonic,size_suffix,dst,src)mnemonic/**/size_suffix src,dst
+#endif
+#define TEXT .text
+#define ALIGN(log) .align log
+#define GLOBL .globl
+#endif
+
+#ifdef INTEL_SYNTAX
+#define R(r) r
+#define MEM(base)[base]
+#define MEM_DISP(base,displacement)[base+(displacement)]
+#define MEM_INDEX(base,index,size)[base+index*size]
+#define INSN1(mnemonic,size_suffix,dst)mnemonic dst
+#define INSN2(mnemonic,size_suffix,dst,src)mnemonic dst,src
+#define TEXT .text
+#define ALIGN(log) .align log
+#define GLOBL .globl
+#endif
+
+#ifdef BROKEN_ALIGN
+#undef ALIGN
+#define ALIGN(log) .align log,0x90
+#endif
+
+#if !defined (NOLOG_ALIGN) && defined (HAVE_ELF)
+#define NOLOG_ALIGN
+#endif
+
+#ifdef NOLOG_ALIGN
+#undef ALIGN
+#define ALIGN(log) .align 1<<log
+#endif
diff --git a/sysdeps/i386/bsd-_setjmp.S b/sysdeps/i386/bsd-_setjmp.S
new file mode 100644
index 0000000000..372fc242b2
--- /dev/null
+++ b/sysdeps/i386/bsd-_setjmp.S
@@ -0,0 +1,32 @@
+/* BSD `_setjmp' entry point to `sigsetjmp (..., 0)'.  i386 version.
+Copyright (C) 1994 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+/* This just does a tail-call to `__sigsetjmp (ARG, 0)'.
+   We cannot do it in C because it must be a tail-call, so frame-unwinding
+   in setjmp doesn't clobber the state restored by longjmp.  */
+
+#include <sysdep.h>
+
+ENTRY (setjmp)
+	popl %eax		/* Pop return PC.  */
+	popl %ecx		/* Pop jmp_buf argument.  */
+	pushl $0		/* Push second argument of zero.  */
+	pushl %ecx		/* Push back first argument.  */
+	pushl %eax		/* Push back return PC.  */
+	jmp C_SYMBOL_NAME (__sigsetjmp)
diff --git a/sysdeps/i386/bsd-setjmp.S b/sysdeps/i386/bsd-setjmp.S
new file mode 100644
index 0000000000..238f0307ad
--- /dev/null
+++ b/sysdeps/i386/bsd-setjmp.S
@@ -0,0 +1,32 @@
+/* BSD `setjmp' entry point to `sigsetjmp (..., 1)'.  i386 version.
+Copyright (C) 1994 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+/* This just does a tail-call to `__sigsetjmp (ARG, 1)'.
+   We cannot do it in C because it must be a tail-call, so frame-unwinding
+   in setjmp doesn't clobber the state restored by longjmp.  */
+
+#include <sysdep.h>
+
+ENTRY (setjmp)
+	popl %eax		/* Pop return PC.  */
+	popl %ecx		/* Pop jmp_buf argument.  */
+	pushl $1		/* Push second argument of one.  */
+	pushl %ecx		/* Push back first argument.  */
+	pushl %eax		/* Push back return PC.  */
+	jmp C_SYMBOL_NAME (__sigsetjmp)
diff --git a/sysdeps/i386/bytesex.h b/sysdeps/i386/bytesex.h
new file mode 100644
index 0000000000..a5d6c5ea92
--- /dev/null
+++ b/sysdeps/i386/bytesex.h
@@ -0,0 +1,3 @@
+/* i386 is little-endian.  */
+
+#define __BYTE_ORDER __LITTLE_ENDIAN
diff --git a/sysdeps/i386/bzero.c b/sysdeps/i386/bzero.c
new file mode 100644
index 0000000000..659e54df22
--- /dev/null
+++ b/sysdeps/i386/bzero.c
@@ -0,0 +1,81 @@
+/* bzero -- set a block of memory to zero.
+   For Intel 80x86, x>=3.
+   Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
+   Contributed by Torbjorn Granlund (tege@sics.se).
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <string.h>
+#include <memcopy.h>
+
+#undef	bzero
+
+#ifdef	__GNUC__
+
+void
+DEFUN(bzero, (dstpp, len),
+      PTR dstpp AND size_t len)
+{
+  /* N.B.: This code is almost verbatim from memset.c.  */
+
+  unsigned long int dstp = (unsigned long int) dstpp;
+
+  /* This explicit register allocation
+     improves code very much indeed.  */
+  register op_t x asm("ax");
+
+  x = 0;
+
+  /* Clear the direction flag, so filling will move forward.  */
+  asm volatile("cld");
+
+  /* This threshold value is optimal.  */
+  if (len >= 12)
+    {
+      /* Adjust LEN for the bytes handled in the first loop.  */
+      len -= (-dstp) % OPSIZ;
+
+      /* There are at least some bytes to set.
+	 No need to test for LEN == 0 in this alignment loop.  */
+
+      /* Fill bytes until DSTP is aligned on a longword boundary.  */
+      asm volatile("rep\n"
+		   "stosb" /* %0, %2, %3 */ :
+		   "=D" (dstp) :
+		   "0" (dstp), "c" ((-dstp) % OPSIZ), "a" (x) :
+		   "cx");
+
+      /* Fill longwords.  */
+      asm volatile("rep\n"
+		   "stosl" /* %0, %2, %3 */ :
+		   "=D" (dstp) :
+		   "0" (dstp), "c" (len / OPSIZ), "a" (x) :
+		   "cx");
+      len %= OPSIZ;
+    }
+
+  /* Write the last few bytes.  */
+  asm volatile("rep\n"
+	       "stosb" /* %0, %2, %3 */ :
+	       "=D" (dstp) :
+	       "0" (dstp), "c" (len), "a" (x) :
+	       "cx");
+}
+
+#else
+#include <sysdeps/generic/bzero.c>
+#endif
diff --git a/sysdeps/i386/ffs.c b/sysdeps/i386/ffs.c
new file mode 100644
index 0000000000..1e21585874
--- /dev/null
+++ b/sysdeps/i386/ffs.c
@@ -0,0 +1,45 @@
+/* ffs -- find first set bit in a word, counted from least significant end.
+   For Intel 80x86, x>=3.
+   Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
+   Contributed by Torbjorn Granlund (tege@sics.se).
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <string.h>
+
+#undef	ffs
+
+#ifdef	__GNUC__
+
+int
+DEFUN(ffs, (x), int x)
+{
+  int cnt;
+  int tmp;
+
+  asm ("xorl %0,%0\n"		/* Set CNT to zero.  */
+       "bsfl %2,%1\n"		/* Count low bits in X and store in %1.  */
+       "jz nonzero\n"		/* Jump if OK, i.e. X was non-zero.  */
+       "leal 1(%1),%0\n"	/* Return bsfl-result plus one on %0.  */
+       "nonzero:" : "=&a" (cnt), "=r" (tmp) : "rm" (x));
+
+  return cnt;
+}
+
+#else
+#include <sysdeps/generic/ffs.c>
+#endif
diff --git a/sysdeps/i386/i586/memcopy.h b/sysdeps/i386/i586/memcopy.h
new file mode 100644
index 0000000000..a9bb9e7a40
--- /dev/null
+++ b/sysdeps/i386/i586/memcopy.h
@@ -0,0 +1,94 @@
+/* memcopy.h -- definitions for memory copy functions.  Pentium version.
+   Copyright (C) 1994 Free Software Foundation, Inc.
+   Contributed by Torbjorn Granlund (tege@sics.se).
+
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+/* Get the i386 definitions.  We will override some of them below.  */
+#include_next <memcopy.h>
+
+
+/* Written like this, the Pentium pipeline can execute the loop at a
+   sustained rate of 2 instructions/clock, or asymptotically 480
+   Mbytes/second at 60Mhz.  */
+
+#undef	WORD_COPY_FWD
+#define WORD_COPY_FWD(dst_bp, src_bp, nbytes_left, nbytes)		\
+  do									\
+    {									\
+      asm volatile ("subl	$32,%2\n"				\
+		    "js		2f\n"					\
+		    "1:\n"						\
+		    "movl	0(%1),%%eax\n"				\
+		    "movl	4(%1),%%edx\n"				\
+		    "movl	%%eax,0(%0)\n"				\
+		    "movl	%%edx,4(%0)\n"				\
+		    "movl	8(%1),%%eax\n"				\
+		    "movl	12(%1),%%edx\n"				\
+		    "movl	%%eax,8(%0)\n"				\
+		    "movl	%%edx,12(%0)\n"				\
+		    "movl	16(%1),%%eax\n"				\
+		    "movl	20(%1),%%edx\n"				\
+		    "movl	%%eax,16(%0)\n"				\
+		    "movl	%%edx,20(%0)\n"				\
+		    "movl	24(%1),%%eax\n"				\
+		    "movl	28(%1),%%edx\n"				\
+		    "movl	%%eax,24(%0)\n"				\
+		    "movl	%%edx,28(%0)\n"				\
+		    "addl	$32,%1\n"				\
+		    "addl	$32,%0\n"				\
+		    "subl	$32,%2\n"				\
+		    "jns	1b\n"					\
+		    "2: addl	$32,%2" :				\
+		    "=r" (dst_bp), "=r" (src_bp), "=r" (nbytes_left) :	\
+		    "0" (dst_bp), "1" (src_bp), "2" (nbytes) :		\
+		    "ax", "dx");					\
+    } while (0)
+
+#undef	WORD_COPY_BWD
+#define WORD_COPY_BWD(dst_ep, src_ep, nbytes_left, nbytes)		\
+  do									\
+    {									\
+      asm volatile ("subl	$32,%2\n"				\
+		    "js		2f\n"					\
+		    "1:\n"						\
+		    "movl	-4(%1),%%eax\n"				\
+		    "movl	-8(%1),%%edx\n"				\
+		    "movl	%%eax,-4(%0)\n"				\
+		    "movl	%%edx,-8(%0)\n"				\
+		    "movl	-12(%1),%%eax\n"			\
+		    "movl	-16(%1),%%edx\n"			\
+		    "movl	%%eax,-12(%0)\n"			\
+		    "movl	%%edx,-16(%0)\n"			\
+		    "movl	-20(%1),%%eax\n"			\
+		    "movl	-24(%1),%%edx\n"			\
+		    "movl	%%eax,-20(%0)\n"			\
+		    "movl	%%edx,-24(%0)\n"			\
+		    "movl	-28(%1),%%eax\n"			\
+		    "movl	-32(%1),%%edx\n"			\
+		    "movl	%%eax,-28(%0)\n"			\
+		    "movl	%%edx,-32(%0)\n"			\
+		    "subl	$32,%1\n"				\
+		    "subl	$32,%0\n"				\
+		    "subl	$32,%2\n"				\
+		    "jns	1b\n"					\
+		    "2: addl	$32,%2" :				\
+		    "=r" (dst_bp), "=r" (src_bp), "=r" (nbytes_left) :	\
+		    "0" (dst_bp), "1" (src_bp), "2" (nbytes) :		\
+		    "ax", "dx");					\
+    } while (0)
diff --git a/sysdeps/i386/jmp_buf.h b/sysdeps/i386/jmp_buf.h
new file mode 100644
index 0000000000..7686c4d278
--- /dev/null
+++ b/sysdeps/i386/jmp_buf.h
@@ -0,0 +1,9 @@
+/* Define the machine-dependent type `jmp_buf'.  Intel 386 version.  */
+
+typedef struct
+  {
+    long int __bx, __si, __di;
+    __ptr_t __bp;
+    __ptr_t __sp;
+    __ptr_t __pc;
+  } __jmp_buf[1];
diff --git a/sysdeps/i386/lshift.S b/sysdeps/i386/lshift.S
new file mode 100644
index 0000000000..ca48eda8ce
--- /dev/null
+++ b/sysdeps/i386/lshift.S
@@ -0,0 +1,84 @@
+/* i80386 __mpn_lshift -- 
+
+Copyright (C) 1992, 1994 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 Library General Public License as published by
+the Free Software Foundation; either version 2 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 Library General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
+the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/*
+  INPUT PARAMETERS
+  res_ptr	(sp + 4)
+  s_ptr		(sp + 8)
+  size		(sp + 12)
+  cnt		(sp + 16)
+*/
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+.text
+	ALIGN (3)
+	.globl C_SYMBOL_NAME(__mpn_lshift)
+C_SYMBOL_NAME(__mpn_lshift:)
+	pushl	%edi
+	pushl	%esi
+	pushl	%ebx
+
+	movl	16(%esp),%edi		/* res_ptr */
+	movl	20(%esp),%esi		/* s_ptr */
+	movl	24(%esp),%edx		/* size */
+	movl	28(%esp),%ecx		/* cnt */
+
+	subl	$4,%esi			/* adjust s_ptr */
+
+	movl	(%esi,%edx,4),%ebx	/* read most significant limb */
+	xorl	%eax,%eax
+	shldl	%cl,%ebx,%eax		/* compute carry limb */
+	decl	%edx
+	jz	Lend
+	pushl	%eax			/* push carry limb onto stack */
+	testb	$1,%edx
+	jnz	L1			/* enter loop in the middle */
+	movl	%ebx,%eax
+
+	ALIGN (3)
+Loop:	movl	(%esi,%edx,4),%ebx	/* load next lower limb */
+	shldl	%cl,%ebx,%eax		/* compute result limb */
+	movl	%eax,(%edi,%edx,4)	/* store it */
+	decl	%edx
+L1:	movl	(%esi,%edx,4),%eax
+	shldl	%cl,%eax,%ebx
+	movl	%ebx,(%edi,%edx,4)
+	decl	%edx
+	jnz	Loop
+
+	shll	%cl,%eax		/* compute least significant limb */
+	movl	%eax,(%edi)		/* store it */
+
+	popl	%eax			/* pop carry limb */
+
+	popl	%ebx
+	popl	%esi
+	popl	%edi
+	ret
+
+Lend:	shll	%cl,%ebx		/* compute least significant limb */
+	movl	%ebx,(%edi)		/* store it */
+
+	popl	%ebx
+	popl	%esi
+	popl	%edi
+	ret
diff --git a/sysdeps/i386/memchr.c b/sysdeps/i386/memchr.c
new file mode 100644
index 0000000000..ff0f8d9044
--- /dev/null
+++ b/sysdeps/i386/memchr.c
@@ -0,0 +1,48 @@
+/* memchr (str, ch, n) -- Return pointer to first occurrence of CH in STR less
+   than N.
+   For Intel 80x86, x>=3.
+   Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
+   Contributed by Torbjorn Granlund (tege@sics.se).
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <string.h>
+
+#ifdef	__GNUC__
+
+PTR
+DEFUN(memchr, (str, c, len),
+      CONST PTR str AND int c AND size_t len)
+{
+  PTR retval;
+  asm("cld\n"			/* Search forward.  */
+      "testl %1,%1\n"		/* Clear Z flag, to handle LEN == 0.  */
+      /* Some old versions of gas need `repne' instead of `repnz'.  */
+      "repnz\n"			/* Search for C in al.  */
+      "scasb\n"
+      "movl %2,%0\n"		/* Set %0 to 0 (without affecting Z flag).  */
+      "jnz done\n"		/* Jump if we found nothing equal to C.  */
+      "leal -1(%1),%0\n"	/* edi has been incremented.  Return edi-1.  */
+      "done:" :
+      "=a" (retval), "=D" (str), "=c" (len) :
+      "0" (c), "1" (str), "2" (len));
+  return retval;
+}
+
+#else
+#include <sysdeps/generic/memchr.c>
+#endif
diff --git a/sysdeps/i386/memcopy.h b/sysdeps/i386/memcopy.h
new file mode 100644
index 0000000000..506d3ea54d
--- /dev/null
+++ b/sysdeps/i386/memcopy.h
@@ -0,0 +1,86 @@
+/* memcopy.h -- definitions for memory copy functions.  i386 version.
+   Copyright (C) 1991 Free Software Foundation, Inc.
+   Contributed by Torbjorn Granlund (tege@sics.se).
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <sysdeps/generic/memcopy.h>
+
+#undef	OP_T_THRES
+#define	OP_T_THRES	8
+
+#undef	BYTE_COPY_FWD
+#define BYTE_COPY_FWD(dst_bp, src_bp, nbytes)				      \
+  asm volatile(/* Clear the direction flag, so copying goes forward.  */      \
+	       "cld\n"							      \
+	       /* Copy bytes.  */					      \
+	       "rep\n"							      \
+	       "movsb" :						      \
+	       "=D" (dst_bp), "=S" (src_bp) :				      \
+	       "0" (dst_bp), "1" (src_bp), "c" (nbytes) :		      \
+	       "cx")
+
+#undef	BYTE_COPY_BWD
+#define BYTE_COPY_BWD(dst_ep, src_ep, nbytes)				      \
+  do									      \
+    {									      \
+      asm volatile(/* Set the direction flag, so copying goes backwards.  */  \
+		   "std\n"						      \
+		   /* Copy bytes.  */					      \
+		   "rep\n"						      \
+		   "movsb\n"						      \
+		   /* Clear the dir flag.  Convention says it should be 0. */ \
+		   "cld" :						      \
+		   "=D" (dst_ep), "=S" (src_ep) :			      \
+		   "0" (dst_ep - 1), "1" (src_ep - 1), "c" (nbytes) :	      \
+		   "cx");						      \
+      dst_ep += 1;							      \
+      src_ep += 1;							      \
+    } while (0)
+
+#undef	WORD_COPY_FWD
+#define WORD_COPY_FWD(dst_bp, src_bp, nbytes_left, nbytes)		      \
+  do									      \
+    {									      \
+      asm volatile(/* Clear the direction flag, so copying goes forward.  */  \
+		   "cld\n"						      \
+		   /* Copy longwords.  */				      \
+		   "rep\n"						      \
+		   "movsl" :						      \
+		   "=D" (dst_bp), "=S" (src_bp) :			      \
+		   "0" (dst_bp), "1" (src_bp), "c" ((nbytes) / 4) :	      \
+		   "cx");						      \
+      (nbytes_left) = (nbytes) % 4;					      \
+    } while (0)
+
+#undef	WORD_COPY_BWD
+#define WORD_COPY_BWD(dst_ep, src_ep, nbytes_left, nbytes)		      \
+  do									      \
+    {									      \
+      asm volatile(/* Set the direction flag, so copying goes backwards.  */  \
+		   "std\n"						      \
+		   /* Copy longwords.  */				      \
+		   "rep\n"						      \
+		   "movsl\n"						      \
+		   /* Clear the dir flag.  Convention says it should be 0. */ \
+		   "cld" :						      \
+		   "=D" (dst_ep), "=S" (src_ep) :			      \
+		   "0" (dst_ep - 4), "1" (src_ep - 4), "c" ((nbytes) / 4) :   \
+		   "cx");						      \
+      dst_ep += 4;							      \
+      src_ep += 4;							      \
+      (nbytes_left) = (nbytes) % 4;					      \
+    } while (0)
diff --git a/sysdeps/i386/memset.c b/sysdeps/i386/memset.c
new file mode 100644
index 0000000000..2987445d4f
--- /dev/null
+++ b/sysdeps/i386/memset.c
@@ -0,0 +1,83 @@
+/* memset -- set a block of memory to some byte value.
+   For Intel 80x86, x>=3.
+   Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
+   Contributed by Torbjorn Granlund (tege@sics.se).
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <string.h>
+#include <memcopy.h>
+
+#ifdef	__GNUC__
+
+PTR
+DEFUN(memset, (dstpp, c, len),
+      PTR dstpp AND int c AND size_t len)
+{
+  unsigned long int dstp = (unsigned long int) dstpp;
+
+  /* This explicit register allocation
+     improves code very much indeed.  */
+  register op_t x asm("ax");
+
+  x = (unsigned char) c;
+
+  /* Clear the direction flag, so filling will move forward.  */
+  asm volatile("cld");
+
+  /* This threshold value is optimal.  */
+  if (len >= 12)
+    {
+      /* Fill X with four copies of the char we want to fill with.  */
+      x |= (x << 8);
+      x |= (x << 16);
+
+      /* Adjust LEN for the bytes handled in the first loop.  */
+      len -= (-dstp) % OPSIZ;
+
+      /* There are at least some bytes to set.
+	 No need to test for LEN == 0 in this alignment loop.  */
+
+      /* Fill bytes until DSTP is aligned on a longword boundary.  */
+      asm volatile("rep\n"
+		   "stosb" /* %0, %2, %3 */ :
+		   "=D" (dstp) :
+		   "0" (dstp), "c" ((-dstp) % OPSIZ), "a" (x) :
+		   "cx");
+
+      /* Fill longwords.  */
+      asm volatile("rep\n"
+		   "stosl" /* %0, %2, %3 */ :
+		   "=D" (dstp) :
+		   "0" (dstp), "c" (len / OPSIZ), "a" (x) :
+		   "cx");
+      len %= OPSIZ;
+    }
+
+  /* Write the last few bytes.  */
+  asm volatile("rep\n"
+	       "stosb" /* %0, %2, %3 */ :
+	       "=D" (dstp) :
+	       "0" (dstp), "c" (len), "a" (x) :
+	       "cx");
+
+  return dstpp;
+}
+
+#else
+#include <sysdeps/generic/memset.c>
+#endif
diff --git a/sysdeps/i386/mul_1.S b/sysdeps/i386/mul_1.S
new file mode 100644
index 0000000000..303a940f0b
--- /dev/null
+++ b/sysdeps/i386/mul_1.S
@@ -0,0 +1,74 @@
+/* i80386 __mpn_mul_1 -- Multiply a limb vector with a limb and store
+   the result in a second limb vector.
+
+Copyright (C) 1992, 1994 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 Library General Public License as published by
+the Free Software Foundation; either version 2 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 Library General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
+the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/*
+   INPUT PARAMETERS
+   res_ptr	(sp + 4)
+   s1_ptr	(sp + 8)
+   size		(sp + 12)
+   s2_limb	(sp + 16)
+*/
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+#define res_ptr edi
+#define s1_ptr esi
+#define size ecx
+#define s2_limb ebp
+
+	TEXT
+	ALIGN (3)
+	GLOBL	C_SYMBOL_NAME(__mpn_mul_1)
+C_SYMBOL_NAME(__mpn_mul_1:)
+
+	INSN1(push,l	,R(edi))
+	INSN1(push,l	,R(esi))
+	INSN1(push,l	,R(ebx))
+	INSN1(push,l	,R(ebp))
+
+	INSN2(mov,l	,R(res_ptr),MEM_DISP(esp,20))
+	INSN2(mov,l	,R(s1_ptr),MEM_DISP(esp,24))
+	INSN2(mov,l	,R(size),MEM_DISP(esp,28))
+	INSN2(mov,l	,R(s2_limb),MEM_DISP(esp,32))
+
+	INSN2(lea,l	,R(res_ptr),MEM_INDEX(res_ptr,size,4))
+	INSN2(lea,l	,R(s1_ptr),MEM_INDEX(s1_ptr,size,4))
+	INSN1(neg,l	,R(size))
+	INSN2(xor,l	,R(ebx),R(ebx))
+	ALIGN (3)
+Loop:
+	INSN2(mov,l	,R(eax),MEM_INDEX(s1_ptr,size,4))
+	INSN1(mul,l	,R(s2_limb))
+	INSN2(add,l	,R(eax),R(ebx))
+	INSN2(mov,l	,MEM_INDEX(res_ptr,size,4),R(eax))
+	INSN2(adc,l	,R(edx),$0)
+	INSN2(mov,l	,R(ebx),R(edx))
+
+	INSN1(inc,l	,R(size))
+	INSN1(jnz,	,Loop)
+	INSN2(mov,l	,R(eax),R(ebx))
+
+	INSN1(pop,l	,R(ebp))
+	INSN1(pop,l	,R(ebx))
+	INSN1(pop,l	,R(esi))
+	INSN1(pop,l	,R(edi))
+	ret
diff --git a/sysdeps/i386/rshift.S b/sysdeps/i386/rshift.S
new file mode 100644
index 0000000000..d4aa0b93e6
--- /dev/null
+++ b/sysdeps/i386/rshift.S
@@ -0,0 +1,86 @@
+/* i80386 __mpn_rshift -- 
+
+Copyright (C) 1992, 1994 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 Library General Public License as published by
+the Free Software Foundation; either version 2 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 Library General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
+the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/*
+  INPUT PARAMETERS
+  res_ptr	(sp + 4)
+  s_ptr		(sp + 8)
+  size		(sp + 12)
+  cnt		(sp + 16)
+*/
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+.text
+	ALIGN (3)
+	.globl C_SYMBOL_NAME(__mpn_rshift)
+C_SYMBOL_NAME(__mpn_rshift:)
+	pushl	%edi
+	pushl	%esi
+	pushl	%ebx
+
+	movl	16(%esp),%edi		/* res_ptr */
+	movl	20(%esp),%esi		/* s_ptr */
+	movl	24(%esp),%edx		/* size */
+	movl	28(%esp),%ecx		/* cnt */
+
+	leal	-4(%edi,%edx,4),%edi
+	leal	(%esi,%edx,4),%esi
+	negl	%edx
+
+	movl	(%esi,%edx,4),%ebx	/* read least significant limb */
+	xorl	%eax,%eax
+	shrdl	%cl,%ebx,%eax		/* compute carry limb */
+	incl	%edx
+	jz	Lend
+	pushl	%eax			/* push carry limb onto stack */
+	testb	$1,%edx
+	jnz	L1			/* enter loop in the middle */
+	movl	%ebx,%eax
+
+	ALIGN (3)
+Loop:	movl	(%esi,%edx,4),%ebx	/* load next higher limb */
+	shrdl	%cl,%ebx,%eax		/* compute result limb */
+	movl	%eax,(%edi,%edx,4)	/* store it */
+	incl	%edx
+L1:	movl	(%esi,%edx,4),%eax
+	shrdl	%cl,%eax,%ebx
+	movl	%ebx,(%edi,%edx,4)
+	incl	%edx
+	jnz	Loop
+
+	shrl	%cl,%eax		/* compute most significant limb */
+	movl	%eax,(%edi)		/* store it */
+
+	popl	%eax			/* pop carry limb */
+
+	popl	%ebx
+	popl	%esi
+	popl	%edi
+	ret
+
+Lend:	shrl	%cl,%ebx		/* compute most significant limb */
+	movl	%ebx,(%edi)		/* store it */
+
+	popl	%ebx
+	popl	%esi
+	popl	%edi
+	ret
diff --git a/sysdeps/i386/setjmp.c b/sysdeps/i386/setjmp.c
new file mode 100644
index 0000000000..fb8fc98659
--- /dev/null
+++ b/sysdeps/i386/setjmp.c
@@ -0,0 +1,55 @@
+/* Copyright (C) 1991, 1992, 1994 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+/* Put these global register declarations first, because we get an error if
+   they come after any function definition, including inlines which might
+   be in some header.  */
+
+#define REGS \
+  REG (bx);\
+  REG (si);\
+  REG (di)
+
+#define REG(xx) register long int xx asm (#xx)
+REGS;
+#undef	REG
+
+#include <errno.h>
+#include <setjmp.h>
+
+/* Save the current program position in ENV and return 0.  */
+int
+__sigsetjmp (jmp_buf env, int savemask)
+{
+  /* Save the general registers.  */
+#define	REG(xx)	env[0].__jmpbuf[0].__##xx = xx
+  REGS;
+#undef REG
+
+  /* Save the return PC.  */
+  env[0].__jmpbuf[0].__pc = ((void **) &env)[-1];
+
+  /* Save caller's FP, not our own.  */
+  env[0].__jmpbuf[0].__bp = ((void **) &env)[-2];
+
+  /* Save caller's SP, not our own.  */
+  env[0].__jmpbuf[0].__sp = (void *) &env;
+
+  /* Save the signal mask if requested.  */
+  return __sigjmp_save (env, savemask);
+}
diff --git a/sysdeps/i386/strlen.c b/sysdeps/i386/strlen.c
new file mode 100644
index 0000000000..3c1398b461
--- /dev/null
+++ b/sysdeps/i386/strlen.c
@@ -0,0 +1,36 @@
+/* strlen -- determine the length of a string.
+   For Intel 80x86, x>=3.
+   Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
+   Contributed by Torbjorn Granlund (tege@sics.se).
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <ansidecl.h>
+#include <string.h>
+
+size_t
+DEFUN(strlen, (str), CONST char *str)
+{
+  int cnt;
+
+  asm("cld\n"			/* Search forward.  */
+      /* Some old versions of gas need `repne' instead of `repnz'.  */
+      "repnz\n"			/* Look for a zero byte.  */
+      "scasb" /* %0, %1, %3 */ :
+      "=c" (cnt) : "D" (str), "0" (-1), "a" (0));
+
+  return -2 - cnt;
+}
diff --git a/sysdeps/i386/sub_n.S b/sysdeps/i386/sub_n.S
new file mode 100644
index 0000000000..a1630d4562
--- /dev/null
+++ b/sysdeps/i386/sub_n.S
@@ -0,0 +1,94 @@
+/* i80386 __mpn_sub_n -- Add two limb vectors of the same length > 0 and store
+   sum in a third limb vector.
+
+Copyright (C) 1992, 1994 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 Library General Public License as published by
+the Free Software Foundation; either version 2 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 Library General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
+the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/*
+  INPUT PARAMETERS
+  res_ptr	(sp + 4)
+  s1_ptr	(sp + 8)
+  s2_ptr	(sp + 12)
+  size		(sp + 16)
+*/
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+.text
+	ALIGN (3)
+	.globl C_SYMBOL_NAME(__mpn_sub_n)
+C_SYMBOL_NAME(__mpn_sub_n:)
+	pushl %edi
+	pushl %esi
+
+	movl 12(%esp),%edi	/* res_ptr */
+	movl 16(%esp),%esi	/* s1_ptr */
+	movl 20(%esp),%edx	/* s2_ptr */
+	movl 24(%esp),%ecx	/* size */
+
+	movl	%ecx,%eax
+	shrl	$3,%ecx			/* compute count for unrolled loop */
+	negl	%eax
+	andl	$7,%eax			/* get index where to start loop */
+	jz	Loop			/* necessary special case for 0 */
+	incl	%ecx			/* adjust loop count */
+	shll	$2,%eax			/* adjustment for pointers... */
+	subl	%eax,%edi		/* ... since they are offset ... */
+	subl	%eax,%esi		/* ... by a constant when we ... */
+	subl	%eax,%edx		/* ... enter the loop */
+	shrl	$2,%eax			/* restore previous value */
+	leal	(Loop - 3)(%eax,%eax,8),%eax	/* calc start addr in loop */
+	jmp	*%eax			/* jump into loop */
+	ALIGN (3)
+Loop:	movl	(%esi),%eax
+	sbbl	(%edx),%eax
+	movl	%eax,(%edi)
+	movl	4(%esi),%eax
+	sbbl	4(%edx),%eax
+	movl	%eax,4(%edi)
+	movl	8(%esi),%eax
+	sbbl	8(%edx),%eax
+	movl	%eax,8(%edi)
+	movl	12(%esi),%eax
+	sbbl	12(%edx),%eax
+	movl	%eax,12(%edi)
+	movl	16(%esi),%eax
+	sbbl	16(%edx),%eax
+	movl	%eax,16(%edi)
+	movl	20(%esi),%eax
+	sbbl	20(%edx),%eax
+	movl	%eax,20(%edi)
+	movl	24(%esi),%eax
+	sbbl	24(%edx),%eax
+	movl	%eax,24(%edi)
+	movl	28(%esi),%eax
+	sbbl	28(%edx),%eax
+	movl	%eax,28(%edi)
+	leal	32(%edi),%edi
+	leal	32(%esi),%esi
+	leal	32(%edx),%edx
+	decl	%ecx
+	jnz	Loop
+
+	sbbl	%eax,%eax
+	negl	%eax
+
+	popl %esi
+	popl %edi
+	ret
diff --git a/sysdeps/i386/submul_1.S b/sysdeps/i386/submul_1.S
new file mode 100644
index 0000000000..5ab78f6846
--- /dev/null
+++ b/sysdeps/i386/submul_1.S
@@ -0,0 +1,75 @@
+/* i80386 __mpn_submul_1 -- Multiply a limb vector with a limb and subtract
+   the result from a second limb vector.
+
+Copyright (C) 1992, 1994 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 Library General Public License as published by
+the Free Software Foundation; either version 2 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 Library General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
+the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/*
+   INPUT PARAMETERS
+   res_ptr	(sp + 4)
+   s1_ptr	(sp + 8)
+   size		(sp + 12)
+   s2_limb	(sp + 16)
+*/
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+#define res_ptr edi
+#define s1_ptr esi
+#define size ecx
+#define s2_limb ebp
+
+	TEXT
+	ALIGN (3)
+	GLOBL	C_SYMBOL_NAME(__mpn_submul_1)
+C_SYMBOL_NAME(__mpn_submul_1:)
+
+	INSN1(push,l	,R(edi))
+	INSN1(push,l	,R(esi))
+	INSN1(push,l	,R(ebx))
+	INSN1(push,l	,R(ebp))
+
+	INSN2(mov,l	,R(res_ptr),MEM_DISP(esp,20))
+	INSN2(mov,l	,R(s1_ptr),MEM_DISP(esp,24))
+	INSN2(mov,l	,R(size),MEM_DISP(esp,28))
+	INSN2(mov,l	,R(s2_limb),MEM_DISP(esp,32))
+
+	INSN2(lea,l	,R(res_ptr),MEM_INDEX(res_ptr,size,4))
+	INSN2(lea,l	,R(s1_ptr),MEM_INDEX(s1_ptr,size,4))
+	INSN1(neg,l	,R(size))
+	INSN2(xor,l	,R(ebx),R(ebx))
+	ALIGN (3)
+Loop:
+	INSN2(mov,l	,R(eax),MEM_INDEX(s1_ptr,size,4))
+	INSN1(mul,l	,R(s2_limb))
+	INSN2(add,l	,R(eax),R(ebx))
+	INSN2(adc,l	,R(edx),$0)
+	INSN2(sub,l	,MEM_INDEX(res_ptr,size,4),R(eax))
+	INSN2(adc,l	,R(edx),$0)
+	INSN2(mov,l	,R(ebx),R(edx))
+
+	INSN1(inc,l	,R(size))
+	INSN1(jnz,	,Loop)
+	INSN2(mov,l	,R(eax),R(ebx))
+
+	INSN1(pop,l	,R(ebp))
+	INSN1(pop,l	,R(ebx))
+	INSN1(pop,l	,R(esi))
+	INSN1(pop,l	,R(edi))
+	ret