a start with 32-bit linux support

This commit is contained in:
Folkert 2022-03-30 23:55:34 +02:00
parent 79d7dd0cbf
commit 61aeaefc76
No known key found for this signature in database
GPG key ID: 1F17F6FFD112B97C
6 changed files with 68 additions and 37 deletions

View file

@ -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()

View file

@ -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, &param.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

View file

@ -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")

View file

@ -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

View file

@ -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")