authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2023-05-23 19:55:33+02:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2023-05-31 18:04:32+02:00
log7cfc44d86ff56fd760eaf0781cc3ba0650267af9
tree7bd69cbf461ec375c5ffbc1c79cb99d039fe5f2f
parent49fddbf4c11d4ea493c1e5b6176052aeacc1ad10
signaturelock-open Commit is signed but in an unrecognized format.

wasm: implement `struct_field_val` for packed unions

We currently have `isRef` return true for any type of union, including packed unions. This means we can simply load it from the data section to the exact type we want. In the future we can optimize it so it works similarly to packed structs below 64 bits which do not get stored in the data section and are not passed by ref.

1 files changed, 5 insertions(+), 3 deletions(-)

src/arch/wasm/CodeGen.zig+5-3
...@@ -3617,7 +3617,6 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3617,7 +3617,6 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3617 .Packed => switch (struct_ty.zigTypeTag()) {3617 .Packed => switch (struct_ty.zigTypeTag()) {
3618 .Struct => result: {3618 .Struct => result: {
3619 const struct_obj = struct_ty.castTag(.@"struct").?.data;3619 const struct_obj = struct_ty.castTag(.@"struct").?.data;
3620 assert(struct_obj.layout == .Packed);
3621 const offset = struct_obj.packedFieldBitOffset(func.target, field_index);3620 const offset = struct_obj.packedFieldBitOffset(func.target, field_index);
3622 const backing_ty = struct_obj.backing_int_ty;3621 const backing_ty = struct_obj.backing_int_ty;
3623 const wasm_bits = toWasmBits(backing_ty.intInfo(func.target).bits) orelse {3622 const wasm_bits = toWasmBits(backing_ty.intInfo(func.target).bits) orelse {
...@@ -3661,7 +3660,10 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3661,7 +3660,10 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3661 const truncated = try func.trunc(shifted_value, field_ty, backing_ty);3660 const truncated = try func.trunc(shifted_value, field_ty, backing_ty);
3662 break :result try truncated.toLocal(func, field_ty);3661 break :result try truncated.toLocal(func, field_ty);
3663 },3662 },
3664 .Union => return func.fail("TODO: airStructFieldVal for packed unions", .{}),3663 .Union => result: {
3664 const val = try func.load(operand, field_ty, 0);
3665 break :result try val.toLocal(func, field_ty);
3666 },
3665 else => unreachable,3667 else => unreachable,
3666 },3668 },
3667 else => result: {3669 else => result: {
...@@ -5032,7 +5034,7 @@ fn airUnionInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5032,7 +5034,7 @@ fn airUnionInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5032 break :result result_ptr;5034 break :result result_ptr;
5033 };5035 };
50345036
5035 func.finishAir(inst, result, &.{extra.init});5037 return func.finishAir(inst, result, &.{extra.init});
5036}5038}
50375039
5038fn airPrefetch(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {5040fn airPrefetch(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {