@@ -45,8 +45,10 @@ fn get_simple_intrinsic<'gcc, 'tcx>(
4545 let gcc_name = match name {
4646 sym:: sqrtf32 => "sqrtf" ,
4747 sym:: sqrtf64 => "sqrt" ,
48+ sym:: sqrtf128 => "sqrtl" ,
4849 sym:: powif32 => "__builtin_powif" ,
4950 sym:: powif64 => "__builtin_powi" ,
51+ sym:: powif128 => "__builtin_powil" ,
5052 sym:: sinf32 => "sinf" ,
5153 sym:: sinf64 => "sin" ,
5254 sym:: cosf32 => "cosf" ,
@@ -65,29 +67,37 @@ fn get_simple_intrinsic<'gcc, 'tcx>(
6567 sym:: log2f64 => "log2" ,
6668 sym:: fmaf32 => "fmaf" ,
6769 sym:: fmaf64 => "fma" ,
70+ sym:: fmaf128 => "fmal" ,
6871 // FIXME: calling `fma` from libc without FMA target feature uses expensive software emulation
6972 sym:: fmuladdf32 => "fmaf" , // TODO: use gcc intrinsic analogous to llvm.fmuladd.f32
7073 sym:: fmuladdf64 => "fma" , // TODO: use gcc intrinsic analogous to llvm.fmuladd.f64
7174 sym:: fabsf32 => "fabsf" ,
7275 sym:: fabsf64 => "fabs" ,
7376 sym:: minnumf32 => "fminf" ,
7477 sym:: minnumf64 => "fmin" ,
78+ sym:: minnumf128 => "fminl" ,
7579 sym:: maxnumf32 => "fmaxf" ,
7680 sym:: maxnumf64 => "fmax" ,
81+ sym:: maxnumf128 => "fmaxl" ,
7782 sym:: copysignf32 => "copysignf" ,
7883 sym:: copysignf64 => "copysign" ,
7984 sym:: copysignf128 => "copysignl" ,
8085 sym:: floorf32 => "floorf" ,
8186 sym:: floorf64 => "floor" ,
87+ sym:: floorf128 => "floorl" ,
8288 sym:: ceilf32 => "ceilf" ,
8389 sym:: ceilf64 => "ceil" ,
90+ sym:: ceilf128 => "ceill" ,
8491 sym:: truncf32 => "truncf" ,
8592 sym:: truncf64 => "trunc" ,
93+ sym:: truncf128 => "truncl" ,
8694 // We match the LLVM backend and lower this to `rint`.
8795 sym:: round_ties_even_f32 => "rintf" ,
8896 sym:: round_ties_even_f64 => "rint" ,
97+ sym:: round_ties_even_f128 => "rintl" ,
8998 sym:: roundf32 => "roundf" ,
9099 sym:: roundf64 => "round" ,
100+ sym:: roundf128 => "roundl" ,
91101 sym:: abort => "abort" ,
92102 _ => return None ,
93103 } ;
@@ -160,6 +170,40 @@ fn get_simple_function<'gcc, 'tcx>(
160170 ) )
161171}
162172
173+ fn f16_builtin < ' gcc , ' tcx > (
174+ cx : & CodegenCx < ' gcc , ' tcx > ,
175+ name : Symbol ,
176+ args : & [ OperandRef < ' tcx , RValue < ' gcc > > ] ,
177+ ) -> RValue < ' gcc > {
178+ let f32_type = cx. type_f32 ( ) ;
179+ let builtin_name = match name {
180+ sym:: ceilf16 => "__builtin_ceilf" ,
181+ sym:: floorf16 => "__builtin_floorf" ,
182+ sym:: fmaf16 => "fmaf" ,
183+ sym:: maxnumf16 => "__builtin_fmaxf" ,
184+ sym:: minnumf16 => "__builtin_fminf" ,
185+ sym:: powf16 => "__builtin_powf" ,
186+ sym:: powif16 => {
187+ let func = cx. context . get_builtin_function ( "__builtin_powif" ) ;
188+ let arg0 = cx. context . new_cast ( None , args[ 0 ] . immediate ( ) , f32_type) ;
189+ let args = [ arg0, args[ 1 ] . immediate ( ) ] ;
190+ let result = cx. context . new_call ( None , func, & args) ;
191+ return cx. context . new_cast ( None , result, cx. type_f16 ( ) ) ;
192+ }
193+ sym:: roundf16 => "__builtin_roundf" ,
194+ sym:: round_ties_even_f16 => "__builtin_rintf" ,
195+ sym:: sqrtf16 => "__builtin_sqrtf" ,
196+ sym:: truncf16 => "__builtin_truncf" ,
197+ _ => unreachable ! ( ) ,
198+ } ;
199+
200+ let func = cx. context . get_builtin_function ( builtin_name) ;
201+ let args: Vec < _ > =
202+ args. iter ( ) . map ( |arg| cx. context . new_cast ( None , arg. immediate ( ) , f32_type) ) . collect ( ) ;
203+ let result = cx. context . new_call ( None , func, & args) ;
204+ cx. context . new_cast ( None , result, cx. type_f16 ( ) )
205+ }
206+
163207impl < ' a , ' gcc , ' tcx > IntrinsicCallBuilderMethods < ' tcx > for Builder < ' a , ' gcc , ' tcx > {
164208 fn codegen_intrinsic_call (
165209 & mut self ,
@@ -211,18 +255,17 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
211255 & args. iter ( ) . map ( |arg| arg. immediate ( ) ) . collect :: < Vec < _ > > ( ) ,
212256 )
213257 }
214- sym:: fmaf16 => {
215- // TODO(antoyo): use the correct builtin for f16.
216- let func = self . cx . context . get_builtin_function ( "fmaf" ) ;
217- let args: Vec < _ > = args
218- . iter ( )
219- . map ( |arg| {
220- self . cx . context . new_cast ( self . location , arg. immediate ( ) , self . cx . type_f32 ( ) )
221- } )
222- . collect ( ) ;
223- let result = self . cx . context . new_call ( self . location , func, & args) ;
224- self . cx . context . new_cast ( self . location , result, self . cx . type_f16 ( ) )
225- }
258+ sym:: ceilf16
259+ | sym:: floorf16
260+ | sym:: fmaf16
261+ | sym:: maxnumf16
262+ | sym:: minnumf16
263+ | sym:: powf16
264+ | sym:: powif16
265+ | sym:: roundf16
266+ | sym:: round_ties_even_f16
267+ | sym:: sqrtf16
268+ | sym:: truncf16 => f16_builtin ( self , name, args) ,
226269 sym:: is_val_statically_known => {
227270 let a = args[ 0 ] . immediate ( ) ;
228271 let builtin = self . context . get_builtin_function ( "__builtin_constant_p" ) ;
0 commit comments