| ... | ... | @@ -1620,13 +1620,23 @@ static LLVMValueRef gen_soft_f80_widen_or_shorten(CodeGen *g, ZigType *actual_ty |
| 1620 | 1620 | LLVMTypeRef return_type; |
| 1621 | 1621 | const char *func_name; |
| 1622 | 1622 | |
| 1623 | LLVMValueRef result; |
| 1624 | bool castTruncatedToF16 = false; |
| 1625 | |
| 1623 | 1626 | if (actual_bits == wanted_bits) { |
| 1624 | 1627 | return expr_val; |
| 1625 | 1628 | } else if (actual_bits == 80) { |
| 1626 | 1629 | param_type = g->builtin_types.entry_f80->llvm_type; |
| 1627 | 1630 | switch (wanted_bits) { |
| 1628 | 1631 | case 16: |
| 1629 | | return_type = g->builtin_types.entry_f16->llvm_type; |
| 1632 | // Only Arm has a native f16 type, other platforms soft-implement it |
| 1633 | // using u16 instead. |
| 1634 | if (target_is_arm(g->zig_target)) { |
| 1635 | return_type = g->builtin_types.entry_f16->llvm_type; |
| 1636 | } else { |
| 1637 | return_type = g->builtin_types.entry_u16->llvm_type; |
| 1638 | castTruncatedToF16 = true; |
| 1639 | } |
| 1630 | 1640 | func_name = "__truncxfhf2"; |
| 1631 | 1641 | break; |
| 1632 | 1642 | case 32: |
| ... | ... | @@ -1648,7 +1658,14 @@ static LLVMValueRef gen_soft_f80_widen_or_shorten(CodeGen *g, ZigType *actual_ty |
| 1648 | 1658 | return_type = g->builtin_types.entry_f80->llvm_type; |
| 1649 | 1659 | switch (actual_bits) { |
| 1650 | 1660 | case 16: |
| 1651 | | param_type = g->builtin_types.entry_f16->llvm_type; |
| 1661 | // Only Arm has a native f16 type, other platforms soft-implement it |
| 1662 | // using u16 instead. |
| 1663 | if (target_is_arm(g->zig_target)) { |
| 1664 | param_type = g->builtin_types.entry_f16->llvm_type; |
| 1665 | } else { |
| 1666 | param_type = g->builtin_types.entry_u16->llvm_type; |
| 1667 | expr_val = LLVMBuildBitCast(g->builder, expr_val, param_type, ""); |
| 1668 | } |
| 1652 | 1669 | func_name = "__extendhfxf2"; |
| 1653 | 1670 | break; |
| 1654 | 1671 | case 32: |
| ... | ... | @@ -1676,7 +1693,14 @@ static LLVMValueRef gen_soft_f80_widen_or_shorten(CodeGen *g, ZigType *actual_ty |
| 1676 | 1693 | func_ref = LLVMAddFunction(g->module, func_name, fn_type); |
| 1677 | 1694 | } |
| 1678 | 1695 | |
| 1679 | | return LLVMBuildCall(g->builder, func_ref, &expr_val, 1, ""); |
| 1696 | result = LLVMBuildCall(g->builder, func_ref, &expr_val, 1, ""); |
| 1697 | |
| 1698 | // On non-Arm platforms we need to bitcast __truncxfhf2 result back to f16 |
| 1699 | if (castTruncatedToF16) { |
| 1700 | result = LLVMBuildBitCast(g->builder, result, g->builtin_types.entry_f16->llvm_type, ""); |
| 1701 | } |
| 1702 | |
| 1703 | return result; |
| 1680 | 1704 | } |
| 1681 | 1705 | |
| 1682 | 1706 | static LLVMValueRef gen_widen_or_shorten(CodeGen *g, bool want_runtime_safety, ZigType *actual_type, |
| ... | ... | @@ -10475,7 +10499,7 @@ void codegen_build_object(CodeGen *g) { |
| 10475 | 10499 | |
| 10476 | 10500 | codegen_add_time_event(g, "Done"); |
| 10477 | 10501 | codegen_switch_sub_prog_node(g, nullptr); |
| 10478 | | |
| 10502 | |
| 10479 | 10503 | // append all export symbols to stage2 so we can provide them to the linker |
| 10480 | 10504 | if (target_is_wasm(g->zig_target)){ |
| 10481 | 10505 | Error err; |