Merge pull request #20807 from Rexicon226/riscv

riscv: more backend progress
This commit is contained in:
Jakub Konka 2024-07-28 11:34:23 +02:00 committed by GitHub
commit 91c17979f1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
64 changed files with 3483 additions and 3246 deletions

View File

@ -535,11 +535,14 @@ set(ZIG_STAGE2_SOURCES
src/arch/arm/Mir.zig
src/arch/arm/abi.zig
src/arch/arm/bits.zig
src/arch/riscv64/CodeGen.zig
src/arch/riscv64/Emit.zig
src/arch/riscv64/Mir.zig
src/arch/riscv64/abi.zig
src/arch/riscv64/bits.zig
src/arch/riscv64/CodeGen.zig
src/arch/riscv64/Emit.zig
src/arch/riscv64/encoding.zig
src/arch/riscv64/Lower.zig
src/arch/riscv64/Mir.zig
src/arch/riscv64/mnem.zig
src/arch/sparc64/CodeGen.zig
src/arch/sparc64/Emit.zig
src/arch/sparc64/Mir.zig

View File

@ -282,11 +282,13 @@ pub fn mainSimple() anyerror!void {
const stderr = if (comptime enable_print) std.io.getStdErr() else {};
for (builtin.test_functions) |test_fn| {
if (enable_print) {
stderr.writeAll(test_fn.name) catch {};
stderr.writeAll("... ") catch {};
}
test_fn.func() catch |err| {
if (test_fn.func()) |_| {
if (enable_print) {
stderr.writeAll(test_fn.name) catch {};
stderr.writeAll("... ") catch {};
stderr.writeAll("PASS\n") catch {};
}
} else |err| if (enable_print) {
if (enable_print) {
stderr.writeAll(test_fn.name) catch {};
stderr.writeAll("... ") catch {};
@ -300,8 +302,7 @@ pub fn mainSimple() anyerror!void {
if (enable_print) stderr.writeAll("SKIP\n") catch {};
skipped += 1;
continue;
};
if (enable_print) stderr.writeAll("PASS\n") catch {};
}
passed += 1;
}
if (enable_print and print_summary) {

View File

@ -385,7 +385,7 @@ pub fn yield() YieldError!void {
}
/// State to synchronize detachment of spawner thread to spawned thread
const Completion = std.atomic.Value(enum(u8) {
const Completion = std.atomic.Value(enum(if (builtin.zig_backend == .stage2_riscv64) u32 else u8) {
running,
detached,
completed,

View File

@ -775,14 +775,8 @@ pub fn default_panic(msg: []const u8, error_return_trace: ?*StackTrace, ret_addr
}
if (builtin.zig_backend == .stage2_riscv64) {
asm volatile ("ecall"
:
: [number] "{a7}" (64),
[arg1] "{a0}" (1),
[arg2] "{a1}" (@intFromPtr(msg.ptr)),
[arg3] "{a2}" (msg.len),
: "memory"
);
std.debug.print("panic: {s}\n", .{msg});
@breakpoint();
std.posix.exit(127);
}

View File

@ -20,8 +20,7 @@ pub const simplified_logic =
builtin.zig_backend == .stage2_arm or
builtin.zig_backend == .stage2_sparc64 or
builtin.cpu.arch == .spirv32 or
builtin.cpu.arch == .spirv64 or
builtin.zig_backend == .stage2_riscv64;
builtin.cpu.arch == .spirv64;
comptime {
// No matter what, we import the root file, so that any export, test, comptime
@ -41,10 +40,6 @@ comptime {
} else if (builtin.os.tag == .opencl) {
if (@hasDecl(root, "main"))
@export(spirvMain2, .{ .name = "main" });
} else if (native_arch.isRISCV()) {
if (!@hasDecl(root, "_start")) {
@export(riscv_start, .{ .name = "_start" });
}
} else {
if (!@hasDecl(root, "_start")) {
@export(_start2, .{ .name = "_start" });
@ -206,42 +201,6 @@ fn wasi_start() callconv(.C) void {
}
}
fn riscv_start() callconv(.C) noreturn {
std.process.exit(switch (@typeInfo(@typeInfo(@TypeOf(root.main)).Fn.return_type.?)) {
.NoReturn => root.main(),
.Void => ret: {
root.main();
break :ret 0;
},
.Int => |info| ret: {
if (info.bits != 8 or info.signedness == .signed) {
@compileError(bad_main_ret);
}
break :ret root.main();
},
.ErrorUnion => ret: {
const result = root.main() catch {
const stderr = std.io.getStdErr().writer();
stderr.writeAll("failed with error\n") catch {
@panic("failed to print when main returned error");
};
break :ret 1;
};
switch (@typeInfo(@TypeOf(result))) {
.Void => break :ret 0,
.Int => |info| {
if (info.bits != 8 or info.signedness == .signed) {
@compileError(bad_main_ret);
}
return result;
},
else => @compileError(bad_main_ret),
}
},
else => @compileError(bad_main_ret),
});
}
fn EfiMain(handle: uefi.Handle, system_table: *uefi.tables.SystemTable) callconv(.C) usize {
uefi.handle = handle;
uefi.system_table = system_table;
@ -563,6 +522,10 @@ pub inline fn callMain() u8 {
if (@typeInfo(ReturnType) != .ErrorUnion) @compileError(bad_main_ret);
const result = root.main() catch |err| {
if (builtin.zig_backend == .stage2_riscv64) {
std.debug.print("error: failed with error\n", .{});
return 1;
}
std.log.err("{s}", .{@errorName(err)});
if (@errorReturnTrace()) |trace| {
std.debug.dumpStackTrace(trace.*);

View File

@ -6334,6 +6334,7 @@ fn canBuildZigLibC(target: std.Target, use_llvm: bool) bool {
}
return switch (target_util.zigBackend(target, use_llvm)) {
.stage2_llvm => true,
.stage2_riscv64 => true,
.stage2_x86_64 => if (target.ofmt == .elf or target.ofmt == .macho) true else build_options.have_llvm,
else => build_options.have_llvm,
};

File diff suppressed because it is too large Load Diff

View File

@ -40,7 +40,7 @@ pub fn emitMir(emit: *Emit) Error!void {
.source = start_offset,
.target = target,
.offset = 0,
.enc = std.meta.activeTag(lowered_inst.encoding.data),
.fmt = std.meta.activeTag(lowered_inst),
}),
.load_symbol_reloc => |symbol| {
const is_obj_or_static_lib = switch (emit.lower.output_mode) {
@ -49,46 +49,70 @@ pub fn emitMir(emit: *Emit) Error!void {
.Lib => emit.lower.link_mode == .static,
};
if (emit.bin_file.cast(link.File.Elf)) |elf_file| {
const atom_ptr = elf_file.symbol(symbol.atom_index).atom(elf_file).?;
const sym_index = elf_file.zigObjectPtr().?.symbol(symbol.sym_index);
const sym = elf_file.symbol(sym_index);
const elf_file = emit.bin_file.cast(link.File.Elf).?;
var hi_r_type: u32 = @intFromEnum(std.elf.R_RISCV.HI20);
var lo_r_type: u32 = @intFromEnum(std.elf.R_RISCV.LO12_I);
const atom_ptr = elf_file.symbol(symbol.atom_index).atom(elf_file).?;
const sym_index = elf_file.zigObjectPtr().?.symbol(symbol.sym_index);
const sym = elf_file.symbol(sym_index);
if (sym.flags.needs_zig_got and !is_obj_or_static_lib) {
_ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);
var hi_r_type: u32 = @intFromEnum(std.elf.R_RISCV.HI20);
var lo_r_type: u32 = @intFromEnum(std.elf.R_RISCV.LO12_I);
hi_r_type = Elf.R_ZIG_GOT_HI20;
lo_r_type = Elf.R_ZIG_GOT_LO12;
}
if (sym.flags.needs_zig_got and !is_obj_or_static_lib) {
_ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);
try atom_ptr.addReloc(elf_file, .{
.r_offset = start_offset,
.r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | hi_r_type,
.r_addend = 0,
});
hi_r_type = Elf.R_ZIG_GOT_HI20;
lo_r_type = Elf.R_ZIG_GOT_LO12;
}
try atom_ptr.addReloc(elf_file, .{
.r_offset = start_offset + 4,
.r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | lo_r_type,
.r_addend = 0,
});
} else unreachable;
try atom_ptr.addReloc(elf_file, .{
.r_offset = start_offset,
.r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | hi_r_type,
.r_addend = 0,
});
try atom_ptr.addReloc(elf_file, .{
.r_offset = start_offset + 4,
.r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | lo_r_type,
.r_addend = 0,
});
},
.load_tlv_reloc => |symbol| {
const elf_file = emit.bin_file.cast(link.File.Elf).?;
const atom_ptr = elf_file.symbol(symbol.atom_index).atom(elf_file).?;
const R_RISCV = std.elf.R_RISCV;
try atom_ptr.addReloc(elf_file, .{
.r_offset = start_offset,
.r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | @intFromEnum(R_RISCV.TPREL_HI20),
.r_addend = 0,
});
try atom_ptr.addReloc(elf_file, .{
.r_offset = start_offset + 4,
.r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | @intFromEnum(R_RISCV.TPREL_ADD),
.r_addend = 0,
});
try atom_ptr.addReloc(elf_file, .{
.r_offset = start_offset + 8,
.r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | @intFromEnum(R_RISCV.TPREL_LO12_I),
.r_addend = 0,
});
},
.call_extern_fn_reloc => |symbol| {
if (emit.bin_file.cast(link.File.Elf)) |elf_file| {
const atom_ptr = elf_file.symbol(symbol.atom_index).atom(elf_file).?;
const elf_file = emit.bin_file.cast(link.File.Elf).?;
const atom_ptr = elf_file.symbol(symbol.atom_index).atom(elf_file).?;
const r_type: u32 = @intFromEnum(std.elf.R_RISCV.CALL_PLT);
const r_type: u32 = @intFromEnum(std.elf.R_RISCV.CALL_PLT);
try atom_ptr.addReloc(elf_file, .{
.r_offset = start_offset,
.r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | r_type,
.r_addend = 0,
});
} else return emit.fail("TODO: call_extern_fn_reloc non-ELF", .{});
try atom_ptr.addReloc(elf_file, .{
.r_offset = start_offset,
.r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | r_type,
.r_addend = 0,
});
},
};
}
@ -98,40 +122,37 @@ pub fn emitMir(emit: *Emit) Error!void {
const mir_inst = emit.lower.mir.instructions.get(mir_index);
switch (mir_inst.tag) {
else => unreachable,
.pseudo => switch (mir_inst.ops) {
else => unreachable,
.pseudo_dbg_prologue_end => {
switch (emit.debug_output) {
.dwarf => |dw| {
try dw.setPrologueEnd();
log.debug("mirDbgPrologueEnd (line={d}, col={d})", .{
emit.prev_di_line, emit.prev_di_column,
});
try emit.dbgAdvancePCAndLine(emit.prev_di_line, emit.prev_di_column);
},
.plan9 => {},
.none => {},
}
},
.pseudo_dbg_line_column => try emit.dbgAdvancePCAndLine(
mir_inst.data.pseudo_dbg_line_column.line,
mir_inst.data.pseudo_dbg_line_column.column,
),
.pseudo_dbg_epilogue_begin => {
switch (emit.debug_output) {
.dwarf => |dw| {
try dw.setEpilogueBegin();
log.debug("mirDbgEpilogueBegin (line={d}, col={d})", .{
emit.prev_di_line, emit.prev_di_column,
});
try emit.dbgAdvancePCAndLine(emit.prev_di_line, emit.prev_di_column);
},
.plan9 => {},
.none => {},
}
},
.pseudo_dead => {},
.pseudo_dbg_prologue_end => {
switch (emit.debug_output) {
.dwarf => |dw| {
try dw.setPrologueEnd();
log.debug("mirDbgPrologueEnd (line={d}, col={d})", .{
emit.prev_di_line, emit.prev_di_column,
});
try emit.dbgAdvancePCAndLine(emit.prev_di_line, emit.prev_di_column);
},
.plan9 => {},
.none => {},
}
},
.pseudo_dbg_line_column => try emit.dbgAdvancePCAndLine(
mir_inst.data.pseudo_dbg_line_column.line,
mir_inst.data.pseudo_dbg_line_column.column,
),
.pseudo_dbg_epilogue_begin => {
switch (emit.debug_output) {
.dwarf => |dw| {
try dw.setEpilogueBegin();
log.debug("mirDbgEpilogueBegin (line={d}, col={d})", .{
emit.prev_di_line, emit.prev_di_column,
});
try emit.dbgAdvancePCAndLine(emit.prev_di_line, emit.prev_di_column);
},
.plan9 => {},
.none => {},
}
},
.pseudo_dead => {},
}
}
}
@ -151,8 +172,8 @@ const Reloc = struct {
target: Mir.Inst.Index,
/// Offset of the relocation within the instruction.
offset: u32,
/// Encoding of the instruction, used to determine how to modify it.
enc: Encoding.InstEnc,
/// Format of the instruction, used to determine how to modify it.
fmt: encoding.Lir.Format,
};
fn fixupRelocs(emit: *Emit) Error!void {
@ -164,12 +185,10 @@ fn fixupRelocs(emit: *Emit) Error!void {
const disp = @as(i32, @intCast(target)) - @as(i32, @intCast(reloc.source));
const code: *[4]u8 = emit.code.items[reloc.source + reloc.offset ..][0..4];
log.debug("disp: {x}", .{disp});
switch (reloc.enc) {
switch (reloc.fmt) {
.J => riscv_util.writeInstJ(code, @bitCast(disp)),
.B => riscv_util.writeInstB(code, @bitCast(disp)),
else => return emit.fail("tried to reloc encoding type {s}", .{@tagName(reloc.enc)}),
else => return emit.fail("tried to reloc format type {s}", .{@tagName(reloc.fmt)}),
}
}
}
@ -209,5 +228,5 @@ const Emit = @This();
const Lower = @import("Lower.zig");
const Mir = @import("Mir.zig");
const riscv_util = @import("../../link/riscv.zig");
const Encoding = @import("Encoding.zig");
const Elf = @import("../../link/Elf.zig");
const encoding = @import("encoding.zig");

File diff suppressed because it is too large Load Diff

View File

@ -34,6 +34,8 @@ pub const Reloc = struct {
/// Relocs the lowered_inst_index and the next instruction.
load_symbol_reloc: bits.Symbol,
/// Relocs the lowered_inst_index and the next two instructions.
load_tlv_reloc: bits.Symbol,
/// Relocs the lowered_inst_index and the next instruction.
call_extern_fn_reloc: bits.Symbol,
};
@ -61,453 +63,418 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index, options: struct {
log.debug("lowerMir {}", .{inst});
switch (inst.tag) {
else => try lower.generic(inst),
.pseudo => switch (inst.ops) {
.pseudo_dbg_line_column,
.pseudo_dbg_epilogue_begin,
.pseudo_dbg_prologue_end,
.pseudo_dead,
=> {},
.pseudo_dbg_line_column,
.pseudo_dbg_epilogue_begin,
.pseudo_dbg_prologue_end,
.pseudo_dead,
=> {},
.pseudo_load_rm, .pseudo_store_rm => {
const rm = inst.data.rm;
.pseudo_load_rm, .pseudo_store_rm => {
const rm = inst.data.rm;
const frame_loc: Mir.FrameLoc = if (options.allow_frame_locs)
rm.m.toFrameLoc(lower.mir)
else
.{ .base = .s0, .disp = 0 };
const frame_loc: Mir.FrameLoc = if (options.allow_frame_locs)
rm.m.toFrameLoc(lower.mir)
else
.{ .base = .s0, .disp = 0 };
switch (inst.ops) {
.pseudo_load_rm => {
const dest_reg = rm.r;
const dest_reg_class = dest_reg.class();
switch (inst.tag) {
.pseudo_load_rm => {
const dest_reg = rm.r;
const dest_reg_class = dest_reg.class();
const src_size = rm.m.mod.size;
const unsigned = rm.m.mod.unsigned;
const src_size = rm.m.mod.size;
const unsigned = rm.m.mod.unsigned;
const tag: Encoding.Mnemonic = switch (dest_reg_class) {
.int => switch (src_size) {
.byte => if (unsigned) .lbu else .lb,
.hword => if (unsigned) .lhu else .lh,
.word => if (unsigned) .lwu else .lw,
.dword => .ld,
},
.float => switch (src_size) {
.byte => unreachable, // Zig does not support 8-bit floats
.hword => return lower.fail("TODO: lowerMir pseudo_load_rm support 16-bit floats", .{}),
.word => .flw,
.dword => .fld,
},
.vector => switch (src_size) {
.byte => .vle8v,
.hword => .vle32v,
.word => .vle32v,
.dword => .vle64v,
},
};
switch (dest_reg_class) {
.int, .float => {
try lower.emit(tag, &.{
.{ .reg = rm.r },
.{ .reg = frame_loc.base },
.{ .imm = Immediate.s(frame_loc.disp) },
});
},
.vector => {
assert(frame_loc.disp == 0);
try lower.emit(tag, &.{
.{ .reg = rm.r },
.{ .reg = frame_loc.base },
.{ .reg = .zero },
});
},
}
},
.pseudo_store_rm => {
const src_reg = rm.r;
const src_reg_class = src_reg.class();
const dest_size = rm.m.mod.size;
const tag: Encoding.Mnemonic = switch (src_reg_class) {
.int => switch (dest_size) {
.byte => .sb,
.hword => .sh,
.word => .sw,
.dword => .sd,
},
.float => switch (dest_size) {
.byte => unreachable, // Zig does not support 8-bit floats
.hword => return lower.fail("TODO: lowerMir pseudo_store_rm support 16-bit floats", .{}),
.word => .fsw,
.dword => .fsd,
},
.vector => switch (dest_size) {
.byte => .vse8v,
.hword => .vse16v,
.word => .vse32v,
.dword => .vse64v,
},
};
switch (src_reg_class) {
.int, .float => {
try lower.emit(tag, &.{
.{ .reg = frame_loc.base },
.{ .reg = rm.r },
.{ .imm = Immediate.s(frame_loc.disp) },
});
},
.vector => {
assert(frame_loc.disp == 0);
try lower.emit(tag, &.{
.{ .reg = rm.r },
.{ .reg = frame_loc.base },
.{ .reg = .zero },
});
},
}
},
else => unreachable,
}
},
.pseudo_mv => {
const rr = inst.data.rr;
const dst_class = rr.rd.class();
const src_class = rr.rs.class();
switch (src_class) {
.float => switch (dst_class) {
.float => {
try lower.emit(if (lower.hasFeature(.d)) .fsgnjnd else .fsgnjns, &.{
.{ .reg = rr.rd },
.{ .reg = rr.rs },
.{ .reg = rr.rs },
});
const mnem: Mnemonic = switch (dest_reg_class) {
.int => switch (src_size) {
.byte => if (unsigned) .lbu else .lb,
.hword => if (unsigned) .lhu else .lh,
.word => if (unsigned) .lwu else .lw,
.dword => .ld,
},
.int, .vector => return lower.fail("TODO: lowerMir pseudo_mv float -> {s}", .{@tagName(dst_class)}),
},
.int => switch (dst_class) {
.int => {
try lower.emit(.addi, &.{
.{ .reg = rr.rd },
.{ .reg = rr.rs },
.{ .imm = Immediate.s(0) },
.float => switch (src_size) {
.byte => unreachable, // Zig does not support 8-bit floats
.hword => return lower.fail("TODO: lowerMir pseudo_load_rm support 16-bit floats", .{}),
.word => .flw,
.dword => .fld,
},
.vector => switch (src_size) {
.byte => .vle8v,
.hword => .vle32v,
.word => .vle32v,
.dword => .vle64v,
},
};
switch (dest_reg_class) {
.int, .float => {
try lower.emit(mnem, &.{
.{ .reg = rm.r },
.{ .reg = frame_loc.base },
.{ .imm = Immediate.s(frame_loc.disp) },
});
},
.vector => {
try lower.emit(.vmvvx, &.{
.{ .reg = rr.rd },
.{ .reg = rr.rs },
.{ .reg = .x0 },
});
},
.float => return lower.fail("TODO: lowerMir pseudo_mv int -> {s}", .{@tagName(dst_class)}),
},
.vector => switch (dst_class) {
.int => {
try lower.emit(.vadcvv, &.{
.{ .reg = rr.rd },
assert(frame_loc.disp == 0);
try lower.emit(mnem, &.{
.{ .reg = rm.r },
.{ .reg = frame_loc.base },
.{ .reg = .zero },
.{ .reg = rr.rs },
});
},
.float, .vector => return lower.fail("TODO: lowerMir pseudo_mv vector -> {s}", .{@tagName(dst_class)}),
},
}
},
}
},
.pseudo_store_rm => {
const src_reg = rm.r;
const src_reg_class = src_reg.class();
.pseudo_j => {
try lower.emit(.jal, &.{
.{ .reg = .zero },
.{ .imm = lower.reloc(.{ .inst = inst.data.inst }) },
});
},
const dest_size = rm.m.mod.size;
.pseudo_spill_regs => try lower.pushPopRegList(true, inst.data.reg_list),
.pseudo_restore_regs => try lower.pushPopRegList(false, inst.data.reg_list),
.pseudo_load_symbol => {
const payload = inst.data.payload;
const data = lower.mir.extraData(Mir.LoadSymbolPayload, payload).data;
const dst_reg: bits.Register = @enumFromInt(data.register);
assert(dst_reg.class() == .int);
try lower.emit(.lui, &.{
.{ .reg = dst_reg },
.{ .imm = lower.reloc(.{
.load_symbol_reloc = .{
.atom_index = data.atom_index,
.sym_index = data.sym_index,
const mnem: Mnemonic = switch (src_reg_class) {
.int => switch (dest_size) {
.byte => .sb,
.hword => .sh,
.word => .sw,
.dword => .sd,
},
}) },
});
.float => switch (dest_size) {
.byte => unreachable, // Zig does not support 8-bit floats
.hword => return lower.fail("TODO: lowerMir pseudo_store_rm support 16-bit floats", .{}),
.word => .fsw,
.dword => .fsd,
},
.vector => switch (dest_size) {
.byte => .vse8v,
.hword => .vse16v,
.word => .vse32v,
.dword => .vse64v,
},
};
// the above reloc implies this one
try lower.emit(.addi, &.{
.{ .reg = dst_reg },
.{ .reg = dst_reg },
.{ .imm = Immediate.s(0) },
});
},
.pseudo_lea_rm => {
const rm = inst.data.rm;
assert(rm.r.class() == .int);
const frame: Mir.FrameLoc = if (options.allow_frame_locs)
rm.m.toFrameLoc(lower.mir)
else
.{ .base = .s0, .disp = 0 };
try lower.emit(.addi, &.{
.{ .reg = rm.r },
.{ .reg = frame.base },
.{ .imm = Immediate.s(frame.disp) },
});
},
.pseudo_fabs => {
const fabs = inst.data.fabs;
assert(fabs.rs.class() == .float and fabs.rd.class() == .float);
const mnem: Encoding.Mnemonic = switch (fabs.bits) {
16 => return lower.fail("TODO: airAbs Float 16", .{}),
32 => .fsgnjxs,
64 => .fsgnjxd,
80 => return lower.fail("TODO: airAbs Float 80", .{}),
128 => return lower.fail("TODO: airAbs Float 128", .{}),
else => unreachable,
};
try lower.emit(mnem, &.{
.{ .reg = fabs.rs },
.{ .reg = fabs.rd },
.{ .reg = fabs.rd },
});
},
.pseudo_compare => {
const compare = inst.data.compare;
const op = compare.op;
const rd = compare.rd;
const rs1 = compare.rs1;
const rs2 = compare.rs2;
const class = rs1.class();
const ty = compare.ty;
const size = std.math.ceilPowerOfTwo(u64, ty.bitSize(pt)) catch {
return lower.fail("pseudo_compare size {}", .{ty.bitSize(pt)});
};
const is_unsigned = ty.isUnsignedInt(pt.zcu);
const less_than: Encoding.Mnemonic = if (is_unsigned) .sltu else .slt;
switch (class) {
.int => switch (op) {
.eq => {
try lower.emit(.xor, &.{
.{ .reg = rd },
.{ .reg = rs1 },
.{ .reg = rs2 },
});
try lower.emit(.sltiu, &.{
.{ .reg = rd },
.{ .reg = rd },
.{ .imm = Immediate.s(1) },
switch (src_reg_class) {
.int, .float => {
try lower.emit(mnem, &.{
.{ .reg = frame_loc.base },
.{ .reg = rm.r },
.{ .imm = Immediate.s(frame_loc.disp) },
});
},
.neq => {
try lower.emit(.xor, &.{
.{ .reg = rd },
.{ .reg = rs1 },
.{ .reg = rs2 },
});
try lower.emit(.sltu, &.{
.{ .reg = rd },
.vector => {
assert(frame_loc.disp == 0);
try lower.emit(mnem, &.{
.{ .reg = rm.r },
.{ .reg = frame_loc.base },
.{ .reg = .zero },
.{ .reg = rd },
});
},
.gt => {
try lower.emit(less_than, &.{
.{ .reg = rd },
.{ .reg = rs1 },
.{ .reg = rs2 },
});
},
.gte => {
try lower.emit(less_than, &.{
.{ .reg = rd },
.{ .reg = rs1 },
.{ .reg = rs2 },
});
}
},
else => unreachable,
}
},
try lower.emit(.xori, &.{
.{ .reg = rd },
.{ .reg = rd },
.{ .imm = Immediate.s(1) },
});
},
.lt => {
try lower.emit(less_than, &.{
.{ .reg = rd },
.{ .reg = rs1 },
.{ .reg = rs2 },
});
},
.lte => {
try lower.emit(less_than, &.{
.{ .reg = rd },
.{ .reg = rs2 },
.{ .reg = rs1 },
});
.pseudo_mv => {
const rr = inst.data.rr;
try lower.emit(.xori, &.{
.{ .reg = rd },
.{ .reg = rd },
.{ .imm = Immediate.s(1) },
});
},
const dst_class = rr.rd.class();
const src_class = rr.rs.class();
switch (src_class) {
.float => switch (dst_class) {
.float => {
try lower.emit(if (lower.hasFeature(.d)) .fsgnjnd else .fsgnjns, &.{
.{ .reg = rr.rd },
.{ .reg = rr.rs },
.{ .reg = rr.rs },
});
},
.float => switch (op) {
// eq
.eq => {
try lower.emit(if (size == 64) .feqd else .feqs, &.{
.{ .reg = rd },
.{ .reg = rs1 },
.{ .reg = rs2 },
});
},
// !(eq)
.neq => {
try lower.emit(if (size == 64) .feqd else .feqs, &.{
.{ .reg = rd },
.{ .reg = rs1 },
.{ .reg = rs2 },
});
try lower.emit(.xori, &.{
.{ .reg = rd },
.{ .reg = rd },
.{ .imm = Immediate.s(1) },
});
},
.lt => {
try lower.emit(if (size == 64) .fltd else .flts, &.{
.{ .reg = rd },
.{ .reg = rs1 },
.{ .reg = rs2 },
});
},
.lte => {
try lower.emit(if (size == 64) .fled else .fles, &.{
.{ .reg = rd },
.{ .reg = rs1 },
.{ .reg = rs2 },
});
},
.gt => {
try lower.emit(if (size == 64) .fltd else .flts, &.{
.{ .reg = rd },
.{ .reg = rs2 },
.{ .reg = rs1 },
});
},
.gte => {
try lower.emit(if (size == 64) .fled else .fles, &.{
.{ .reg = rd },
.{ .reg = rs2 },
.{ .reg = rs1 },
});
},
.int, .vector => return lower.fail("TODO: lowerMir pseudo_mv float -> {s}", .{@tagName(dst_class)}),
},
.int => switch (dst_class) {
.int => {
try lower.emit(.addi, &.{
.{ .reg = rr.rd },
.{ .reg = rr.rs },
.{ .imm = Immediate.s(0) },
});
},
.vector => return lower.fail("TODO: lowerMir pseudo_cmp vector", .{}),
}
},
.vector => {
try lower.emit(.vmvvx, &.{
.{ .reg = rr.rd },
.{ .reg = rr.rs },
.{ .reg = .x0 },
});
},
.float => return lower.fail("TODO: lowerMir pseudo_mv int -> {s}", .{@tagName(dst_class)}),
},
.vector => switch (dst_class) {
.int => {
try lower.emit(.vadcvv, &.{
.{ .reg = rr.rd },
.{ .reg = .zero },
.{ .reg = rr.rs },
});
},
.float, .vector => return lower.fail("TODO: lowerMir pseudo_mv vector -> {s}", .{@tagName(dst_class)}),
},
}
},
.pseudo_not => {
const rr = inst.data.rr;
assert(rr.rs.class() == .int and rr.rd.class() == .int);
.pseudo_j => {
const j_type = inst.data.j_type;
try lower.emit(.jal, &.{
.{ .reg = j_type.rd },
.{ .imm = lower.reloc(.{ .inst = j_type.inst }) },
});
},
// mask out any other bits that aren't the boolean
try lower.emit(.andi, &.{
.{ .reg = rr.rs },
.{ .reg = rr.rs },
.{ .imm = Immediate.s(1) },
});
.pseudo_spill_regs => try lower.pushPopRegList(true, inst.data.reg_list),
.pseudo_restore_regs => try lower.pushPopRegList(false, inst.data.reg_list),
try lower.emit(.sltiu, &.{
.{ .reg = rr.rd },
.{ .reg = rr.rs },
.{ .imm = Immediate.s(1) },
});
},
.pseudo_load_symbol => {
const payload = inst.data.reloc;
const dst_reg = payload.register;
assert(dst_reg.class() == .int);
.pseudo_extern_fn_reloc => {
const inst_reloc = inst.data.reloc;
try lower.emit(.lui, &.{
.{ .reg = dst_reg },
.{ .imm = lower.reloc(.{
.load_symbol_reloc = .{
.atom_index = payload.atom_index,
.sym_index = payload.sym_index,
},
}) },
});
try lower.emit(.auipc, &.{
.{ .reg = .ra },
.{ .imm = lower.reloc(
.{ .call_extern_fn_reloc = .{
.atom_index = inst_reloc.atom_index,
.sym_index = inst_reloc.sym_index,
} },
) },
});
// the reloc above implies this one
try lower.emit(.addi, &.{
.{ .reg = dst_reg },
.{ .reg = dst_reg },
.{ .imm = Immediate.s(0) },
});
},
try lower.emit(.jalr, &.{
.{ .reg = .ra },
.{ .reg = .ra },
.{ .imm = Immediate.s(0) },
});
},
.pseudo_load_tlv => {
const payload = inst.data.reloc;
const dst_reg = payload.register;
assert(dst_reg.class() == .int);
.pseudo_amo => {
const amo = inst.data.amo;
const is_d = amo.ty.abiSize(pt) == 8;
const is_un = amo.ty.isUnsignedInt(pt.zcu);
try lower.emit(.lui, &.{
.{ .reg = dst_reg },
.{ .imm = lower.reloc(.{
.load_tlv_reloc = .{
.atom_index = payload.atom_index,
.sym_index = payload.sym_index,
},
}) },
});
const mnem: Encoding.Mnemonic = switch (amo.op) {
// zig fmt: off
.SWAP => if (is_d) .amoswapd else .amoswapw,
.ADD => if (is_d) .amoaddd else .amoaddw,
.AND => if (is_d) .amoandd else .amoandw,
.OR => if (is_d) .amoord else .amoorw,
.XOR => if (is_d) .amoxord else .amoxorw,
.MAX => if (is_d) if (is_un) .amomaxud else .amomaxd else if (is_un) .amomaxuw else .amomaxw,
.MIN => if (is_d) if (is_un) .amominud else .amomind else if (is_un) .amominuw else .amominw,
// zig fmt: on
};
try lower.emit(.add, &.{
.{ .reg = dst_reg },
.{ .reg = dst_reg },
.{ .reg = .tp },
});
try lower.emit(mnem, &.{
.{ .reg = inst.data.amo.rd },
.{ .reg = inst.data.amo.rs1 },
.{ .reg = inst.data.amo.rs2 },
.{ .barrier = inst.data.amo.rl },
.{ .barrier = inst.data.amo.aq },
});
},
try lower.emit(.addi, &.{
.{ .reg = dst_reg },
.{ .reg = dst_reg },
.{ .imm = Immediate.s(0) },
});
},
.pseudo_fence => {
const fence = inst.data.fence;
.pseudo_lea_rm => {
const rm = inst.data.rm;
assert(rm.r.class() == .int);
try lower.emit(switch (fence.fm) {
.tso => .fencetso,
.none => .fence,
}, &.{
.{ .barrier = fence.succ },
.{ .barrier = fence.pred },
});
},
const frame: Mir.FrameLoc = if (options.allow_frame_locs)
rm.m.toFrameLoc(lower.mir)
else
.{ .base = .s0, .disp = 0 };
else => return lower.fail("TODO lower: psuedo {s}", .{@tagName(inst.ops)}),
try lower.emit(.addi, &.{
.{ .reg = rm.r },
.{ .reg = frame.base },
.{ .imm = Immediate.s(frame.disp) },
});
},
.pseudo_compare => {
const compare = inst.data.compare;
const op = compare.op;
const rd = compare.rd;
const rs1 = compare.rs1;
const rs2 = compare.rs2;
const class = rs1.class();
const ty = compare.ty;
const size = std.math.ceilPowerOfTwo(u64, ty.bitSize(pt)) catch {
return lower.fail("pseudo_compare size {}", .{ty.bitSize(pt)});
};
const is_unsigned = ty.isUnsignedInt(pt.zcu);
const less_than: Mnemonic = if (is_unsigned) .sltu else .slt;
switch (class) {
.int => switch (op) {
.eq => {
try lower.emit(.xor, &.{
.{ .reg = rd },
.{ .reg = rs1 },
.{ .reg = rs2 },
});
try lower.emit(.sltiu, &.{
.{ .reg = rd },
.{ .reg = rd },
.{ .imm = Immediate.s(1) },
});
},
.neq => {
try lower.emit(.xor, &.{
.{ .reg = rd },
.{ .reg = rs1 },
.{ .reg = rs2 },
});
try lower.emit(.sltu, &.{
.{ .reg = rd },
.{ .reg = .zero },
.{ .reg = rd },
});
},
.gt => {
try lower.emit(less_than, &.{
.{ .reg = rd },
.{ .reg = rs2 },
.{ .reg = rs1 },
});
},
.gte => {
try lower.emit(less_than, &.{
.{ .reg = rd },
.{ .reg = rs1 },
.{ .reg = rs2 },
});
try lower.emit(.xori, &.{
.{ .reg = rd },
.{ .reg = rd },
.{ .imm = Immediate.s(1) },
});
},
.lt => {
try lower.emit(less_than, &.{
.{ .reg = rd },
.{ .reg = rs1 },
.{ .reg = rs2 },
});
},
.lte => {
try lower.emit(less_than, &.{
.{ .reg = rd },
.{ .reg = rs2 },
.{ .reg = rs1 },
});
try lower.emit(.xori, &.{
.{ .reg = rd },
.{ .reg = rd },
.{ .imm = Immediate.s(1) },
});
},
},
.float => switch (op) {
// eq
.eq => {
try lower.emit(if (size == 64) .feqd else .feqs, &.{
.{ .reg = rd },
.{ .reg = rs1 },
.{ .reg = rs2 },
});
},
// !(eq)
.neq => {
try lower.emit(if (size == 64) .feqd else .feqs, &.{
.{ .reg = rd },
.{ .reg = rs1 },
.{ .reg = rs2 },
});
try lower.emit(.xori, &.{
.{ .reg = rd },
.{ .reg = rd },
.{ .imm = Immediate.s(1) },
});
},
.lt => {
try lower.emit(if (size == 64) .fltd else .flts, &.{
.{ .reg = rd },
.{ .reg = rs1 },
.{ .reg = rs2 },
});
},
.lte => {
try lower.emit(if (size == 64) .fled else .fles, &.{
.{ .reg = rd },
.{ .reg = rs1 },
.{ .reg = rs2 },
});
},
.gt => {
try lower.emit(if (size == 64) .fltd else .flts, &.{
.{ .reg = rd },
.{ .reg = rs2 },
.{ .reg = rs1 },
});
},
.gte => {
try lower.emit(if (size == 64) .fled else .fles, &.{
.{ .reg = rd },
.{ .reg = rs2 },
.{ .reg = rs1 },
});
},
},
.vector => return lower.fail("TODO: lowerMir pseudo_cmp vector", .{}),
}
},
.pseudo_not => {
const rr = inst.data.rr;
assert(rr.rs.class() == .int and rr.rd.class() == .int);
// mask out any other bits that aren't the boolean
try lower.emit(.andi, &.{
.{ .reg = rr.rs },
.{ .reg = rr.rs },
.{ .imm = Immediate.s(1) },
});
try lower.emit(.sltiu, &.{
.{ .reg = rr.rd },
.{ .reg = rr.rs },
.{ .imm = Immediate.s(1) },
});
},
.pseudo_extern_fn_reloc => {
const inst_reloc = inst.data.reloc;
const link_reg = inst_reloc.register;
try lower.emit(.auipc, &.{
.{ .reg = link_reg },
.{ .imm = lower.reloc(
.{ .call_extern_fn_reloc = .{
.atom_index = inst_reloc.atom_index,
.sym_index = inst_reloc.sym_index,
} },
) },
});
try lower.emit(.jalr, &.{
.{ .reg = link_reg },
.{ .reg = link_reg },
.{ .imm = Immediate.s(0) },
});
},
}
@ -518,49 +485,57 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index, options: struct {
}
fn generic(lower: *Lower, inst: Mir.Inst) Error!void {
const mnemonic = std.meta.stringToEnum(Encoding.Mnemonic, @tagName(inst.tag)) orelse {
return lower.fail("generic inst name '{s}' with op {s} doesn't match with a mnemonic", .{
@tagName(inst.tag),
@tagName(inst.ops),
});
};
try lower.emit(mnemonic, switch (inst.ops) {
const mnemonic = inst.tag;
try lower.emit(mnemonic, switch (inst.data) {
.none => &.{},
.ri => &.{
.{ .reg = inst.data.u_type.rd },
.{ .imm = inst.data.u_type.imm20 },
.u_type => |u| &.{
.{ .reg = u.rd },
.{ .imm = u.imm20 },
},
.rr => &.{
.{ .reg = inst.data.rr.rd },
.{ .reg = inst.data.rr.rs },
.i_type => |i| &.{
.{ .reg = i.rd },
.{ .reg = i.rs1 },
.{ .imm = i.imm12 },
},
.rri => &.{
.{ .reg = inst.data.i_type.rd },
.{ .reg = inst.data.i_type.rs1 },
.{ .imm = inst.data.i_type.imm12 },
.rr => |rr| &.{
.{ .reg = rr.rd },
.{ .reg = rr.rs },
},
.rr_inst => &.{
.{ .reg = inst.data.b_type.rs1 },
.{ .reg = inst.data.b_type.rs2 },
.{ .imm = lower.reloc(.{ .inst = inst.data.b_type.inst }) },
.b_type => |b| &.{
.{ .reg = b.rs1 },
.{ .reg = b.rs2 },
.{ .imm = lower.reloc(.{ .inst = b.inst }) },
},
.rrr => &.{
.{ .reg = inst.data.r_type.rd },
.{ .reg = inst.data.r_type.rs1 },
.{ .reg = inst.data.r_type.rs2 },
.r_type => |r| &.{
.{ .reg = r.rd },
.{ .reg = r.rs1 },
.{ .reg = r.rs2 },
},
.csr => &.{
.{ .csr = inst.data.csr.csr },
.{ .reg = inst.data.csr.rs1 },
.{ .reg = inst.data.csr.rd },
.csr => |csr| &.{
.{ .csr = csr.csr },
.{ .reg = csr.rs1 },
.{ .reg = csr.rd },
},
else => return lower.fail("TODO: generic lower ops {s}", .{@tagName(inst.ops)}),
.amo => |amo| &.{
.{ .reg = amo.rd },
.{ .reg = amo.rs1 },
.{ .reg = amo.rs2 },
.{ .barrier = amo.rl },
.{ .barrier = amo.aq },
},
.fence => |fence| &.{
.{ .barrier = fence.succ },
.{ .barrier = fence.pred },
},
else => return lower.fail("TODO: generic lower {s}", .{@tagName(inst.data)}),
});
}
fn emit(lower: *Lower, mnemonic: Encoding.Mnemonic, ops: []const Instruction.Operand) !void {
lower.result_insts[lower.result_insts_len] =
try Instruction.new(mnemonic, ops);
fn emit(lower: *Lower, mnemonic: Mnemonic, ops: []const Instruction.Operand) !void {
const lir = encoding.Lir.fromMnem(mnemonic);
const inst = Instruction.fromLir(lir, ops);
lower.result_insts[lower.result_insts_len] = inst;
lower.result_insts_len += 1;
}
@ -582,7 +557,7 @@ fn pushPopRegList(lower: *Lower, comptime spilling: bool, reg_list: Mir.Register
const reg = abi.Registers.all_preserved[i];
const reg_class = reg.class();
const load_inst: Encoding.Mnemonic, const store_inst: Encoding.Mnemonic = switch (reg_class) {
const load_inst: Mnemonic, const store_inst: Mnemonic = switch (reg_class) {
.int => .{ .ld, .sd },
.float => .{ .fld, .fsd },
.vector => unreachable,
@ -620,20 +595,22 @@ fn hasFeature(lower: *Lower, feature: std.Target.riscv.Feature) bool {
}
const Lower = @This();
const abi = @import("abi.zig");
const assert = std.debug.assert;
const bits = @import("bits.zig");
const encoder = @import("encoder.zig");
const link = @import("../../link.zig");
const Encoding = @import("Encoding.zig");
const std = @import("std");
const assert = std.debug.assert;
const log = std.log.scoped(.lower);
const Air = @import("../../Air.zig");
const Allocator = std.mem.Allocator;
const ErrorMsg = Zcu.ErrorMsg;
const Mir = @import("Mir.zig");
const link = @import("../../link.zig");
const Air = @import("../../Air.zig");
const Zcu = @import("../../Zcu.zig");
const Instruction = encoder.Instruction;
const Mir = @import("Mir.zig");
const abi = @import("abi.zig");
const bits = @import("bits.zig");
const encoding = @import("encoding.zig");
const Mnemonic = @import("mnem.zig").Mnemonic;
const Immediate = bits.Immediate;
const Instruction = encoding.Instruction;

View File

@ -1,164 +1,17 @@
//! Machine Intermediate Representation.
//! This data is produced by RISCV64 Codegen or RISCV64 assembly parsing
//! These instructions have a 1:1 correspondence with machine code instructions
//! for the target. MIR can be lowered to source-annotated textual assembly code
//! instructions, or it can be lowered to machine code.
//! The main purpose of MIR is to postpone the assignment of offsets until Isel,
//! so that, for example, the smaller encodings of jump instructions can be used.
//! This data is produced by CodeGen.zig
instructions: std.MultiArrayList(Inst).Slice,
/// The meaning of this data is determined by `Inst.Tag` value.
extra: []const u32,
frame_locs: std.MultiArrayList(FrameLoc).Slice,
pub const Inst = struct {
tag: Tag,
tag: Mnemonic,
data: Data,
ops: Ops,
/// The position of an MIR instruction within the `Mir` instructions array.
pub const Index = u32;
pub const Tag = enum(u16) {
// base extension
addi,
addiw,
jalr,
lui,
@"and",
andi,
xori,
xor,
@"or",
ebreak,
ecall,
unimp,
add,
addw,
sub,
subw,
sltu,
slt,
slli,
srli,
srai,
slliw,
srliw,
sraiw,
sll,
srl,
sra,
sllw,
srlw,
sraw,
jal,
beq,
bne,
nop,
ld,
lw,
lh,
lb,
sd,
sw,
sh,
sb,
// M extension
mul,
mulw,
div,
divu,
divw,
divuw,
rem,
remu,
remw,
remuw,
// F extension (32-bit float)
fadds,
fsubs,
fmuls,
fdivs,
fabss,
fmins,
fmaxs,
fsqrts,
flw,
fsw,
feqs,
flts,
fles,
// D extension (64-bit float)
faddd,
fsubd,
fmuld,
fdivd,
fabsd,
fmind,
fmaxd,
fsqrtd,
fld,
fsd,
feqd,
fltd,
fled,
// Zicsr Extension Instructions
csrrs,
// V Extension Instructions
vsetvli,
vsetivli,
vsetvl,
vaddvv,
vfaddvv,
vsubvv,
vfsubvv,
vslidedownvx,
/// A pseudo-instruction. Used for anything that isn't 1:1 with an
/// assembly instruction.
pseudo,
};
/// All instructions have a 4-byte payload, which is contained within
/// this union. `Ops` determines which union field is active, as well as
/// how to interpret the data within.
pub const Data = union {
nop: void,
inst: Index,
payload: u32,
pub const Data = union(enum) {
none: void,
r_type: struct {
rd: Register,
rs1: Register,
@ -188,10 +41,6 @@ pub const Inst = struct {
rd: Register,
inst: Inst.Index,
},
pseudo_dbg_line_column: struct {
line: u32,
column: u32,
},
rm: struct {
r: Register,
m: Memory,
@ -202,11 +51,6 @@ pub const Inst = struct {
rd: Register,
rs: Register,
},
fabs: struct {
rd: Register,
rs: Register,
bits: u16,
},
compare: struct {
rd: Register,
rs1: Register,
@ -222,16 +66,13 @@ pub const Inst = struct {
ty: Type,
},
reloc: struct {
register: Register,
atom_index: u32,
sym_index: u32,
},
fence: struct {
pred: Barrier,
succ: Barrier,
fm: enum {
none,
tso,
},
},
amo: struct {
rd: Register,
@ -239,123 +80,32 @@ pub const Inst = struct {
rs2: Register,
aq: Barrier,
rl: Barrier,
op: AmoOp,
ty: Type,
},
csr: struct {
csr: CSR,
rs1: Register,
rd: Register,
},
};
pub const Ops = enum {
/// No data associated with this instruction (only mnemonic is used).
none,
/// Two registers
rr,
/// Three registers
rrr,
/// Two registers + immediate, uses the i_type payload.
rri,
//extern_fn_reloc/ Two registers + another instruction.
rr_inst,
/// Register + Memory
rm,
/// Register + Immediate
ri,
/// Another instruction.
inst,
/// Control and Status Register Instruction.
csr,
/// Pseudo-instruction that will generate a backpatched
/// function prologue.
pseudo_prologue,
/// Pseudo-instruction that will generate a backpatched
/// function epilogue
pseudo_epilogue,
/// Pseudo-instruction: End of prologue
pseudo_dbg_prologue_end,
/// Pseudo-instruction: Beginning of epilogue
pseudo_dbg_epilogue_begin,
/// Pseudo-instruction: Update debug line
pseudo_dbg_line_column,
/// Pseudo-instruction that loads from memory into a register.
///
/// Uses `rm` payload.
pseudo_load_rm,
/// Pseudo-instruction that stores from a register into memory
///
/// Uses `rm` payload.
pseudo_store_rm,
/// Pseudo-instruction that loads the address of memory into a register.
///
/// Uses `rm` payload.
pseudo_lea_rm,
/// Jumps. Uses `inst` payload.
pseudo_j,
/// Floating point absolute value.
pseudo_fabs,
/// Dead inst, ignored by the emitter.
pseudo_dead,
/// Loads the address of a value that hasn't yet been allocated in memory.
///
/// uses the Mir.LoadSymbolPayload payload.
pseudo_load_symbol,
/// Moves the value of rs1 to rd.
///
/// uses the `rr` payload.
pseudo_mv,
pseudo_restore_regs,
pseudo_spill_regs,
pseudo_compare,
/// NOT operation on booleans. Does an `andi reg, reg, 1` to mask out any other bits from the boolean.
pseudo_not,
/// Generates an auipc + jalr pair, with a R_RISCV_CALL_PLT reloc
pseudo_extern_fn_reloc,
/// IORW, IORW
pseudo_fence,
/// Ordering, Src, Addr, Dest
pseudo_amo,
pseudo_dbg_line_column: struct {
line: u32,
column: u32,
},
};
pub fn format(
inst: Inst,
comptime fmt: []const u8,
options: std.fmt.FormatOptions,
_: std.fmt.FormatOptions,
writer: anytype,
) !void {
assert(fmt.len == 0);
_ = options;
try writer.print("Tag: {s}, Ops: {s}", .{ @tagName(inst.tag), @tagName(inst.ops) });
try writer.print("Tag: {s}, Data: {s}", .{ @tagName(inst.tag), @tagName(inst.data) });
}
};
pub fn deinit(mir: *Mir, gpa: std.mem.Allocator) void {
mir.instructions.deinit(gpa);
mir.frame_locs.deinit(gpa);
gpa.free(mir.extra);
mir.* = undefined;
}
@ -386,25 +136,12 @@ pub const AmoOp = enum(u5) {
MIN,
};
/// Returns the requested data, as well as the new index which is at the start of the
/// trailers for the object.
pub fn extraData(mir: Mir, comptime T: type, index: usize) struct { data: T, end: usize } {
const fields = std.meta.fields(T);
var i: usize = index;
var result: T = undefined;
inline for (fields) |field| {
@field(result, field.name) = switch (field.type) {
u32 => mir.extra[i],
i32 => @as(i32, @bitCast(mir.extra[i])),
else => @compileError("bad field type"),
};
i += 1;
}
return .{
.data = result,
.end = i,
};
}
pub const FcvtOp = enum(u5) {
w = 0b00000,
wu = 0b00001,
l = 0b00010,
lu = 0b00011,
};
pub const LoadSymbolPayload = struct {
register: u32,
@ -453,10 +190,10 @@ const Mir = @This();
const std = @import("std");
const builtin = @import("builtin");
const Type = @import("../../Type.zig");
const bits = @import("bits.zig");
const assert = std.debug.assert;
const bits = @import("bits.zig");
const Register = bits.Register;
const CSR = bits.CSR;
const Immediate = bits.Immediate;
@ -464,3 +201,4 @@ const Memory = bits.Memory;
const FrameIndex = bits.FrameIndex;
const FrameAddr = @import("CodeGen.zig").FrameAddr;
const IntegerBitSet = std.bit_set.IntegerBitSet;
const Mnemonic = @import("mnem.zig").Mnemonic;

View File

@ -125,10 +125,7 @@ pub fn classifySystem(ty: Type, pt: Zcu.PerThread) [8]SystemClass {
result[0] = .integer;
return result;
}
result[0] = .integer;
if (ty.optionalChild(zcu).abiSize(pt) == 0) return result;
result[1] = .integer;
return result;
return memory_class;
},
.Int, .Enum, .ErrorSet => {
const int_bits = ty.intInfo(pt.zcu).bits;
@ -167,7 +164,7 @@ pub fn classifySystem(ty: Type, pt: Zcu.PerThread) [8]SystemClass {
return memory_class;
},
.Struct => {
.Struct, .Union => {
const layout = ty.containerLayout(pt.zcu);
const ty_size = ty.abiSize(pt);
@ -200,6 +197,8 @@ pub fn classifySystem(ty: Type, pt: Zcu.PerThread) [8]SystemClass {
result[0] = .integer;
return result;
}
// we should pass vector registers of size <= 128 through 2 integer registers
// but we haven't implemented seperating vector registers into register_pairs
return memory_class;
},
else => |bad_ty| std.debug.panic("classifySystem {s}", .{@tagName(bad_ty)}),

View File

@ -5,7 +5,6 @@ const testing = std.testing;
const Target = std.Target;
const Zcu = @import("../../Zcu.zig");
const Encoding = @import("Encoding.zig");
const Mir = @import("Mir.zig");
const abi = @import("abi.zig");
@ -16,7 +15,6 @@ pub const Memory = struct {
pub const Base = union(enum) {
reg: Register,
frame: FrameIndex,
reloc: Symbol,
};
pub const Mod = struct {
@ -83,7 +81,6 @@ pub const Memory = struct {
.disp = base_loc.disp + offset,
};
},
.reloc => unreachable,
}
}
};
@ -193,7 +190,7 @@ pub const Register = enum(u8) {
/// The goal of this function is to return the same ID for `zero` and `x0` but two
/// seperate IDs for `x0` and `f0`. We will assume that each register set has 32 registers
/// and is repeated twice, once for the named version, once for the number version.
pub fn id(reg: Register) u8 {
pub fn id(reg: Register) std.math.IntFittingRange(0, @typeInfo(Register).Enum.fields.len) {
const base = switch (@intFromEnum(reg)) {
// zig fmt: off
@intFromEnum(Register.zero) ... @intFromEnum(Register.x31) => @intFromEnum(Register.zero),
@ -251,8 +248,7 @@ pub const FrameIndex = enum(u32) {
/// This index referes to a frame dedicated to setting up args for function called
/// in this function. Useful for aligning args separately.
call_frame,
/// This index referes to the frame where callee saved registers are spilled and restore
/// from.
/// This index referes to the frame where callee saved registers are spilled and restored from.
spill_frame,
/// Other indices are used for local variable stack slots
_,

View File

@ -1,80 +0,0 @@
pub const Instruction = struct {
encoding: Encoding,
ops: [5]Operand = .{.none} ** 5,
pub const Operand = union(enum) {
none,
reg: Register,
csr: CSR,
mem: Memory,
imm: Immediate,
barrier: Mir.Barrier,
};
pub fn new(mnemonic: Encoding.Mnemonic, ops: []const Operand) !Instruction {
const encoding = (try Encoding.findByMnemonic(mnemonic, ops)) orelse {
std.log.err("no encoding found for: {s} [{s} {s} {s} {s} {s}]", .{
@tagName(mnemonic),
@tagName(if (ops.len > 0) ops[0] else .none),
@tagName(if (ops.len > 1) ops[1] else .none),
@tagName(if (ops.len > 2) ops[2] else .none),
@tagName(if (ops.len > 3) ops[3] else .none),
@tagName(if (ops.len > 4) ops[4] else .none),
});
return error.InvalidInstruction;
};
var result_ops: [5]Operand = .{.none} ** 5;
@memcpy(result_ops[0..ops.len], ops);
return .{
.encoding = encoding,
.ops = result_ops,
};
}
pub fn encode(inst: Instruction, writer: anytype) !void {
try writer.writeInt(u32, inst.encoding.data.toU32(), .little);
}
pub fn format(
inst: Instruction,
comptime fmt: []const u8,
_: std.fmt.FormatOptions,
writer: anytype,
) !void {
std.debug.assert(fmt.len == 0);
const encoding = inst.encoding;
try writer.print("{s} ", .{@tagName(encoding.mnemonic)});
var i: u32 = 0;
while (i < inst.ops.len and inst.ops[i] != .none) : (i += 1) {
if (i != inst.ops.len and i != 0) try writer.writeAll(", ");
switch (@as(Instruction.Operand, inst.ops[i])) {
.none => unreachable, // it's sliced out above
.reg => |reg| try writer.writeAll(@tagName(reg)),
.imm => |imm| try writer.print("{d}", .{imm.asSigned(64)}),
.mem => try writer.writeAll("mem"),
.barrier => |barrier| try writer.writeAll(@tagName(barrier)),
.csr => |csr| try writer.writeAll(@tagName(csr)),
}
}
}
};
const std = @import("std");
const Lower = @import("Lower.zig");
const Mir = @import("Mir.zig");
const bits = @import("bits.zig");
const Encoding = @import("Encoding.zig");
const Register = bits.Register;
const CSR = bits.CSR;
const Memory = bits.Memory;
const Immediate = bits.Immediate;
const log = std.log.scoped(.encode);

View File

@ -0,0 +1,729 @@
//! This file is responsible for going from MIR, which is emitted by CodeGen
//! and converting it into Instructions, which can be used as needed.
//!
//! Here we encode how mnemonics relate to opcodes and where their operands go.
/// Lower Instruction Representation
///
/// This format encodes a specific instruction, however it's still abstracted
/// away from the true encoding it'll be in. It's meant to make the process of
/// indicating unique encoding data easier.
pub const Lir = struct {
opcode: OpCode,
format: Format,
data: Data,
pub const Format = enum {
R,
I,
S,
B,
U,
J,
extra,
};
const Data = union(enum) {
none,
f: struct { funct3: u3 },
ff: struct {
funct3: u3,
funct7: u7,
},
sh: struct {
typ: u6,
funct3: u3,
has_5: bool,
},
fmt: struct {
funct5: u5,
rm: u3,
fmt: FpFmt,
},
fcvt: struct {
funct5: u5,
rm: u3,
fmt: FpFmt,
width: Mir.FcvtOp,
},
vecls: struct {
width: VecWidth,
umop: Umop,
vm: bool,
mop: Mop,
mew: bool,
nf: u3,
},
vecmath: struct {
vm: bool,
funct6: u6,
funct3: VecType,
},
amo: struct {
funct5: u5,
width: AmoWidth,
},
fence: struct {
funct3: u3,
fm: FenceMode,
},
/// the mnemonic has some special properities that can't be handled in a generic fashion
extra: Mnemonic,
};
const OpCode = enum(u7) {
LOAD = 0b0000011,
LOAD_FP = 0b0000111,
MISC_MEM = 0b0001111,
OP_IMM = 0b0010011,
AUIPC = 0b0010111,
OP_IMM_32 = 0b0011011,
STORE = 0b0100011,
STORE_FP = 0b0100111,
AMO = 0b0101111,
OP_V = 0b1010111,
OP = 0b0110011,
OP_32 = 0b0111011,
LUI = 0b0110111,
MADD = 0b1000011,
MSUB = 0b1000111,
NMSUB = 0b1001011,
NMADD = 0b1001111,
OP_FP = 0b1010011,
OP_IMM_64 = 0b1011011,
BRANCH = 0b1100011,
JALR = 0b1100111,
JAL = 0b1101111,
SYSTEM = 0b1110011,
OP_64 = 0b1111011,
NONE = 0b00000000,
};
const FpFmt = enum(u2) {
/// 32-bit single-precision
S = 0b00,
/// 64-bit double-precision
D = 0b01,
// H = 0b10, unused in the G extension
/// 128-bit quad-precision
Q = 0b11,
};
const AmoWidth = enum(u3) {
W = 0b010,
D = 0b011,
};
const FenceMode = enum(u4) {
none = 0b0000,
tso = 0b1000,
};
const Mop = enum(u2) {
// zig fmt: off
unit = 0b00,
unord = 0b01,
stride = 0b10,
ord = 0b11,
// zig fmt: on
};
const Umop = enum(u5) {
// zig fmt: off
unit = 0b00000,
whole = 0b01000,
mask = 0b01011,
fault = 0b10000,
// zig fmt: on
};
const VecWidth = enum(u3) {
// zig fmt: off
@"8" = 0b000,
@"16" = 0b101,
@"32" = 0b110,
@"64" = 0b111,
// zig fmt: on
};
const VecType = enum(u3) {
OPIVV = 0b000,
OPFVV = 0b001,
OPMVV = 0b010,
OPIVI = 0b011,
OPIVX = 0b100,
OPFVF = 0b101,
OPMVX = 0b110,
};
pub fn fromMnem(mnem: Mnemonic) Lir {
return switch (mnem) {
// zig fmt: off
// OP
.add => .{ .opcode = .OP, .format = .R, .data = .{ .ff = .{ .funct3 = 0b000, .funct7 = 0b0000000 } } },
.sub => .{ .opcode = .OP, .format = .R, .data = .{ .ff = .{ .funct3 = 0b000, .funct7 = 0b0100000 } } },
.@"and" => .{ .opcode = .OP, .format = .R, .data = .{ .ff = .{ .funct3 = 0b111, .funct7 = 0b0000000 } } },
.@"or" => .{ .opcode = .OP, .format = .R, .data = .{ .ff = .{ .funct3 = 0b110, .funct7 = 0b0000000 } } },
.xor => .{ .opcode = .OP, .format = .R, .data = .{ .ff = .{ .funct3 = 0b100, .funct7 = 0b0000000 } } },
.sltu => .{ .opcode = .OP, .format = .R, .data = .{ .ff = .{ .funct3 = 0b011, .funct7 = 0b0000000 } } },
.slt => .{ .opcode = .OP, .format = .R, .data = .{ .ff = .{ .funct3 = 0b010, .funct7 = 0b0000000 } } },
.mul => .{ .opcode = .OP, .format = .R, .data = .{ .ff = .{ .funct3 = 0b000, .funct7 = 0b0000001 } } },
.mulh => .{ .opcode = .OP, .format = .R, .data = .{ .ff = .{ .funct3 = 0b001, .funct7 = 0b0000001 } } },
.mulhsu => .{ .opcode = .OP, .format = .R, .data = .{ .ff = .{ .funct3 = 0b010, .funct7 = 0b0000001 } } },
.mulhu => .{ .opcode = .OP, .format = .R, .data = .{ .ff = .{ .funct3 = 0b011, .funct7 = 0b0000001 } } },
.div => .{ .opcode = .OP, .format = .R, .data = .{ .ff = .{ .funct3 = 0b100, .funct7 = 0b0000001 } } },
.divu => .{ .opcode = .OP, .format = .R, .data = .{ .ff = .{ .funct3 = 0b101, .funct7 = 0b0000001 } } },
.rem => .{ .opcode = .OP, .format = .R, .data = .{ .ff = .{ .funct3 = 0b110, .funct7 = 0b0000001 } } },
.remu => .{ .opcode = .OP, .format = .R, .data = .{ .ff = .{ .funct3 = 0b111, .funct7 = 0b0000001 } } },
.sll => .{ .opcode = .OP, .format = .R, .data = .{ .ff = .{ .funct3 = 0b001, .funct7 = 0b0000000 } } },
.srl => .{ .opcode = .OP, .format = .R, .data = .{ .ff = .{ .funct3 = 0b101, .funct7 = 0b0000000 } } },
.sra => .{ .opcode = .OP, .format = .R, .data = .{ .ff = .{ .funct3 = 0b101, .funct7 = 0b0100000 } } },
// OP_IMM
.addi => .{ .opcode = .OP_IMM, .format = .I, .data = .{ .f = .{ .funct3 = 0b000 } } },
.andi => .{ .opcode = .OP_IMM, .format = .I, .data = .{ .f = .{ .funct3 = 0b111 } } },
.xori => .{ .opcode = .OP_IMM, .format = .I, .data = .{ .f = .{ .funct3 = 0b100 } } },
.sltiu => .{ .opcode = .OP_IMM, .format = .I, .data = .{ .f = .{ .funct3 = 0b011 } } },
.slli => .{ .opcode = .OP_IMM, .format = .I, .data = .{ .sh = .{ .typ = 0b000000, .funct3 = 0b001, .has_5 = true } } },
.srli => .{ .opcode = .OP_IMM, .format = .I, .data = .{ .sh = .{ .typ = 0b000000, .funct3 = 0b101, .has_5 = true } } },
.srai => .{ .opcode = .OP_IMM, .format = .I, .data = .{ .sh = .{ .typ = 0b010000, .funct3 = 0b101, .has_5 = true } } },
.clz => .{ .opcode = .OP_IMM, .format = .R, .data = .{ .ff = .{ .funct3 = 0b001, .funct7 = 0b0110000 } } },
.cpop => .{ .opcode = .OP_IMM, .format = .R, .data = .{ .ff = .{ .funct3 = 0b001, .funct7 = 0b0110000 } } },
// OP_IMM_32
.slliw => .{ .opcode = .OP_IMM_32, .format = .I, .data = .{ .sh = .{ .typ = 0b000000, .funct3 = 0b001, .has_5 = false } } },
.srliw => .{ .opcode = .OP_IMM_32, .format = .I, .data = .{ .sh = .{ .typ = 0b000000, .funct3 = 0b101, .has_5 = false } } },
.sraiw => .{ .opcode = .OP_IMM_32, .format = .I, .data = .{ .sh = .{ .typ = 0b010000, .funct3 = 0b101, .has_5 = false } } },
.clzw => .{ .opcode = .OP_IMM_32, .format = .R, .data = .{ .ff = .{ .funct3 = 0b001, .funct7 = 0b0110000 } } },
.cpopw => .{ .opcode = .OP_IMM_32, .format = .R, .data = .{ .ff = .{ .funct3 = 0b001, .funct7 = 0b0110000 } } },
// OP_32
.addw => .{ .opcode = .OP_32, .format = .R, .data = .{ .ff = .{ .funct3 = 0b000, .funct7 = 0b0000000 } } },
.subw => .{ .opcode = .OP_32, .format = .R, .data = .{ .ff = .{ .funct3 = 0b000, .funct7 = 0b0100000 } } },
.mulw => .{ .opcode = .OP_32, .format = .R, .data = .{ .ff = .{ .funct3 = 0b000, .funct7 = 0b0000001 } } },
.divw => .{ .opcode = .OP_32, .format = .R, .data = .{ .ff = .{ .funct3 = 0b100, .funct7 = 0b0000001 } } },
.divuw => .{ .opcode = .OP_32, .format = .R, .data = .{ .ff = .{ .funct3 = 0b101, .funct7 = 0b0000001 } } },
.remw => .{ .opcode = .OP_32, .format = .R, .data = .{ .ff = .{ .funct3 = 0b110, .funct7 = 0b0000001 } } },
.remuw => .{ .opcode = .OP_32, .format = .R, .data = .{ .ff = .{ .funct3 = 0b111, .funct7 = 0b0000001 } } },
.sllw => .{ .opcode = .OP_32, .format = .R, .data = .{ .ff = .{ .funct3 = 0b001, .funct7 = 0b0000000 } } },
.srlw => .{ .opcode = .OP_32, .format = .R, .data = .{ .ff = .{ .funct3 = 0b101, .funct7 = 0b0000000 } } },
.sraw => .{ .opcode = .OP_32, .format = .R, .data = .{ .ff = .{ .funct3 = 0b101, .funct7 = 0b0100000 } } },
// OP_FP
.fadds => .{ .opcode = .OP_FP, .format = .R, .data = .{ .fmt = .{ .funct5 = 0b00000, .fmt = .S, .rm = 0b111 } } },
.faddd => .{ .opcode = .OP_FP, .format = .R, .data = .{ .fmt = .{ .funct5 = 0b00000, .fmt = .D, .rm = 0b111 } } },
.fsubs => .{ .opcode = .OP_FP, .format = .R, .data = .{ .fmt = .{ .funct5 = 0b00001, .fmt = .S, .rm = 0b111 } } },
.fsubd => .{ .opcode = .OP_FP, .format = .R, .data = .{ .fmt = .{ .funct5 = 0b00001, .fmt = .D, .rm = 0b111 } } },
.fmuls => .{ .opcode = .OP_FP, .format = .R, .data = .{ .fmt = .{ .funct5 = 0b00010, .fmt = .S, .rm = 0b111 } } },
.fmuld => .{ .opcode = .OP_FP, .format = .R, .data = .{ .fmt = .{ .funct5 = 0b00010, .fmt = .D, .rm = 0b111 } } },
.fdivs => .{ .opcode = .OP_FP, .format = .R, .data = .{ .fmt = .{ .funct5 = 0b00011, .fmt = .S, .rm = 0b111 } } },
.fdivd => .{ .opcode = .OP_FP, .format = .R, .data = .{ .fmt = .{ .funct5 = 0b00011, .fmt = .D, .rm = 0b111 } } },
.fmins => .{ .opcode = .OP_FP, .format = .R, .data = .{ .fmt = .{ .funct5 = 0b00101, .fmt = .S, .rm = 0b000 } } },
.fmind => .{ .opcode = .OP_FP, .format = .R, .data = .{ .fmt = .{ .funct5 = 0b00101, .fmt = .D, .rm = 0b000 } } },
.fmaxs => .{ .opcode = .OP_FP, .format = .R, .data = .{ .fmt = .{ .funct5 = 0b00101, .fmt = .S, .rm = 0b001 } } },
.fmaxd => .{ .opcode = .OP_FP, .format = .R, .data = .{ .fmt = .{ .funct5 = 0b00101, .fmt = .D, .rm = 0b001 } } },
.fsqrts => .{ .opcode = .OP_FP, .format = .R, .data = .{ .fmt = .{ .funct5 = 0b01011, .fmt = .S, .rm = 0b111 } } },
.fsqrtd => .{ .opcode = .OP_FP, .format = .R, .data = .{ .fmt = .{ .funct5 = 0b01011, .fmt = .D, .rm = 0b111 } } },
.fles => .{ .opcode = .OP_FP, .format = .R, .data = .{ .fmt = .{ .funct5 = 0b10100, .fmt = .S, .rm = 0b000 } } },
.fled => .{ .opcode = .OP_FP, .format = .R, .data = .{ .fmt = .{ .funct5 = 0b10100, .fmt = .D, .rm = 0b000 } } },
.flts => .{ .opcode = .OP_FP, .format = .R, .data = .{ .fmt = .{ .funct5 = 0b10100, .fmt = .S, .rm = 0b001 } } },
.fltd => .{ .opcode = .OP_FP, .format = .R, .data = .{ .fmt = .{ .funct5 = 0b10100, .fmt = .D, .rm = 0b001 } } },
.feqs => .{ .opcode = .OP_FP, .format = .R, .data = .{ .fmt = .{ .funct5 = 0b10100, .fmt = .S, .rm = 0b010 } } },
.feqd => .{ .opcode = .OP_FP, .format = .R, .data = .{ .fmt = .{ .funct5 = 0b10100, .fmt = .D, .rm = 0b010 } } },
.fsgnjns => .{ .opcode = .OP_FP, .format = .R, .data = .{ .fmt = .{ .funct5 = 0b00100, .fmt = .S, .rm = 0b000 } } },
.fsgnjnd => .{ .opcode = .OP_FP, .format = .R, .data = .{ .fmt = .{ .funct5 = 0b00100, .fmt = .D, .rm = 0b000 } } },
.fsgnjxs => .{ .opcode = .OP_FP, .format = .R, .data = .{ .fmt = .{ .funct5 = 0b00100, .fmt = .S, .rm = 0b010 } } },
.fsgnjxd => .{ .opcode = .OP_FP, .format = .R, .data = .{ .fmt = .{ .funct5 = 0b00100, .fmt = .D, .rm = 0b010 } } },
.fcvtws => .{ .opcode = .OP_FP, .format = .R, .data = .{ .fcvt = .{ .funct5 = 0b11000, .fmt = .S, .rm = 0b111, .width = .w } } },
.fcvtwus => .{ .opcode = .OP_FP, .format = .R, .data = .{ .fcvt = .{ .funct5 = 0b11000, .fmt = .S, .rm = 0b111, .width = .wu } } },
.fcvtls => .{ .opcode = .OP_FP, .format = .R, .data = .{ .fcvt = .{ .funct5 = 0b11000, .fmt = .S, .rm = 0b111, .width = .l } } },
.fcvtlus => .{ .opcode = .OP_FP, .format = .R, .data = .{ .fcvt = .{ .funct5 = 0b11000, .fmt = .S, .rm = 0b111, .width = .lu } } },
.fcvtwd => .{ .opcode = .OP_FP, .format = .R, .data = .{ .fcvt = .{ .funct5 = 0b11000, .fmt = .D, .rm = 0b111, .width = .w } } },
.fcvtwud => .{ .opcode = .OP_FP, .format = .R, .data = .{ .fcvt = .{ .funct5 = 0b11000, .fmt = .D, .rm = 0b111, .width = .wu } } },
.fcvtld => .{ .opcode = .OP_FP, .format = .R, .data = .{ .fcvt = .{ .funct5 = 0b11000, .fmt = .D, .rm = 0b111, .width = .l } } },
.fcvtlud => .{ .opcode = .OP_FP, .format = .R, .data = .{ .fcvt = .{ .funct5 = 0b11000, .fmt = .D, .rm = 0b111, .width = .lu } } },
.fcvtsw => .{ .opcode = .OP_FP, .format = .R, .data = .{ .fcvt = .{ .funct5 = 0b11010, .fmt = .S, .rm = 0b111, .width = .w } } },
.fcvtswu => .{ .opcode = .OP_FP, .format = .R, .data = .{ .fcvt = .{ .funct5 = 0b11010, .fmt = .S, .rm = 0b111, .width = .wu } } },
.fcvtsl => .{ .opcode = .OP_FP, .format = .R, .data = .{ .fcvt = .{ .funct5 = 0b11010, .fmt = .S, .rm = 0b111, .width = .l } } },
.fcvtslu => .{ .opcode = .OP_FP, .format = .R, .data = .{ .fcvt = .{ .funct5 = 0b11010, .fmt = .S, .rm = 0b111, .width = .lu } } },
.fcvtdw => .{ .opcode = .OP_FP, .format = .R, .data = .{ .fcvt = .{ .funct5 = 0b11010, .fmt = .D, .rm = 0b111, .width = .w } } },
.fcvtdwu => .{ .opcode = .OP_FP, .format = .R, .data = .{ .fcvt = .{ .funct5 = 0b11010, .fmt = .D, .rm = 0b111, .width = .wu } } },
.fcvtdl => .{ .opcode = .OP_FP, .format = .R, .data = .{ .fcvt = .{ .funct5 = 0b11010, .fmt = .D, .rm = 0b111, .width = .l } } },
.fcvtdlu => .{ .opcode = .OP_FP, .format = .R, .data = .{ .fcvt = .{ .funct5 = 0b11010, .fmt = .D, .rm = 0b111, .width = .lu } } },
// LOAD
.lb => .{ .opcode = .LOAD, .format = .I, .data = .{ .f = .{ .funct3 = 0b000 } } },
.lh => .{ .opcode = .LOAD, .format = .I, .data = .{ .f = .{ .funct3 = 0b001 } } },
.lw => .{ .opcode = .LOAD, .format = .I, .data = .{ .f = .{ .funct3 = 0b010 } } },
.ld => .{ .opcode = .LOAD, .format = .I, .data = .{ .f = .{ .funct3 = 0b011 } } },
.lbu => .{ .opcode = .LOAD, .format = .I, .data = .{ .f = .{ .funct3 = 0b100 } } },
.lhu => .{ .opcode = .LOAD, .format = .I, .data = .{ .f = .{ .funct3 = 0b101 } } },
.lwu => .{ .opcode = .LOAD, .format = .I, .data = .{ .f = .{ .funct3 = 0b110 } } },
// STORE
.sb => .{ .opcode = .STORE, .format = .S, .data = .{ .f = .{ .funct3 = 0b000 } } },
.sh => .{ .opcode = .STORE, .format = .S, .data = .{ .f = .{ .funct3 = 0b001 } } },
.sw => .{ .opcode = .STORE, .format = .S, .data = .{ .f = .{ .funct3 = 0b010 } } },
.sd => .{ .opcode = .STORE, .format = .S, .data = .{ .f = .{ .funct3 = 0b011 } } },
// LOAD_FP
.flw => .{ .opcode = .LOAD_FP, .format = .I, .data = .{ .f = .{ .funct3 = 0b010 } } },
.fld => .{ .opcode = .LOAD_FP, .format = .I, .data = .{ .f = .{ .funct3 = 0b011 } } },
.vle8v => .{ .opcode = .LOAD_FP, .format = .R, .data = .{ .vecls = .{ .width = .@"8", .umop = .unit, .vm = true, .mop = .unit, .mew = false, .nf = 0b000 } } },
.vle16v => .{ .opcode = .LOAD_FP, .format = .R, .data = .{ .vecls = .{ .width = .@"16", .umop = .unit, .vm = true, .mop = .unit, .mew = false, .nf = 0b000 } } },
.vle32v => .{ .opcode = .LOAD_FP, .format = .R, .data = .{ .vecls = .{ .width = .@"32", .umop = .unit, .vm = true, .mop = .unit, .mew = false, .nf = 0b000 } } },
.vle64v => .{ .opcode = .LOAD_FP, .format = .R, .data = .{ .vecls = .{ .width = .@"64", .umop = .unit, .vm = true, .mop = .unit, .mew = false, .nf = 0b000 } } },
// STORE_FP
.fsw => .{ .opcode = .STORE_FP, .format = .S, .data = .{ .f = .{ .funct3 = 0b010 } } },
.fsd => .{ .opcode = .STORE_FP, .format = .S, .data = .{ .f = .{ .funct3 = 0b011 } } },
.vse8v => .{ .opcode = .STORE_FP, .format = .R, .data = .{ .vecls = .{ .width = .@"8", .umop = .unit, .vm = true, .mop = .unit, .mew = false, .nf = 0b000 } } },
.vse16v => .{ .opcode = .STORE_FP, .format = .R, .data = .{ .vecls = .{ .width = .@"16", .umop = .unit, .vm = true, .mop = .unit, .mew = false, .nf = 0b000 } } },
.vse32v => .{ .opcode = .STORE_FP, .format = .R, .data = .{ .vecls = .{ .width = .@"32", .umop = .unit, .vm = true, .mop = .unit, .mew = false, .nf = 0b000 } } },
.vse64v => .{ .opcode = .STORE_FP, .format = .R, .data = .{ .vecls = .{ .width = .@"64", .umop = .unit, .vm = true, .mop = .unit, .mew = false, .nf = 0b000 } } },
// JALR
.jalr => .{ .opcode = .JALR, .format = .I, .data = .{ .f = .{ .funct3 = 0b000 } } },
// LUI
.lui => .{ .opcode = .LUI, .format = .U, .data = .{ .none = {} } },
// AUIPC
.auipc => .{ .opcode = .AUIPC, .format = .U, .data = .{ .none = {} } },
// JAL
.jal => .{ .opcode = .JAL, .format = .J, .data = .{ .none = {} } },
// BRANCH
.beq => .{ .opcode = .BRANCH, .format = .B, .data = .{ .f = .{ .funct3 = 0b000 } } },
.bne => .{ .opcode = .BRANCH, .format = .B, .data = .{ .f = .{ .funct3 = 0b001 } } },
// SYSTEM
.ecall => .{ .opcode = .SYSTEM, .format = .extra, .data = .{ .extra = .ecall } },
.ebreak => .{ .opcode = .SYSTEM, .format = .extra, .data = .{ .extra = .ebreak } },
.csrrs => .{ .opcode = .SYSTEM, .format = .I, .data = .{ .f = .{ .funct3 = 0b010 } } },
// NONE
.unimp => .{ .opcode = .NONE, .format = .extra, .data = .{ .extra = .unimp } },
// MISC_MEM
.fence => .{ .opcode = .MISC_MEM, .format = .I, .data = .{ .fence = .{ .funct3 = 0b000, .fm = .none } } },
.fencetso => .{ .opcode = .MISC_MEM, .format = .I, .data = .{ .fence = .{ .funct3 = 0b000, .fm = .tso } } },
// AMO
.amoaddw => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .W, .funct5 = 0b00000 } } },
.amoswapw => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .W, .funct5 = 0b00001 } } },
.lrw => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .W, .funct5 = 0b00010 } } },
.scw => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .W, .funct5 = 0b00011 } } },
.amoxorw => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .W, .funct5 = 0b00100 } } },
.amoandw => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .W, .funct5 = 0b01100 } } },
.amoorw => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .W, .funct5 = 0b01000 } } },
.amominw => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .W, .funct5 = 0b10000 } } },
.amomaxw => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .W, .funct5 = 0b10100 } } },
.amominuw => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .W, .funct5 = 0b11000 } } },
.amomaxuw => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .W, .funct5 = 0b11100 } } },
.amoaddd => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .D, .funct5 = 0b00000 } } },
.amoswapd => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .D, .funct5 = 0b00001 } } },
.lrd => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .D, .funct5 = 0b00010 } } },
.scd => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .D, .funct5 = 0b00011 } } },
.amoxord => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .D, .funct5 = 0b00100 } } },
.amoandd => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .D, .funct5 = 0b01100 } } },
.amoord => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .D, .funct5 = 0b01000 } } },
.amomind => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .D, .funct5 = 0b10000 } } },
.amomaxd => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .D, .funct5 = 0b10100 } } },
.amominud => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .D, .funct5 = 0b11000 } } },
.amomaxud => .{ .opcode = .AMO, .format = .R, .data = .{ .amo = .{ .width = .D, .funct5 = 0b11100 } } },
// OP_V
.vsetivli => .{ .opcode = .OP_V, .format = .I, .data = .{ .f = .{ .funct3 = 0b111 } } },
.vsetvli => .{ .opcode = .OP_V, .format = .I, .data = .{ .f = .{ .funct3 = 0b111 } } },
.vaddvv => .{ .opcode = .OP_V, .format = .R, .data = .{ .vecmath = .{ .vm = true, .funct6 = 0b000000, .funct3 = .OPIVV } } },
.vsubvv => .{ .opcode = .OP_V, .format = .R, .data = .{ .vecmath = .{ .vm = true, .funct6 = 0b000010, .funct3 = .OPIVV } } },
.vmulvv => .{ .opcode = .OP_V, .format = .R, .data = .{ .vecmath = .{ .vm = true, .funct6 = 0b100101, .funct3 = .OPIVV } } },
.vfaddvv => .{ .opcode = .OP_V, .format = .R, .data = .{ .vecmath = .{ .vm = true, .funct6 = 0b000000, .funct3 = .OPFVV } } },
.vfsubvv => .{ .opcode = .OP_V, .format = .R, .data = .{ .vecmath = .{ .vm = true, .funct6 = 0b000010, .funct3 = .OPFVV } } },
.vfmulvv => .{ .opcode = .OP_V, .format = .R, .data = .{ .vecmath = .{ .vm = true, .funct6 = 0b100100, .funct3 = .OPFVV } } },
.vadcvv => .{ .opcode = .OP_V, .format = .R, .data = .{ .vecmath = .{ .vm = true, .funct6 = 0b010000, .funct3 = .OPMVV } } },
.vmvvx => .{ .opcode = .OP_V, .format = .R, .data = .{ .vecmath = .{ .vm = true, .funct6 = 0b010111, .funct3 = .OPIVX } } },
.vslidedownvx => .{ .opcode = .OP_V, .format = .R, .data = .{ .vecmath = .{ .vm = true, .funct6 = 0b001111, .funct3 = .OPIVX } } },
.pseudo_prologue,
.pseudo_epilogue,
.pseudo_dbg_prologue_end,
.pseudo_dbg_epilogue_begin,
.pseudo_dbg_line_column,
.pseudo_load_rm,
.pseudo_store_rm,
.pseudo_lea_rm,
.pseudo_j,
.pseudo_dead,
.pseudo_load_symbol,
.pseudo_load_tlv,
.pseudo_mv,
.pseudo_restore_regs,
.pseudo_spill_regs,
.pseudo_compare,
.pseudo_not,
.pseudo_extern_fn_reloc,
.nop,
=> std.debug.panic("lir: didn't catch pseudo {s}", .{@tagName(mnem)}),
// zig fmt: on
};
}
};
/// This is the final form of the instruction. Lir is transformed into
/// this, which is then bitcast into a u32.
pub const Instruction = union(Lir.Format) {
R: packed struct(u32) {
opcode: u7,
rd: u5,
funct3: u3,
rs1: u5,
rs2: u5,
funct7: u7,
},
I: packed struct(u32) {
opcode: u7,
rd: u5,
funct3: u3,
rs1: u5,
imm0_11: u12,
},
S: packed struct(u32) {
opcode: u7,
imm0_4: u5,
funct3: u3,
rs1: u5,
rs2: u5,
imm5_11: u7,
},
B: packed struct(u32) {
opcode: u7,
imm11: u1,
imm1_4: u4,
funct3: u3,
rs1: u5,
rs2: u5,
imm5_10: u6,
imm12: u1,
},
U: packed struct(u32) {
opcode: u7,
rd: u5,
imm12_31: u20,
},
J: packed struct(u32) {
opcode: u7,
rd: u5,
imm12_19: u8,
imm11: u1,
imm1_10: u10,
imm20: u1,
},
extra: u32,
comptime {
for (std.meta.fields(Instruction)) |field| {
assert(@bitSizeOf(field.type) == 32);
}
}
pub const Operand = union(enum) {
none,
reg: Register,
csr: CSR,
mem: Memory,
imm: Immediate,
barrier: Mir.Barrier,
};
pub fn toU32(inst: Instruction) u32 {
return switch (inst) {
inline else => |v| @bitCast(v),
};
}
pub fn encode(inst: Instruction, writer: anytype) !void {
try writer.writeInt(u32, inst.toU32(), .little);
}
pub fn fromLir(lir: Lir, ops: []const Operand) Instruction {
const opcode: u7 = @intFromEnum(lir.opcode);
switch (lir.format) {
.R => {
return .{
.R = switch (lir.data) {
.ff => |ff| .{
.rd = ops[0].reg.encodeId(),
.rs1 = ops[1].reg.encodeId(),
.rs2 = ops[2].reg.encodeId(),
.opcode = opcode,
.funct3 = ff.funct3,
.funct7 = ff.funct7,
},
.fmt => |fmt| .{
.rd = ops[0].reg.encodeId(),
.rs1 = ops[1].reg.encodeId(),
.rs2 = ops[2].reg.encodeId(),
.opcode = opcode,
.funct3 = fmt.rm,
.funct7 = (@as(u7, fmt.funct5) << 2) | @intFromEnum(fmt.fmt),
},
.fcvt => |fcvt| .{
.rd = ops[0].reg.encodeId(),
.rs1 = ops[1].reg.encodeId(),
.rs2 = @intFromEnum(fcvt.width),
.opcode = opcode,
.funct3 = fcvt.rm,
.funct7 = (@as(u7, fcvt.funct5) << 2) | @intFromEnum(fcvt.fmt),
},
.vecls => |vec| .{
.rd = ops[0].reg.encodeId(),
.rs1 = ops[1].reg.encodeId(),
.rs2 = @intFromEnum(vec.umop),
.opcode = opcode,
.funct3 = @intFromEnum(vec.width),
.funct7 = (@as(u7, vec.nf) << 4) | (@as(u7, @intFromBool(vec.mew)) << 3) | (@as(u7, @intFromEnum(vec.mop)) << 1) | @intFromBool(vec.vm),
},
.vecmath => |vec| .{
.rd = ops[0].reg.encodeId(),
.rs1 = ops[1].reg.encodeId(),
.rs2 = ops[2].reg.encodeId(),
.opcode = opcode,
.funct3 = @intFromEnum(vec.funct3),
.funct7 = (@as(u7, vec.funct6) << 1) | @intFromBool(vec.vm),
},
.amo => |amo| .{
.rd = ops[0].reg.encodeId(),
.rs1 = ops[1].reg.encodeId(),
.rs2 = ops[2].reg.encodeId(),
.opcode = opcode,
.funct3 = @intFromEnum(amo.width),
.funct7 = @as(u7, amo.funct5) << 2 |
@as(u7, @intFromBool(ops[3].barrier == .rl)) << 1 |
@as(u7, @intFromBool(ops[4].barrier == .aq)),
},
else => unreachable,
},
};
},
.S => {
assert(ops.len == 3);
const umm = ops[2].imm.asBits(u12);
return .{
.S = .{
.imm0_4 = @truncate(umm),
.rs1 = ops[0].reg.encodeId(),
.rs2 = ops[1].reg.encodeId(),
.imm5_11 = @truncate(umm >> 5),
.opcode = opcode,
.funct3 = lir.data.f.funct3,
},
};
},
.I => {
return .{
.I = switch (lir.data) {
.f => |f| .{
.rd = ops[0].reg.encodeId(),
.rs1 = ops[1].reg.encodeId(),
.imm0_11 = ops[2].imm.asBits(u12),
.opcode = opcode,
.funct3 = f.funct3,
},
.sh => |sh| .{
.rd = ops[0].reg.encodeId(),
.rs1 = ops[1].reg.encodeId(),
.imm0_11 = (@as(u12, sh.typ) << 6) |
if (sh.has_5) ops[2].imm.asBits(u6) else (@as(u6, 0) | ops[2].imm.asBits(u5)),
.opcode = opcode,
.funct3 = sh.funct3,
},
.fence => |fence| .{
.rd = 0,
.rs1 = 0,
.funct3 = 0,
.imm0_11 = (@as(u12, @intFromEnum(fence.fm)) << 8) |
(@as(u12, @intFromEnum(ops[1].barrier)) << 4) |
@as(u12, @intFromEnum(ops[0].barrier)),
.opcode = opcode,
},
else => unreachable,
},
};
},
.U => {
assert(ops.len == 2);
return .{
.U = .{
.rd = ops[0].reg.encodeId(),
.imm12_31 = ops[1].imm.asBits(u20),
.opcode = opcode,
},
};
},
.J => {
assert(ops.len == 2);
const umm = ops[1].imm.asBits(u21);
// the RISC-V spec says the target index of a jump
// must be a multiple of 2
assert(umm % 2 == 0);
return .{
.J = .{
.rd = ops[0].reg.encodeId(),
.imm1_10 = @truncate(umm >> 1),
.imm11 = @truncate(umm >> 11),
.imm12_19 = @truncate(umm >> 12),
.imm20 = @truncate(umm >> 20),
.opcode = opcode,
},
};
},
.B => {
assert(ops.len == 3);
const umm = ops[2].imm.asBits(u13);
// the RISC-V spec says the target index of a branch
// must be a multiple of 2
assert(umm % 2 == 0);
return .{
.B = .{
.rs1 = ops[0].reg.encodeId(),
.rs2 = ops[1].reg.encodeId(),
.imm1_4 = @truncate(umm >> 1),
.imm5_10 = @truncate(umm >> 5),
.imm11 = @truncate(umm >> 11),
.imm12 = @truncate(umm >> 12),
.opcode = opcode,
.funct3 = lir.data.f.funct3,
},
};
},
.extra => {
assert(ops.len == 0);
return .{
.I = .{
.rd = Register.zero.encodeId(),
.rs1 = Register.zero.encodeId(),
.imm0_11 = switch (lir.data.extra) {
.ecall => 0x000,
.ebreak => 0x001,
.unimp => 0x000,
else => unreachable,
},
.opcode = opcode,
.funct3 = 0b000,
},
};
},
}
}
};
const std = @import("std");
const assert = std.debug.assert;
const log = std.log.scoped(.format);
const bits = @import("bits.zig");
const Mir = @import("Mir.zig");
const Mnemonic = @import("mnem.zig").Mnemonic;
const Lower = @import("Lower.zig");
const Register = bits.Register;
const CSR = bits.CSR;
const Memory = bits.Memory;
const Immediate = bits.Immediate;

