1
1
use std:: borrow:: Cow ;
2
2
3
3
use gccjit:: { Function , FunctionPtrType , RValue , ToRValue , UnaryOp } ;
4
+ use rustc_codegen_ssa:: traits:: BuilderMethods ;
4
5
5
6
use crate :: { context:: CodegenCx , builder:: Builder } ;
6
7
@@ -277,14 +278,23 @@ pub fn adjust_intrinsic_arguments<'a, 'b, 'gcc, 'tcx>(builder: &Builder<'a, 'gcc
277
278
* arg3 = builder. context . new_unary_op ( None , UnaryOp :: Minus , arg3. get_type ( ) , * arg3) ;
278
279
args = new_args. into ( ) ;
279
280
} ,
281
+ "__builtin_ia32_ldmxcsr" => {
282
+ // The builtin __builtin_ia32_ldmxcsr takes an integer value while llvm.x86.sse.ldmxcsr takes a pointer,
283
+ // so dereference the pointer.
284
+ let mut new_args = args. to_vec ( ) ;
285
+ let uint_ptr_type = builder. uint_type . make_pointer ( ) ;
286
+ let arg1 = builder. context . new_cast ( None , args[ 0 ] , uint_ptr_type) ;
287
+ new_args[ 0 ] = arg1. dereference ( None ) . to_rvalue ( ) ;
288
+ args = new_args. into ( ) ;
289
+ } ,
280
290
_ => ( ) ,
281
291
}
282
292
}
283
293
284
294
args
285
295
}
286
296
287
- pub fn adjust_intrinsic_return_value < ' a , ' gcc , ' tcx > ( builder : & Builder < ' a , ' gcc , ' tcx > , mut return_value : RValue < ' gcc > , func_name : & str , args : & [ RValue < ' gcc > ] , args_adjusted : bool ) -> RValue < ' gcc > {
297
+ pub fn adjust_intrinsic_return_value < ' a , ' gcc , ' tcx > ( builder : & Builder < ' a , ' gcc , ' tcx > , mut return_value : RValue < ' gcc > , func_name : & str , args : & [ RValue < ' gcc > ] , args_adjusted : bool , orig_args : & [ RValue < ' gcc > ] ) -> RValue < ' gcc > {
288
298
match func_name {
289
299
"__builtin_ia32_vfmaddss3_round" | "__builtin_ia32_vfmaddsd3_round" => {
290
300
#[ cfg( feature="master" ) ]
@@ -306,6 +316,18 @@ pub fn adjust_intrinsic_return_value<'a, 'gcc, 'tcx>(builder: &Builder<'a, 'gcc,
306
316
return_value = builder. context . new_struct_constructor ( None , struct_type. as_type ( ) , None , & [ return_value, last_arg. dereference ( None ) . to_rvalue ( ) ] ) ;
307
317
}
308
318
} ,
319
+ "__builtin_ia32_stmxcsr" => {
320
+ // The builtin __builtin_ia32_stmxcsr returns a value while llvm.x86.sse.stmxcsr writes
321
+ // the result in its pointer argument.
322
+ // We removed the argument since __builtin_ia32_stmxcsr takes no arguments, so we need
323
+ // to get back the original argument to get the pointer we need to write the result to.
324
+ let uint_ptr_type = builder. uint_type . make_pointer ( ) ;
325
+ let ptr = builder. context . new_cast ( None , orig_args[ 0 ] , uint_ptr_type) ;
326
+ builder. llbb ( ) . add_assignment ( None , ptr. dereference ( None ) , return_value) ;
327
+ // The return value was assigned to the result pointer above. In order to not call the
328
+ // builtin twice, we overwrite the return value with a dummy value.
329
+ return_value = builder. context . new_rvalue_zero ( builder. int_type ) ;
330
+ } ,
309
331
_ => ( ) ,
310
332
}
311
333
0 commit comments