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
|
/* Copyright (C) 2006-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 */
FUNC(__truncdfsf2)
.global __truncdfsf2
.balign 4
__truncdfsf2:
push_s blink
push_s r0
bl.d __truncdfsf2_c
push_s r1
mov_s r2,r0
pop_s r1
ld r0,[sp]
bl.d __truncdfsf2_asm
st r2,[sp]
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(__truncdfsf2)
#define __truncdfsf2 __truncdfsf2_asm
#endif /* DEBUG */
.global __truncdfsf2
.balign 4
FUNC(__truncdfsf2)
__truncdfsf2:
lsr r2,DBL0H,20
asl_s DBL0H,DBL0H,12
sub r12,r2,0x380
bclr.f r3,r12,11
brhs r3,0xff,.Lill_exp
beq_l .Ldenorm0
asl_s r12,r12,23
tst DBL0L, \
0x2fffffff /* Check if msb guard bit wants rounding up. */
lsr_s DBL0L,DBL0L,28
lsr_s DBL0H,DBL0H,8
add.ne DBL0L,DBL0L,1
add_s DBL0H,DBL0H,DBL0L
lsr_s DBL0H,DBL0H
btst_s r2,11
add_s r0,DBL0H,r12
j_s.d [blink]
bxor.ne r0,r0,31
.balign 4
.Lill_exp:
bbit1 r2,10,.Linf_nan
bmsk_s r12,r12,9
rsub.f r12,r12,8+0x400-32 ; Go from 9 to 1 guard bit in MSW. */
bhs_s .Lzero
lsr r3,DBL0L,21
rrc DBL0H,DBL0H ; insert leading 1
asl.f 0,DBL0L,8 ; check lower 24 guard bits
add_s r3,DBL0H,r3
add.pnz r3,r3,1 ; assemble fraction with compressed guard bits.
lsr r0,r3,r12
neg_s r12,r12
btst_s r0,1
asl.eq.f r3,r3,r12
add.ne r0,r0,1
btst_s r2,11
lsr_s r0,r0
j_s.d [blink]
bxor.ne r0,r0,31
.Lzero:
lsr_s r2,r2,11
j_s.d [blink]
asl r0,r2,31
.Ldenorm0:
asl_s r12,r12,20
tst DBL0L, \
0x5fffffff /* Check if msb guard bit wants rounding up. */
lsr_s DBL0L,DBL0L,29
lsr_s DBL0H,DBL0H,9
add.ne DBL0L,DBL0L,1
bset_s DBL0H,DBL0H,23
add_s DBL0H,DBL0H,DBL0L
lsr_s DBL0H,DBL0H
j_s.d [blink]
add_l r0,DBL0H,r12
/* We would generally say that NaNs must have a non-zero high fraction part,
but to allow hardware double precision floating point to interoperate
with single precision software floating point, we make an exception here.
The cost is to replace a tst_s DBL0H with an or.f DBL0L,DBL0L,DBL0H .
As we start out unaligned, and there is an odd number of other short insns,
we have a choice of letting this cost us a misalign penalty or
4 more bytes (if we align the code). We choose the former here because
infinity / NaN is not expected to be prevalent in time-critical code. */
.Linf_nan:
or.f DBL0L,DBL0L,DBL0H
mov_s r0,1
add.ne r2,r2,1
tst r2,0x7ff
asl.ne r0,r0,23
btst_s r12,11
neg r0,r0
j_s.d [blink]
bxor.eq r0,r0,31
ENDFUNC(__truncdfsf2)
|