| ... | ... | @@ -19,7 +19,7 @@ const Mir = @import("Mir.zig"); |
| 19 | 19 | const Emit = @import("Emit.zig"); |
| 20 | 20 | const Liveness = @import("../../Liveness.zig"); |
| 21 | 21 | const Type = @import("../../type.zig").Type; |
| 22 | | const GenerateSymbolError = @import("../../codegen.zig").GenerateSymbolError; |
| 22 | const CodeGenError = codegen.CodeGenError; |
| 23 | 23 | const Result = @import("../../codegen.zig").Result; |
| 24 | 24 | const DebugInfoOutput = @import("../../codegen.zig").DebugInfoOutput; |
| 25 | 25 | |
| ... | ... | @@ -38,7 +38,7 @@ const gp = abi.RegisterClass.gp; |
| 38 | 38 | |
| 39 | 39 | const Self = @This(); |
| 40 | 40 | |
| 41 | | const InnerError = codegen.CodeGenError || error{OutOfRegisters}; |
| 41 | const InnerError = CodeGenError || error{OutOfRegisters}; |
| 42 | 42 | |
| 43 | 43 | const RegisterView = enum(u1) { |
| 44 | 44 | caller, |
| ... | ... | @@ -261,7 +261,7 @@ pub fn generate( |
| 261 | 261 | liveness: Liveness, |
| 262 | 262 | code: *std.ArrayList(u8), |
| 263 | 263 | debug_output: DebugInfoOutput, |
| 264 | | ) GenerateSymbolError!Result { |
| 264 | ) CodeGenError!Result { |
| 265 | 265 | if (build_options.skip_non_native and builtin.cpu.arch != bin_file.options.target.cpu.arch) { |
| 266 | 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 | 3894 | } |
| 3895 | 3895 | |
| 3896 | 3896 | fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue { |
| 3897 | | var tv = typed_value; |
| 3898 | | log.debug("genTypedValue: ty = {}, val = {}", .{ tv.ty.fmtDebug(), tv.val.fmtDebug() }); |
| 3899 | | |
| 3900 | | if (tv.val.castTag(.runtime_value)) |rt| { |
| 3901 | | tv.val = rt.data; |
| 3902 | | } |
| 3903 | | |
| 3904 | | if (tv.val.isUndef()) |
| 3905 | | return MCValue{ .undef = {} }; |
| 3906 | | |
| 3907 | | if (tv.val.castTag(.decl_ref)) |payload| { |
| 3908 | | return self.lowerDeclRef(tv, payload.data); |
| 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 | | } |
| 3897 | const mcv: MCValue = switch (try codegen.genTypedValue( |
| 3898 | self.bin_file, |
| 3899 | self.src_loc, |
| 3900 | typed_value, |
| 3901 | self.mod_fn.owner_decl, |
| 3902 | )) { |
| 3903 | .mcv => |mcv| switch (mcv) { |
| 3904 | .none => .none, |
| 3905 | .undef => .undef, |
| 3906 | .linker_load => unreachable, // TODO |
| 3907 | .immediate => |imm| .{ .immediate = imm }, |
| 3908 | .memory => |addr| .{ .memory = addr }, |
| 3945 | 3909 | }, |
| 3946 | | .Optional => { |
| 3947 | | if (tv.ty.isPtrLikeOptional()) { |
| 3948 | | if (tv.val.isNull()) |
| 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 | | } |
| 3910 | .fail => |msg| { |
| 3911 | self.err_msg = msg; |
| 3912 | return error.CodegenFail; |
| 3959 | 3913 | }, |
| 3960 | | .Enum => { |
| 3961 | | if (tv.val.castTag(.enum_field_index)) |field_index| { |
| 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()}); |
| 3914 | }; |
| 3915 | return mcv; |
| 4024 | 3916 | } |
| 4025 | 3917 | |
| 4026 | 3918 | fn 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 | 4088 | } |
| 4197 | 4089 | } |
| 4198 | 4090 | |
| 4199 | | fn 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 | | |
| 4221 | 4091 | fn minMax( |
| 4222 | 4092 | self: *Self, |
| 4223 | 4093 | tag: Air.Inst.Tag, |