Imported Upstream version 4.8.1
[platform/upstream/gcc48.git] / libgcc / config / frv / lib1funcs.S
1 /* Library functions.
2    Copyright (C) 2000-2013 Free Software Foundation, Inc.
3    Contributed by Red Hat, Inc.
4   
5    This file is part of GCC.
6   
7    GCC is free software ; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3, or (at your option)
10    any later version.
11   
12    GCC is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY ; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16   
17    Under Section 7 of GPL version 3, you are granted additional
18    permissions described in the GCC Runtime Library Exception, version
19    3.1, as published by the Free Software Foundation.
20
21    You should have received a copy of the GNU General Public License and
22    a copy of the GCC Runtime Library Exception along with this program;
23    see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24    <http://www.gnu.org/licenses/>.  */
25
26 #include <frv-asm.h>
27
28 \f
29 #ifdef L_cmpll
30 /* icc0 = __cmpll (long long a, long long b)  */
31
32         .globl  EXT(__cmpll)
33         .type   EXT(__cmpll),@function
34         .text
35         .p2align 4
36 EXT(__cmpll):
37         cmp     gr8, gr10, icc0
38         ckeq    icc0, cc4
39         P(ccmp) gr9, gr11, cc4, 1
40         ret
41 .Lend:
42         .size   EXT(__cmpll),.Lend-EXT(__cmpll)
43 #endif /* L_cmpll */
44 \f
45 #ifdef L_cmpf
46 /* icc0 = __cmpf (float a, float b) */
47 /* Note, because this function returns the result in ICC0, it means it can't
48    handle NaNs.  */
49
50         .globl  EXT(__cmpf)
51         .type   EXT(__cmpf),@function
52         .text
53         .p2align 4
54 EXT(__cmpf):
55 #ifdef __FRV_HARD_FLOAT__       /* floating point instructions available */
56         movgf   gr8, fr0
57         P(movgf) gr9, fr1
58         setlos  #1, gr8
59         fcmps   fr0, fr1, fcc0
60         P(fcklt) fcc0, cc0
61         fckeq   fcc0, cc1
62         csub    gr0, gr8, gr8, cc0, 1
63         cmov    gr0, gr8, cc1, 1
64         cmpi    gr8, 0, icc0
65         ret
66 #else                           /* no floating point instructions available */
67         movsg   lr, gr4
68         addi    sp, #-16, sp
69         sti     gr4, @(sp, 8)
70         st      fp, @(sp, gr0)
71         mov     sp, fp
72         call    EXT(__cmpsf2)
73         cmpi    gr8, #0, icc0
74         ldi     @(sp, 8), gr4
75         movgs   gr4, lr
76         ld      @(sp,gr0), fp
77         addi    sp, #16, sp
78         ret
79 #endif
80 .Lend:
81         .size   EXT(__cmpf),.Lend-EXT(__cmpf)
82 #endif
83 \f
84 #ifdef L_cmpd
85 /* icc0 = __cmpd (double a, double b) */
86 /* Note, because this function returns the result in ICC0, it means it can't
87    handle NaNs.  */
88
89         .globl  EXT(__cmpd)
90         .type   EXT(__cmpd),@function
91         .text
92         .p2align 4
93 EXT(__cmpd):
94         movsg   lr, gr4
95         addi    sp, #-16, sp
96         sti     gr4, @(sp, 8)
97         st      fp, @(sp, gr0)
98         mov     sp, fp
99         call    EXT(__cmpdf2)
100         cmpi    gr8, #0, icc0
101         ldi     @(sp, 8), gr4
102         movgs   gr4, lr
103         ld      @(sp,gr0), fp
104         addi    sp, #16, sp
105         ret
106 .Lend:
107         .size   EXT(__cmpd),.Lend-EXT(__cmpd)
108 #endif
109 \f
110 #ifdef L_addll
111 /* gr8,gr9 = __addll (long long a, long long b) */
112 /* Note, gcc will never call this function, but it is present in case an
113    ABI program calls it.  */
114
115         .globl  EXT(__addll)
116         .type   EXT(__addll),@function
117         .text
118         .p2align
119 EXT(__addll):
120         addcc   gr9, gr11, gr9, icc0
121         addx    gr8, gr10, gr8, icc0
122         ret
123 .Lend:
124         .size   EXT(__addll),.Lend-EXT(__addll)
125 #endif
126 \f
127 #ifdef L_subll
128 /* gr8,gr9 = __subll (long long a, long long b) */
129 /* Note, gcc will never call this function, but it is present in case an
130    ABI program calls it.  */
131
132         .globl  EXT(__subll)
133         .type   EXT(__subll),@function
134         .text
135         .p2align 4
136 EXT(__subll):
137         subcc   gr9, gr11, gr9, icc0
138         subx    gr8, gr10, gr8, icc0
139         ret
140 .Lend:
141         .size   EXT(__subll),.Lend-EXT(__subll)
142 #endif
143 \f
144 #ifdef L_andll
145 /* gr8,gr9 = __andll (long long a, long long b) */
146 /* Note, gcc will never call this function, but it is present in case an
147    ABI program calls it.  */
148
149         .globl  EXT(__andll)
150         .type   EXT(__andll),@function
151         .text
152         .p2align 4
153 EXT(__andll):
154         P(and)  gr9, gr11, gr9
155         P2(and) gr8, gr10, gr8
156         ret
157 .Lend:
158         .size   EXT(__andll),.Lend-EXT(__andll)
159 #endif
160 \f
161 #ifdef L_orll
162 /* gr8,gr9 = __orll (long long a, long long b) */
163 /* Note, gcc will never call this function, but it is present in case an
164    ABI program calls it.  */
165
166         .globl  EXT(__orll)
167         .type   EXT(__orll),@function
168         .text
169         .p2align 4
170 EXT(__orll):
171         P(or)   gr9, gr11, gr9
172         P2(or)  gr8, gr10, gr8
173         ret
174 .Lend:
175         .size   EXT(__orll),.Lend-EXT(__orll)
176 #endif
177 \f
178 #ifdef L_xorll
179 /* gr8,gr9 = __xorll (long long a, long long b) */
180 /* Note, gcc will never call this function, but it is present in case an
181    ABI program calls it.  */
182
183         .globl  EXT(__xorll)
184         .type   EXT(__xorll),@function
185         .text
186         .p2align 4
187 EXT(__xorll):
188         P(xor)  gr9, gr11, gr9
189         P2(xor) gr8, gr10, gr8
190         ret
191 .Lend:
192         .size   EXT(__xorll),.Lend-EXT(__xorll)
193 #endif
194 \f
195 #ifdef L_notll
196 /* gr8,gr9 = __notll (long long a) */
197 /* Note, gcc will never call this function, but it is present in case an
198    ABI program calls it.  */
199
200         .globl  EXT(__notll)
201         .type   EXT(__notll),@function
202         .text
203         .p2align 4
204 EXT(__notll):
205         P(not)  gr9, gr9
206         P2(not) gr8, gr8
207         ret
208 .Lend:
209         .size   EXT(__notll),.Lend-EXT(__notll)
210 #endif
211 \f
212 #ifdef L_cmov
213 /* (void) __cmov (char *dest, const char *src, size_t len) */
214 /*
215  * void __cmov (char *dest, const char *src, size_t len)
216  * {
217  *   size_t i;
218  * 
219  *   if (dest < src || dest > src+len)
220  *     {
221  *       for (i = 0; i < len; i++)
222  *       dest[i] = src[i];
223  *     }
224  *   else
225  *     {
226  *       while (len-- > 0)
227  *       dest[len] = src[len];
228  *     }
229  * }
230  */
231
232         .globl  EXT(__cmov)
233         .type   EXT(__cmov),@function
234         .text
235         .p2align 4
236 EXT(__cmov):
237         P(cmp)  gr8, gr9, icc0
238         add     gr9, gr10, gr4
239         P(cmp)  gr8, gr4, icc1
240         bc      icc0, 0, .Lfwd
241         bls     icc1, 0, .Lback
242 .Lfwd:
243         /* move bytes in a forward direction */
244         P(setlos) #0, gr5
245         cmp     gr0, gr10, icc0
246         P(subi) gr9, #1, gr9
247         P2(subi) gr8, #1, gr8
248         bnc     icc0, 0, .Lret
249 .Lfloop:
250         /* forward byte move loop */
251         addi    gr5, #1, gr5
252         P(ldsb) @(gr9, gr5), gr4
253         cmp     gr5, gr10, icc0
254         P(stb)  gr4, @(gr8, gr5)
255         bc      icc0, 0, .Lfloop
256         ret
257 .Lbloop:
258         /* backward byte move loop body */
259         ldsb    @(gr9,gr10),gr4
260         stb     gr4,@(gr8,gr10)
261 .Lback:
262         P(cmpi) gr10, #0, icc0
263         addi    gr10, #-1, gr10
264         bne     icc0, 0, .Lbloop
265 .Lret:
266         ret
267 .Lend:
268         .size    EXT(__cmov),.Lend-EXT(__cmov)
269 #endif