| ... | @@ -3862,27 +3862,48 @@ fn genStore(self: *Self, value_reg: Register, addr_reg: Register, comptime off_t | ... | @@ -3862,27 +3862,48 @@ fn genStore(self: *Self, value_reg: Register, addr_reg: Register, comptime off_t |
| 3862 | } | 3862 | } |
| 3863 | | 3863 | |
| 3864 | fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue { | 3864 | fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue { |
| 3865 | if (typed_value.val.isUndef()) | 3865 | var tv = typed_value; |
| | 3866 | log.debug("genTypedValue: ty = {}, val = {}", .{ tv.ty.fmtDebug(), tv.val.fmtDebug() }); |
| | 3867 | |
| | 3868 | if (tv.val.castTag(.runtime_value)) |rt| { |
| | 3869 | tv.val = rt.data; |
| | 3870 | } |
| | 3871 | |
| | 3872 | if (tv.val.isUndef()) |
| 3866 | return MCValue{ .undef = {} }; | 3873 | return MCValue{ .undef = {} }; |
| 3867 | | 3874 | |
| 3868 | if (typed_value.val.castTag(.decl_ref)) |payload| { | 3875 | if (tv.val.castTag(.decl_ref)) |payload| { |
| 3869 | return self.lowerDeclRef(typed_value, payload.data); | 3876 | return self.lowerDeclRef(tv, payload.data); |
| 3870 | } | 3877 | } |
| 3871 | if (typed_value.val.castTag(.decl_ref_mut)) |payload| { | 3878 | if (tv.val.castTag(.decl_ref_mut)) |payload| { |
| 3872 | return self.lowerDeclRef(typed_value, payload.data.decl_index); | 3879 | return self.lowerDeclRef(tv, payload.data.decl_index); |
| 3873 | } | 3880 | } |
| 3874 | const target = self.target.*; | 3881 | const target = self.target.*; |
| 3875 | | 3882 | |
| 3876 | switch (typed_value.ty.zigTypeTag()) { | 3883 | switch (tv.ty.zigTypeTag()) { |
| | 3884 | .Pointer => switch (tv.ty.ptrSize()) { |
| | 3885 | .Slice => {}, |
| | 3886 | else => { |
| | 3887 | switch (tv.val.tag()) { |
| | 3888 | .int_u64 => { |
| | 3889 | return MCValue{ .immediate = tv.val.toUnsignedInt(target) }; |
| | 3890 | }, |
| | 3891 | else => {}, |
| | 3892 | } |
| | 3893 | }, |
| | 3894 | }, |
| | 3895 | .Bool => { |
| | 3896 | return MCValue{ .immediate = @boolToInt(tv.val.toBool()) }; |
| | 3897 | }, |
| 3877 | .Int => { | 3898 | .Int => { |
| 3878 | const info = typed_value.ty.intInfo(self.target.*); | 3899 | const info = tv.ty.intInfo(self.target.*); |
| 3879 | if (info.bits <= 64) { | 3900 | if (info.bits <= 64) { |
| 3880 | const unsigned = switch (info.signedness) { | 3901 | const unsigned = switch (info.signedness) { |
| 3881 | .signed => blk: { | 3902 | .signed => blk: { |
| 3882 | const signed = typed_value.val.toSignedInt(target); | 3903 | const signed = tv.val.toSignedInt(target); |
| 3883 | break :blk @bitCast(u64, signed); | 3904 | break :blk @bitCast(u64, signed); |
| 3884 | }, | 3905 | }, |
| 3885 | .unsigned => typed_value.val.toUnsignedInt(target), | 3906 | .unsigned => tv.val.toUnsignedInt(target), |
| 3886 | }; | 3907 | }; |
| 3887 | | 3908 | |
| 3888 | return MCValue{ .immediate = unsigned }; | 3909 | return MCValue{ .immediate = unsigned }; |
| ... | @@ -3890,38 +3911,84 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue { | ... | @@ -3890,38 +3911,84 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue { |
| 3890 | return self.fail("TODO implement int genTypedValue of > 64 bits", .{}); | 3911 | return self.fail("TODO implement int genTypedValue of > 64 bits", .{}); |
| 3891 | } | 3912 | } |
| 3892 | }, | 3913 | }, |
| | 3914 | .Optional => { |
| | 3915 | if (tv.ty.isPtrLikeOptional()) { |
| | 3916 | if (tv.val.isNull()) |
| | 3917 | return MCValue{ .immediate = 0 }; |
| | 3918 | |
| | 3919 | var buf: Type.Payload.ElemType = undefined; |
| | 3920 | return self.genTypedValue(.{ |
| | 3921 | .ty = tv.ty.optionalChild(&buf), |
| | 3922 | .val = tv.val, |
| | 3923 | }); |
| | 3924 | } else if (tv.ty.abiSize(self.target.*) == 1) { |
| | 3925 | return MCValue{ .immediate = @boolToInt(tv.val.isNull()) }; |
| | 3926 | } |
| | 3927 | }, |
| | 3928 | .Enum => { |
| | 3929 | if (tv.val.castTag(.enum_field_index)) |field_index| { |
| | 3930 | switch (tv.ty.tag()) { |
| | 3931 | .enum_simple => { |
| | 3932 | return MCValue{ .immediate = field_index.data }; |
| | 3933 | }, |
| | 3934 | .enum_full, .enum_nonexhaustive => { |
| | 3935 | const enum_full = tv.ty.cast(Type.Payload.EnumFull).?.data; |
| | 3936 | if (enum_full.values.count() != 0) { |
| | 3937 | const tag_val = enum_full.values.keys()[field_index.data]; |
| | 3938 | return self.genTypedValue(.{ .ty = enum_full.tag_ty, .val = tag_val }); |
| | 3939 | } else { |
| | 3940 | return MCValue{ .immediate = field_index.data }; |
| | 3941 | } |
| | 3942 | }, |
| | 3943 | else => unreachable, |
| | 3944 | } |
| | 3945 | } else { |
| | 3946 | var int_tag_buffer: Type.Payload.Bits = undefined; |
| | 3947 | const int_tag_ty = tv.ty.intTagType(&int_tag_buffer); |
| | 3948 | return self.genTypedValue(.{ .ty = int_tag_ty, .val = tv.val }); |
| | 3949 | } |
| | 3950 | }, |
| 3893 | .ErrorSet => { | 3951 | .ErrorSet => { |
| 3894 | const err_name = typed_value.val.castTag(.@"error").?.data.name; | 3952 | const err_name = tv.val.castTag(.@"error").?.data.name; |
| 3895 | const module = self.bin_file.options.module.?; | 3953 | const module = self.bin_file.options.module.?; |
| 3896 | const global_error_set = module.global_error_set; | 3954 | const global_error_set = module.global_error_set; |
| 3897 | const error_index = global_error_set.get(err_name).?; | 3955 | const error_index = global_error_set.get(err_name).?; |
| 3898 | return MCValue{ .immediate = error_index }; | 3956 | return MCValue{ .immediate = error_index }; |
| 3899 | }, | 3957 | }, |
| 3900 | .ErrorUnion => { | 3958 | .ErrorUnion => { |
| 3901 | const error_type = typed_value.ty.errorUnionSet(); | 3959 | const error_type = tv.ty.errorUnionSet(); |
| 3902 | const payload_type = typed_value.ty.errorUnionPayload(); | 3960 | const payload_type = tv.ty.errorUnionPayload(); |
| 3903 | | 3961 | |
| 3904 | if (typed_value.val.castTag(.eu_payload)) |pl| { | 3962 | if (tv.val.castTag(.eu_payload)) |pl| { |
| 3905 | if (!payload_type.hasRuntimeBits()) { | 3963 | if (!payload_type.hasRuntimeBits()) { |
| 3906 | // We use the error type directly as the type. | 3964 | // We use the error type directly as the type. |
| 3907 | return MCValue{ .immediate = 0 }; | 3965 | return MCValue{ .immediate = 0 }; |
| 3908 | } | 3966 | } |
| 3909 | | 3967 | |
| 3910 | _ = pl; | 3968 | _ = pl; |
| 3911 | return self.fail("TODO implement error union const of type '{}' (non-error)", .{typed_value.ty.fmtDebug()}); | 3969 | return self.fail("TODO implement error union const of type '{}' (non-error)", .{tv.ty.fmtDebug()}); |
| 3912 | } else { | 3970 | } else { |
| 3913 | if (!payload_type.hasRuntimeBits()) { | 3971 | if (!payload_type.hasRuntimeBits()) { |
| 3914 | // We use the error type directly as the type. | 3972 | // We use the error type directly as the type. |
| 3915 | return self.genTypedValue(.{ .ty = error_type, .val = typed_value.val }); | 3973 | return self.genTypedValue(.{ .ty = error_type, .val = tv.val }); |
| 3916 | } | 3974 | } |
| 3917 | | 3975 | |
| 3918 | return self.fail("TODO implement error union const of type '{}' (error)", .{typed_value.ty.fmtDebug()}); | 3976 | return self.fail("TODO implement error union const of type '{}' (error)", .{tv.ty.fmtDebug()}); |
| 3919 | } | 3977 | } |
| 3920 | }, | 3978 | }, |
| 3921 | .ComptimeInt => unreachable, // semantic analysis prevents this | 3979 | .ComptimeInt => unreachable, // semantic analysis prevents this |
| 3922 | .ComptimeFloat => unreachable, // semantic analysis prevents this | 3980 | .ComptimeFloat => unreachable, // semantic analysis prevents this |
| 3923 | else => return self.fail("TODO implement const of type '{}'", .{typed_value.ty.fmtDebug()}), | 3981 | .Type => unreachable, |
| | 3982 | .EnumLiteral => unreachable, |
| | 3983 | .Void => unreachable, |
| | 3984 | .NoReturn => unreachable, |
| | 3985 | .Undefined => unreachable, |
| | 3986 | .Null => unreachable, |
| | 3987 | .Opaque => unreachable, |
| | 3988 | else => {}, |
| 3924 | } | 3989 | } |
| | 3990 | |
| | 3991 | return self.fail("TODO implement const of type '{}'", .{tv.ty.fmtDebug()}); |
| 3925 | } | 3992 | } |
| 3926 | | 3993 | |
| 3927 | fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue { | 3994 | fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue { |