Annotation of OpenXM_contrib/gmp/mpn/m68k/lshift.S, Revision 1.1.1.1
1.1 maekawa 1: /* mc68020 __mpn_lshift -- Shift left a low-level natural-number integer.
2:
3: Copyright (C) 1996 Free Software Foundation, Inc.
4:
5: This file is part of the GNU MP Library.
6:
7: The GNU MP Library is free software; you can redistribute it and/or modify
8: it under the terms of the GNU Library General Public License as published by
9: the Free Software Foundation; either version 2 of the License, or (at your
10: option) any later version.
11:
12: The GNU MP Library is distributed in the hope that it will be useful, but
13: WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14: or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
15: License for more details.
16:
17: You should have received a copy of the GNU Library General Public License
18: along with the GNU MP Library; see the file COPYING.LIB. If not, write to
19: the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20: MA 02111-1307, USA. */
21:
22: /*
23: INPUT PARAMETERS
24: res_ptr (sp + 4)
25: s_ptr (sp + 8)
26: s_size (sp + 16)
27: cnt (sp + 12)
28: */
29:
30: #include "sysdep.h"
31: #include "asm-syntax.h"
32:
33: #define res_ptr a1
34: #define s_ptr a0
35: #define s_size d6
36: #define cnt d4
37:
38: TEXT
39: ALIGN
40: GLOBL C_SYMBOL_NAME(__mpn_lshift)
41:
42: C_SYMBOL_NAME(__mpn_lshift:)
43: PROLOG(__mpn_lshift)
44:
45: /* Save used registers on the stack. */
46: moveml R(d2)-R(d6)/R(a2),MEM_PREDEC(sp)
47:
48: /* Copy the arguments to registers. */
49: movel MEM_DISP(sp,28),R(res_ptr)
50: movel MEM_DISP(sp,32),R(s_ptr)
51: movel MEM_DISP(sp,36),R(s_size)
52: movel MEM_DISP(sp,40),R(cnt)
53:
54: moveql #1,R(d5)
55: cmpl R(d5),R(cnt)
56: bne L(Lnormal)
57: cmpl R(s_ptr),R(res_ptr)
58: bls L(Lspecial) /* jump if s_ptr >= res_ptr */
59: #if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020))
60: lea MEM_INDX1(s_ptr,s_size,l,4),R(a2)
61: #else /* not mc68020 */
62: movel R(s_size),R(d0)
63: asll #2,R(d0)
64: lea MEM_INDX(s_ptr,d0,l),R(a2)
65: #endif
66: cmpl R(res_ptr),R(a2)
67: bls L(Lspecial) /* jump if res_ptr >= s_ptr + s_size */
68:
69: L(Lnormal:)
70: moveql #32,R(d5)
71: subl R(cnt),R(d5)
72:
73: #if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020))
74: lea MEM_INDX1(s_ptr,s_size,l,4),R(s_ptr)
75: lea MEM_INDX1(res_ptr,s_size,l,4),R(res_ptr)
76: #else /* not mc68000 */
77: movel R(s_size),R(d0)
78: asll #2,R(d0)
79: addl R(s_size),R(s_ptr)
80: addl R(s_size),R(res_ptr)
81: #endif
82: movel MEM_PREDEC(s_ptr),R(d2)
83: movel R(d2),R(d0)
84: lsrl R(d5),R(d0) /* compute carry limb */
85:
86: lsll R(cnt),R(d2)
87: movel R(d2),R(d1)
88: subql #1,R(s_size)
89: beq L(Lend)
90: lsrl #1,R(s_size)
91: bcs L(L1)
92: subql #1,R(s_size)
93:
94: L(Loop:)
95: movel MEM_PREDEC(s_ptr),R(d2)
96: movel R(d2),R(d3)
97: lsrl R(d5),R(d3)
98: orl R(d3),R(d1)
99: movel R(d1),MEM_PREDEC(res_ptr)
100: lsll R(cnt),R(d2)
101: L(L1:)
102: movel MEM_PREDEC(s_ptr),R(d1)
103: movel R(d1),R(d3)
104: lsrl R(d5),R(d3)
105: orl R(d3),R(d2)
106: movel R(d2),MEM_PREDEC(res_ptr)
107: lsll R(cnt),R(d1)
108:
109: dbf R(s_size),L(Loop)
110: subl #0x10000,R(s_size)
111: bcc L(Loop)
112:
113: L(Lend:)
114: movel R(d1),MEM_PREDEC(res_ptr) /* store least significant limb */
115:
116: /* Restore used registers from stack frame. */
117: moveml MEM_POSTINC(sp),R(d2)-R(d6)/R(a2)
118: rts
119:
120: /* We loop from least significant end of the arrays, which is only
121: permissable if the source and destination don't overlap, since the
122: function is documented to work for overlapping source and destination. */
123:
124: L(Lspecial:)
125: clrl R(d0) /* initialize carry */
126: eorw #1,R(s_size)
127: lsrl #1,R(s_size)
128: bcc L(LL1)
129: subql #1,R(s_size)
130:
131: L(LLoop:)
132: movel MEM_POSTINC(s_ptr),R(d2)
133: addxl R(d2),R(d2)
134: movel R(d2),MEM_POSTINC(res_ptr)
135: L(LL1:)
136: movel MEM_POSTINC(s_ptr),R(d2)
137: addxl R(d2),R(d2)
138: movel R(d2),MEM_POSTINC(res_ptr)
139:
140: dbf R(s_size),L(LLoop)
141: addxl R(d0),R(d0) /* save cy in lsb */
142: subl #0x10000,R(s_size)
143: bcs L(LLend)
144: lsrl #1,R(d0) /* restore cy */
145: bra L(LLoop)
146:
147: L(LLend:)
148: /* Restore used registers from stack frame. */
149: moveml MEM_POSTINC(sp),R(d2)-R(d6)/R(a2)
150: rts
151: EPILOG(__mpn_lshift)
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>