1/* i80386 __mpn_rshift --
2   Copyright (C) 1992-2022 Free Software Foundation, Inc.
3   This file is part of the GNU MP Library.
4
5   The GNU MP Library is free software; you can redistribute it and/or modify
6   it under the terms of the GNU Lesser General Public License as published by
7   the Free Software Foundation; either version 2.1 of the License, or (at your
8   option) any later version.
9
10   The GNU MP Library is distributed in the hope that it will be useful, but
11   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
13   License for more details.
14
15   You should have received a copy of the GNU Lesser General Public License
16   along with the GNU MP Library; see the file COPYING.LIB.  If not,
17   see <https://www.gnu.org/licenses/>.  */
18
19#include "sysdep.h"
20#include "asm-syntax.h"
21
22#define PARMS	4+12		/* space for 3 saved regs */
23#define RES	PARMS
24#define S	RES+4
25#define SIZE	S+4
26#define CNT	SIZE+4
27
28	.text
29ENTRY (__mpn_rshift)
30
31	pushl	%edi
32	cfi_adjust_cfa_offset (4)
33	pushl	%esi
34	cfi_adjust_cfa_offset (4)
35	pushl	%ebx
36	cfi_adjust_cfa_offset (4)
37
38	movl	RES(%esp),%edi
39	cfi_rel_offset (edi, 8)
40	movl	S(%esp),%esi
41	cfi_rel_offset (esi, 4)
42	movl	SIZE(%esp),%edx
43	movl	CNT(%esp),%ecx
44	leal	-4(%edi,%edx,4),%edi
45	leal	(%esi,%edx,4),%esi
46	negl	%edx
47
48	movl	(%esi,%edx,4),%ebx	/* read least significant limb */
49	cfi_rel_offset (ebx, 0)
50	cfi_remember_state
51	xorl	%eax,%eax
52	shrdl	%cl,%ebx,%eax		/* compute carry limb */
53	incl	%edx
54	jz	L(end)
55	pushl	%eax			/* push carry limb onto stack */
56	cfi_adjust_cfa_offset (4)
57	testb	$1,%dl
58	jnz	L(1)			/* enter loop in the middle */
59	movl	%ebx,%eax
60
61	ALIGN (3)
62L(oop):	movl	(%esi,%edx,4),%ebx	/* load next higher limb */
63	shrdl	%cl,%ebx,%eax		/* compute result limb */
64	movl	%eax,(%edi,%edx,4)	/* store it */
65	incl	%edx
66L(1):	movl	(%esi,%edx,4),%eax
67	shrdl	%cl,%eax,%ebx
68	movl	%ebx,(%edi,%edx,4)
69	incl	%edx
70	jnz	L(oop)
71
72	shrl	%cl,%eax		/* compute most significant limb */
73	movl	%eax,(%edi)		/* store it */
74
75	popl	%eax			/* pop carry limb */
76	cfi_adjust_cfa_offset (-4)
77
78	popl	%ebx
79	cfi_adjust_cfa_offset (-4)
80	cfi_restore (ebx)
81	popl	%esi
82	cfi_adjust_cfa_offset (-4)
83	cfi_restore (esi)
84	popl	%edi
85	cfi_adjust_cfa_offset (-4)
86	cfi_restore (edi)
87
88	ret
89
90	cfi_restore_state
91L(end):	shrl	%cl,%ebx		/* compute most significant limb */
92	movl	%ebx,(%edi)		/* store it */
93
94	popl	%ebx
95	cfi_adjust_cfa_offset (-4)
96	cfi_restore (ebx)
97	popl	%esi
98	cfi_adjust_cfa_offset (-4)
99	cfi_restore (esi)
100	popl	%edi
101	cfi_adjust_cfa_offset (-4)
102	cfi_restore (edi)
103
104	ret
105END (__mpn_rshift)
106