diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2023-03-03 18:24:58 +0100 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2023-03-03 18:24:58 +0100 |
| commit | 1024332adc88928299dfc07426f11624ae8ba18b (patch) | |
| tree | 4a648aa23b519cf2d7ee99142ea067c9c8849a6a /src | |
| parent | c746cbc686c46904a5d381725079a69e38b201cd (diff) | |
| download | zig-1024332adc88928299dfc07426f11624ae8ba18b.tar.gz zig-1024332adc88928299dfc07426f11624ae8ba18b.zip | |
arm: use common implementation of genTypedValue helper
Diffstat (limited to 'src')
| -rw-r--r-- | src/arch/arm/CodeGen.zig | 192 | ||||
| -rw-r--r-- | src/arch/x86_64/CodeGen.zig | 6 |
2 files changed, 23 insertions, 175 deletions
diff --git a/src/arch/arm/CodeGen.zig b/src/arch/arm/CodeGen.zig index 87806223e3..7d8708c44d 100644 --- a/src/arch/arm/CodeGen.zig +++ b/src/arch/arm/CodeGen.zig @@ -24,7 +24,7 @@ const log = std.log.scoped(.codegen); const build_options = @import("build_options"); const Result = codegen.Result; -const GenerateSymbolError = codegen.GenerateSymbolError; +const CodeGenError = codegen.CodeGenError; const DebugInfoOutput = codegen.DebugInfoOutput; const bits = @import("bits.zig"); @@ -42,7 +42,7 @@ const c_abi_int_param_regs = abi.c_abi_int_param_regs; const c_abi_int_return_regs = abi.c_abi_int_return_regs; const gp = abi.RegisterClass.gp; -const InnerError = codegen.CodeGenError || error{OutOfRegisters}; +const InnerError = CodeGenError || error{OutOfRegisters}; gpa: Allocator, air: Air, @@ -339,7 +339,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"); } @@ -6083,178 +6083,26 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue { } } -fn lowerDeclRef(self: *Self, tv: TypedValue, decl_index: Module.Decl.Index) InnerError!MCValue { - const ptr_bits = self.target.cpu.arch.ptrBitWidth(); - const ptr_bytes: u64 = @divExact(ptr_bits, 8); - - 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 if (self.bin_file.cast(link.File.MachO)) |_| { - unreachable; // unsupported architecture for MachO - } else if (self.bin_file.cast(link.File.Coff)) |_| { - return self.fail("TODO codegen COFF const Decl pointer", .{}); - } else if (self.bin_file.cast(link.File.Plan9)) |p9| { - const decl_block_index = try p9.seeDecl(decl_index); - const decl_block = p9.getDeclBlock(decl_block_index); - const got_addr = p9.bases.data + decl_block.got_index.? * ptr_bytes; - return MCValue{ .memory = got_addr }; - } else { - return self.fail("TODO codegen non-ELF const Decl pointer", .{}); - } - - _ = tv; -} - -fn lowerUnnamedConst(self: *Self, tv: TypedValue) InnerError!MCValue { - const local_sym_index = self.bin_file.lowerUnnamedConst(tv, self.mod_fn.owner_decl) catch |err| { - return self.fail("lowering unnamed constant failed: {s}", .{@errorName(err)}); - }; - if (self.bin_file.cast(link.File.Elf)) |elf_file| { - return MCValue{ .memory = elf_file.getSymbol(local_sym_index).st_value }; - } else if (self.bin_file.cast(link.File.MachO)) |_| { - unreachable; - } else if (self.bin_file.cast(link.File.Coff)) |_| { - return self.fail("TODO lower unnamed const in COFF", .{}); - } else if (self.bin_file.cast(link.File.Plan9)) |_| { - return self.fail("TODO lower unnamed const in Plan9", .{}); - } else { - return self.fail("TODO lower unnamed const", .{}); - } -} - fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue { - var typed_value = arg_tv; - if (typed_value.val.castTag(.runtime_value)) |rt| { - typed_value.val = rt.data; - } - log.debug("genTypedValue: ty = {}, val = {}", .{ typed_value.ty.fmtDebug(), typed_value.val.fmtDebug() }); - if (typed_value.val.isUndef()) - return MCValue{ .undef = {} }; - const ptr_bits = self.target.cpu.arch.ptrBitWidth(); - - if (typed_value.val.castTag(.decl_ref)) |payload| { - return self.lowerDeclRef(typed_value, payload.data); - } - if (typed_value.val.castTag(.decl_ref_mut)) |payload| { - return self.lowerDeclRef(typed_value, payload.data.decl_index); - } - const target = self.target.*; - - switch (typed_value.ty.zigTypeTag()) { - .Pointer => switch (typed_value.ty.ptrSize()) { - .Slice => {}, - else => { - switch (typed_value.val.tag()) { - .int_u64 => { - return MCValue{ .immediate = @intCast(u32, typed_value.val.toUnsignedInt(target)) }; - }, - else => {}, - } - }, + const mcv: MCValue = switch (try codegen.genTypedValue( + self.bin_file, + self.src_loc, + arg_tv, + self.mod_fn.owner_decl, + )) { + .mcv => |mcv| switch (mcv) { + .none => .none, + .undef => .undef, + .linker_load => unreachable, // TODO + .immediate => |imm| .{ .immediate = @truncate(u32, imm) }, + .memory => |addr| .{ .memory = addr }, }, - .Int => { - const info = typed_value.ty.intInfo(self.target.*); - if (info.bits <= ptr_bits) { - const unsigned = switch (info.signedness) { - .signed => blk: { - const signed = @intCast(i32, typed_value.val.toSignedInt(target)); - break :blk @bitCast(u32, signed); - }, - .unsigned => @intCast(u32, typed_value.val.toUnsignedInt(target)), - }; - - return MCValue{ .immediate = unsigned }; - } else { - return self.lowerUnnamedConst(typed_value); - } - }, - .Bool => { - return MCValue{ .immediate = @boolToInt(typed_value.val.toBool()) }; - }, - .Optional => { - if (typed_value.ty.isPtrLikeOptional()) { - if (typed_value.val.isNull()) - return MCValue{ .immediate = 0 }; - - var buf: Type.Payload.ElemType = undefined; - return self.genTypedValue(.{ - .ty = typed_value.ty.optionalChild(&buf), - .val = typed_value.val, - }); - } else if (typed_value.ty.abiSize(self.target.*) == 1) { - return MCValue{ .immediate = @boolToInt(typed_value.val.isNull()) }; - } - }, - .Enum => { - if (typed_value.val.castTag(.enum_field_index)) |field_index| { - switch (typed_value.ty.tag()) { - .enum_simple => { - return MCValue{ .immediate = field_index.data }; - }, - .enum_full, .enum_nonexhaustive => { - const enum_full = typed_value.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 = typed_value.ty.intTagType(&int_tag_buffer); - return self.genTypedValue(.{ .ty = int_tag_ty, .val = typed_value.val }); - } - }, - .ErrorSet => { - switch (typed_value.val.tag()) { - .@"error" => { - const err_name = typed_value.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 }; - }, - else => { - // In this case we are rendering an error union which has a 0 bits payload. - return MCValue{ .immediate = 0 }; - }, - } + .fail => |msg| { + self.err_msg = msg; + return error.CodegenFail; }, - .ErrorUnion => { - const error_type = typed_value.ty.errorUnionSet(); - const payload_type = typed_value.ty.errorUnionPayload(); - const is_pl = typed_value.val.errorUnionIsPayload(); - - if (!payload_type.hasRuntimeBitsIgnoreComptime()) { - // We use the error type directly as the type. - const err_val = if (!is_pl) typed_value.val else Value.initTag(.zero); - return self.genTypedValue(.{ .ty = error_type, .val = err_val }); - } - }, - - .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.lowerUnnamedConst(typed_value); + }; + return mcv; } const CallMCValues = struct { diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 2ec1a33619..a2c11b332b 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -12,12 +12,12 @@ const trace = @import("../../tracy.zig").trace; const Air = @import("../../Air.zig"); const Allocator = mem.Allocator; +const CodeGenError = codegen.CodeGenError; const Compilation = @import("../../Compilation.zig"); const DebugInfoOutput = codegen.DebugInfoOutput; const DW = std.dwarf; const ErrorMsg = Module.ErrorMsg; const Result = codegen.Result; -const GenerateSymbolError = codegen.GenerateSymbolError; const Emit = @import("Emit.zig"); const Liveness = @import("../../Liveness.zig"); const Mir = @import("Mir.zig"); @@ -40,7 +40,7 @@ const Register = bits.Register; const gp = abi.RegisterClass.gp; const sse = abi.RegisterClass.sse; -const InnerError = codegen.CodeGenError || error{OutOfRegisters}; +const InnerError = CodeGenError || error{OutOfRegisters}; gpa: Allocator, air: Air, @@ -253,7 +253,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"); } |
