@@ -45,10 +45,8 @@ fn get_simple_intrinsic<'gcc, 'tcx>(
45
45
let gcc_name = match name {
46
46
sym:: sqrtf32 => "sqrtf" ,
47
47
sym:: sqrtf64 => "sqrt" ,
48
- sym:: sqrtf128 => "sqrtl" ,
49
48
sym:: powif32 => "__builtin_powif" ,
50
49
sym:: powif64 => "__builtin_powi" ,
51
- sym:: powif128 => "__builtin_powil" ,
52
50
sym:: sinf32 => "sinf" ,
53
51
sym:: sinf64 => "sin" ,
54
52
sym:: cosf32 => "cosf" ,
@@ -67,37 +65,29 @@ fn get_simple_intrinsic<'gcc, 'tcx>(
67
65
sym:: log2f64 => "log2" ,
68
66
sym:: fmaf32 => "fmaf" ,
69
67
sym:: fmaf64 => "fma" ,
70
- sym:: fmaf128 => "fmal" ,
71
68
// FIXME: calling `fma` from libc without FMA target feature uses expensive software emulation
72
69
sym:: fmuladdf32 => "fmaf" , // TODO: use gcc intrinsic analogous to llvm.fmuladd.f32
73
70
sym:: fmuladdf64 => "fma" , // TODO: use gcc intrinsic analogous to llvm.fmuladd.f64
74
71
sym:: fabsf32 => "fabsf" ,
75
72
sym:: fabsf64 => "fabs" ,
76
73
sym:: minnumf32 => "fminf" ,
77
74
sym:: minnumf64 => "fmin" ,
78
- sym:: minnumf128 => "fminl" ,
79
75
sym:: maxnumf32 => "fmaxf" ,
80
76
sym:: maxnumf64 => "fmax" ,
81
- sym:: maxnumf128 => "fmaxl" ,
82
77
sym:: copysignf32 => "copysignf" ,
83
78
sym:: copysignf64 => "copysign" ,
84
79
sym:: copysignf128 => "copysignl" ,
85
80
sym:: floorf32 => "floorf" ,
86
81
sym:: floorf64 => "floor" ,
87
- sym:: floorf128 => "floorl" ,
88
82
sym:: ceilf32 => "ceilf" ,
89
83
sym:: ceilf64 => "ceil" ,
90
- sym:: ceilf128 => "ceill" ,
91
84
sym:: truncf32 => "truncf" ,
92
85
sym:: truncf64 => "trunc" ,
93
- sym:: truncf128 => "truncl" ,
94
86
// We match the LLVM backend and lower this to `rint`.
95
87
sym:: round_ties_even_f32 => "rintf" ,
96
88
sym:: round_ties_even_f64 => "rint" ,
97
- sym:: round_ties_even_f128 => "rintl" ,
98
89
sym:: roundf32 => "roundf" ,
99
90
sym:: roundf64 => "round" ,
100
- sym:: roundf128 => "roundl" ,
101
91
sym:: abort => "abort" ,
102
92
_ => return None ,
103
93
} ;
@@ -170,6 +160,61 @@ fn get_simple_function<'gcc, 'tcx>(
170
160
) )
171
161
}
172
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
+
173
218
fn f16_builtin < ' gcc , ' tcx > (
174
219
cx : & CodegenCx < ' gcc , ' tcx > ,
175
220
name : Symbol ,
@@ -232,7 +277,9 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
232
277
let result = PlaceRef :: new_sized ( llresult, fn_abi. ret . layout ) ;
233
278
234
279
let simple = get_simple_intrinsic ( self , name) ;
235
- 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) ) ;
236
283
237
284
// FIXME(tempdragon): Re-enable `clippy::suspicious_else_formatting` if the following issue is solved:
238
285
// https://github.com/rust-lang/rust-clippy/issues/12497
@@ -266,6 +313,45 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
266
313
| sym:: round_ties_even_f16
267
314
| sym:: sqrtf16
268
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
+ )
354
+ }
269
355
sym:: is_val_statically_known => {
270
356
let a = args[ 0 ] . immediate ( ) ;
271
357
let builtin = self . context . get_builtin_function ( "__builtin_constant_p" ) ;
0 commit comments