mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-27 05:49:08 +00:00
Merge pull request #4683 from roc-lang/gen-wasm-shr-128
gen_wasm: Implement u128 right shift by delegating to compiler_rt
This commit is contained in:
commit
ac45fa2bba
4 changed files with 70 additions and 46 deletions
|
@ -1708,12 +1708,11 @@ impl<'a> LowLevelCall<'a> {
|
|||
backend.code_builder.i64_extend_u_i32();
|
||||
backend.code_builder.i64_shr_u();
|
||||
}
|
||||
I128 => todo!("{:?} for I128", self.lowlevel),
|
||||
I128 => self.load_args_and_call_zig(backend, "__lshrti3"), // from compiler_rt
|
||||
_ => panic_ret_type(),
|
||||
}
|
||||
}
|
||||
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) {
|
||||
|
@ -1729,19 +1728,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),
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue