use crate::code_bld::CodeBuilder;
use crate::ctx::Context;
use source_map_node::Node;
use swamp_semantic::Expression;
use swamp_types::TypeRef;
use swamp_vm_types::types::{Place, VmType};
use swamp_vm_types::{MemoryLocation, PointerLocation};
impl CodeBuilder<'_> {
pub(crate) fn grid_subscript_helper(
&mut self,
grid_header_location: &Place,
analyzed_element_type: &TypeRef,
x_expr: &Expression,
y_expr: &Expression,
ctx: &Context,
) -> Place {
let pointer_location = self.grid_subscript_helper_helper(
grid_header_location,
analyzed_element_type,
x_expr,
y_expr,
ctx,
);
Place::Memory(MemoryLocation::new_copy_over_whole_type_with_zero_offset(
pointer_location.ptr_reg,
))
}
pub fn vec_subscript_helper(
&mut self,
vec_header_location: &Place,
analyzed_element_type: &TypeRef,
int_expr: &Expression,
ctx: &Context,
) -> Place {
let pointer_location = self.vec_subscript_helper_helper(
vec_header_location,
analyzed_element_type,
int_expr,
ctx,
);
Place::Memory(pointer_location.memory_location())
}
pub fn emit_vec_subscript_range_helper(
&mut self,
destination_memory_location: &Place,
source_memory_location: &Place,
range_expr: &Expression,
node: &Node,
comment: &str,
ctx: &Context,
) {
let destination_pointer = self.emit_compute_effective_address_to_register(
destination_memory_location,
node,
"get the destination vec",
);
let destination_pointer_loc = PointerLocation::new(destination_pointer);
let source_pointer = self.emit_compute_effective_address_to_register(
source_memory_location,
node,
"get vector source address to take range from",
);
let source_pointer_loc = PointerLocation::new(source_pointer);
let range_header_register = self.emit_scalar_rvalue(range_expr, ctx);
self.builder.add_vec_copy_range(
&destination_pointer_loc,
&source_pointer_loc,
&range_header_register,
node,
"copy range, but leave the capacity on the destination",
);
}
pub fn grid_subscript_helper_helper(
&mut self,
grid_header_location: &Place,
analyzed_element_type: &TypeRef,
x_int_expr: &Expression,
y_int_expr: &Expression,
ctx: &Context,
) -> PointerLocation {
let gen_element_type = self.state.layout_cache.layout(analyzed_element_type);
let x_int_reg = self.emit_scalar_rvalue(x_int_expr, ctx);
let y_int_reg = self.emit_scalar_rvalue(y_int_expr, ctx);
let node = &x_int_expr.node;
let grid_header_ptr_reg = self.emit_compute_effective_address_to_register(
grid_header_location,
node,
"get grid header absolute pointer",
);
let grid_header_ptr_location = PointerLocation {
ptr_reg: grid_header_ptr_reg,
};
let absolute_pointer_to_element = self.temp_registers.allocate(
VmType::new_contained_in_register(gen_element_type.clone()),
"temporary target",
);
self.builder.add_grid_get_entry_addr(
absolute_pointer_to_element.register(),
&grid_header_ptr_location,
&x_int_reg,
&y_int_reg,
gen_element_type.total_size,
node,
"lookup grid subscript",
);
PointerLocation {
ptr_reg: absolute_pointer_to_element.register,
}
}
pub fn vec_subscript_helper_helper(
&mut self,
vec_header_location: &Place,
analyzed_element_type: &TypeRef,
int_expr: &Expression,
ctx: &Context,
) -> PointerLocation {
let gen_element_type = self.state.layout_cache.layout(analyzed_element_type);
let index_int_reg = self.emit_scalar_rvalue(int_expr, ctx);
let node = &int_expr.node;
let vec_header_ptr_reg = self.emit_compute_effective_address_to_register(
vec_header_location,
node,
"get vec header absolute pointer",
);
let absolute_pointer_to_element = self.temp_registers.allocate(
VmType::new_contained_in_register(gen_element_type.clone()),
"temporary target",
);
self.builder.add_vec_subscript(
absolute_pointer_to_element.register(),
&vec_header_ptr_reg,
&index_int_reg,
node,
"lookup veclike subscript",
);
PointerLocation {
ptr_reg: absolute_pointer_to_element.register,
}
}
}