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