257
src/arch/riscv64/mnem.zig Normal file
View File

@ -0,0 +1,257 @@
pub const Mnemonic = enum(u16) {
// Arithmetics
addi,
add,
addw,
sub,
subw,
// Bits
xori,
xor,
@"or",
@"and",
andi,
slt,
sltu,
sltiu,
slli,
srli,
srai,
slliw,
srliw,
sraiw,
sll,
srl,
sra,
sllw,
srlw,
sraw,
// Control Flow
jalr,
jal,
beq,
bne,
// Memory
lui,
auipc,
ld,
lw,
lh,
lb,
lbu,
lhu,
lwu,
sd,
sw,
sh,
sb,
// System
ebreak,
ecall,
unimp,
nop,
// M extension
mul,
mulh,
mulhu,
mulhsu,
mulw,
div,
divu,
divw,
divuw,
rem,
remu,
remw,
remuw,
// F extension (32-bit float)
fadds,
fsubs,
fmuls,
fdivs,
fmins,
fmaxs,
fsqrts,
flw,
fsw,
feqs,
flts,
fles,
// D extension (64-bit float)
faddd,
fsubd,
fmuld,
fdivd,
fmind,
fmaxd,
fsqrtd,
fld,
fsd,
feqd,
fltd,
fled,
fcvtws,
fcvtwus,
fcvtls,
fcvtlus,
fcvtwd,
fcvtwud,
fcvtld,
fcvtlud,
fcvtsw,
fcvtswu,
fcvtsl,
fcvtslu,
fcvtdw,
fcvtdwu,
fcvtdl,
fcvtdlu,
fsgnjns,
fsgnjnd,
fsgnjxs,
fsgnjxd,
// Zicsr Extension Instructions
csrrs,
// V Extension Instructions
vsetvli,
vsetivli,
vaddvv,
vfaddvv,
vsubvv,
vfsubvv,
vmulvv,
vfmulvv,
vslidedownvx,
vle8v,
vle16v,
vle32v,
vle64v,
vse8v,
vse16v,
vse32v,
vse64v,
vadcvv,
vmvvx,
// Zbb Extension Instructions
clz,
clzw,
cpop,
cpopw,
// A Extension Instructions
fence,
fencetso,
lrw,
scw,
amoswapw,
amoaddw,
amoandw,
amoorw,
amoxorw,
amomaxw,
amominw,
amomaxuw,
amominuw,
lrd,
scd,
amoswapd,
amoaddd,
amoandd,
amoord,
amoxord,
amomaxd,
amomind,
amomaxud,
amominud,
// Pseudo-instructions. Used for anything that isn't 1:1 with an
// assembly instruction.
/// Pseudo-instruction that will generate a backpatched
/// function prologue.
pseudo_prologue,
/// Pseudo-instruction that will generate a backpatched
/// function epilogue
pseudo_epilogue,
/// Pseudo-instruction: End of prologue
pseudo_dbg_prologue_end,
/// Pseudo-instruction: Beginning of epilogue
pseudo_dbg_epilogue_begin,
/// Pseudo-instruction: Update debug line
pseudo_dbg_line_column,
/// Pseudo-instruction that loads from memory into a register.
pseudo_load_rm,
/// Pseudo-instruction that stores from a register into memory
pseudo_store_rm,
/// Pseudo-instruction that loads the address of memory into a register.
pseudo_lea_rm,
/// Jumps. Uses `inst` payload.
pseudo_j,
/// Dead inst, ignored by the emitter.
pseudo_dead,
/// Loads the address of a value that hasn't yet been allocated in memory.
pseudo_load_symbol,
/// Loads the address of a TLV.
pseudo_load_tlv,
/// Moves the value of rs1 to rd.
pseudo_mv,
pseudo_restore_regs,
pseudo_spill_regs,
pseudo_compare,
pseudo_not,
pseudo_extern_fn_reloc,
};
pub const Pseudo = enum(u8) {
li,
mv,
tail,
beqz,
ret,
};

