1/* Copyright (C) 2008-2019 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#if 1
45	bne abort
46	jeq_s [blink]
47	b abort
48#else
49	bne abort
50	j_s [blink]
51#endif
52	ENDFUNC(__divsf3)
53#define __divsf3 __divsf3_asm
54#endif /* DEBUG */
55
56	.balign 4
57__divdf3_support: /* This label makes debugger output saner.  */
58	FUNC(__divsf3)
59.Ldenorm_fp0:
60	norm.f r12,r2 ; flag for 0/x -> 0 check
61	bic.ne.f 0,0x60000000,r1 ; denorm/large number -> 0
62	beq_s .Lret0_NaN
63	tst r1,r9
64	add_s r2,r2,r2
65	sub_s r12,r12,8
66	asl_s r2,r2,r12
67	asl_l r12,r12,23
68	bne.d .Lpast_denorm_fp0
69	add r5,r5,r12
70/* r0 is subnormal, r1 is subnormal or 0.  */
71
72	.balign 4
73.Ldenorm_fp1:
74	norm.f r12,r3 ; flag for  x/0 -> Inf check
75	bic.ne.f 0,0x60000000,r0 ; large number/denorm -> Inf
76	beq_s .Linf
77	add_s r3,r3,r3
78	sub_s r12,r12,8
79	asl_s r3,r3,r12
80	asl_s r12,r12,23
81	b.d .Lpast_denorm_fp1
82	add r4,r4,r12
83
84.Lret0_NaN:
85	bclr.f 0,r1,31 ; 0/0 -> NaN
86	bic r0,r10,r9
87	j_s.d [blink]
88	sub.eq r0,r0,1
89
90	.global __divsf3
91	.balign 4
92        .long 0x7f800000 ; exponent mask
93__divsf3:
94	ld r9,[pcl,-4]
95	bmsk r2,r0,22
96	xor r4,r0,r2
97	bmsk r3,r1,22
98	xor r5,r1,r3
99	and r11,r0,r9
100	breq.d r11,0,.Ldenorm_fp0
101	xor r10,r4,r5
102	breq r11,r9,.Linf_nan_fp0
103	bset_s r2,r2,23
104	and r11,r1,r9
105	breq r11,0,.Ldenorm_fp1
106	breq r11,r9,.Linf_nan_fp1
107.Lpast_denorm_fp0:
108	bset_s r3,r3,23
109.Lpast_denorm_fp1:
110	cmp r2,r3
111	asl_s r2,r2,6+1
112	asl_s r3,r3,7
113	add.lo r2,r2,r2
114	bclr r8,r9,30 ; exponent bias
115	bclr.lo r8,r8,23 ; reduce exp by one if fraction is shifted
116	sub r4,r4,r5
117	add r4,r4,r8
118	xor.f 0,r10,r4
119	bmi .Linf_denorm
120	and r12,r4,r9
121	breq r12,0,.Ldenorm
122	sub_s r2,r2,r3 ; discard implicit 1
123.Ldiv_23bit:
124	.rep 6
125	divaw r2,r2,r3
126	.endr
127	breq r12,r9,.Linf
128	bmsk r0,r2,6
129	xor_s r2,r2,r0
130.Ldiv_17bit:
131	.rep 7
132	divaw r2,r2,r3
133	.endr
134	asl_s r0,r0,7
135	bmsk r1,r2,6
136	xor_s r2,r2,r1
137	or_s r0,r0,r1
138.Ldiv_10bit:
139	.rep 7
140	divaw r2,r2,r3
141	.endr
142	asl_s r0,r0,7
143	bmsk r1,r2,6
144	xor_s r2,r2,r1
145	or_s r0,r0,r1
146.Ldiv_3bit:
147	.rep 3
148	divaw r2,r2,r3
149	.endr
150	asl_s r0,r0,3
151.Ldiv_0bit:
152	divaw r1,r2,r3
153	bmsk_s r2,r2,2
154	tst r1,-0x7e ; 0xffffff82, test for rest or odd
155	bmsk_s r1,r1,0
156	add_s r0,r0,r2 ; assemble fraction
157	add_s r0,r0,r4 ; add in sign & exponent
158	j_s.d [blink]
159	add.ne r0,r0,r1 ; round to nearest / even
160
161	.balign 4
162.Linf_nan_fp0:
163	bic.f 0,r9,r1 ; fp1 Inf -> result NaN
164	bic r1,r5,r9  ; fp1 sign
165	sub.eq r1,r1,1
166	j_s.d [blink]
167	xor_s r0,r0,r1
168.Linf_nan_fp1:
169	bic r0,r4,r9 ; fp0 sign
170	bmsk.f 0,r1,22 ; x/inf -> 0, x/nan -> nan
171	xor.eq r1,r1,r9
172	j_s.d [blink]
173	xor_s r0,r0,r1
174.Linf:
175	j_s.d [blink]
176	or r0,r10,r9
177
178.Lret_r4:
179	j_s.d [blink]
180	mov_s r0,r4
181	.balign 4
182.Linf_denorm:
183	add.f r12,r4,r4
184	asr_l r12,r12,24
185	bpl .Linf
186	max r12,r12,-24
187.Ldenorm:
188	add r1,pcl,42; .Ldenorm_tab-.
189	ldb_s r12,[r12,r1]
190	mov_s r0,0
191	lsr_s r2,r2
192	sub_s r1,r1,r12
193	j_s.d [r1]
194	bic r4,r10,r9
195	.byte .Ldenorm_tab-.Lret_r4
196	.byte .Ldenorm_tab-.Ldiv_0bit
197	.byte .Ldenorm_tab-.Ldiv_3bit-8
198	.byte .Ldenorm_tab-.Ldiv_3bit-4
199	.byte .Ldenorm_tab-.Ldiv_3bit
200	.byte .Ldenorm_tab-.Ldiv_10bit-24
201	.byte .Ldenorm_tab-.Ldiv_10bit-20
202	.byte .Ldenorm_tab-.Ldiv_10bit-16
203	.byte .Ldenorm_tab-.Ldiv_10bit-12
204	.byte .Ldenorm_tab-.Ldiv_10bit-8
205	.byte .Ldenorm_tab-.Ldiv_10bit-4
206	.byte .Ldenorm_tab-.Ldiv_10bit
207	.byte .Ldenorm_tab-.Ldiv_17bit-24
208	.byte .Ldenorm_tab-.Ldiv_17bit-20
209	.byte .Ldenorm_tab-.Ldiv_17bit-16
210	.byte .Ldenorm_tab-.Ldiv_17bit-12
211	.byte .Ldenorm_tab-.Ldiv_17bit-8
212	.byte .Ldenorm_tab-.Ldiv_17bit-4
213	.byte .Ldenorm_tab-.Ldiv_17bit
214	.byte .Ldenorm_tab-.Ldiv_23bit-20
215	.byte .Ldenorm_tab-.Ldiv_23bit-16
216	.byte .Ldenorm_tab-.Ldiv_23bit-12
217	.byte .Ldenorm_tab-.Ldiv_23bit-8
218	.byte .Ldenorm_tab-.Ldiv_23bit-4
219.Ldenorm_tab:
220	.byte .Ldenorm_tab-.Ldiv_23bit
221	ENDFUNC(__divsf3)
222