Add create_stack_slot helper to FunctionCx
This will allow centrally handling a workaround for the lack of stack alignment specifier in cranelift.
This commit is contained in:
parent
a99b1b4c0b
commit
38e8be9673
@ -120,32 +120,25 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
|
||||
args: &[Value],
|
||||
) -> Cow<'_, [Value]> {
|
||||
if self.tcx.sess.target.is_like_windows {
|
||||
let (mut params, mut args): (Vec<_>, Vec<_>) =
|
||||
params
|
||||
.into_iter()
|
||||
.zip(args)
|
||||
.map(|(param, &arg)| {
|
||||
if param.value_type == types::I128 {
|
||||
let arg_ptr = Pointer::stack_slot(self.bcx.create_sized_stack_slot(
|
||||
StackSlotData { kind: StackSlotKind::ExplicitSlot, size: 16 },
|
||||
));
|
||||
arg_ptr.store(self, arg, MemFlags::trusted());
|
||||
(AbiParam::new(self.pointer_type), arg_ptr.get_addr(self))
|
||||
} else {
|
||||
(param, arg)
|
||||
}
|
||||
})
|
||||
.unzip();
|
||||
let (mut params, mut args): (Vec<_>, Vec<_>) = params
|
||||
.into_iter()
|
||||
.zip(args)
|
||||
.map(|(param, &arg)| {
|
||||
if param.value_type == types::I128 {
|
||||
let arg_ptr = self.create_stack_slot(16, 16);
|
||||
arg_ptr.store(self, arg, MemFlags::trusted());
|
||||
(AbiParam::new(self.pointer_type), arg_ptr.get_addr(self))
|
||||
} else {
|
||||
(param, arg)
|
||||
}
|
||||
})
|
||||
.unzip();
|
||||
|
||||
let indirect_ret_val = returns.len() == 1 && returns[0].value_type == types::I128;
|
||||
|
||||
if indirect_ret_val {
|
||||
params.insert(0, AbiParam::new(self.pointer_type));
|
||||
let ret_ptr =
|
||||
Pointer::stack_slot(self.bcx.create_sized_stack_slot(StackSlotData {
|
||||
kind: StackSlotKind::ExplicitSlot,
|
||||
size: 16,
|
||||
}));
|
||||
let ret_ptr = self.create_stack_slot(16, 16);
|
||||
args.insert(0, ret_ptr.get_addr(self));
|
||||
self.lib_call_unadjusted(name, params, vec![], &args);
|
||||
return Cow::Owned(vec![ret_ptr.load(self, types::I128, MemFlags::trusted())]);
|
||||
|
@ -189,16 +189,13 @@ pub(super) fn from_casted_value<'tcx>(
|
||||
let abi_params = cast_target_to_abi_params(cast);
|
||||
let abi_param_size: u32 = abi_params.iter().map(|param| param.value_type.bytes()).sum();
|
||||
let layout_size = u32::try_from(layout.size.bytes()).unwrap();
|
||||
let stack_slot = fx.bcx.create_sized_stack_slot(StackSlotData {
|
||||
kind: StackSlotKind::ExplicitSlot,
|
||||
// FIXME Don't force the size to a multiple of 16 bytes once Cranelift gets a way to
|
||||
// specify stack slot alignment.
|
||||
let ptr = fx.create_stack_slot(
|
||||
// Stack slot size may be bigger for example `[u8; 3]` which is packed into an `i32`.
|
||||
// It may also be smaller for example when the type is a wrapper around an integer with a
|
||||
// larger alignment than the integer.
|
||||
size: (std::cmp::max(abi_param_size, layout_size) + 15) / 16 * 16,
|
||||
});
|
||||
let ptr = Pointer::stack_slot(stack_slot);
|
||||
std::cmp::max(abi_param_size, layout_size),
|
||||
u32::try_from(layout.align.pref.bytes()).unwrap(),
|
||||
);
|
||||
let mut offset = 0;
|
||||
let mut block_params_iter = block_params.iter().copied();
|
||||
for param in abi_params {
|
||||
|
@ -104,11 +104,7 @@ pub(crate) fn clif_int_or_float_cast(
|
||||
&[from],
|
||||
)[0];
|
||||
// FIXME(bytecodealliance/wasmtime#6104) use bitcast instead of store to get from i64x2 to i128
|
||||
let stack_slot = fx.bcx.create_sized_stack_slot(StackSlotData {
|
||||
kind: StackSlotKind::ExplicitSlot,
|
||||
size: 16,
|
||||
});
|
||||
let ret_ptr = Pointer::stack_slot(stack_slot);
|
||||
let ret_ptr = fx.create_stack_slot(16, 16);
|
||||
ret_ptr.store(fx, ret, MemFlags::trusted());
|
||||
ret_ptr.load(fx, types::I128, MemFlags::trusted())
|
||||
} else {
|
||||
|
@ -383,6 +383,16 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn create_stack_slot(&mut self, size: u32, align: u32) -> Pointer {
|
||||
let stack_slot = self.bcx.create_sized_stack_slot(StackSlotData {
|
||||
kind: StackSlotKind::ExplicitSlot,
|
||||
// FIXME Don't force the size to a multiple of 16 bytes once Cranelift gets a way to
|
||||
// specify stack slot alignment.
|
||||
size: (size + 15) / 16 * 16,
|
||||
});
|
||||
Pointer::stack_slot(stack_slot)
|
||||
}
|
||||
|
||||
pub(crate) fn set_debug_loc(&mut self, source_info: mir::SourceInfo) {
|
||||
if let Some(debug_context) = &mut self.cx.debug_context {
|
||||
let (file, line, column) =
|
||||
|
@ -878,13 +878,7 @@ fn call_inline_asm<'tcx>(
|
||||
inputs: Vec<(Size, Value)>,
|
||||
outputs: Vec<(Size, CPlace<'tcx>)>,
|
||||
) {
|
||||
let stack_slot = fx.bcx.func.create_sized_stack_slot(StackSlotData {
|
||||
kind: StackSlotKind::ExplicitSlot,
|
||||
size: u32::try_from(slot_size.bytes()).unwrap(),
|
||||
});
|
||||
if fx.clif_comments.enabled() {
|
||||
fx.add_comment(stack_slot, "inline asm scratch slot");
|
||||
}
|
||||
let stack_slot = fx.create_stack_slot(u32::try_from(slot_size.bytes()).unwrap(), 16);
|
||||
|
||||
let inline_asm_func = fx
|
||||
.module
|
||||
@ -904,15 +898,23 @@ fn call_inline_asm<'tcx>(
|
||||
}
|
||||
|
||||
for (offset, value) in inputs {
|
||||
fx.bcx.ins().stack_store(value, stack_slot, i32::try_from(offset.bytes()).unwrap());
|
||||
stack_slot.offset(fx, i32::try_from(offset.bytes()).unwrap().into()).store(
|
||||
fx,
|
||||
value,
|
||||
MemFlags::trusted(),
|
||||
);
|
||||
}
|
||||
|
||||
let stack_slot_addr = fx.bcx.ins().stack_addr(fx.pointer_type, stack_slot, 0);
|
||||
let stack_slot_addr = stack_slot.get_addr(fx);
|
||||
fx.bcx.ins().call(inline_asm_func, &[stack_slot_addr]);
|
||||
|
||||
for (offset, place) in outputs {
|
||||
let ty = fx.clif_type(place.layout().ty).unwrap();
|
||||
let value = fx.bcx.ins().stack_load(ty, stack_slot, i32::try_from(offset.bytes()).unwrap());
|
||||
let value = stack_slot.offset(fx, i32::try_from(offset.bytes()).unwrap().into()).load(
|
||||
fx,
|
||||
ty,
|
||||
MemFlags::trusted(),
|
||||
);
|
||||
place.write_cvalue(fx, CValue::by_val(value, place.layout()));
|
||||
}
|
||||
}
|
||||
|
@ -132,18 +132,11 @@ impl<'tcx> CValue<'tcx> {
|
||||
(ptr.get_addr(fx), vtable)
|
||||
}
|
||||
CValueInner::ByValPair(data, vtable) => {
|
||||
let stack_slot = fx.bcx.create_sized_stack_slot(StackSlotData {
|
||||
kind: StackSlotKind::ExplicitSlot,
|
||||
// FIXME Don't force the size to a multiple of 16 bytes once Cranelift gets a way to
|
||||
// specify stack slot alignment.
|
||||
size: (u32::try_from(fx.target_config.pointer_type().bytes()).unwrap() + 15)
|
||||
/ 16
|
||||
* 16,
|
||||
});
|
||||
let data_ptr = Pointer::stack_slot(stack_slot);
|
||||
let mut flags = MemFlags::new();
|
||||
flags.set_notrap();
|
||||
data_ptr.store(fx, data, flags);
|
||||
let data_ptr = fx.create_stack_slot(
|
||||
u32::try_from(fx.target_config.pointer_type().bytes()).unwrap(),
|
||||
u32::try_from(fx.target_config.pointer_type().bytes()).unwrap(),
|
||||
);
|
||||
data_ptr.store(fx, data, MemFlags::trusted());
|
||||
|
||||
(data_ptr.get_addr(fx), vtable)
|
||||
}
|
||||
@ -372,13 +365,11 @@ impl<'tcx> CPlace<'tcx> {
|
||||
.fatal(format!("values of type {} are too big to store on the stack", layout.ty));
|
||||
}
|
||||
|
||||
let stack_slot = fx.bcx.create_sized_stack_slot(StackSlotData {
|
||||
kind: StackSlotKind::ExplicitSlot,
|
||||
// FIXME Don't force the size to a multiple of 16 bytes once Cranelift gets a way to
|
||||
// specify stack slot alignment.
|
||||
size: (u32::try_from(layout.size.bytes()).unwrap() + 15) / 16 * 16,
|
||||
});
|
||||
CPlace { inner: CPlaceInner::Addr(Pointer::stack_slot(stack_slot), None), layout }
|
||||
let stack_slot = fx.create_stack_slot(
|
||||
u32::try_from(layout.size.bytes()).unwrap(),
|
||||
u32::try_from(layout.align.pref.bytes()).unwrap(),
|
||||
);
|
||||
CPlace { inner: CPlaceInner::Addr(stack_slot, None), layout }
|
||||
}
|
||||
|
||||
pub(crate) fn new_var(
|
||||
@ -543,13 +534,7 @@ impl<'tcx> CPlace<'tcx> {
|
||||
_ if src_ty.is_vector() && dst_ty.is_vector() => codegen_bitcast(fx, dst_ty, data),
|
||||
_ if src_ty.is_vector() || dst_ty.is_vector() => {
|
||||
// FIXME(bytecodealliance/wasmtime#6104) do something more efficient for transmutes between vectors and integers.
|
||||
let stack_slot = fx.bcx.create_sized_stack_slot(StackSlotData {
|
||||
kind: StackSlotKind::ExplicitSlot,
|
||||
// FIXME Don't force the size to a multiple of 16 bytes once Cranelift gets a way to
|
||||
// specify stack slot alignment.
|
||||
size: (src_ty.bytes() + 15) / 16 * 16,
|
||||
});
|
||||
let ptr = Pointer::stack_slot(stack_slot);
|
||||
let ptr = fx.create_stack_slot(src_ty.bytes(), src_ty.bytes());
|
||||
ptr.store(fx, data, MemFlags::trusted());
|
||||
ptr.load(fx, dst_ty, MemFlags::trusted())
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user