beta-0.89.2
[luatex.git] / source / libs / gmp / gmp-src / mpn / m68k / rshift.asm
blob21b5f89f48376569b8755dd45463d8d044b41d88
1 dnl mc68020 mpn_rshift -- mpn right shift.
3 dnl Copyright 1996, 1999-2003 Free Software Foundation, Inc.
5 dnl This file is part of the GNU MP Library.
6 dnl
7 dnl The GNU MP Library is free software; you can redistribute it and/or modify
8 dnl it under the terms of either:
9 dnl
10 dnl * the GNU Lesser General Public License as published by the Free
11 dnl Software Foundation; either version 3 of the License, or (at your
12 dnl option) any later version.
13 dnl
14 dnl or
15 dnl
16 dnl * the GNU General Public License as published by the Free Software
17 dnl Foundation; either version 2 of the License, or (at your option) any
18 dnl later version.
19 dnl
20 dnl or both in parallel, as here.
21 dnl
22 dnl The GNU MP Library is distributed in the hope that it will be useful, but
23 dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
24 dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
25 dnl for more details.
26 dnl
27 dnl You should have received copies of the GNU General Public License and the
28 dnl GNU Lesser General Public License along with the GNU MP Library. If not,
29 dnl see https://www.gnu.org/licenses/.
31 include(`../config.m4')
34 C cycles/limb
35 C shift==1 shift>1
36 C 68040: 9 12
39 C mp_limb_t mpn_rshift (mp_ptr res_ptr, mp_srcptr s_ptr, mp_size_t s_size,
40 C unsigned cnt);
42 C The "cnt" parameter is either 16 bits or 32 bits depending on
43 C SIZEOF_UNSIGNED (see ABI notes in mpn/m68k/README). The value is of
44 C course only 1 to 31. When loaded as 16 bits there's garbage in the upper
45 C half, hence the use of cmpw. The shift instructions take the their count
46 C modulo 64, so the upper part doesn't matter to them either.
49 C INPUT PARAMETERS
50 C res_ptr (sp + 4)
51 C s_ptr (sp + 8)
52 C s_size (sp + 12)
53 C cnt (sp + 16)
55 define(res_ptr, `a1')
56 define(s_ptr, `a0')
57 define(s_size, `d6')
58 define(cnt, `d4')
60 ifdef(`SIZEOF_UNSIGNED',,
61 `m4_error(`SIZEOF_UNSIGNED not defined, should be in config.m4
62 ')')
64 PROLOGUE(mpn_rshift)
65 C Save used registers on the stack.
66 moveml d2-d6/a2, M(-,sp)
68 C Copy the arguments to registers.
69 movel M(sp,28), res_ptr
70 movel M(sp,32), s_ptr
71 movel M(sp,36), s_size
72 ifelse(SIZEOF_UNSIGNED,2,
73 ` movew M(sp,40), cnt',
74 ` movel M(sp,40), cnt')
76 moveql #1, d5
77 cmpw d5, cnt
78 bne L(Lnormal)
79 cmpl res_ptr, s_ptr
80 bls L(Lspecial) C jump if res_ptr >= s_ptr
82 ifelse(scale_available_p,1,`
83 lea M(res_ptr,s_size,l,4), a2
84 ',`
85 movel s_size, d0
86 asll #2, d0
87 lea M(res_ptr,d0,l), a2
89 cmpl s_ptr, a2
90 bls L(Lspecial) C jump if s_ptr >= res_ptr + s_size
92 L(Lnormal):
93 moveql #32, d5
94 subl cnt, d5
95 movel M(s_ptr,+), d2
96 movel d2, d0
97 lsll d5, d0 C compute carry limb
99 lsrl cnt, d2
100 movel d2, d1
101 subql #1, s_size
102 beq L(Lend)
103 lsrl #1, s_size
104 bcs L(L1)
105 subql #1, s_size
107 L(Loop):
108 movel M(s_ptr,+), d2
109 movel d2, d3
110 lsll d5, d3
111 orl d3, d1
112 movel d1, M(res_ptr,+)
113 lsrl cnt, d2
114 L(L1):
115 movel M(s_ptr,+), d1
116 movel d1, d3
117 lsll d5, d3
118 orl d3, d2
119 movel d2, M(res_ptr,+)
120 lsrl cnt, d1
122 dbf s_size, L(Loop)
123 subl #0x10000, s_size
124 bcc L(Loop)
126 L(Lend):
127 movel d1, M(res_ptr) C store most significant limb
129 C Restore used registers from stack frame.
130 moveml M(sp,+), d2-d6/a2
133 C We loop from most significant end of the arrays, which is only permissable
134 C if the source and destination don't overlap, since the function is
135 C documented to work for overlapping source and destination.
137 L(Lspecial):
138 ifelse(scale_available_p,1,`
139 lea M(s_ptr,s_size,l,4), s_ptr
140 lea M(res_ptr,s_size,l,4), res_ptr
142 movel s_size, d0
143 asll #2, d0
144 addl d0, s_ptr
145 addl d0, res_ptr
148 clrl d0 C initialize carry
149 eorw #1, s_size
150 lsrl #1, s_size
151 bcc L(LL1)
152 subql #1, s_size
154 L(LLoop):
155 movel M(-,s_ptr), d2
156 roxrl #1, d2
157 movel d2, M(-,res_ptr)
158 L(LL1):
159 movel M(-,s_ptr), d2
160 roxrl #1, d2
161 movel d2, M(-,res_ptr)
163 dbf s_size, L(LLoop)
164 roxrl #1, d0 C save cy in msb
165 subl #0x10000, s_size
166 bcs L(LLend)
167 addl d0, d0 C restore cy
168 bra L(LLoop)
170 L(LLend):
171 C Restore used registers from stack frame.
172 moveml M(sp,+), d2-d6/a2
175 EPILOGUE(mpn_rshift)