| ... | @@ -623,10 +623,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -623,10 +623,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 623 | .atomic_store_release => @panic("TODO try self.airAtomicStore(inst, .Release)"), | 623 | .atomic_store_release => @panic("TODO try self.airAtomicStore(inst, .Release)"), |
| 624 | .atomic_store_seq_cst => @panic("TODO try self.airAtomicStore(inst, .SeqCst)"), | 624 | .atomic_store_seq_cst => @panic("TODO try self.airAtomicStore(inst, .SeqCst)"), |
| 625 | | 625 | |
| 626 | .struct_field_ptr_index_0 => @panic("TODO try self.airStructFieldPtrIndex(inst, 0)"), | 626 | .struct_field_ptr_index_0 => try self.airStructFieldPtrIndex(inst, 0), |
| 627 | .struct_field_ptr_index_1 => @panic("TODO try self.airStructFieldPtrIndex(inst, 1)"), | 627 | .struct_field_ptr_index_1 => try self.airStructFieldPtrIndex(inst, 1), |
| 628 | .struct_field_ptr_index_2 => @panic("TODO try self.airStructFieldPtrIndex(inst, 2)"), | 628 | .struct_field_ptr_index_2 => try self.airStructFieldPtrIndex(inst, 2), |
| 629 | .struct_field_ptr_index_3 => @panic("TODO try self.airStructFieldPtrIndex(inst, 3)"), | 629 | .struct_field_ptr_index_3 => try self.airStructFieldPtrIndex(inst, 3), |
| 630 | | 630 | |
| 631 | .field_parent_ptr => @panic("TODO try self.airFieldParentPtr(inst)"), | 631 | .field_parent_ptr => @panic("TODO try self.airFieldParentPtr(inst)"), |
| 632 | | 632 | |
| ... | @@ -1452,6 +1452,12 @@ fn airStore(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1452,6 +1452,12 @@ fn airStore(self: *Self, inst: Air.Inst.Index) !void { |
| 1452 | return self.finishAir(inst, .dead, .{ bin_op.lhs, bin_op.rhs, .none }); | 1452 | return self.finishAir(inst, .dead, .{ bin_op.lhs, bin_op.rhs, .none }); |
| 1453 | } | 1453 | } |
| 1454 | | 1454 | |
| | 1455 | fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void { |
| | 1456 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| | 1457 | const result = try self.structFieldPtr(inst, ty_op.operand, index); |
| | 1458 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| | 1459 | } |
| | 1460 | |
| 1455 | fn airSwitch(self: *Self, inst: Air.Inst.Index) !void { | 1461 | fn airSwitch(self: *Self, inst: Air.Inst.Index) !void { |
| 1456 | _ = self; | 1462 | _ = self; |
| 1457 | _ = inst; | 1463 | _ = inst; |
| ... | @@ -2987,6 +2993,42 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type | ... | @@ -2987,6 +2993,42 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 2987 | } | 2993 | } |
| 2988 | } | 2994 | } |
| 2989 | | 2995 | |
| | 2996 | fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue { |
| | 2997 | return if (self.liveness.isUnused(inst)) .dead else result: { |
| | 2998 | const mcv = try self.resolveInst(operand); |
| | 2999 | const ptr_ty = self.air.typeOf(operand); |
| | 3000 | const struct_ty = ptr_ty.childType(); |
| | 3001 | const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, self.target.*)); |
| | 3002 | switch (mcv) { |
| | 3003 | .ptr_stack_offset => |off| { |
| | 3004 | break :result MCValue{ .ptr_stack_offset = off - struct_field_offset }; |
| | 3005 | }, |
| | 3006 | else => { |
| | 3007 | const offset_reg = try self.copyToTmpRegister(ptr_ty, .{ |
| | 3008 | .immediate = struct_field_offset, |
| | 3009 | }); |
| | 3010 | const offset_reg_lock = self.register_manager.lockRegAssumeUnused(offset_reg); |
| | 3011 | defer self.register_manager.unlockReg(offset_reg_lock); |
| | 3012 | |
| | 3013 | const addr_reg = try self.copyToTmpRegister(ptr_ty, mcv); |
| | 3014 | const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| | 3015 | defer self.register_manager.unlockReg(addr_reg_lock); |
| | 3016 | |
| | 3017 | const dest = try self.binOp( |
| | 3018 | .add, |
| | 3019 | null, |
| | 3020 | .{ .register = addr_reg }, |
| | 3021 | .{ .register = offset_reg }, |
| | 3022 | Type.usize, |
| | 3023 | Type.usize, |
| | 3024 | ); |
| | 3025 | |
| | 3026 | break :result dest; |
| | 3027 | }, |
| | 3028 | } |
| | 3029 | }; |
| | 3030 | } |
| | 3031 | |
| 2990 | fn truncRegister( | 3032 | fn truncRegister( |
| 2991 | self: *Self, | 3033 | self: *Self, |
| 2992 | operand_reg: Register, | 3034 | operand_reg: Register, |