@@ -160,6 +160,95 @@ fn get_simple_function<'gcc, 'tcx>(
160160 ) )
161161}
162162
163+ fn get_simple_function_f128 < ' gcc , ' tcx > (
164+ cx : & CodegenCx < ' gcc , ' tcx > ,
165+ name : Symbol ,
166+ ) -> Option < Function < ' gcc > > {
167+ if !cx. supports_f128_type {
168+ return None ;
169+ }
170+
171+ let f128_type = cx. type_f128 ( ) ;
172+ let func_name = match name {
173+ sym:: ceilf128 => "ceilf128" ,
174+ sym:: floorf128 => "floorf128" ,
175+ sym:: truncf128 => "truncf128" ,
176+ sym:: roundf128 => "roundf128" ,
177+ sym:: round_ties_even_f128 => "roundevenf128" ,
178+ sym:: sqrtf128 => "sqrtf128" ,
179+ _ => return None ,
180+ } ;
181+ Some ( cx. context . new_function (
182+ None ,
183+ FunctionType :: Extern ,
184+ f128_type,
185+ & [ cx. context . new_parameter ( None , f128_type, "a" ) ] ,
186+ func_name,
187+ false ,
188+ ) )
189+ }
190+
191+ fn get_simple_function_f128_2args < ' gcc , ' tcx > (
192+ cx : & CodegenCx < ' gcc , ' tcx > ,
193+ name : Symbol ,
194+ ) -> Option < Function < ' gcc > > {
195+ if !cx. supports_f128_type {
196+ return None ;
197+ }
198+
199+ let f128_type = cx. type_f128 ( ) ;
200+ let func_name = match name {
201+ sym:: maxnumf128 => "fmaxf128" ,
202+ sym:: minnumf128 => "fminf128" ,
203+ _ => return None ,
204+ } ;
205+ Some ( cx. context . new_function (
206+ None ,
207+ FunctionType :: Extern ,
208+ f128_type,
209+ & [
210+ cx. context . new_parameter ( None , f128_type, "a" ) ,
211+ cx. context . new_parameter ( None , f128_type, "b" ) ,
212+ ] ,
213+ func_name,
214+ false ,
215+ ) )
216+ }
217+
218+ fn f16_builtin < ' gcc , ' tcx > (
219+ cx : & CodegenCx < ' gcc , ' tcx > ,
220+ name : Symbol ,
221+ args : & [ OperandRef < ' tcx , RValue < ' gcc > > ] ,
222+ ) -> RValue < ' gcc > {
223+ let f32_type = cx. type_f32 ( ) ;
224+ let builtin_name = match name {
225+ sym:: ceilf16 => "__builtin_ceilf" ,
226+ sym:: floorf16 => "__builtin_floorf" ,
227+ sym:: fmaf16 => "fmaf" ,
228+ sym:: maxnumf16 => "__builtin_fmaxf" ,
229+ sym:: minnumf16 => "__builtin_fminf" ,
230+ sym:: powf16 => "__builtin_powf" ,
231+ sym:: powif16 => {
232+ let func = cx. context . get_builtin_function ( "__builtin_powif" ) ;
233+ let arg0 = cx. context . new_cast ( None , args[ 0 ] . immediate ( ) , f32_type) ;
234+ let args = [ arg0, args[ 1 ] . immediate ( ) ] ;
235+ let result = cx. context . new_call ( None , func, & args) ;
236+ return cx. context . new_cast ( None , result, cx. type_f16 ( ) ) ;
237+ }
238+ sym:: roundf16 => "__builtin_roundf" ,
239+ sym:: round_ties_even_f16 => "__builtin_rintf" ,
240+ sym:: sqrtf16 => "__builtin_sqrtf" ,
241+ sym:: truncf16 => "__builtin_truncf" ,
242+ _ => unreachable ! ( ) ,
243+ } ;
244+
245+ let func = cx. context . get_builtin_function ( builtin_name) ;
246+ let args: Vec < _ > =
247+ args. iter ( ) . map ( |arg| cx. context . new_cast ( None , arg. immediate ( ) , f32_type) ) . collect ( ) ;
248+ let result = cx. context . new_call ( None , func, & args) ;
249+ cx. context . new_cast ( None , result, cx. type_f16 ( ) )
250+ }
251+
163252impl < ' a , ' gcc , ' tcx > IntrinsicCallBuilderMethods < ' tcx > for Builder < ' a , ' gcc , ' tcx > {
164253 fn codegen_intrinsic_call (
165254 & mut self ,
@@ -188,7 +277,9 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
188277 let result = PlaceRef :: new_sized ( llresult, fn_abi. ret . layout ) ;
189278
190279 let simple = get_simple_intrinsic ( self , name) ;
191- let simple_func = get_simple_function ( self , name) ;
280+ let simple_func = get_simple_function ( self , name)
281+ . or_else ( || get_simple_function_f128 ( self , name) )
282+ . or_else ( || get_simple_function_f128_2args ( self , name) ) ;
192283
193284 // FIXME(tempdragon): Re-enable `clippy::suspicious_else_formatting` if the following issue is solved:
194285 // https://github.com/rust-lang/rust-clippy/issues/12497
@@ -211,17 +302,55 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
211302 & args. iter ( ) . map ( |arg| arg. immediate ( ) ) . collect :: < Vec < _ > > ( ) ,
212303 )
213304 }
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 ( ) )
305+ sym:: ceilf16
306+ | sym:: floorf16
307+ | sym:: fmaf16
308+ | sym:: maxnumf16
309+ | sym:: minnumf16
310+ | sym:: powf16
311+ | sym:: powif16
312+ | sym:: roundf16
313+ | sym:: round_ties_even_f16
314+ | sym:: sqrtf16
315+ | sym:: truncf16 => f16_builtin ( self , name, args) ,
316+ sym:: fmaf128 => {
317+ let f128_type = self . cx . type_f128 ( ) ;
318+ let func = self . cx . context . new_function (
319+ None ,
320+ FunctionType :: Extern ,
321+ f128_type,
322+ & [
323+ self . cx . context . new_parameter ( None , f128_type, "a" ) ,
324+ self . cx . context . new_parameter ( None , f128_type, "b" ) ,
325+ self . cx . context . new_parameter ( None , f128_type, "c" ) ,
326+ ] ,
327+ "fmaf128" ,
328+ false ,
329+ ) ;
330+ self . cx . context . new_call (
331+ self . location ,
332+ func,
333+ & args. iter ( ) . map ( |arg| arg. immediate ( ) ) . collect :: < Vec < _ > > ( ) ,
334+ )
335+ }
336+ sym:: powif128 => {
337+ let f128_type = self . cx . type_f128 ( ) ;
338+ let func = self . cx . context . new_function (
339+ None ,
340+ FunctionType :: Extern ,
341+ f128_type,
342+ & [
343+ self . cx . context . new_parameter ( None , f128_type, "a" ) ,
344+ self . cx . context . new_parameter ( None , self . int_type , "b" ) ,
345+ ] ,
346+ "__powitf2" ,
347+ false ,
348+ ) ;
349+ self . cx . context . new_call (
350+ self . location ,
351+ func,
352+ & args. iter ( ) . map ( |arg| arg. immediate ( ) ) . collect :: < Vec < _ > > ( ) ,
353+ )
225354 }
226355 sym:: is_val_statically_known => {
227356 let a = args[ 0 ] . immediate ( ) ;
0 commit comments