authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2023-05-29 12:33:24+02:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2023-05-31 18:04:33+02:00
loge36cc0ce8f4c0ec7c1398149c5fa30f15d8dae9f
tree15c5787dde73bf473c8e79de3f03843db754ef59
parent128814f9bf89460232569ae3e47c52f90cdf4ffd
signaturelock-open Commit is signed but in an unrecognized format.

wasm: `union_init` support packed unions


1 files changed, 61 insertions(+), 22 deletions(-)

src/arch/wasm/CodeGen.zig+61-22
...@@ -1014,6 +1014,17 @@ fn typeToValtype(ty: Type, target: std.Target) wasm.Valtype {...@@ -1014,6 +1014,17 @@ fn typeToValtype(ty: Type, target: std.Target) wasm.Valtype {
1014 .direct => wasm.Valtype.v128,1014 .direct => wasm.Valtype.v128,
1015 .unrolled => wasm.Valtype.i32,1015 .unrolled => wasm.Valtype.i32,
1016 },1016 },
1017 .Union => switch (ty.containerLayout()) {
1018 .Packed => {
1019 var int_ty_payload: Type.Payload.Bits = .{
1020 .base = .{ .tag = .int_unsigned },
1021 .data = @intCast(u16, ty.bitSize(target)),
1022 };
1023 const int_ty = Type.initPayload(&int_ty_payload.base);
1024 return typeToValtype(int_ty, target);
1025 },
1026 else => wasm.Valtype.i32,
1027 },
1017 else => wasm.Valtype.i32, // all represented as reference/immediate1028 else => wasm.Valtype.i32, // all represented as reference/immediate
1018 };1029 };
1019}1030}
...@@ -5074,33 +5085,61 @@ fn airUnionInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5074,33 +5085,61 @@ fn airUnionInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5074 assert(!isByRef(union_ty, func.target));5085 assert(!isByRef(union_ty, func.target));
5075 break :result tag_int;5086 break :result tag_int;
5076 }5087 }
5077 assert(isByRef(union_ty, func.target));
5078
5079 const result_ptr = try func.allocStack(union_ty);
5080 const payload = try func.resolveInst(extra.init);
5081 if (layout.tag_align >= layout.payload_align) {
5082 if (isByRef(field.ty, func.target)) {
5083 const payload_ptr = try func.buildPointerOffset(result_ptr, layout.tag_size, .new);
5084 try func.store(payload_ptr, payload, field.ty, 0);
5085 } else {
5086 try func.store(result_ptr, payload, field.ty, @intCast(u32, layout.tag_size));
5087 }
50885088
5089 if (layout.tag_size > 0) {5089 if (isByRef(union_ty, func.target)) {
5090 try func.store(result_ptr, tag_int, union_obj.tag_ty, 0);5090 const result_ptr = try func.allocStack(union_ty);
5091 const payload = try func.resolveInst(extra.init);
5092 if (layout.tag_align >= layout.payload_align) {
5093 if (isByRef(field.ty, func.target)) {
5094 const payload_ptr = try func.buildPointerOffset(result_ptr, layout.tag_size, .new);
5095 try func.store(payload_ptr, payload, field.ty, 0);
5096 } else {
5097 try func.store(result_ptr, payload, field.ty, @intCast(u32, layout.tag_size));
5098 }
5099
5100 if (layout.tag_size > 0) {
5101 try func.store(result_ptr, tag_int, union_obj.tag_ty, 0);
5102 }
5103 } else {
5104 try func.store(result_ptr, payload, field.ty, 0);
5105 if (layout.tag_size > 0) {
5106 try func.store(
5107 result_ptr,
5108 tag_int,
5109 union_obj.tag_ty,
5110 @intCast(u32, layout.payload_size),
5111 );
5112 }
5091 }5113 }
5114 break :result result_ptr;
5092 } else {5115 } else {
5093 try func.store(result_ptr, payload, field.ty, 0);5116 const operand = try func.resolveInst(extra.init);
5094 if (layout.tag_size > 0) {5117 var payload: Type.Payload.Bits = .{
5095 try func.store(5118 .base = .{ .tag = .int_unsigned },
5096 result_ptr,5119 .data = @intCast(u16, union_ty.bitSize(func.target)),
5097 tag_int,5120 };
5098 union_obj.tag_ty,5121 const union_int_type = Type.initPayload(&payload.base);
5099 @intCast(u32, layout.payload_size),5122 if (field.ty.zigTypeTag() == .Float) {
5100 );5123 var int_payload: Type.Payload.Bits = .{
5124 .base = .{ .tag = .int_unsigned },
5125 .data = @intCast(u16, field.ty.bitSize(func.target)),
5126 };
5127 const int_type = Type.initPayload(&int_payload.base);
5128 const bitcasted = try func.bitcast(field.ty, int_type, operand);
5129 const casted = try func.trunc(bitcasted, int_type, union_int_type);
5130 break :result try casted.toLocal(func, field.ty);
5131 } else if (field.ty.isPtrAtRuntime()) {
5132 var int_payload: Type.Payload.Bits = .{
5133 .base = .{ .tag = .int_unsigned },
5134 .data = @intCast(u16, field.ty.bitSize(func.target)),
5135 };
5136 const int_type = Type.initPayload(&int_payload.base);
5137 const casted = try func.intcast(operand, int_type, union_int_type);
5138 break :result try casted.toLocal(func, field.ty);
5101 }5139 }
5140 const casted = try func.intcast(operand, field.ty, union_int_type);
5141 break :result try casted.toLocal(func, field.ty);
5102 }5142 }
5103 break :result result_ptr;
5104 };5143 };
51055144
5106 return func.finishAir(inst, result, &.{extra.init});5145 return func.finishAir(inst, result, &.{extra.init});