| ... | @@ -1643,7 +1643,8 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void { | ... | @@ -1643,7 +1643,8 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void { |
| 1643 | fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue { | 1643 | fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue { |
| 1644 | return if (self.liveness.isUnused(inst)) .dead else result: { | 1644 | return if (self.liveness.isUnused(inst)) .dead else result: { |
| 1645 | const mcv = try self.resolveInst(operand); | 1645 | const mcv = try self.resolveInst(operand); |
| 1646 | const struct_ty = self.air.typeOf(operand).childType(); | 1646 | const ptr_ty = self.air.typeOf(operand); |
| | 1647 | const struct_ty = ptr_ty.childType(); |
| 1647 | const struct_size = @intCast(u32, struct_ty.abiSize(self.target.*)); | 1648 | const struct_size = @intCast(u32, struct_ty.abiSize(self.target.*)); |
| 1648 | const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, self.target.*)); | 1649 | const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, self.target.*)); |
| 1649 | const struct_field_ty = struct_ty.structFieldType(index); | 1650 | const struct_field_ty = struct_ty.structFieldType(index); |
| ... | @@ -1652,6 +1653,28 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde | ... | @@ -1652,6 +1653,28 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde |
| 1652 | .ptr_stack_offset => |off| { | 1653 | .ptr_stack_offset => |off| { |
| 1653 | break :result MCValue{ .ptr_stack_offset = off + struct_size - struct_field_offset - struct_field_size }; | 1654 | break :result MCValue{ .ptr_stack_offset = off + struct_size - struct_field_offset - struct_field_size }; |
| 1654 | }, | 1655 | }, |
| | 1656 | .stack_argument_offset => { |
| | 1657 | const offset_reg = try self.copyToTmpRegister(ptr_ty, .{ |
| | 1658 | .immediate = struct_field_offset, |
| | 1659 | }); |
| | 1660 | self.register_manager.freezeRegs(&.{offset_reg}); |
| | 1661 | defer self.register_manager.unfreezeRegs(&.{offset_reg}); |
| | 1662 | |
| | 1663 | const addr_reg = try self.copyToTmpRegister(ptr_ty, mcv); |
| | 1664 | self.register_manager.freezeRegs(&.{addr_reg}); |
| | 1665 | defer self.register_manager.unfreezeRegs(&.{addr_reg}); |
| | 1666 | |
| | 1667 | const dst_reg = try self.register_manager.allocReg(inst); |
| | 1668 | try self.genBinOpCode( |
| | 1669 | dst_reg, |
| | 1670 | .{ .register = addr_reg }, |
| | 1671 | .{ .register = offset_reg }, |
| | 1672 | false, |
| | 1673 | .add, |
| | 1674 | .unsigned, |
| | 1675 | ); |
| | 1676 | break :result MCValue{ .register = dst_reg }; |
| | 1677 | }, |
| 1655 | else => return self.fail("TODO implement codegen struct_field_ptr for {}", .{mcv}), | 1678 | else => return self.fail("TODO implement codegen struct_field_ptr for {}", .{mcv}), |
| 1656 | } | 1679 | } |
| 1657 | }; | 1680 | }; |
| ... | @@ -3841,6 +3864,24 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCVa | ... | @@ -3841,6 +3864,24 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCVa |
| 3841 | _ = tv; | 3864 | _ = tv; |
| 3842 | } | 3865 | } |
| 3843 | | 3866 | |
| | 3867 | fn lowerUnnamedConst(self: *Self, tv: TypedValue) InnerError!MCValue { |
| | 3868 | const local_sym_index = self.bin_file.lowerUnnamedConst(tv, self.mod_fn.owner_decl) catch |err| { |
| | 3869 | return self.fail("lowering unnamed constant failed: {s}", .{@errorName(err)}); |
| | 3870 | }; |
| | 3871 | if (self.bin_file.cast(link.File.Elf)) |elf_file| { |
| | 3872 | const vaddr = elf_file.local_symbols.items[local_sym_index].st_value; |
| | 3873 | return MCValue{ .memory = vaddr }; |
| | 3874 | } else if (self.bin_file.cast(link.File.MachO)) |_| { |
| | 3875 | unreachable; |
| | 3876 | } else if (self.bin_file.cast(link.File.Coff)) |_| { |
| | 3877 | return self.fail("TODO lower unnamed const in COFF", .{}); |
| | 3878 | } else if (self.bin_file.cast(link.File.Plan9)) |_| { |
| | 3879 | return self.fail("TODO lower unnamed const in Plan9", .{}); |
| | 3880 | } else { |
| | 3881 | return self.fail("TODO lower unnamed const", .{}); |
| | 3882 | } |
| | 3883 | } |
| | 3884 | |
| 3844 | fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue { | 3885 | fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue { |
| 3845 | if (typed_value.val.isUndef()) | 3886 | if (typed_value.val.isUndef()) |
| 3846 | return MCValue{ .undef = {} }; | 3887 | return MCValue{ .undef = {} }; |
| ... | @@ -3953,6 +3994,9 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue { | ... | @@ -3953,6 +3994,9 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue { |
| 3953 | return self.fail("TODO implement error union const of type '{}' (error)", .{typed_value.ty}); | 3994 | return self.fail("TODO implement error union const of type '{}' (error)", .{typed_value.ty}); |
| 3954 | } | 3995 | } |
| 3955 | }, | 3996 | }, |
| | 3997 | .Struct => { |
| | 3998 | return self.lowerUnnamedConst(typed_value); |
| | 3999 | }, |
| 3956 | else => return self.fail("TODO implement const of type '{}'", .{typed_value.ty}), | 4000 | else => return self.fail("TODO implement const of type '{}'", .{typed_value.ty}), |
| 3957 | } | 4001 | } |
| 3958 | } | 4002 | } |