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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgcc/] [config/] [mcore/] [lib1funcs.S] - Blame information for rev 758

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 734 jeremybenn
/* libgcc routines for the MCore.
2
   Copyright (C) 1993, 1999, 2000, 2009 Free Software Foundation, Inc.
3
 
4
This file is part of GCC.
5
 
6
GCC 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 3, or (at your option) any
9
later version.
10
 
11
This file is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
Under Section 7 of GPL version 3, you are granted additional
17
permissions described in the GCC Runtime Library Exception, version
18
3.1, as published by the Free Software Foundation.
19
 
20
You should have received a copy of the GNU General Public License and
21
a copy of the GCC Runtime Library Exception along with this program;
22
see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23
.  */
24
 
25
#define CONCAT1(a, b) CONCAT2(a, b)
26
#define CONCAT2(a, b) a ## b
27
 
28
/* Use the right prefix for global labels.  */
29
 
30
#define SYM(x) CONCAT1 (__, x)
31
 
32
#ifdef __ELF__
33
#define TYPE(x) .type SYM (x),@function
34
#define SIZE(x) .size SYM (x), . - SYM (x)
35
#else
36
#define TYPE(x)
37
#define SIZE(x)
38
#endif
39
 
40
.macro FUNC_START name
41
        .text
42
        .globl SYM (\name)
43
        TYPE (\name)
44
SYM (\name):
45
.endm
46
 
47
.macro FUNC_END name
48
        SIZE (\name)
49
.endm
50
 
51
#ifdef  L_udivsi3
52
FUNC_START udiv32
53
FUNC_START udivsi32
54
 
55
        movi    r1,0            // r1-r2 form 64 bit dividend
56
        movi    r4,1            // r4 is quotient (1 for a sentinel)
57
 
58
        cmpnei  r3,0            // look for 0 divisor
59
        bt      9f
60
        trap    3               // divide by 0
61
9:
62
        // control iterations; skip across high order 0 bits in dividend
63
        mov     r7,r2
64
        cmpnei  r7,0
65
        bt      8f
66
        movi    r2,0            // 0 dividend
67
        jmp     r15             // quick return
68
8:
69
        ff1     r7              // figure distance to skip
70
        lsl     r4,r7           // move the sentinel along (with 0's behind)
71
        lsl     r2,r7           // and the low 32 bits of numerator
72
 
73
// appears to be wrong...
74
// tested out incorrectly in our OS work...
75
//      mov     r7,r3           // looking at divisor
76
//      ff1     r7              // I can move 32-r7 more bits to left.
77
//      addi    r7,1            // ok, one short of that...
78
//      mov     r1,r2
79
//      lsr     r1,r7           // bits that came from low order...
80
//      rsubi   r7,31           // r7 == "32-n" == LEFT distance
81
//      addi    r7,1            // this is (32-n)
82
//      lsl     r4,r7           // fixes the high 32 (quotient)
83
//      lsl     r2,r7
84
//      cmpnei  r4,0
85
//      bf      4f              // the sentinel went away...
86
 
87
        // run the remaining bits
88
 
89
1:      lslc    r2,1            // 1 bit left shift of r1-r2
90
        addc    r1,r1
91
        cmphs   r1,r3           // upper 32 of dividend >= divisor?
92
        bf      2f
93
        sub     r1,r3           // if yes, subtract divisor
94
2:      addc    r4,r4           // shift by 1 and count subtracts
95
        bf      1b              // if sentinel falls out of quotient, stop
96
 
97
4:      mov     r2,r4           // return quotient
98
        mov     r3,r1           // and piggyback the remainder
99
        jmp     r15
100
FUNC_END udiv32
101
FUNC_END udivsi32
102
#endif
103
 
104
#ifdef  L_umodsi3
105
FUNC_START urem32
106
FUNC_START umodsi3
107
        movi    r1,0            // r1-r2 form 64 bit dividend
108
        movi    r4,1            // r4 is quotient (1 for a sentinel)
