1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
|
/* Copyright (C) 2008-2013 Free Software Foundation, Inc.
Contributor: Joern Rennecke <joern.rennecke@embecosm.com>
on behalf of Synopsys Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#include "../arc-ieee-754.h"
#if 0 /* DEBUG */
.global __mulsf3
FUNC(__mulsf3)
.balign 4
__mulsf3:
push_s blink
push_s r1
bl.d __mulsf3_c
push_s r0
ld_s r1,[sp,4]
st_s r0,[sp,4]
bl.d __mulsf3_asm
pop_s r0
pop_s r1
pop_s blink
cmp r0,r1
jeq_s [blink]
and r12,r0,r1
bic.f 0,0x7f800000,r12
bne 0f
bmsk.f 0,r0,22
bmsk.ne.f r1,r1,22
jne_s [blink] ; both NaN -> OK
0: bl abort
ENDFUNC(__mulsf3)
#define __mulsf3 __mulsf3_asm
#endif /* DEBUG */
.balign 4
.global __mulsf3
FUNC(__mulsf3)
__mulsf3:
ld.as r9,[pcl,76]; [pcl,((.L7f800000-.+2)/4)]
bmsk r4,r1,22
bset r3,r4,23
bmsk r2,r0,22
and r11,r0,r9
breq.d r11,0,.Ldenorm_dbl0
and r12,r1,r9
xor_s r0,r0,r1
breq.d r11,r9,.Linf_nan_dbl0
bset_s r2,r2,23
breq r12,0,.Ldenorm_dbl1
breq r12,r9,.Linf_nan_dbl1
.Lpast_denorm:
mov r6,0
lsr.f r7,r2
; We could so this a bit faster here with a 32 bit shift register and
; inserting the r2 factor / retrieving the low result a byte at a time,
; but that'd increase code size.
mov lp_count,24
.balign 4
lp 0f
add.cs r6,r6,r3
lsr.f r6,r6
rrc.f r7,r7
0:
ld.as r4,[pcl,59]; [pcl,((.L7fffffff-.+2)/4)]
asl.f 0,r6,8
add.pl r6,r6,r6
bclr.pl r6,r6,23
add.pl.f r7,r7,r7
add.cs r6,r6,1
lsr.f 0,r6,1
add_s r12,r12,r11
adc.f 0,r7,r4
add_s r12,r12, \
-0x3f800000
adc.f r8,r6,r12
tst.pl r8,r9
bic r0,r0,r4
min r3,r8,r9
jpnz.d [blink]
add.pnz r0,r0,r3
; infinity or denormal number
add.ne.f r3,r3,r3
asr_s r3,r3,23+1
bset r6,r6,23
bpnz.d .Linfinity
sub_s r3,r3,1
neg_s r2,r3
brhi.d r2,24,.Lret_r0 ; right shift shift > 24 -> return +-0
lsr r2,r6,r2
asl r9,r6,r3
lsr.f 0,r2,1
tst r7,r7
add_s r0,r0,r2
bset.ne r9,r9,0
adc.f 0,r9,r4
j_s.d [blink]
add.cs r0,r0,1
.Linfinity:
j_s.d [blink]
add_s r0,r0,r9
.Lret_r0: j_s [blink]
.balign 4
.Ldenorm_dbl0:
asl_s r2,r2,8
norm.f r4,r2
lsr_s r2,r2,7
asl r2,r2,r4
breq.d r12,r9,.Ldenorm_dbl0_inf_nan_dbl1
asl r4,r4,23
sub.ne.f r12,r12,r4
bhi.d .Lpast_denorm
xor_s r0,r0,r1
bmsk r1,r0,30
j_s.d [blink]
bic_s r0,r0,r1
.balign 4
.Ldenorm_dbl0_inf_nan_dbl1:
bmsk.f 0,r0,30
beq_s .Lretnan
xor_s r0,r0,r1
.Linf_nan_dbl1:
xor_s r1,r1,r0
bclr_s r1,r1,31
j_s.d [blink]
xor_s r0,r0,r1
.Linf_nan_dbl0:
sub_s r2,r1,1 ; inf/nan * 0 -> nan; inf * nan -> nan (use |r2| >= inf)
bic.f 0,r9,r2
xor_s r0,r0,r1
bclr_s r1,r1,31
xor_s r0,r0,r1
jne_s [blink]
.Lretnan:
j_s.d [blink]
mov r0,-1
.balign 4
.Ldenorm_dbl1:
norm.f r3,r4
sub_s r3,r3,7
asl r4,r4,r3
sub_s r3,r3,1
asl_s r3,r3,23
sub.ne.f r11,r11,r3
bhi.d .Lpast_denorm
mov_s r3,r4
bmsk r3,r0,30
j_s.d [blink]
bic_s r0,r0,r3
.balign 4
.L7f800000:
.long 0x7f800000
.L7fffffff:
.long 0x7fffffff
ENDFUNC(__mulsf3)
|