diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 02:49:42 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 02:49:42 +0000 |
commit | 837b550238aa671a591ccf282dddeab29cadb206 (patch) | |
tree | 914b6b8862bace72bd3245ca184d374b08d8a672 /compiler/rustc_codegen_cranelift/src/codegen_i128.rs | |
parent | Adding debian version 1.70.0+dfsg2-1. (diff) | |
download | rustc-837b550238aa671a591ccf282dddeab29cadb206.tar.xz rustc-837b550238aa671a591ccf282dddeab29cadb206.zip |
Merging upstream version 1.71.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_codegen_cranelift/src/codegen_i128.rs')
-rw-r--r-- | compiler/rustc_codegen_cranelift/src/codegen_i128.rs | 147 |
1 files changed, 81 insertions, 66 deletions
diff --git a/compiler/rustc_codegen_cranelift/src/codegen_i128.rs b/compiler/rustc_codegen_cranelift/src/codegen_i128.rs index f674ce776..f751d8c17 100644 --- a/compiler/rustc_codegen_cranelift/src/codegen_i128.rs +++ b/compiler/rustc_codegen_cranelift/src/codegen_i128.rs @@ -7,7 +7,6 @@ use crate::prelude::*; pub(crate) fn maybe_codegen<'tcx>( fx: &mut FunctionCx<'_, '_, 'tcx>, bin_op: BinOp, - checked: bool, lhs: CValue<'tcx>, rhs: CValue<'tcx>, ) -> Option<CValue<'tcx>> { @@ -22,69 +21,23 @@ pub(crate) fn maybe_codegen<'tcx>( let is_signed = type_sign(lhs.layout().ty); match bin_op { - BinOp::BitAnd | BinOp::BitOr | BinOp::BitXor => { - assert!(!checked); - None - } - BinOp::Add | BinOp::Sub if !checked => None, - BinOp::Mul if !checked || is_signed => { - if !checked { - let args = [lhs.load_scalar(fx), rhs.load_scalar(fx)]; - let ret_val = fx.lib_call( - "__multi3", - vec![AbiParam::new(types::I128), AbiParam::new(types::I128)], - vec![AbiParam::new(types::I128)], - &args, - )[0]; - Some(CValue::by_val( - ret_val, - fx.layout_of(if is_signed { fx.tcx.types.i128 } else { fx.tcx.types.u128 }), - )) - } else { - let out_ty = fx.tcx.mk_tup(&[lhs.layout().ty, fx.tcx.types.bool]); - let oflow = CPlace::new_stack_slot(fx, fx.layout_of(fx.tcx.types.i32)); - let lhs = lhs.load_scalar(fx); - let rhs = rhs.load_scalar(fx); - let oflow_ptr = oflow.to_ptr().get_addr(fx); - let res = fx.lib_call_unadjusted( - "__muloti4", - vec![ - AbiParam::new(types::I128), - AbiParam::new(types::I128), - AbiParam::new(fx.pointer_type), - ], - vec![AbiParam::new(types::I128)], - &[lhs, rhs, oflow_ptr], - )[0]; - let oflow = oflow.to_cvalue(fx).load_scalar(fx); - let oflow = fx.bcx.ins().ireduce(types::I8, oflow); - Some(CValue::by_val_pair(res, oflow, fx.layout_of(out_ty))) - } - } - BinOp::Add | BinOp::Sub | BinOp::Mul => { - assert!(checked); - let out_ty = fx.tcx.mk_tup(&[lhs.layout().ty, fx.tcx.types.bool]); - let out_place = CPlace::new_stack_slot(fx, fx.layout_of(out_ty)); - let param_types = vec![ - AbiParam::special(fx.pointer_type, ArgumentPurpose::StructReturn), - AbiParam::new(types::I128), - AbiParam::new(types::I128), - ]; - let args = [out_place.to_ptr().get_addr(fx), lhs.load_scalar(fx), rhs.load_scalar(fx)]; - let name = match (bin_op, is_signed) { - (BinOp::Add, false) => "__rust_u128_addo", - (BinOp::Add, true) => "__rust_i128_addo", - (BinOp::Sub, false) => "__rust_u128_subo", - (BinOp::Sub, true) => "__rust_i128_subo", - (BinOp::Mul, false) => "__rust_u128_mulo", - _ => unreachable!(), - }; - fx.lib_call(name, param_types, vec![], &args); - Some(out_place.to_cvalue(fx)) + BinOp::BitAnd | BinOp::BitOr | BinOp::BitXor => None, + BinOp::Add | BinOp::Sub => None, + BinOp::Mul => { + let args = [lhs.load_scalar(fx), rhs.load_scalar(fx)]; + let ret_val = fx.lib_call( + "__multi3", + vec![AbiParam::new(types::I128), AbiParam::new(types::I128)], + vec![AbiParam::new(types::I128)], + &args, + )[0]; + Some(CValue::by_val( + ret_val, + fx.layout_of(if is_signed { fx.tcx.types.i128 } else { fx.tcx.types.u128 }), + )) } BinOp::Offset => unreachable!("offset should only be used on pointers, not 128bit ints"), BinOp::Div | BinOp::Rem => { - assert!(!checked); let name = match (bin_op, is_signed) { (BinOp::Div, false) => "__udivti3", (BinOp::Div, true) => "__divti3", @@ -100,7 +53,7 @@ pub(crate) fn maybe_codegen<'tcx>( vec![AbiParam::new(types::I64X2)], &args, )[0]; - // FIXME use bitcast instead of store to get from i64x2 to i128 + // FIXME(bytecodealliance/wasmtime#6104) use bitcast instead of store to get from i64x2 to i128 let ret_place = CPlace::new_stack_slot(fx, lhs.layout()); ret_place.to_ptr().store(fx, ret, MemFlags::trusted()); Some(ret_place.to_cvalue(fx)) @@ -115,10 +68,72 @@ pub(crate) fn maybe_codegen<'tcx>( Some(CValue::by_val(ret_val, lhs.layout())) } } - BinOp::Lt | BinOp::Le | BinOp::Eq | BinOp::Ge | BinOp::Gt | BinOp::Ne => { - assert!(!checked); - None - } + BinOp::Lt | BinOp::Le | BinOp::Eq | BinOp::Ge | BinOp::Gt | BinOp::Ne => None, BinOp::Shl | BinOp::Shr => None, } } + +pub(crate) fn maybe_codegen_checked<'tcx>( + fx: &mut FunctionCx<'_, '_, 'tcx>, + bin_op: BinOp, + lhs: CValue<'tcx>, + rhs: CValue<'tcx>, +) -> Option<CValue<'tcx>> { + if lhs.layout().ty != fx.tcx.types.u128 + && lhs.layout().ty != fx.tcx.types.i128 + && rhs.layout().ty != fx.tcx.types.u128 + && rhs.layout().ty != fx.tcx.types.i128 + { + return None; + } + + let is_signed = type_sign(lhs.layout().ty); + + match bin_op { + BinOp::BitAnd | BinOp::BitOr | BinOp::BitXor => unreachable!(), + BinOp::Mul if is_signed => { + let out_ty = fx.tcx.mk_tup(&[lhs.layout().ty, fx.tcx.types.bool]); + let oflow = CPlace::new_stack_slot(fx, fx.layout_of(fx.tcx.types.i32)); + let lhs = lhs.load_scalar(fx); + let rhs = rhs.load_scalar(fx); + let oflow_ptr = oflow.to_ptr().get_addr(fx); + let res = fx.lib_call_unadjusted( + "__muloti4", + vec![ + AbiParam::new(types::I128), + AbiParam::new(types::I128), + AbiParam::new(fx.pointer_type), + ], + vec![AbiParam::new(types::I128)], + &[lhs, rhs, oflow_ptr], + )[0]; + let oflow = oflow.to_cvalue(fx).load_scalar(fx); + let oflow = fx.bcx.ins().ireduce(types::I8, oflow); + Some(CValue::by_val_pair(res, oflow, fx.layout_of(out_ty))) + } + BinOp::Add | BinOp::Sub | BinOp::Mul => { + let out_ty = fx.tcx.mk_tup(&[lhs.layout().ty, fx.tcx.types.bool]); + let out_place = CPlace::new_stack_slot(fx, fx.layout_of(out_ty)); + let param_types = vec![ + AbiParam::special(fx.pointer_type, ArgumentPurpose::StructReturn), + AbiParam::new(types::I128), + AbiParam::new(types::I128), + ]; + let args = [out_place.to_ptr().get_addr(fx), lhs.load_scalar(fx), rhs.load_scalar(fx)]; + let name = match (bin_op, is_signed) { + (BinOp::Add, false) => "__rust_u128_addo", + (BinOp::Add, true) => "__rust_i128_addo", + (BinOp::Sub, false) => "__rust_u128_subo", + (BinOp::Sub, true) => "__rust_i128_subo", + (BinOp::Mul, false) => "__rust_u128_mulo", + _ => unreachable!(), + }; + fx.lib_call(name, param_types, vec![], &args); + Some(out_place.to_cvalue(fx)) + } + BinOp::Offset => unreachable!("offset should only be used on pointers, not 128bit ints"), + BinOp::Div | BinOp::Rem => unreachable!(), + BinOp::Lt | BinOp::Le | BinOp::Eq | BinOp::Ge | BinOp::Gt | BinOp::Ne => unreachable!(), + BinOp::Shl | BinOp::Shr => unreachable!(), + } +} |