| author | |
| committer | |
| log | 8d30fc45c424ed1aaf9067436a64b0744619c250 |
| tree | 69d6d86af25281f7d999990629305da76ff9913b |
| parent | 9766b68c475438e24885dd75cf137d51e72ccfa3 |
| signature |
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 | }; |
| 276 | 277 | ||
| ... | @@ -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 {}; |
| 283 | 284 | ||
| 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 | } |
| 776 | 776 | ||
| 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 | } |
| 788 | 781 |
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 { |
| 159 | 159 | ||
| 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 | }; |
| 164 | 164 | ||
| 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}; |
| 51 | pt: Zcu.PerThread, | 51 | pt: Zcu.PerThread, |
| 52 | air: Air, | 52 | air: Air, |
| 53 | liveness: Liveness, | 53 | liveness: Liveness, |
| 54 | zcu: *Zcu, | ||
| 55 | bin_file: *link.File, | 54 | bin_file: *link.File, |
| 56 | gpa: Allocator, | 55 | gpa: Allocator, |
| 57 | 56 | ||
| ... | @@ -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 offsettable | 270 | 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 | } |
| 947 | fn fmtDecl(func: *Func, decl_index: InternPool.DeclIndex) std.fmt.Formatter(formatDecl) { | 945 | fn 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, | ||
| 1328 | 1327 | ||
| 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), |
| 1346 | 1345 | ||
| 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 }); |
| 2154 | 2152 | // 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 | } |
| 2160 | 2163 | ||
| 2161 | fn airIntFromBool(func: *Func, inst: Air.Inst.Index) !void { | 2164 | fn 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 | } |
| 2314 | 2314 | ||
| ... | @@ -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 | ); |
| 2393 | 2394 | ||
| 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 | }; |
| 2414 | 2428 | ||
| ... | @@ -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); |
| 2638 | 2638 | ||
| 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 | }, |
| 2670 | 2663 | ||
| 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); |
| 2812 | 2805 | ||
| 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 | ); |
| 2823 | 2812 | ||
| 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); |
| 2826 | 2819 | ||
| 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 | |
| 3034 | 3030 | // 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); |
| 3037 | 3033 | 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 }, |
| 3040 | 3036 | 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 }, |
| 3050 | 3046 | ); | |
| 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); |
| 4060 | 4039 | ||
| 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, |
| 4974 | 4953 | ||
| 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 | }, |
| 5000 | 4997 | ||
| 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 | } |
| 6557 | 6554 | ||
| 6558 | fn airAtomicLoad(func: *Func, inst: Air.Inst.Index) !void { | 6555 | fn 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; |
| 6562 | 6560 | ||
| ... | @@ -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); |
| 6566 | 6564 | ||
| 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 bytes | 6569 | assert(result_mcv == .register); // should be less than 8 bytes |
| 6569 | 6570 | ||
| ... | @@ -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); |
| 6618 | 6619 | ||
| 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 | } |
| 62 | 62 | ||
| 63 | pub fn defaultSingleThreaded(target: std.Target) bool { | 63 | pub 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 | } |
| 17 | 17 | ||
| 18 | test "large alignment of local constant" { | 18 | test "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; // flaky | 21 | 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 | } |
| 17 | 17 | ||
| 18 | test "truncate" { | 18 | test "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; // TODO | 441 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 442 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 442 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 443 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 443 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 444 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 445 | 444 | ||
| 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; // TODO | 1845 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1846 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1846 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1847 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1847 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1848 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 1849 | 1848 | ||
| 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; // TODO | 1959 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1961 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1960 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1962 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1961 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1963 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 1964 | 1962 | ||
| 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 | } |
| 24 | 24 | ||
| 25 | test "destructure with comptime syntax" { | 25 | test "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; // TODO | 1078 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 1079 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 1080 | 1079 | ||
| 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; // TODO | 183 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 184 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 185 | 184 | ||
| 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; // TODO | 114 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 115 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 116 | 115 | ||
| 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" { |
| 228 | 227 | ||
| 229 | test "for loop with else branch" { | 228 | test "for loop with else branch" { |
| 230 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 229 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 231 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 232 | 230 | ||
| 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" { |
| 82 | test "if copies its payload" { | 82 | test "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; // TODO | 84 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 85 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 86 | 85 | ||
| 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 | } |
| 148 | 147 | ||
| 149 | test "result location with inferred type ends up being pointer to comptime_int" { | 148 | test "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 | } |
| 690 | 690 | ||
| 691 | test "signed negation wrapping" { | 691 | test "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 | } |
| 700 | 702 | ||
| 701 | test "unsigned negation wrapping" { | 703 | test "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 { |
| 725 | test "unsigned 64-bit division" { | 729 | test "unsigned 64-bit division" { |
| 726 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 730 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 727 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 731 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 728 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 729 | 732 | ||
| 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/16846 | 734 | // 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; // TODO | 841 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 839 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 842 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 840 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 843 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 841 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 842 | 844 | ||
| 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 { |
| 927 | test "basic @mulWithOverflow" { | 929 | test "basic @mulWithOverflow" { |
| 928 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 930 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 929 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 931 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 930 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 931 | 932 | ||
| 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 | } |
| 1331 | 1332 | ||
| 1332 | test "truncating shift left" { | 1333 | test "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; // TODO | 190 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 191 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 192 | 191 | ||
| 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; // TODO | 135 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 136 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 136 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 137 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 138 | 137 | ||
| 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" { |
| 287 | test "self-referential struct through a slice of optional" { | 286 | test "self-referential struct through a slice of optional" { |
| 288 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 287 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 289 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 288 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 290 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 291 | 289 | ||
| 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" { |
| 566 | test "peer type resolution in nested if expressions" { | 564 | test "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; | ||
| 570 | 567 | ||
| 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; // TODO | 1096 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1097 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1097 | 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; | ||
| 1100 | 1099 | ||
| 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" { |
| 1573 | test "optional field init with tuple" { | 1573 | test "optional field init with tuple" { |
| 1574 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1574 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1575 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1575 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1576 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 1577 | 1576 | ||
| 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; // TODO | 516 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 517 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 517 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 518 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 518 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 519 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 520 | 519 | ||
| 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; // TODO | 6 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 7 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 7 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 8 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 8 | 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; // TODO | 46 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 48 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 47 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 49 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 48 | 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 { |
| 106 | test "while copies its payload" { | 106 | test "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; // TODO | 108 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 109 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 110 | 109 | ||
| 111 | const S = struct { | 110 | const S = struct { |
| 112 | fn doTheTest() !void { | 111 | fn doTheTest() !void { |