mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 23:04:49 +00:00
a start with 32-bit linux support
This commit is contained in:
parent
79d7dd0cbf
commit
61aeaefc76
6 changed files with 68 additions and 37 deletions
|
@ -75,16 +75,26 @@ pub fn call_str_bitcode_fn<'a, 'ctx, 'env>(
|
|||
.unwrap();
|
||||
|
||||
let str_type = super::convert::zig_str_type(env);
|
||||
let result = create_entry_block_alloca(env, parent, str_type.into(), "return_str_alloca");
|
||||
let mut arguments: Vec<BasicValueEnum> = Vec::with_capacity_in(args.len() + 1, env.arena);
|
||||
|
||||
arguments.push(result.into());
|
||||
arguments.extend(args);
|
||||
match env.target_info.ptr_width() {
|
||||
roc_target::PtrWidth::Bytes4 => {
|
||||
// 3 machine words actually fit into 2 registers
|
||||
call_bitcode_fn(env, args, fn_name)
|
||||
}
|
||||
roc_target::PtrWidth::Bytes8 => {
|
||||
let result =
|
||||
create_entry_block_alloca(env, parent, str_type.into(), "return_str_alloca");
|
||||
let mut arguments: Vec<BasicValueEnum> =
|
||||
Vec::with_capacity_in(args.len() + 1, env.arena);
|
||||
|
||||
call_void_bitcode_fn(env, &arguments, fn_name);
|
||||
arguments.push(result.into());
|
||||
arguments.extend(args);
|
||||
|
||||
// TODO make this function return a PointerValue
|
||||
result.into()
|
||||
call_void_bitcode_fn(env, &arguments, fn_name);
|
||||
|
||||
result.into()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn call_void_bitcode_fn<'a, 'ctx, 'env>(
|
||||
|
@ -403,7 +413,7 @@ fn build_transform_caller_help<'a, 'ctx, 'env>(
|
|||
for (argument_ptr, layout) in arguments.iter().zip(argument_layouts) {
|
||||
let basic_type = basic_type_from_layout(env, layout).ptr_type(AddressSpace::Generic);
|
||||
|
||||
let argument = if layout.is_passed_by_reference() {
|
||||
let argument = if layout.is_passed_by_reference(env.target_info) {
|
||||
env.builder
|
||||
.build_pointer_cast(
|
||||
argument_ptr.into_pointer_value(),
|
||||
|
@ -557,7 +567,7 @@ fn build_rc_wrapper<'a, 'ctx, 'env>(
|
|||
|
||||
let value_type = basic_type_from_layout(env, layout).ptr_type(AddressSpace::Generic);
|
||||
|
||||
let value = if layout.is_passed_by_reference() {
|
||||
let value = if layout.is_passed_by_reference(env.target_info) {
|
||||
env.builder
|
||||
.build_pointer_cast(value_ptr, value_type, "cast_ptr_to_tag_build_rc_wrapper")
|
||||
.into()
|
||||
|
|
|
@ -1070,7 +1070,7 @@ pub fn build_exp_expr<'a, 'ctx, 'env>(
|
|||
if !field_layout.is_dropped_because_empty() {
|
||||
field_types.push(basic_type_from_layout(env, field_layout));
|
||||
|
||||
if field_layout.is_passed_by_reference() {
|
||||
if field_layout.is_passed_by_reference(env.target_info) {
|
||||
let field_value = env.builder.build_load(
|
||||
field_expr.into_pointer_value(),
|
||||
"load_tag_to_put_in_struct",
|
||||
|
@ -1475,7 +1475,7 @@ fn build_tag_field_value<'a, 'ctx, 'env>(
|
|||
env.context.i64_type().ptr_type(AddressSpace::Generic),
|
||||
"cast_recursive_pointer",
|
||||
)
|
||||
} else if tag_field_layout.is_passed_by_reference() {
|
||||
} else if tag_field_layout.is_passed_by_reference(env.target_info) {
|
||||
debug_assert!(value.is_pointer_value(), "{:#?}", value);
|
||||
|
||||
// NOTE: we rely on this being passed to `store_roc_value` so that
|
||||
|
@ -2354,7 +2354,7 @@ pub fn load_roc_value<'a, 'ctx, 'env>(
|
|||
source: PointerValue<'ctx>,
|
||||
name: &str,
|
||||
) -> BasicValueEnum<'ctx> {
|
||||
if layout.is_passed_by_reference() {
|
||||
if layout.is_passed_by_reference(env.target_info) {
|
||||
let alloca = entry_block_alloca_zerofill(env, basic_type_from_layout(env, &layout), name);
|
||||
|
||||
store_roc_value(env, layout, alloca, source.into());
|
||||
|
@ -2371,7 +2371,7 @@ pub fn use_roc_value<'a, 'ctx, 'env>(
|
|||
source: BasicValueEnum<'ctx>,
|
||||
name: &str,
|
||||
) -> BasicValueEnum<'ctx> {
|
||||
if layout.is_passed_by_reference() {
|
||||
if layout.is_passed_by_reference(env.target_info) {
|
||||
let alloca = entry_block_alloca_zerofill(env, basic_type_from_layout(env, &layout), name);
|
||||
|
||||
env.builder.build_store(alloca, source);
|
||||
|
@ -2402,7 +2402,7 @@ pub fn store_roc_value<'a, 'ctx, 'env>(
|
|||
destination: PointerValue<'ctx>,
|
||||
value: BasicValueEnum<'ctx>,
|
||||
) {
|
||||
if layout.is_passed_by_reference() {
|
||||
if layout.is_passed_by_reference(env.target_info) {
|
||||
debug_assert!(value.is_pointer_value());
|
||||
|
||||
let align_bytes = layout.alignment_bytes(env.target_info);
|
||||
|
@ -2505,7 +2505,7 @@ pub fn build_exp_stmt<'a, 'ctx, 'env>(
|
|||
// store_roc_value(env, *layout, out_parameter.into_pointer_value(), value);
|
||||
|
||||
let destination = out_parameter.into_pointer_value();
|
||||
if layout.is_passed_by_reference() {
|
||||
if layout.is_passed_by_reference(env.target_info) {
|
||||
let align_bytes = layout.alignment_bytes(env.target_info);
|
||||
|
||||
if align_bytes > 0 {
|
||||
|
@ -2618,7 +2618,7 @@ pub fn build_exp_stmt<'a, 'ctx, 'env>(
|
|||
for param in parameters.iter() {
|
||||
let basic_type = basic_type_from_layout(env, ¶m.layout);
|
||||
|
||||
let phi_type = if param.layout.is_passed_by_reference() {
|
||||
let phi_type = if param.layout.is_passed_by_reference(env.target_info) {
|
||||
basic_type.ptr_type(AddressSpace::Generic).into()
|
||||
} else {
|
||||
basic_type
|
||||
|
@ -3926,7 +3926,7 @@ fn make_good_roc_result<'a, 'ctx, 'env>(
|
|||
.build_insert_value(v1, context.i64_type().const_zero(), 0, "set_no_error")
|
||||
.unwrap();
|
||||
|
||||
let v3 = if return_layout.is_passed_by_reference() {
|
||||
let v3 = if return_layout.is_passed_by_reference(env.target_info) {
|
||||
let loaded = env.builder.build_load(
|
||||
return_value.into_pointer_value(),
|
||||
"load_call_result_passed_by_ptr",
|
||||
|
@ -4332,7 +4332,7 @@ pub fn build_closure_caller<'a, 'ctx, 'env>(
|
|||
let closure_layout = lambda_set.runtime_representation();
|
||||
let layouts_it = arguments.iter().chain(std::iter::once(&closure_layout));
|
||||
for (param, layout) in evaluator_arguments.iter_mut().zip(layouts_it) {
|
||||
if param.is_pointer_value() && !layout.is_passed_by_reference() {
|
||||
if param.is_pointer_value() && !layout.is_passed_by_reference(env.target_info) {
|
||||
*param = builder.build_load(param.into_pointer_value(), "load_param");
|
||||
}
|
||||
}
|
||||
|
@ -4350,7 +4350,7 @@ pub fn build_closure_caller<'a, 'ctx, 'env>(
|
|||
} else {
|
||||
let call_result = call_roc_function(env, evaluator, return_layout, &evaluator_arguments);
|
||||
|
||||
if return_layout.is_passed_by_reference() {
|
||||
if return_layout.is_passed_by_reference(env.target_info) {
|
||||
let align_bytes = return_layout.alignment_bytes(env.target_info);
|
||||
|
||||
if align_bytes > 0 {
|
||||
|
@ -4674,7 +4674,7 @@ pub fn call_roc_function<'a, 'ctx, 'env>(
|
|||
debug_assert_eq!(roc_function.get_call_conventions(), FAST_CALL_CONV);
|
||||
call.set_call_convention(FAST_CALL_CONV);
|
||||
|
||||
if result_layout.is_passed_by_reference() {
|
||||
if result_layout.is_passed_by_reference(env.target_info) {
|
||||
result_alloca.into()
|
||||
} else {
|
||||
env.builder
|
||||
|
@ -6212,23 +6212,30 @@ enum RocReturn {
|
|||
}
|
||||
|
||||
impl RocReturn {
|
||||
fn roc_return_by_pointer(layout: Layout) -> bool {
|
||||
fn roc_return_by_pointer(target_info: TargetInfo, layout: Layout) -> bool {
|
||||
match layout {
|
||||
Layout::Builtin(builtin) => {
|
||||
use Builtin::*;
|
||||
|
||||
matches!(builtin, Str)
|
||||
match target_info.ptr_width() {
|
||||
roc_target::PtrWidth::Bytes4 => false,
|
||||
|
||||
roc_target::PtrWidth::Bytes8 => {
|
||||
//
|
||||
matches!(builtin, Str)
|
||||
}
|
||||
}
|
||||
}
|
||||
Layout::Union(UnionLayout::NonRecursive(_)) => true,
|
||||
Layout::LambdaSet(lambda_set) => {
|
||||
RocReturn::roc_return_by_pointer(lambda_set.runtime_representation())
|
||||
RocReturn::roc_return_by_pointer(target_info, lambda_set.runtime_representation())
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn from_layout<'a, 'ctx, 'env>(_env: &Env<'a, 'ctx, 'env>, layout: &Layout<'a>) -> Self {
|
||||
if Self::roc_return_by_pointer(*layout) {
|
||||
fn from_layout<'a, 'ctx, 'env>(env: &Env<'a, 'ctx, 'env>, layout: &Layout<'a>) -> Self {
|
||||
if Self::roc_return_by_pointer(env.target_info, *layout) {
|
||||
RocReturn::ByPointer
|
||||
} else {
|
||||
RocReturn::Return
|
||||
|
|
|
@ -434,7 +434,7 @@ pub fn list_walk_generic<'a, 'ctx, 'env>(
|
|||
ListWalk::WalkBackwardsUntil => todo!(),
|
||||
};
|
||||
|
||||
let default_ptr = if default_layout.is_passed_by_reference() {
|
||||
let default_ptr = if default_layout.is_passed_by_reference(env.target_info) {
|
||||
debug_assert!(default.is_pointer_value());
|
||||
default.into_pointer_value()
|
||||
} else {
|
||||
|
@ -503,7 +503,7 @@ pub fn list_walk_generic<'a, 'ctx, 'env>(
|
|||
}
|
||||
}
|
||||
|
||||
if default_layout.is_passed_by_reference() {
|
||||
if default_layout.is_passed_by_reference(env.target_info) {
|
||||
result_ptr.into()
|
||||
} else {
|
||||
env.builder.build_load(result_ptr, "load_result")
|
||||
|
|
|
@ -135,7 +135,7 @@ pub fn argument_type_from_layout<'a, 'ctx, 'env>(
|
|||
Builtin(_) => {
|
||||
let base = basic_type_from_layout(env, layout);
|
||||
|
||||
if layout.is_passed_by_reference() {
|
||||
if layout.is_passed_by_reference(env.target_info) {
|
||||
base.ptr_type(AddressSpace::Generic).into()
|
||||
} else {
|
||||
base
|
||||
|
|
|
@ -865,9 +865,14 @@ fn modify_refcount_str_help<'a, 'ctx, 'env>(
|
|||
|
||||
let parent = fn_val;
|
||||
|
||||
let arg_val = env
|
||||
.builder
|
||||
.build_load(arg_val.into_pointer_value(), "load_str_to_stack");
|
||||
let arg_val = if Layout::Builtin(Builtin::Str).is_passed_by_reference(env.target_info) {
|
||||
env.builder
|
||||
.build_load(arg_val.into_pointer_value(), "load_str_to_stack")
|
||||
} else {
|
||||
// it's already a struct, just do nothing
|
||||
debug_assert!(arg_val.is_struct_value());
|
||||
arg_val
|
||||
};
|
||||
let str_wrapper = arg_val.into_struct_value();
|
||||
|
||||
let capacity = builder
|
||||
|
@ -1829,7 +1834,7 @@ fn modify_refcount_union_help<'a, 'ctx, 'env>(
|
|||
.build_struct_gep(cast_tag_data_pointer, i as u32, "modify_tag_field")
|
||||
.unwrap();
|
||||
|
||||
let field_value = if field_layout.is_passed_by_reference() {
|
||||
let field_value = if field_layout.is_passed_by_reference(env.target_info) {
|
||||
field_ptr.into()
|
||||
} else {
|
||||
env.builder.build_load(field_ptr, "field_value")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue