* gcc-interface/decl.c (gnat_to_gnu_field): Do not set the alignment
[official-gcc.git] / libgcc / config / mcore / lib1funcs.S
blobe141f9ca2f398d350cb923c37047e9872291f017
1 /* libgcc routines for the MCore.
2    Copyright (C) 1993-2017 Free Software Foundation, Inc.
4 This file is part of GCC.
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.
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.
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.
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 <http://www.gnu.org/licenses/>.  */
25 #define CONCAT1(a, b) CONCAT2(a, b)
26 #define CONCAT2(a, b) a ## b
28 /* Use the right prefix for global labels.  */
30 #define SYM(x) CONCAT1 (__, x)
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
40 .macro FUNC_START name
41         .text
42         .globl SYM (\name)
43         TYPE (\name)
44 SYM (\name):
45 .endm
47 .macro FUNC_END name
48         SIZE (\name)
49 .endm
51 #ifdef  L_udivsi3
52 FUNC_START udiv32
53 FUNC_START udivsi32
55         movi    r1,0            // r1-r2 form 64 bit dividend
56         movi    r4,1            // r4 is quotient (1 for a sentinel)
58         cmpnei  r3,0            // look for 0 divisor
59         bt      9f
60         trap    3               // divide by 0
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
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
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...
87         // run the remaining bits
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
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
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
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
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
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
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
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
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
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...
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
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
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
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
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
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.
238    All of these shortcircuit the return path so that __cmp{sd}f2
239    will go directly back to the caller.  */
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 */
252 #ifdef  L_nedf2
253 COMPARE_DF_JUMP nedf2
254 #endif /* L_nedf2 */
256 #ifdef  L_gtdf2
257 COMPARE_DF_JUMP gtdf2
258 #endif /* L_gtdf2 */
260 #ifdef  L_gedf2
261 COMPARE_DF_JUMP gedf2
262 #endif /* L_gedf2 */
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 */
272 /* SINGLE PRECISION FLOATING POINT STUBS */
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 */