authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-02-07 17:08:33+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-02-07 20:13:29+01:00
log7a9b9df80e9799421393f476ea10332ba35ec258
treecac6f357f444b7c756226809979ea0d9d6a12d15
parentac36fe71147a78e5f9299428eee776efcc9e4afb

stage2,x64: impl masking reg for struct_field_val


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

src/arch/x86_64/CodeGen.zig+23-4
...@@ -2025,16 +2025,35 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -2025,16 +2025,35 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
2025 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {2025 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2026 const mcv = try self.resolveInst(operand);2026 const mcv = try self.resolveInst(operand);
2027 const struct_ty = self.air.typeOf(operand);2027 const struct_ty = self.air.typeOf(operand);
2028 const struct_size = @intCast(i32, struct_ty.abiSize(self.target.*));2028 const struct_size = struct_ty.abiSize(self.target.*);
2029 const struct_field_offset = @intCast(i32, struct_ty.structFieldOffset(index, self.target.*));2029 const struct_field_offset = struct_ty.structFieldOffset(index, self.target.*);
2030 const struct_field_ty = struct_ty.structFieldType(index);2030 const struct_field_ty = struct_ty.structFieldType(index);
2031 const struct_field_size = @intCast(i32, struct_field_ty.abiSize(self.target.*));2031 const struct_field_size = struct_field_ty.abiSize(self.target.*);
20322032
2033 switch (mcv) {2033 switch (mcv) {
2034 .stack_offset => |off| {2034 .stack_offset => |off| {
2035 const stack_offset = off + struct_size - struct_field_offset - struct_field_size;2035 const offset_to_field = struct_size - struct_field_offset - struct_field_size;
2036 const stack_offset = off + @intCast(i32, offset_to_field);
2036 break :result MCValue{ .stack_offset = stack_offset };2037 break :result MCValue{ .stack_offset = stack_offset };
2037 },2038 },
2039 .register => |reg| {
2040 // 1. Shift by struct_field_offset.
2041 // 2. Mask with reg.size() - struct_field_size
2042 // 3. Return in register
2043
2044 // TODO check if register can be re-used
2045 self.register_manager.freezeRegs(&.{reg});
2046 defer self.register_manager.unfreezeRegs(&.{reg});
2047 const dst_mcv = try self.copyToNewRegister(inst, Type.usize, .{ .register = reg.to64() });
2048
2049 // TODO shift here
2050
2051 const mask_shift = @intCast(u6, (64 - struct_field_ty.bitSize(self.target.*)));
2052 const mask = (~@as(u64, 0)) >> mask_shift;
2053 try self.genBinMathOpMir(.@"and", Type.usize, dst_mcv, .{ .immediate = mask });
2054
2055 break :result dst_mcv;
2056 },
2038 else => return self.fail("TODO implement codegen struct_field_val for {}", .{mcv}),2057 else => return self.fail("TODO implement codegen struct_field_val for {}", .{mcv}),
2039 }2058 }
2040 };2059 };