1258791Spjd/* Pentium __mpn_submul_1 -- Multiply a limb vector with a limb and subtract
2258791Spjd   the result from a second limb vector.
3258791Spjd   Copyright (C) 1992, 94, 96, 97, 98, 00 Free Software Foundation, Inc.
4258791Spjd   This file is part of the GNU MP Library.
5258791Spjd
6258791Spjd   The GNU MP Library is free software; you can redistribute it and/or modify
7258791Spjd   it under the terms of the GNU Lesser General Public License as published by
8258791Spjd   the Free Software Foundation; either version 2.1 of the License, or (at your
9258791Spjd   option) any later version.
10258791Spjd
11258791Spjd   The GNU MP Library is distributed in the hope that it will be useful, but
12258791Spjd   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13258791Spjd   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
14258791Spjd   License for more details.
15258791Spjd
16258791Spjd   You should have received a copy of the GNU Lesser General Public License
17258791Spjd   along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
18258791Spjd   the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
19258791Spjd   MA 02111-1307, USA. */
20258791Spjd
21258791Spjd#include "sysdep.h"
22258791Spjd#include "asm-syntax.h"
23258791Spjd#include "bp-sym.h"
24258791Spjd#include "bp-asm.h"
25258791Spjd
26258791Spjd#define PARMS	LINKAGE+16	/* space for 4 saved regs */
27258791Spjd#define RES	PARMS
28258791Spjd#define S1	RES+PTR_SIZE
29258791Spjd#define SIZE	S1+PTR_SIZE
30258791Spjd#define S2LIMB	SIZE+4
31258791Spjd
32258791Spjd#define res_ptr edi
33258791Spjd#define s1_ptr esi
34258791Spjd#define size ecx
35258791Spjd#define s2_limb ebx
36258791Spjd
37258791Spjd	.text
38258791SpjdENTRY (BP_SYM (__mpn_submul_1))
39258791Spjd	ENTER
40258791Spjd
41258791Spjd	pushl	%edi
42258791Spjd	pushl	%esi
43258791Spjd	pushl	%ebp
44258791Spjd	pushl	%ebx
45258791Spjd
46258791Spjd	movl	RES(%esp), %res_ptr
47258791Spjd	movl	S1(%esp), %s1_ptr
48258791Spjd	movl	SIZE(%esp), %size
49258791Spjd	movl	S2LIMB(%esp), %s2_limb
50258791Spjd#if __BOUNDED_POINTERS__
51258791Spjd	shll	$2, %sizeP	/* convert limbs to bytes */
52258791Spjd	CHECK_BOUNDS_BOTH_WIDE (%res_ptr, RES(%esp), %sizeP)
53258791Spjd	CHECK_BOUNDS_BOTH_WIDE (%s1_ptr, S1(%esp), %sizeP)
54258791Spjd	shrl	$2, %sizeP
55258791Spjd#endif
56258791Spjd	leal	(%res_ptr,%size,4), %res_ptr
57258791Spjd	leal	(%s1_ptr,%size,4), %s1_ptr
58258791Spjd	negl	%size
59258791Spjd	xorl	%ebp, %ebp
60258791Spjd	ALIGN (3)
61258791Spjd
62258791SpjdL(oop):	adcl	$0, %ebp
63258791Spjd	movl	(%s1_ptr,%size,4), %eax
64258791Spjd
65258791Spjd	mull	%s2_limb
66258791Spjd
67258791Spjd	addl	%ebp, %eax
68258791Spjd	movl	(%res_ptr,%size,4), %ebp
69258791Spjd
70258791Spjd	adcl	$0, %edx
71258791Spjd	subl	%eax, %ebp
72258791Spjd
73258791Spjd	movl	%ebp, (%res_ptr,%size,4)
74258791Spjd	incl	%size
75258791Spjd
76258791Spjd	movl	%edx, %ebp
77258791Spjd	jnz	L(oop)
78258791Spjd
79258791Spjd	adcl	$0, %ebp
80258791Spjd	movl	%ebp, %eax
81258791Spjd	popl	%ebx
82258791Spjd	popl	%ebp
83258791Spjd	popl	%esi
84258791Spjd	popl	%edi
85258791Spjd
86258791Spjd	LEAVE
87258791Spjd	ret
88258791Spjd#undef size
89258791SpjdEND (BP_SYM (__mpn_submul_1))
90258791Spjd