authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-03-21 23:54:17+01:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-03-21 23:54:17+01:00
loga9b6de693ce04f73f8aecce91e8033951024c123
treea4600da1abaa7a18f3af1595dbb38b09d10955f4
parent916a65cb7bc96e5faa9337ab541d1ae230b48259
parent00e2113c8b07f9d1c67c7c70b69e7b9e6343b2d9
signature Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #11223 from mparadinha/ptr-elem-val

stage2: x86_64: implement `ptr_elem_val`

3 files changed, 44 insertions(+), 16 deletions(-)

src/arch/x86_64/CodeGen.zig+43-9
...@@ -2174,10 +2174,44 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -2174,10 +2174,44 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
2174fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void {2174fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void {
2175 const is_volatile = false; // TODO2175 const is_volatile = false; // TODO
2176 const bin_op = self.air.instructions.items(.data)[inst].bin_op;2176 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
2177 const result: MCValue = if (!is_volatile and self.liveness.isUnused(inst))2177 const result: MCValue = if (!is_volatile and self.liveness.isUnused(inst)) .dead else result: {
2178 .dead2178 // this is identical to the `airPtrElemPtr` codegen expect here an
2179 else2179 // additional `mov` is needed at the end to get the actual value
2180 return self.fail("TODO implement ptr_elem_val for {}", .{self.target.cpu.arch});2180
2181 const ptr_ty = self.air.typeOf(bin_op.lhs);
2182 const ptr = try self.resolveInst(bin_op.lhs);
2183 ptr.freezeIfRegister(&self.register_manager);
2184 defer ptr.unfreezeIfRegister(&self.register_manager);
2185
2186 const elem_ty = ptr_ty.elemType2();
2187 const elem_abi_size = elem_ty.abiSize(self.target.*);
2188 const index_ty = self.air.typeOf(bin_op.rhs);
2189 const index = try self.resolveInst(bin_op.rhs);
2190 index.freezeIfRegister(&self.register_manager);
2191 defer index.unfreezeIfRegister(&self.register_manager);
2192
2193 const offset_reg = try self.elemOffset(index_ty, index, elem_abi_size);
2194 self.register_manager.freezeRegs(&.{offset_reg});
2195 defer self.register_manager.unfreezeRegs(&.{offset_reg});
2196
2197 const dst_mcv = try self.copyToRegisterWithInstTracking(inst, ptr_ty, ptr);
2198 try self.genBinMathOpMir(.add, ptr_ty, dst_mcv, .{ .register = offset_reg });
2199 if (elem_abi_size > 8) {
2200 return self.fail("TODO copy value with size {} from pointer", .{elem_abi_size});
2201 } else {
2202 // mov dst_mcv, [dst_mcv]
2203 _ = try self.addInst(.{
2204 .tag = .mov,
2205 .ops = (Mir.Ops{
2206 .flags = 0b01,
2207 .reg1 = registerAlias(dst_mcv.register, @intCast(u32, elem_abi_size)),
2208 .reg2 = dst_mcv.register,
2209 }).encode(),
2210 .data = .{ .imm = 0 },
2211 });
2212 break :result .{ .register = registerAlias(dst_mcv.register, @intCast(u32, elem_abi_size)) };
2213 }
2214 };
2181 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });2215 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
2182}2216}
21832217
...@@ -5166,7 +5200,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void...@@ -5166,7 +5200,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
5166 if (!self.wantSafety())5200 if (!self.wantSafety())
5167 return; // The already existing value will do just fine.5201 return; // The already existing value will do just fine.
5168 // Write the debug undefined value.5202 // Write the debug undefined value.
5169 switch (reg.size()) {5203 switch (registerAlias(reg, abi_size).size()) {
5170 8 => return self.genSetReg(ty, reg, .{ .immediate = 0xaa }),5204 8 => return self.genSetReg(ty, reg, .{ .immediate = 0xaa }),
5171 16 => return self.genSetReg(ty, reg, .{ .immediate = 0xaaaa }),5205 16 => return self.genSetReg(ty, reg, .{ .immediate = 0xaaaa }),
5172 32 => return self.genSetReg(ty, reg, .{ .immediate = 0xaaaaaaaa }),5206 32 => return self.genSetReg(ty, reg, .{ .immediate = 0xaaaaaaaa }),
...@@ -5303,7 +5337,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void...@@ -5303,7 +5337,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
5303 _ = try self.addInst(.{5337 _ = try self.addInst(.{
5304 .tag = .mov,5338 .tag = .mov,
5305 .ops = (Mir.Ops{5339 .ops = (Mir.Ops{
5306 .reg1 = reg.to64(),5340 .reg1 = registerAlias(reg, abi_size),
5307 .reg2 = reg.to64(),5341 .reg2 = reg.to64(),
5308 .flags = 0b01,5342 .flags = 0b01,
5309 }).encode(),5343 }).encode(),
...@@ -5316,7 +5350,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void...@@ -5316,7 +5350,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
5316 _ = try self.addInst(.{5350 _ = try self.addInst(.{
5317 .tag = .mov,5351 .tag = .mov,
5318 .ops = (Mir.Ops{5352 .ops = (Mir.Ops{
5319 .reg1 = reg,5353 .reg1 = registerAlias(reg, abi_size),
5320 .flags = 0b01,5354 .flags = 0b01,
5321 }).encode(),5355 }).encode(),
5322 .data = .{ .imm = @truncate(u32, x) },5356 .data = .{ .imm = @truncate(u32, x) },
...@@ -5343,8 +5377,8 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void...@@ -5343,8 +5377,8 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
5343 _ = try self.addInst(.{5377 _ = try self.addInst(.{
5344 .tag = .mov,5378 .tag = .mov,
5345 .ops = (Mir.Ops{5379 .ops = (Mir.Ops{
5346 .reg1 = reg,5380 .reg1 = registerAlias(reg, abi_size),
5347 .reg2 = reg,5381 .reg2 = reg.to64(),
5348 .flags = 0b01,5382 .flags = 0b01,
5349 }).encode(),5383 }).encode(),
5350 .data = .{ .imm = 0 },5384 .data = .{ .imm = 0 },
test/behavior/basic.zig-7
...@@ -382,7 +382,6 @@ fn hereIsAnOpaqueType(ptr: *OpaqueA) *OpaqueA {...@@ -382,7 +382,6 @@ fn hereIsAnOpaqueType(ptr: *OpaqueA) *OpaqueA {
382test "take address of parameter" {382test "take address of parameter" {
383 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;383 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
384 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;384 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
385 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
386385
387 try testTakeAddressOfParameter(12.34);386 try testTakeAddressOfParameter(12.34);
388}387}
...@@ -408,7 +407,6 @@ fn testPointerToVoidReturnType2() *const void {...@@ -408,7 +407,6 @@ fn testPointerToVoidReturnType2() *const void {
408test "array 2D const double ptr" {407test "array 2D const double ptr" {
409 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;408 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
410 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;409 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
411 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
412 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO410 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
413411
414 const rect_2d_vertexes = [_][1]f32{412 const rect_2d_vertexes = [_][1]f32{
...@@ -421,7 +419,6 @@ test "array 2D const double ptr" {...@@ -421,7 +419,6 @@ test "array 2D const double ptr" {
421test "array 2D const double ptr with offset" {419test "array 2D const double ptr with offset" {
422 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;420 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
423 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;421 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
424 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
425 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;422 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
426423
427 const rect_2d_vertexes = [_][2]f32{424 const rect_2d_vertexes = [_][2]f32{
...@@ -434,7 +431,6 @@ test "array 2D const double ptr with offset" {...@@ -434,7 +431,6 @@ test "array 2D const double ptr with offset" {
434test "array 3D const double ptr with offset" {431test "array 3D const double ptr with offset" {
435 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;432 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
436 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;433 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
437 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
438 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO434 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
439435
440 const rect_3d_vertexes = [_][2][2]f32{436 const rect_3d_vertexes = [_][2][2]f32{
...@@ -519,7 +515,6 @@ var global_foo: *i32 = undefined;...@@ -519,7 +515,6 @@ var global_foo: *i32 = undefined;
519test "peer result location with typed parent, runtime condition, comptime prongs" {515test "peer result location with typed parent, runtime condition, comptime prongs" {
520 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;516 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
521 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;517 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
522 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
523518
524 const S = struct {519 const S = struct {
525 fn doTheTest(arg: i32) i32 {520 fn doTheTest(arg: i32) i32 {
...@@ -620,7 +615,6 @@ test "self reference through fn ptr field" {...@@ -620,7 +615,6 @@ test "self reference through fn ptr field" {
620test "global variable initialized to global variable array element" {615test "global variable initialized to global variable array element" {
621 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;616 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
622 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;617 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
623 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
624618
625 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;619 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
626620
...@@ -655,7 +649,6 @@ test "global constant is loaded with a runtime-known index" {...@@ -655,7 +649,6 @@ test "global constant is loaded with a runtime-known index" {
655test "multiline string literal is null terminated" {649test "multiline string literal is null terminated" {
656 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;650 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
657 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;651 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
658 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
659652
660 const s1 =653 const s1 =
661 \\one654 \\one
test/behavior/eval.zig+1
...@@ -424,6 +424,7 @@ test "f64 at compile time is lossy" {...@@ -424,6 +424,7 @@ test "f64 at compile time is lossy" {
424}424}
425425
426test {426test {
427 if (builtin.zig_backend != .stage1 and builtin.os.tag == .macos) return error.SkipZigTest;
427 comptime try expect(@as(f128, 1 << 113) == 10384593717069655257060992658440192);428 comptime try expect(@as(f128, 1 << 113) == 10384593717069655257060992658440192);
428}429}
429430