1 | /* mc68020 __mpn_sub_n -- Subtract two limb vectors of the same length > 0 and |
2 | store difference in a third limb vector. |
3 | |
4 | Copyright (C) 1992-2024 Free Software Foundation, Inc. |
5 | |
6 | This file is part of the GNU MP Library. |
7 | |
8 | The GNU MP Library is free software; you can redistribute it and/or modify |
9 | it under the terms of the GNU Lesser General Public License as published by |
10 | the Free Software Foundation; either version 2.1 of the License, or (at your |
11 | option) any later version. |
12 | |
13 | The GNU MP Library is distributed in the hope that it will be useful, but |
14 | WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
15 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public |
16 | License for more details. |
17 | |
18 | You should have received a copy of the GNU Lesser General Public License |
19 | along with the GNU MP Library. If not, see <https://www.gnu.org/licenses/>. */ |
20 | |
21 | /* |
22 | INPUT PARAMETERS |
23 | res_ptr (sp + 4) |
24 | s1_ptr (sp + 8) |
25 | s2_ptr (sp + 16) |
26 | size (sp + 12) |
27 | */ |
28 | |
29 | #include "sysdep.h" |
30 | #include "asm-syntax.h" |
31 | |
32 | TEXT |
33 | ENTRY(__mpn_sub_n) |
34 | /* Save used registers on the stack. */ |
35 | movel R(d2),MEM_PREDEC(sp) |
36 | cfi_adjust_cfa_offset (4) |
37 | movel R(a2),MEM_PREDEC(sp) |
38 | cfi_adjust_cfa_offset (4) |
39 | cfi_rel_offset (R(d2), 4) |
40 | cfi_rel_offset (R(a2), 0) |
41 | |
42 | /* Copy the arguments to registers. Better use movem? */ |
43 | movel MEM_DISP(sp,12),R(a2) |
44 | movel MEM_DISP(sp,16),R(a0) |
45 | movel MEM_DISP(sp,20),R(a1) |
46 | movel MEM_DISP(sp,24),R(d2) |
47 | |
48 | eorw #1,R(d2) |
49 | lsrl #1,R(d2) |
50 | bcc L(L1) |
51 | subql #1,R(d2) /* clears cy as side effect */ |
52 | |
53 | L(Loop:) |
54 | movel MEM_POSTINC(a0),R(d0) |
55 | movel MEM_POSTINC(a1),R(d1) |
56 | subxl R(d1),R(d0) |
57 | movel R(d0),MEM_POSTINC(a2) |
58 | L(L1:) movel MEM_POSTINC(a0),R(d0) |
59 | movel MEM_POSTINC(a1),R(d1) |
60 | subxl R(d1),R(d0) |
61 | movel R(d0),MEM_POSTINC(a2) |
62 | |
63 | dbf R(d2),L(Loop) /* loop until 16 lsb of %4 == -1 */ |
64 | subxl R(d0),R(d0) /* d0 <= -cy; save cy as 0 or -1 in d0 */ |
65 | subl #0x10000,R(d2) |
66 | bcs L(L2) |
67 | addl R(d0),R(d0) /* restore cy */ |
68 | bra L(Loop) |
69 | |
70 | L(L2:) |
71 | negl R(d0) |
72 | |
73 | /* Restore used registers from stack frame. */ |
74 | movel MEM_POSTINC(sp),R(a2) |
75 | cfi_adjust_cfa_offset (-4) |
76 | cfi_restore (R(a2)) |
77 | movel MEM_POSTINC(sp),R(d2) |
78 | cfi_adjust_cfa_offset (-4) |
79 | cfi_restore (R(d2)) |
80 | |
81 | rts |
82 | END(__mpn_sub_n) |
83 | |