mirror of
https://github.com/ziglang/zig.git
synced 2026-01-20 14:25:16 +00:00
riscv: add enough components to get a test runner working
This commit is contained in:
parent
c0629c3539
commit
8ac239ebce
@ -12,9 +12,9 @@ var cmdline_buffer: [4096]u8 = undefined;
|
||||
var fba = std.heap.FixedBufferAllocator.init(&cmdline_buffer);
|
||||
|
||||
pub fn main() void {
|
||||
if (builtin.zig_backend == .stage2_aarch64 or
|
||||
builtin.zig_backend == .stage2_riscv64)
|
||||
{
|
||||
if (builtin.zig_backend == .stage2_riscv64) return mainExtraSimple() catch @panic("test failure");
|
||||
|
||||
if (builtin.zig_backend == .stage2_aarch64) {
|
||||
return mainSimple() catch @panic("test failure");
|
||||
}
|
||||
|
||||
@ -249,3 +249,17 @@ pub fn mainSimple() anyerror!void {
|
||||
if (failed != 0) std.process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mainExtraSimple() !void {
|
||||
var pass_count: u8 = 0;
|
||||
|
||||
for (builtin.test_functions) |test_fn| {
|
||||
test_fn.func() catch |err| {
|
||||
if (err != error.SkipZigTest) {
|
||||
@panic(test_fn.name);
|
||||
}
|
||||
continue;
|
||||
};
|
||||
pass_count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,7 +20,6 @@ pub const simplified_logic =
|
||||
builtin.zig_backend == .stage2_x86 or
|
||||
builtin.zig_backend == .stage2_aarch64 or
|
||||
builtin.zig_backend == .stage2_arm or
|
||||
builtin.zig_backend == .stage2_riscv64 or
|
||||
builtin.zig_backend == .stage2_sparc64 or
|
||||
builtin.cpu.arch == .spirv32 or
|
||||
builtin.cpu.arch == .spirv64;
|
||||
@ -61,6 +60,10 @@ comptime {
|
||||
} else if (@typeInfo(@TypeOf(root.main)).Fn.calling_convention != .C) {
|
||||
@export(main, .{ .name = "main" });
|
||||
}
|
||||
} else if (native_arch.isRISCV()) {
|
||||
if (!@hasDecl(root, "_start")) {
|
||||
@export(riscv_start, .{ .name = "_start" });
|
||||
}
|
||||
} else if (native_os == .windows) {
|
||||
if (!@hasDecl(root, "WinMain") and !@hasDecl(root, "WinMainCRTStartup") and
|
||||
!@hasDecl(root, "wWinMain") and !@hasDecl(root, "wWinMainCRTStartup"))
|
||||
@ -151,14 +154,6 @@ fn exit2(code: usize) noreturn {
|
||||
: "memory", "cc"
|
||||
);
|
||||
},
|
||||
.riscv64 => {
|
||||
asm volatile ("ecall"
|
||||
:
|
||||
: [number] "{a7}" (94),
|
||||
[arg1] "{a0}" (code),
|
||||
: "rcx", "r11", "memory"
|
||||
);
|
||||
},
|
||||
.sparc64 => {
|
||||
asm volatile ("ta 0x6d"
|
||||
:
|
||||
@ -212,6 +207,11 @@ fn wasi_start() callconv(.C) void {
|
||||
}
|
||||
}
|
||||
|
||||
fn riscv_start() callconv(.C) noreturn {
|
||||
const code = @call(.always_inline, callMain, .{});
|
||||
std.process.exit(code);
|
||||
}
|
||||
|
||||
fn EfiMain(handle: uefi.Handle, system_table: *uefi.tables.SystemTable) callconv(.C) usize {
|
||||
uefi.handle = handle;
|
||||
uefi.system_table = system_table;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -4,6 +4,8 @@
|
||||
mir: Mir,
|
||||
bin_file: *link.File,
|
||||
debug_output: DebugInfoOutput,
|
||||
output_mode: std.builtin.OutputMode,
|
||||
link_mode: std.builtin.LinkMode,
|
||||
target: *const std.Target,
|
||||
err_msg: ?*ErrorMsg = null,
|
||||
src_loc: Module.SrcLoc,
|
||||
@ -47,6 +49,7 @@ pub fn emitMir(
|
||||
switch (tag) {
|
||||
.add => try emit.mirRType(inst),
|
||||
.sub => try emit.mirRType(inst),
|
||||
.mul => try emit.mirRType(inst),
|
||||
.@"or" => try emit.mirRType(inst),
|
||||
|
||||
.cmp_eq => try emit.mirRType(inst),
|
||||
@ -56,7 +59,9 @@ pub fn emitMir(
|
||||
.cmp_lt => try emit.mirRType(inst),
|
||||
.cmp_imm_gte => try emit.mirRType(inst),
|
||||
.cmp_imm_eq => try emit.mirIType(inst),
|
||||
.cmp_imm_neq => try emit.mirIType(inst),
|
||||
.cmp_imm_lte => try emit.mirIType(inst),
|
||||
.cmp_imm_lt => try emit.mirIType(inst),
|
||||
|
||||
.beq => try emit.mirBType(inst),
|
||||
.bne => try emit.mirBType(inst),
|
||||
@ -186,6 +191,7 @@ fn mirRType(emit: *Emit, inst: Mir.Inst.Index) !void {
|
||||
switch (tag) {
|
||||
.add => try emit.writeInstruction(Instruction.add(rd, rs1, rs2)),
|
||||
.sub => try emit.writeInstruction(Instruction.sub(rd, rs1, rs2)),
|
||||
.mul => try emit.writeInstruction(Instruction.mul(rd, rs1, rs2)),
|
||||
.cmp_gt => {
|
||||
// rs1 > rs2
|
||||
try emit.writeInstruction(Instruction.sltu(rd, rs2, rs1));
|
||||
@ -284,6 +290,14 @@ fn mirIType(emit: *Emit, inst: Mir.Inst.Index) !void {
|
||||
try emit.writeInstruction(Instruction.xori(rd, rs1, imm12));
|
||||
try emit.writeInstruction(Instruction.sltiu(rd, rd, 1));
|
||||
},
|
||||
.cmp_imm_neq => {
|
||||
try emit.writeInstruction(Instruction.xori(rd, rs1, imm12));
|
||||
try emit.writeInstruction(Instruction.sltu(rd, .x0, rd));
|
||||
},
|
||||
|
||||
.cmp_imm_lt => {
|
||||
try emit.writeInstruction(Instruction.slti(rd, rs1, imm12));
|
||||
},
|
||||
|
||||
.cmp_imm_lte => {
|
||||
try emit.writeInstruction(Instruction.sltiu(rd, rs1, @bitCast(imm12)));
|
||||
@ -447,6 +461,7 @@ fn mirLoadSymbol(emit: *Emit, inst: Mir.Inst.Index) !void {
|
||||
|
||||
const start_offset = @as(u32, @intCast(emit.code.items.len));
|
||||
try emit.writeInstruction(Instruction.lui(reg, 0));
|
||||
try emit.writeInstruction(Instruction.addi(reg, reg, 0));
|
||||
|
||||
switch (emit.bin_file.tag) {
|
||||
.elf => {
|
||||
@ -463,12 +478,6 @@ fn mirLoadSymbol(emit: *Emit, inst: Mir.Inst.Index) !void {
|
||||
|
||||
hi_r_type = Elf.R_ZIG_GOT_HI20;
|
||||
lo_r_type = Elf.R_ZIG_GOT_LO12;
|
||||
|
||||
// we need to deref once if we are getting from zig_got, as itll
|
||||
// reloc an address of the address in the got.
|
||||
try emit.writeInstruction(Instruction.ld(reg, 0, reg));
|
||||
} else {
|
||||
try emit.writeInstruction(Instruction.addi(reg, reg, 0));
|
||||
}
|
||||
|
||||
try atom_ptr.addReloc(elf_file, .{
|
||||
@ -544,6 +553,7 @@ fn instructionSize(emit: *Emit, inst: Mir.Inst.Index) usize {
|
||||
.cmp_eq,
|
||||
.cmp_neq,
|
||||
.cmp_imm_eq,
|
||||
.cmp_imm_neq,
|
||||
.cmp_gte,
|
||||
.load_symbol,
|
||||
.abs,
|
||||
|
||||
@ -33,6 +33,8 @@ pub const Inst = struct {
|
||||
add,
|
||||
/// Subtraction
|
||||
sub,
|
||||
/// Multiply, uses r_type. Needs the M extension.
|
||||
mul,
|
||||
|
||||
/// Absolute Value, uses i_type payload.
|
||||
abs,
|
||||
@ -76,8 +78,12 @@ pub const Inst = struct {
|
||||
|
||||
/// Immediate `==`, uses i_type
|
||||
cmp_imm_eq,
|
||||
/// Immediate `!=`, uses i_type.
|
||||
cmp_imm_neq,
|
||||
/// Immediate `<=`, uses i_type
|
||||
cmp_imm_lte,
|
||||
/// Immediate `<`, uses i_type
|
||||
cmp_imm_lt,
|
||||
|
||||
/// Branch if equal, Uses b_type
|
||||
beq,
|
||||
|
||||
@ -112,7 +112,7 @@ pub const Instruction = union(enum) {
|
||||
// -- less burden on callsite, bonus semantic checking
|
||||
fn bType(op: u7, fn3: u3, r1: Register, r2: Register, imm: i13) Instruction {
|
||||
const umm = @as(u13, @bitCast(imm));
|
||||
assert(umm % 2 == 0); // misaligned branch target
|
||||
assert(umm % 4 == 0); // misaligned branch target
|
||||
|
||||
return Instruction{
|
||||
.B = .{
|
||||
@ -201,6 +201,12 @@ pub const Instruction = union(enum) {
|
||||
return rType(0b0110011, 0b011, 0b0000000, rd, r1, r2);
|
||||
}
|
||||
|
||||
// M extension operations
|
||||
|
||||
pub fn mul(rd: Register, r1: Register, r2: Register) Instruction {
|
||||
return rType(0b0110011, 0b000, 0b0000001, rd, r1, r2);
|
||||
}
|
||||
|
||||
// Arithmetic/Logical, Register-Register (32-bit)
|
||||
|
||||
pub fn addw(rd: Register, r1: Register, r2: Register) Instruction {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user