| ... | @@ -9432,29 +9432,40 @@ static void define_builtin_types(CodeGen *g) { | ... | @@ -9432,29 +9432,40 @@ static void define_builtin_types(CodeGen *g) { |
| 9432 | buf_init_from_str(&entry->name, "f80"); | 9432 | buf_init_from_str(&entry->name, "f80"); |
| 9433 | entry->data.floating.bit_count = 80; | 9433 | entry->data.floating.bit_count = 80; |
| 9434 | | 9434 | |
| 9435 | switch (g->zig_target->arch) { | 9435 | if (target_has_f80(g->zig_target)) { |
| 9436 | case ZigLLVM_x86_64: | 9436 | entry->llvm_type = LLVMX86FP80Type(); |
| 9437 | 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 | entry->abi_size = 16; | 9450 | entry->abi_size = 16; |
| 9439 | entry->abi_align = 16; | 9451 | entry->abi_align = 16; |
| 9440 | break; | 9452 | } else if (u64_alignment >= 4) { |
| 9441 | case ZigLLVM_x86: | | |
| 9442 | entry->llvm_type = LLVMX86FP80Type(); | | |
| 9443 | entry->abi_size = 12; | 9453 | entry->abi_size = 12; |
| 9444 | entry->abi_align = 4; | 9454 | entry->abi_align = 4; |
| 9445 | break; | 9455 | } else { |
| 9446 | default: { | 9456 | entry->abi_size = 10; |
| 9447 | // We use an int here instead of x86_fp80 because on targets such as arm, | 9457 | entry->abi_align = u64_alignment; |
| 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; | | |
| 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 | entry->llvm_di_type = ZigLLVMCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name), | 9471 | entry->llvm_di_type = ZigLLVMCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name), |