| ... | ... | @@ -9432,29 +9432,40 @@ static void define_builtin_types(CodeGen *g) { |
| 9432 | 9432 | buf_init_from_str(&entry->name, "f80"); |
| 9433 | 9433 | entry->data.floating.bit_count = 80; |
| 9434 | 9434 | |
| 9435 | | switch (g->zig_target->arch) { |
| 9436 | | case ZigLLVM_x86_64: |
| 9437 | | entry->llvm_type = LLVMX86FP80Type(); |
| 9435 | if (target_has_f80(g->zig_target)) { |
| 9436 | entry->llvm_type = LLVMX86FP80Type(); |
| 9437 | |
| 9438 | // Note the following u64 alignments: |
| 9439 | // x86-linux: 4 |
| 9440 | // x86-windows: 8 |
| 9441 | // LLVM makes x86_fp80 have the following alignment and sizes regardless |
| 9442 | // of operating system: |
| 9443 | // x86_64: size=16, align=16 |
| 9444 | // x86: size=12, align=4 |
| 9445 | // However in Zig we override x86-windows to have size=16, align=16 |
| 9446 | // in order for the property to hold that u80 and f80 have the same ABI size. |
| 9447 | unsigned u64_alignment = LLVMABIAlignmentOfType(g->target_data_ref, LLVMInt64Type()); |
| 9448 | |
| 9449 | if (u64_alignment >= 8) { |
| 9438 | 9450 | entry->abi_size = 16; |
| 9439 | 9451 | entry->abi_align = 16; |
| 9440 | | break; |
| 9441 | | case ZigLLVM_x86: |
| 9442 | | entry->llvm_type = LLVMX86FP80Type(); |
| 9452 | } else if (u64_alignment >= 4) { |
| 9443 | 9453 | entry->abi_size = 12; |
| 9444 | 9454 | entry->abi_align = 4; |
| 9445 | | break; |
| 9446 | | default: { |
| 9447 | | // We use an int here instead of x86_fp80 because on targets such as arm, |
| 9448 | | // LLVM will give "ERROR: Cannot select" for any instructions involving |
| 9449 | | // the x86_fp80 type. |
| 9450 | | ZigType *u80_ty = get_int_type(g, false, 80); |
| 9451 | | assert(!target_has_f80(g->zig_target)); |
| 9452 | | assert(u80_ty->size_in_bits == entry->size_in_bits); |
| 9453 | | entry->llvm_type = get_llvm_type(g, u80_ty); |
| 9454 | | entry->abi_size = u80_ty->abi_size; |
| 9455 | | entry->abi_align = u80_ty->abi_align; |
| 9456 | | break; |
| 9455 | } else { |
| 9456 | entry->abi_size = 10; |
| 9457 | entry->abi_align = u64_alignment; |
| 9457 | 9458 | } |
| 9459 | } else { |
| 9460 | // We use an int here instead of x86_fp80 because on targets such as arm, |
| 9461 | // LLVM will give "ERROR: Cannot select" for any instructions involving |
| 9462 | // the x86_fp80 type. |
| 9463 | ZigType *u80_ty = get_int_type(g, false, 80); |
| 9464 | assert(!target_has_f80(g->zig_target)); |
| 9465 | assert(u80_ty->size_in_bits == entry->size_in_bits); |
| 9466 | entry->llvm_type = get_llvm_type(g, u80_ty); |
| 9467 | entry->abi_size = u80_ty->abi_size; |
| 9468 | entry->abi_align = u80_ty->abi_align; |
| 9458 | 9469 | } |
| 9459 | 9470 | |
| 9460 | 9471 | entry->llvm_di_type = ZigLLVMCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name), |