109
        cmpnei  r3,0            // look for 0 divisor
110
        bt      9f
111
        trap    3               // divide by 0
112
9:
113
        // control iterations; skip across high order 0 bits in dividend
114
        mov     r7,r2
115
        cmpnei  r7,0
116
        bt      8f
117
        movi    r2,0            // 0 dividend
118
        jmp     r15             // quick return
119
8:
120
        ff1     r7              // figure distance to skip
121
        lsl     r4,r7           // move the sentinel along (with 0's behind)
122
        lsl     r2,r7           // and the low 32 bits of numerator
123
 
124
1:      lslc    r2,1            // 1 bit left shift of r1-r2
125
        addc    r1,r1
126
        cmphs   r1,r3           // upper 32 of dividend >= divisor?
127
        bf      2f
128
        sub     r1,r3           // if yes, subtract divisor
129
2:      addc    r4,r4           // shift by 1 and count subtracts
130
        bf      1b              // if sentinel falls out of quotient, stop
131
        mov     r2,r1           // return remainder
132
        jmp     r15
133
FUNC_END urem32
134
FUNC_END umodsi3
135
#endif
136
 
137
#ifdef  L_divsi3
138
FUNC_START div32
139
FUNC_START divsi3
140
        mov     r5,r2           // calc sign of quotient
141
        xor     r5,r3
142
        abs     r2              // do unsigned divide
143
        abs     r3
144
        movi    r1,0            // r1-r2 form 64 bit dividend
145
        movi    r4,1            // r4 is quotient (1 for a sentinel)
146
        cmpnei  r3,0            // look for 0 divisor
147
        bt      9f
148
        trap    3               // divide by 0
149
9:
150
        // control iterations; skip across high order 0 bits in dividend
151
        mov     r7,r2
152
        cmpnei  r7,0
153
        bt      8f
154
        movi    r2,0            // 0 dividend
155
        jmp     r15             // quick return
156
8:
157
        ff1     r7              // figure distance to skip
158
        lsl     r4,r7           // move the sentinel along (with 0's behind)
159
        lsl     r2,r7           // and the low 32 bits of numerator
160
 
161
// tested out incorrectly in our OS work...
162
//      mov     r7,r3           // looking at divisor
163
//      ff1     r7              // I can move 32-r7 more bits to left.
164
//      addi    r7,1            // ok, one short of that...
165
//      mov     r1,r2
166
//      lsr     r1,r7           // bits that came from low order...
167
//      rsubi   r7,31           // r7 == "32-n" == LEFT distance
168
//      addi    r7,1            // this is (32-n)
169
//      lsl     r4,r7           // fixes the high 32 (quotient)
170
//      lsl     r2,r7
171
//      cmpnei  r4,0
172
//      bf      4f              // the sentinel went away...
173
 
174
        // run the remaining bits
175
1:      lslc    r2,1            // 1 bit left shift of r1-r2
176
        addc    r1,r1
177
        cmphs   r1,r3           // upper 32 of dividend >= divisor?
178
        bf      2f
179
        sub     r1,r3           // if yes, subtract divisor
180
2:      addc    r4,r4           // shift by 1 and count subtracts
181
        bf      1b              // if sentinel falls out of quotient, stop
182
 
183
4:      mov     r2,r4           // return quotient
184
        mov     r3,r1           // piggyback the remainder
185
        btsti   r5,31           // after adjusting for sign
186
        bf      3f
187
        rsubi   r2,0
188
        rsubi   r3,0
189
3:      jmp     r15
190
FUNC_END div32
191
FUNC_END divsi3
192
#endif
193
 
194
#ifdef  L_modsi3
195
FUNC_START rem32
196
FUNC_START modsi3
197
        mov     r5,r2           // calc sign of remainder
198
        abs     r2              // do unsigned divide
199
        abs     r3
200
        movi    r1,0            // r1-r2 form 64 bit dividend
201
        movi    r4,1            // r4 is quotient (1 for a sentinel)
