11//! Various operations on integer and floating-point numbers
22
3+ use crate :: codegen_f16_f128;
34use crate :: prelude:: * ;
45
56fn bin_op_to_intcc ( bin_op : BinOp , signed : bool ) -> IntCC {
@@ -350,25 +351,60 @@ pub(crate) fn codegen_float_binop<'tcx>(
350351 let lhs = in_lhs. load_scalar ( fx) ;
351352 let rhs = in_rhs. load_scalar ( fx) ;
352353
354+ // FIXME(bytecodealliance/wasmtime#8312): Remove once backend lowerings have
355+ // been added to Cranelift.
356+ let ( lhs, rhs) = if * in_lhs. layout ( ) . ty . kind ( ) == ty:: Float ( FloatTy :: F16 ) {
357+ ( codegen_f16_f128:: f16_to_f32 ( fx, lhs) , codegen_f16_f128:: f16_to_f32 ( fx, rhs) )
358+ } else {
359+ ( lhs, rhs)
360+ } ;
353361 let b = fx. bcx . ins ( ) ;
354362 let res = match bin_op {
363+ // FIXME(bytecodealliance/wasmtime#8312): Remove once backend lowerings
364+ // have been added to Cranelift.
365+ BinOp :: Add | BinOp :: Sub | BinOp :: Mul | BinOp :: Div
366+ if * in_lhs. layout ( ) . ty . kind ( ) == ty:: Float ( FloatTy :: F128 ) =>
367+ {
368+ codegen_f16_f128:: codegen_f128_binop ( fx, bin_op, lhs, rhs)
369+ }
355370 BinOp :: Add => b. fadd ( lhs, rhs) ,
356371 BinOp :: Sub => b. fsub ( lhs, rhs) ,
357372 BinOp :: Mul => b. fmul ( lhs, rhs) ,
358373 BinOp :: Div => b. fdiv ( lhs, rhs) ,
359374 BinOp :: Rem => {
360- let ( name, ty) = match in_lhs. layout ( ) . ty . kind ( ) {
361- ty:: Float ( FloatTy :: F32 ) => ( "fmodf" , types:: F32 ) ,
362- ty:: Float ( FloatTy :: F64 ) => ( "fmod" , types:: F64 ) ,
375+ let ( name, ty, lhs, rhs) = match in_lhs. layout ( ) . ty . kind ( ) {
376+ ty:: Float ( FloatTy :: F16 ) => (
377+ "fmodf" ,
378+ types:: F32 ,
379+ // FIXME(bytecodealliance/wasmtime#8312): Already converted
380+ // by the FIXME above.
381+ // fx.bcx.ins().fpromote(types::F32, lhs),
382+ // fx.bcx.ins().fpromote(types::F32, rhs),
383+ lhs,
384+ rhs,
385+ ) ,
386+ ty:: Float ( FloatTy :: F32 ) => ( "fmodf" , types:: F32 , lhs, rhs) ,
387+ ty:: Float ( FloatTy :: F64 ) => ( "fmod" , types:: F64 , lhs, rhs) ,
388+ ty:: Float ( FloatTy :: F128 ) => ( "fmodf128" , types:: F128 , lhs, rhs) ,
363389 _ => bug ! ( ) ,
364390 } ;
365391
366- fx. lib_call (
392+ let ret_val = fx. lib_call (
367393 name,
368394 vec ! [ AbiParam :: new( ty) , AbiParam :: new( ty) ] ,
369395 vec ! [ AbiParam :: new( ty) ] ,
370396 & [ lhs, rhs] ,
371- ) [ 0 ]
397+ ) [ 0 ] ;
398+
399+ let ret_val = if * in_lhs. layout ( ) . ty . kind ( ) == ty:: Float ( FloatTy :: F16 ) {
400+ // FIXME(bytecodealliance/wasmtime#8312): Use native Cranelift
401+ // operation once Cranelift backend lowerings have been
402+ // implemented.
403+ codegen_f16_f128:: f32_to_f16 ( fx, ret_val)
404+ } else {
405+ ret_val
406+ } ;
407+ return CValue :: by_val ( ret_val, in_lhs. layout ( ) ) ;
372408 }
373409 BinOp :: Eq | BinOp :: Lt | BinOp :: Le | BinOp :: Ne | BinOp :: Ge | BinOp :: Gt => {
374410 let fltcc = match bin_op {
@@ -386,6 +422,13 @@ pub(crate) fn codegen_float_binop<'tcx>(
386422 _ => unreachable ! ( "{:?}({:?}, {:?})" , bin_op, in_lhs, in_rhs) ,
387423 } ;
388424
425+ // FIXME(bytecodealliance/wasmtime#8312): Remove once backend lowerings have
426+ // been added to Cranelift.
427+ let res = if * in_lhs. layout ( ) . ty . kind ( ) == ty:: Float ( FloatTy :: F16 ) {
428+ codegen_f16_f128:: f32_to_f16 ( fx, res)
429+ } else {
430+ res
431+ } ;
389432 CValue :: by_val ( res, in_lhs. layout ( ) )
390433}
391434
0 commit comments