File tree 6 files changed +91
-28
lines changed
compiler-rt/compiler-rt-cdylib
6 files changed +91
-28
lines changed Original file line number Diff line number Diff line change @@ -159,8 +159,8 @@ porting that particular intrinsic.
159
159
- [x] mulodi4.c
160
160
- [x] mulosi4.c
161
161
- [ ] mulsf3.c
162
- - [ ] powidf2.c
163
- - [ ] powisf2.c
162
+ - [x ] powidf2.c
163
+ - [x ] powisf2.c
164
164
- [ ] subdf3.c
165
165
- [ ] subsf3.c
166
166
- [ ] truncdfhf2.c
Original file line number Diff line number Diff line change @@ -58,6 +58,8 @@ fn main() {
58
58
"udivmodsi4.c" ,
59
59
"adddf3.c" ,
60
60
"addsf3.c" ,
61
+ "powidf2.c" ,
62
+ "powisf2.c" ,
61
63
] ) ;
62
64
63
65
for src in sources. files . iter ( ) {
Original file line number Diff line number Diff line change @@ -22,6 +22,8 @@ extern {
22
22
fn __umodsi3 ( ) ;
23
23
fn __addsf3 ( ) ;
24
24
fn __adddf3 ( ) ;
25
+ fn __powisf2 ( ) ;
26
+ fn __powidf2 ( ) ;
25
27
}
26
28
27
29
macro_rules! declare {
@@ -53,6 +55,8 @@ declare!(___umoddi3, __umoddi3);
53
55
declare ! ( ___umodsi3, __umodsi3) ;
54
56
declare ! ( ___addsf3, __addsf3) ;
55
57
declare ! ( ___adddf3, __adddf3) ;
58
+ declare ! ( ___powisf2, __powisf2) ;
59
+ declare ! ( ___powidf2, __powidf2) ;
56
60
57
61
#[ lang = "eh_personality" ]
58
62
fn eh_personality ( ) { }
Original file line number Diff line number Diff line change @@ -186,35 +186,10 @@ add!(__adddf3: f64);
186
186
#[ cfg( test) ]
187
187
mod tests {
188
188
use core:: { f32, f64} ;
189
- use core:: fmt;
190
189
191
- use float:: Float ;
190
+ use float:: { Float , FRepr } ;
192
191
use qc:: { U32 , U64 } ;
193
192
194
- // TODO: Move this to F32/F64 in qc.rs
195
- #[ derive( Copy , Clone ) ]
196
- struct FRepr < F > ( F ) ;
197
-
198
- impl < F : Float > PartialEq for FRepr < F > {
199
- fn eq ( & self , other : & FRepr < F > ) -> bool {
200
- // NOTE(cfg) for some reason, on hard float targets, our implementation doesn't
201
- // match the output of its gcc_s counterpart. Until we investigate further, we'll
202
- // just avoid testing against gcc_s on those targets. Do note that our
203
- // implementation matches the output of the FPU instruction on *hard* float targets
204
- // and matches its gcc_s counterpart on *soft* float targets.
205
- if cfg ! ( gnueabihf) {
206
- return true
207
- }
208
- self . 0 . eq_repr ( other. 0 )
209
- }
210
- }
211
-
212
- impl < F : fmt:: Debug > fmt:: Debug for FRepr < F > {
213
- fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
214
- self . 0 . fmt ( f)
215
- }
216
- }
217
-
218
193
// TODO: Add F32/F64 to qc so that they print the right values (at the very least)
219
194
check ! {
220
195
fn __addsf3( f: extern fn ( f32 , f32 ) -> f32 ,
Original file line number Diff line number Diff line change 1
1
use core:: mem;
2
+ use core:: fmt;
2
3
3
4
pub mod add;
5
+ pub mod pow;
4
6
5
7
/// Trait for some basic operations on floats
6
8
pub trait Float : Sized + Copy {
@@ -85,3 +87,30 @@ impl Float for f64 {
85
87
( 1i32 . wrapping_sub ( shift as i32 ) , significand << shift as Self :: Int )
86
88
}
87
89
}
90
+
91
+ // TODO: Move this to F32/F64 in qc.rs
92
+ #[ cfg( test) ]
93
+ #[ derive( Copy , Clone ) ]
94
+ pub struct FRepr < F > ( F ) ;
95
+
96
+ #[ cfg( test) ]
97
+ impl < F : Float > PartialEq for FRepr < F > {
98
+ fn eq ( & self , other : & FRepr < F > ) -> bool {
99
+ // NOTE(cfg) for some reason, on hard float targets, our implementation doesn't
100
+ // match the output of its gcc_s counterpart. Until we investigate further, we'll
101
+ // just avoid testing against gcc_s on those targets. Do note that our
102
+ // implementation matches the output of the FPU instruction on *hard* float targets
103
+ // and matches its gcc_s counterpart on *soft* float targets.
104
+ if cfg ! ( gnueabihf) {
105
+ return true
106
+ }
107
+ self . 0 . eq_repr ( other. 0 )
108
+ }
109
+ }
110
+
111
+ #[ cfg( test) ]
112
+ impl < F : fmt:: Debug > fmt:: Debug for FRepr < F > {
113
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
114
+ self . 0 . fmt ( f)
115
+ }
116
+ }
Original file line number Diff line number Diff line change
1
+
2
+ macro_rules! pow {
3
+ ( $intrinsic: ident: $fty: ty, $ity: ty) => {
4
+ /// Returns `a` raised to the power `b`
5
+ #[ cfg_attr( not( test) , no_mangle) ]
6
+ pub extern "C" fn $intrinsic( a: $fty, b: $ity) -> $fty {
7
+ let ( mut a, mut b) = ( a, b) ;
8
+ let recip = b < 0 ;
9
+ let mut r: $fty = 1.0 ;
10
+ loop {
11
+ if ( b & 1 ) != 0 {
12
+ r *= a;
13
+ }
14
+ b /= 2 ;
15
+ if b == 0 {
16
+ break ;
17
+ }
18
+ a *= a;
19
+ }
20
+
21
+ if recip {
22
+ 1.0 / r
23
+ } else {
24
+ r
25
+ }
26
+ }
27
+ }
28
+ }
29
+
30
+ pow ! ( __powisf2: f32 , i32 ) ;
31
+ pow ! ( __powidf2: f64 , i32 ) ;
32
+
33
+ #[ cfg( test) ]
34
+ mod tests {
35
+ use float:: { Float , FRepr } ;
36
+ use qc:: { I32 , U32 , U64 } ;
37
+
38
+ check ! {
39
+ fn __powisf2( f: extern fn ( f32 , i32 ) -> f32 ,
40
+ a: U32 ,
41
+ b: I32 ) -> Option <FRepr <f32 > > {
42
+ let ( a, b) = ( f32 :: from_repr( a. 0 ) , b. 0 ) ;
43
+ Some ( FRepr ( f( a, b) ) )
44
+ }
45
+
46
+ fn __powidf2( f: extern fn ( f64 , i32 ) -> f64 ,
47
+ a: U64 ,
48
+ b: I32 ) -> Option <FRepr <f64 > > {
49
+ let ( a, b) = ( f64 :: from_repr( a. 0 ) , b. 0 ) ;
50
+ Some ( FRepr ( f( a, b) ) )
51
+ }
52
+ }
53
+ }
You can’t perform that action at this time.
0 commit comments