mirror of
https://github.com/ziglang/zig.git
synced 2026-02-21 16:54:52 +00:00
stage1: override f80 alignment for i386-windows
Comment reproduced here: Note the following u64 alignments: x86-linux: 4 x86-windows: 8 LLVM makes x86_fp80 have the following alignment and sizes regardless of operating system: x86_64: size=16, align=16 x86: size=12, align=4 However in Zig we override x86-windows to have size=16, align=16 in order for the property to hold that u80 and f80 have the same ABI size. Fixes "error: destination type 'f80' has size 12 but source type 'u80' has size 16" when trying to bitcast between f80 and u80 on i386-windows.
This commit is contained in:
parent
d72f832b1e
commit
b92e1ab8cc
@ -9432,29 +9432,40 @@ static void define_builtin_types(CodeGen *g) {
|
|||||||
buf_init_from_str(&entry->name, "f80");
|
buf_init_from_str(&entry->name, "f80");
|
||||||
entry->data.floating.bit_count = 80;
|
entry->data.floating.bit_count = 80;
|
||||||
|
|
||||||
switch (g->zig_target->arch) {
|
if (target_has_f80(g->zig_target)) {
|
||||||
case ZigLLVM_x86_64:
|
entry->llvm_type = LLVMX86FP80Type();
|
||||||
entry->llvm_type = LLVMX86FP80Type();
|
|
||||||
|
// Note the following u64 alignments:
|
||||||
|
// x86-linux: 4
|
||||||
|
// x86-windows: 8
|
||||||
|
// LLVM makes x86_fp80 have the following alignment and sizes regardless
|
||||||
|
// of operating system:
|
||||||
|
// x86_64: size=16, align=16
|
||||||
|
// x86: size=12, align=4
|
||||||
|
// However in Zig we override x86-windows to have size=16, align=16
|
||||||
|
// in order for the property to hold that u80 and f80 have the same ABI size.
|
||||||
|
unsigned u64_alignment = LLVMABIAlignmentOfType(g->target_data_ref, LLVMInt64Type());
|
||||||
|
|
||||||
|
if (u64_alignment >= 8) {
|
||||||
entry->abi_size = 16;
|
entry->abi_size = 16;
|
||||||
entry->abi_align = 16;
|
entry->abi_align = 16;
|
||||||
break;
|
} else if (u64_alignment >= 4) {
|
||||||
case ZigLLVM_x86:
|
|
||||||
entry->llvm_type = LLVMX86FP80Type();
|
|
||||||
entry->abi_size = 12;
|
entry->abi_size = 12;
|
||||||
entry->abi_align = 4;
|
entry->abi_align = 4;
|
||||||
break;
|
} else {
|
||||||
default: {
|
entry->abi_size = 10;
|
||||||
// We use an int here instead of x86_fp80 because on targets such as arm,
|
entry->abi_align = u64_alignment;
|
||||||
// LLVM will give "ERROR: Cannot select" for any instructions involving
|
|
||||||
// the x86_fp80 type.
|
|
||||||
ZigType *u80_ty = get_int_type(g, false, 80);
|
|
||||||
assert(!target_has_f80(g->zig_target));
|
|
||||||
assert(u80_ty->size_in_bits == entry->size_in_bits);
|
|
||||||
entry->llvm_type = get_llvm_type(g, u80_ty);
|
|
||||||
entry->abi_size = u80_ty->abi_size;
|
|
||||||
entry->abi_align = u80_ty->abi_align;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// We use an int here instead of x86_fp80 because on targets such as arm,
|
||||||
|
// LLVM will give "ERROR: Cannot select" for any instructions involving
|
||||||
|
// the x86_fp80 type.
|
||||||
|
ZigType *u80_ty = get_int_type(g, false, 80);
|
||||||
|
assert(!target_has_f80(g->zig_target));
|
||||||
|
assert(u80_ty->size_in_bits == entry->size_in_bits);
|
||||||
|
entry->llvm_type = get_llvm_type(g, u80_ty);
|
||||||
|
entry->abi_size = u80_ty->abi_size;
|
||||||
|
entry->abi_align = u80_ty->abi_align;
|
||||||
}
|
}
|
||||||
|
|
||||||
entry->llvm_di_type = ZigLLVMCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name),
|
entry->llvm_di_type = ZigLLVMCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user