diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/arch/sparc64/CodeGen.zig | 170 |
1 files changed, 20 insertions, 150 deletions
diff --git a/src/arch/sparc64/CodeGen.zig b/src/arch/sparc64/CodeGen.zig index 5a108eca85..dc1a450e9a 100644 --- a/src/arch/sparc64/CodeGen.zig +++ b/src/arch/sparc64/CodeGen.zig @@ -19,7 +19,7 @@ const Mir = @import("Mir.zig"); const Emit = @import("Emit.zig"); const Liveness = @import("../../Liveness.zig"); const Type = @import("../../type.zig").Type; -const GenerateSymbolError = @import("../../codegen.zig").GenerateSymbolError; +const CodeGenError = codegen.CodeGenError; const Result = @import("../../codegen.zig").Result; const DebugInfoOutput = @import("../../codegen.zig").DebugInfoOutput; @@ -38,7 +38,7 @@ const gp = abi.RegisterClass.gp; const Self = @This(); -const InnerError = codegen.CodeGenError || error{OutOfRegisters}; +const InnerError = CodeGenError || error{OutOfRegisters}; const RegisterView = enum(u1) { caller, @@ -261,7 +261,7 @@ pub fn generate( liveness: Liveness, code: *std.ArrayList(u8), debug_output: DebugInfoOutput, -) GenerateSymbolError!Result { +) CodeGenError!Result { if (build_options.skip_non_native and builtin.cpu.arch != bin_file.options.target.cpu.arch) { @panic("Attempted to compile for architecture that was disabled by build configuration"); } @@ -3894,133 +3894,25 @@ fn genStore(self: *Self, value_reg: Register, addr_reg: Register, comptime off_t } fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue { - var tv = typed_value; - log.debug("genTypedValue: ty = {}, val = {}", .{ tv.ty.fmtDebug(), tv.val.fmtDebug() }); - - if (tv.val.castTag(.runtime_value)) |rt| { - tv.val = rt.data; - } - - if (tv.val.isUndef()) - return MCValue{ .undef = {} }; - - if (tv.val.castTag(.decl_ref)) |payload| { - return self.lowerDeclRef(tv, payload.data); - } - if (tv.val.castTag(.decl_ref_mut)) |payload| { - return self.lowerDeclRef(tv, payload.data.decl_index); - } - const target = self.target.*; - - switch (tv.ty.zigTypeTag()) { - .Pointer => switch (tv.ty.ptrSize()) { - .Slice => {}, - else => { - switch (tv.val.tag()) { - .int_u64 => { - return MCValue{ .immediate = tv.val.toUnsignedInt(target) }; - }, - else => {}, - } - }, - }, - .Bool => { - return MCValue{ .immediate = @boolToInt(tv.val.toBool()) }; - }, - .Int => { - const info = tv.ty.intInfo(self.target.*); - if (info.bits <= 64) { - const unsigned = switch (info.signedness) { - .signed => blk: { - const signed = tv.val.toSignedInt(target); - break :blk @bitCast(u64, signed); - }, - .unsigned => tv.val.toUnsignedInt(target), - }; - - return MCValue{ .immediate = unsigned }; - } else { - return self.fail("TODO implement int genTypedValue of > 64 bits", .{}); - } + const mcv: MCValue = switch (try codegen.genTypedValue( + self.bin_file, + self.src_loc, + typed_value, + self.mod_fn.owner_decl, + )) { + .mcv => |mcv| switch (mcv) { + .none => .none, + .undef => .undef, + .linker_load => unreachable, // TODO + .immediate => |imm| .{ .immediate = imm }, + .memory => |addr| .{ .memory = addr }, }, - .Optional => { - if (tv.ty.isPtrLikeOptional()) { - if (tv.val.isNull()) - return MCValue{ .immediate = 0 }; - - var buf: Type.Payload.ElemType = undefined; - return self.genTypedValue(.{ - .ty = tv.ty.optionalChild(&buf), - .val = tv.val, - }); - } else if (tv.ty.abiSize(self.target.*) == 1) { - return MCValue{ .immediate = @boolToInt(tv.val.isNull()) }; - } + .fail => |msg| { + self.err_msg = msg; + return error.CodegenFail; }, - .Enum => { - if (tv.val.castTag(.enum_field_index)) |field_index| { - switch (tv.ty.tag()) { - .enum_simple => { - return MCValue{ .immediate = field_index.data }; - }, - .enum_full, .enum_nonexhaustive => { - const enum_full = tv.ty.cast(Type.Payload.EnumFull).?.data; - if (enum_full.values.count() != 0) { - const tag_val = enum_full.values.keys()[field_index.data]; - return self.genTypedValue(.{ .ty = enum_full.tag_ty, .val = tag_val }); - } else { - return MCValue{ .immediate = field_index.data }; - } - }, - else => unreachable, - } - } else { - var int_tag_buffer: Type.Payload.Bits = undefined; - const int_tag_ty = tv.ty.intTagType(&int_tag_buffer); - return self.genTypedValue(.{ .ty = int_tag_ty, .val = tv.val }); - } - }, - .ErrorSet => { - const err_name = tv.val.castTag(.@"error").?.data.name; - const module = self.bin_file.options.module.?; - const global_error_set = module.global_error_set; - const error_index = global_error_set.get(err_name).?; - return MCValue{ .immediate = error_index }; - }, - .ErrorUnion => { - const error_type = tv.ty.errorUnionSet(); - const payload_type = tv.ty.errorUnionPayload(); - - if (tv.val.castTag(.eu_payload)) |pl| { - if (!payload_type.hasRuntimeBits()) { - // We use the error type directly as the type. - return MCValue{ .immediate = 0 }; - } - - _ = pl; - return self.fail("TODO implement error union const of type '{}' (non-error)", .{tv.ty.fmtDebug()}); - } else { - if (!payload_type.hasRuntimeBits()) { - // We use the error type directly as the type. - return self.genTypedValue(.{ .ty = error_type, .val = tv.val }); - } - - return self.fail("TODO implement error union const of type '{}' (error)", .{tv.ty.fmtDebug()}); - } - }, - .ComptimeInt => unreachable, // semantic analysis prevents this - .ComptimeFloat => unreachable, // semantic analysis prevents this - .Type => unreachable, - .EnumLiteral => unreachable, - .Void => unreachable, - .NoReturn => unreachable, - .Undefined => unreachable, - .Null => unreachable, - .Opaque => unreachable, - else => {}, - } - - return self.fail("TODO implement const of type '{}'", .{tv.ty.fmtDebug()}); + }; + return mcv; } 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 } } -fn lowerDeclRef(self: *Self, tv: TypedValue, decl_index: Module.Decl.Index) InnerError!MCValue { - // TODO this feels clunky. Perhaps we should check for it in `genTypedValue`? - if (tv.ty.zigTypeTag() == .Pointer) blk: { - if (tv.ty.castPtrToFn()) |_| break :blk; - if (!tv.ty.elemType2().hasRuntimeBits()) { - return MCValue.none; - } - } - - const mod = self.bin_file.options.module.?; - const decl = mod.declPtr(decl_index); - - mod.markDeclAlive(decl); - if (self.bin_file.cast(link.File.Elf)) |elf_file| { - const atom_index = try elf_file.getOrCreateAtomForDecl(decl_index); - const atom = elf_file.getAtom(atom_index); - return MCValue{ .memory = atom.getOffsetTableAddress(elf_file) }; - } else { - return self.fail("TODO codegen non-ELF const Decl pointer", .{}); - } -} - fn minMax( self: *Self, tag: Air.Inst.Tag, |
