OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [arch/] [arm/] [lib/] [lib1funcs.S] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
@ libgcc1 routines for ARM cpu.
2
@ Division routines, written by Richard Earnshaw, (rearnsha@armltd.co.uk)
3
 
4
/* Copyright (C) 1995, 1996, 1998 Free Software Foundation, Inc.
5
 
6
This file is free software; you can redistribute it and/or modify it
7
under the terms of the GNU General Public License as published by the
8
Free Software Foundation; either version 2, or (at your option) any
9
later version.
10
 
11
In addition to the permissions in the GNU General Public License, the
12
Free Software Foundation gives you unlimited permission to link the
13
compiled version of this file with other programs, and to distribute
14
those programs without any restriction coming from the use of this
15
file.  (The General Public License restrictions do apply in other
16
respects; for example, they cover modification of the file, and
17
distribution when not linked into another program.)
18
 
19
This file is distributed in the hope that it will be useful, but
20
WITHOUT ANY WARRANTY; without even the implied warranty of
21
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
22
General Public License for more details.
23
 
24
You should have received a copy of the GNU General Public License
25
along with this program; see the file COPYING.  If not, write to
26
the Free Software Foundation, 59 Temple Place - Suite 330,
27
Boston, MA 02111-1307, USA.  */
28
 
29
/* As a special exception, if you link this library with other files,
30
   some of which are compiled with GCC, to produce an executable,
31
   this library does not by itself cause the resulting executable
32
   to be covered by the GNU General Public License.
33
   This exception does not however invalidate any other reasons why
34
   the executable file might be covered by the GNU General Public License.
35
 */
36
/* This code is derived from gcc 2.95.3 */
37
/* I Molton     29/07/01 */
38
 
39
#include 
40
#include 
41
#include 
42
#include 
43
 
44
#ifdef CONFIG_CPU_26
45
#define RET     movs
46
#define RETc(x) mov##x##s
47
#define RETCOND ^
48
#else
49
#define RET     mov
50
#define RETc(x) mov##x
51
#define RETCOND
52
#endif
53
 
54
dividend        .req    r0
55
divisor         .req    r1
56
result          .req    r2
57
overdone        .req    r2
58
curbit          .req    r3
59
ip              .req    r12
60
sp              .req    r13
61
lr              .req    r14
62
pc              .req    r15
63
 
64
ENTRY(__udivsi3)
65
        cmp     divisor, #0
66
        beq     Ldiv0
67
        mov     curbit, #1
68
        mov     result, #0
69
        cmp     dividend, divisor
70
        bcc     Lgot_result_udivsi3
71
1:
72
        @ Unless the divisor is very big, shift it up in multiples of
73
        @ four bits, since this is the amount of unwinding in the main
74
        @ division loop.  Continue shifting until the divisor is
75
        @ larger than the dividend.
76
        cmp     divisor, #0x10000000
77
        cmpcc   divisor, dividend
78
        movcc   divisor, divisor, lsl #4
79
        movcc   curbit, curbit, lsl #4
80
        bcc     1b
81
 
82
2:
83
        @ For very big divisors, we must shift it a bit at a time, or
84
        @ we will be in danger of overflowing.
85
        cmp     divisor, #0x80000000
86
        cmpcc   divisor, dividend
87
        movcc   divisor, divisor, lsl #1
88
        movcc   curbit, curbit, lsl #1
89
        bcc     2b
90
 
91
3:
92
        @ Test for possible subtractions, and note which bits
93
        @ are done in the result.  On the final pass, this may subtract
94
        @ too much from the dividend, but the result will be ok, since the
95
        @ "bit" will have been shifted out at the bottom.
96
        cmp     dividend, divisor
97
        subcs   dividend, dividend, divisor
98
        orrcs   result, result, curbit
99
        cmp     dividend, divisor, lsr #1
100
        subcs   dividend, dividend, divisor, lsr #1
101
        orrcs   result, result, curbit, lsr #1
102
        cmp     dividend, divisor, lsr #2
103
        subcs   dividend, dividend, divisor, lsr #2
104
        orrcs   result, result, curbit, lsr #2
105
        cmp     dividend, divisor, lsr #3
106
        subcs   dividend, dividend, divisor, lsr #3
107
        orrcs   result, result, curbit, lsr #3
108
        cmp     dividend, #0                    @ Early termination?
109
        movnes  curbit, curbit, lsr #4          @ No, any more bits to do?
110
        movne   divisor, divisor, lsr #4
111
        bne     3b
112
Lgot_result_udivsi3:
113
        mov     r0, result
114
        RET     pc, lr
115
 
