1/* i80386 mul_1 -- Multiply a limb vector with a limb and store
2 *			 the result in a second limb vector.
3 *      Copyright (C) 1992, 1994, 1998,
4 *                    2001, 2002 Free Software Foundation, Inc.
5 *
6 * This file is part of Libgcrypt.
7 *
8 * Libgcrypt is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License as
10 * published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * Libgcrypt is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 * GNU Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
21 *
22 * Note: This code is heavily based on the GNU MP Library.
23 *	 Actually it's the same code with only minor changes in the
24 *	 way the data is stored; this is to support the abstraction
25 *	 of an optional secure memory allocation which may be used
26 *	 to avoid revealing of sensitive data due to paging etc.
27 */
28
29
30#include "sysdep.h"
31#include "asm-syntax.h"
32
33
34/*******************
35 * mpi_limb_t
36 * _gcry_mpih_mul_1( mpi_ptr_t res_ptr,	(sp + 4)
37 *		  mpi_ptr_t s1_ptr,	(sp + 8)
38 *		  mpi_size_t s1_size,	(sp + 12)
39 *		  mpi_limb_t s2_limb)	(sp + 16)
40 */
41
42#define res_ptr edi
43#define s1_ptr	esi
44#define size	ecx
45#define s2_limb ebp
46
47	TEXT
48	ALIGN (2)
49	GLOBL	C_SYMBOL_NAME(_gcry_mpih_mul_1)
50C_SYMBOL_NAME(_gcry_mpih_mul_1:)
51
52	CFI_STARTPROC()
53	INSN1(push,l	,R(edi))
54	CFI_PUSH(%edi)
55	INSN1(push,l	,R(esi))
56	CFI_PUSH(%esi)
57	INSN1(push,l	,R(ebx))
58	CFI_PUSH(%ebx)
59	INSN1(push,l	,R(ebp))
60	CFI_PUSH(%ebp)
61
62	INSN2(mov,l	,R(res_ptr),MEM_DISP(esp,20))
63	INSN2(mov,l	,R(s1_ptr),MEM_DISP(esp,24))
64	INSN2(mov,l	,R(size),MEM_DISP(esp,28))
65	INSN2(mov,l	,R(s2_limb),MEM_DISP(esp,32))
66
67	INSN2(lea,l	,R(res_ptr),MEM_INDEX(res_ptr,size,4))
68	INSN2(lea,l	,R(s1_ptr),MEM_INDEX(s1_ptr,size,4))
69	INSN1(neg,l	,R(size))
70	INSN2(xor,l	,R(ebx),R(ebx))
71	ALIGN (2)
72Loop:
73	INSN2(mov,l	,R(eax),MEM_INDEX(s1_ptr,size,4))
74	INSN1(mul,l	,R(s2_limb))
75	INSN2(add,l	,R(eax),R(ebx))
76	INSN2(mov,l	,MEM_INDEX(res_ptr,size,4),R(eax))
77	INSN2(adc,l	,R(edx),$0)
78	INSN2(mov,l	,R(ebx),R(edx))
79
80	INSN1(inc,l	,R(size))
81	INSN1(jnz,	,Loop)
82	INSN2(mov,l	,R(eax),R(ebx))
83
84	INSN1(pop,l	,R(ebp))
85	CFI_POP(%ebp)
86	INSN1(pop,l	,R(ebx))
87	CFI_POP(%ebx)
88	INSN1(pop,l	,R(esi))
89	CFI_POP(%esi)
90	INSN1(pop,l	,R(edi))
91	CFI_POP(%edi)
92	ret
93	CFI_ENDPROC()
94
95