@@ -45,8 +45,10 @@ 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" ,
48
49
sym:: powif32 => "__builtin_powif" ,
49
50
sym:: powif64 => "__builtin_powi" ,
51
+ sym:: powif128 => "__builtin_powil" ,
50
52
sym:: sinf32 => "sinf" ,
51
53
sym:: sinf64 => "sin" ,
52
54
sym:: cosf32 => "cosf" ,
@@ -65,29 +67,37 @@ fn get_simple_intrinsic<'gcc, 'tcx>(
65
67
sym:: log2f64 => "log2" ,
66
68
sym:: fmaf32 => "fmaf" ,
67
69
sym:: fmaf64 => "fma" ,
70
+ sym:: fmaf128 => "fmal" ,
68
71
// FIXME: calling `fma` from libc without FMA target feature uses expensive software emulation
69
72
sym:: fmuladdf32 => "fmaf" , // TODO: use gcc intrinsic analogous to llvm.fmuladd.f32
70
73
sym:: fmuladdf64 => "fma" , // TODO: use gcc intrinsic analogous to llvm.fmuladd.f64
71
74
sym:: fabsf32 => "fabsf" ,
72
75
sym:: fabsf64 => "fabs" ,
73
76
sym:: minnumf32 => "fminf" ,
74
77
sym:: minnumf64 => "fmin" ,
78
+ sym:: minnumf128 => "fminl" ,
75
79
sym:: maxnumf32 => "fmaxf" ,
76
80
sym:: maxnumf64 => "fmax" ,
81
+ sym:: maxnumf128 => "fmaxl" ,
77
82
sym:: copysignf32 => "copysignf" ,
78
83
sym:: copysignf64 => "copysign" ,
79
84
sym:: copysignf128 => "copysignl" ,
80
85
sym:: floorf32 => "floorf" ,
81
86
sym:: floorf64 => "floor" ,
87
+ sym:: floorf128 => "floorl" ,
82
88
sym:: ceilf32 => "ceilf" ,
83
89
sym:: ceilf64 => "ceil" ,
90
+ sym:: ceilf128 => "ceill" ,
84
91
sym:: truncf32 => "truncf" ,
85
92
sym:: truncf64 => "trunc" ,
93
+ sym:: truncf128 => "truncl" ,
86
94
// We match the LLVM backend and lower this to `rint`.
87
95
sym:: round_ties_even_f32 => "rintf" ,
88
96
sym:: round_ties_even_f64 => "rint" ,
97
+ sym:: round_ties_even_f128 => "rintl" ,
89
98
sym:: roundf32 => "roundf" ,
90
99
sym:: roundf64 => "round" ,
100
+ sym:: roundf128 => "roundl" ,
91
101
sym:: abort => "abort" ,
92
102
_ => return None ,
93
103
} ;
@@ -160,6 +170,40 @@ fn get_simple_function<'gcc, 'tcx>(
160
170
) )
161
171
}
162
172
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
+
163
207
impl < ' a , ' gcc , ' tcx > IntrinsicCallBuilderMethods < ' tcx > for Builder < ' a , ' gcc , ' tcx > {
164
208
fn codegen_intrinsic_call (
165
209
& mut self ,
@@ -211,18 +255,17 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
211
255
& args. iter ( ) . map ( |arg| arg. immediate ( ) ) . collect :: < Vec < _ > > ( ) ,
212
256
)
213
257
}
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) ,
226
269
sym:: is_val_statically_known => {
227
270
let a = args[ 0 ] . immediate ( ) ;
228
271
let builtin = self . context . get_builtin_function ( "__builtin_constant_p" ) ;
0 commit comments