This commit is contained in:
David Gonzalez Martin 2025-06-13 07:50:12 -06:00
parent 95154512da
commit f327934caf
2 changed files with 150 additions and 47 deletions

View File

@ -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,33 @@ emit_assignment = fn (module: &Module, left_llvm: &LLVMValue, left_type: &Type,
emit_intrinsic_call(module, ."llvm.va_start", argument_types[..], argument_values[..]);
},
.aggregate_initialization =>
{
>elements = right.content.aggregate_initialization.elements;
>scope = right.content.aggregate_initialization.scope;
>is_constant = right.content.aggregate_initialization.is_constant;
>is_zero = right.content.aggregate_initialization.is_zero;
>u64_type = uint64(module);
resolve_type_in_place(module, u64_type);
>byte_size = get_byte_size(value_type);
>byte_size_value = LLVMConstInt(u64_type.llvm.abi, byte_size, 0);
>alignment = get_byte_alignment(value_type);
if (is_constant)
{
emit_value(module, right, .memory, 1);
>linkage: LLVMLinkage = .internal;
>thread_local_mode: LLVMThreadLocalMode = .none;
>externally_initialized: u1 = 0;
>unnamed_address: LLVMUnnamedAddress = .global;
>global = llvm_create_global_variable(module.llvm.module, value_type.llvm.memory, is_constant, linkage, right.llvm, "const.aggregate", thread_local_mode, externally_initialized, alignment, unnamed_address);
LLVMBuildMemCpy(module.llvm.builder, left_llvm, alignment, global, alignment, byte_size_value);
}
else
{
#trap();
}
},
else =>
{
#trap();
@ -11719,7 +11792,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 +11823,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;
}
>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 =>
{
@ -11960,23 +12043,34 @@ emit = fn (module: &Module) void
switch (return_abi.flags.kind)
{
.ignore => {},
.indirect =>
.indirect =>
{
>indirect_argument_index = function_type.abi.return_abi.flags.sret_after_this;
if (function_type.abi.return_abi.flags.sret_after_this)
{
#trap();
},
.in_alloca =>
#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();
},
else =>
{
>alloca = create_alloca(module, {
.type = return_abi.semantic_type,
.name = "return_value",
zero,
});
function.content.function.llvm.return_alloca = alloca;
},
#trap();
}
},
.in_alloca =>
{
#trap();
},
else =>
{
>alloca = create_alloca(module, {
.type = return_abi.semantic_type,
.name = "return_value",
zero,
});
function.content.function.llvm.return_alloca = alloca;
},
}
>arguments = function.content.function.arguments;
@ -12008,12 +12102,12 @@ emit = fn (module: &Module) void
if (coerce_to_type.llvm.abi != LLVMTypeOf(v))
{
#trap();
#trap();
}
if (is_promoted)
{
#trap();
#trap();
}
// TODO: this we can get rid of because we handle all of this inside `create_alloca`, load, stores, etc
@ -12080,7 +12174,7 @@ emit = fn (module: &Module) void
>is_fixed_vector_type: u1 = 0;
if (is_fixed_vector_type)
{
#trap();
#trap();
}
if (coerce_to_type.id == .struct and coerce_to_type.content.struct.fields.length > 1 and argument_abi.flags.kind == .direct and !argument_abi.flags.can_be_flattened)
@ -12088,7 +12182,7 @@ emit = fn (module: &Module) void
>contains_homogeneous_scalable_vector_types: u1 = 0;
if (contains_homogeneous_scalable_vector_types)
{
#trap();
#trap();
}
}
@ -12103,7 +12197,7 @@ emit = fn (module: &Module) void
if (argument_abi.attributes.direct.offset > 0)
{
#trap();
#trap();
}
else
{
@ -12119,7 +12213,7 @@ emit = fn (module: &Module) void
if (is_scalable)
{
#trap();
#trap();
}
else
{
@ -12181,14 +12275,14 @@ emit = fn (module: &Module) void
semantic_argument_storage = alloca;
}
},
.indirect =>
{
#trap();
},
else =>
{
unreachable;
},
.indirect =>
{
#trap();
},
else =>
{
unreachable;
},
}
assert(semantic_argument_storage != zero);
@ -12223,7 +12317,7 @@ emit = fn (module: &Module) void
}
else
{
#trap();
#trap();
}
}
else
@ -12247,7 +12341,7 @@ emit = fn (module: &Module) void
if (has_single_jump_to_return_block)
{
#trap();
#trap();
}
else
{
@ -12265,7 +12359,7 @@ emit = fn (module: &Module) void
>semantic_return_type = return_abi.semantic_type;
if (semantic_return_type == noreturn_type(module) or function.content.function.attributes.naked)
{
#trap();
#trap();
}
else if (semantic_return_type == void_type(module))
{
@ -12303,13 +12397,19 @@ emit = fn (module: &Module) void
}
else
{
#trap();
#trap();
}
},
.indirect =>
.indirect =>
{
>evaluation_kind = get_evaluation_kind(function_type.abi.return_type.semantic_type);
switch (evaluation_kind)
{
#trap();
},
.scalar => { #trap(); },
.aggregate => {},
.complex => { #trap(); },
}
},
}
LLVMBuildRet(module.llvm.builder, return_value);
@ -12613,7 +12713,8 @@ compile_file = fn (arena: &Arena, compile_options: CompileFile) []u8
return output_executable_path;
}
names: [_][]u8 = [
names: [_][]u8 =
[
"minimal",
"comments",
"constant_add",
@ -12662,6 +12763,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

View File

@ -6526,10 +6526,9 @@ fn void emit_assignment(Module* module, LLVMValueRef left_llvm, Type* left_type,
emit_value(module, right, TypeKind::memory, true);
LLVMLinkage linkage_type = LLVMInternalLinkage;
unsigned address_space = 0;
LLVMThreadLocalMode thread_local_mode = LLVMNotThreadLocal;
bool externally_initialized = false;
auto global = llvm_module_create_global_variable(module->llvm.module, value_type->llvm.memory, is_constant, linkage_type, right->llvm, string_literal("constarray"), thread_local_mode, externally_initialized, alignment, LLVMGlobalUnnamedAddr);
auto global = llvm_module_create_global_variable(module->llvm.module, value_type->llvm.memory, is_constant, linkage_type, right->llvm, string_literal("const.aggregate"), thread_local_mode, externally_initialized, alignment, LLVMGlobalUnnamedAddr);
LLVMBuildMemCpy(module->llvm.builder, left_llvm, alignment, global, alignment, byte_size_value);
}
else