authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-08-01 07:17:40+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-08-01 07:17:40+02:00
log8ea323822ba1fc2f54940841b2cedb3494230a3c
tree6ba1a9006af4f9e0e7737310cd646f4f836edf8e
parenteb1a199dff2b54271bd275c2528bdd898bf1d4eb
parent2b8a71489a24649342e797f609fc6bb1b141a422
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #20884 from Rexicon226/riscv


6 files changed, 72 insertions(+), 21 deletions(-)

lib/std/start.zig+12-15
...@@ -465,21 +465,18 @@ fn posixCallMainAndExit(argc_argv_ptr: [*]usize) callconv(.C) noreturn {...@@ -465,21 +465,18 @@ fn posixCallMainAndExit(argc_argv_ptr: [*]usize) callconv(.C) noreturn {
465 // to ask for more stack space.465 // to ask for more stack space.
466 expandStackSize(phdrs);466 expandStackSize(phdrs);
467467
468 // Disabled with the riscv backend because it cannot handle this code yet.468 const opt_init_array_start = @extern([*]*const fn () callconv(.C) void, .{
469 if (builtin.zig_backend != .stage2_riscv64) {469 .name = "__init_array_start",
470 const opt_init_array_start = @extern([*]*const fn () callconv(.C) void, .{470 .linkage = .weak,
471 .name = "__init_array_start",471 });
472 .linkage = .weak,472 const opt_init_array_end = @extern([*]*const fn () callconv(.C) void, .{
473 });473 .name = "__init_array_end",
474 const opt_init_array_end = @extern([*]*const fn () callconv(.C) void, .{474 .linkage = .weak,
475 .name = "__init_array_end",475 });
476 .linkage = .weak,476 if (opt_init_array_start) |init_array_start| {
477 });477 const init_array_end = opt_init_array_end.?;
478 if (opt_init_array_start) |init_array_start| {478 const slice = init_array_start[0 .. init_array_end - init_array_start];
479 const init_array_end = opt_init_array_end.?;479 for (slice) |func| func();
480 const slice = init_array_start[0 .. init_array_end - init_array_start];
481 for (slice) |func| func();
482 }
483 }480 }
484 }481 }
485482
src/arch/riscv64/CodeGen.zig+5-3
...@@ -1510,6 +1510,7 @@ fn genBody(func: *Func, body: []const Air.Inst.Index) InnerError!void {...@@ -1510,6 +1510,7 @@ fn genBody(func: *Func, body: []const Air.Inst.Index) InnerError!void {
1510 .mul,1510 .mul,
1511 .mul_wrap,1511 .mul_wrap,
1512 .div_trunc, 1512 .div_trunc,
1513 .div_exact,
1513 .rem,1514 .rem,
15141515
1515 .shl, .shl_exact,1516 .shl, .shl_exact,
...@@ -1533,7 +1534,6 @@ fn genBody(func: *Func, body: []const Air.Inst.Index) InnerError!void {...@@ -1533,7 +1534,6 @@ fn genBody(func: *Func, body: []const Air.Inst.Index) InnerError!void {
1533 .mod,1534 .mod,
1534 .div_float, 1535 .div_float,
1535 .div_floor, 1536 .div_floor,
1536 .div_exact,
1537 => return func.fail("TODO: {s}", .{@tagName(tag)}),1537 => return func.fail("TODO: {s}", .{@tagName(tag)}),
15381538
1539 .sqrt,1539 .sqrt,
...@@ -2563,10 +2563,12 @@ fn genBinOp(...@@ -2563,10 +2563,12 @@ fn genBinOp(
2563 .mul_wrap,2563 .mul_wrap,
2564 .rem,2564 .rem,
2565 .div_trunc,2565 .div_trunc,
2566 .div_exact,
2566 => {2567 => {
2567 switch (tag) {2568 switch (tag) {
2568 .rem,2569 .rem,
2569 .div_trunc,2570 .div_trunc,
2571 .div_exact,
2570 => {2572 => {
2571 if (!math.isPowerOfTwo(bit_size)) {2573 if (!math.isPowerOfTwo(bit_size)) {
2572 try func.truncateRegister(lhs_ty, lhs_reg);2574 try func.truncateRegister(lhs_ty, lhs_reg);
...@@ -2576,7 +2578,7 @@ fn genBinOp(...@@ -2576,7 +2578,7 @@ fn genBinOp(
2576 else => {2578 else => {
2577 if (!math.isPowerOfTwo(bit_size))2579 if (!math.isPowerOfTwo(bit_size))
2578 return func.fail(2580 return func.fail(
2579 "TODO: genBinOp verify {s} non-pow 2, found {}",2581 "TODO: genBinOp verify if needs to truncate {s} non-pow 2, found {}",
2580 .{ @tagName(tag), bit_size },2582 .{ @tagName(tag), bit_size },
2581 );2583 );
2582 },2584 },
...@@ -2604,7 +2606,7 @@ fn genBinOp(...@@ -2604,7 +2606,7 @@ fn genBinOp(
2604 8, 16, 32 => if (is_unsigned) .remuw else .remw,2606 8, 16, 32 => if (is_unsigned) .remuw else .remw,
2605 else => if (is_unsigned) .remu else .rem,2607 else => if (is_unsigned) .remu else .rem,
2606 },2608 },
2607 .div_trunc => switch (bit_size) {2609 .div_trunc, .div_exact => switch (bit_size) {
2608 8, 16, 32 => if (is_unsigned) .divuw else .divw,2610 8, 16, 32 => if (is_unsigned) .divuw else .divw,
2609 else => if (is_unsigned) .divu else .div,2611 else => if (is_unsigned) .divu else .div,
2610 },2612 },
src/arch/riscv64/Emit.zig+3
...@@ -63,6 +63,9 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -63,6 +63,9 @@ pub fn emitMir(emit: *Emit) Error!void {
6363
64 hi_r_type = Elf.R_ZIG_GOT_HI20;64 hi_r_type = Elf.R_ZIG_GOT_HI20;
65 lo_r_type = Elf.R_ZIG_GOT_LO12;65 lo_r_type = Elf.R_ZIG_GOT_LO12;
66 } else if (sym.flags.needs_got) {
67 hi_r_type = Elf.R_GOT_HI20_STATIC; // TODO: rework this #20887
68 lo_r_type = Elf.R_GOT_LO12_I_STATIC; // TODO: rework this #20887
66 }69 }
6770
68 try atom_ptr.addReloc(elf_file, .{71 try atom_ptr.addReloc(elf_file, .{
src/link/Elf.zig+30-1
...@@ -6059,11 +6059,40 @@ const RelaSection = struct {...@@ -6059,11 +6059,40 @@ const RelaSection = struct {
6059};6059};
6060const RelaSectionTable = std.AutoArrayHashMapUnmanaged(u32, RelaSection);6060const RelaSectionTable = std.AutoArrayHashMapUnmanaged(u32, RelaSection);
60616061
6062// TODO: add comptime check we don't clobber any reloc for any ISA
6063pub const R_ZIG_GOT32: u32 = 0xff00;6062pub const R_ZIG_GOT32: u32 = 0xff00;
6064pub const R_ZIG_GOTPCREL: u32 = 0xff01;6063pub const R_ZIG_GOTPCREL: u32 = 0xff01;
6065pub const R_ZIG_GOT_HI20: u32 = 0xff02;6064pub const R_ZIG_GOT_HI20: u32 = 0xff02;
6066pub const R_ZIG_GOT_LO12: u32 = 0xff03;6065pub const R_ZIG_GOT_LO12: u32 = 0xff03;
6066pub const R_GOT_HI20_STATIC: u32 = 0xff04;
6067pub const R_GOT_LO12_I_STATIC: u32 = 0xff05;
6068
6069// Comptime asserts that no Zig relocs overlap with another ISA's reloc number
6070comptime {
6071 const zig_relocs = .{
6072 R_ZIG_GOT32,
6073 R_ZIG_GOT_HI20,
6074 R_ZIG_GOT_LO12,
6075 R_ZIG_GOTPCREL,
6076 R_GOT_HI20_STATIC,
6077 R_GOT_LO12_I_STATIC,
6078 };
6079
6080 const other_relocs = .{
6081 elf.R_X86_64,
6082 elf.R_AARCH64,
6083 elf.R_RISCV,
6084 elf.R_PPC64,
6085 };
6086
6087 @setEvalBranchQuota(@min(other_relocs.len * zig_relocs.len * 256, 6200));
6088 for (other_relocs) |relocs| {
6089 for (@typeInfo(relocs).Enum.fields) |reloc| {
6090 for (zig_relocs) |zig_reloc| {
6091 assert(reloc.value != zig_reloc);
6092 }
6093 }
6094 }
6095}
60676096
6068fn defaultEntrySymbolName(cpu_arch: std.Target.Cpu.Arch) []const u8 {6097fn defaultEntrySymbolName(cpu_arch: std.Target.Cpu.Arch) []const u8 {
6069 return switch (cpu_arch) {6098 return switch (cpu_arch) {
src/link/Elf/Atom.zig+18-2
...@@ -2016,6 +2016,10 @@ const riscv = struct {...@@ -2016,6 +2016,10 @@ const riscv = struct {
2016 assert(symbol.flags.has_zig_got);2016 assert(symbol.flags.has_zig_got);
2017 },2017 },
20182018
2019 Elf.R_GOT_HI20_STATIC,
2020 Elf.R_GOT_LO12_I_STATIC,
2021 => symbol.flags.needs_got = true,
2022
2019 else => try atom.reportUnhandledRelocError(rel, elf_file),2023 else => try atom.reportUnhandledRelocError(rel, elf_file),
2020 },2024 },
2021 }2025 }
...@@ -2161,16 +2165,28 @@ const riscv = struct {...@@ -2161,16 +2165,28 @@ const riscv = struct {
2161 // Zig custom relocations2165 // Zig custom relocations
2162 Elf.R_ZIG_GOT_HI20 => {2166 Elf.R_ZIG_GOT_HI20 => {
2163 assert(target.flags.has_zig_got);2167 assert(target.flags.has_zig_got);
2164 const disp: u32 = @bitCast(math.cast(i32, G + ZIG_GOT + A) orelse return error.Overflow);2168 const disp: u32 = @bitCast(math.cast(i32, ZIG_GOT + A) orelse return error.Overflow);
2165 riscv_util.writeInstU(code[r_offset..][0..4], disp);2169 riscv_util.writeInstU(code[r_offset..][0..4], disp);
2166 },2170 },
21672171
2168 Elf.R_ZIG_GOT_LO12 => {2172 Elf.R_ZIG_GOT_LO12 => {
2169 assert(target.flags.has_zig_got);2173 assert(target.flags.has_zig_got);
2170 const value: u32 = @bitCast(math.cast(i32, G + ZIG_GOT + A) orelse return error.Overflow);2174 const value: u32 = @bitCast(math.cast(i32, ZIG_GOT + A) orelse return error.Overflow);
2171 riscv_util.writeInstI(code[r_offset..][0..4], value);2175 riscv_util.writeInstI(code[r_offset..][0..4], value);
2172 },2176 },
21732177
2178 Elf.R_GOT_HI20_STATIC => {
2179 assert(target.flags.has_got);
2180 const disp: u32 = @bitCast(math.cast(i32, G + GOT + A) orelse return error.Overflow);
2181 riscv_util.writeInstU(code[r_offset..][0..4], disp);
2182 },
2183
2184 Elf.R_GOT_LO12_I_STATIC => {
2185 assert(target.flags.has_got);
2186 const disp: u32 = @bitCast(math.cast(i32, G + GOT + A) orelse return error.Overflow);
2187 riscv_util.writeInstI(code[r_offset..][0..4], disp);
2188 },
2189
2174 else => try atom.reportUnhandledRelocError(rel, elf_file),2190 else => try atom.reportUnhandledRelocError(rel, elf_file),
2175 },2191 },
2176 }2192 }
src/link/Elf/relocation.zig+4
...@@ -115,6 +115,10 @@ fn formatRelocType(...@@ -115,6 +115,10 @@ fn formatRelocType(
115 switch (r_type) {115 switch (r_type) {
116 Elf.R_ZIG_GOT32 => try writer.writeAll("R_ZIG_GOT32"),116 Elf.R_ZIG_GOT32 => try writer.writeAll("R_ZIG_GOT32"),
117 Elf.R_ZIG_GOTPCREL => try writer.writeAll("R_ZIG_GOTPCREL"),117 Elf.R_ZIG_GOTPCREL => try writer.writeAll("R_ZIG_GOTPCREL"),
118 Elf.R_ZIG_GOT_HI20 => try writer.writeAll("R_ZIG_GOT_HI20"),
119 Elf.R_ZIG_GOT_LO12 => try writer.writeAll("R_ZIG_GOT_LO12"),
120 Elf.R_GOT_HI20_STATIC => try writer.writeAll("R_GOT_HI20_STATIC"),
121 Elf.R_GOT_LO12_I_STATIC => try writer.writeAll("R_GOT_LO12_I_STATIC"),
118 else => switch (ctx.cpu_arch) {122 else => switch (ctx.cpu_arch) {
119 .x86_64 => try writer.print("R_X86_64_{s}", .{@tagName(@as(elf.R_X86_64, @enumFromInt(r_type)))}),123 .x86_64 => try writer.print("R_X86_64_{s}", .{@tagName(@as(elf.R_X86_64, @enumFromInt(r_type)))}),
120 .aarch64 => try writer.print("R_AARCH64_{s}", .{@tagName(@as(elf.R_AARCH64, @enumFromInt(r_type)))}),124 .aarch64 => try writer.print("R_AARCH64_{s}", .{@tagName(@as(elf.R_AARCH64, @enumFromInt(r_type)))}),