| ... | ... | @@ -623,10 +623,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 623 | 623 | .atomic_store_release => @panic("TODO try self.airAtomicStore(inst, .Release)"), |
| 624 | 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)"), |
| 627 | | .struct_field_ptr_index_1 => @panic("TODO try self.airStructFieldPtrIndex(inst, 1)"), |
| 628 | | .struct_field_ptr_index_2 => @panic("TODO try self.airStructFieldPtrIndex(inst, 2)"), |
| 629 | | .struct_field_ptr_index_3 => @panic("TODO try self.airStructFieldPtrIndex(inst, 3)"), |
| 626 | .struct_field_ptr_index_0 => try self.airStructFieldPtrIndex(inst, 0), |
| 627 | .struct_field_ptr_index_1 => try self.airStructFieldPtrIndex(inst, 1), |
| 628 | .struct_field_ptr_index_2 => try self.airStructFieldPtrIndex(inst, 2), |
| 629 | .struct_field_ptr_index_3 => try self.airStructFieldPtrIndex(inst, 3), |
| 630 | 630 | |
| 631 | 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 | 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 | 1461 | fn airSwitch(self: *Self, inst: Air.Inst.Index) !void { |
| 1456 | 1462 | _ = self; |
| 1457 | 1463 | _ = inst; |
| ... | ... | @@ -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 | 3032 | fn truncRegister( |
| 2991 | 3033 | self: *Self, |
| 2992 | 3034 | operand_reg: Register, |