Remove easy_call
This commit is contained in:
parent
718574a53e
commit
cdf4f4287a
@ -125,42 +125,12 @@ pub(crate) fn lib_call(
|
|||||||
}
|
}
|
||||||
let call_inst = self.bcx.ins().call(func_ref, args);
|
let call_inst = self.bcx.ins().call(func_ref, args);
|
||||||
if self.clif_comments.enabled() {
|
if self.clif_comments.enabled() {
|
||||||
self.add_comment(call_inst, format!("easy_call {}", name));
|
self.add_comment(call_inst, format!("lib_call {}", name));
|
||||||
}
|
}
|
||||||
let results = self.bcx.inst_results(call_inst);
|
let results = self.bcx.inst_results(call_inst);
|
||||||
assert!(results.len() <= 2, "{}", results.len());
|
assert!(results.len() <= 2, "{}", results.len());
|
||||||
results
|
results
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn easy_call(
|
|
||||||
&mut self,
|
|
||||||
name: &str,
|
|
||||||
args: &[CValue<'tcx>],
|
|
||||||
return_ty: Ty<'tcx>,
|
|
||||||
) -> CValue<'tcx> {
|
|
||||||
let (input_tys, args): (Vec<_>, Vec<_>) = args
|
|
||||||
.iter()
|
|
||||||
.map(|arg| {
|
|
||||||
(AbiParam::new(self.clif_type(arg.layout().ty).unwrap()), arg.load_scalar(self))
|
|
||||||
})
|
|
||||||
.unzip();
|
|
||||||
let return_layout = self.layout_of(return_ty);
|
|
||||||
let return_tys = if let ty::Tuple(tup) = return_ty.kind() {
|
|
||||||
tup.iter().map(|ty| AbiParam::new(self.clif_type(ty).unwrap())).collect()
|
|
||||||
} else {
|
|
||||||
vec![AbiParam::new(self.clif_type(return_ty).unwrap())]
|
|
||||||
};
|
|
||||||
let ret_vals = self.lib_call(name, input_tys, return_tys, &args);
|
|
||||||
match *ret_vals {
|
|
||||||
[] => CValue::by_ref(
|
|
||||||
Pointer::const_addr(self, i64::from(self.pointer_type.bytes())),
|
|
||||||
return_layout,
|
|
||||||
),
|
|
||||||
[val] => CValue::by_val(val, return_layout),
|
|
||||||
[val, extra] => CValue::by_val_pair(val, extra, return_layout),
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Make a [`CPlace`] capable of holding value of the specified type.
|
/// Make a [`CPlace`] capable of holding value of the specified type.
|
||||||
|
33
src/cast.rs
33
src/cast.rs
@ -64,17 +64,12 @@ pub(crate) fn clif_int_or_float_cast(
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
let from_rust_ty = if from_signed { fx.tcx.types.i128 } else { fx.tcx.types.u128 };
|
return fx.lib_call(
|
||||||
|
&name,
|
||||||
let to_rust_ty = match to_ty {
|
vec![AbiParam::new(types::I128)],
|
||||||
types::F32 => fx.tcx.types.f32,
|
vec![AbiParam::new(to_ty)],
|
||||||
types::F64 => fx.tcx.types.f64,
|
&[from],
|
||||||
_ => unreachable!(),
|
)[0];
|
||||||
};
|
|
||||||
|
|
||||||
return fx
|
|
||||||
.easy_call(&name, &[CValue::by_val(from, fx.layout_of(from_rust_ty))], to_rust_ty)
|
|
||||||
.load_scalar(fx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// int-like -> float
|
// int-like -> float
|
||||||
@ -101,16 +96,12 @@ pub(crate) fn clif_int_or_float_cast(
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
let from_rust_ty = match from_ty {
|
fx.lib_call(
|
||||||
types::F32 => fx.tcx.types.f32,
|
&name,
|
||||||
types::F64 => fx.tcx.types.f64,
|
vec![AbiParam::new(from_ty)],
|
||||||
_ => unreachable!(),
|
vec![AbiParam::new(types::I128)],
|
||||||
};
|
&[from],
|
||||||
|
)[0]
|
||||||
let to_rust_ty = if to_signed { fx.tcx.types.i128 } else { fx.tcx.types.u128 };
|
|
||||||
|
|
||||||
fx.easy_call(&name, &[CValue::by_val(from, fx.layout_of(from_rust_ty))], to_rust_ty)
|
|
||||||
.load_scalar(fx)
|
|
||||||
} else if to_ty == types::I8 || to_ty == types::I16 {
|
} else if to_ty == types::I8 || to_ty == types::I16 {
|
||||||
// FIXME implement fcvt_to_*int_sat.i8/i16
|
// FIXME implement fcvt_to_*int_sat.i8/i16
|
||||||
let val = if to_signed {
|
let val = if to_signed {
|
||||||
|
@ -53,7 +53,14 @@ pub(crate) fn maybe_codegen<'tcx>(
|
|||||||
);
|
);
|
||||||
Some(ret_place.to_cvalue(fx))
|
Some(ret_place.to_cvalue(fx))
|
||||||
} else {
|
} else {
|
||||||
Some(fx.easy_call("__multi3", &[lhs, rhs], val_ty))
|
let args: Vec<_> = vec![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(val_ty)))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let out_ty = fx.tcx.mk_tup([lhs.layout().ty, fx.tcx.types.bool].iter());
|
let out_ty = fx.tcx.mk_tup([lhs.layout().ty, fx.tcx.types.bool].iter());
|
||||||
@ -141,7 +148,14 @@ pub(crate) fn maybe_codegen<'tcx>(
|
|||||||
ret_place.to_ptr().store(fx, ret, MemFlags::trusted());
|
ret_place.to_ptr().store(fx, ret, MemFlags::trusted());
|
||||||
Some(ret_place.to_cvalue(fx))
|
Some(ret_place.to_cvalue(fx))
|
||||||
} else {
|
} else {
|
||||||
Some(fx.easy_call(name, &[lhs, rhs], lhs.layout().ty))
|
let args: Vec<_> = vec![lhs.load_scalar(fx), rhs.load_scalar(fx)];
|
||||||
|
let ret_val = fx.lib_call(
|
||||||
|
name,
|
||||||
|
vec![AbiParam::new(types::I128), AbiParam::new(types::I128)],
|
||||||
|
vec![AbiParam::new(types::I128)],
|
||||||
|
&args,
|
||||||
|
)[0];
|
||||||
|
Some(CValue::by_val(ret_val, lhs.layout()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BinOp::Lt | BinOp::Le | BinOp::Eq | BinOp::Ge | BinOp::Gt | BinOp::Ne => {
|
BinOp::Lt | BinOp::Le | BinOp::Eq | BinOp::Ge | BinOp::Gt | BinOp::Ne => {
|
||||||
|
@ -251,41 +251,41 @@ fn codegen_float_intrinsic_call<'tcx>(
|
|||||||
args: &[mir::Operand<'tcx>],
|
args: &[mir::Operand<'tcx>],
|
||||||
ret: CPlace<'tcx>,
|
ret: CPlace<'tcx>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let (name, arg_count, ty) = match intrinsic {
|
let (name, arg_count, ty, clif_ty) = match intrinsic {
|
||||||
sym::expf32 => ("expf", 1, fx.tcx.types.f32),
|
sym::expf32 => ("expf", 1, fx.tcx.types.f32, types::F32),
|
||||||
sym::expf64 => ("exp", 1, fx.tcx.types.f64),
|
sym::expf64 => ("exp", 1, fx.tcx.types.f64, types::F64),
|
||||||
sym::exp2f32 => ("exp2f", 1, fx.tcx.types.f32),
|
sym::exp2f32 => ("exp2f", 1, fx.tcx.types.f32, types::F32),
|
||||||
sym::exp2f64 => ("exp2", 1, fx.tcx.types.f64),
|
sym::exp2f64 => ("exp2", 1, fx.tcx.types.f64, types::F64),
|
||||||
sym::sqrtf32 => ("sqrtf", 1, fx.tcx.types.f32),
|
sym::sqrtf32 => ("sqrtf", 1, fx.tcx.types.f32, types::F32),
|
||||||
sym::sqrtf64 => ("sqrt", 1, fx.tcx.types.f64),
|
sym::sqrtf64 => ("sqrt", 1, fx.tcx.types.f64, types::F64),
|
||||||
sym::powif32 => ("__powisf2", 2, fx.tcx.types.f32), // compiler-builtins
|
sym::powif32 => ("__powisf2", 2, fx.tcx.types.f32, types::F32), // compiler-builtins
|
||||||
sym::powif64 => ("__powidf2", 2, fx.tcx.types.f64), // compiler-builtins
|
sym::powif64 => ("__powidf2", 2, fx.tcx.types.f64, types::F64), // compiler-builtins
|
||||||
sym::powf32 => ("powf", 2, fx.tcx.types.f32),
|
sym::powf32 => ("powf", 2, fx.tcx.types.f32, types::F32),
|
||||||
sym::powf64 => ("pow", 2, fx.tcx.types.f64),
|
sym::powf64 => ("pow", 2, fx.tcx.types.f64, types::F64),
|
||||||
sym::logf32 => ("logf", 1, fx.tcx.types.f32),
|
sym::logf32 => ("logf", 1, fx.tcx.types.f32, types::F32),
|
||||||
sym::logf64 => ("log", 1, fx.tcx.types.f64),
|
sym::logf64 => ("log", 1, fx.tcx.types.f64, types::F64),
|
||||||
sym::log2f32 => ("log2f", 1, fx.tcx.types.f32),
|
sym::log2f32 => ("log2f", 1, fx.tcx.types.f32, types::F32),
|
||||||
sym::log2f64 => ("log2", 1, fx.tcx.types.f64),
|
sym::log2f64 => ("log2", 1, fx.tcx.types.f64, types::F64),
|
||||||
sym::log10f32 => ("log10f", 1, fx.tcx.types.f32),
|
sym::log10f32 => ("log10f", 1, fx.tcx.types.f32, types::F32),
|
||||||
sym::log10f64 => ("log10", 1, fx.tcx.types.f64),
|
sym::log10f64 => ("log10", 1, fx.tcx.types.f64, types::F64),
|
||||||
sym::fabsf32 => ("fabsf", 1, fx.tcx.types.f32),
|
sym::fabsf32 => ("fabsf", 1, fx.tcx.types.f32, types::F32),
|
||||||
sym::fabsf64 => ("fabs", 1, fx.tcx.types.f64),
|
sym::fabsf64 => ("fabs", 1, fx.tcx.types.f64, types::F64),
|
||||||
sym::fmaf32 => ("fmaf", 3, fx.tcx.types.f32),
|
sym::fmaf32 => ("fmaf", 3, fx.tcx.types.f32, types::F32),
|
||||||
sym::fmaf64 => ("fma", 3, fx.tcx.types.f64),
|
sym::fmaf64 => ("fma", 3, fx.tcx.types.f64, types::F64),
|
||||||
sym::copysignf32 => ("copysignf", 2, fx.tcx.types.f32),
|
sym::copysignf32 => ("copysignf", 2, fx.tcx.types.f32, types::F32),
|
||||||
sym::copysignf64 => ("copysign", 2, fx.tcx.types.f64),
|
sym::copysignf64 => ("copysign", 2, fx.tcx.types.f64, types::F64),
|
||||||
sym::floorf32 => ("floorf", 1, fx.tcx.types.f32),
|
sym::floorf32 => ("floorf", 1, fx.tcx.types.f32, types::F32),
|
||||||
sym::floorf64 => ("floor", 1, fx.tcx.types.f64),
|
sym::floorf64 => ("floor", 1, fx.tcx.types.f64, types::F64),
|
||||||
sym::ceilf32 => ("ceilf", 1, fx.tcx.types.f32),
|
sym::ceilf32 => ("ceilf", 1, fx.tcx.types.f32, types::F32),
|
||||||
sym::ceilf64 => ("ceil", 1, fx.tcx.types.f64),
|
sym::ceilf64 => ("ceil", 1, fx.tcx.types.f64, types::F64),
|
||||||
sym::truncf32 => ("truncf", 1, fx.tcx.types.f32),
|
sym::truncf32 => ("truncf", 1, fx.tcx.types.f32, types::F32),
|
||||||
sym::truncf64 => ("trunc", 1, fx.tcx.types.f64),
|
sym::truncf64 => ("trunc", 1, fx.tcx.types.f64, types::F64),
|
||||||
sym::roundf32 => ("roundf", 1, fx.tcx.types.f32),
|
sym::roundf32 => ("roundf", 1, fx.tcx.types.f32, types::F32),
|
||||||
sym::roundf64 => ("round", 1, fx.tcx.types.f64),
|
sym::roundf64 => ("round", 1, fx.tcx.types.f64, types::F64),
|
||||||
sym::sinf32 => ("sinf", 1, fx.tcx.types.f32),
|
sym::sinf32 => ("sinf", 1, fx.tcx.types.f32, types::F32),
|
||||||
sym::sinf64 => ("sin", 1, fx.tcx.types.f64),
|
sym::sinf64 => ("sin", 1, fx.tcx.types.f64, types::F64),
|
||||||
sym::cosf32 => ("cosf", 1, fx.tcx.types.f32),
|
sym::cosf32 => ("cosf", 1, fx.tcx.types.f32, types::F32),
|
||||||
sym::cosf64 => ("cos", 1, fx.tcx.types.f64),
|
sym::cosf64 => ("cos", 1, fx.tcx.types.f64, types::F64),
|
||||||
_ => return false,
|
_ => return false,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -296,15 +296,19 @@ fn codegen_float_intrinsic_call<'tcx>(
|
|||||||
let (a, b, c);
|
let (a, b, c);
|
||||||
let args = match args {
|
let args = match args {
|
||||||
[x] => {
|
[x] => {
|
||||||
a = [codegen_operand(fx, x)];
|
a = [codegen_operand(fx, x).load_scalar(fx)];
|
||||||
&a as &[_]
|
&a as &[_]
|
||||||
}
|
}
|
||||||
[x, y] => {
|
[x, y] => {
|
||||||
b = [codegen_operand(fx, x), codegen_operand(fx, y)];
|
b = [codegen_operand(fx, x).load_scalar(fx), codegen_operand(fx, y).load_scalar(fx)];
|
||||||
&b
|
&b
|
||||||
}
|
}
|
||||||
[x, y, z] => {
|
[x, y, z] => {
|
||||||
c = [codegen_operand(fx, x), codegen_operand(fx, y), codegen_operand(fx, z)];
|
c = [
|
||||||
|
codegen_operand(fx, x).load_scalar(fx),
|
||||||
|
codegen_operand(fx, y).load_scalar(fx),
|
||||||
|
codegen_operand(fx, z).load_scalar(fx),
|
||||||
|
];
|
||||||
&c
|
&c
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
@ -313,15 +317,10 @@ fn codegen_float_intrinsic_call<'tcx>(
|
|||||||
let layout = fx.layout_of(ty);
|
let layout = fx.layout_of(ty);
|
||||||
let res = match intrinsic {
|
let res = match intrinsic {
|
||||||
sym::fmaf32 | sym::fmaf64 => {
|
sym::fmaf32 | sym::fmaf64 => {
|
||||||
let a = args[0].load_scalar(fx);
|
CValue::by_val(fx.bcx.ins().fma(args[0], args[1], args[2]), layout)
|
||||||
let b = args[1].load_scalar(fx);
|
|
||||||
let c = args[2].load_scalar(fx);
|
|
||||||
CValue::by_val(fx.bcx.ins().fma(a, b, c), layout)
|
|
||||||
}
|
}
|
||||||
sym::copysignf32 | sym::copysignf64 => {
|
sym::copysignf32 | sym::copysignf64 => {
|
||||||
let a = args[0].load_scalar(fx);
|
CValue::by_val(fx.bcx.ins().fcopysign(args[0], args[1]), layout)
|
||||||
let b = args[1].load_scalar(fx);
|
|
||||||
CValue::by_val(fx.bcx.ins().fcopysign(a, b), layout)
|
|
||||||
}
|
}
|
||||||
sym::fabsf32
|
sym::fabsf32
|
||||||
| sym::fabsf64
|
| sym::fabsf64
|
||||||
@ -331,21 +330,29 @@ fn codegen_float_intrinsic_call<'tcx>(
|
|||||||
| sym::ceilf64
|
| sym::ceilf64
|
||||||
| sym::truncf32
|
| sym::truncf32
|
||||||
| sym::truncf64 => {
|
| sym::truncf64 => {
|
||||||
let a = args[0].load_scalar(fx);
|
|
||||||
|
|
||||||
let val = match intrinsic {
|
let val = match intrinsic {
|
||||||
sym::fabsf32 | sym::fabsf64 => fx.bcx.ins().fabs(a),
|
sym::fabsf32 | sym::fabsf64 => fx.bcx.ins().fabs(args[0]),
|
||||||
sym::floorf32 | sym::floorf64 => fx.bcx.ins().floor(a),
|
sym::floorf32 | sym::floorf64 => fx.bcx.ins().floor(args[0]),
|
||||||
sym::ceilf32 | sym::ceilf64 => fx.bcx.ins().ceil(a),
|
sym::ceilf32 | sym::ceilf64 => fx.bcx.ins().ceil(args[0]),
|
||||||
sym::truncf32 | sym::truncf64 => fx.bcx.ins().trunc(a),
|
sym::truncf32 | sym::truncf64 => fx.bcx.ins().trunc(args[0]),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
CValue::by_val(val, layout)
|
CValue::by_val(val, layout)
|
||||||
}
|
}
|
||||||
|
|
||||||
// These intrinsics aren't supported natively by Cranelift.
|
// These intrinsics aren't supported natively by Cranelift.
|
||||||
// Lower them to a libcall.
|
// Lower them to a libcall.
|
||||||
_ => fx.easy_call(name, &args, ty),
|
sym::powif32 | sym::powif64 => {
|
||||||
|
let input_tys: Vec<_> = vec![AbiParam::new(clif_ty), AbiParam::new(types::I32)];
|
||||||
|
let ret_val = fx.lib_call(name, input_tys, vec![AbiParam::new(clif_ty)], &args)[0];
|
||||||
|
CValue::by_val(ret_val, fx.layout_of(ty))
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
let input_tys: Vec<_> = args.iter().map(|_| AbiParam::new(clif_ty)).collect();
|
||||||
|
let ret_val = fx.lib_call(name, input_tys, vec![AbiParam::new(clif_ty)], &args)[0];
|
||||||
|
CValue::by_val(ret_val, fx.layout_of(ty))
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ret.write_cvalue(fx, res);
|
ret.write_cvalue(fx, res);
|
||||||
|
16
src/num.rs
16
src/num.rs
@ -347,12 +347,20 @@ pub(crate) fn codegen_float_binop<'tcx>(
|
|||||||
BinOp::Mul => b.fmul(lhs, rhs),
|
BinOp::Mul => b.fmul(lhs, rhs),
|
||||||
BinOp::Div => b.fdiv(lhs, rhs),
|
BinOp::Div => b.fdiv(lhs, rhs),
|
||||||
BinOp::Rem => {
|
BinOp::Rem => {
|
||||||
let name = match in_lhs.layout().ty.kind() {
|
let (name, ty) = match in_lhs.layout().ty.kind() {
|
||||||
ty::Float(FloatTy::F32) => "fmodf",
|
ty::Float(FloatTy::F32) => ("fmodf", types::F32),
|
||||||
ty::Float(FloatTy::F64) => "fmod",
|
ty::Float(FloatTy::F64) => ("fmod", types::F64),
|
||||||
_ => bug!(),
|
_ => bug!(),
|
||||||
};
|
};
|
||||||
return fx.easy_call(name, &[in_lhs, in_rhs], in_lhs.layout().ty);
|
|
||||||
|
let ret_val = fx.lib_call(
|
||||||
|
name,
|
||||||
|
vec![AbiParam::new(ty), AbiParam::new(ty)],
|
||||||
|
vec![AbiParam::new(ty)],
|
||||||
|
&[lhs, rhs],
|
||||||
|
)[0];
|
||||||
|
|
||||||
|
return CValue::by_val(ret_val, in_lhs.layout());
|
||||||
}
|
}
|
||||||
BinOp::Eq | BinOp::Lt | BinOp::Le | BinOp::Ne | BinOp::Ge | BinOp::Gt => {
|
BinOp::Eq | BinOp::Lt | BinOp::Le | BinOp::Ne | BinOp::Ge | BinOp::Gt => {
|
||||||
let fltcc = match bin_op {
|
let fltcc = match bin_op {
|
||||||
|
@ -30,11 +30,6 @@ pub(crate) fn stack_slot(stack_slot: StackSlot) -> Self {
|
|||||||
Pointer { base: PointerBase::Stack(stack_slot), offset: Offset32::new(0) }
|
Pointer { base: PointerBase::Stack(stack_slot), offset: Offset32::new(0) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn const_addr(fx: &mut FunctionCx<'_, '_, '_>, addr: i64) -> Self {
|
|
||||||
let addr = fx.bcx.ins().iconst(fx.pointer_type, addr);
|
|
||||||
Pointer { base: PointerBase::Addr(addr), offset: Offset32::new(0) }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn dangling(align: Align) -> Self {
|
pub(crate) fn dangling(align: Align) -> Self {
|
||||||
Pointer { base: PointerBase::Dangling(align), offset: Offset32::new(0) }
|
Pointer { base: PointerBase::Dangling(align), offset: Offset32::new(0) }
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user