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