]> git.ipfire.org Git - thirdparty/gcc.git/blob - libgcc/config/arc/ieee-754/arc600-mul64/muldf3.S
Update copyright years.
[thirdparty/gcc.git] / libgcc / config / arc / ieee-754 / arc600-mul64 / muldf3.S
1 /* Copyright (C) 2008-2020 Free Software Foundation, Inc.
2 Contributor: Joern Rennecke <joern.rennecke@embecosm.com>
3 on behalf of Synopsys Inc.
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 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 "../arc-ieee-754.h"
27
28 #if 0 /* DEBUG */
29 .global __muldf3
30 .balign 4
31 __muldf3:
32 push_s blink
33 push_s r2
34 push_s r3
35 push_s r0
36 bl.d __muldf3_c
37 push_s r1
38 ld_s r2,[sp,12]
39 ld_s r3,[sp,8]
40 st_s r0,[sp,12]
41 st_s r1,[sp,8]
42 pop_s r1
43 bl.d __muldf3_asm
44 pop_s r0
45 pop_s r3
46 pop_s r2
47 pop_s blink
48 cmp r0,r2
49 cmp.eq r1,r3
50 jeq_s [blink]
51 and r12,DBL0H,DBL1H
52 bic.f 0,0x7ff80000,r12 ; both NaN -> OK
53 jeq_s [blink]
54 b abort
55 #define __muldf3 __muldf3_asm
56 #endif /* DEBUG */
57
58 __muldf3_support: /* This label makes debugger output saner. */
59 .balign 4
60 FUNC(__muldf3)
61 .Ldenorm_2:
62 breq.d DBL1L,0,.Lret0_2 ; 0 input -> 0 output
63 norm.f r12,DBL1L
64 mov.mi r12,21
65 add.pl r12,r12,22
66 neg r11,r12
67 asl_s r12,r12,20
68 lsr.f DBL1H,DBL1L,r11
69 ror DBL1L,DBL1L,r11
70 sub_s DBL0H,DBL0H,r12
71 mov.eq DBL1H,DBL1L
72 sub_l DBL1L,DBL1L,DBL1H
73 /* Fall through. */
74 .global __muldf3
75 .balign 4
76 __muldf3:
77 mulu64 DBL0L,DBL1L
78 ld.as r9,[pcl,0x68] ; ((.L7ff00000-.+2)/4)]
79 bmsk r6,DBL0H,19
80 bset r6,r6,20
81 and r11,DBL0H,r9
82 breq.d r11,0,.Ldenorm_dbl0
83 and r12,DBL1H,r9
84 breq.d r12,0,.Ldenorm_dbl1
85 mov r8,mlo
86 mov r4,mhi
87 mulu64 r6,DBL1L
88 breq.d r11,r9,.Linf_nan
89 bmsk r10,DBL1H,19
90 breq.d r12,r9,.Linf_nan
91 bset r10,r10,20
92 add.f r4,r4,mlo
93 adc r5,mhi,0
94 mulu64 r10,DBL0L
95 add_s r12,r12,r11 ; add exponents
96 add.f r4,r4,mlo
97 adc r5,r5,mhi
98 mulu64 r6,r10
99 tst r8,r8
100 bclr r8,r9,30 ; 0x3ff00000
101 bset.ne r4,r4,0 ; put least significant word into sticky bit
102 bclr r6,r9,20 ; 0x7fe00000
103 add.f r5,r5,mlo
104 adc r7,mhi,0 ; fraction product in r7:r5:r4
105 lsr.f r10,r7,9
106 rsub.eq r8,r8,r9 ; 0x40000000
107 sub r12,r12,r8 ; subtract bias + implicit 1
108 brhs.d r12,r6,.Linf_denorm
109 rsub r10,r10,12
110 .Lshift_frac:
111 neg r8,r10
112 asl r6,r4,r10
113 lsr DBL0L,r4,r8
114 add.f 0,r6,r6
115 btst.eq DBL0L,0
116 cmp.eq r4,r4 ; round to nearest / round to even
117 asl r4,r5,r10
118 lsr r5,r5,r8
119 adc.f DBL0L,DBL0L,r4
120 xor.f 0,DBL0H,DBL1H
121 asl r7,r7,r10
122 add_s r12,r12,r5
123 adc DBL0H,r12,r7
124 j_s.d [blink]
125 bset.mi DBL0H,DBL0H,31
126
127 /* N.B. This is optimized for ARC700.
128 ARC600 has very different scheduling / instruction selection criteria. */
129
130 /* If one number is denormal, subtract some from the exponent of the other
131 one (if the other exponent is too small, return 0), and normalize the
132 denormal. Then re-run the computation. */
133 .Lret0_2:
134 lsr_s DBL0H,DBL0H,31
135 asl_s DBL0H,DBL0H,31
136 j_s.d [blink]
137 mov_s DBL0L,0
138 .balign 4
139 .Ldenorm_dbl0:
140 mov_s r12,DBL0L
141 mov_s DBL0L,DBL1L
142 mov_s DBL1L,r12
143 mov_s r12,DBL0H
144 mov_s DBL0H,DBL1H
145 mov_s DBL1H,r12
146 and r11,DBL0H,r9
147 .Ldenorm_dbl1:
148 brhs r11,r9,.Linf_nan
149 brhs 0x3ca00001,r11,.Lret0
150 sub_s DBL0H,DBL0H,DBL1H
151 bmsk.f DBL1H,DBL1H,30
152 add_s DBL0H,DBL0H,DBL1H
153 beq.d .Ldenorm_2
154 norm r12,DBL1H
155 sub_s r12,r12,10
156 asl r5,r12,20
157 asl_s DBL1H,DBL1H,r12
158 sub DBL0H,DBL0H,r5
159 neg r5,r12
160 lsr r6,DBL1L,r5
161 asl_s DBL1L,DBL1L,r12
162 b.d __muldf3
163 add_s DBL1H,DBL1H,r6
164
165 .Lret0: xor_s DBL0H,DBL0H,DBL1H
166 bclr DBL1H,DBL0H,31
167 xor_s DBL0H,DBL0H,DBL1H
168 j_s.d [blink]
169 mov_s DBL0L,0
170
171 .balign 4
172 .Linf_nan:
173 bclr r12,DBL1H,31
174 xor_s DBL1H,DBL1H,DBL0H
175 bclr_s DBL0H,DBL0H,31
176 max r8,DBL0H,r12 ; either NaN -> NaN ; otherwise inf
177 or.f 0,DBL0H,DBL0L
178 mov_s DBL0L,0
179 or.ne.f DBL1L,DBL1L,r12
180 not_s DBL0H,DBL0L ; inf * 0 -> NaN
181 mov.ne DBL0H,r8
182 tst_s DBL1H,DBL1H
183 j_s.d [blink]
184 bset.mi DBL0H,DBL0H,31
185
186 /* We have checked for infinity / NaN input before, and transformed
187 denormalized inputs into normalized inputs. Thus, the worst case
188 exponent overflows are:
189 1 + 1 - 0x400 == 0xc02 : maximum underflow
190 0x7fe + 0x7fe - 0x3ff == 0xbfd ; maximum overflow
191 N.B. 0x7e and 0x7f are also values for overflow.
192
193 If (r12 <= -54), we have an underflow to zero. */
194 .balign 4
195 .Linf_denorm:
196 lsr r6,r12,28
197 brlo.d r6,0xc,.Linf
198 asr r6,r12,20
199 add.f r10,r10,r6
200 brgt.d r10,0,.Lshift_frac
201 mov_s r12,0
202 beq.d .Lround_frac
203 add r10,r10,32
204 .Lshift32_frac:
205 tst r4,r4
206 mov r4,r5
207 bset.ne r4,r4,1
208 mov r5,r7
209 brge.d r10,1,.Lshift_frac
210 mov r7,0
211 breq.d r10,0,.Lround_frac
212 add r10,r10,32
213 brgt r10,21,.Lshift32_frac
214 b_s .Lret0
215
216 .Lround_frac:
217 add.f 0,r4,r4
218 btst.eq r5,0
219 mov_s DBL0L,r5
220 mov_s DBL0H,r7
221 adc.eq.f DBL0L,DBL0L,0
222 j_s.d [blink]
223 adc.eq DBL0H,DBL0H,0
224
225 .Linf: mov_s DBL0L,0
226 xor.f DBL1H,DBL1H,DBL0H
227 mov_s DBL0H,r9
228 j_s.d [blink]
229 bset.mi DBL0H,DBL0H,31
230 ENDFUNC(__muldf3)
231
232 .balign 4
233 .L7ff00000:
234 .long 0x7ff00000