1/* Copyright (C) 2008-2018 Free Software Foundation, Inc.
2   Contributor: Joern Rennecke <joern.rennecke@embecosm.com>
3		on behalf of Synopsys Inc.
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 3, or (at your option) any later
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15for more details.
16
17Under Section 7 of GPL version 3, you are granted additional
18permissions described in the GCC Runtime Library Exception, version
193.1, as published by the Free Software Foundation.
20
21You should have received a copy of the GNU General Public License and
22a copy of the GCC Runtime Library Exception along with this program;
23see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24<http://www.gnu.org/licenses/>.  */
25
26#include "../arc-ieee-754.h"
27
28#if 0 /* DEBUG */
29	.global __divsf3
30	FUNC(__divsf3)
31	.balign 4
32__divsf3:
33	push_s blink
34	push_s r1
35	bl.d __divsf3_c
36	push_s r0
37	ld_s r1,[sp,4]
38	st_s r0,[sp,4]
39	bl.d __divsf3_asm
40	pop_s r0
41	pop_s r1
42	pop_s blink
43	cmp r0,r1
44        jeq_s [blink]
45        and r12,r0,r1
46        bic.f 0,0x7f800000,r12 ; both NaN -> OK
47        jeq_s [blink]
48        bl abort
49	ENDFUNC(__divsf3)
50#define __divsf3 __divsf3_asm
51#endif /* DEBUG */
52
53	.balign 4
54__divdf3_support: /* This label makes debugger output saner.  */
55	FUNC(__divsf3)
56.Ldenorm_fp0:
57	norm.f r12,r2 ; flag for 0/x -> 0 check
58	bic.ne.f 0,0x60000000,r1 ; denorm/large number -> 0
59	beq_s .Lret0_NaN
60	tst r1,r9
61	add_s r2,r2,r2
62	sub_s r12,r12,8
63	asl_s r2,r2,r12
64	asl_l r12,r12,23
65	bne.d .Lpast_denorm_fp0
66	add r5,r5,r12
67/* r0 is subnormal, r1 is subnormal or 0.  */
68
69	.balign 4
70.Ldenorm_fp1:
71	norm.f r12,r3 ; flag for  x/0 -> Inf check
72	bic.ne.f 0,0x60000000,r0 ; large number/denorm -> Inf
73	beq_s .Linf
74	add_s r3,r3,r3
75	sub_s r12,r12,8
76	asl_s r3,r3,r12
77	asl_s r12,r12,23
78	b.d .Lpast_denorm_fp1
79	add r4,r4,r12
80
81.Lret0_NaN:
82	bclr.f 0,r1,31 ; 0/0 -> NaN
83	bic r0,r10,r9
84	j_s.d [blink]
85	sub.eq r0,r0,1
86
87	.balign 4
88.Linf_nan_fp0:
89	bic.f 0,r9,r1 ; fp1 Inf -> result NaN
90	bic r1,r5,r9  ; fp1 sign
91	sub.eq r1,r1,1
92	j_s.d [blink]
93	xor_s r0,r0,r1
94.Linf_nan_fp1:
95	bic r0,r4,r9 ; fp0 sign
96	bmsk.f 0,r1,22 ; x/inf -> 0, x/nan -> nan
97	xor.eq r1,r1,r9
98	j_s.d [blink]
99	xor_s r0,r0,r1
100
101	.global __divsf3
102	.balign 4
103        .long 0x7f800000 ; exponent mask
104__divsf3:
105	ld r9,[pcl,-4]
106	bmsk r2,r0,22
107	xor r4,r0,r2
108	bmsk r3,r1,22
109	xor r5,r1,r3
110	and r11,r0,r9
111	breq.d r11,0,.Ldenorm_fp0
112	xor r10,r4,r5
113	breq r11,r9,.Linf_nan_fp0
114	bset_s r2,r2,23
115	and r11,r1,r9
116	breq r11,0,.Ldenorm_fp1
117	breq r11,r9,.Linf_nan_fp1
118.Lpast_denorm_fp0:
119	bset_s r3,r3,23
120.Lpast_denorm_fp1:
121	cmp r2,r3
122	asl_s r2,r2,6+1
123	asl_s r3,r3,7
124	add.lo r2,r2,r2
125	bclr r8,r9,30 ; exponent bias
126	bclr.lo r8,r8,23 ; reduce exp by one if fraction is shifted
127	sub r4,r4,r5
128	add r4,r4,r8
129	xor.f 0,r10,r4
130	bmi .Linf_denorm
131	and.f r12,r4,r9
132	beq .Ldenorm
133	sub_s r2,r2,r3 ; discard implicit 1
134	rsub r3,r3,1 ; prime r3 for two-insn divide-step use
135.Ldiv_23bit:
136	.rep 6
137	add1.f r2,r3,r2
138	sub.cc r2,r2,r3
139	.endr
140	breq r12,r9,.Linf
141	bmsk r0,r2,6
142	xor_s r2,r2,r0
143.Ldiv_17bit:
144	.rep 7
145	add1.f r2,r3,r2
146	sub.cc r2,r2,r3
147	.endr
148	asl_s r0,r0,7
149	bmsk r1,r2,6
150	xor_s r2,r2,r1
151	or_s r0,r0,r1
152.Ldiv_10bit:
153	.rep 7
154	add1.f r2,r3,r2
155	sub.cc r2,r2,r3
156	.endr
157	asl_s r0,r0,7
158	bmsk r1,r2,6
159	xor_s r2,r2,r1
160	or_s r0,r0,r1
161.Ldiv_3bit:
162	.rep 3
163	add1.f r2,r3,r2
164	sub.cc r2,r2,r3
165	.endr
166	asl_s r0,r0,3
167.Ldiv_0bit:
168	add1.f r1,r3,r2
169	sub.cc r1,r1,r3
170	bmsk_s r2,r2,2
171	tst r1,-0x7e ; 0xffffff82, test for rest or odd
172	bmsk_s r1,r1,0
173	add_s r0,r0,r2 ; assemble fraction
174	add_s r0,r0,r4 ; add in sign & exponent
175	j_s.d [blink]
176	add.ne r0,r0,r1 ; round to nearest / even
177
178	.balign 4
179.Linf:
180	j_s.d [blink]
181	or r0,r10,r9
182
183.Lret_r4:
184	j_s.d [blink]
185	mov_s r0,r4
186	.balign 4
187.Linf_denorm:
188	add.f r12,r4,r4
189	asr_l r12,r12,24
190	bpl .Linf
191	max r12,r12,-24
192.Ldenorm:
193	rsub r3,r3,1
194	add r1,pcl,68; .Ldenorm_tab-.
195	ldw.as r12,[r1,r12]
196	mov_s r0,0
197	lsr_s r2,r2
198	sub_s r1,r1,r12
199	j_s.d [r1]
200	bic r4,r10,r9
201	.short .Ldenorm_tab-.Lret_r4
202	.short .Ldenorm_tab-.Ldiv_0bit
203	.short .Ldenorm_tab-.Ldiv_3bit-2*8
204	.short .Ldenorm_tab-.Ldiv_3bit-1*8
205	.short .Ldenorm_tab-.Ldiv_3bit
206	.short .Ldenorm_tab-.Ldiv_10bit-6*8
207	.short .Ldenorm_tab-.Ldiv_10bit-5*8
208	.short .Ldenorm_tab-.Ldiv_10bit-3*8
209	.short .Ldenorm_tab-.Ldiv_10bit-3*8
210	.short .Ldenorm_tab-.Ldiv_10bit-2*8
211	.short .Ldenorm_tab-.Ldiv_10bit-1*8
212	.short .Ldenorm_tab-.Ldiv_10bit
213	.short .Ldenorm_tab-.Ldiv_17bit-6*8
214	.short .Ldenorm_tab-.Ldiv_17bit-5*8
215	.short .Ldenorm_tab-.Ldiv_17bit-4*8
216	.short .Ldenorm_tab-.Ldiv_17bit-3*8
217	.short .Ldenorm_tab-.Ldiv_17bit-2*8
218	.short .Ldenorm_tab-.Ldiv_17bit-1*8
219	.short .Ldenorm_tab-.Ldiv_17bit
220	.short .Ldenorm_tab-.Ldiv_23bit-5*8
221	.short .Ldenorm_tab-.Ldiv_23bit-4*8
222	.short .Ldenorm_tab-.Ldiv_23bit-3*8
223	.short .Ldenorm_tab-.Ldiv_23bit-2*8
224	.short .Ldenorm_tab-.Ldiv_23bit-1*8
225.Ldenorm_tab:
226	.short .Ldenorm_tab-.Ldiv_23bit
227	ENDFUNC(__divsf3)
228