1/* Library functions.
2   Copyright (C) 2000, 2003, 2008, 2009 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
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
36EXT(__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
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
54EXT(__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
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
93EXT(__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
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
119EXT(__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
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
136EXT(__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
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
153EXT(__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
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
170EXT(__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
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
187EXT(__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
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
204EXT(__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
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
236EXT(__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
270