authorgravatar for miguel.p.paradinha@gmail.commparadinha <miguel.p.paradinha@gmail.com> 2022-03-18 03:33:18+00:00
committergravatar for miguel.p.paradinha@gmail.commparadinha <miguel.p.paradinha@gmail.com> 2022-03-21 19:32:46+00:00
log6d7808e647e6d244e53a18139c22bce8cd38a3ca
tree5cf473b372fff7177a6f91b00459de74dc006aa9
parent18a43b61f92ae937e39fc5dbc3de581e26709151

stage2: x86_64: implement `ptr_elem_val`

The codegen for this is almost identical to `ptr_elem_ptr` except there's an extra `mov` at the end to replace the pointer with the value it points to, "in-place" (which can be done in a single instruction without any extra registers).

1 files changed, 38 insertions(+), 4 deletions(-)

src/arch/x86_64/CodeGen.zig+38-4
......@@ -2174,10 +2174,44 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
21742174fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void {
21752175 const is_volatile = false; // TODO
21762176 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
2177 const result: MCValue = if (!is_volatile and self.liveness.isUnused(inst))
2178 .dead
2179 else
2180 return self.fail("TODO implement ptr_elem_val for {}", .{self.target.cpu.arch});
2177 const result: MCValue = if (!is_volatile and self.liveness.isUnused(inst)) .dead else result: {
2178 // this is identical to the `airPtrElemPtr` codegen expect here an
2179 // additional `mov` is needed at the end to get the actual value
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 };
21812215 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
21822216}
21832217