1 dnl mc68020 mpn_lshift -- mpn left shift.
3 dnl Copyright 1996, 1999, 2000, 2001, 2002, 2003 Free Software Foundation,
6 dnl This file is part of the GNU MP Library.
8 dnl The GNU MP Library is free software; you can redistribute it and/or
9 dnl modify it under the terms of the GNU Lesser General Public License as
10 dnl published by the Free Software Foundation; either version 3 of the
11 dnl License, or (at your option) any later version.
13 dnl The GNU MP Library is distributed in the hope that it will be useful,
14 dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
15 dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 dnl Lesser General Public License for more details.
18 dnl You should have received a copy of the GNU Lesser General Public License
19 dnl along with the GNU MP Library. If not, see http://www.gnu.org/licenses/.
21 include(`../config.m4')
29 C mp_limb_t mpn_lshift (mp_ptr res_ptr, mp_srcptr s_ptr, mp_size_t s_size,
32 C The "cnt" parameter is either 16 bits or 32 bits depending on
33 C SIZEOF_UNSIGNED (see ABI notes in mpn/m68k/README). The value is of
34 C course only 1 to 31. When loaded as 16 bits there's garbage in the upper
35 C half, hence the use of cmpw. The shift instructions take the their count
36 C modulo 64, so the upper part doesn't matter to them either.
50 ifdef(`SIZEOF_UNSIGNED',,
51 `m4_error(`SIZEOF_UNSIGNED not defined, should be in config.m4
55 C Save used registers on the stack.
56 moveml d2-d6/a2, M(-,sp)
58 C Copy the arguments to registers.
59 movel M(sp,28), res_ptr
61 movel M(sp,36), s_size
62 ifelse(SIZEOF_UNSIGNED,2,
63 ` movew M(sp,40), cnt',
64 ` movel M(sp,40), cnt')
70 bls L(Lspecial) C jump if s_ptr >= res_ptr
72 ifelse(scale_available_p,1,`
73 lea M(s_ptr,s_size,l,4), a2
80 bls L(Lspecial) C jump if res_ptr >= s_ptr + s_size
86 ifelse(scale_available_p,1,`
87 lea M(s_ptr,s_size,l,4), s_ptr
88 lea M(res_ptr,s_size,l,4), res_ptr
97 lsrl d5, d0 C compute carry limb
112 movel d1, M(-,res_ptr)
119 movel d2, M(-,res_ptr)
123 subl #0x10000, s_size
127 movel d1, M(-,res_ptr) C store least significant limb
129 C Restore used registers from stack frame.
130 moveml M(sp,+), d2-d6/a2
133 C We loop from least significant end of the arrays, which is only
134 C permissable if the source and destination don't overlap, since the
135 C function is documented to work for overlapping source and destination.
138 clrl d0 C initialize carry
147 movel d2, M(res_ptr,+)
151 movel d2, M(res_ptr,+)
154 addxl d0, d0 C save cy in lsb
155 subl #0x10000, s_size
157 lsrl #1, d0 C restore cy
161 C Restore used registers from stack frame.
162 moveml M(sp,+), d2-d6/a2