File tree Expand file tree Collapse file tree 6 files changed +91
-28
lines changed
library/compiler-builtins
compiler-rt/compiler-rt-cdylib Expand file tree Collapse file tree 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.
159159- [x] mulodi4.c
160160- [x] mulosi4.c
161161- [ ] mulsf3.c
162- - [ ] powidf2.c
163- - [ ] powisf2.c
162+ - [x ] powidf2.c
163+ - [x ] powisf2.c
164164- [ ] subdf3.c
165165- [ ] subsf3.c
166166- [ ] truncdfhf2.c
Original file line number Diff line number Diff line change @@ -58,6 +58,8 @@ fn main() {
5858 "udivmodsi4.c" ,
5959 "adddf3.c" ,
6060 "addsf3.c" ,
61+ "powidf2.c" ,
62+ "powisf2.c" ,
6163 ] ) ;
6264
6365 for src in sources. files . iter ( ) {
Original file line number Diff line number Diff line change @@ -22,6 +22,8 @@ extern {
2222 fn __umodsi3 ( ) ;
2323 fn __addsf3 ( ) ;
2424 fn __adddf3 ( ) ;
25+ fn __powisf2 ( ) ;
26+ fn __powidf2 ( ) ;
2527}
2628
2729macro_rules! declare {
@@ -53,6 +55,8 @@ declare!(___umoddi3, __umoddi3);
5355declare ! ( ___umodsi3, __umodsi3) ;
5456declare ! ( ___addsf3, __addsf3) ;
5557declare ! ( ___adddf3, __adddf3) ;
58+ declare ! ( ___powisf2, __powisf2) ;
59+ declare ! ( ___powidf2, __powidf2) ;
5660
5761#[ lang = "eh_personality" ]
5862fn eh_personality ( ) { }
Original file line number Diff line number Diff line change @@ -186,35 +186,10 @@ add!(__adddf3: f64);
186186#[ cfg( test) ]
187187mod tests {
188188 use core:: { f32, f64} ;
189- use core:: fmt;
190189
191- use float:: Float ;
190+ use float:: { Float , FRepr } ;
192191 use qc:: { U32 , U64 } ;
193192
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-
218193 // TODO: Add F32/F64 to qc so that they print the right values (at the very least)
219194 check ! {
220195 fn __addsf3( f: extern fn ( f32 , f32 ) -> f32 ,
Original file line number Diff line number Diff line change 11use core:: mem;
2+ use core:: fmt;
23
34pub mod add;
5+ pub mod pow;
46
57/// Trait for some basic operations on floats
68pub trait Float : Sized + Copy {
@@ -85,3 +87,30 @@ impl Float for f64 {
8587 ( 1i32 . wrapping_sub ( shift as i32 ) , significand << shift as Self :: Int )
8688 }
8789}
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