Annotation of OpenXM_contrib/gmp/mpn/m68k/rshift.S, Revision 1.1.1.1
1.1 maekawa 1: /* mc68020 __mpn_rshift -- Shift right 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_rshift)
41:
42: C_SYMBOL_NAME(__mpn_rshift:)
43: PROLOG(__mpn_rshift)
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(res_ptr),R(s_ptr)
57: bls L(Lspecial) /* jump if res_ptr >= s_ptr */
58: #if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020))
59: lea MEM_INDX1(res_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(res_ptr,d0,l),R(a2)
64: #endif
65: cmpl R(s_ptr),R(a2)
66: bls L(Lspecial) /* jump if s_ptr >= res_ptr + s_size */
67:
68: L(Lnormal:)
69: moveql #32,R(d5)
70: subl R(cnt),R(d5)
71: movel MEM_POSTINC(s_ptr),R(d2)
72: movel R(d2),R(d0)
73: lsll R(d5),R(d0) /* compute carry limb */
74:
75: lsrl R(cnt),R(d2)
76: movel R(d2),R(d1)
77: subql #1,R(s_size)
78: beq L(Lend)
79: lsrl #1,R(s_size)
80: bcs L(L1)
81: subql #1,R(s_size)
82:
83: L(Loop:)
84: movel MEM_POSTINC(s_ptr),R(d2)
85: movel R(d2),R(d3)
86: lsll R(d5),R(d3)
87: orl R(d3),R(d1)
88: movel R(d1),MEM_POSTINC(res_ptr)
89: lsrl R(cnt),R(d2)
90: L(L1:)
91: movel MEM_POSTINC(s_ptr),R(d1)
92: movel R(d1),R(d3)
93: lsll R(d5),R(d3)
94: orl R(d3),R(d2)
95: movel R(d2),MEM_POSTINC(res_ptr)
96: lsrl R(cnt),R(d1)
97:
98: dbf R(s_size),L(Loop)
99: subl #0x10000,R(s_size)
100: bcc L(Loop)
101:
102: L(Lend:)
103: movel R(d1),MEM(res_ptr) /* store most significant limb */
104:
105: /* Restore used registers from stack frame. */
106: moveml MEM_POSTINC(sp),R(d2)-R(d6)/R(a2)
107: rts
108:
109: /* We loop from most significant end of the arrays, which is only
110: permissable if the source and destination don't overlap, since the
111: function is documented to work for overlapping source and destination. */
112:
113: L(Lspecial:)
114: #if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020))
115: lea MEM_INDX1(s_ptr,s_size,l,4),R(s_ptr)
116: lea MEM_INDX1(res_ptr,s_size,l,4),R(res_ptr)
117: #else /* not mc68000 */
118: movel R(s_size),R(d0)
119: asll #2,R(d0)
120: addl R(s_size),R(s_ptr)
121: addl R(s_size),R(res_ptr)
122: #endif
123:
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_PREDEC(s_ptr),R(d2)
132: roxrl #1,R(d2)
133: movel R(d2),MEM_PREDEC(res_ptr)
134: L(LL1:)
135: movel MEM_PREDEC(s_ptr),R(d2)
136: roxrl #1,R(d2)
137: movel R(d2),MEM_PREDEC(res_ptr)
138:
139: dbf R(s_size),L(LLoop)
140: roxrl #1,R(d0) /* save cy in msb */
141: subl #0x10000,R(s_size)
142: bcs L(LLend)
143: addl R(d0),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
150: EPILOG(__mpn_rshift)
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>