aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKoakuma <koachan@protonmail.com>2022-05-15 10:20:35 +0700
committerKoakuma <koachan@protonmail.com>2022-05-16 23:30:54 +0700
commit77eef33c044d08096d828a3178ff6166a1502c26 (patch)
tree9c3293e9ce3190847c9e5e4bff75665c0bfe70c8
parent26116211eccddbe47afde4cbe0795c257cc882b8 (diff)
downloadzig-77eef33c044d08096d828a3178ff6166a1502c26.tar.gz
zig-77eef33c044d08096d828a3178ff6166a1502c26.zip
stage2: sparc64: Implement airStructFieldPtrIndex
-rw-r--r--src/arch/sparc64/CodeGen.zig50
1 files changed, 46 insertions, 4 deletions
diff --git a/src/arch/sparc64/CodeGen.zig b/src/arch/sparc64/CodeGen.zig
index f301f7412a..8ad135609b 100644
--- a/src/arch/sparc64/CodeGen.zig
+++ b/src/arch/sparc64/CodeGen.zig
@@ -623,10 +623,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
.atomic_store_release => @panic("TODO try self.airAtomicStore(inst, .Release)"),
.atomic_store_seq_cst => @panic("TODO try self.airAtomicStore(inst, .SeqCst)"),
- .struct_field_ptr_index_0 => @panic("TODO try self.airStructFieldPtrIndex(inst, 0)"),
- .struct_field_ptr_index_1 => @panic("TODO try self.airStructFieldPtrIndex(inst, 1)"),
- .struct_field_ptr_index_2 => @panic("TODO try self.airStructFieldPtrIndex(inst, 2)"),
- .struct_field_ptr_index_3 => @panic("TODO try self.airStructFieldPtrIndex(inst, 3)"),
+ .struct_field_ptr_index_0 => try self.airStructFieldPtrIndex(inst, 0),
+ .struct_field_ptr_index_1 => try self.airStructFieldPtrIndex(inst, 1),
+ .struct_field_ptr_index_2 => try self.airStructFieldPtrIndex(inst, 2),
+ .struct_field_ptr_index_3 => try self.airStructFieldPtrIndex(inst, 3),
.field_parent_ptr => @panic("TODO try self.airFieldParentPtr(inst)"),
@@ -1452,6 +1452,12 @@ fn airStore(self: *Self, inst: Air.Inst.Index) !void {
return self.finishAir(inst, .dead, .{ bin_op.lhs, bin_op.rhs, .none });
}
+fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void {
+ const ty_op = self.air.instructions.items(.data)[inst].ty_op;
+ const result = try self.structFieldPtr(inst, ty_op.operand, index);
+ return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
+}
+
fn airSwitch(self: *Self, inst: Air.Inst.Index) !void {
_ = self;
_ = inst;
@@ -2987,6 +2993,42 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
}
}
+fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue {
+ return if (self.liveness.isUnused(inst)) .dead else result: {
+ const mcv = try self.resolveInst(operand);
+ const ptr_ty = self.air.typeOf(operand);
+ const struct_ty = ptr_ty.childType();
+ const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, self.target.*));
+ switch (mcv) {
+ .ptr_stack_offset => |off| {
+ break :result MCValue{ .ptr_stack_offset = off - struct_field_offset };
+ },
+ else => {
+ const offset_reg = try self.copyToTmpRegister(ptr_ty, .{
+ .immediate = struct_field_offset,
+ });
+ const offset_reg_lock = self.register_manager.lockRegAssumeUnused(offset_reg);
+ defer self.register_manager.unlockReg(offset_reg_lock);
+
+ const addr_reg = try self.copyToTmpRegister(ptr_ty, mcv);
+ const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg);
+ defer self.register_manager.unlockReg(addr_reg_lock);
+
+ const dest = try self.binOp(
+ .add,
+ null,
+ .{ .register = addr_reg },
+ .{ .register = offset_reg },
+ Type.usize,
+ Type.usize,
+ );
+
+ break :result dest;
+ },
+ }
+ };
+}
+
fn truncRegister(
self: *Self,
operand_reg: Register,