authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-03-03 18:53:30+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-03-03 18:53:30+01:00
logf6eeb6c8ce83af392dc075e3f80846aefc791f42
tree80f35bfd16883bb9588b98a73590aff6dfb80f90
parent5b3ea49806f5d0b9034e3eacbef9e19428a5db8a

sparc64: use common implementation of genTypedValue


1 files changed, 20 insertions(+), 150 deletions(-)

src/arch/sparc64/CodeGen.zig+20-150
...@@ -19,7 +19,7 @@ const Mir = @import("Mir.zig");...@@ -19,7 +19,7 @@ const Mir = @import("Mir.zig");
19const Emit = @import("Emit.zig");19const Emit = @import("Emit.zig");
20const Liveness = @import("../../Liveness.zig");20const Liveness = @import("../../Liveness.zig");
21const Type = @import("../../type.zig").Type;21const Type = @import("../../type.zig").Type;
22const GenerateSymbolError = @import("../../codegen.zig").GenerateSymbolError;22const CodeGenError = codegen.CodeGenError;
23const Result = @import("../../codegen.zig").Result;23const Result = @import("../../codegen.zig").Result;
24const DebugInfoOutput = @import("../../codegen.zig").DebugInfoOutput;24const DebugInfoOutput = @import("../../codegen.zig").DebugInfoOutput;
2525
...@@ -38,7 +38,7 @@ const gp = abi.RegisterClass.gp;...@@ -38,7 +38,7 @@ const gp = abi.RegisterClass.gp;
3838
39const Self = @This();39const Self = @This();
4040
41const InnerError = codegen.CodeGenError || error{OutOfRegisters};41const InnerError = CodeGenError || error{OutOfRegisters};
4242
43const RegisterView = enum(u1) {43const RegisterView = enum(u1) {
44 caller,44 caller,
...@@ -261,7 +261,7 @@ pub fn generate(...@@ -261,7 +261,7 @@ pub fn generate(
261 liveness: Liveness,261 liveness: Liveness,
262 code: *std.ArrayList(u8),262 code: *std.ArrayList(u8),
263 debug_output: DebugInfoOutput,263 debug_output: DebugInfoOutput,
264) GenerateSymbolError!Result {264) CodeGenError!Result {
265 if (build_options.skip_non_native and builtin.cpu.arch != bin_file.options.target.cpu.arch) {265 if (build_options.skip_non_native and builtin.cpu.arch != bin_file.options.target.cpu.arch) {
266 @panic("Attempted to compile for architecture that was disabled by build configuration");266 @panic("Attempted to compile for architecture that was disabled by build configuration");
267 }267 }
...@@ -3894,133 +3894,25 @@ fn genStore(self: *Self, value_reg: Register, addr_reg: Register, comptime off_t...@@ -3894,133 +3894,25 @@ fn genStore(self: *Self, value_reg: Register, addr_reg: Register, comptime off_t
3894}3894}
38953895
3896fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {3896fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
3897 var tv = typed_value;3897 const mcv: MCValue = switch (try codegen.genTypedValue(
3898 log.debug("genTypedValue: ty = {}, val = {}", .{ tv.ty.fmtDebug(), tv.val.fmtDebug() });3898 self.bin_file,
38993899 self.src_loc,
3900 if (tv.val.castTag(.runtime_value)) |rt| {3900 typed_value,
3901 tv.val = rt.data;3901 self.mod_fn.owner_decl,
3902 }3902 )) {
39033903 .mcv => |mcv| switch (mcv) {
3904 if (tv.val.isUndef())3904 .none => .none,
3905 return MCValue{ .undef = {} };3905 .undef => .undef,
39063906 .linker_load => unreachable, // TODO
3907 if (tv.val.castTag(.decl_ref)) |payload| {3907 .immediate => |imm| .{ .immediate = imm },
3908 return self.lowerDeclRef(tv, payload.data);3908 .memory => |addr| .{ .memory = addr },
3909 }
3910 if (tv.val.castTag(.decl_ref_mut)) |payload| {
3911 return self.lowerDeclRef(tv, payload.data.decl_index);
3912 }
3913 const target = self.target.*;
3914
3915 switch (tv.ty.zigTypeTag()) {
3916 .Pointer => switch (tv.ty.ptrSize()) {
3917 .Slice => {},
3918 else => {
3919 switch (tv.val.tag()) {
3920 .int_u64 => {
3921 return MCValue{ .immediate = tv.val.toUnsignedInt(target) };
3922 },
3923 else => {},
3924 }
3925 },
3926 },
3927 .Bool => {
3928 return MCValue{ .immediate = @boolToInt(tv.val.toBool()) };
3929 },
3930 .Int => {
3931 const info = tv.ty.intInfo(self.target.*);
3932 if (info.bits <= 64) {
3933 const unsigned = switch (info.signedness) {
3934 .signed => blk: {
3935 const signed = tv.val.toSignedInt(target);
3936 break :blk @bitCast(u64, signed);
3937 },
3938 .unsigned => tv.val.toUnsignedInt(target),
3939 };
3940
3941 return MCValue{ .immediate = unsigned };
3942 } else {
3943 return self.fail("TODO implement int genTypedValue of > 64 bits", .{});
3944 }
3945 },3909 },
3946 .Optional => {3910 .fail => |msg| {
3947 if (tv.ty.isPtrLikeOptional()) {3911 self.err_msg = msg;
3948 if (tv.val.isNull())3912 return error.CodegenFail;
3949 return MCValue{ .immediate = 0 };
3950
3951 var buf: Type.Payload.ElemType = undefined;
3952 return self.genTypedValue(.{
3953 .ty = tv.ty.optionalChild(&buf),
3954 .val = tv.val,
3955 });
3956 } else if (tv.ty.abiSize(self.target.*) == 1) {
3957 return MCValue{ .immediate = @boolToInt(tv.val.isNull()) };
3958 }
3959 },3913 },
3960 .Enum => {3914 };
3961 if (tv.val.castTag(.enum_field_index)) |field_index| {3915 return mcv;
3962 switch (tv.ty.tag()) {
3963 .enum_simple => {
3964 return MCValue{ .immediate = field_index.data };
3965 },
3966 .enum_full, .enum_nonexhaustive => {
3967 const enum_full = tv.ty.cast(Type.Payload.EnumFull).?.data;
3968 if (enum_full.values.count() != 0) {
3969 const tag_val = enum_full.values.keys()[field_index.data];
3970 return self.genTypedValue(.{ .ty = enum_full.tag_ty, .val = tag_val });
3971 } else {
3972 return MCValue{ .immediate = field_index.data };
3973 }
3974 },
3975 else => unreachable,
3976 }
3977 } else {
3978 var int_tag_buffer: Type.Payload.Bits = undefined;
3979 const int_tag_ty = tv.ty.intTagType(&int_tag_buffer);
3980 return self.genTypedValue(.{ .ty = int_tag_ty, .val = tv.val });
3981 }
3982 },
3983 .ErrorSet => {
3984 const err_name = tv.val.castTag(.@"error").?.data.name;
3985 const module = self.bin_file.options.module.?;
3986 const global_error_set = module.global_error_set;
3987 const error_index = global_error_set.get(err_name).?;
3988 return MCValue{ .immediate = error_index };
3989 },
3990 .ErrorUnion => {
3991 const error_type = tv.ty.errorUnionSet();
3992 const payload_type = tv.ty.errorUnionPayload();
3993
3994 if (tv.val.castTag(.eu_payload)) |pl| {
3995 if (!payload_type.hasRuntimeBits()) {
3996 // We use the error type directly as the type.
3997 return MCValue{ .immediate = 0 };
3998 }
3999
4000 _ = pl;
4001 return self.fail("TODO implement error union const of type '{}' (non-error)", .{tv.ty.fmtDebug()});
4002 } else {
4003 if (!payload_type.hasRuntimeBits()) {
4004 // We use the error type directly as the type.
4005 return self.genTypedValue(.{ .ty = error_type, .val = tv.val });
4006 }
4007
4008 return self.fail("TODO implement error union const of type '{}' (error)", .{tv.ty.fmtDebug()});
4009 }
4010 },
4011 .ComptimeInt => unreachable, // semantic analysis prevents this
4012 .ComptimeFloat => unreachable, // semantic analysis prevents this
4013 .Type => unreachable,
4014 .EnumLiteral => unreachable,
4015 .Void => unreachable,
4016 .NoReturn => unreachable,
4017 .Undefined => unreachable,
4018 .Null => unreachable,
4019 .Opaque => unreachable,
4020 else => {},
4021 }
4022
4023 return self.fail("TODO implement const of type '{}'", .{tv.ty.fmtDebug()});
4024}3916}
40253917
4026fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue {3918fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue {
...@@ -4196,28 +4088,6 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo...@@ -4196,28 +4088,6 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo
4196 }4088 }
4197}4089}
41984090
4199fn lowerDeclRef(self: *Self, tv: TypedValue, decl_index: Module.Decl.Index) InnerError!MCValue {
4200 // TODO this feels clunky. Perhaps we should check for it in `genTypedValue`?
4201 if (tv.ty.zigTypeTag() == .Pointer) blk: {
4202 if (tv.ty.castPtrToFn()) |_| break :blk;
4203 if (!tv.ty.elemType2().hasRuntimeBits()) {
4204 return MCValue.none;
4205 }
4206 }
4207
4208 const mod = self.bin_file.options.module.?;
4209 const decl = mod.declPtr(decl_index);
4210
4211 mod.markDeclAlive(decl);
4212 if (self.bin_file.cast(link.File.Elf)) |elf_file| {
4213 const atom_index = try elf_file.getOrCreateAtomForDecl(decl_index);
4214 const atom = elf_file.getAtom(atom_index);
4215 return MCValue{ .memory = atom.getOffsetTableAddress(elf_file) };
4216 } else {
4217 return self.fail("TODO codegen non-ELF const Decl pointer", .{});
4218 }
4219}
4220
4221fn minMax(4091fn minMax(
4222 self: *Self,4092 self: *Self,
4223 tag: Air.Inst.Tag,4093 tag: Air.Inst.Tag,