diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2022-03-21 23:54:17 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-03-21 23:54:17 +0100 |
| commit | a9b6de693ce04f73f8aecce91e8033951024c123 (patch) | |
| tree | a4600da1abaa7a18f3af1595dbb38b09d10955f4 /src | |
| parent | 916a65cb7bc96e5faa9337ab541d1ae230b48259 (diff) | |
| parent | 00e2113c8b07f9d1c67c7c70b69e7b9e6343b2d9 (diff) | |
| download | zig-a9b6de693ce04f73f8aecce91e8033951024c123.tar.gz zig-a9b6de693ce04f73f8aecce91e8033951024c123.zip | |
Merge pull request #11223 from mparadinha/ptr-elem-val
stage2: x86_64: implement `ptr_elem_val`
Diffstat (limited to 'src')
| -rw-r--r-- | src/arch/x86_64/CodeGen.zig | 52 |
1 files changed, 43 insertions, 9 deletions
diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 37d93f870c..ce049a4541 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -2174,10 +2174,44 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void { const is_volatile = false; // TODO const bin_op = self.air.instructions.items(.data)[inst].bin_op; - const result: MCValue = if (!is_volatile and self.liveness.isUnused(inst)) - .dead - else - return self.fail("TODO implement ptr_elem_val for {}", .{self.target.cpu.arch}); + const result: MCValue = if (!is_volatile and self.liveness.isUnused(inst)) .dead else result: { + // this is identical to the `airPtrElemPtr` codegen expect here an + // additional `mov` is needed at the end to get the actual value + + const ptr_ty = self.air.typeOf(bin_op.lhs); + const ptr = try self.resolveInst(bin_op.lhs); + ptr.freezeIfRegister(&self.register_manager); + defer ptr.unfreezeIfRegister(&self.register_manager); + + const elem_ty = ptr_ty.elemType2(); + const elem_abi_size = elem_ty.abiSize(self.target.*); + const index_ty = self.air.typeOf(bin_op.rhs); + const index = try self.resolveInst(bin_op.rhs); + index.freezeIfRegister(&self.register_manager); + defer index.unfreezeIfRegister(&self.register_manager); + + const offset_reg = try self.elemOffset(index_ty, index, elem_abi_size); + self.register_manager.freezeRegs(&.{offset_reg}); + defer self.register_manager.unfreezeRegs(&.{offset_reg}); + + const dst_mcv = try self.copyToRegisterWithInstTracking(inst, ptr_ty, ptr); + try self.genBinMathOpMir(.add, ptr_ty, dst_mcv, .{ .register = offset_reg }); + if (elem_abi_size > 8) { + return self.fail("TODO copy value with size {} from pointer", .{elem_abi_size}); + } else { + // mov dst_mcv, [dst_mcv] + _ = try self.addInst(.{ + .tag = .mov, + .ops = (Mir.Ops{ + .flags = 0b01, + .reg1 = registerAlias(dst_mcv.register, @intCast(u32, elem_abi_size)), + .reg2 = dst_mcv.register, + }).encode(), + .data = .{ .imm = 0 }, + }); + break :result .{ .register = registerAlias(dst_mcv.register, @intCast(u32, elem_abi_size)) }; + } + }; return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); } @@ -5166,7 +5200,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void if (!self.wantSafety()) return; // The already existing value will do just fine. // Write the debug undefined value. - switch (reg.size()) { + switch (registerAlias(reg, abi_size).size()) { 8 => return self.genSetReg(ty, reg, .{ .immediate = 0xaa }), 16 => return self.genSetReg(ty, reg, .{ .immediate = 0xaaaa }), 32 => return self.genSetReg(ty, reg, .{ .immediate = 0xaaaaaaaa }), @@ -5303,7 +5337,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void _ = try self.addInst(.{ .tag = .mov, .ops = (Mir.Ops{ - .reg1 = reg.to64(), + .reg1 = registerAlias(reg, abi_size), .reg2 = reg.to64(), .flags = 0b01, }).encode(), @@ -5316,7 +5350,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void _ = try self.addInst(.{ .tag = .mov, .ops = (Mir.Ops{ - .reg1 = reg, + .reg1 = registerAlias(reg, abi_size), .flags = 0b01, }).encode(), .data = .{ .imm = @truncate(u32, x) }, @@ -5343,8 +5377,8 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void _ = try self.addInst(.{ .tag = .mov, .ops = (Mir.Ops{ - .reg1 = reg, - .reg2 = reg, + .reg1 = registerAlias(reg, abi_size), + .reg2 = reg.to64(), .flags = 0b01, }).encode(), .data = .{ .imm = 0 }, |
