summaryrefslogtreecommitdiff
path: root/libgcc/config/arc/ieee-754/arc600/mulsf3.S
blob: 9c48a99f2a735e61caeab2bd7e60161e8a157910 (plain)
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-2016 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)