authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-05-08 19:31:16-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-05-15 03:07:51-04:00
loge36e9323f4c4ce66013ba4774ff0145fc9cad34d
treec50e24a04d072b93125c95d0ff99cac564bd036b
parent1667e831cf8099271d97c9391fe4400622e6f96f

x86_64: implement union_init


5 files changed, 40 insertions(+), 13 deletions(-)

src/arch/x86_64/CodeGen.zig+40-3
......@@ -10147,9 +10147,46 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
1014710147fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void {
1014810148 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
1014910149 const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data;
10150 _ = extra;
10151 return self.fail("TODO implement airUnionInit for x86_64", .{});
10152 //return self.finishAir(inst, result, .{ extra.init, .none, .none });
10150 const result: MCValue = result: {
10151 const union_ty = self.air.typeOfIndex(inst);
10152 const layout = union_ty.unionGetLayout(self.target.*);
10153
10154 const src_ty = self.air.typeOf(extra.init);
10155 const src_mcv = try self.resolveInst(extra.init);
10156 if (layout.tag_size == 0) {
10157 if (self.reuseOperand(inst, extra.init, 0, src_mcv)) break :result src_mcv;
10158
10159 const dst_mcv = try self.allocRegOrMem(inst, true);
10160 try self.genCopy(src_ty, dst_mcv, src_mcv);
10161 break :result dst_mcv;
10162 }
10163
10164 const dst_mcv = try self.allocRegOrMem(inst, false);
10165
10166 const union_obj = union_ty.cast(Type.Payload.Union).?.data;
10167 const field_name = union_obj.fields.keys()[extra.field_index];
10168 const tag_ty = union_ty.unionTagTypeSafety().?;
10169 const field_index = @intCast(u32, tag_ty.enumFieldIndex(field_name).?);
10170 var tag_pl = Value.Payload.U32{ .base = .{ .tag = .enum_field_index }, .data = field_index };
10171 const tag_val = Value.initPayload(&tag_pl.base);
10172 var tag_int_pl: Value.Payload.U64 = undefined;
10173 const tag_int_val = tag_val.enumToInt(tag_ty, &tag_int_pl);
10174 const tag_int = tag_int_val.toUnsignedInt(self.target.*);
10175 const tag_off = if (layout.tag_align < layout.payload_align)
10176 @intCast(i32, layout.payload_size)
10177 else
10178 0;
10179 try self.genCopy(tag_ty, dst_mcv.address().offset(tag_off).deref(), .{ .immediate = tag_int });
10180
10181 const pl_off = if (layout.tag_align < layout.payload_align)
10182 0
10183 else
10184 @intCast(i32, layout.tag_size);
10185 try self.genCopy(src_ty, dst_mcv.address().offset(pl_off).deref(), src_mcv);
10186
10187 break :result dst_mcv;
10188 };
10189 return self.finishAir(inst, result, .{ extra.init, .none, .none });
1015310190}
1015410191
1015510192fn airPrefetch(self: *Self, inst: Air.Inst.Index) !void {
test/behavior/bugs/13366.zig-1
......@@ -14,7 +14,6 @@ const Block = struct {
1414
1515test {
1616 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
17 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1817 if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO
1918 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
2019 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
test/behavior/struct.zig-1
......@@ -1352,7 +1352,6 @@ test "struct field init value is size of the struct" {
13521352}
13531353
13541354test "under-aligned struct field" {
1355 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
13561355 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
13571356 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
13581357 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
test/behavior/tuple.zig-1
......@@ -367,7 +367,6 @@ test "branching inside tuple literal" {
367367test "tuple initialized with a runtime known value" {
368368 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
369369 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
370 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
371370 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
372371 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
373372
test/behavior/union.zig-7
......@@ -821,7 +821,6 @@ test "return union init with void payload" {
821821}
822822
823823test "@unionInit stored to a const" {
824 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
825824 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
826825 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
827826 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
......@@ -994,7 +993,6 @@ test "function call result coerces from tagged union to the tag" {
994993}
995994
996995test "cast from anonymous struct to union" {
997 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
998996 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
999997 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1000998 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
......@@ -1028,7 +1026,6 @@ test "cast from anonymous struct to union" {
10281026}
10291027
10301028test "cast from pointer to anonymous struct to pointer to union" {
1031 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
10321029 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
10331030 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
10341031 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
......@@ -1199,7 +1196,6 @@ test "global variable struct contains union initialized to non-most-aligned fiel
11991196test "union with no result loc initiated with a runtime value" {
12001197 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
12011198 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1202 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
12031199 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
12041200 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
12051201
......@@ -1217,7 +1213,6 @@ test "union with no result loc initiated with a runtime value" {
12171213test "union with a large struct field" {
12181214 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
12191215 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1220 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
12211216 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
12221217 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
12231218
......@@ -1288,7 +1283,6 @@ test "extern union most-aligned field is smaller" {
12881283}
12891284
12901285test "return an extern union from C calling convention" {
1291 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
12921286 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
12931287 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
12941288 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
......@@ -1397,7 +1391,6 @@ test "union and enum field order doesn't match" {
13971391}
13981392
13991393test "@unionInit uses tag value instead of field index" {
1400 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
14011394 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
14021395 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
14031396 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO