authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-12-28 18:43:01-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-12-28 18:43:01-07:00
loga54ccd85374407a5015c5d8e0173089e75da9be4
tree78bf30d38ba33fd9656a23cb0a3be8de96e672f1
parent37f04d66be014291303b7d8ba49ff4232dbdb696

stage2: C backend: implement `@breakpoint` and clean up test harness


4 files changed, 48 insertions(+), 64 deletions(-)

src/codegen/c.zig+3-3
......@@ -232,7 +232,7 @@ pub fn generate(file: *C, decl: *Decl) !void {
232232 .retvoid => try genRetVoid(file),
233233 .arg => try genArg(&ctx),
234234 .dbg_stmt => try genDbgStmt(&ctx, inst.castTag(.dbg_stmt).?),
235 .breakpoint => try genBreak(&ctx, inst.castTag(.breakpoint).?),
235 .breakpoint => try genBreakpoint(file, inst.castTag(.breakpoint).?),
236236 .unreach => try genUnreach(file, inst.castTag(.unreach).?),
237237 .intcast => try genIntCast(&ctx, file, inst.castTag(.intcast).?),
238238 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 {
447447 return null;
448448}
449449
450fn genBreak(ctx: *Context, inst: *Inst.NoOp) !?[]u8 {
451 // TODO ??
450fn genBreakpoint(file: *C, inst: *Inst.NoOp) !?[]u8 {
451 try file.main.writer().writeAll("zig_breakpoint();\n");
452452 return null;
453453}
454454
src/link/cbe.h+17-2
......@@ -1,5 +1,4 @@
11#if __STDC_VERSION__ >= 199901L
2// C99 or newer
32#include <stdbool.h>
43#else
54#define bool unsigned char
......@@ -17,12 +16,28 @@
1716#define zig_noreturn
1817#endif
1918
20#if __GNUC__
19#if defined(__GNUC__)
2120#define zig_unreachable() __builtin_unreachable()
2221#else
2322#define zig_unreachable()
2423#endif
2524
25#if defined(_MSC_VER)
26#define zig_breakpoint __debugbreak()
27#else
28#if defined(__MINGW32__) || defined(__MINGW64__)
29#define zig_breakpoint __debugbreak()
30#elif defined(__clang__)
31#define zig_breakpoint __builtin_debugtrap()
32#elif defined(__GNUC__)
33#define zig_breakpoint __builtin_trap()
34#elif defined(__i386__) || defined(__x86_64__)
35#define zig_breakpoint __asm__ volatile("int $0x03");
36#else
37#define zig_breakpoint raise(SIGTRAP)
38#endif
39#endif
40
2641#include <stdint.h>
2742#define int128_t __int128
2843#define uint128_t unsigned __int128
src/test.zig+4-32
......@@ -646,35 +646,16 @@ pub const TestContext = struct {
646646 defer file.close();
647647 var out = file.reader().readAllAlloc(arena, 1024 * 1024) catch @panic("Unable to read headeroutput!");
648648
649 if (expected_output.len != out.len) {
650 std.debug.print("\nTransformed header length differs:\n================\nExpected:\n================\n{}\n================\nFound:\n================\n{}\n================\nTest failed.\n", .{ expected_output, out });
651 std.process.exit(1);
652 }
653 for (expected_output) |e, i| {
654 if (out[i] != e) {
655 std.debug.print("\nTransformed header differs:\n================\nExpected:\n================\n{}\n================\nFound:\n================\n{}\n================\nTest failed.\n", .{ expected_output, out });
656 std.process.exit(1);
657 }
658 }
649 std.testing.expectEqualStrings(expected_output, out);
659650 },
660651 .Transformation => |expected_output| {
661652 if (case.cbe) {
662653 // The C file is always closed after an update, because we don't support
663 // incremental updates
654 // incremental updates.
664655 var file = try tmp.dir.openFile(bin_name, .{ .read = true });
665656 defer file.close();
666657 var out = file.reader().readAllAlloc(arena, 1024 * 1024) catch @panic("Unable to read C output!");
667
668 if (expected_output.len != out.len) {
669 std.debug.print("\nTransformed C length differs:\n================\nExpected:\n================\n{}\n================\nFound:\n================\n{}\n================\nTest failed.\n", .{ expected_output, out });
670 std.process.exit(1);
671 }
672 for (expected_output) |e, i| {
673 if (out[i] != e) {
674 std.debug.print("\nTransformed C differs:\n================\nExpected:\n================\n{}\n================\nFound:\n================\n{}\n================\nTest failed.\n", .{ expected_output, out });
675 std.process.exit(1);
676 }
677 }
658 std.testing.expectEqualStrings(expected_output, out);
678659 } else {
679660 update_node.setEstimatedTotalItems(5);
680661 var emit_node = update_node.start("emit", 0);
......@@ -694,16 +675,7 @@ pub const TestContext = struct {
694675 test_node.activate();
695676 defer test_node.end();
696677
697 if (expected_output.len != out_zir.items.len) {
698 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 });
699 std.process.exit(1);
700 }
701 for (expected_output) |e, i| {
702 if (out_zir.items[i] != e) {
703 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 });
704 std.process.exit(1);
705 }
706 }
678 std.testing.expectEqualStrings(expected_output, out_zir.items);
707679 }
708680 },
709681 .Error => |e| {
test/stage2/cbe.zig+24-27
......@@ -15,6 +15,7 @@ pub fn addCases(ctx: *TestContext) !void {
1515 \\}
1616 ,
1717 \\zig_noreturn void _start(void) {
18 \\ zig_breakpoint();
1819 \\ zig_unreachable();
1920 \\}
2021 \\
......@@ -41,6 +42,7 @@ pub fn addCases(ctx: *TestContext) !void {
4142 \\}
4243 \\
4344 \\zig_noreturn void main(void) {
45 \\ zig_breakpoint();
4446 \\ zig_unreachable();
4547 \\}
4648 \\
......@@ -61,8 +63,6 @@ pub fn addCases(ctx: *TestContext) !void {
6163 \\ exitGood();
6264 \\}
6365 ,
64 \\#include <stddef.h>
65 \\
6666 \\zig_noreturn void exitGood(void);
6767 \\
6868 \\const char *const exitGood__anon_0 = "{rax}";
......@@ -74,9 +74,10 @@ pub fn addCases(ctx: *TestContext) !void {
7474 \\}
7575 \\
7676 \\zig_noreturn void exitGood(void) {
77 \\ register size_t rax_constant __asm__("rax") = 231;
78 \\ register size_t rdi_constant __asm__("rdi") = 0;
77 \\ register uintptr_t rax_constant __asm__("rax") = 231;
78 \\ register uintptr_t rdi_constant __asm__("rdi") = 0;
7979 \\ __asm volatile ("syscall" :: ""(rax_constant), ""(rdi_constant));
80 \\ zig_breakpoint();
8081 \\ zig_unreachable();
8182 \\}
8283 \\
......@@ -96,9 +97,7 @@ pub fn addCases(ctx: *TestContext) !void {
9697 \\}
9798 \\
9899 ,
99 \\#include <stddef.h>
100 \\
101 \\zig_noreturn void exit(size_t arg0);
100 \\zig_noreturn void exit(uintptr_t arg0);
102101 \\
103102 \\const char *const exit__anon_0 = "{rax}";
104103 \\const char *const exit__anon_1 = "{rdi}";
......@@ -108,10 +107,11 @@ pub fn addCases(ctx: *TestContext) !void {
108107 \\ exit(0);
109108 \\}
110109 \\
111 \\zig_noreturn void exit(size_t arg0) {
112 \\ register size_t rax_constant __asm__("rax") = 231;
113 \\ register size_t rdi_constant __asm__("rdi") = arg0;
110 \\zig_noreturn void exit(uintptr_t arg0) {
111 \\ register uintptr_t rax_constant __asm__("rax") = 231;
112 \\ register uintptr_t rdi_constant __asm__("rdi") = arg0;
114113 \\ __asm volatile ("syscall" :: ""(rax_constant), ""(rdi_constant));
114 \\ zig_breakpoint();
115115 \\ zig_unreachable();
116116 \\}
117117 \\
......@@ -131,7 +131,6 @@ pub fn addCases(ctx: *TestContext) !void {
131131 \\}
132132 \\
133133 ,
134 \\#include <stddef.h>
135134 \\#include <stdint.h>
136135 \\
137136 \\zig_noreturn void exit(uint8_t arg0);
......@@ -145,10 +144,11 @@ pub fn addCases(ctx: *TestContext) !void {
145144 \\}
146145 \\
147146 \\zig_noreturn void exit(uint8_t arg0) {
148 \\ const size_t __temp_0 = (size_t)arg0;
149 \\ register size_t rax_constant __asm__("rax") = 231;
150 \\ register size_t rdi_constant __asm__("rdi") = __temp_0;
147 \\ const uintptr_t __temp_0 = (uintptr_t)arg0;
148 \\ register uintptr_t rax_constant __asm__("rax") = 231;
149 \\ register uintptr_t rdi_constant __asm__("rdi") = __temp_0;
151150 \\ __asm volatile ("syscall" :: ""(rax_constant), ""(rdi_constant));
151 \\ zig_breakpoint();
152152 \\ zig_unreachable();
153153 \\}
154154 \\
......@@ -172,7 +172,6 @@ pub fn addCases(ctx: *TestContext) !void {
172172 \\}
173173 \\
174174 ,
175 \\#include <stddef.h>
176175 \\#include <stdint.h>
177176 \\
178177 \\zig_noreturn void exitMath(uint8_t arg0);
......@@ -193,10 +192,11 @@ pub fn addCases(ctx: *TestContext) !void {
193192 \\}
194193 \\
195194 \\zig_noreturn void exit(uint8_t arg0) {
196 \\ const size_t __temp_0 = (size_t)arg0;
197 \\ register size_t rax_constant __asm__("rax") = 231;
198 \\ register size_t rdi_constant __asm__("rdi") = __temp_0;
195 \\ const uintptr_t __temp_0 = (uintptr_t)arg0;
196 \\ register uintptr_t rax_constant __asm__("rax") = 231;
197 \\ register uintptr_t rdi_constant __asm__("rdi") = __temp_0;
199198 \\ __asm volatile ("syscall" :: ""(rax_constant), ""(rdi_constant));
199 \\ zig_breakpoint();
200200 \\ zig_unreachable();
201201 \\}
202202 \\
......@@ -220,7 +220,6 @@ pub fn addCases(ctx: *TestContext) !void {
220220 \\}
221221 \\
222222 ,
223 \\#include <stddef.h>
224223 \\#include <stdint.h>
225224 \\
226225 \\zig_noreturn void exitMath(uint8_t arg0);
......@@ -241,10 +240,11 @@ pub fn addCases(ctx: *TestContext) !void {
241240 \\}
242241 \\
243242 \\zig_noreturn void exit(uint8_t arg0) {
244 \\ const size_t __temp_0 = (size_t)arg0;
245 \\ register size_t rax_constant __asm__("rax") = 231;
246 \\ register size_t rdi_constant __asm__("rdi") = __temp_0;
243 \\ const uintptr_t __temp_0 = (uintptr_t)arg0;
244 \\ register uintptr_t rax_constant __asm__("rax") = 231;
245 \\ register uintptr_t rdi_constant __asm__("rdi") = __temp_0;
247246 \\ __asm volatile ("syscall" :: ""(rax_constant), ""(rdi_constant));
247 \\ zig_breakpoint();
248248 \\ zig_unreachable();
249249 \\}
250250 \\
......@@ -276,9 +276,7 @@ pub fn addCases(ctx: *TestContext) !void {
276276 ctx.h("header with usize param function", linux_x64,
277277 \\export fn start(a: usize) void{}
278278 ,
279 \\#include <stddef.h>
280 \\
281 \\void start(size_t arg0);
279 \\void start(uintptr_t arg0);
282280 \\
283281 );
284282 ctx.h("header with bool param function", linux_x64,
......@@ -308,10 +306,9 @@ pub fn addCases(ctx: *TestContext) !void {
308306 ctx.h("header with multiple includes", linux_x64,
309307 \\export fn start(a: u32, b: usize) void{}
310308 ,
311 \\#include <stddef.h>
312309 \\#include <stdint.h>
313310 \\
314 \\void start(uint32_t arg0, size_t arg1);
311 \\void start(uint32_t arg0, uintptr_t arg1);
315312 \\
316313 );
317314}