116
Ldiv0:
117
        str     lr, [sp, #-4]!
118
        bl      __div0
119
        mov     r0, #0                  @ about as wrong as it could be
120
        ldmia   sp!, {pc}RETCOND
121
 
122
/* __umodsi3 ----------------------- */
123
 
124
ENTRY(__umodsi3)
125
        cmp     divisor, #0
126
        beq     Ldiv0
127
        mov     curbit, #1
128
        cmp     dividend, divisor
129
        RETc(cc)        pc, lr
130
1:
131
        @ Unless the divisor is very big, shift it up in multiples of
132
        @ four bits, since this is the amount of unwinding in the main
133
        @ division loop.  Continue shifting until the divisor is
134
        @ larger than the dividend.
135
        cmp     divisor, #0x10000000
136
        cmpcc   divisor, dividend
137
        movcc   divisor, divisor, lsl #4
138
        movcc   curbit, curbit, lsl #4
139
        bcc     1b
140
 
141
2:
142
        @ For very big divisors, we must shift it a bit at a time, or
143
        @ we will be in danger of overflowing.
144
        cmp     divisor, #0x80000000
145
        cmpcc   divisor, dividend
146
        movcc   divisor, divisor, lsl #1
147
        movcc   curbit, curbit, lsl #1
148
        bcc     2b
149
 
150
3:
151
        @ Test for possible subtractions.  On the final pass, this may
152
        @ subtract too much from the dividend, so keep track of which
153
        @ subtractions are done, we can fix them up afterwards...
154
        mov     overdone, #0
155
        cmp     dividend, divisor
156
        subcs   dividend, dividend, divisor
157
        cmp     dividend, divisor, lsr #1
158
        subcs   dividend, dividend, divisor, lsr #1
159
        orrcs   overdone, overdone, curbit, ror #1
160
        cmp     dividend, divisor, lsr #2
161
        subcs   dividend, dividend, divisor, lsr #2
162
        orrcs   overdone, overdone, curbit, ror #2
163
        cmp     dividend, divisor, lsr #3
164
        subcs   dividend, dividend, divisor, lsr #3
165
        orrcs   overdone, overdone, curbit, ror #3
166
        mov     ip, curbit
167
        cmp     dividend, #0                    @ Early termination?
168
        movnes  curbit, curbit, lsr #4          @ No, any more bits to do?
169
        movne   divisor, divisor, lsr #4
170
        bne     3b
171
 
172
        @ Any subtractions that we should not have done will be recorded in
173
        @ the top three bits of "overdone".  Exactly which were not needed
174
        @ are governed by the position of the bit, stored in ip.
175
        @ If we terminated early, because dividend became zero,
176
        @ then none of the below will match, since the bit in ip will not be
177
        @ in the bottom nibble.
178
        ands    overdone, overdone, #0xe0000000
179
        RETc(eq)        pc, lr                          @ No fixups needed
180
        tst     overdone, ip, ror #3
181
        addne   dividend, dividend, divisor, lsr #3
182
        tst     overdone, ip, ror #2
183
        addne   dividend, dividend, divisor, lsr #2
184
        tst     overdone, ip, ror #1
185
        addne   dividend, dividend, divisor, lsr #1
186
        RET     pc, lr
187
 
188
ENTRY(__divsi3)
189
        eor     ip, dividend, divisor           @ Save the sign of the result.
190
        mov     curbit, #1
191
        mov     result, #0
192
        cmp     divisor, #0
193
        rsbmi   divisor, divisor, #0            @ Loops below use unsigned.
194
        beq     Ldiv0
195
        cmp     dividend, #0
196
        rsbmi   dividend, dividend, #0
197
        cmp     dividend, divisor
198
        bcc     Lgot_result_divsi3
199
 
200
1:
201
        @ Unless the divisor is very big, shift it up in multiples of
202
        @ four bits, since this is the amount of unwinding in the main
203
        @ division loop.  Continue shifting until the divisor is
204
        @ larger than the dividend.
205
        cmp     divisor, #0x10000000
206
        cmpcc   divisor, dividend
207
        movcc   divisor, divisor, lsl #4
208
        movcc   curbit, curbit, lsl #4
209
        bcc     1b
210
 
211
2:
212
        @ For very big divisors, we must shift it a bit at a time, or
213
        @ we will be in danger of overflowing.
214
        cmp     divisor, #0x80000000
215
        cmpcc   divisor, dividend
216
        movcc   divisor, divisor, lsl #1
217
        movcc   curbit, curbit, lsl #1
218
        bcc     2b
219
 
220
3:
221
        @ Test for possible subtractions, and note which bits
222
        @ are done in the result.  On the final pass, this may subtract
223
        @ too much from the dividend, but the result will be ok, since the
224
        @ "bit" will have been shifted out at the bottom.
225
        cmp     dividend, divisor
226
        subcs   dividend, dividend, divisor
227
        orrcs   result, result, curbit
228
        cmp     dividend, divisor, lsr #1
229
        subcs   dividend, dividend, divisor, lsr #1
230
        orrcs   result, result, curbit, lsr #1
231
        cmp     dividend, divisor, lsr #2
232
        subcs   dividend, dividend, divisor, lsr #2
233
        orrcs   result, result, curbit, lsr #2
234
        cmp     dividend, divisor, lsr #3
235
        subcs   dividend, dividend, divisor, lsr #3
236
        orrcs   result, result, curbit, lsr #3
237
        cmp     dividend, #0                    @ Early termination?
238
        movnes  curbit, curbit, lsr #4          @ No, any more bits to do?
239
        movne   divisor, divisor, lsr #4
240
        bne     3b
241
Lgot_result_divsi3:
242
        mov     r0, result
243
        cmp     ip, #0
244
        rsbmi   r0, r0, #0
245
        RET     pc, lr
246
 
247
ENTRY(__modsi3)
248
        mov     curbit, #1
249
        cmp     divisor, #0
250
        rsbmi   divisor, divisor, #0            @ Loops below use unsigned.
251
        beq     Ldiv0
252
        @ Need to save the sign of the dividend, unfortunately, we need
253
        @ ip later on; this is faster than pushing lr and using that.
254
        str     dividend, [sp, #-4]!
255
        cmp     dividend, #0
256
        rsbmi   dividend, dividend, #0
257
        cmp     dividend, divisor
258
        bcc     Lgot_result_modsi3
259
 
260
1:
261
        @ Unless the divisor is very big, shift it up in multiples of
262
        @ four bits, since this is the amount of unwinding in the main
263
        @ division loop.  Continue shifting until the divisor is
264
        @ larger than the dividend.
265
        cmp     divisor, #0x10000000
266
        cmpcc   divisor, dividend
267
        movcc   divisor, divisor, lsl #4
268
        movcc   curbit, curbit, lsl #4
269
        bcc     1b
270
 
271
2:
272
        @ For very big divisors, we must shift it a bit at a time, or
273
        @ we will be in danger of overflowing.
274
        cmp     divisor, #0x80000000
275
        cmpcc   divisor, dividend
276
        movcc   divisor, divisor, lsl #1
277
        movcc   curbit, curbit, lsl #1
278
        bcc     2b
279
 
280
3:
281
        @ Test for possible subtractions.  On the final pass, this may
282
        @ subtract too much from the dividend, so keep track of which
283
        @ subtractions are done, we can fix them up afterwards...
284
        mov     overdone, #0
285
        cmp     dividend, divisor
286
        subcs   dividend, dividend, divisor
287
        cmp     dividend, divisor, lsr #1
288
        subcs   dividend, dividend, divisor, lsr #1
289
        orrcs   overdone, overdone, curbit, ror #1
290
        cmp     dividend, divisor, lsr #2
291
        subcs   dividend, dividend, divisor, lsr #2
292
        orrcs   overdone, overdone, curbit, ror #2
293
        cmp     dividend, divisor, lsr #3
294
        subcs   dividend, dividend, divisor, lsr #3
295
        orrcs   overdone, overdone, curbit, ror #3
296
        mov     ip, curbit
297
        cmp     dividend, #0                    @ Early termination?
298
        movnes  curbit, curbit, lsr #4          @ No, any more bits to do?
299
        movne   divisor, divisor, lsr #4
300
        bne     3b
301
 
302
        @ Any subtractions that we should not have done will be recorded in
303
        @ the top three bits of "overdone".  Exactly which were not needed
304
        @ are governed by the position of the bit, stored in ip.
305
        @ If we terminated early, because dividend became zero,
306
        @ then none of the below will match, since the bit in ip will not be
307
        @ in the bottom nibble.
308
        ands    overdone, overdone, #0xe0000000
309
        beq     Lgot_result_modsi3
310
        tst     overdone, ip, ror #3
311
        addne   dividend, dividend, divisor, lsr #3
312
        tst     overdone, ip, ror #2
313
        addne   dividend, dividend, divisor, lsr #2
314
        tst     overdone, ip, ror #1
315
        addne   dividend, dividend, divisor, lsr #1
316
Lgot_result_modsi3:
317
        ldr     ip, [sp], #4
318
        cmp     ip, #0
319
        rsbmi   dividend, dividend, #0
320
        RET     pc, lr

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.