@@ -160,6 +160,95 @@ fn get_simple_function<'gcc, 'tcx>(
160
160
) )
161
161
}
162
162
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
+
163
252
impl < ' a , ' gcc , ' tcx > IntrinsicCallBuilderMethods < ' tcx > for Builder < ' a , ' gcc , ' tcx > {
164
253
fn codegen_intrinsic_call (
165
254
& mut self ,
@@ -188,7 +277,9 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
188
277
let result = PlaceRef :: new_sized ( llresult, fn_abi. ret . layout ) ;
189
278
190
279
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) ) ;
192
283
193
284
// FIXME(tempdragon): Re-enable `clippy::suspicious_else_formatting` if the following issue is solved:
194
285
// https://github.com/rust-lang/rust-clippy/issues/12497
@@ -211,17 +302,55 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
211
302
& args. iter ( ) . map ( |arg| arg. immediate ( ) ) . collect :: < Vec < _ > > ( ) ,
212
303
)
213
304
}
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
+ )
225
354
}
226
355
sym:: is_val_statically_known => {
227
356
let a = args[ 0 ] . immediate ( ) ;
0 commit comments