Logic to load 128-bit numbers

This commit is contained in:
Brian Carroll 2021-11-21 20:35:46 +00:00
parent ee1c4478da
commit 2e31350010
3 changed files with 58 additions and 14 deletions

View File

@ -277,6 +277,7 @@ impl<'a> WasmBackend<'a> {
location,
size,
alignment_bytes,
..
} => {
let (from_ptr, from_offset) =
location.local_and_offset(self.storage.stack_frame_pointer);

View File

@ -2,6 +2,15 @@ use roc_mono::layout::{Layout, UnionLayout};
use crate::{wasm_module::ValueType, PTR_SIZE, PTR_TYPE};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum StackMemoryFormat {
/// Record, Str, List, Dict, etc.
Aggregate,
Int128,
Float128,
Decimal,
}
// See README for background information on Wasm locals, memory and function calls
#[derive(Debug, Clone)]
pub enum WasmLayout {
@ -10,7 +19,11 @@ pub enum WasmLayout {
Primitive(ValueType, u32),
// Local pointer to stack memory
StackMemory { size: u32, alignment_bytes: u32 },
StackMemory {
size: u32,
alignment_bytes: u32,
format: StackMemoryFormat,
},
// Local pointer to heap memory
HeapMemory,
@ -35,23 +48,32 @@ impl WasmLayout {
Layout::Builtin(Float64) => Self::Primitive(F64, size),
Layout::Builtin(
Int128
| Decimal
| Float128
| Str
| Dict(_, _)
| Set(_)
| List(_)
| EmptyStr
| EmptyList
| EmptyDict
| EmptySet,
Str | Dict(_, _) | Set(_) | List(_) | EmptyStr | EmptyList | EmptyDict | EmptySet,
)
| Layout::Struct(_)
| Layout::LambdaSet(_)
| Layout::Union(NonRecursive(_)) => Self::StackMemory {
size,
alignment_bytes,
format: StackMemoryFormat::Aggregate,
},
Layout::Builtin(Int128) => Self::StackMemory {
size,
alignment_bytes,
format: StackMemoryFormat::Int128,
},
Layout::Builtin(Decimal) => Self::StackMemory {
size,
alignment_bytes,
format: StackMemoryFormat::Decimal,
},
Layout::Builtin(Float128) => Self::StackMemory {
size,
alignment_bytes,
format: StackMemoryFormat::Float128,
},
Layout::Union(

View File

@ -4,7 +4,7 @@ use bumpalo::Bump;
use roc_collections::all::MutMap;
use roc_module::symbol::Symbol;
use crate::layout::WasmLayout;
use crate::layout::{StackMemoryFormat, WasmLayout};
use crate::wasm_module::{Align, CodeBuilder, LocalId, ValueType, VmSymbolState};
use crate::{copy_memory, round_up_to_alignment, CopyMemoryConfig, PTR_SIZE, PTR_TYPE};
@ -50,6 +50,7 @@ pub enum StoredValue {
location: StackMemoryLocation,
size: u32,
alignment_bytes: u32,
format: StackMemoryFormat,
},
}
@ -147,6 +148,7 @@ impl<'a> Storage<'a> {
WasmLayout::StackMemory {
size,
alignment_bytes,
format,
} => {
let location = match kind {
StoredValueKind::Parameter => {
@ -175,6 +177,7 @@ impl<'a> Storage<'a> {
location,
size: *size,
alignment_bytes: *alignment_bytes,
format: *format,
}
}
};
@ -239,13 +242,26 @@ impl<'a> Storage<'a> {
code_builder.set_top_symbol(sym);
}
StoredValue::StackMemory { location, .. } => {
StoredValue::StackMemory {
location, format, ..
} => {
let (local_id, offset) = location.local_and_offset(self.stack_frame_pointer);
// Load the address of the value
code_builder.get_local(local_id);
if offset != 0 {
code_builder.i32_const(offset as i32);
code_builder.i32_add();
}
if format != StackMemoryFormat::Aggregate {
// It's one of the 128-bit numbers, all of which we load as two i64's
// Mark the same Symbol twice in the VM value stack! Shouldn't matter except debug.
code_builder.i64_load(Align::Bytes8, offset);
code_builder.set_top_symbol(sym);
code_builder.i64_load(Align::Bytes8, offset + 8);
}
code_builder.set_top_symbol(sym);
}
}
@ -292,6 +308,7 @@ impl<'a> Storage<'a> {
location,
size,
alignment_bytes,
format: StackMemoryFormat::Aggregate,
} = self.get(sym)
{
if *size == 0 {
@ -334,6 +351,7 @@ impl<'a> Storage<'a> {
location,
size,
alignment_bytes,
..
} => {
let (from_ptr, from_offset) = location.local_and_offset(self.stack_frame_pointer);
copy_memory(
@ -390,6 +408,7 @@ impl<'a> Storage<'a> {
location,
size,
alignment_bytes,
..
} => {
let (to_ptr, to_offset) = location.local_and_offset(self.stack_frame_pointer);
copy_memory(
@ -490,11 +509,13 @@ impl<'a> Storage<'a> {
location: to_location,
size: to_size,
alignment_bytes: to_alignment_bytes,
..
},
StackMemory {
location: from_location,
size: from_size,
alignment_bytes: from_alignment_bytes,
..
},
) => {
let (from_ptr, from_offset) =