authorgravatar for techatrix@mailbox.orgTechatrix <techatrix@mailbox.org> 2023-09-08 01:19:38+02:00
committergravatar for techatrix@mailbox.orgTechatrix <techatrix@mailbox.org> 2023-09-10 15:59:02+02:00
log9d6b6bddb60e5a970b1c849c2a0b7a66451f8bc3
tree8a94a2bb772e8b03fa58d7a2af381aa4f12f3ddd
parent55694c2a4df8d11f5197b57393b0c64664d045b9

wasm: implement common conversions between integers/floats with bitsize larger than 64 bits


1 files changed, 48 insertions(+), 8 deletions(-)

src/arch/wasm/CodeGen.zig+48-8
......@@ -4857,11 +4857,31 @@ fn airIntFromFloat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
48574857 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
48584858
48594859 const operand = try func.resolveInst(ty_op.operand);
4860 const dest_ty = func.typeOfIndex(inst);
48614860 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;
48624882
4863 if (op_ty.abiSize(mod) > 8) {
4864 return func.fail("TODO: intFromFloat for integers/floats with bitsize larger than 64 bits", .{});
4883 const result = try (try func.callIntrinsic(fn_name, &.{op_ty.ip_index}, dest_ty, &.{operand})).toLocal(func, dest_ty);
4884 return func.finishAir(inst, result, &.{ty_op.operand});
48654885 }
48664886
48674887 try func.emitWValue(operand);
......@@ -4869,7 +4889,7 @@ fn airIntFromFloat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
48694889 .op = .trunc,
48704890 .valtype1 = typeToValtype(dest_ty, mod),
48714891 .valtype2 = typeToValtype(op_ty, mod),
4872 .signedness = if (dest_ty.isSignedInt(mod)) .signed else .unsigned,
4892 .signedness = dest_info.signedness,
48734893 });
48744894 try func.addTag(Mir.Inst.Tag.fromOpcode(op));
48754895 const wrapped = try func.wrapOperand(.{ .stack = {} }, dest_ty);
......@@ -4882,11 +4902,31 @@ fn airFloatFromInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
48824902 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
48834903
48844904 const operand = try func.resolveInst(ty_op.operand);
4885 const dest_ty = func.typeOfIndex(inst);
48864905 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;
48874927
4888 if (op_ty.abiSize(mod) > 8) {
4889 return func.fail("TODO: floatFromInt for integers/floats with bitsize larger than 64 bits", .{});
4928 const result = try (try func.callIntrinsic(fn_name, &.{op_ty.ip_index}, dest_ty, &.{operand})).toLocal(func, dest_ty);
4929 return func.finishAir(inst, result, &.{ty_op.operand});
48904930 }
48914931
48924932 try func.emitWValue(operand);
......@@ -4894,7 +4934,7 @@ fn airFloatFromInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
48944934 .op = .convert,
48954935 .valtype1 = typeToValtype(dest_ty, mod),
48964936 .valtype2 = typeToValtype(op_ty, mod),
4897 .signedness = if (op_ty.isSignedInt(mod)) .signed else .unsigned,
4937 .signedness = op_info.signedness,
48984938 });
48994939 try func.addTag(Mir.Inst.Tag.fromOpcode(op));
49004940