1/* Copyright (C) 2008-2020 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/* XMAC schedule: directly back-to-back multiplies stall; the third
27   instruction after a multiply stalls unless it is also a multiply.  */
28#include "arc-ieee-754.h"
29
30#if 0 /* DEBUG */
31	.global __mulsf3
32	FUNC(__mulsf3)
33	.balign 4
34__mulsf3:
35	push_s blink
36	push_s r1
37	bl.d __mulsf3_c
38	push_s r0
39	ld_s r1,[sp,4]
40	st_s r0,[sp,4]
41	bl.d __mulsf3_asm
42	pop_s r0
43	pop_s r1
44	pop_s blink
45	cmp r0,r1
46	jeq_s [blink]
47	and r12,r0,r1
48	bic.f 0,0x7f800000,r12
49	bne 0f
50	bmsk.f 0,r0,22
51	bmsk.ne.f r1,r1,22
52	jne_s [blink] ; both NaN -> OK
530:	bl abort
54	ENDFUNC(__mulsf3)
55#define __mulsf3 __mulsf3_asm
56#endif /* DEBUG */
57
58	.balign	4
59	.global	__mulsf3
60	FUNC(__mulsf3)
61__mulsf3:
62	ld.as	r9,[pcl,79]; [pcl,((.L7f800000-.+2)/4)]
63	bmsk	r4,r1,22
64	bset	r2,r0,23
65	asl_s	r2,r2,8
66	bset	r3,r4,23
67	MPYHU	r6,r2,r3
68	and	r11,r0,r9
69	breq	r11,0,.Ldenorm_dbl0
70	mpyu	r7,r2,r3
71	breq	r11,r9,.Linf_nan_dbl0
72	and	r12,r1,r9
73	asl.f	0,r6,8
74	breq	r12,0,.Ldenorm_dbl1
75.Lpast_denorm:
76	xor_s	r0,r0,r1
77.Lpast_denorm_dbl1:
78	add.pl	r6,r6,r6
79	bclr.pl	r6,r6,23
80	add.pl.f r7,r7,r7
81	ld.as	r4,[pcl,64]; [pcl,((.L7fffffff-.+2)/4)]
82	add.cs	r6,r6,1
83	lsr.f	0,r6,1
84	breq	r12,r9,.Linf_nan_dbl1
85	add_s	r12,r12,r11
86	adc.f	0,r7,r4
87	add_s	r12,r12, \
88		-0x3f800000
89	adc.f	r8,r6,r12
90	bic	r0,r0,r4
91	tst.pl	r8,r9
92	min	r3,r8,r9
93	jpnz.d	[blink]
94	add.pnz	r0,r0,r3
95; infinity or denormal number
96	add.ne.f r3,r3,r3
97	bpnz	.Linfinity
98	asr_s	r3,r3,23+1
99	bset	r6,r6,23
100	sub_s	r3,r3,1
101	neg_s	r2,r3
102	brhi	r2,24,.Lret_r0 ; right shift shift > 24 -> return +-0
103	lsr	r2,r6,r2
104	asl	r9,r6,r3
105	lsr.f	0,r2,1
106	tst	r7,r7
107	add_s	r0,r0,r2
108	bset.ne	r9,r9,0
109	adc.f	0,r9,r4
110	j_s.d	[blink]
111	add.cs	r0,r0,1
112.Linfinity:
113	j_s.d	[blink]
114	add_s	r0,r0,r9
115
116.Lret_r0: j_s [blink]
117
118	.balign	4
119.Linf_nan_dbl0:
120	sub_s	r2,r1,1 ; inf/nan * 0 -> nan; inf * nan -> nan (use |r2| >= inf)
121	bic.f	0,r9,r2
122	xor_s	r0,r0,r1
123	bclr_s	r1,r1,31
124	xor_s	r0,r0,r1
125	jne_s	[blink]
126.Lretnan:
127	j_s.d	[blink]
128	mov	r0,-1
129.Ldenorm_dbl0_inf_nan_dbl1:
130	bmsk.f	0,r0,30
131	beq_s	.Lretnan
132	xor_s	r0,r0,r1
133.Linf_nan_dbl1:
134	xor_s	r1,r1,r0
135	bclr_s	r1,r1,31
136	j_s.d	[blink]
137	xor_s	r0,r0,r1
138
139	.balign	4
140.Ldenorm_dbl0:
141	bclr_s	r2,r2,31
142	norm.f	r4,r2
143	and	r12,r1,r9
144	add_s	r2,r2,r2
145	asl	r2,r2,r4
146	asl	r4,r4,23
147	MPYHU	r6,r2,r3
148	breq	r12,r9,.Ldenorm_dbl0_inf_nan_dbl1
149	sub.ne.f r12,r12,r4
150	mpyu	r7,r2,r3
151	bhi.d	.Lpast_denorm
152	asl.f	0,r6,8
153	xor_s	r0,r0,r1
154	bmsk	r1,r0,30
155	j_s.d	[blink]
156	bic_l	r0,r0,r1
157
158	.balign	4
159.Ldenorm_dbl1:
160	norm.f	r3,r4
161	xor_s	r0,r0,r1
162	sub_s	r3,r3,7
163	asl	r4,r4,r3
164	sub_s	r3,r3,1
165	asl_s	r3,r3,23
166	MPYHU	r6,r2,r4
167	sub.ne.f r11,r11,r3
168	bmsk	r8,r0,30
169	mpyu	r7,r2,r4
170	bhi.d	.Lpast_denorm_dbl1
171	asl.f	0,r6,8
172	j_s.d	[blink]
173	bic	r0,r0,r8
174
175	.balign	4
176.L7f800000:
177	.long	0x7f800000
178.L7fffffff:
179	.long	0x7fffffff
180	ENDFUNC(__mulsf3)
181