authorgravatar for david@vortan.devDavid Rubin <david@vortan.dev> 2024-07-05 03:49:09-07:00
committergravatar for david@vortan.devDavid Rubin <david@vortan.dev> 2024-07-26 04:05:39-07:00
log8d30fc45c424ed1aaf9067436a64b0744619c250
tree69d6d86af25281f7d999990629305da76ff9913b
parent9766b68c475438e24885dd75cf137d51e72ccfa3
signaturelock-open Commit is signed but in an unrecognized format.

riscv: implement more operators

we can run `std.debug.print` now, with both run-time strings and integers!

22 files changed, 129 insertions(+), 151 deletions(-)

lib/compiler/test_runner.zig+9-7
......@@ -271,6 +271,7 @@ pub fn mainSimple() anyerror!void {
271271 };
272272 // is the backend capable of using std.fmt.format to print a summary at the end?
273273 const print_summary = switch (builtin.zig_backend) {
274 .stage2_riscv64 => true,
274275 else => false,
275276 };
276277
......@@ -282,11 +283,13 @@ pub fn mainSimple() anyerror!void {
282283 const stderr = if (comptime enable_print) std.io.getStdErr() else {};
283284
284285 for (builtin.test_functions) |test_fn| {
285 if (enable_print) {
286 stderr.writeAll(test_fn.name) catch {};
287 stderr.writeAll("... ") catch {};
288 }
289 test_fn.func() catch |err| {
286 if (test_fn.func()) |_| {
287 if (enable_print) {
288 stderr.writeAll(test_fn.name) catch {};
289 stderr.writeAll("... ") catch {};
290 stderr.writeAll("PASS\n") catch {};
291 }
292 } else |err| if (enable_print) {
290293 if (enable_print) {
291294 stderr.writeAll(test_fn.name) catch {};
292295 stderr.writeAll("... ") catch {};
......@@ -300,8 +303,7 @@ pub fn mainSimple() anyerror!void {
300303 if (enable_print) stderr.writeAll("SKIP\n") catch {};
301304 skipped += 1;
302305 continue;
303 };
304 if (enable_print) stderr.writeAll("PASS\n") catch {};
306 }
305307 passed += 1;
306308 }
307309 if (enable_print and print_summary) {
lib/std/builtin.zig+1-8
......@@ -775,14 +775,7 @@ pub fn default_panic(msg: []const u8, error_return_trace: ?*StackTrace, ret_addr
775775 }
776776
777777 if (builtin.zig_backend == .stage2_riscv64) {
778 asm volatile ("ecall"
779 :
780 : [number] "{a7}" (64),
781 [arg1] "{a0}" (1),
782 [arg2] "{a1}" (@intFromPtr(msg.ptr)),
783 [arg3] "{a2}" (msg.len),
784 : "memory"
785 );
778 std.debug.print("panic: {s}\n", .{msg});
786779 std.posix.exit(127);
787780 }
788781
src/Package/Module.zig+1-1
......@@ -159,7 +159,7 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module {
159159
160160 if (options.inherited.single_threaded) |x| break :b x;
161161 if (options.parent) |p| break :b p.single_threaded;
162 break :b target_util.defaultSingleThreaded(target);
162 break :b target_util.defaultSingleThreaded(target, zig_backend);
163163 };
164164
165165 const error_tracing = b: {
src/arch/riscv64/CodeGen.zig+110-106
......@@ -51,7 +51,6 @@ const InnerError = CodeGenError || error{OutOfRegisters};
5151pt: Zcu.PerThread,
5252air: Air,
5353liveness: Liveness,
54zcu: *Zcu,
5554bin_file: *link.File,
5655gpa: Allocator,
5756
......@@ -264,13 +263,13 @@ const MCValue = union(enum) {
264263 .register_pair,
265264 .memory,
266265 .indirect,
267 .load_frame,
268266 .load_symbol,
269267 .lea_symbol,
270268 => switch (off) {
271269 0 => mcv,
272 else => unreachable, // not offsettable
270 else => unreachable,
273271 },
272 .load_frame => |frame| .{ .load_frame = .{ .index = frame.index, .off = frame.off + off } },
274273 .immediate => |imm| .{ .immediate = @bitCast(@as(i64, @bitCast(imm)) +% off) },
275274 .register => |reg| .{ .register_offset = .{ .reg = reg, .off = off } },
276275 .register_offset => |reg_off| .{ .register_offset = .{ .reg = reg_off.reg, .off = reg_off.off + off } },
......@@ -737,7 +736,6 @@ pub fn generate(
737736 .air = air,
738737 .pt = pt,
739738 .mod = mod,
740 .zcu = zcu,
741739 .bin_file = bin_file,
742740 .liveness = liveness,
743741 .target = target,
......@@ -946,7 +944,7 @@ fn formatDecl(
946944}
947945fn fmtDecl(func: *Func, decl_index: InternPool.DeclIndex) std.fmt.Formatter(formatDecl) {
948946 return .{ .data = .{
949 .zcu = func.zcu,
947 .zcu = func.pt.zcu,
950948 .decl_index = decl_index,
951949 } };
952950}
......@@ -1325,6 +1323,7 @@ fn genBody(func: *Func, body: []const Air.Inst.Index) InnerError!void {
13251323 .mul,
13261324 .mul_wrap,
13271325 .div_trunc,
1326 .rem,
13281327
13291328 .shl, .shl_exact,
13301329 .shr, .shr_exact,
......@@ -1344,7 +1343,6 @@ fn genBody(func: *Func, body: []const Air.Inst.Index) InnerError!void {
13441343 .ptr_add,
13451344 .ptr_sub => try func.airPtrArithmetic(inst, tag),
13461345
1347 .rem,
13481346 .mod,
13491347 .div_float,
13501348 .div_floor,
......@@ -2151,11 +2149,16 @@ fn airTrunc(func: *Func, inst: Air.Inst.Index) !void {
21512149 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
21522150 if (func.liveness.isUnused(inst))
21532151 return func.finishAir(inst, .unreach, .{ ty_op.operand, .none, .none });
2154
2152 // we assume no zeroext in the "Zig ABI", so it's fine to just not truncate it.
21552153 const operand = try func.resolveInst(ty_op.operand);
2156 _ = operand;
2157 return func.fail("TODO implement trunc for {}", .{func.target.cpu.arch});
2158 // return func.finishAir(inst, result, .{ ty_op.operand, .none, .none });
2154
2155 // we can do it just to be safe, but this shouldn't be needed for no-runtime safety modes
2156 switch (operand) {
2157 .register => |reg| try func.truncateRegister(func.typeOf(ty_op.operand), reg),
2158 else => {},
2159 }
2160
2161 return func.finishAir(inst, operand, .{ ty_op.operand, .none, .none });
21592162}
21602163
21612164fn airIntFromBool(func: *Func, inst: Air.Inst.Index) !void {
......@@ -2305,10 +2308,7 @@ fn binOp(
23052308 80, 128 => true,
23062309 else => unreachable,
23072310 };
2308 switch (air_tag) {
2309 .rem, .mod => {},
2310 else => if (!type_needs_libcall) break :libcall,
2311 }
2311 if (!type_needs_libcall) break :libcall;
23122312 return func.fail("binOp libcall runtime-float ops", .{});
23132313 }
23142314
......@@ -2384,6 +2384,7 @@ fn genBinOp(
23842384 .sub_wrap,
23852385 .mul,
23862386 .mul_wrap,
2387 .rem,
23872388 => {
23882389 if (!math.isPowerOfTwo(bit_size))
23892390 return func.fail(
......@@ -2391,6 +2392,15 @@ fn genBinOp(
23912392 .{ @tagName(tag), bit_size },
23922393 );
23932394
2395 switch (tag) {
2396 .rem,
2397 => {
2398 try func.truncateRegister(lhs_ty, lhs_reg);
2399 try func.truncateRegister(rhs_ty, rhs_reg);
2400 },
2401 else => {},
2402 }
2403
23942404 switch (lhs_ty.zigTypeTag(zcu)) {
23952405 .Int => {
23962406 const mir_tag: Mir.Inst.Tag = switch (tag) {
......@@ -2409,6 +2419,10 @@ fn genBinOp(
24092419 32 => .mulw,
24102420 else => unreachable,
24112421 },
2422 .rem => switch (bit_size) {
2423 64 => if (is_unsigned) .remu else .rem,
2424 else => if (is_unsigned) .remuw else .remu,
2425 },
24122426 else => unreachable,
24132427 };
24142428
......@@ -2423,14 +2437,6 @@ fn genBinOp(
24232437 },
24242438 },
24252439 });
2426
2427 // truncate when the instruction is larger than the bit size.
2428 switch (bit_size) {
2429 8, 16 => try func.truncateRegister(lhs_ty, dst_reg),
2430 32 => {}, // addw/subw affects the first 32-bits
2431 64 => {}, // add/sub affects the entire register
2432 else => unreachable,
2433 }
24342440 },
24352441 .Float => {
24362442 const mir_tag: Mir.Inst.Tag = switch (tag) {
......@@ -2627,23 +2633,17 @@ fn genBinOp(
26272633 .shl,
26282634 .shl_exact,
26292635 => {
2630 if (!math.isPowerOfTwo(bit_size))
2631 return func.fail(
2632 "TODO: genBinOp {s} non-pow 2, found {}",
2633 .{ @tagName(tag), bit_size },
2634 );
2635
2636 // it's important that the shift amount is exact
2636 if (bit_size > 64) return func.fail("TODO: genBinOp shift > 64 bits, {}", .{bit_size});
26372637 try func.truncateRegister(rhs_ty, rhs_reg);
26382638
26392639 const mir_tag: Mir.Inst.Tag = switch (tag) {
26402640 .shl, .shl_exact => switch (bit_size) {
2641 8, 16, 64 => .sll,
2641 1...31, 33...64 => .sll,
26422642 32 => .sllw,
26432643 else => unreachable,
26442644 },
26452645 .shr, .shr_exact => switch (bit_size) {
2646 8, 16, 64 => .srl,
2646 1...31, 33...64 => .srl,
26472647 32 => .srlw,
26482648 else => unreachable,
26492649 },
......@@ -2659,13 +2659,6 @@ fn genBinOp(
26592659 .rs2 = rhs_reg,
26602660 } },
26612661 });
2662
2663 switch (bit_size) {
2664 8, 16 => try func.truncateRegister(lhs_ty, dst_reg),
2665 32 => {},
2666 64 => {},
2667 else => unreachable,
2668 }
26692662 },
26702663
26712664 // TODO: move the isel logic out of lower and into here.
......@@ -2810,10 +2803,6 @@ fn airAddWithOverflow(func: *Func, inst: Air.Inst.Index) !void {
28102803 if (int_info.bits >= 8 and math.isPowerOfTwo(int_info.bits)) {
28112804 const add_result = try func.binOp(null, .add, extra.lhs, extra.rhs);
28122805
2813 const add_result_reg = try func.copyToTmpRegister(ty, add_result);
2814 const add_result_reg_lock = func.register_manager.lockRegAssumeUnused(add_result_reg);
2815 defer func.register_manager.unlockReg(add_result_reg_lock);
2816
28172806 try func.genSetMem(
28182807 .{ .frame = offset.index },
28192808 offset.off + @as(i32, @intCast(tuple_ty.structFieldOffset(0, pt))),
......@@ -2821,14 +2810,21 @@ fn airAddWithOverflow(func: *Func, inst: Air.Inst.Index) !void {
28212810 add_result,
28222811 );
28232812
2813 const trunc_reg = try func.copyToTmpRegister(ty, add_result);
2814 const trunc_reg_lock = func.register_manager.lockRegAssumeUnused(trunc_reg);
2815 defer func.register_manager.unlockReg(trunc_reg_lock);
2816
28242817 const overflow_reg, const overflow_lock = try func.allocReg(.int);
28252818 defer func.register_manager.unlockReg(overflow_lock);
28262819
2820 // if the result isn't equal after truncating it to the given type,
2821 // an overflow must have happened.
2822 try func.truncateRegister(func.typeOf(extra.lhs), trunc_reg);
28272823 try func.genBinOp(
28282824 .cmp_neq,
2829 .{ .register = add_result_reg },
2825 add_result,
28302826 ty,
2831 .{ .register = add_result_reg },
2827 .{ .register = trunc_reg },
28322828 ty,
28332829 overflow_reg,
28342830 );
......@@ -3022,61 +3018,34 @@ fn airMulWithOverflow(func: *Func, inst: Air.Inst.Index) !void {
30223018 switch (lhs_ty.zigTypeTag(zcu)) {
30233019 else => |x| return func.fail("TODO: airMulWithOverflow {s}", .{@tagName(x)}),
30243020 .Int => {
3025 assert(lhs_ty.eql(rhs_ty, zcu));
3026 const int_info = lhs_ty.intInfo(zcu);
3027 switch (int_info.bits) {
3028 1...32 => {
3029 if (int_info.bits >= 8 and math.isPowerOfTwo(int_info.bits)) {
3030 if (int_info.signedness == .unsigned) {
3031 switch (int_info.bits) {
3032 1...8 => {
3033 const max_val = std.math.pow(u16, 2, int_info.bits) - 1;
3034
3035 const add_reg, const add_lock = try func.promoteReg(lhs_ty, lhs);
3036 defer if (add_lock) |lock| func.register_manager.unlockReg(lock);
3037
3038 const overflow_reg, const overflow_lock = try func.allocReg(.int);
3039 defer func.register_manager.unlockReg(overflow_lock);
3040
3041 _ = try func.addInst(.{
3042 .tag = .andi,
3043 .ops = .rri,
3044 .data = .{ .i_type = .{
3045 .rd = overflow_reg,
3046 .rs1 = add_reg,
3047 .imm12 = Immediate.s(max_val),
3048 } },
3049 });
3050
3051 try func.genBinOp(
3052 .cmp_neq,
3053 .{ .register = overflow_reg },
3054 lhs_ty,
3055 .{ .register = add_reg },
3056 lhs_ty,
3057 overflow_reg,
3058 );
3059
3060 try func.genCopy(
3061 lhs_ty,
3062 result_mcv.offset(overflow_off),
3063 .{ .register = overflow_reg },
3064 );
3065
3066 break :result result_mcv;
3067 },
3068
3069 else => return func.fail("TODO: airMulWithOverflow check for size {d}", .{int_info.bits}),
3070 }
3071 } else {
3072 return func.fail("TODO: airMulWithOverflow calculate carry for signed addition", .{});
3073 }
3074 } else {
3075 return func.fail("TODO: airMulWithOverflow with < 8 bits or non-pow of 2", .{});
3076 }
3077 },
3078 else => return func.fail("TODO: airMulWithOverflow larger than 32-bit mul", .{}),
3079 }
3021 if (std.debug.runtime_safety) assert(lhs_ty.eql(rhs_ty, zcu));
3022
3023 const trunc_reg = try func.copyToTmpRegister(lhs_ty, .{ .register = dest_reg });
3024 const trunc_reg_lock = func.register_manager.lockRegAssumeUnused(trunc_reg);
3025 defer func.register_manager.unlockReg(trunc_reg_lock);
3026
3027 const overflow_reg, const overflow_lock = try func.allocReg(.int);
3028 defer func.register_manager.unlockReg(overflow_lock);
3029
3030 // if the result isn't equal after truncating it to the given type,
3031 // an overflow must have happened.
3032 try func.truncateRegister(func.typeOf(extra.lhs), trunc_reg);
3033 try func.genBinOp(
3034 .cmp_neq,
3035 .{ .register = dest_reg },
3036 lhs_ty,
3037 .{ .register = trunc_reg },
3038 rhs_ty,
3039 overflow_reg,
3040 );
3041
3042 try func.genCopy(
3043 lhs_ty,
3044 result_mcv.offset(overflow_off),
3045 .{ .register = overflow_reg },
3046 );
3047
3048 break :result result_mcv;
30803049 },
30813050 }
30823051 };
......@@ -3317,7 +3286,17 @@ fn airWrapOptional(func: *Func, inst: Air.Inst.Index) !void {
33173286 Type.u8,
33183287 .{ .immediate = 1 },
33193288 ),
3320 .register => return func.fail("TODO: airWrapOption opt_mcv register", .{}),
3289
3290 .register => |opt_reg| {
3291 try func.genBinOp(
3292 .shl,
3293 .{ .immediate = 1 },
3294 Type.u64,
3295 .{ .immediate = 32 },
3296 Type.u64,
3297 opt_reg,
3298 );
3299 },
33213300 else => unreachable,
33223301 }
33233302 }
......@@ -4059,7 +4038,7 @@ fn airLoad(func: *Func, inst: Air.Inst.Index) !void {
40594038 const elem_size = elem_ty.abiSize(pt);
40604039
40614040 const dst_mcv: MCValue = blk: {
4062 // Pointer is 8 bytes, and if the element is more than that, we cannot reuse it.
4041 // "ptr" is 8 bytes, and if the element is more than that, we cannot reuse it.
40634042 if (elem_size <= 8 and func.reuseOperand(inst, ty_op.operand, 0, ptr)) {
40644043 // The MCValue that holds the pointer can be re-used as the value.
40654044 break :blk ptr;
......@@ -4970,7 +4949,7 @@ fn isNull(func: *Func, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
49704949 .lea_symbol,
49714950 .reserved_frame,
49724951 .air_ref,
4973 => return func.fail("TODO: hmm {}", .{opt_mcv}),
4952 => unreachable,
49744953
49754954 .register => |opt_reg| {
49764955 if (some_info.off == 0) {
......@@ -4993,9 +4972,27 @@ fn isNull(func: *Func, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
49934972 return return_mcv;
49944973 }
49954974 assert(some_info.ty.ip_index == .bool_type);
4996 const opt_abi_size: u32 = @intCast(opt_ty.abiSize(pt));
4997 _ = opt_abi_size;
4998 return func.fail("TODO: isNull some_info.off != 0 register", .{});
4975 const bit_offset: u7 = @intCast(some_info.off * 8);
4976
4977 try func.genBinOp(
4978 .shr,
4979 .{ .register = opt_reg },
4980 Type.u64,
4981 .{ .immediate = bit_offset },
4982 Type.u8,
4983 return_reg,
4984 );
4985 try func.truncateRegister(Type.u8, return_reg);
4986 try func.genBinOp(
4987 .cmp_eq,
4988 .{ .register = return_reg },
4989 Type.u64,
4990 .{ .immediate = 0 },
4991 Type.u8,
4992 return_reg,
4993 );
4994
4995 return return_mcv;
49994996 },
50004997
50014998 .load_frame => {
......@@ -6556,7 +6553,8 @@ fn airAtomicRmw(func: *Func, inst: Air.Inst.Index) !void {
65566553}
65576554
65586555fn airAtomicLoad(func: *Func, inst: Air.Inst.Index) !void {
6559 const zcu = func.pt.zcu;
6556 const pt = func.pt;
6557 const zcu = pt.zcu;
65606558 const atomic_load = func.air.instructions.items(.data)[@intFromEnum(inst)].atomic_load;
65616559 const order: std.builtin.AtomicOrder = atomic_load.order;
65626560
......@@ -6564,6 +6562,9 @@ fn airAtomicLoad(func: *Func, inst: Air.Inst.Index) !void {
65646562 const elem_ty = ptr_ty.childType(zcu);
65656563 const ptr_mcv = try func.resolveInst(atomic_load.ptr);
65666564
6565 const bit_size = elem_ty.bitSize(pt);
6566 if (bit_size > 64) return func.fail("TODO: airAtomicStore > 64 bits", .{});
6567
65676568 const result_mcv = try func.allocRegOrMem(elem_ty, inst, true);
65686569 assert(result_mcv == .register); // should be less than 8 bytes
65696570
......@@ -6616,6 +6617,9 @@ fn airAtomicStore(func: *Func, inst: Air.Inst.Index, order: std.builtin.AtomicOr
66166617 const val_ty = func.typeOf(bin_op.rhs);
66176618 const val_mcv = try func.resolveInst(bin_op.rhs);
66186619
6620 const bit_size = val_ty.bitSize(func.pt);
6621 if (bit_size > 64) return func.fail("TODO: airAtomicStore > 64 bits", .{});
6622
66196623 switch (order) {
66206624 .unordered, .monotonic => {},
66216625 .release, .seq_cst => {
src/target.zig+2-1
......@@ -60,9 +60,10 @@ pub fn alwaysSingleThreaded(target: std.Target) bool {
6060 return false;
6161}
6262
63pub fn defaultSingleThreaded(target: std.Target) bool {
63pub fn defaultSingleThreaded(target: std.Target, backend: std.builtin.CompilerBackend) bool {
6464 switch (target.cpu.arch) {
6565 .wasm32, .wasm64 => return true,
66 .riscv64 => if (backend == .stage2_riscv64) return true,
6667 else => {},
6768 }
6869 switch (target.os.tag) {
test/behavior/align.zig-1
......@@ -16,7 +16,6 @@ test "global variable alignment" {
1616}
1717
1818test "large alignment of local constant" {
19 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
2019 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
2120 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
2221 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // flaky
test/behavior/basic.zig-2
......@@ -16,8 +16,6 @@ test "empty function with comments" {
1616}
1717
1818test "truncate" {
19 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
20
2119 try expect(testTruncate(0x10fd) == 0xfd);
2220 comptime assert(testTruncate(0x10fd) == 0xfd);
2321}
test/behavior/call.zig-1
......@@ -441,7 +441,6 @@ test "non-anytype generic parameters provide result type" {
441441 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
442442 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
443443 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
444 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
445444
446445 const S = struct {
447446 fn f(comptime T: type, y: T) !void {
test/behavior/cast.zig-2
......@@ -1845,7 +1845,6 @@ test "peer type resolution: three-way resolution combines error set and optional
18451845 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
18461846 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
18471847 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1848 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
18491848
18501849 const E = error{Foo};
18511850 var a: E = error.Foo;
......@@ -1960,7 +1959,6 @@ test "peer type resolution: vector and tuple" {
19601959 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
19611960 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
19621961 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1963 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
19641962
19651963 var vec: @Vector(3, i32) = .{ 1, 2, 3 };
19661964 _ = &vec;
test/behavior/destructure.zig-2
......@@ -23,8 +23,6 @@ test "simple destructure" {
2323}
2424
2525test "destructure with comptime syntax" {
26 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
27
2826 const S = struct {
2927 fn doTheTest() !void {
3028 {
test/behavior/enum.zig-1
......@@ -1076,7 +1076,6 @@ test "enum literal casting to optional" {
10761076 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
10771077 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
10781078 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1079 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
10801079
10811080 var bar: ?Bar = undefined;
10821081 bar = .B;
test/behavior/fn.zig-1
......@@ -181,7 +181,6 @@ test "function with complex callconv and return type expressions" {
181181 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
182182 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
183183 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
184 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
185184
186185 try expect(fComplexCallconvRet(3).x == 9);
187186}
test/behavior/for.zig-2
......@@ -112,7 +112,6 @@ test "for with null and T peer types and inferred result location type" {
112112 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
113113 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
114114 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
115 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
116115
117116 const S = struct {
118117 fn doTheTest(slice: []const u8) !void {
......@@ -228,7 +227,6 @@ test "else continue outer for" {
228227
229228test "for loop with else branch" {
230229 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
231 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
232230
233231 {
234232 var x = [_]u32{ 1, 2 };
test/behavior/if.zig-3
......@@ -82,7 +82,6 @@ test "const result loc, runtime if cond, else unreachable" {
8282test "if copies its payload" {
8383 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
8484 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
85 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
8685
8786 const S = struct {
8887 fn doTheTest() !void {
......@@ -147,8 +146,6 @@ test "if-else expression with runtime condition result location is inferred opti
147146}
148147
149148test "result location with inferred type ends up being pointer to comptime_int" {
150 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
151
152149 var a: ?u32 = 1234;
153150 var b: u32 = 2000;
154151 _ = .{ &a, &b };
test/behavior/math.zig+6-3
......@@ -689,6 +689,8 @@ fn testSignedWrappingEval(x: i32) !void {
689689}
690690
691691test "signed negation wrapping" {
692 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
693
692694 try testSignedNegationWrappingEval(minInt(i16));
693695 try comptime testSignedNegationWrappingEval(minInt(i16));
694696}
......@@ -699,6 +701,8 @@ fn testSignedNegationWrappingEval(x: i16) !void {
699701}
700702
701703test "unsigned negation wrapping" {
704 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
705
702706 try testUnsignedNegationWrappingEval(1);
703707 try comptime testUnsignedNegationWrappingEval(1);
704708}
......@@ -725,7 +729,6 @@ fn negateWrap(comptime T: type, x: T) T {
725729test "unsigned 64-bit division" {
726730 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
727731 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
728 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
729732
730733 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isMIPS()) {
731734 // https://github.com/ziglang/zig/issues/16846
......@@ -838,7 +841,6 @@ test "@addWithOverflow" {
838841 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
839842 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
840843 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
841 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
842844
843845 try testAddWithOverflow(u8, 250, 100, 94, 1);
844846 try testAddWithOverflow(u8, 100, 150, 250, 0);
......@@ -927,7 +929,6 @@ fn testMulWithOverflow(comptime T: type, a: T, b: T, mul: T, bit: u1) !void {
927929test "basic @mulWithOverflow" {
928930 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
929931 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
930 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
931932
932933 try testMulWithOverflow(u8, 86, 3, 2, 1);
933934 try testMulWithOverflow(u8, 85, 3, 255, 0);
......@@ -1330,6 +1331,8 @@ test "quad hex float literal parsing accurate" {
13301331}
13311332
13321333test "truncating shift left" {
1334 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1335
13331336 try testShlTrunc(maxInt(u16));
13341337 try comptime testShlTrunc(maxInt(u16));
13351338}
test/behavior/null.zig-1
......@@ -188,7 +188,6 @@ test "unwrap optional which is field of global var" {
188188 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
189189 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
190190 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
191 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
192191
193192 struct_with_optional.field = null;
194193 if (struct_with_optional.field) |payload| {
test/behavior/optional.zig-3
......@@ -134,7 +134,6 @@ test "nested optional field in struct" {
134134 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
135135 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
136136 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
137 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
138137
139138 const S2 = struct {
140139 y: u8,
......@@ -287,7 +286,6 @@ test "nested orelse" {
287286test "self-referential struct through a slice of optional" {
288287 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
289288 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
290 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
291289
292290 const S = struct {
293291 const Node = struct {
......@@ -566,7 +564,6 @@ test "Optional slice passed to function" {
566564test "peer type resolution in nested if expressions" {
567565 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
568566 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
569 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
570567
571568 const Thing = struct { n: i32 };
572569 var a = false;
test/behavior/packed-struct.zig-1
......@@ -1096,7 +1096,6 @@ test "packed struct used as part of anon decl name" {
10961096 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
10971097 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
10981098 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1099 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
11001099
11011100 const S = packed struct { a: u0 = 0 };
11021101 var a: u8 = 0;
test/behavior/struct.zig-1
......@@ -1573,7 +1573,6 @@ test "no dependency loop on optional field wrapped in generic function" {
15731573test "optional field init with tuple" {
15741574 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
15751575 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1576 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
15771576
15781577 const S = struct {
15791578 a: ?struct { b: u32 },
test/behavior/switch.zig-1
......@@ -516,7 +516,6 @@ test "switch with null and T peer types and inferred result location type" {
516516 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
517517 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
518518 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
519 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
520519
521520 const S = struct {
522521 fn doTheTest(c: u8) !void {
test/behavior/threadlocal.zig-2
......@@ -6,7 +6,6 @@ test "thread local variable" {
66 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
77 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
88 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
9 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
109 if (builtin.zig_backend == .stage2_llvm) switch (builtin.cpu.arch) {
1110 .x86_64, .x86 => {},
1211 else => return error.SkipZigTest,
......@@ -47,7 +46,6 @@ test "reference a global threadlocal variable" {
4746 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
4847 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
4948 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
50 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
5149 if (builtin.zig_backend == .stage2_llvm) switch (builtin.cpu.arch) {
5250 .x86_64, .x86 => {},
5351 else => return error.SkipZigTest,
test/behavior/while.zig-1
......@@ -106,7 +106,6 @@ fn testBreakOuter() void {
106106test "while copies its payload" {
107107 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
108108 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
109 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
110109
111110 const S = struct {
112111 fn doTheTest() !void {