1
/* mc68020 __mpn_lshift -- Shift left a low-level natural-number integer.
3
Copyright (C) 1996 Free Software Foundation, Inc.
5
This file is part of the GNU MP Library.
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.
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.
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. */
23
#include "asm-syntax.h"
28
* mpihelp_lshift( mpi_ptr_t wp, (sp + 4)
29
* mpi_ptr_t up, (sp + 8)
30
* mpi_size_t usize, (sp + 12)
31
* unsigned cnt) (sp + 16)
41
GLOBL C_SYMBOL_NAME(mpihelp_lshift)
43
C_SYMBOL_NAME(mpihelp_lshift:)
44
PROLOG(mpihelp_lshift)
46
/* Save used registers on the stack. */
47
moveml R(d2)-R(d6)/R(a2),MEM_PREDEC(sp)
49
/* Copy the arguments to registers. */
50
movel MEM_DISP(sp,28),R(res_ptr)
51
movel MEM_DISP(sp,32),R(s_ptr)
52
movel MEM_DISP(sp,36),R(s_size)
53
movel MEM_DISP(sp,40),R(cnt)
58
cmpl R(s_ptr),R(res_ptr)
59
bls L(Lspecial) /* jump if s_ptr >= res_ptr */
60
#if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020))
61
lea MEM_INDX1(s_ptr,s_size,l,4),R(a2)
62
#else /* not mc68020 */
65
lea MEM_INDX(s_ptr,d0,l),R(a2)
68
bls L(Lspecial) /* jump if res_ptr >= s_ptr + s_size */
74
#if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020))
75
lea MEM_INDX1(s_ptr,s_size,l,4),R(s_ptr)
76
lea MEM_INDX1(res_ptr,s_size,l,4),R(res_ptr)
77
#else /* not mc68000 */
80
addl R(s_size),R(s_ptr)
81
addl R(s_size),R(res_ptr)
83
movel MEM_PREDEC(s_ptr),R(d2)
85
lsrl R(d5),R(d0) /* compute carry limb */
96
movel MEM_PREDEC(s_ptr),R(d2)
100
movel R(d1),MEM_PREDEC(res_ptr)
103
movel MEM_PREDEC(s_ptr),R(d1)
107
movel R(d2),MEM_PREDEC(res_ptr)
110
dbf R(s_size),L(Loop)
111
subl #0x10000,R(s_size)
115
movel R(d1),MEM_PREDEC(res_ptr) /* store least significant limb */
117
/* Restore used registers from stack frame. */
118
moveml MEM_POSTINC(sp),R(d2)-R(d6)/R(a2)
121
/* We loop from least significant end of the arrays, which is only
122
permissable if the source and destination don't overlap, since the
123
function is documented to work for overlapping source and destination. */
126
clrl R(d0) /* initialize carry */
133
movel MEM_POSTINC(s_ptr),R(d2)
135
movel R(d2),MEM_POSTINC(res_ptr)
137
movel MEM_POSTINC(s_ptr),R(d2)
139
movel R(d2),MEM_POSTINC(res_ptr)
141
dbf R(s_size),L(LLoop)
142
addxl R(d0),R(d0) /* save cy in lsb */
143
subl #0x10000,R(s_size)
145
lsrl #1,R(d0) /* restore cy */
149
/* Restore used registers from stack frame. */
150
moveml MEM_POSTINC(sp),R(d2)-R(d6)/R(a2)
152
EPILOG(mpihelp_lshift)
159
* mpihelp_rshift( mpi_ptr_t wp, (sp + 4)
160
* mpi_ptr_t up, (sp + 8)
161
* mpi_size_t usize, (sp + 12)
162
* unsigned cnt) (sp + 16)
172
GLOBL C_SYMBOL_NAME(mpihelp_rshift)
174
C_SYMBOL_NAME(mpihelp_rshift:)
175
PROLOG(mpihelp_rshift)
176
/* Save used registers on the stack. */
177
moveml R(d2)-R(d6)/R(a2),MEM_PREDEC(sp)
179
/* Copy the arguments to registers. */
180
movel MEM_DISP(sp,28),R(res_ptr)
181
movel MEM_DISP(sp,32),R(s_ptr)
182
movel MEM_DISP(sp,36),R(s_size)
183
movel MEM_DISP(sp,40),R(cnt)
188
cmpl R(res_ptr),R(s_ptr)
189
bls L(Rspecial) /* jump if res_ptr >= s_ptr */
190
#if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020))
191
lea MEM_INDX1(res_ptr,s_size,l,4),R(a2)
192
#else /* not mc68020 */
193
movel R(s_size),R(d0)
195
lea MEM_INDX(res_ptr,d0,l),R(a2)
198
bls L(Rspecial) /* jump if s_ptr >= res_ptr + s_size */
203
movel MEM_POSTINC(s_ptr),R(d2)
205
lsll R(d5),R(d0) /* compute carry limb */
216
movel MEM_POSTINC(s_ptr),R(d2)
220
movel R(d1),MEM_POSTINC(res_ptr)
223
movel MEM_POSTINC(s_ptr),R(d1)
227
movel R(d2),MEM_POSTINC(res_ptr)
230
dbf R(s_size),L(Roop)
231
subl #0x10000,R(s_size)
235
movel R(d1),MEM(res_ptr) /* store most significant limb */
237
/* Restore used registers from stack frame. */
238
moveml MEM_POSTINC(sp),R(d2)-R(d6)/R(a2)
241
/* We loop from most significant end of the arrays, which is only
242
permissable if the source and destination don't overlap, since the
243
function is documented to work for overlapping source and destination. */
246
#if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020))
247
lea MEM_INDX1(s_ptr,s_size,l,4),R(s_ptr)
248
lea MEM_INDX1(res_ptr,s_size,l,4),R(res_ptr)
249
#else /* not mc68000 */
250
movel R(s_size),R(d0)
252
addl R(s_size),R(s_ptr)
253
addl R(s_size),R(res_ptr)
256
clrl R(d0) /* initialize carry */
263
movel MEM_PREDEC(s_ptr),R(d2)
265
movel R(d2),MEM_PREDEC(res_ptr)
267
movel MEM_PREDEC(s_ptr),R(d2)
269
movel R(d2),MEM_PREDEC(res_ptr)
271
dbf R(s_size),L(LRoop)
272
roxrl #1,R(d0) /* save cy in msb */
273
subl #0x10000,R(s_size)
275
addl R(d0),R(d0) /* restore cy */
279
/* Restore used registers from stack frame. */
280
moveml MEM_POSTINC(sp),R(d2)-R(d6)/R(a2)
282
EPILOG(mpihelp_rshift)