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 {...@@ -271,6 +271,7 @@ pub fn mainSimple() anyerror!void {
271 };271 };
272 // is the backend capable of using std.fmt.format to print a summary at the end?272 // is the backend capable of using std.fmt.format to print a summary at the end?
273 const print_summary = switch (builtin.zig_backend) {273 const print_summary = switch (builtin.zig_backend) {
274 .stage2_riscv64 => true,
274 else => false,275 else => false,
275 };276 };
276277
...@@ -282,11 +283,13 @@ pub fn mainSimple() anyerror!void {...@@ -282,11 +283,13 @@ pub fn mainSimple() anyerror!void {
282 const stderr = if (comptime enable_print) std.io.getStdErr() else {};283 const stderr = if (comptime enable_print) std.io.getStdErr() else {};
283284
284 for (builtin.test_functions) |test_fn| {285 for (builtin.test_functions) |test_fn| {
285 if (enable_print) {286 if (test_fn.func()) |_| {
286 stderr.writeAll(test_fn.name) catch {};287 if (enable_print) {
287 stderr.writeAll("... ") catch {};288 stderr.writeAll(test_fn.name) catch {};
288 }289 stderr.writeAll("... ") catch {};
289 test_fn.func() catch |err| {290 stderr.writeAll("PASS\n") catch {};
291 }
292 } else |err| if (enable_print) {
290 if (enable_print) {293 if (enable_print) {
291 stderr.writeAll(test_fn.name) catch {};294 stderr.writeAll(test_fn.name) catch {};
292 stderr.writeAll("... ") catch {};295 stderr.writeAll("... ") catch {};
...@@ -300,8 +303,7 @@ pub fn mainSimple() anyerror!void {...@@ -300,8 +303,7 @@ pub fn mainSimple() anyerror!void {
300 if (enable_print) stderr.writeAll("SKIP\n") catch {};303 if (enable_print) stderr.writeAll("SKIP\n") catch {};
301 skipped += 1;304 skipped += 1;
302 continue;305 continue;
303 };306 }
304 if (enable_print) stderr.writeAll("PASS\n") catch {};
305 passed += 1;307 passed += 1;
306 }308 }
307 if (enable_print and print_summary) {309 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...@@ -775,14 +775,7 @@ pub fn default_panic(msg: []const u8, error_return_trace: ?*StackTrace, ret_addr
775 }775 }
776776
777 if (builtin.zig_backend == .stage2_riscv64) {777 if (builtin.zig_backend == .stage2_riscv64) {
778 asm volatile ("ecall"778 std.debug.print("panic: {s}\n", .{msg});
779 :
780 : [number] "{a7}" (64),
781 [arg1] "{a0}" (1),
782 [arg2] "{a1}" (@intFromPtr(msg.ptr)),
783 [arg3] "{a2}" (msg.len),
784 : "memory"
785 );
786 std.posix.exit(127);779 std.posix.exit(127);
787 }780 }
788781
src/Package/Module.zig+1-1
...@@ -159,7 +159,7 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module {...@@ -159,7 +159,7 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module {
159159
160 if (options.inherited.single_threaded) |x| break :b x;160 if (options.inherited.single_threaded) |x| break :b x;
161 if (options.parent) |p| break :b p.single_threaded;161 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);
163 };163 };
164164
165 const error_tracing = b: {165 const error_tracing = b: {
src/arch/riscv64/CodeGen.zig+110-106
...@@ -51,7 +51,6 @@ const InnerError = CodeGenError || error{OutOfRegisters};...@@ -51,7 +51,6 @@ const InnerError = CodeGenError || error{OutOfRegisters};
51pt: Zcu.PerThread,51pt: Zcu.PerThread,
52air: Air,52air: Air,
53liveness: Liveness,53liveness: Liveness,
54zcu: *Zcu,
55bin_file: *link.File,54bin_file: *link.File,
56gpa: Allocator,55gpa: Allocator,
5756
...@@ -264,13 +263,13 @@ const MCValue = union(enum) {...@@ -264,13 +263,13 @@ const MCValue = union(enum) {
264 .register_pair,263 .register_pair,
265 .memory,264 .memory,
266 .indirect,265 .indirect,
267 .load_frame,
268 .load_symbol,266 .load_symbol,
269 .lea_symbol,267 .lea_symbol,
270 => switch (off) {268 => switch (off) {
271 0 => mcv,269 0 => mcv,
272 else => unreachable, // not offsettable270 else => unreachable,
273 },271 },
272 .load_frame => |frame| .{ .load_frame = .{ .index = frame.index, .off = frame.off + off } },
274 .immediate => |imm| .{ .immediate = @bitCast(@as(i64, @bitCast(imm)) +% off) },273 .immediate => |imm| .{ .immediate = @bitCast(@as(i64, @bitCast(imm)) +% off) },
275 .register => |reg| .{ .register_offset = .{ .reg = reg, .off = off } },274 .register => |reg| .{ .register_offset = .{ .reg = reg, .off = off } },
276 .register_offset => |reg_off| .{ .register_offset = .{ .reg = reg_off.reg, .off = reg_off.off + off } },275 .register_offset => |reg_off| .{ .register_offset = .{ .reg = reg_off.reg, .off = reg_off.off + off } },
...@@ -737,7 +736,6 @@ pub fn generate(...@@ -737,7 +736,6 @@ pub fn generate(
737 .air = air,736 .air = air,
738 .pt = pt,737 .pt = pt,
739 .mod = mod,738 .mod = mod,
740 .zcu = zcu,
741 .bin_file = bin_file,739 .bin_file = bin_file,
742 .liveness = liveness,740 .liveness = liveness,
743 .target = target,741 .target = target,
...@@ -946,7 +944,7 @@ fn formatDecl(...@@ -946,7 +944,7 @@ fn formatDecl(
946}944}
947fn fmtDecl(func: *Func, decl_index: InternPool.DeclIndex) std.fmt.Formatter(formatDecl) {945fn fmtDecl(func: *Func, decl_index: InternPool.DeclIndex) std.fmt.Formatter(formatDecl) {
948 return .{ .data = .{946 return .{ .data = .{
949 .zcu = func.zcu,947 .zcu = func.pt.zcu,
950 .decl_index = decl_index,948 .decl_index = decl_index,
951 } };949 } };
952}950}
...@@ -1325,6 +1323,7 @@ fn genBody(func: *Func, body: []const Air.Inst.Index) InnerError!void {...@@ -1325,6 +1323,7 @@ fn genBody(func: *Func, body: []const Air.Inst.Index) InnerError!void {
1325 .mul,1323 .mul,
1326 .mul_wrap,1324 .mul_wrap,
1327 .div_trunc, 1325 .div_trunc,
1326 .rem,
13281327
1329 .shl, .shl_exact,1328 .shl, .shl_exact,
1330 .shr, .shr_exact,1329 .shr, .shr_exact,
...@@ -1344,7 +1343,6 @@ fn genBody(func: *Func, body: []const Air.Inst.Index) InnerError!void {...@@ -1344,7 +1343,6 @@ fn genBody(func: *Func, body: []const Air.Inst.Index) InnerError!void {
1344 .ptr_add,1343 .ptr_add,
1345 .ptr_sub => try func.airPtrArithmetic(inst, tag),1344 .ptr_sub => try func.airPtrArithmetic(inst, tag),
13461345
1347 .rem,
1348 .mod,1346 .mod,
1349 .div_float, 1347 .div_float,
1350 .div_floor, 1348 .div_floor,
...@@ -2151,11 +2149,16 @@ fn airTrunc(func: *Func, inst: Air.Inst.Index) !void {...@@ -2151,11 +2149,16 @@ fn airTrunc(func: *Func, inst: Air.Inst.Index) !void {
2151 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;2149 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
2152 if (func.liveness.isUnused(inst))2150 if (func.liveness.isUnused(inst))
2153 return func.finishAir(inst, .unreach, .{ ty_op.operand, .none, .none });2151 return func.finishAir(inst, .unreach, .{ ty_op.operand, .none, .none });
21542152 // we assume no zeroext in the "Zig ABI", so it's fine to just not truncate it.
2155 const operand = try func.resolveInst(ty_op.operand);2153 const operand = try func.resolveInst(ty_op.operand);
2156 _ = operand;2154
2157 return func.fail("TODO implement trunc for {}", .{func.target.cpu.arch});2155 // we can do it just to be safe, but this shouldn't be needed for no-runtime safety modes
2158 // return func.finishAir(inst, result, .{ ty_op.operand, .none, .none });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 });
2159}2162}
21602163
2161fn airIntFromBool(func: *Func, inst: Air.Inst.Index) !void {2164fn airIntFromBool(func: *Func, inst: Air.Inst.Index) !void {
...@@ -2305,10 +2308,7 @@ fn binOp(...@@ -2305,10 +2308,7 @@ fn binOp(
2305 80, 128 => true,2308 80, 128 => true,
2306 else => unreachable,2309 else => unreachable,
2307 };2310 };
2308 switch (air_tag) {2311 if (!type_needs_libcall) break :libcall;
2309 .rem, .mod => {},
2310 else => if (!type_needs_libcall) break :libcall,
2311 }
2312 return func.fail("binOp libcall runtime-float ops", .{});2312 return func.fail("binOp libcall runtime-float ops", .{});
2313 }2313 }
23142314
...@@ -2384,6 +2384,7 @@ fn genBinOp(...@@ -2384,6 +2384,7 @@ fn genBinOp(
2384 .sub_wrap,2384 .sub_wrap,
2385 .mul,2385 .mul,
2386 .mul_wrap,2386 .mul_wrap,
2387 .rem,
2387 => {2388 => {
2388 if (!math.isPowerOfTwo(bit_size))2389 if (!math.isPowerOfTwo(bit_size))
2389 return func.fail(2390 return func.fail(
...@@ -2391,6 +2392,15 @@ fn genBinOp(...@@ -2391,6 +2392,15 @@ fn genBinOp(
2391 .{ @tagName(tag), bit_size },2392 .{ @tagName(tag), bit_size },
2392 );2393 );
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
2394 switch (lhs_ty.zigTypeTag(zcu)) {2404 switch (lhs_ty.zigTypeTag(zcu)) {
2395 .Int => {2405 .Int => {
2396 const mir_tag: Mir.Inst.Tag = switch (tag) {2406 const mir_tag: Mir.Inst.Tag = switch (tag) {
...@@ -2409,6 +2419,10 @@ fn genBinOp(...@@ -2409,6 +2419,10 @@ fn genBinOp(
2409 32 => .mulw,2419 32 => .mulw,
2410 else => unreachable,2420 else => unreachable,
2411 },2421 },
2422 .rem => switch (bit_size) {
2423 64 => if (is_unsigned) .remu else .rem,
2424 else => if (is_unsigned) .remuw else .remu,
2425 },
2412 else => unreachable,2426 else => unreachable,
2413 };2427 };
24142428
...@@ -2423,14 +2437,6 @@ fn genBinOp(...@@ -2423,14 +2437,6 @@ fn genBinOp(
2423 },2437 },
2424 },2438 },
2425 });2439 });
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 }
2434 },2440 },
2435 .Float => {2441 .Float => {
2436 const mir_tag: Mir.Inst.Tag = switch (tag) {2442 const mir_tag: Mir.Inst.Tag = switch (tag) {
...@@ -2627,23 +2633,17 @@ fn genBinOp(...@@ -2627,23 +2633,17 @@ fn genBinOp(
2627 .shl,2633 .shl,
2628 .shl_exact,2634 .shl_exact,
2629 => {2635 => {
2630 if (!math.isPowerOfTwo(bit_size))2636 if (bit_size > 64) return func.fail("TODO: genBinOp shift > 64 bits, {}", .{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
2637 try func.truncateRegister(rhs_ty, rhs_reg);2637 try func.truncateRegister(rhs_ty, rhs_reg);
26382638
2639 const mir_tag: Mir.Inst.Tag = switch (tag) {2639 const mir_tag: Mir.Inst.Tag = switch (tag) {
2640 .shl, .shl_exact => switch (bit_size) {2640 .shl, .shl_exact => switch (bit_size) {
2641 8, 16, 64 => .sll,2641 1...31, 33...64 => .sll,
2642 32 => .sllw,2642 32 => .sllw,
2643 else => unreachable,2643 else => unreachable,
2644 },2644 },
2645 .shr, .shr_exact => switch (bit_size) {2645 .shr, .shr_exact => switch (bit_size) {
2646 8, 16, 64 => .srl,2646 1...31, 33...64 => .srl,
2647 32 => .srlw,2647 32 => .srlw,
2648 else => unreachable,2648 else => unreachable,
2649 },2649 },
...@@ -2659,13 +2659,6 @@ fn genBinOp(...@@ -2659,13 +2659,6 @@ fn genBinOp(
2659 .rs2 = rhs_reg,2659 .rs2 = rhs_reg,
2660 } },2660 } },
2661 });2661 });
2662
2663 switch (bit_size) {
2664 8, 16 => try func.truncateRegister(lhs_ty, dst_reg),
2665 32 => {},
2666 64 => {},
2667 else => unreachable,
2668 }
2669 },2662 },
26702663
2671 // TODO: move the isel logic out of lower and into here.2664 // TODO: move the isel logic out of lower and into here.
...@@ -2810,10 +2803,6 @@ fn airAddWithOverflow(func: *Func, inst: Air.Inst.Index) !void {...@@ -2810,10 +2803,6 @@ fn airAddWithOverflow(func: *Func, inst: Air.Inst.Index) !void {
2810 if (int_info.bits >= 8 and math.isPowerOfTwo(int_info.bits)) {2803 if (int_info.bits >= 8 and math.isPowerOfTwo(int_info.bits)) {
2811 const add_result = try func.binOp(null, .add, extra.lhs, extra.rhs);2804 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
2817 try func.genSetMem(2806 try func.genSetMem(
2818 .{ .frame = offset.index },2807 .{ .frame = offset.index },
2819 offset.off + @as(i32, @intCast(tuple_ty.structFieldOffset(0, pt))),2808 offset.off + @as(i32, @intCast(tuple_ty.structFieldOffset(0, pt))),
...@@ -2821,14 +2810,21 @@ fn airAddWithOverflow(func: *Func, inst: Air.Inst.Index) !void {...@@ -2821,14 +2810,21 @@ fn airAddWithOverflow(func: *Func, inst: Air.Inst.Index) !void {
2821 add_result,2810 add_result,
2822 );2811 );
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
2824 const overflow_reg, const overflow_lock = try func.allocReg(.int);2817 const overflow_reg, const overflow_lock = try func.allocReg(.int);
2825 defer func.register_manager.unlockReg(overflow_lock);2818 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);
2827 try func.genBinOp(2823 try func.genBinOp(
2828 .cmp_neq,2824 .cmp_neq,
2829 .{ .register = add_result_reg },2825 add_result,
2830 ty,2826 ty,
2831 .{ .register = add_result_reg },2827 .{ .register = trunc_reg },
2832 ty,2828 ty,
2833 overflow_reg,2829 overflow_reg,
2834 );2830 );
...@@ -3022,61 +3018,34 @@ fn airMulWithOverflow(func: *Func, inst: Air.Inst.Index) !void {...@@ -3022,61 +3018,34 @@ fn airMulWithOverflow(func: *Func, inst: Air.Inst.Index) !void {
3022 switch (lhs_ty.zigTypeTag(zcu)) {3018 switch (lhs_ty.zigTypeTag(zcu)) {
3023 else => |x| return func.fail("TODO: airMulWithOverflow {s}", .{@tagName(x)}),3019 else => |x| return func.fail("TODO: airMulWithOverflow {s}", .{@tagName(x)}),
3024 .Int => {3020 .Int => {
3025 assert(lhs_ty.eql(rhs_ty, zcu));3021 if (std.debug.runtime_safety) assert(lhs_ty.eql(rhs_ty, zcu));
3026 const int_info = lhs_ty.intInfo(zcu);3022
3027 switch (int_info.bits) {3023 const trunc_reg = try func.copyToTmpRegister(lhs_ty, .{ .register = dest_reg });
3028 1...32 => {3024 const trunc_reg_lock = func.register_manager.lockRegAssumeUnused(trunc_reg);
3029 if (int_info.bits >= 8 and math.isPowerOfTwo(int_info.bits)) {3025 defer func.register_manager.unlockReg(trunc_reg_lock);
3030 if (int_info.signedness == .unsigned) {3026
3031 switch (int_info.bits) {3027 const overflow_reg, const overflow_lock = try func.allocReg(.int);
3032 1...8 => {3028 defer func.register_manager.unlockReg(overflow_lock);
3033 const max_val = std.math.pow(u16, 2, int_info.bits) - 1;3029
30343030 // if the result isn't equal after truncating it to the given type,
3035 const add_reg, const add_lock = try func.promoteReg(lhs_ty, lhs);3031 // an overflow must have happened.
3036 defer if (add_lock) |lock| func.register_manager.unlockReg(lock);3032 try func.truncateRegister(func.typeOf(extra.lhs), trunc_reg);
30373033 try func.genBinOp(
3038 const overflow_reg, const overflow_lock = try func.allocReg(.int);3034 .cmp_neq,
3039 defer func.register_manager.unlockReg(overflow_lock);3035 .{ .register = dest_reg },
30403036 lhs_ty,
3041 _ = try func.addInst(.{3037 .{ .register = trunc_reg },
3042 .tag = .andi,3038 rhs_ty,
3043 .ops = .rri,3039 overflow_reg,
3044 .data = .{ .i_type = .{3040 );
3045 .rd = overflow_reg,3041
3046 .rs1 = add_reg,3042 try func.genCopy(
3047 .imm12 = Immediate.s(max_val),3043 lhs_ty,
3048 } },3044 result_mcv.offset(overflow_off),
3049 });3045 .{ .register = overflow_reg },
30503046 );
3051 try func.genBinOp(3047
3052 .cmp_neq,3048 break :result result_mcv;
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 }
3080 },3049 },
3081 }3050 }
3082 };3051 };
...@@ -3317,7 +3286,17 @@ fn airWrapOptional(func: *Func, inst: Air.Inst.Index) !void {...@@ -3317,7 +3286,17 @@ fn airWrapOptional(func: *Func, inst: Air.Inst.Index) !void {
3317 Type.u8,3286 Type.u8,
3318 .{ .immediate = 1 },3287 .{ .immediate = 1 },
3319 ),3288 ),
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 },
3321 else => unreachable,3300 else => unreachable,
3322 }3301 }
3323 }3302 }
...@@ -4059,7 +4038,7 @@ fn airLoad(func: *Func, inst: Air.Inst.Index) !void {...@@ -4059,7 +4038,7 @@ fn airLoad(func: *Func, inst: Air.Inst.Index) !void {
4059 const elem_size = elem_ty.abiSize(pt);4038 const elem_size = elem_ty.abiSize(pt);
40604039
4061 const dst_mcv: MCValue = blk: {4040 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.
4063 if (elem_size <= 8 and func.reuseOperand(inst, ty_op.operand, 0, ptr)) {4042 if (elem_size <= 8 and func.reuseOperand(inst, ty_op.operand, 0, ptr)) {
4064 // The MCValue that holds the pointer can be re-used as the value.4043 // The MCValue that holds the pointer can be re-used as the value.
4065 break :blk ptr;4044 break :blk ptr;
...@@ -4970,7 +4949,7 @@ fn isNull(func: *Func, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC...@@ -4970,7 +4949,7 @@ fn isNull(func: *Func, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
4970 .lea_symbol,4949 .lea_symbol,
4971 .reserved_frame,4950 .reserved_frame,
4972 .air_ref,4951 .air_ref,
4973 => return func.fail("TODO: hmm {}", .{opt_mcv}),4952 => unreachable,
49744953
4975 .register => |opt_reg| {4954 .register => |opt_reg| {
4976 if (some_info.off == 0) {4955 if (some_info.off == 0) {
...@@ -4993,9 +4972,27 @@ fn isNull(func: *Func, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC...@@ -4993,9 +4972,27 @@ fn isNull(func: *Func, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
4993 return return_mcv;4972 return return_mcv;
4994 }4973 }
4995 assert(some_info.ty.ip_index == .bool_type);4974 assert(some_info.ty.ip_index == .bool_type);
4996 const opt_abi_size: u32 = @intCast(opt_ty.abiSize(pt));4975 const bit_offset: u7 = @intCast(some_info.off * 8);
4997 _ = opt_abi_size;4976
4998 return func.fail("TODO: isNull some_info.off != 0 register", .{});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;
4999 },4996 },
50004997
5001 .load_frame => {4998 .load_frame => {
...@@ -6556,7 +6553,8 @@ fn airAtomicRmw(func: *Func, inst: Air.Inst.Index) !void {...@@ -6556,7 +6553,8 @@ fn airAtomicRmw(func: *Func, inst: Air.Inst.Index) !void {
6556}6553}
65576554
6558fn airAtomicLoad(func: *Func, inst: Air.Inst.Index) !void {6555fn airAtomicLoad(func: *Func, inst: Air.Inst.Index) !void {
6559 const zcu = func.pt.zcu;6556 const pt = func.pt;
6557 const zcu = pt.zcu;
6560 const atomic_load = func.air.instructions.items(.data)[@intFromEnum(inst)].atomic_load;6558 const atomic_load = func.air.instructions.items(.data)[@intFromEnum(inst)].atomic_load;
6561 const order: std.builtin.AtomicOrder = atomic_load.order;6559 const order: std.builtin.AtomicOrder = atomic_load.order;
65626560
...@@ -6564,6 +6562,9 @@ fn airAtomicLoad(func: *Func, inst: Air.Inst.Index) !void {...@@ -6564,6 +6562,9 @@ fn airAtomicLoad(func: *Func, inst: Air.Inst.Index) !void {
6564 const elem_ty = ptr_ty.childType(zcu);6562 const elem_ty = ptr_ty.childType(zcu);
6565 const ptr_mcv = try func.resolveInst(atomic_load.ptr);6563 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
6567 const result_mcv = try func.allocRegOrMem(elem_ty, inst, true);6568 const result_mcv = try func.allocRegOrMem(elem_ty, inst, true);
6568 assert(result_mcv == .register); // should be less than 8 bytes6569 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...@@ -6616,6 +6617,9 @@ fn airAtomicStore(func: *Func, inst: Air.Inst.Index, order: std.builtin.AtomicOr
6616 const val_ty = func.typeOf(bin_op.rhs);6617 const val_ty = func.typeOf(bin_op.rhs);
6617 const val_mcv = try func.resolveInst(bin_op.rhs);6618 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
6619 switch (order) {6623 switch (order) {
6620 .unordered, .monotonic => {},6624 .unordered, .monotonic => {},
6621 .release, .seq_cst => {6625 .release, .seq_cst => {
src/target.zig+2-1
...@@ -60,9 +60,10 @@ pub fn alwaysSingleThreaded(target: std.Target) bool {...@@ -60,9 +60,10 @@ pub fn alwaysSingleThreaded(target: std.Target) bool {
60 return false;60 return false;
61}61}
6262
63pub fn defaultSingleThreaded(target: std.Target) bool {63pub fn defaultSingleThreaded(target: std.Target, backend: std.builtin.CompilerBackend) bool {
64 switch (target.cpu.arch) {64 switch (target.cpu.arch) {
65 .wasm32, .wasm64 => return true,65 .wasm32, .wasm64 => return true,
66 .riscv64 => if (backend == .stage2_riscv64) return true,
66 else => {},67 else => {},
67 }68 }
68 switch (target.os.tag) {69 switch (target.os.tag) {
test/behavior/align.zig-1
...@@ -16,7 +16,6 @@ test "global variable alignment" {...@@ -16,7 +16,6 @@ test "global variable alignment" {
16}16}
1717
18test "large alignment of local constant" {18test "large alignment of local constant" {
19 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
20 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;19 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
21 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;20 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
22 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // flaky21 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // flaky
test/behavior/basic.zig-2
...@@ -16,8 +16,6 @@ test "empty function with comments" {...@@ -16,8 +16,6 @@ test "empty function with comments" {
16}16}
1717
18test "truncate" {18test "truncate" {
19 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
20
21 try expect(testTruncate(0x10fd) == 0xfd);19 try expect(testTruncate(0x10fd) == 0xfd);
22 comptime assert(testTruncate(0x10fd) == 0xfd);20 comptime assert(testTruncate(0x10fd) == 0xfd);
23}21}
test/behavior/call.zig-1
...@@ -441,7 +441,6 @@ test "non-anytype generic parameters provide result type" {...@@ -441,7 +441,6 @@ test "non-anytype generic parameters provide result type" {
441 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO441 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
442 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO442 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
443 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO443 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
444 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
445444
446 const S = struct {445 const S = struct {
447 fn f(comptime T: type, y: T) !void {446 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...@@ -1845,7 +1845,6 @@ test "peer type resolution: three-way resolution combines error set and optional
1845 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1845 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1846 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1846 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1847 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1847 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1848 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
18491848
1850 const E = error{Foo};1849 const E = error{Foo};
1851 var a: E = error.Foo;1850 var a: E = error.Foo;
...@@ -1960,7 +1959,6 @@ test "peer type resolution: vector and tuple" {...@@ -1960,7 +1959,6 @@ test "peer type resolution: vector and tuple" {
1960 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1959 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1961 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1960 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1962 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1961 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1963 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
19641962
1965 var vec: @Vector(3, i32) = .{ 1, 2, 3 };1963 var vec: @Vector(3, i32) = .{ 1, 2, 3 };
1966 _ = &vec;1964 _ = &vec;
test/behavior/destructure.zig-2
...@@ -23,8 +23,6 @@ test "simple destructure" {...@@ -23,8 +23,6 @@ test "simple destructure" {
23}23}
2424
25test "destructure with comptime syntax" {25test "destructure with comptime syntax" {
26 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
27
28 const S = struct {26 const S = struct {
29 fn doTheTest() !void {27 fn doTheTest() !void {
30 {28 {
test/behavior/enum.zig-1
...@@ -1076,7 +1076,6 @@ test "enum literal casting to optional" {...@@ -1076,7 +1076,6 @@ test "enum literal casting to optional" {
1076 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;1076 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
1077 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1077 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1078 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1078 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1079 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
10801079
1081 var bar: ?Bar = undefined;1080 var bar: ?Bar = undefined;
1082 bar = .B;1081 bar = .B;
test/behavior/fn.zig-1
...@@ -181,7 +181,6 @@ test "function with complex callconv and return type expressions" {...@@ -181,7 +181,6 @@ test "function with complex callconv and return type expressions" {
181 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;181 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
182 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;182 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
183 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO183 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
184 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
185184
186 try expect(fComplexCallconvRet(3).x == 9);185 try expect(fComplexCallconvRet(3).x == 9);
187}186}
test/behavior/for.zig-2
...@@ -112,7 +112,6 @@ test "for with null and T peer types and inferred result location type" {...@@ -112,7 +112,6 @@ test "for with null and T peer types and inferred result location type" {
112 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;112 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
113 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;113 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
114 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO114 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
115 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
116115
117 const S = struct {116 const S = struct {
118 fn doTheTest(slice: []const u8) !void {117 fn doTheTest(slice: []const u8) !void {
...@@ -228,7 +227,6 @@ test "else continue outer for" {...@@ -228,7 +227,6 @@ test "else continue outer for" {
228227
229test "for loop with else branch" {228test "for loop with else branch" {
230 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO229 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
231 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
232230
233 {231 {
234 var x = [_]u32{ 1, 2 };232 var x = [_]u32{ 1, 2 };
test/behavior/if.zig-3
...@@ -82,7 +82,6 @@ test "const result loc, runtime if cond, else unreachable" {...@@ -82,7 +82,6 @@ test "const result loc, runtime if cond, else unreachable" {
82test "if copies its payload" {82test "if copies its payload" {
83 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;83 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
84 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO84 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
85 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
8685
87 const S = struct {86 const S = struct {
88 fn doTheTest() !void {87 fn doTheTest() !void {
...@@ -147,8 +146,6 @@ test "if-else expression with runtime condition result location is inferred opti...@@ -147,8 +146,6 @@ test "if-else expression with runtime condition result location is inferred opti
147}146}
148147
149test "result location with inferred type ends up being pointer to comptime_int" {148test "result location with inferred type ends up being pointer to comptime_int" {
150 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
151
152 var a: ?u32 = 1234;149 var a: ?u32 = 1234;
153 var b: u32 = 2000;150 var b: u32 = 2000;
154 _ = .{ &a, &b };151 _ = .{ &a, &b };
test/behavior/math.zig+6-3
...@@ -689,6 +689,8 @@ fn testSignedWrappingEval(x: i32) !void {...@@ -689,6 +689,8 @@ fn testSignedWrappingEval(x: i32) !void {
689}689}
690690
691test "signed negation wrapping" {691test "signed negation wrapping" {
692 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
693
692 try testSignedNegationWrappingEval(minInt(i16));694 try testSignedNegationWrappingEval(minInt(i16));
693 try comptime testSignedNegationWrappingEval(minInt(i16));695 try comptime testSignedNegationWrappingEval(minInt(i16));
694}696}
...@@ -699,6 +701,8 @@ fn testSignedNegationWrappingEval(x: i16) !void {...@@ -699,6 +701,8 @@ fn testSignedNegationWrappingEval(x: i16) !void {
699}701}
700702
701test "unsigned negation wrapping" {703test "unsigned negation wrapping" {
704 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
705
702 try testUnsignedNegationWrappingEval(1);706 try testUnsignedNegationWrappingEval(1);
703 try comptime testUnsignedNegationWrappingEval(1);707 try comptime testUnsignedNegationWrappingEval(1);
704}708}
...@@ -725,7 +729,6 @@ fn negateWrap(comptime T: type, x: T) T {...@@ -725,7 +729,6 @@ fn negateWrap(comptime T: type, x: T) T {
725test "unsigned 64-bit division" {729test "unsigned 64-bit division" {
726 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO730 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
727 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO731 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
728 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
729732
730 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isMIPS()) {733 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isMIPS()) {
731 // https://github.com/ziglang/zig/issues/16846734 // https://github.com/ziglang/zig/issues/16846
...@@ -838,7 +841,6 @@ test "@addWithOverflow" {...@@ -838,7 +841,6 @@ test "@addWithOverflow" {
838 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO841 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
839 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO842 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
840 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO843 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
841 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
842844
843 try testAddWithOverflow(u8, 250, 100, 94, 1);845 try testAddWithOverflow(u8, 250, 100, 94, 1);
844 try testAddWithOverflow(u8, 100, 150, 250, 0);846 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 {...@@ -927,7 +929,6 @@ fn testMulWithOverflow(comptime T: type, a: T, b: T, mul: T, bit: u1) !void {
927test "basic @mulWithOverflow" {929test "basic @mulWithOverflow" {
928 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO930 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
929 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO931 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
930 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
931932
932 try testMulWithOverflow(u8, 86, 3, 2, 1);933 try testMulWithOverflow(u8, 86, 3, 2, 1);
933 try testMulWithOverflow(u8, 85, 3, 255, 0);934 try testMulWithOverflow(u8, 85, 3, 255, 0);
...@@ -1330,6 +1331,8 @@ test "quad hex float literal parsing accurate" {...@@ -1330,6 +1331,8 @@ test "quad hex float literal parsing accurate" {
1330}1331}
13311332
1332test "truncating shift left" {1333test "truncating shift left" {
1334 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1335
1333 try testShlTrunc(maxInt(u16));1336 try testShlTrunc(maxInt(u16));
1334 try comptime testShlTrunc(maxInt(u16));1337 try comptime testShlTrunc(maxInt(u16));
1335}1338}
test/behavior/null.zig-1
...@@ -188,7 +188,6 @@ test "unwrap optional which is field of global var" {...@@ -188,7 +188,6 @@ test "unwrap optional which is field of global var" {
188 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;188 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
189 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;189 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
190 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO190 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
191 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
192191
193 struct_with_optional.field = null;192 struct_with_optional.field = null;
194 if (struct_with_optional.field) |payload| {193 if (struct_with_optional.field) |payload| {
test/behavior/optional.zig-3
...@@ -134,7 +134,6 @@ test "nested optional field in struct" {...@@ -134,7 +134,6 @@ test "nested optional field in struct" {
134 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;134 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
135 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO135 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
136 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO136 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
137 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
138137
139 const S2 = struct {138 const S2 = struct {
140 y: u8,139 y: u8,
...@@ -287,7 +286,6 @@ test "nested orelse" {...@@ -287,7 +286,6 @@ test "nested orelse" {
287test "self-referential struct through a slice of optional" {286test "self-referential struct through a slice of optional" {
288 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO287 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
289 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO288 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
290 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
291289
292 const S = struct {290 const S = struct {
293 const Node = struct {291 const Node = struct {
...@@ -566,7 +564,6 @@ test "Optional slice passed to function" {...@@ -566,7 +564,6 @@ test "Optional slice passed to function" {
566test "peer type resolution in nested if expressions" {564test "peer type resolution in nested if expressions" {
567 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;565 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
568 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;566 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
569 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
570567
571 const Thing = struct { n: i32 };568 const Thing = struct { n: i32 };
572 var a = false;569 var a = false;
test/behavior/packed-struct.zig-1
...@@ -1096,7 +1096,6 @@ test "packed struct used as part of anon decl name" {...@@ -1096,7 +1096,6 @@ test "packed struct used as part of anon decl name" {
1096 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1096 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1097 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1097 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1098 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;1098 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1099 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
11001099
1101 const S = packed struct { a: u0 = 0 };1100 const S = packed struct { a: u0 = 0 };
1102 var a: u8 = 0;1101 var a: u8 = 0;
test/behavior/struct.zig-1
...@@ -1573,7 +1573,6 @@ test "no dependency loop on optional field wrapped in generic function" {...@@ -1573,7 +1573,6 @@ test "no dependency loop on optional field wrapped in generic function" {
1573test "optional field init with tuple" {1573test "optional field init with tuple" {
1574 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1574 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1575 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1575 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1576 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
15771576
1578 const S = struct {1577 const S = struct {
1579 a: ?struct { b: u32 },1578 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" {...@@ -516,7 +516,6 @@ test "switch with null and T peer types and inferred result location type" {
516 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO516 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
517 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO517 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
518 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO518 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
519 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
520519
521 const S = struct {520 const S = struct {
522 fn doTheTest(c: u8) !void {521 fn doTheTest(c: u8) !void {
test/behavior/threadlocal.zig-2
...@@ -6,7 +6,6 @@ test "thread local variable" {...@@ -6,7 +6,6 @@ test "thread local variable" {
6 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO6 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
7 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO7 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
8 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO8 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
9 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
10 if (builtin.zig_backend == .stage2_llvm) switch (builtin.cpu.arch) {9 if (builtin.zig_backend == .stage2_llvm) switch (builtin.cpu.arch) {
11 .x86_64, .x86 => {},10 .x86_64, .x86 => {},
12 else => return error.SkipZigTest,11 else => return error.SkipZigTest,
...@@ -47,7 +46,6 @@ test "reference a global threadlocal variable" {...@@ -47,7 +46,6 @@ test "reference a global threadlocal variable" {
47 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO46 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
48 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO47 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
49 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO48 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
50 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
51 if (builtin.zig_backend == .stage2_llvm) switch (builtin.cpu.arch) {49 if (builtin.zig_backend == .stage2_llvm) switch (builtin.cpu.arch) {
52 .x86_64, .x86 => {},50 .x86_64, .x86 => {},
53 else => return error.SkipZigTest,51 else => return error.SkipZigTest,
test/behavior/while.zig-1
...@@ -106,7 +106,6 @@ fn testBreakOuter() void {...@@ -106,7 +106,6 @@ fn testBreakOuter() void {
106test "while copies its payload" {106test "while copies its payload" {
107 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;107 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
108 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO108 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
109 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
110109
111 const S = struct {110 const S = struct {
112 fn doTheTest() !void {111 fn doTheTest() !void {