1 | /* i80386 __mpn_sub_n -- Add two limb vectors of the same length > 0 and store |
2 | sum in a third limb vector. |
3 | Copyright (C) 1992-2024 Free Software Foundation, Inc. |
4 | This file is part of the GNU MP Library. |
5 | |
6 | The GNU MP Library is free software; you can redistribute it and/or modify |
7 | it under the terms of the GNU Lesser General Public License as published by |
8 | the Free Software Foundation; either version 2.1 of the License, or (at your |
9 | option) any later version. |
10 | |
11 | The GNU MP Library is distributed in the hope that it will be useful, but |
12 | WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
13 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public |
14 | License for more details. |
15 | |
16 | You should have received a copy of the GNU Lesser General Public License |
17 | along with the GNU MP Library; see the file COPYING.LIB. If not, |
18 | see <https://www.gnu.org/licenses/>. */ |
19 | |
20 | #include <sysdep.h> |
21 | #include "asm-syntax.h" |
22 | |
23 | #define PARMS 4+8 /* space for 2 saved regs */ |
24 | #define RES PARMS |
25 | #define S1 RES+4 |
26 | #define S2 S1+4 |
27 | #define SIZE S2+4 |
28 | |
29 | .text |
30 | ENTRY (__mpn_sub_n) |
31 | |
32 | pushl %edi |
33 | cfi_adjust_cfa_offset (4) |
34 | pushl %esi |
35 | cfi_adjust_cfa_offset (4) |
36 | |
37 | movl RES(%esp),%edi |
38 | cfi_rel_offset (edi, 4) |
39 | movl S1(%esp),%esi |
40 | cfi_rel_offset (esi, 0) |
41 | movl S2(%esp),%edx |
42 | movl SIZE(%esp),%ecx |
43 | movl %ecx,%eax |
44 | shrl $3,%ecx /* compute count for unrolled loop */ |
45 | negl %eax |
46 | andl $7,%eax /* get index where to start loop */ |
47 | jz L(oop) /* necessary special case for 0 */ |
48 | incl %ecx /* adjust loop count */ |
49 | shll $2,%eax /* adjustment for pointers... */ |
50 | subl %eax,%edi /* ... since they are offset ... */ |
51 | subl %eax,%esi /* ... by a constant when we ... */ |
52 | subl %eax,%edx /* ... enter the loop */ |
53 | shrl $2,%eax /* restore previous value */ |
54 | #ifdef PIC |
55 | /* Calculate start address in loop for PIC. Due to limitations in some |
56 | assemblers, Loop-L0-3 cannot be put into the leal */ |
57 | call L(0) |
58 | cfi_adjust_cfa_offset (4) |
59 | L(0): leal (%eax,%eax,8),%eax |
60 | addl (%esp),%eax |
61 | addl $(L(oop)-L(0)-3),%eax |
62 | addl $4,%esp |
63 | cfi_adjust_cfa_offset (-4) |
64 | #else |
65 | /* Calculate start address in loop for non-PIC. */ |
66 | leal (L(oop) - 3)(%eax,%eax,8),%eax |
67 | #endif |
68 | jmp *%eax /* jump into loop */ |
69 | ALIGN (3) |
70 | L(oop): movl (%esi),%eax |
71 | sbbl (%edx),%eax |
72 | movl %eax,(%edi) |
73 | movl 4(%esi),%eax |
74 | sbbl 4(%edx),%eax |
75 | movl %eax,4(%edi) |
76 | movl 8(%esi),%eax |
77 | sbbl 8(%edx),%eax |
78 | movl %eax,8(%edi) |
79 | movl 12(%esi),%eax |
80 | sbbl 12(%edx),%eax |
81 | movl %eax,12(%edi) |
82 | movl 16(%esi),%eax |
83 | sbbl 16(%edx),%eax |
84 | movl %eax,16(%edi) |
85 | movl 20(%esi),%eax |
86 | sbbl 20(%edx),%eax |
87 | movl %eax,20(%edi) |
88 | movl 24(%esi),%eax |
89 | sbbl 24(%edx),%eax |
90 | movl %eax,24(%edi) |
91 | movl 28(%esi),%eax |
92 | sbbl 28(%edx),%eax |
93 | movl %eax,28(%edi) |
94 | leal 32(%edi),%edi |
95 | leal 32(%esi),%esi |
96 | leal 32(%edx),%edx |
97 | decl %ecx |
98 | jnz L(oop) |
99 | |
100 | sbbl %eax,%eax |
101 | negl %eax |
102 | |
103 | popl %esi |
104 | cfi_adjust_cfa_offset (-4) |
105 | cfi_restore (esi) |
106 | popl %edi |
107 | cfi_adjust_cfa_offset (-4) |
108 | cfi_restore (edi) |
109 | |
110 | ret |
111 | END (__mpn_sub_n) |
112 | |