1/* Copyright (C) 2006-2021 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	FUNC(__truncdfsf2)
30	.global __truncdfsf2
31	.balign 4
32__truncdfsf2:
33	push_s blink
34	push_s r0
35	bl.d __truncdfsf2_c
36	push_s r1
37	mov_s r2,r0
38	pop_s r1
39	ld r0,[sp]
40	bl.d __truncdfsf2_asm
41	st r2,[sp]
42	pop_s r1
43	pop_s blink
44	cmp r0,r1
45	jeq_s [blink]
46	and r12,r0,r1
47	bic.f 0,0x7f800000,r12
48	bne 0f
49	bmsk.f 0,r0,22
50	bmsk.ne.f r1,r1,22
51	jne_s [blink] ; both NaN -> OK
520:	bl abort
53	ENDFUNC(__truncdfsf2)
54#define __truncdfsf2 __truncdfsf2_asm
55#endif /* DEBUG */
56
57	.global __truncdfsf2
58	.balign 4
59	FUNC(__truncdfsf2)
60__truncdfsf2:
61	lsr r2,DBL0H,20
62	asl_s DBL0H,DBL0H,12
63	sub r12,r2,0x380
64	bclr.f r3,r12,11
65	brhs r3,0xff,.Lill_exp
66	beq_l .Ldenorm0
67	asl_s r12,r12,23
68	tst DBL0L, \
69		0x2fffffff /* Check if msb guard bit wants rounding up.  */
70	lsr_s DBL0L,DBL0L,28
71	lsr_s DBL0H,DBL0H,8
72	add.ne DBL0L,DBL0L,1
73	add_s DBL0H,DBL0H,DBL0L
74	lsr_s DBL0H,DBL0H
75	btst_s r2,11
76	add_s r0,DBL0H,r12
77	j_s.d [blink]
78	bxor.ne r0,r0,31
79	.balign 4
80.Lill_exp:
81	bbit1 r2,10,.Linf_nan
82	bmsk_s r12,r12,9
83	rsub.f r12,r12,8+0x400-32 ; Go from 9 to 1 guard bit in MSW.  */
84	bhs_s .Lzero
85	lsr r3,DBL0L,21
86	rrc DBL0H,DBL0H ; insert leading 1
87	asl.f 0,DBL0L,8 ; check lower 24 guard bits
88	add_s r3,DBL0H,r3
89	add.pnz r3,r3,1 ; assemble fraction with compressed guard bits.
90	lsr r0,r3,r12
91	neg_s r12,r12
92	btst_s r0,1
93	asl.eq.f r3,r3,r12
94	add.ne r0,r0,1
95	btst_s r2,11
96	lsr_s r0,r0
97	j_s.d [blink]
98	bxor.ne r0,r0,31
99.Lzero:
100	lsr_s r2,r2,11
101	j_s.d [blink]
102	asl r0,r2,31
103.Ldenorm0:
104	asl_s r12,r12,20
105	tst DBL0L, \
106		0x5fffffff /* Check if msb guard bit wants rounding up.  */
107	lsr_s DBL0L,DBL0L,29
108	lsr_s DBL0H,DBL0H,9
109	add.ne DBL0L,DBL0L,1
110	bset_s DBL0H,DBL0H,23
111	add_s DBL0H,DBL0H,DBL0L
112	lsr_s DBL0H,DBL0H
113	j_s.d [blink]
114	add_l r0,DBL0H,r12
115
116/* We would generally say that NaNs must have a non-zero high fraction part,
117   but to allow hardware double precision floating point to interoperate
118   with single precision software floating point, we make an exception here.
119   The cost is to replace a tst_s DBL0H with an or.f DBL0L,DBL0L,DBL0H .
120   As we start out unaligned, and there is an odd number of other short insns,
121   we have a choice of letting this cost us a misalign penalty or
122   4 more bytes (if we align the code).  We choose the former here because
123   infinity / NaN is not expected to be prevalent in time-critical code.  */
124.Linf_nan:
125	or.f DBL0L,DBL0L,DBL0H
126	mov_s r0,1
127	add.ne r2,r2,1
128	tst r2,0x7ff
129	asl.ne r0,r0,23
130	btst_s r12,11
131	neg r0,r0
132	j_s.d [blink]
133	bxor.eq r0,r0,31
134	ENDFUNC(__truncdfsf2)
135