202
        cmpnei  r3,0            // look for 0 divisor
203
        bt      9f
204
        trap    3               // divide by 0
205
9:
206
        // control iterations; skip across high order 0 bits in dividend
207
        mov     r7,r2
208
        cmpnei  r7,0
209
        bt      8f
210
        movi    r2,0            // 0 dividend
211
        jmp     r15             // quick return
212
8:
213
        ff1     r7              // figure distance to skip
214
        lsl     r4,r7           // move the sentinel along (with 0's behind)
215
        lsl     r2,r7           // and the low 32 bits of numerator
216
 
217
1:      lslc    r2,1            // 1 bit left shift of r1-r2
218
        addc    r1,r1
219
        cmphs   r1,r3           // upper 32 of dividend >= divisor?
220
        bf      2f
221
        sub     r1,r3           // if yes, subtract divisor
222
2:      addc    r4,r4           // shift by 1 and count subtracts
223
        bf      1b              // if sentinel falls out of quotient, stop
224
        mov     r2,r1           // return remainder
225
        btsti   r5,31           // after adjusting for sign
226
        bf      3f
227
        rsubi   r2,0
228
3:      jmp     r15
229
FUNC_END rem32
230
FUNC_END modsi3
231
#endif
232
 
233
 
234
/* GCC expects that {__eq,__ne,__gt,__ge,__le,__lt}{df2,sf2}
235
   will behave as __cmpdf2. So, we stub the implementations to
236
   jump on to __cmpdf2 and __cmpsf2.
237
 
238
   All of these shortcircuit the return path so that __cmp{sd}f2
239
   will go directly back to the caller.  */
240
 
241
.macro  COMPARE_DF_JUMP name
242
        .import SYM (cmpdf2)
243
FUNC_START \name
244
        jmpi SYM (cmpdf2)
245
FUNC_END \name
246
.endm
247
 
248
#ifdef  L_eqdf2
249
COMPARE_DF_JUMP eqdf2
250
#endif /* L_eqdf2 */
251
 
252
#ifdef  L_nedf2
253
COMPARE_DF_JUMP nedf2
254
#endif /* L_nedf2 */
255
 
256
#ifdef  L_gtdf2
257
COMPARE_DF_JUMP gtdf2
258
#endif /* L_gtdf2 */
259
 
260
#ifdef  L_gedf2
261
COMPARE_DF_JUMP gedf2
262
#endif /* L_gedf2 */
263
 
264
#ifdef  L_ltdf2
265
COMPARE_DF_JUMP ltdf2
266
#endif /* L_ltdf2 */
267
 
268
#ifdef  L_ledf2
269
COMPARE_DF_JUMP ledf2
270
#endif /* L_ledf2 */
271
 
272
/* SINGLE PRECISION FLOATING POINT STUBS */
273
 
274
.macro  COMPARE_SF_JUMP name
275
        .import SYM (cmpsf2)
276
FUNC_START \name
277
        jmpi SYM (cmpsf2)
278
FUNC_END \name
279
.endm
280
 
281
#ifdef  L_eqsf2
282
COMPARE_SF_JUMP eqsf2
283
#endif /* L_eqsf2 */
284
 
285
#ifdef  L_nesf2
286
COMPARE_SF_JUMP nesf2
287
#endif /* L_nesf2 */
288
 
289
#ifdef  L_gtsf2
290
COMPARE_SF_JUMP gtsf2
291
#endif /* L_gtsf2 */
292
 
293
#ifdef  L_gesf2
294
COMPARE_SF_JUMP __gesf2
295
#endif /* L_gesf2 */
296
 
297
#ifdef  L_ltsf2
298
COMPARE_SF_JUMP __ltsf2
299
#endif /* L_ltsf2 */
300
 
301
#ifdef  L_lesf2
302
COMPARE_SF_JUMP lesf2
303
#endif /* L_lesf2 */

powered by: WebSVN 2.1.0

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