diff --git a/src/codegen/c.zig b/src/codegen/c.zig index 3311a9a25e..d949591a49 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -232,7 +232,7 @@ pub fn generate(file: *C, decl: *Decl) !void { .retvoid => try genRetVoid(file), .arg => try genArg(&ctx), .dbg_stmt => try genDbgStmt(&ctx, inst.castTag(.dbg_stmt).?), - .breakpoint => try genBreak(&ctx, inst.castTag(.breakpoint).?), + .breakpoint => try genBreakpoint(file, inst.castTag(.breakpoint).?), .unreach => try genUnreach(file, inst.castTag(.unreach).?), .intcast => try genIntCast(&ctx, file, inst.castTag(.intcast).?), else => |e| return ctx.fail(decl.src(), "TODO: C backend: implement codegen for {}", .{e}), @@ -447,8 +447,8 @@ fn genDbgStmt(ctx: *Context, inst: *Inst.NoOp) !?[]u8 { return null; } -fn genBreak(ctx: *Context, inst: *Inst.NoOp) !?[]u8 { - // TODO ?? +fn genBreakpoint(file: *C, inst: *Inst.NoOp) !?[]u8 { + try file.main.writer().writeAll("zig_breakpoint();\n"); return null; } diff --git a/src/link/cbe.h b/src/link/cbe.h index cd37ba2f2e..e62e6766ef 100644 --- a/src/link/cbe.h +++ b/src/link/cbe.h @@ -1,5 +1,4 @@ #if __STDC_VERSION__ >= 199901L -// C99 or newer #include #else #define bool unsigned char @@ -17,12 +16,28 @@ #define zig_noreturn #endif -#if __GNUC__ +#if defined(__GNUC__) #define zig_unreachable() __builtin_unreachable() #else #define zig_unreachable() #endif +#if defined(_MSC_VER) +#define zig_breakpoint __debugbreak() +#else +#if defined(__MINGW32__) || defined(__MINGW64__) +#define zig_breakpoint __debugbreak() +#elif defined(__clang__) +#define zig_breakpoint __builtin_debugtrap() +#elif defined(__GNUC__) +#define zig_breakpoint __builtin_trap() +#elif defined(__i386__) || defined(__x86_64__) +#define zig_breakpoint __asm__ volatile("int $0x03"); +#else +#define zig_breakpoint raise(SIGTRAP) +#endif +#endif + #include #define int128_t __int128 #define uint128_t unsigned __int128 diff --git a/src/test.zig b/src/test.zig index 6deee347af..f4374ea0bd 100644 --- a/src/test.zig +++ b/src/test.zig @@ -646,35 +646,16 @@ pub const TestContext = struct { defer file.close(); var out = file.reader().readAllAlloc(arena, 1024 * 1024) catch @panic("Unable to read headeroutput!"); - if (expected_output.len != out.len) { - std.debug.print("\nTransformed header length differs:\n================\nExpected:\n================\n{}\n================\nFound:\n================\n{}\n================\nTest failed.\n", .{ expected_output, out }); - std.process.exit(1); - } - for (expected_output) |e, i| { - if (out[i] != e) { - std.debug.print("\nTransformed header differs:\n================\nExpected:\n================\n{}\n================\nFound:\n================\n{}\n================\nTest failed.\n", .{ expected_output, out }); - std.process.exit(1); - } - } + std.testing.expectEqualStrings(expected_output, out); }, .Transformation => |expected_output| { if (case.cbe) { // The C file is always closed after an update, because we don't support - // incremental updates + // incremental updates. var file = try tmp.dir.openFile(bin_name, .{ .read = true }); defer file.close(); var out = file.reader().readAllAlloc(arena, 1024 * 1024) catch @panic("Unable to read C output!"); - - if (expected_output.len != out.len) { - std.debug.print("\nTransformed C length differs:\n================\nExpected:\n================\n{}\n================\nFound:\n================\n{}\n================\nTest failed.\n", .{ expected_output, out }); - std.process.exit(1); - } - for (expected_output) |e, i| { - if (out[i] != e) { - std.debug.print("\nTransformed C differs:\n================\nExpected:\n================\n{}\n================\nFound:\n================\n{}\n================\nTest failed.\n", .{ expected_output, out }); - std.process.exit(1); - } - } + std.testing.expectEqualStrings(expected_output, out); } else { update_node.setEstimatedTotalItems(5); var emit_node = update_node.start("emit", 0); @@ -694,16 +675,7 @@ pub const TestContext = struct { test_node.activate(); defer test_node.end(); - if (expected_output.len != out_zir.items.len) { - std.debug.print("{}\nTransformed ZIR length differs:\n================\nExpected:\n================\n{}\n================\nFound:\n================\n{}\n================\nTest failed.\n", .{ case.name, expected_output, out_zir.items }); - std.process.exit(1); - } - for (expected_output) |e, i| { - if (out_zir.items[i] != e) { - std.debug.print("{}\nTransformed ZIR differs:\n================\nExpected:\n================\n{}\n================\nFound:\n================\n{}\n================\nTest failed.\n", .{ case.name, expected_output, out_zir.items }); - std.process.exit(1); - } - } + std.testing.expectEqualStrings(expected_output, out_zir.items); } }, .Error => |e| { diff --git a/test/stage2/cbe.zig b/test/stage2/cbe.zig index 96db7b835e..3a9bff897a 100644 --- a/test/stage2/cbe.zig +++ b/test/stage2/cbe.zig @@ -15,6 +15,7 @@ pub fn addCases(ctx: *TestContext) !void { \\} , \\zig_noreturn void _start(void) { + \\ zig_breakpoint(); \\ zig_unreachable(); \\} \\ @@ -41,6 +42,7 @@ pub fn addCases(ctx: *TestContext) !void { \\} \\ \\zig_noreturn void main(void) { + \\ zig_breakpoint(); \\ zig_unreachable(); \\} \\ @@ -61,8 +63,6 @@ pub fn addCases(ctx: *TestContext) !void { \\ exitGood(); \\} , - \\#include - \\ \\zig_noreturn void exitGood(void); \\ \\const char *const exitGood__anon_0 = "{rax}"; @@ -74,9 +74,10 @@ pub fn addCases(ctx: *TestContext) !void { \\} \\ \\zig_noreturn void exitGood(void) { - \\ register size_t rax_constant __asm__("rax") = 231; - \\ register size_t rdi_constant __asm__("rdi") = 0; + \\ register uintptr_t rax_constant __asm__("rax") = 231; + \\ register uintptr_t rdi_constant __asm__("rdi") = 0; \\ __asm volatile ("syscall" :: ""(rax_constant), ""(rdi_constant)); + \\ zig_breakpoint(); \\ zig_unreachable(); \\} \\ @@ -96,9 +97,7 @@ pub fn addCases(ctx: *TestContext) !void { \\} \\ , - \\#include - \\ - \\zig_noreturn void exit(size_t arg0); + \\zig_noreturn void exit(uintptr_t arg0); \\ \\const char *const exit__anon_0 = "{rax}"; \\const char *const exit__anon_1 = "{rdi}"; @@ -108,10 +107,11 @@ pub fn addCases(ctx: *TestContext) !void { \\ exit(0); \\} \\ - \\zig_noreturn void exit(size_t arg0) { - \\ register size_t rax_constant __asm__("rax") = 231; - \\ register size_t rdi_constant __asm__("rdi") = arg0; + \\zig_noreturn void exit(uintptr_t arg0) { + \\ register uintptr_t rax_constant __asm__("rax") = 231; + \\ register uintptr_t rdi_constant __asm__("rdi") = arg0; \\ __asm volatile ("syscall" :: ""(rax_constant), ""(rdi_constant)); + \\ zig_breakpoint(); \\ zig_unreachable(); \\} \\ @@ -131,7 +131,6 @@ pub fn addCases(ctx: *TestContext) !void { \\} \\ , - \\#include \\#include \\ \\zig_noreturn void exit(uint8_t arg0); @@ -145,10 +144,11 @@ pub fn addCases(ctx: *TestContext) !void { \\} \\ \\zig_noreturn void exit(uint8_t arg0) { - \\ const size_t __temp_0 = (size_t)arg0; - \\ register size_t rax_constant __asm__("rax") = 231; - \\ register size_t rdi_constant __asm__("rdi") = __temp_0; + \\ const uintptr_t __temp_0 = (uintptr_t)arg0; + \\ register uintptr_t rax_constant __asm__("rax") = 231; + \\ register uintptr_t rdi_constant __asm__("rdi") = __temp_0; \\ __asm volatile ("syscall" :: ""(rax_constant), ""(rdi_constant)); + \\ zig_breakpoint(); \\ zig_unreachable(); \\} \\ @@ -172,7 +172,6 @@ pub fn addCases(ctx: *TestContext) !void { \\} \\ , - \\#include \\#include \\ \\zig_noreturn void exitMath(uint8_t arg0); @@ -193,10 +192,11 @@ pub fn addCases(ctx: *TestContext) !void { \\} \\ \\zig_noreturn void exit(uint8_t arg0) { - \\ const size_t __temp_0 = (size_t)arg0; - \\ register size_t rax_constant __asm__("rax") = 231; - \\ register size_t rdi_constant __asm__("rdi") = __temp_0; + \\ const uintptr_t __temp_0 = (uintptr_t)arg0; + \\ register uintptr_t rax_constant __asm__("rax") = 231; + \\ register uintptr_t rdi_constant __asm__("rdi") = __temp_0; \\ __asm volatile ("syscall" :: ""(rax_constant), ""(rdi_constant)); + \\ zig_breakpoint(); \\ zig_unreachable(); \\} \\ @@ -220,7 +220,6 @@ pub fn addCases(ctx: *TestContext) !void { \\} \\ , - \\#include \\#include \\ \\zig_noreturn void exitMath(uint8_t arg0); @@ -241,10 +240,11 @@ pub fn addCases(ctx: *TestContext) !void { \\} \\ \\zig_noreturn void exit(uint8_t arg0) { - \\ const size_t __temp_0 = (size_t)arg0; - \\ register size_t rax_constant __asm__("rax") = 231; - \\ register size_t rdi_constant __asm__("rdi") = __temp_0; + \\ const uintptr_t __temp_0 = (uintptr_t)arg0; + \\ register uintptr_t rax_constant __asm__("rax") = 231; + \\ register uintptr_t rdi_constant __asm__("rdi") = __temp_0; \\ __asm volatile ("syscall" :: ""(rax_constant), ""(rdi_constant)); + \\ zig_breakpoint(); \\ zig_unreachable(); \\} \\ @@ -276,9 +276,7 @@ pub fn addCases(ctx: *TestContext) !void { ctx.h("header with usize param function", linux_x64, \\export fn start(a: usize) void{} , - \\#include - \\ - \\void start(size_t arg0); + \\void start(uintptr_t arg0); \\ ); ctx.h("header with bool param function", linux_x64, @@ -308,10 +306,9 @@ pub fn addCases(ctx: *TestContext) !void { ctx.h("header with multiple includes", linux_x64, \\export fn start(a: u32, b: usize) void{} , - \\#include \\#include \\ - \\void start(uint32_t arg0, size_t arg1); + \\void start(uint32_t arg0, uintptr_t arg1); \\ ); }