gen_wasm: implement NumIntCast for i128

This commit is contained in:
Brian Carroll 2023-01-23 22:27:07 +00:00
parent a249e14ee5
commit 5179057fc5
No known key found for this signature in database
GPG key ID: 5C7B2EC4101703C0

View file

@ -1721,7 +1721,6 @@ impl<'a> LowLevelCall<'a> {
}
}
NumIntCast => {
self.load_args(backend);
let arg_layout = backend.storage.symbol_layouts[&self.arguments[0]];
let arg_type = CodeGenNumType::from(arg_layout);
let arg_width = match backend.layout_interner.get(arg_layout) {
@ -1737,19 +1736,56 @@ impl<'a> LowLevelCall<'a> {
};
match (ret_type, arg_type) {
(I32, I32) => self.wrap_small_int(backend, ret_width),
(I32, I32) => {
self.load_args(backend);
self.wrap_small_int(backend, ret_width);
}
(I32, I64) => {
self.load_args(backend);
backend.code_builder.i32_wrap_i64();
self.wrap_small_int(backend, ret_width);
}
(I32, I128) => {
self.load_args(backend);
backend.code_builder.i32_load(Align::Bytes4, 0);
}
(I64, I32) => {
self.load_args(backend);
if arg_width.is_signed() {
backend.code_builder.i64_extend_s_i32()
} else {
backend.code_builder.i64_extend_u_i32()
}
}
(I64, I64) => {}
(I64, I64) => {
self.load_args(backend);
}
(I64, I128) => {
let (frame_ptr, offset) = match backend.storage.get(&self.arguments[0]) {
StoredValue::StackMemory { location, .. } => {
location.local_and_offset(backend.storage.stack_frame_pointer)
}
_ => internal_error!("I128 should be in stack memory"),
};
backend.code_builder.get_local(frame_ptr);
backend.code_builder.i64_load(Align::Bytes8, offset);
}
(I128, I64) => {
// Symbols are loaded as if for a call, so the i128 "return address" and i64 value are on the value stack
self.load_args(backend);
backend.code_builder.i64_store(Align::Bytes8, 0);
// Zero the most significant 64 bits
let (frame_ptr, offset) = match &self.ret_storage {
StoredValue::StackMemory { location, .. } => {
location.local_and_offset(backend.storage.stack_frame_pointer)
}
_ => internal_error!("I128 should be in stack memory"),
};
backend.code_builder.get_local(frame_ptr);
backend.code_builder.i64_const(0);
backend.code_builder.i64_store(Align::Bytes8, offset + 8);
}
_ => todo!("{:?}: {:?} -> {:?}", self.lowlevel, arg_type, ret_type),
}