mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
Merge pull request #20884 from Rexicon226/riscv
This commit is contained in:
commit
8ea323822b
@ -465,21 +465,18 @@ fn posixCallMainAndExit(argc_argv_ptr: [*]usize) callconv(.C) noreturn {
|
||||
// to ask for more stack space.
|
||||
expandStackSize(phdrs);
|
||||
|
||||
// Disabled with the riscv backend because it cannot handle this code yet.
|
||||
if (builtin.zig_backend != .stage2_riscv64) {
|
||||
const opt_init_array_start = @extern([*]*const fn () callconv(.C) void, .{
|
||||
.name = "__init_array_start",
|
||||
.linkage = .weak,
|
||||
});
|
||||
const opt_init_array_end = @extern([*]*const fn () callconv(.C) void, .{
|
||||
.name = "__init_array_end",
|
||||
.linkage = .weak,
|
||||
});
|
||||
if (opt_init_array_start) |init_array_start| {
|
||||
const init_array_end = opt_init_array_end.?;
|
||||
const slice = init_array_start[0 .. init_array_end - init_array_start];
|
||||
for (slice) |func| func();
|
||||
}
|
||||
const opt_init_array_start = @extern([*]*const fn () callconv(.C) void, .{
|
||||
.name = "__init_array_start",
|
||||
.linkage = .weak,
|
||||
});
|
||||
const opt_init_array_end = @extern([*]*const fn () callconv(.C) void, .{
|
||||
.name = "__init_array_end",
|
||||
.linkage = .weak,
|
||||
});
|
||||
if (opt_init_array_start) |init_array_start| {
|
||||
const init_array_end = opt_init_array_end.?;
|
||||
const slice = init_array_start[0 .. init_array_end - init_array_start];
|
||||
for (slice) |func| func();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1510,6 +1510,7 @@ fn genBody(func: *Func, body: []const Air.Inst.Index) InnerError!void {
|
||||
.mul,
|
||||
.mul_wrap,
|
||||
.div_trunc,
|
||||
.div_exact,
|
||||
.rem,
|
||||
|
||||
.shl, .shl_exact,
|
||||
@ -1533,7 +1534,6 @@ fn genBody(func: *Func, body: []const Air.Inst.Index) InnerError!void {
|
||||
.mod,
|
||||
.div_float,
|
||||
.div_floor,
|
||||
.div_exact,
|
||||
=> return func.fail("TODO: {s}", .{@tagName(tag)}),
|
||||
|
||||
.sqrt,
|
||||
@ -2563,10 +2563,12 @@ fn genBinOp(
|
||||
.mul_wrap,
|
||||
.rem,
|
||||
.div_trunc,
|
||||
.div_exact,
|
||||
=> {
|
||||
switch (tag) {
|
||||
.rem,
|
||||
.div_trunc,
|
||||
.div_exact,
|
||||
=> {
|
||||
if (!math.isPowerOfTwo(bit_size)) {
|
||||
try func.truncateRegister(lhs_ty, lhs_reg);
|
||||
@ -2576,7 +2578,7 @@ fn genBinOp(
|
||||
else => {
|
||||
if (!math.isPowerOfTwo(bit_size))
|
||||
return func.fail(
|
||||
"TODO: genBinOp verify {s} non-pow 2, found {}",
|
||||
"TODO: genBinOp verify if needs to truncate {s} non-pow 2, found {}",
|
||||
.{ @tagName(tag), bit_size },
|
||||
);
|
||||
},
|
||||
@ -2604,7 +2606,7 @@ fn genBinOp(
|
||||
8, 16, 32 => if (is_unsigned) .remuw else .remw,
|
||||
else => if (is_unsigned) .remu else .rem,
|
||||
},
|
||||
.div_trunc => switch (bit_size) {
|
||||
.div_trunc, .div_exact => switch (bit_size) {
|
||||
8, 16, 32 => if (is_unsigned) .divuw else .divw,
|
||||
else => if (is_unsigned) .divu else .div,
|
||||
},
|
||||
|
||||
@ -63,6 +63,9 @@ pub fn emitMir(emit: *Emit) Error!void {
|
||||
|
||||
hi_r_type = Elf.R_ZIG_GOT_HI20;
|
||||
lo_r_type = Elf.R_ZIG_GOT_LO12;
|
||||
} else if (sym.flags.needs_got) {
|
||||
hi_r_type = Elf.R_GOT_HI20_STATIC; // TODO: rework this #20887
|
||||
lo_r_type = Elf.R_GOT_LO12_I_STATIC; // TODO: rework this #20887
|
||||
}
|
||||
|
||||
try atom_ptr.addReloc(elf_file, .{
|
||||
|
||||
@ -6059,11 +6059,40 @@ const RelaSection = struct {
|
||||
};
|
||||
const RelaSectionTable = std.AutoArrayHashMapUnmanaged(u32, RelaSection);
|
||||
|
||||
// TODO: add comptime check we don't clobber any reloc for any ISA
|
||||
pub const R_ZIG_GOT32: u32 = 0xff00;
|
||||
pub const R_ZIG_GOTPCREL: u32 = 0xff01;
|
||||
pub const R_ZIG_GOT_HI20: u32 = 0xff02;
|
||||
pub const R_ZIG_GOT_LO12: u32 = 0xff03;
|
||||
pub const R_GOT_HI20_STATIC: u32 = 0xff04;
|
||||
pub const R_GOT_LO12_I_STATIC: u32 = 0xff05;
|
||||
|
||||
// Comptime asserts that no Zig relocs overlap with another ISA's reloc number
|
||||
comptime {
|
||||
const zig_relocs = .{
|
||||
R_ZIG_GOT32,
|
||||
R_ZIG_GOT_HI20,
|
||||
R_ZIG_GOT_LO12,
|
||||
R_ZIG_GOTPCREL,
|
||||
R_GOT_HI20_STATIC,
|
||||
R_GOT_LO12_I_STATIC,
|
||||
};
|
||||
|
||||
const other_relocs = .{
|
||||
elf.R_X86_64,
|
||||
elf.R_AARCH64,
|
||||
elf.R_RISCV,
|
||||
elf.R_PPC64,
|
||||
};
|
||||
|
||||
@setEvalBranchQuota(@min(other_relocs.len * zig_relocs.len * 256, 6200));
|
||||
for (other_relocs) |relocs| {
|
||||
for (@typeInfo(relocs).Enum.fields) |reloc| {
|
||||
for (zig_relocs) |zig_reloc| {
|
||||
assert(reloc.value != zig_reloc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn defaultEntrySymbolName(cpu_arch: std.Target.Cpu.Arch) []const u8 {
|
||||
return switch (cpu_arch) {
|
||||
|
||||
@ -2016,6 +2016,10 @@ const riscv = struct {
|
||||
assert(symbol.flags.has_zig_got);
|
||||
},
|
||||
|
||||
Elf.R_GOT_HI20_STATIC,
|
||||
Elf.R_GOT_LO12_I_STATIC,
|
||||
=> symbol.flags.needs_got = true,
|
||||
|
||||
else => try atom.reportUnhandledRelocError(rel, elf_file),
|
||||
},
|
||||
}
|
||||
@ -2161,16 +2165,28 @@ const riscv = struct {
|
||||
// Zig custom relocations
|
||||
Elf.R_ZIG_GOT_HI20 => {
|
||||
assert(target.flags.has_zig_got);
|
||||
const disp: u32 = @bitCast(math.cast(i32, G + ZIG_GOT + A) orelse return error.Overflow);
|
||||
const disp: u32 = @bitCast(math.cast(i32, ZIG_GOT + A) orelse return error.Overflow);
|
||||
riscv_util.writeInstU(code[r_offset..][0..4], disp);
|
||||
},
|
||||
|
||||
Elf.R_ZIG_GOT_LO12 => {
|
||||
assert(target.flags.has_zig_got);
|
||||
const value: u32 = @bitCast(math.cast(i32, G + ZIG_GOT + A) orelse return error.Overflow);
|
||||
const value: u32 = @bitCast(math.cast(i32, ZIG_GOT + A) orelse return error.Overflow);
|
||||
riscv_util.writeInstI(code[r_offset..][0..4], value);
|
||||
},
|
||||
|
||||
Elf.R_GOT_HI20_STATIC => {
|
||||
assert(target.flags.has_got);
|
||||
const disp: u32 = @bitCast(math.cast(i32, G + GOT + A) orelse return error.Overflow);
|
||||
riscv_util.writeInstU(code[r_offset..][0..4], disp);
|
||||
},
|
||||
|
||||
Elf.R_GOT_LO12_I_STATIC => {
|
||||
assert(target.flags.has_got);
|
||||
const disp: u32 = @bitCast(math.cast(i32, G + GOT + A) orelse return error.Overflow);
|
||||
riscv_util.writeInstI(code[r_offset..][0..4], disp);
|
||||
},
|
||||
|
||||
else => try atom.reportUnhandledRelocError(rel, elf_file),
|
||||
},
|
||||
}
|
||||
|
||||
@ -115,6 +115,10 @@ fn formatRelocType(
|
||||
switch (r_type) {
|
||||
Elf.R_ZIG_GOT32 => try writer.writeAll("R_ZIG_GOT32"),
|
||||
Elf.R_ZIG_GOTPCREL => try writer.writeAll("R_ZIG_GOTPCREL"),
|
||||
Elf.R_ZIG_GOT_HI20 => try writer.writeAll("R_ZIG_GOT_HI20"),
|
||||
Elf.R_ZIG_GOT_LO12 => try writer.writeAll("R_ZIG_GOT_LO12"),
|
||||
Elf.R_GOT_HI20_STATIC => try writer.writeAll("R_GOT_HI20_STATIC"),
|
||||
Elf.R_GOT_LO12_I_STATIC => try writer.writeAll("R_GOT_LO12_I_STATIC"),
|
||||
else => switch (ctx.cpu_arch) {
|
||||
.x86_64 => try writer.print("R_X86_64_{s}", .{@tagName(@as(elf.R_X86_64, @enumFromInt(r_type)))}),
|
||||
.aarch64 => try writer.print("R_AARCH64_{s}", .{@tagName(@as(elf.R_AARCH64, @enumFromInt(r_type)))}),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user