| ... | @@ -4857,11 +4857,31 @@ fn airIntFromFloat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -4857,11 +4857,31 @@ fn airIntFromFloat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4857 | const ty_op = func.air.instructions.items(.data)[inst].ty_op; | 4857 | const ty_op = func.air.instructions.items(.data)[inst].ty_op; |
| 4858 | | 4858 | |
| 4859 | const operand = try func.resolveInst(ty_op.operand); | 4859 | const operand = try func.resolveInst(ty_op.operand); |
| 4860 | const dest_ty = func.typeOfIndex(inst); | | |
| 4861 | const op_ty = func.typeOf(ty_op.operand); | 4860 | const op_ty = func.typeOf(ty_op.operand); |
| | 4861 | const op_bits = op_ty.floatBits(func.target); |
| | 4862 | |
| | 4863 | const dest_ty = func.typeOfIndex(inst); |
| | 4864 | const dest_info = dest_ty.intInfo(mod); |
| | 4865 | |
| | 4866 | if (dest_info.bits > 128) { |
| | 4867 | return func.fail("TODO: intFromFloat for integers/floats with bitsize {}", .{dest_info.bits}); |
| | 4868 | } |
| | 4869 | |
| | 4870 | if ((op_bits != 32 and op_bits != 64) or dest_info.bits > 64) { |
| | 4871 | const dest_bitsize = if (dest_info.bits <= 16) 16 else std.math.ceilPowerOfTwoAssert(u16, dest_info.bits); |
| | 4872 | |
| | 4873 | var fn_name_buf: [16]u8 = undefined; |
| | 4874 | const fn_name = std.fmt.bufPrint(&fn_name_buf, "__fix{s}{s}f{s}i", .{ |
| | 4875 | switch (dest_info.signedness) { |
| | 4876 | .signed => "", |
| | 4877 | .unsigned => "uns", |
| | 4878 | }, |
| | 4879 | target_util.compilerRtFloatAbbrev(op_bits), |
| | 4880 | target_util.compilerRtIntAbbrev(dest_bitsize), |
| | 4881 | }) catch unreachable; |
| 4862 | | 4882 | |
| 4863 | if (op_ty.abiSize(mod) > 8) { | 4883 | const result = try (try func.callIntrinsic(fn_name, &.{op_ty.ip_index}, dest_ty, &.{operand})).toLocal(func, dest_ty); |
| 4864 | return func.fail("TODO: intFromFloat for integers/floats with bitsize larger than 64 bits", .{}); | 4884 | return func.finishAir(inst, result, &.{ty_op.operand}); |
| 4865 | } | 4885 | } |
| 4866 | | 4886 | |
| 4867 | try func.emitWValue(operand); | 4887 | try func.emitWValue(operand); |
| ... | @@ -4869,7 +4889,7 @@ fn airIntFromFloat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -4869,7 +4889,7 @@ fn airIntFromFloat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4869 | .op = .trunc, | 4889 | .op = .trunc, |
| 4870 | .valtype1 = typeToValtype(dest_ty, mod), | 4890 | .valtype1 = typeToValtype(dest_ty, mod), |
| 4871 | .valtype2 = typeToValtype(op_ty, mod), | 4891 | .valtype2 = typeToValtype(op_ty, mod), |
| 4872 | .signedness = if (dest_ty.isSignedInt(mod)) .signed else .unsigned, | 4892 | .signedness = dest_info.signedness, |
| 4873 | }); | 4893 | }); |
| 4874 | try func.addTag(Mir.Inst.Tag.fromOpcode(op)); | 4894 | try func.addTag(Mir.Inst.Tag.fromOpcode(op)); |
| 4875 | const wrapped = try func.wrapOperand(.{ .stack = {} }, dest_ty); | 4895 | const wrapped = try func.wrapOperand(.{ .stack = {} }, dest_ty); |
| ... | @@ -4882,11 +4902,31 @@ fn airFloatFromInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -4882,11 +4902,31 @@ fn airFloatFromInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4882 | const ty_op = func.air.instructions.items(.data)[inst].ty_op; | 4902 | const ty_op = func.air.instructions.items(.data)[inst].ty_op; |
| 4883 | | 4903 | |
| 4884 | const operand = try func.resolveInst(ty_op.operand); | 4904 | const operand = try func.resolveInst(ty_op.operand); |
| 4885 | const dest_ty = func.typeOfIndex(inst); | | |
| 4886 | const op_ty = func.typeOf(ty_op.operand); | 4905 | const op_ty = func.typeOf(ty_op.operand); |
| | 4906 | const op_info = op_ty.intInfo(mod); |
| | 4907 | |
| | 4908 | const dest_ty = func.typeOfIndex(inst); |
| | 4909 | const dest_bits = dest_ty.floatBits(func.target); |
| | 4910 | |
| | 4911 | if (op_info.bits > 128) { |
| | 4912 | return func.fail("TODO: floatFromInt for integers/floats with bitsize {d} bits", .{op_info.bits}); |
| | 4913 | } |
| | 4914 | |
| | 4915 | if (op_info.bits > 64 or (dest_bits > 64 or dest_bits < 32)) { |
| | 4916 | const op_bitsize = if (op_info.bits <= 16) 16 else std.math.ceilPowerOfTwoAssert(u16, op_info.bits); |
| | 4917 | |
| | 4918 | var fn_name_buf: [16]u8 = undefined; |
| | 4919 | const fn_name = std.fmt.bufPrint(&fn_name_buf, "__float{s}{s}i{s}f", .{ |
| | 4920 | switch (op_info.signedness) { |
| | 4921 | .signed => "", |
| | 4922 | .unsigned => "un", |
| | 4923 | }, |
| | 4924 | target_util.compilerRtIntAbbrev(op_bitsize), |
| | 4925 | target_util.compilerRtFloatAbbrev(dest_bits), |
| | 4926 | }) catch unreachable; |
| 4887 | | 4927 | |
| 4888 | if (op_ty.abiSize(mod) > 8) { | 4928 | const result = try (try func.callIntrinsic(fn_name, &.{op_ty.ip_index}, dest_ty, &.{operand})).toLocal(func, dest_ty); |
| 4889 | return func.fail("TODO: floatFromInt for integers/floats with bitsize larger than 64 bits", .{}); | 4929 | return func.finishAir(inst, result, &.{ty_op.operand}); |
| 4890 | } | 4930 | } |
| 4891 | | 4931 | |
| 4892 | try func.emitWValue(operand); | 4932 | try func.emitWValue(operand); |
| ... | @@ -4894,7 +4934,7 @@ fn airFloatFromInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -4894,7 +4934,7 @@ fn airFloatFromInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4894 | .op = .convert, | 4934 | .op = .convert, |
| 4895 | .valtype1 = typeToValtype(dest_ty, mod), | 4935 | .valtype1 = typeToValtype(dest_ty, mod), |
| 4896 | .valtype2 = typeToValtype(op_ty, mod), | 4936 | .valtype2 = typeToValtype(op_ty, mod), |
| 4897 | .signedness = if (op_ty.isSignedInt(mod)) .signed else .unsigned, | 4937 | .signedness = op_info.signedness, |
| 4898 | }); | 4938 | }); |
| 4899 | try func.addTag(Mir.Inst.Tag.fromOpcode(op)); | 4939 | try func.addTag(Mir.Inst.Tag.fromOpcode(op)); |
| 4900 | | 4940 | |