View File

@ -106,7 +106,9 @@ pub fn generateLazyFunction(
const target = namespace.fileScope(zcu).mod.resolved_target.result;
switch (target_util.zigBackend(target, false)) {
else => unreachable,
inline .stage2_x86_64 => |backend| {
inline .stage2_x86_64,
.stage2_riscv64,
=> |backend| {
dev.check(devFeatureForBackend(backend));
return importBackend(backend).generateLazy(lf, pt, src_loc, lazy_sym, code, debug_output);
},

View File

@ -25,47 +25,27 @@ pub fn writeAddend(
}
pub fn writeInstU(code: *[4]u8, value: u32) void {
var data = Encoding.Data{
.U = mem.bytesToValue(std.meta.TagPayload(
Encoding.Data,
Encoding.Data.U,
), code),
};
var data: Instruction = .{ .U = mem.bytesToValue(std.meta.TagPayload(Instruction, .U), code) };
const compensated: u32 = @bitCast(@as(i32, @bitCast(value)) + 0x800);
data.U.imm12_31 = bitSlice(compensated, 31, 12);
mem.writeInt(u32, code, data.toU32(), .little);
}
pub fn writeInstI(code: *[4]u8, value: u32) void {
var data = Encoding.Data{
.I = mem.bytesToValue(std.meta.TagPayload(
Encoding.Data,
Encoding.Data.I,
), code),
};
var data: Instruction = .{ .I = mem.bytesToValue(std.meta.TagPayload(Instruction, .I), code) };
data.I.imm0_11 = bitSlice(value, 11, 0);
mem.writeInt(u32, code, data.toU32(), .little);
}
pub fn writeInstS(code: *[4]u8, value: u32) void {
var data = Encoding.Data{
.S = mem.bytesToValue(std.meta.TagPayload(
Encoding.Data,
Encoding.Data.S,
), code),
};
var data: Instruction = .{ .S = mem.bytesToValue(std.meta.TagPayload(Instruction, .S), code) };
data.S.imm0_4 = bitSlice(value, 4, 0);
data.S.imm5_11 = bitSlice(value, 11, 5);
mem.writeInt(u32, code, data.toU32(), .little);
}
pub fn writeInstJ(code: *[4]u8, value: u32) void {
var data = Encoding.Data{
.J = mem.bytesToValue(std.meta.TagPayload(
Encoding.Data,
Encoding.Data.J,
), code),
};
var data: Instruction = .{ .J = mem.bytesToValue(std.meta.TagPayload(Instruction, .J), code) };
data.J.imm1_10 = bitSlice(value, 10, 1);
data.J.imm11 = bitSlice(value, 11, 11);
data.J.imm12_19 = bitSlice(value, 19, 12);
@ -74,12 +54,7 @@ pub fn writeInstJ(code: *[4]u8, value: u32) void {
}
pub fn writeInstB(code: *[4]u8, value: u32) void {
var data = Encoding.Data{
.B = mem.bytesToValue(std.meta.TagPayload(
Encoding.Data,
Encoding.Data.B,
), code),
};
var data: Instruction = .{ .B = mem.bytesToValue(std.meta.TagPayload(Instruction, .B), code) };
data.B.imm1_4 = bitSlice(value, 4, 1);
data.B.imm5_10 = bitSlice(value, 10, 5);
data.B.imm11 = bitSlice(value, 11, 11);
@ -109,9 +84,8 @@ pub const RiscvEflags = packed struct(u32) {
_unused: u8,
};
const encoder = @import("../arch/riscv64/encoder.zig");
const Encoding = @import("../arch/riscv64/Encoding.zig");
const mem = std.mem;
const std = @import("std");
pub const Instruction = encoder.Instruction;
const encoding = @import("../arch/riscv64/encoding.zig");
const Instruction = encoding.Instruction;

View File

@ -6,6 +6,7 @@ test "@abs integers" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
try comptime testAbsIntegers();
try testAbsIntegers();

View File

@ -16,7 +16,6 @@ test "global variable alignment" {
}
test "large alignment of local constant" {
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // flaky
@ -26,7 +25,6 @@ test "large alignment of local constant" {
}
test "slicing array of length 1 can not assume runtime index is always zero" {
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // flaky
@ -511,7 +509,6 @@ test "read 128-bit field from default aligned struct in global memory" {
}
test "struct field explicit alignment" {
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO

View File

@ -22,7 +22,6 @@ test "arrays" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
var array: [5]u32 = undefined;
@ -160,7 +159,6 @@ test "array len field" {
test "array with sentinels" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
fn doTheTest(is_ct: bool) !void {
@ -532,7 +530,6 @@ test "sentinel element count towards the ABI size calculation" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {
@ -614,7 +611,6 @@ test "type coercion of pointer to anon struct literal to pointer to array" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
const U = union {
@ -667,7 +663,6 @@ test "array init of container level array variable" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
var pair: [2]usize = .{ 1, 2 };
@ -688,8 +683,6 @@ test "array init of container level array variable" {
}
test "runtime initialized sentinel-terminated array literal" {
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
var c: u16 = 300;
_ = &c;
const f = &[_:0x9999]u16{c};
@ -776,8 +769,6 @@ test "array init with no result pointer sets field result types" {
}
test "runtime side-effects in comptime-known array init" {
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
var side_effects: u4 = 0;
const init = [4]u4{
blk: {
@ -802,8 +793,6 @@ test "runtime side-effects in comptime-known array init" {
}
test "slice initialized through reference to anonymous array init provides result types" {
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
var my_u32: u32 = 123;
var my_u64: u64 = 456;
_ = .{ &my_u32, &my_u64 };
@ -817,8 +806,6 @@ test "slice initialized through reference to anonymous array init provides resul
}
test "sentinel-terminated slice initialized through reference to anonymous array init provides result types" {
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
var my_u32: u32 = 123;
var my_u64: u64 = 456;
_ = .{ &my_u32, &my_u64 };
@ -869,8 +856,6 @@ test "many-item sentinel-terminated pointer initialized through reference to ano
}
test "pointer to array initialized through reference to anonymous array init provides result types" {
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
var my_u32: u32 = 123;
var my_u64: u64 = 456;
_ = .{ &my_u32, &my_u64 };
@ -884,8 +869,6 @@ test "pointer to array initialized through reference to anonymous array init pro
}
test "pointer to sentinel-terminated array initialized through reference to anonymous array init provides result types" {
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
var my_u32: u32 = 123;
var my_u64: u64 = 456;
_ = .{ &my_u32, &my_u64 };
@ -912,7 +895,6 @@ test "copied array element doesn't alias source" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
var x: [10][10]u32 = undefined;
@ -925,7 +907,6 @@ test "copied array element doesn't alias source" {
test "array initialized with string literal" {
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
a: u32,
@ -993,7 +974,6 @@ test "accessing multidimensional global array at comptime" {
if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
const array = [_][]const []const u8{

View File

@ -15,7 +15,6 @@ test "cmpxchg" {
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
try testCmpxchg();
try comptime testCmpxchg();
@ -108,7 +107,6 @@ test "cmpxchg with ignored result" {
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
var x: i32 = 1234;
@ -153,7 +151,6 @@ test "cmpxchg on a global variable" {
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .aarch64) {
// https://github.com/ziglang/zig/issues/10627
@ -169,7 +166,6 @@ test "atomic load and rmw with enum" {
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const Value = enum(u8) { a, b, c };
var x = Value.a;
@ -205,7 +201,6 @@ test "atomicrmw with floats" {
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .aarch64) {
// https://github.com/ziglang/zig/issues/10627

View File

@ -16,8 +16,6 @@ test "empty function with comments" {
}
test "truncate" {
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
try expect(testTruncate(0x10fd) == 0xfd);
comptime assert(testTruncate(0x10fd) == 0xfd);
}
@ -27,7 +25,6 @@ fn testTruncate(x: u32) u8 {
test "truncate to non-power-of-two integers" {
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
try testTrunc(u32, u1, 0b10101, 0b1);
try testTrunc(u32, u1, 0b10110, 0b0);
@ -45,7 +42,6 @@ test "truncate to non-power-of-two integers from 128-bit" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
try testTrunc(u128, u1, 0xffffffff_ffffffff_ffffffff_01010101, 0x01);
try testTrunc(u128, u1, 0xffffffff_ffffffff_ffffffff_01010110, 0x00);
@ -224,7 +220,6 @@ const OpaqueB = opaque {};
test "opaque types" {
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
try expect(*OpaqueA != *OpaqueB);
@ -376,7 +371,6 @@ test "take address of parameter" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
try testTakeAddressOfParameter(12.34);
}
@ -401,7 +395,6 @@ test "array 2D const double ptr" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const rect_2d_vertexes = [_][1]f32{
[_]f32{1.0},
@ -414,7 +407,6 @@ test "array 2D const double ptr with offset" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const rect_2d_vertexes = [_][2]f32{
[_]f32{ 3.0, 4.239 },
@ -427,7 +419,6 @@ test "array 3D const double ptr with offset" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const rect_3d_vertexes = [_][2][2]f32{
[_][2]f32{
@ -622,7 +613,6 @@ var global_ptr = &gdt[0];
test "global constant is loaded with a runtime-known index" {
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {
@ -641,7 +631,6 @@ test "global constant is loaded with a runtime-known index" {
test "multiline string literal is null terminated" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const s1 =
\\one
@ -656,7 +645,6 @@ test "string escapes" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
try expectEqualStrings("\"", "\x22");
try expectEqualStrings("\'", "\x27");
@ -789,7 +777,6 @@ test "discarding the result of various expressions" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
fn foo() !u32 {
@ -1072,7 +1059,6 @@ test "returning an opaque type from a function" {
test "orelse coercion as function argument" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const Loc = struct { start: i32 = -1 };
const Container = struct {
@ -1186,8 +1172,6 @@ fn testUnsignedCmp(comptime T: type) !void {
}
test "integer compare <= 64 bits" {
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
inline for (.{ u8, u16, u32, u64, usize, u10, u20, u30, u60 }) |T| {
try testUnsignedCmp(T);
try comptime testUnsignedCmp(T);
@ -1324,7 +1308,6 @@ test "break out of block based on comptime known values" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
const source = "A-";

View File

@ -65,7 +65,6 @@ test "sharded table" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
// realistic 16-way sharding
try testShardedTable(u32, 4, 8);

View File

@ -10,7 +10,6 @@ const native_endian = builtin.target.cpu.arch.endian();
test "@bitCast iX -> uX (32, 64)" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const bit_values = [_]usize{ 32, 64 };
@ -165,7 +164,6 @@ test "@bitCast packed structs at runtime and comptime" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const Full = packed struct {
number: u16,
@ -491,7 +489,6 @@ test "@bitCast of packed struct of bools all true" {
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const P = packed struct {
b0: bool,

View File

@ -342,7 +342,6 @@ test "inline call preserves tail call" {
test "inline call doesn't re-evaluate non generic struct" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
fn foo(f: struct { a: u8, b: u8 }) !void {
@ -441,7 +440,6 @@ test "non-anytype generic parameters provide result type" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
fn f(comptime T: type, y: T) !void {

View File

@ -24,7 +24,6 @@ test "peer type resolution: ?T and T" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
try expect(peerTypeTAndOptionalT(true, false).? == 0);
try expect(peerTypeTAndOptionalT(false, false).? == 3);
@ -104,7 +103,6 @@ test "@floatFromInt" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {
@ -163,7 +161,6 @@ test "@intFromFloat" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
try testIntFromFloats();
try comptime testIntFromFloats();
@ -303,7 +300,6 @@ test "peer result null and comptime_int" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
fn blah(n: i32) ?i32 {
@ -372,7 +368,6 @@ test "return u8 coercing into ?u32 return type" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {
@ -450,7 +445,6 @@ test "implicitly cast from T to anyerror!?T" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
try castToOptionalTypeError(1);
try comptime castToOptionalTypeError(1);
@ -602,7 +596,6 @@ fn testCastPtrOfArrayToSliceAndPtr() !void {
test "cast *[1][*]const u8 to [*]const ?[*]const u8" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const window_name = [1][*]const u8{"window name"};
const x: [*]const ?[*]const u8 = &window_name;
@ -668,7 +661,6 @@ test "@floatCast cast down" {
test "peer type resolution: unreachable, error set, unreachable" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const Error = error{
FileDescriptorAlreadyPresentInSet,
@ -763,7 +755,6 @@ test "peer type resolution: error union and error set" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const a: error{Three} = undefined;
const b: error{ One, Two }!u32 = undefined;
@ -957,7 +948,6 @@ test "peer cast [:x]T to [*:x]T" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {
@ -1023,7 +1013,6 @@ test "variable initialization uses result locations properly with regards to the
test "cast between C pointer with different but compatible types" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
fn foo(arg: [*]c_ushort) u16 {
@ -1219,7 +1208,6 @@ test "implicitly cast from [N]T to ?[]const T" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
try expect(mem.eql(u8, castToOptionalSlice().?, "hi"));
comptime assert(mem.eql(u8, castToOptionalSlice().?, "hi"));
@ -1544,7 +1532,6 @@ test "cast typed undefined to int" {
test "implicit cast from [:0]T to [*c]T" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
var a: [:0]const u8 = "foo";
_ = &a;
@ -1753,7 +1740,6 @@ test "peer type resolution: array and vector with same child type" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
var arr: [2]u32 = .{ 0, 1 };
var vec: @Vector(2, u32) = .{ 2, 3 };
@ -1845,7 +1831,6 @@ test "peer type resolution: three-way resolution combines error set and optional
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const E = error{Foo};
var a: E = error.Foo;
@ -1913,7 +1898,6 @@ test "peer type resolution: optional fixed-width int and comptime_int" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
var a: ?i32 = 42;
_ = &a;
@ -1960,7 +1944,6 @@ test "peer type resolution: vector and tuple" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
var vec: @Vector(3, i32) = .{ 1, 2, 3 };
_ = &vec;
@ -1985,7 +1968,6 @@ test "peer type resolution: vector and array and tuple" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
var vec: @Vector(2, i8) = .{ 10, 20 };
var arr: [2]i8 = .{ 30, 40 };
@ -2094,7 +2076,6 @@ test "peer type resolution: many compatible pointers" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
var buf = "foo-3".*;
@ -2216,7 +2197,6 @@ test "peer type resolution: pointer attributes are combined correctly" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
var buf_a align(4) = "foo".*;
var buf_b align(4) = "bar".*;
@ -2277,7 +2257,6 @@ test "cast builtins can wrap result in optional" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
const MyEnum = enum(u32) { _ };
@ -2586,7 +2565,6 @@ test "result information is preserved through many nested structures" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {

View File

@ -35,8 +35,6 @@ test "coerce i8 to i32 and @intCast back" {
}
test "coerce non byte-sized integers accross 32bits boundary" {
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
{
var v: u21 = 6417;
_ = &v;

View File

@ -53,7 +53,6 @@ test "return variable while defer expression in scope to modify it" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {
@ -116,6 +115,7 @@ test "errdefer with payload" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
fn foo() !i32 {
@ -138,6 +138,7 @@ test "reference to errdefer payload" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
fn foo() !i32 {

View File

@ -23,8 +23,6 @@ test "simple destructure" {
}
test "destructure with comptime syntax" {
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {
{

View File

@ -618,7 +618,6 @@ test "enum with specified tag values" {
test "non-exhaustive enum" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
const E = enum(u8) { a, b, _ };
@ -934,7 +933,6 @@ const Bar = enum { A, B, C, D };
test "enum literal casting to error union with payload enum" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
var bar: error{B}!Bar = undefined;
bar = .B; // should never cast to the error set
@ -1076,7 +1074,6 @@ test "enum literal casting to optional" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
var bar: ?Bar = undefined;
bar = .B;
@ -1105,7 +1102,6 @@ test "bit field access with enum fields" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
var data = bit_field_1;
try expect(getA(&data) == A.Two);
@ -1223,8 +1219,6 @@ test "enum tag from a local variable" {
}
test "auto-numbered enum with signed tag type" {
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const E = enum(i32) { a, b };
try std.testing.expectEqual(@as(i32, 0), @intFromEnum(E.a));

View File

@ -319,7 +319,6 @@ test "error inference with an empty set" {
test "error union peer type resolution" {
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
try testErrorUnionPeerTypeResolution(1);
}
@ -403,7 +402,6 @@ test "nested error union function call in optional unwrap" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
const Foo = struct {
@ -450,7 +448,6 @@ test "nested error union function call in optional unwrap" {
test "return function call to error set from error union function" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
fn errorable() anyerror!i32 {
@ -469,7 +466,6 @@ test "optional error set is the same size as error set" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
comptime assert(@sizeOf(?anyerror) == @sizeOf(anyerror));
comptime assert(@alignOf(?anyerror) == @alignOf(anyerror));
@ -917,7 +913,6 @@ test "field access of anyerror results in smaller error set" {
test "optional error union return type" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
fn foo() ?anyerror!u32 {
@ -932,7 +927,6 @@ test "optional error union return type" {
test "optional error set return type" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const E = error{ A, B };
const S = struct {
@ -946,8 +940,6 @@ test "optional error set return type" {
}
test "optional error set function parameter" {
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
fn doTheTest(a: ?anyerror) !void {
try std.testing.expect(a.? == error.OutOfMemory);
@ -977,7 +969,6 @@ test "returning an error union containing a type with no runtime bits" {
test "try used in recursive function with inferred error set" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
const Value = union(enum) {
@ -1079,7 +1070,6 @@ test "result location initialization of error union with OPV payload" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
x: u0,

View File

@ -782,7 +782,6 @@ test "array concatenation peer resolves element types - pointer" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
var a = [2]u3{ 1, 7 };
var b = [3]u8{ 200, 225, 255 };

View File

@ -134,7 +134,6 @@ test "cmp f16" {
test "cmp f32/f64" {
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
try testCmp(f32);
try comptime testCmp(f32);

View File

@ -181,7 +181,6 @@ test "function with complex callconv and return type expressions" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
try expect(fComplexCallconvRet(3).x == 9);
}
@ -451,7 +450,6 @@ test "implicit cast function to function ptr" {
test "method call with optional and error union first param" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
x: i32 = 1234,

View File

@ -112,7 +112,6 @@ test "for with null and T peer types and inferred result location type" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
fn doTheTest(slice: []const u8) !void {
@ -154,7 +153,6 @@ test "for loop with pointer elem var" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const source = "abcdefg";
var target: [source.len]u8 = undefined;
@ -228,7 +226,6 @@ test "else continue outer for" {
test "for loop with else branch" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
{
var x = [_]u32{ 1, 2 };
@ -489,7 +486,6 @@ test "inferred alloc ptr of for loop" {
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
{
var cond = false;

View File

@ -19,7 +19,6 @@ fn checkSize(comptime T: type) usize {
test "simple generic fn" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
try expect(max(i32, 3, -1) == 3);
try expect(max(u8, 1, 100) == 100);
@ -56,7 +55,6 @@ test "fn with comptime args" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
try expect(gimmeTheBigOne(1234, 5678) == 5678);
try expect(shouldCallSameInstance(34, 12) == 34);
@ -67,7 +65,6 @@ test "anytype params" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
try expect(max_i32(12, 34) == 34);
try expect(max_f64(1.2, 3.4) == 3.4);
@ -404,8 +401,6 @@ test "generic struct as parameter type" {
}
test "slice as parameter type" {
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
fn internComptimeString(comptime str: []const u8) *const []const u8 {
return &struct {
@ -503,7 +498,6 @@ test "union in struct captures argument" {
test "function argument tuple used as struct field" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
fn DeleagateWithContext(comptime Function: type) type {

View File

@ -18,7 +18,6 @@ test "store to global vector" {
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
try expect(vpos[1] == 0.0);
vpos = @Vector(2, f32){ 0.0, 1.0 };

View File

@ -82,7 +82,6 @@ test "const result loc, runtime if cond, else unreachable" {
test "if copies its payload" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {
@ -119,7 +118,6 @@ test "if peer expressions inferred optional type" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
var self: []const u8 = "abcdef";
var index: usize = 0;
@ -147,8 +145,6 @@ test "if-else expression with runtime condition result location is inferred opti
}
test "result location with inferred type ends up being pointer to comptime_int" {
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
var a: ?u32 = 1234;
var b: u32 = 2000;
_ = .{ &a, &b };
@ -194,8 +190,6 @@ test "if value shouldn't be load-elided if used later (structs)" {
}
test "if value shouldn't be load-elided if used later (optionals)" {
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
var a: ?i32 = 1;
var b: ?i32 = 1;

View File

@ -65,7 +65,6 @@ test "@clz" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
try testClz();
try comptime testClz();
@ -663,8 +662,6 @@ fn rem(comptime T: type, a: T, b: T) T {
}
test "unsigned wrapping" {
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
try testUnsignedWrappingEval(maxInt(u32));
try comptime testUnsignedWrappingEval(maxInt(u32));
}
@ -676,8 +673,6 @@ fn testUnsignedWrappingEval(x: u32) !void {
}
test "signed wrapping" {
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
try testSignedWrappingEval(maxInt(i32));
try comptime testSignedWrappingEval(maxInt(i32));
}
@ -725,7 +720,6 @@ fn negateWrap(comptime T: type, x: T) T {
test "unsigned 64-bit division" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isMIPS()) {
// https://github.com/ziglang/zig/issues/16846
@ -838,7 +832,6 @@ test "@addWithOverflow" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
try testAddWithOverflow(u8, 250, 100, 94, 1);
try testAddWithOverflow(u8, 100, 150, 250, 0);
@ -899,7 +892,6 @@ test "@addWithOverflow > 64 bits" {
test "small int addition" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
var x: u2 = 0;
try expect(x == 0);
@ -927,7 +919,6 @@ fn testMulWithOverflow(comptime T: type, a: T, b: T, mul: T, bit: u1) !void {
test "basic @mulWithOverflow" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
try testMulWithOverflow(u8, 86, 3, 2, 1);
try testMulWithOverflow(u8, 85, 3, 255, 0);

View File

@ -7,7 +7,6 @@ test "memcpy and memset intrinsics" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
try testMemcpyMemset();
try comptime testMemcpyMemset();
@ -29,7 +28,6 @@ test "@memcpy with both operands single-ptr-to-array, one is null-terminated" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
try testMemcpyBothSinglePtrArrayOneIsNullTerminated();
try comptime testMemcpyBothSinglePtrArrayOneIsNullTerminated();
@ -50,7 +48,6 @@ test "@memcpy dest many pointer" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
try testMemcpyDestManyPtr();
try comptime testMemcpyDestManyPtr();
@ -73,7 +70,6 @@ test "@memcpy slice" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
try testMemcpySlice();
try comptime testMemcpySlice();

View File

@ -53,7 +53,6 @@ test "maybe return" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
try maybeReturnImpl();
try comptime maybeReturnImpl();
@ -73,7 +72,6 @@ fn foo(x: ?i32) ?bool {
test "test null runtime" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
try testTestNullRuntime(null);
}
@ -188,7 +186,6 @@ test "unwrap optional which is field of global var" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
struct_with_optional.field = null;
if (struct_with_optional.field) |payload| {

View File

@ -9,7 +9,6 @@ const expectEqualStrings = std.testing.expectEqualStrings;
test "passing an optional integer as a parameter" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
fn entry() bool {
@ -134,7 +133,6 @@ test "nested optional field in struct" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S2 = struct {
y: u8,
@ -260,7 +258,6 @@ test "unwrap function call with optional pointer return value" {
test "nested orelse" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
fn entry() !void {
@ -287,7 +284,6 @@ test "nested orelse" {
test "self-referential struct through a slice of optional" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
const Node = struct {
@ -344,7 +340,6 @@ test "0-bit child type coerced to optional return ptr result location" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {
@ -535,7 +530,6 @@ test "Optional slice size is optimized" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
try expect(@sizeOf(?[]u8) == @sizeOf([]u8));
var a: ?[]const u8 = null;
@ -549,7 +543,6 @@ test "Optional slice passed to function" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
fn foo(a: ?[]const u8) !void {
@ -566,7 +559,6 @@ test "Optional slice passed to function" {
test "peer type resolution in nested if expressions" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const Thing = struct { n: i32 };
var a = false;
@ -594,6 +586,7 @@ test "cast slice to const slice nested in error union and optional" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
fn inner() !?[]u8 {
@ -632,7 +625,6 @@ test "result location initialization of optional with OPV payload" {
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
x: u0,

View File

@ -258,7 +258,6 @@ test "nested packed struct unaligned" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
if (native_endian != .little) return error.SkipZigTest; // Byte aligned packed struct field pointers have not been implemented yet
const S1 = packed struct {
@ -331,7 +330,6 @@ test "byte-aligned field pointer offsets" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
const A = packed struct {
@ -434,7 +432,6 @@ test "nested packed struct field pointers" {
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // ubsan unaligned pointer access
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
if (native_endian != .little) return error.SkipZigTest; // Byte aligned packed struct field pointers have not been implemented yet
const S2 = packed struct {
@ -962,7 +959,6 @@ test "pointer to container level packed struct field" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = packed struct(u32) {
test_bit: bool,
@ -1008,8 +1004,6 @@ test "bitcast back and forth" {
}
test "field access of packed struct smaller than its abi size inside struct initialized with rls" {
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
// Originally reported at https://github.com/ziglang/zig/issues/14200
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
@ -1028,8 +1022,6 @@ test "field access of packed struct smaller than its abi size inside struct init
}
test "modify nested packed struct aligned field" {
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
// Originally reported at https://github.com/ziglang/zig/issues/14632
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
@ -1096,7 +1088,6 @@ test "packed struct used as part of anon decl name" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = packed struct { a: u0 = 0 };
var a: u8 = 0;
@ -1164,7 +1155,6 @@ test "assignment to non-byte-aligned field in packed struct" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const Frame = packed struct {
num: u20,
@ -1275,7 +1265,6 @@ test "2-byte packed struct argument in C calling convention" {
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = packed struct(u16) {
x: u15 = 0,

View File

@ -8,7 +8,6 @@ test "flags in packed union" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
try testFlagsInPackedUnion();
try comptime testFlagsInPackedUnion();
@ -51,7 +50,6 @@ test "flags in packed union at offset" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
try testFlagsInPackedUnionAtOffset();
try comptime testFlagsInPackedUnionAtOffset();

View File

@ -125,7 +125,6 @@ test "initialize const optional C pointer to null" {
test "assigning integer to C pointer" {
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
var x: i32 = 0;
var y: i32 = 1;
@ -143,7 +142,6 @@ test "assigning integer to C pointer" {
test "C pointer comparison and arithmetic" {
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {
@ -230,6 +228,7 @@ test "implicit cast error unions with non-optional to optional pointer" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {
@ -343,7 +342,6 @@ test "array initialization types" {
test "null terminated pointer" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {
@ -517,7 +515,6 @@ test "element pointer to slice" {
test "element pointer arithmetic to slice" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {
@ -572,7 +569,6 @@ test "ptrCast comptime known slice to C pointer" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const s: [:0]const u8 = "foo";
var p: [*c]const u8 = @ptrCast(s);

View File

@ -8,7 +8,6 @@ test "@popCount integers" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
try comptime testPopCountIntegers();
try testPopCountIntegers();

View File

@ -30,7 +30,6 @@ comptime {
test "slicing" {
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
var array: [20]i32 = undefined;
@ -256,7 +255,6 @@ test "C pointer slice access" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
var buf: [10]u32 = [1]u32{42} ** 10;
const c_ptr = @as([*c]const u32, @ptrCast(&buf));
@ -836,7 +834,6 @@ test "global slice field access" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
var slice: []const u8 = undefined;
@ -892,7 +889,6 @@ test "empty slice ptr is non null" {
test "slice decays to many pointer" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
var buf: [8]u8 = "abcdefg\x00".*;
const p: [*:0]const u8 = buf[0..7 :0];
@ -903,7 +899,6 @@ test "write through pointer to optional slice arg" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
fn bar(foo: *?[]const u8) !void {
@ -956,7 +951,6 @@ test "slicing slices gives correct result" {
if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const foo = "1234";
const bar = foo[0..4];

View File

@ -17,7 +17,6 @@ test "@src" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
try doTheTest();
}
@ -38,8 +37,6 @@ test "@src used as a comptime parameter" {
}
test "@src in tuple passed to anytype function" {
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
fn Foo(a: anytype) u32 {
return a[0].line;

View File

@ -34,7 +34,6 @@ const ptr_type_name: [*:0]const u8 = type_name;
test "@typeName() returns a string literal" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
try std.testing.expect(*const [type_name.len:0]u8 == @TypeOf(type_name));
@ -65,7 +64,6 @@ fn testFnForSrc() std.builtin.SourceLocation {
test "@src() returns a struct containing 0-terminated string slices" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const src = testFnForSrc();
try std.testing.expect([:0]const u8 == @TypeOf(src.file));

View File

@ -68,7 +68,6 @@ const SmallStruct = struct {
test "lower unnamed constants" {
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
var foo = SmallStruct{ .a = 1, .b = 255 };
try expect(foo.first() == 1);
@ -419,7 +418,6 @@ test "packed struct 24bits" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
if (builtin.cpu.arch == .wasm32) return error.SkipZigTest; // TODO
if (comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
@ -506,7 +504,6 @@ test "packed struct fields are ordered from LSB to MSB" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
var all: u64 = 0x7765443322221111;
var bytes: [8]u8 align(@alignOf(Bitfields)) = undefined;
@ -527,7 +524,6 @@ test "implicit cast packed struct field to const ptr" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const LevelUpMove = packed struct {
move_id: u9,
@ -593,7 +589,6 @@ test "bit field access" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
var data = bit_field_1;
try expect(getA(&data) == 1);
@ -650,7 +645,6 @@ test "packed array 24bits" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
comptime {
try expect(@sizeOf([9]Foo32Bits) == 9 * 4);
@ -718,7 +712,6 @@ test "pointer to packed struct member in a stack variable" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = packed struct {
a: u2,
@ -1103,7 +1096,6 @@ test "packed struct with undefined initializers" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
const P = packed struct {
@ -1133,7 +1125,6 @@ test "packed struct with undefined initializers" {
test "for loop over pointers to struct, getting field from struct pointer" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
const Foo = struct {
@ -1243,7 +1234,6 @@ test "typed init through error unions and optionals" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
a: u32,
@ -1465,8 +1455,6 @@ test "struct field has a pointer to an aligned version of itself" {
}
test "struct has only one reference" {
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
fn optionalStructParam(_: ?struct { x: u8 }) void {}
fn errorUnionStructParam(_: error{}!struct { x: u8 }) void {}
@ -1573,7 +1561,6 @@ test "no dependency loop on optional field wrapped in generic function" {
test "optional field init with tuple" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
a: ?struct { b: u32 },
@ -1588,7 +1575,6 @@ test "optional field init with tuple" {
test "if inside struct init inside if" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const MyStruct = struct { x: u32 };
const b: u32 = 5;
@ -1770,8 +1756,6 @@ test "struct init with no result pointer sets field result types" {
}
test "runtime side-effects in comptime-known struct init" {
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
var side_effects: u4 = 0;
const S = struct { a: u4, b: u4, c: u4, d: u4 };
const init = S{
@ -1797,8 +1781,6 @@ test "runtime side-effects in comptime-known struct init" {
}
test "pointer to struct initialized through reference to anonymous initializer provides result types" {
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct { a: u8, b: u16, c: *const anyopaque };
var my_u16: u16 = 0xABCD;
_ = &my_u16;
@ -1995,7 +1977,6 @@ test "runtime call in nested initializer" {
if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const Holder = struct {
array: []const u8,

View File

@ -316,7 +316,6 @@ test "switch on union with some prongs capturing" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const X = union(enum) {
a,
@ -427,6 +426,7 @@ test "else prong of switch on error set excludes other cases" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {
@ -462,6 +462,7 @@ test "switch prongs with error set cases make a new error set type for capture v
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {
@ -516,7 +517,6 @@ test "switch with null and T peer types and inferred result location type" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
fn doTheTest(c: u8) !void {
@ -537,7 +537,6 @@ test "switch prongs with cases with identical payload types" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const Union = union(enum) {
A: usize,
@ -781,8 +780,6 @@ test "comptime inline switch" {
}
test "switch capture peer type resolution" {
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const U = union(enum) {
a: u32,
b: u64,
@ -798,8 +795,6 @@ test "switch capture peer type resolution" {
}
test "switch capture peer type resolution for in-memory coercible payloads" {
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const T1 = c_int;
const T2 = @Type(@typeInfo(T1));
@ -821,7 +816,6 @@ test "switch capture peer type resolution for in-memory coercible payloads" {
test "switch pointer capture peer type resolution" {
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const T1 = c_int;
const T2 = @Type(@typeInfo(T1));
@ -924,8 +918,6 @@ test "switch prong captures range" {
}
test "prong with inline call to unreachable" {
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const U = union(enum) {
void: void,
bool: bool,

View File

@ -18,7 +18,6 @@ test "switch prong implicit cast" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const result = switch (foo(2) catch unreachable) {
FormValue.One => false,

View File

@ -6,7 +6,6 @@ test "thread local variable" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_llvm) switch (builtin.cpu.arch) {
.x86_64, .x86 => {},
else => return error.SkipZigTest,
@ -29,7 +28,6 @@ test "pointer to thread local array" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_llvm) switch (builtin.cpu.arch) {
.x86_64, .x86 => {},
else => return error.SkipZigTest,
@ -47,7 +45,6 @@ test "reference a global threadlocal variable" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_llvm) switch (builtin.cpu.arch) {
.x86_64, .x86 => {},
else => return error.SkipZigTest,

View File

@ -51,6 +51,7 @@ test "`try`ing an if/else expression" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
fn getError() !void {

View File

@ -280,7 +280,6 @@ test "tuple in tuple passed to generic function" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
fn pair(x: f32, y: f32) std.meta.Tuple(&.{ f32, f32 }) {
@ -300,7 +299,6 @@ test "coerce tuple to tuple" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const T = std.meta.Tuple(&.{u8});
const S = struct {
@ -315,7 +313,6 @@ test "tuple type with void field" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const T = std.meta.Tuple(&[_]type{void});
const x = T{{}};
@ -352,7 +349,6 @@ test "zero sized struct in tuple handled correctly" {
test "tuple type with void field and a runtime field" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const T = std.meta.Tuple(&[_]type{ usize, void });
var t: T = .{ 5, {} };
@ -409,7 +405,6 @@ test "nested runtime conditionals in tuple initializer" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
var data: u8 = 0;
_ = &data;

View File

@ -7,7 +7,6 @@ const expectEqualStrings = testing.expectEqualStrings;
test "tuple declaration type info" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
{
const T = struct { comptime u32 align(2) = 1, []const u8 };
@ -36,7 +35,6 @@ test "tuple declaration type info" {
test "Tuple declaration usage" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const T = struct { u32, []const u8 };
var t: T = .{ 1, "foo" };

View File

@ -565,8 +565,6 @@ test "StructField.is_comptime" {
}
test "typeInfo resolves usingnamespace declarations" {
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const A = struct {
pub const f1 = 42;
};
@ -592,7 +590,6 @@ test "value from struct @typeInfo default_value can be loaded at comptime" {
test "@typeInfo decls and usingnamespace" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const A = struct {
pub const x = 5;
@ -633,8 +630,6 @@ test "type info of tuple of string literal default value" {
}
test "@typeInfo only contains pub decls" {
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const other = struct {
const std = @import("std");

View File

@ -16,7 +16,6 @@ test "anon fn param" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
// https://github.com/ziglang/zig/issues/9339
try expectEqualStringsIgnoreDigits(
@ -42,7 +41,6 @@ test "anon field init" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
const Foo = .{
@ -69,7 +67,6 @@ test "basic" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
try expectEqualStrings("i64", @typeName(i64));
try expectEqualStrings("*usize", @typeName(*usize));
@ -91,7 +88,6 @@ test "top level decl" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
try expectEqualStrings(
@ -142,7 +138,6 @@ test "fn param" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
// https://github.com/ziglang/zig/issues/675
@ -223,7 +218,6 @@ test "local variable" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
const Foo = struct { a: u32 };
@ -243,7 +237,6 @@ test "comptime parameters not converted to anytype in function type" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const T = fn (fn (type) void, void) void;
try expectEqualStrings("fn (comptime fn (comptime type) void, void) void", @typeName(T));
@ -253,7 +246,6 @@ test "anon name strategy used in sub expression" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
const S = struct {

View File

@ -100,7 +100,6 @@ const FooExtern = extern union {
test "basic extern unions" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
var foo = FooExtern{ .int = 1 };
try expect(foo.int == 1);
@ -172,7 +171,6 @@ test "constant tagged union with payload" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
var empty = TaggedUnionWithPayload{ .Empty = {} };
var full = TaggedUnionWithPayload{ .Full = 13 };
@ -656,7 +654,6 @@ test "union(enum(u32)) with specified and unspecified tag values" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
comptime assert(Tag(Tag(MultipleChoice2)) == u32);
try testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2{ .C = 123 });
@ -808,7 +805,6 @@ test "return union init with void payload" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
fn entry() !void {
@ -971,7 +967,6 @@ test "function call result coerces from tagged union to the tag" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
const Arch = union(enum) {
@ -1136,7 +1131,6 @@ test "@unionInit on union with tag but no fields" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
const Type = enum(u8) { no_op = 105 };
@ -1700,7 +1694,6 @@ test "packed union field pointer has correct alignment" {
test "union with 128 bit integer" {
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const ValueTag = enum { int, other };
@ -1917,7 +1910,6 @@ test "reinterpret packed union" {
test "reinterpret packed union inside packed struct" {
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const U = packed union {
a: u7,
@ -2196,7 +2188,6 @@ test "copied union field doesn't alias source" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const U = union(enum) {
array: [10]u32,

View File

@ -21,7 +21,6 @@ test "enum with members" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const a = ET{ .SINT = -42 };
const b = ET{ .UINT = 42 };

View File

@ -102,7 +102,6 @@ test "vector float operators" {
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .aarch64) {
@ -119,7 +118,7 @@ test "vector float operators" {
try expectEqual(v + x, .{ 11, 22, 33, 44 });
try expectEqual(v - x, .{ 9, 18, 27, 36 });
try expectEqual(v * x, .{ 10, 40, 90, 160 });
try expectEqual(-x, .{ -1, -2, -3, -4 });
if (builtin.zig_backend != .stage2_riscv64) try expectEqual(-x, .{ -1, -2, -3, -4 });
}
};
@ -129,6 +128,8 @@ test "vector float operators" {
try S.doTheTest(f64);
try comptime S.doTheTest(f64);
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
try S.doTheTest(f16);
try comptime S.doTheTest(f16);
@ -394,7 +395,6 @@ test "load vector elements via comptime index" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {
@ -416,7 +416,6 @@ test "store vector elements via comptime index" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {
@ -444,7 +443,6 @@ test "load vector elements via runtime index" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {
@ -467,7 +465,6 @@ test "store vector elements via runtime index" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {
@ -1239,7 +1236,6 @@ test "loading the second vector from a slice of vectors" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
@setRuntimeSafety(false);
var small_bases = [2]@Vector(2, u8){
@ -1326,7 +1322,6 @@ test "zero multiplicand" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const zeros = @Vector(2, u32){ 0.0, 0.0 };
var ones = @Vector(2, u32){ 1.0, 1.0 };
@ -1487,7 +1482,6 @@ test "store vector with memset" {
test "addition of vectors represented as strings" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const V = @Vector(3, u8);
const foo: V = "foo".*;
@ -1514,7 +1508,6 @@ test "vector pointer is indexable" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const V = @Vector(2, u32);

View File

@ -106,7 +106,6 @@ fn testBreakOuter() void {
test "while copies its payload" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {
@ -208,7 +207,6 @@ test "while on optional with else result follow else prong" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const result = while (returnNull()) |value| {
break value;
@ -220,7 +218,6 @@ test "while on optional with else result follow break prong" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const result = while (returnOptional(10)) |value| {
break value;
@ -293,7 +290,6 @@ test "while optional 2 break statements and an else" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
fn entry(opt_t: ?bool, f: bool) !void {
@ -392,7 +388,6 @@ test "breaking from a loop in an if statement" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const S = struct {
fn retOpt() ?u32 {

View File

@ -439,7 +439,7 @@ const test_targets = blk: {
.target = std.Target.Query.parse(
.{
.arch_os_abi = "riscv64-linux-musl",
.cpu_features = "baseline+v",
.cpu_features = "baseline+v+zbb",
},
) catch @panic("OOM"),
.use_llvm = false,