]>
Commit | Line | Data |
---|---|---|
8d9254fc | 1 | /* Copyright (C) 2006-2020 Free Software Foundation, Inc. |
d38a64b4 JR |
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 | 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 | |
52 | 0: 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) |