Indirect
This commit is contained in:
parent
95154512da
commit
a5842a4181
@ -7054,7 +7054,8 @@ abi_system_v_classify_type = fn (type: &Type, options: AbiSystemVClassifyArgumen
|
||||
if (gt_16 or padding)
|
||||
{
|
||||
result[0] = .memory;
|
||||
#trap();
|
||||
result = abi_system_v_classify_post_merge(byte_size, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
>member_classes = abi_system_v_classify_type(member_type, {
|
||||
@ -7391,6 +7392,42 @@ abi_system_v_get_indirect_result = fn (module: &Module, type: &Type, free_gpr: u
|
||||
}
|
||||
}
|
||||
|
||||
NaturalAlignIndirect = struct
|
||||
{
|
||||
semantic_type: &Type,
|
||||
padding_type: &Type,
|
||||
not_by_value: u1, // by_value = true by default
|
||||
realign: u1,
|
||||
}
|
||||
|
||||
abi_system_v_get_natural_align_indirect = fn (natural: NaturalAlignIndirect) AbiInformation
|
||||
{
|
||||
>alignment = get_byte_alignment(natural.semantic_type);
|
||||
|
||||
return abi_system_v_get_indirect({
|
||||
.semantic_type = natural.semantic_type,
|
||||
.padding_type = natural.padding_type,
|
||||
.alignment = alignment,
|
||||
.not_by_value = natural.not_by_value,
|
||||
.realign = natural.realign,
|
||||
});
|
||||
}
|
||||
|
||||
abi_system_v_get_indirect_return_result = fn (type: &Type) AbiInformation
|
||||
{
|
||||
if (type_is_aggregate_type_for_abi(type))
|
||||
{
|
||||
return abi_system_v_get_natural_align_indirect({
|
||||
.semantic_type = type,
|
||||
zero,
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
#trap();
|
||||
}
|
||||
}
|
||||
|
||||
abi_system_v_classify_return_type = fn (module: &Module, semantic_return_type: &Type) AbiInformation
|
||||
{
|
||||
>classes = abi_system_v_classify_type(semantic_return_type, zero);
|
||||
@ -7428,6 +7465,10 @@ abi_system_v_classify_return_type = fn (module: &Module, semantic_return_type: &
|
||||
}
|
||||
}
|
||||
},
|
||||
.memory =>
|
||||
{
|
||||
return abi_system_v_get_indirect_return_result(semantic_return_type);
|
||||
},
|
||||
else =>
|
||||
{
|
||||
#trap();
|
||||
@ -7648,11 +7689,16 @@ abi_system_v_classify_argument = fn (module: &Module, available_registers: &AbiR
|
||||
abi_argument_type_buffer[abi_start] = coerce_to_type;
|
||||
count = 1;
|
||||
}
|
||||
}
|
||||
},
|
||||
.indirect =>
|
||||
{
|
||||
#trap();
|
||||
}
|
||||
>indirect_type = get_pointer_type(module, argument_abi.semantic_type);
|
||||
>abi_index = argument_abi.abi_start;
|
||||
abi_argument_type_buffer[abi_index] = indirect_type;
|
||||
resolve_type_in_place(module, indirect_type);
|
||||
llvm_abi_argument_type_buffer[abi_index] = indirect_type.llvm.abi;
|
||||
count = 1;
|
||||
},
|
||||
else => { unreachable; },
|
||||
}
|
||||
|
||||
@ -10937,6 +10983,10 @@ emit_assignment = fn (module: &Module, left_llvm: &LLVMValue, left_type: &Type,
|
||||
|
||||
emit_intrinsic_call(module, ."llvm.va_start", argument_types[..], argument_values[..]);
|
||||
},
|
||||
.aggregate_initialization =>
|
||||
{
|
||||
#trap();
|
||||
},
|
||||
else =>
|
||||
{
|
||||
#trap();
|
||||
@ -11719,7 +11769,16 @@ emit = fn (module: &Module) void
|
||||
|
||||
if (return_abi_kind == .indirect)
|
||||
{
|
||||
#trap();
|
||||
assert(!function_type.abi.return_abi.flags.sret_after_this);
|
||||
function_type.abi.available_registers.system_v.gpr -= 1;
|
||||
>indirect_type = get_pointer_type(module, function_type.abi.return_abi.semantic_type);
|
||||
resolve_type_in_place(module, indirect_type);
|
||||
|
||||
>abi_index = abi_argument_type_count;
|
||||
abi_argument_type_buffer[abi_index] = indirect_type;
|
||||
llvm_abi_argument_type_buffer[abi_index] = indirect_type.llvm.abi;
|
||||
|
||||
abi_argument_type_count += 1;
|
||||
}
|
||||
|
||||
if (semantic_argument_types.length != 0)
|
||||
@ -11741,10 +11800,11 @@ emit = fn (module: &Module) void
|
||||
abi_argument_type_count += abi.abi_count;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
>abi_argument_types = arena_allocate_slice[&Type](module.arena, #extend(abi_argument_type_count));
|
||||
memcpy(#pointer_cast(abi_argument_types.pointer), #pointer_cast(&abi_argument_type_buffer), #extend(#byte_size(&Type) * abi_argument_type_count));
|
||||
function_type.abi.abi_argument_types = abi_argument_types;
|
||||
}
|
||||
},
|
||||
.win64 =>
|
||||
{
|
||||
@ -11961,8 +12021,19 @@ emit = fn (module: &Module) void
|
||||
{
|
||||
.ignore => {},
|
||||
.indirect =>
|
||||
{
|
||||
>indirect_argument_index = function_type.abi.return_abi.flags.sret_after_this;
|
||||
if (function_type.abi.return_abi.flags.sret_after_this)
|
||||
{
|
||||
#trap();
|
||||
}
|
||||
|
||||
global.variable.storage.content.function.llvm.return_alloca = llvm_abi_arguments[indirect_argument_index];
|
||||
|
||||
if (!function_type.abi.return_abi.flags.indirect_by_value)
|
||||
{
|
||||
#trap();
|
||||
}
|
||||
},
|
||||
.in_alloca =>
|
||||
{
|
||||
@ -12613,7 +12684,8 @@ compile_file = fn (arena: &Arena, compile_options: CompileFile) []u8
|
||||
return output_executable_path;
|
||||
}
|
||||
|
||||
names: [_][]u8 = [
|
||||
names: [_][]u8 =
|
||||
[
|
||||
"minimal",
|
||||
"comments",
|
||||
"constant_add",
|
||||
@ -12662,6 +12734,9 @@ names: [_][]u8 = [
|
||||
"bits_zero",
|
||||
"comparison",
|
||||
"global_struct",
|
||||
"if_no_else",
|
||||
"if_no_else_void",
|
||||
"indirect",
|
||||
];
|
||||
|
||||
[export] main = fn [cc(c)] (argument_count: u32, argv: &&u8, envp: &&u8) s32
|
||||
|
Loading…
x
Reference in New Issue
Block a user