authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-04-28 00:09:26+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-04-28 18:35:01+02:00
loged51a5d02af58b3d11b555233781d71e6bde60af
tree21f6695493827646c1db3df3c80f12c51b5c37f8
parentfc4fbfe8e1689417da8130f02045e5cc9e120a1a

test: migrate arm incremental tests


25 files changed, 571 insertions(+), 799 deletions(-)

test/cases.zig-1
......@@ -9,7 +9,6 @@ const TestContext = @import("../src/test.zig").TestContext;
99pub fn addCases(ctx: *TestContext) !void {
1010 try @import("compile_errors.zig").addCases(ctx);
1111 try @import("stage2/cbe.zig").addCases(ctx);
12 try @import("stage2/arm.zig").addCases(ctx);
1312 try @import("stage2/llvm.zig").addCases(ctx);
1413 try @import("stage2/plan9.zig").addCases(ctx);
1514 try @import("stage2/x86_64.zig").addCases(ctx);
test/incremental/arm-linux/arithmetic_operations.0.zig created+21
......@@ -0,0 +1,21 @@
1pub fn main() void {
2 print(2, 4);
3 print(1, 7);
4}
5
6fn print(a: u32, b: u32) void {
7 asm volatile ("svc #0"
8 :
9 : [number] "{r7}" (4),
10 [arg3] "{r2}" (a + b),
11 [arg1] "{r0}" (1),
12 [arg2] "{r1}" (@ptrToInt("123456789")),
13 : "memory"
14 );
15 return;
16}
17
18// run
19// target=arm-linux
20//
21// 12345612345678
test/incremental/arm-linux/arithmetic_operations.1.zig created+20
......@@ -0,0 +1,20 @@
1pub fn main() void {
2 print(10, 5);
3 print(4, 3);
4}
5
6fn print(a: u32, b: u32) void {
7 asm volatile ("svc #0"
8 :
9 : [number] "{r7}" (4),
10 [arg3] "{r2}" (a - b),
11 [arg1] "{r0}" (1),
12 [arg2] "{r1}" (@ptrToInt("123456789")),
13 : "memory"
14 );
15 return;
16}
17
18// run
19//
20// 123451
test/incremental/arm-linux/arithmetic_operations.2.zig created+20
......@@ -0,0 +1,20 @@
1pub fn main() void {
2 print(8, 9);
3 print(3, 7);
4}
5
6fn print(a: u32, b: u32) void {
7 asm volatile ("svc #0"
8 :
9 : [number] "{r7}" (4),
10 [arg3] "{r2}" (a & b),
11 [arg1] "{r0}" (1),
12 [arg2] "{r1}" (@ptrToInt("123456789")),
13 : "memory"
14 );
15 return;
16}
17
18// run
19//
20// 12345678123
test/incremental/arm-linux/arithmetic_operations.3.zig created+20
......@@ -0,0 +1,20 @@
1pub fn main() void {
2 print(4, 2);
3 print(3, 7);
4}
5
6fn print(a: u32, b: u32) void {
7 asm volatile ("svc #0"
8 :
9 : [number] "{r7}" (4),
10 [arg3] "{r2}" (a | b),
11 [arg1] "{r0}" (1),
12 [arg2] "{r1}" (@ptrToInt("123456789")),
13 : "memory"
14 );
15 return;
16}
17
18// run
19//
20// 1234561234567
test/incremental/arm-linux/arithmetic_operations.4.zig created+20
......@@ -0,0 +1,20 @@
1pub fn main() void {
2 print(42, 42);
3 print(3, 5);
4}
5
6fn print(a: u32, b: u32) void {
7 asm volatile ("svc #0"
8 :
9 : [number] "{r7}" (4),
10 [arg3] "{r2}" (a ^ b),
11 [arg1] "{r0}" (1),
12 [arg2] "{r1}" (@ptrToInt("123456789")),
13 : "memory"
14 );
15 return;
16}
17
18// run
19//
20// 123456
test/incremental/arm-linux/arithmetic_operations.5.zig created+15
......@@ -0,0 +1,15 @@
1pub fn main() void {
2 var x: u32 = 1;
3 assert(x << 1 == 2);
4
5 x <<= 1;
6 assert(x << 2 == 8);
7 assert(x << 3 == 16);
8}
9
10pub fn assert(ok: bool) void {
11 if (!ok) unreachable; // assertion failure
12}
13
14// run
15//
test/incremental/arm-linux/arithmetic_operations.6.zig created+21
......@@ -0,0 +1,21 @@
1pub fn main() void {
2 var a: u32 = 1024;
3 assert(a >> 1 == 512);
4
5 a >>= 1;
6 assert(a >> 2 == 128);
7 assert(a >> 3 == 64);
8 assert(a >> 4 == 32);
9 assert(a >> 5 == 16);
10 assert(a >> 6 == 8);
11 assert(a >> 7 == 4);
12 assert(a >> 8 == 2);
13 assert(a >> 9 == 1);
14}
15
16pub fn assert(ok: bool) void {
17 if (!ok) unreachable; // assertion failure
18}
19
20// run
21//
test/incremental/arm-linux/errors.0.zig created+21
......@@ -0,0 +1,21 @@
1pub fn main() void {
2 foo() catch print();
3}
4
5fn foo() anyerror!void {}
6
7fn print() void {
8 asm volatile ("svc #0"
9 :
10 : [number] "{r7}" (4),
11 [arg1] "{r0}" (1),
12 [arg2] "{r1}" (@ptrToInt("Hello, World!\n")),
13 [arg3] "{r2}" ("Hello, World!\n".len),
14 : "memory"
15 );
16 return;
17}
18
19// run
20// target=arm-linux
21//
test/incremental/arm-linux/errors.1.zig created+24
......@@ -0,0 +1,24 @@
1pub fn main() void {
2 foo() catch print();
3}
4
5fn foo() anyerror!void {
6 return error.Test;
7}
8
9fn print() void {
10 asm volatile ("svc #0"
11 :
12 : [number] "{r7}" (4),
13 [arg1] "{r0}" (1),
14 [arg2] "{r1}" (@ptrToInt("Hello, World!\n")),
15 [arg3] "{r2}" ("Hello, World!\n".len),
16 : "memory"
17 );
18 return;
19}
20
21// run
22//
23// Hello, World!
24//
test/incremental/arm-linux/errors.2.zig created+27
......@@ -0,0 +1,27 @@
1pub fn main() void {
2 foo() catch |err| {
3 assert(err == error.Foo);
4 assert(err != error.Bar);
5 assert(err != error.Baz);
6 };
7 bar() catch |err| {
8 assert(err != error.Foo);
9 assert(err == error.Bar);
10 assert(err != error.Baz);
11 };
12}
13
14fn assert(ok: bool) void {
15 if (!ok) unreachable;
16}
17
18fn foo() anyerror!void {
19 return error.Foo;
20}
21
22fn bar() anyerror!void {
23 return error.Bar;
24}
25
26// run
27//
test/incremental/arm-linux/errors.3.zig created+12
......@@ -0,0 +1,12 @@
1pub fn main() void {
2 foo() catch unreachable;
3}
4
5fn foo() anyerror!void {
6 try bar();
7}
8
9fn bar() anyerror!void {}
10
11// run
12//
test/incremental/arm-linux/function_pointers.zig created+44
......@@ -0,0 +1,44 @@
1const PrintFn = *const fn () void;
2
3pub fn main() void {
4 var printFn: PrintFn = stopSayingThat;
5 var i: u32 = 0;
6 while (i < 4) : (i += 1) printFn();
7
8 printFn = moveEveryZig;
9 printFn();
10}
11
12fn stopSayingThat() void {
13 asm volatile ("svc #0"
14 :
15 : [number] "{r7}" (4),
16 [arg1] "{r0}" (1),
17 [arg2] "{r1}" (@ptrToInt("Hello, my name is Inigo Montoya; you killed my father, prepare to die.\n")),
18 [arg3] "{r2}" ("Hello, my name is Inigo Montoya; you killed my father, prepare to die.\n".len),
19 : "memory"
20 );
21 return;
22}
23
24fn moveEveryZig() void {
25 asm volatile ("svc #0"
26 :
27 : [number] "{r7}" (4),
28 [arg1] "{r0}" (1),
29 [arg2] "{r1}" (@ptrToInt("All your codebase are belong to us\n")),
30 [arg3] "{r2}" ("All your codebase are belong to us\n".len),
31 : "memory"
32 );
33 return;
34}
35
36// run
37// target=arm-linux
38//
39// Hello, my name is Inigo Montoya; you killed my father, prepare to die.
40// Hello, my name is Inigo Montoya; you killed my father, prepare to die.
41// Hello, my name is Inigo Montoya; you killed my father, prepare to die.
42// Hello, my name is Inigo Montoya; you killed my father, prepare to die.
43// All your codebase are belong to us
44//
test/incremental/arm-linux/hello_world_with_updates.0.zig created+32
......@@ -0,0 +1,32 @@
1pub export fn _start() noreturn {
2 print();
3 exit();
4}
5
6fn print() void {
7 asm volatile ("svc #0"
8 :
9 : [number] "{r7}" (4),
10 [arg1] "{r0}" (1),
11 [arg2] "{r1}" (@ptrToInt("Hello, World!\n")),
12 [arg3] "{r2}" (14),
13 : "memory"
14 );
15 return;
16}
17
18fn exit() noreturn {
19 asm volatile ("svc #0"
20 :
21 : [number] "{r7}" (1),
22 [arg1] "{r0}" (0),
23 : "memory"
24 );
25 unreachable;
26}
27
28// run
29// target=arm-linux
30//
31// Hello, World!
32//
test/incremental/arm-linux/hello_world_with_updates.1.zig created+37
......@@ -0,0 +1,37 @@
1pub export fn _start() noreturn {
2 print();
3 print();
4 print();
5 print();
6 exit();
7}
8
9fn print() void {
10 asm volatile ("svc #0"
11 :
12 : [number] "{r7}" (4),
13 [arg1] "{r0}" (1),
14 [arg2] "{r1}" (@ptrToInt("Hello, World!\n")),
15 [arg3] "{r2}" (14),
16 : "memory"
17 );
18 return;
19}
20
21fn exit() noreturn {
22 asm volatile ("svc #0"
23 :
24 : [number] "{r7}" (1),
25 [arg1] "{r0}" (0),
26 : "memory"
27 );
28 unreachable;
29}
30
31// run
32//
33// Hello, World!
34// Hello, World!
35// Hello, World!
36// Hello, World!
37//
test/incremental/arm-linux/hello_world_with_updates.2.zig created+22
......@@ -0,0 +1,22 @@
1pub fn main() void {
2 print();
3 print();
4}
5
6fn print() void {
7 asm volatile ("svc #0"
8 :
9 : [number] "{r7}" (4),
10 [arg1] "{r0}" (1),
11 [arg2] "{r1}" (@ptrToInt("Hello, World!\n")),
12 [arg3] "{r2}" (14),
13 : "memory"
14 );
15 return;
16}
17
18// run
19//
20// Hello, World!
21// Hello, World!
22//
test/incremental/arm-linux/parameters_and_return_values.0.zig created+28
......@@ -0,0 +1,28 @@
1pub fn main() void {
2 print(id(14));
3}
4
5fn id(x: u32) u32 {
6 return x;
7}
8
9// TODO: The parameters to the asm statement in print() had to
10// be in a specific order because otherwise the write to r0
11// would overwrite the len parameter which resides in r0
12fn print(len: u32) void {
13 asm volatile ("svc #0"
14 :
15 : [number] "{r7}" (4),
16 [arg3] "{r2}" (len),
17 [arg1] "{r0}" (1),
18 [arg2] "{r1}" (@ptrToInt("Hello, World!\n")),
19 : "memory"
20 );
21 return;
22}
23
24// run
25// target=arm-linux
26//
27// Hello, World!
28//
test/incremental/arm-linux/parameters_and_return_values.1.zig created+14
......@@ -0,0 +1,14 @@
1pub fn main() void {
2 assert(add(1, 2, 3, 4, 5, 6) == 21);
3}
4
5fn add(a: u32, b: u32, c: u32, d: u32, e: u32, f: u32) u32 {
6 return a + b + c + d + e + f;
7}
8
9pub fn assert(ok: bool) void {
10 if (!ok) unreachable; // assertion failure
11}
12
13// run
14//
test/incremental/arm-linux/print_u32s.zig created+40
......@@ -0,0 +1,40 @@
1pub fn main() void {
2 printNumberHex(0x00000000);
3 printNumberHex(0xaaaaaaaa);
4 printNumberHex(0xdeadbeef);
5 printNumberHex(0x31415926);
6}
7
8fn printNumberHex(x: u32) void {
9 var i: u5 = 28;
10 while (true) : (i -= 4) {
11 const digit = (x >> i) & 0xf;
12 asm volatile ("svc #0"
13 :
14 : [number] "{r7}" (4),
15 [arg1] "{r0}" (1),
16 [arg2] "{r1}" (@ptrToInt("0123456789abcdef") + digit),
17 [arg3] "{r2}" (1),
18 : "memory"
19 );
20
21 if (i == 0) break;
22 }
23 asm volatile ("svc #0"
24 :
25 : [number] "{r7}" (4),
26 [arg1] "{r0}" (1),
27 [arg2] "{r1}" (@ptrToInt("\n")),
28 [arg3] "{r2}" (1),
29 : "memory"
30 );
31}
32
33// run
34// target=arm-linux
35//
36// 00000000
37// aaaaaaaa
38// deadbeef
39// 31415926
40//
test/incremental/arm-linux/spilling_registers.0.zig created+38
......@@ -0,0 +1,38 @@
1pub fn main() void {
2 assert(add(3, 4) == 791);
3}
4
5fn add(a: u32, b: u32) u32 {
6 const x: u32 = blk: {
7 const c = a + b; // 7
8 const d = a + c; // 10
9 const e = d + b; // 14
10 const f = d + e; // 24
11 const g = e + f; // 38
12 const h = f + g; // 62
13 const i = g + h; // 100
14 const j = i + d; // 110
15 const k = i + j; // 210
16 const l = k + c; // 217
17 const m = l + d; // 227
18 const n = m + e; // 241
19 const o = n + f; // 265
20 const p = o + g; // 303
21 const q = p + h; // 365
22 const r = q + i; // 465
23 const s = r + j; // 575
24 const t = s + k; // 785
25 break :blk t;
26 };
27 const y = x + a; // 788
28 const z = y + a; // 791
29 return z;
30}
31
32fn assert(ok: bool) void {
33 if (!ok) unreachable;
34}
35
36// run
37// target=arm-linux
38//
test/incremental/arm-linux/spilling_registers.1.zig created+37
......@@ -0,0 +1,37 @@
1pub fn main() void {
2 assert(addMul(3, 4) == 357747496);
3}
4
5fn addMul(a: u32, b: u32) u32 {
6 const x: u32 = blk: {
7 const c = a + b; // 7
8 const d = a + c; // 10
9 const e = d + b; // 14
10 const f = d + e; // 24
11 const g = e + f; // 38
12 const h = f + g; // 62
13 const i = g + h; // 100
14 const j = i + d; // 110
15 const k = i + j; // 210
16 const l = k + c; // 217
17 const m = l * d; // 2170
18 const n = m + e; // 2184
19 const o = n * f; // 52416
20 const p = o + g; // 52454
21 const q = p * h; // 3252148
22 const r = q + i; // 3252248
23 const s = r * j; // 357747280
24 const t = s + k; // 357747490
25 break :blk t;
26 };
27 const y = x + a; // 357747493
28 const z = y + a; // 357747496
29 return z;
30}
31
32fn assert(ok: bool) void {
33 if (!ok) unreachable;
34}
35
36// run
37//
test/incremental/non_leaf_functions.zig created+12
......@@ -0,0 +1,12 @@
1pub fn main() void {
2 foo();
3}
4
5fn foo() void {
6 bar();
7}
8
9fn bar() void {}
10
11// run
12//
test/incremental/recursive_fibonacci.zig created+24
......@@ -0,0 +1,24 @@
1pub fn main() void {
2 assert(fib(0) == 0);
3 assert(fib(1) == 1);
4 assert(fib(2) == 1);
5 assert(fib(3) == 2);
6 assert(fib(10) == 55);
7 assert(fib(20) == 6765);
8}
9
10fn fib(n: u32) u32 {
11 if (n < 2) {
12 return n;
13 } else {
14 return fib(n - 2) + fib(n - 1);
15 }
16}
17
18fn assert(ok: bool) void {
19 if (!ok) unreachable;
20}
21
22// run
23// target=arm-linux,x86_64-linux,x86_64-macos,wasm32-wasi
24//
test/incremental/save_function_return_values_in_callee_preserved_register.zig created+22
......@@ -0,0 +1,22 @@
1pub fn main() void {
2 assert(foo() == 43);
3}
4
5fn foo() u32 {
6 return bar() + baz(42);
7}
8
9fn bar() u32 {
10 return 1;
11}
12
13fn baz(x: u32) u32 {
14 return x;
15}
16
17fn assert(ok: bool) void {
18 if (!ok) unreachable;
19}
20
21// run
22//
test/stage2/arm.zig deleted-798
......@@ -1,798 +0,0 @@
1const std = @import("std");
2const TestContext = @import("../../src/test.zig").TestContext;
3
4const linux_arm = std.zig.CrossTarget{
5 .cpu_arch = .arm,
6 .os_tag = .linux,
7};
8
9pub fn addCases(ctx: *TestContext) !void {
10 {
11 var case = ctx.exe("linux_arm hello world", linux_arm);
12 // Hello world using _start and inline asm.
13 case.addCompareOutput(
14 \\pub export fn _start() noreturn {
15 \\ print();
16 \\ exit();
17 \\}
18 \\
19 \\fn print() void {
20 \\ asm volatile ("svc #0"
21 \\ :
22 \\ : [number] "{r7}" (4),
23 \\ [arg1] "{r0}" (1),
24 \\ [arg2] "{r1}" (@ptrToInt("Hello, World!\n")),
25 \\ [arg3] "{r2}" (14)
26 \\ : "memory"
27 \\ );
28 \\ return;
29 \\}
30 \\
31 \\fn exit() noreturn {
32 \\ asm volatile ("svc #0"
33 \\ :
34 \\ : [number] "{r7}" (1),
35 \\ [arg1] "{r0}" (0)
36 \\ : "memory"
37 \\ );
38 \\ unreachable;
39 \\}
40 ,
41 "Hello, World!\n",
42 );
43 }
44
45 {
46 var case = ctx.exe("parameters and return values", linux_arm);
47 // Testing simple parameters and return values
48 //
49 // TODO: The parameters to the asm statement in print() had to
50 // be in a specific order because otherwise the write to r0
51 // would overwrite the len parameter which resides in r0
52 case.addCompareOutput(
53 \\pub fn main() void {
54 \\ print(id(14));
55 \\}
56 \\
57 \\fn id(x: u32) u32 {
58 \\ return x;
59 \\}
60 \\
61 \\fn print(len: u32) void {
62 \\ asm volatile ("svc #0"
63 \\ :
64 \\ : [number] "{r7}" (4),
65 \\ [arg3] "{r2}" (len),
66 \\ [arg1] "{r0}" (1),
67 \\ [arg2] "{r1}" (@ptrToInt("Hello, World!\n"))
68 \\ : "memory"
69 \\ );
70 \\ return;
71 \\}
72 ,
73 "Hello, World!\n",
74 );
75
76 case.addCompareOutput(
77 \\pub fn main() void {
78 \\ assert(add(1, 2, 3, 4, 5, 6) == 21);
79 \\}
80 \\
81 \\fn add(a: u32, b: u32, c: u32, d: u32, e: u32, f: u32) u32 {
82 \\ return a + b + c + d + e + f;
83 \\}
84 \\
85 \\pub fn assert(ok: bool) void {
86 \\ if (!ok) unreachable; // assertion failure
87 \\}
88 ,
89 "",
90 );
91 }
92
93 {
94 var case = ctx.exe("non-leaf functions", linux_arm);
95 // Testing non-leaf functions
96 case.addCompareOutput(
97 \\pub fn main() void {
98 \\ foo();
99 \\}
100 \\
101 \\fn foo() void {
102 \\ bar();
103 \\}
104 \\
105 \\fn bar() void {}
106 ,
107 "",
108 );
109 }
110
111 {
112 var case = ctx.exe("arithmetic operations", linux_arm);
113
114 // Add two numbers
115 case.addCompareOutput(
116 \\pub fn main() void {
117 \\ print(2, 4);
118 \\ print(1, 7);
119 \\}
120 \\
121 \\fn print(a: u32, b: u32) void {
122 \\ asm volatile ("svc #0"
123 \\ :
124 \\ : [number] "{r7}" (4),
125 \\ [arg3] "{r2}" (a + b),
126 \\ [arg1] "{r0}" (1),
127 \\ [arg2] "{r1}" (@ptrToInt("123456789"))
128 \\ : "memory"
129 \\ );
130 \\ return;
131 \\}
132 ,
133 "12345612345678",
134 );
135
136 // Subtract two numbers
137 case.addCompareOutput(
138 \\pub fn main() void {
139 \\ print(10, 5);
140 \\ print(4, 3);
141 \\}
142 \\
143 \\fn print(a: u32, b: u32) void {
144 \\ asm volatile ("svc #0"
145 \\ :
146 \\ : [number] "{r7}" (4),
147 \\ [arg3] "{r2}" (a - b),
148 \\ [arg1] "{r0}" (1),
149 \\ [arg2] "{r1}" (@ptrToInt("123456789"))
150 \\ : "memory"
151 \\ );
152 \\ return;
153 \\}
154 ,
155 "123451",
156 );
157
158 // Bitwise And
159 case.addCompareOutput(
160 \\pub fn main() void {
161 \\ print(8, 9);
162 \\ print(3, 7);
163 \\}
164 \\
165 \\fn print(a: u32, b: u32) void {
166 \\ asm volatile ("svc #0"
167 \\ :
168 \\ : [number] "{r7}" (4),
169 \\ [arg3] "{r2}" (a & b),
170 \\ [arg1] "{r0}" (1),
171 \\ [arg2] "{r1}" (@ptrToInt("123456789"))
172 \\ : "memory"
173 \\ );
174 \\ return;
175 \\}
176 ,
177 "12345678123",
178 );
179
180 // Bitwise Or
181 case.addCompareOutput(
182 \\pub fn main() void {
183 \\ print(4, 2);
184 \\ print(3, 7);
185 \\}
186 \\
187 \\fn print(a: u32, b: u32) void {
188 \\ asm volatile ("svc #0"
189 \\ :
190 \\ : [number] "{r7}" (4),
191 \\ [arg3] "{r2}" (a | b),
192 \\ [arg1] "{r0}" (1),
193 \\ [arg2] "{r1}" (@ptrToInt("123456789"))
194 \\ : "memory"
195 \\ );
196 \\ return;
197 \\}
198 ,
199 "1234561234567",
200 );
201
202 // Bitwise Xor
203 case.addCompareOutput(
204 \\pub fn main() void {
205 \\ print(42, 42);
206 \\ print(3, 5);
207 \\}
208 \\
209 \\fn print(a: u32, b: u32) void {
210 \\ asm volatile ("svc #0"
211 \\ :
212 \\ : [number] "{r7}" (4),
213 \\ [arg3] "{r2}" (a ^ b),
214 \\ [arg1] "{r0}" (1),
215 \\ [arg2] "{r1}" (@ptrToInt("123456789"))
216 \\ : "memory"
217 \\ );
218 \\ return;
219 \\}
220 ,
221 "123456",
222 );
223
224 // Bit Shift Left
225 case.addCompareOutput(
226 \\pub fn main() void {
227 \\ var x: u32 = 1;
228 \\ assert(x << 1 == 2);
229 \\
230 \\ x <<= 1;
231 \\ assert(x << 2 == 8);
232 \\ assert(x << 3 == 16);
233 \\}
234 \\
235 \\pub fn assert(ok: bool) void {
236 \\ if (!ok) unreachable; // assertion failure
237 \\}
238 ,
239 "",
240 );
241
242 // Bit Shift Right
243 case.addCompareOutput(
244 \\pub fn main() void {
245 \\ var a: u32 = 1024;
246 \\ assert(a >> 1 == 512);
247 \\
248 \\ a >>= 1;
249 \\ assert(a >> 2 == 128);
250 \\ assert(a >> 3 == 64);
251 \\ assert(a >> 4 == 32);
252 \\ assert(a >> 5 == 16);
253 \\ assert(a >> 6 == 8);
254 \\ assert(a >> 7 == 4);
255 \\ assert(a >> 8 == 2);
256 \\ assert(a >> 9 == 1);
257 \\}
258 \\
259 \\pub fn assert(ok: bool) void {
260 \\ if (!ok) unreachable; // assertion failure
261 \\}
262 ,
263 "",
264 );
265 }
266
267 {
268 var case = ctx.exe("if statements", linux_arm);
269 // Simple if statement in assert
270 case.addCompareOutput(
271 \\pub fn main() void {
272 \\ var x: u32 = 123;
273 \\ var y: u32 = 42;
274 \\ assert(x > y);
275 \\}
276 \\
277 \\fn assert(ok: bool) void {
278 \\ if (!ok) unreachable;
279 \\}
280 ,
281 "",
282 );
283 }
284
285 {
286 var case = ctx.exe("while loops", linux_arm);
287 // Simple while loop with assert
288 case.addCompareOutput(
289 \\pub fn main() void {
290 \\ var x: u32 = 2020;
291 \\ var i: u32 = 0;
292 \\ while (x > 0) {
293 \\ x -= 2;
294 \\ i += 1;
295 \\ }
296 \\ assert(i == 1010);
297 \\}
298 \\
299 \\fn assert(ok: bool) void {
300 \\ if (!ok) unreachable;
301 \\}
302 ,
303 "",
304 );
305 }
306
307 {
308 var case = ctx.exe("integer multiplication", linux_arm);
309 // Simple u32 integer multiplication
310 case.addCompareOutput(
311 \\pub fn main() void {
312 \\ assert(mul(1, 1) == 1);
313 \\ assert(mul(42, 1) == 42);
314 \\ assert(mul(1, 42) == 42);
315 \\ assert(mul(123, 42) == 5166);
316 \\}
317 \\
318 \\fn mul(x: u32, y: u32) u32 {
319 \\ return x * y;
320 \\}
321 \\
322 \\fn assert(ok: bool) void {
323 \\ if (!ok) unreachable;
324 \\}
325 ,
326 "",
327 );
328 }
329
330 {
331 var case = ctx.exe("save function return values in callee preserved register", linux_arm);
332 // Here, it is necessary to save the result of bar() into a
333 // callee preserved register, otherwise it will be overwritten
334 // by the first parameter to baz.
335 case.addCompareOutput(
336 \\pub fn main() void {
337 \\ assert(foo() == 43);
338 \\}
339 \\
340 \\fn foo() u32 {
341 \\ return bar() + baz(42);
342 \\}
343 \\
344 \\fn bar() u32 {
345 \\ return 1;
346 \\}
347 \\
348 \\fn baz(x: u32) u32 {
349 \\ return x;
350 \\}
351 \\
352 \\fn assert(ok: bool) void {
353 \\ if (!ok) unreachable;
354 \\}
355 ,
356 "",
357 );
358 }
359
360 {
361 var case = ctx.exe("enums", linux_arm);
362 case.addCompareOutput(
363 \\const Number = enum { one, two, three };
364 \\
365 \\pub fn main() void {
366 \\ var x: Number = .one;
367 \\ var y = Number.two;
368 \\ var z = @intToEnum(Number, 2);
369 \\ assert(@enumToInt(x) == 0);
370 \\ assert(@enumToInt(y) == 1);
371 \\ assert(@enumToInt(z) == 2);
372 \\}
373 \\
374 \\fn assert(ok: bool) void {
375 \\ if (!ok) unreachable; // assertion failure
376 \\}
377 ,
378 "",
379 );
380
381 case.addCompareOutput(
382 \\const Number = enum { one, two, three };
383 \\
384 \\pub fn main() void {
385 \\ var x: Number = .one;
386 \\ var y = Number.two;
387 \\ assert(@enumToInt(x) < @enumToInt(y));
388 \\}
389 \\
390 \\fn assert(ok: bool) void {
391 \\ if (!ok) unreachable; // assertion failure
392 \\}
393 ,
394 "",
395 );
396 }
397
398 {
399 var case = ctx.exe("recursive fibonacci", linux_arm);
400 case.addCompareOutput(
401 \\pub fn main() void {
402 \\ assert(fib(0) == 0);
403 \\ assert(fib(1) == 1);
404 \\ assert(fib(2) == 1);
405 \\ assert(fib(3) == 2);
406 \\ assert(fib(10) == 55);
407 \\ assert(fib(20) == 6765);
408 \\}
409 \\
410 \\fn fib(n: u32) u32 {
411 \\ if (n < 2) {
412 \\ return n;
413 \\ } else {
414 \\ return fib(n - 2) + fib(n - 1);
415 \\ }
416 \\}
417 \\
418 \\fn assert(ok: bool) void {
419 \\ if (!ok) unreachable;
420 \\}
421 ,
422 "",
423 );
424 }
425
426 {
427 var case = ctx.exe("spilling registers", linux_arm);
428 case.addCompareOutput(
429 \\pub fn main() void {
430 \\ assert(add(3, 4) == 791);
431 \\}
432 \\
433 \\fn add(a: u32, b: u32) u32 {
434 \\ const x: u32 = blk: {
435 \\ const c = a + b; // 7
436 \\ const d = a + c; // 10
437 \\ const e = d + b; // 14
438 \\ const f = d + e; // 24
439 \\ const g = e + f; // 38
440 \\ const h = f + g; // 62
441 \\ const i = g + h; // 100
442 \\ const j = i + d; // 110
443 \\ const k = i + j; // 210
444 \\ const l = k + c; // 217
445 \\ const m = l + d; // 227
446 \\ const n = m + e; // 241
447 \\ const o = n + f; // 265
448 \\ const p = o + g; // 303
449 \\ const q = p + h; // 365
450 \\ const r = q + i; // 465
451 \\ const s = r + j; // 575
452 \\ const t = s + k; // 785
453 \\ break :blk t;
454 \\ };
455 \\ const y = x + a; // 788
456 \\ const z = y + a; // 791
457 \\ return z;
458 \\}
459 \\
460 \\fn assert(ok: bool) void {
461 \\ if (!ok) unreachable;
462 \\}
463 ,
464 "",
465 );
466
467 case.addCompareOutput(
468 \\pub fn main() void {
469 \\ assert(addMul(3, 4) == 357747496);
470 \\}
471 \\
472 \\fn addMul(a: u32, b: u32) u32 {
473 \\ const x: u32 = blk: {
474 \\ const c = a + b; // 7
475 \\ const d = a + c; // 10
476 \\ const e = d + b; // 14
477 \\ const f = d + e; // 24
478 \\ const g = e + f; // 38
479 \\ const h = f + g; // 62
480 \\ const i = g + h; // 100
481 \\ const j = i + d; // 110
482 \\ const k = i + j; // 210
483 \\ const l = k + c; // 217
484 \\ const m = l * d; // 2170
485 \\ const n = m + e; // 2184
486 \\ const o = n * f; // 52416
487 \\ const p = o + g; // 52454
488 \\ const q = p * h; // 3252148
489 \\ const r = q + i; // 3252248
490 \\ const s = r * j; // 357747280
491 \\ const t = s + k; // 357747490
492 \\ break :blk t;
493 \\ };
494 \\ const y = x + a; // 357747493
495 \\ const z = y + a; // 357747496
496 \\ return z;
497 \\}
498 \\
499 \\fn assert(ok: bool) void {
500 \\ if (!ok) unreachable;
501 \\}
502 ,
503 "",
504 );
505 }
506
507 {
508 var case = ctx.exe("print u32s", linux_arm);
509 case.addCompareOutput(
510 \\pub fn main() void {
511 \\ printNumberHex(0x00000000);
512 \\ printNumberHex(0xaaaaaaaa);
513 \\ printNumberHex(0xdeadbeef);
514 \\ printNumberHex(0x31415926);
515 \\}
516 \\
517 \\fn printNumberHex(x: u32) void {
518 \\ var i: u5 = 28;
519 \\ while (true) : (i -= 4) {
520 \\ const digit = (x >> i) & 0xf;
521 \\ asm volatile ("svc #0"
522 \\ :
523 \\ : [number] "{r7}" (4),
524 \\ [arg1] "{r0}" (1),
525 \\ [arg2] "{r1}" (@ptrToInt("0123456789abcdef") + digit),
526 \\ [arg3] "{r2}" (1)
527 \\ : "memory"
528 \\ );
529 \\
530 \\ if (i == 0) break;
531 \\ }
532 \\ asm volatile ("svc #0"
533 \\ :
534 \\ : [number] "{r7}" (4),
535 \\ [arg1] "{r0}" (1),
536 \\ [arg2] "{r1}" (@ptrToInt("\n")),
537 \\ [arg3] "{r2}" (1)
538 \\ : "memory"
539 \\ );
540 \\}
541 ,
542 \\00000000
543 \\aaaaaaaa
544 \\deadbeef
545 \\31415926
546 \\
547 ,
548 );
549 }
550
551 {
552 var case = ctx.exe("save compare flags", linux_arm);
553 case.addCompareOutput(
554 \\pub fn main() void {
555 \\ foo(2, 1);
556 \\}
557 \\
558 \\fn foo(x: u32, y: u32) void {
559 \\ const b = x > y;
560 \\ assert(b);
561 \\ assert(b);
562 \\}
563 \\
564 \\pub fn assert(ok: bool) void {
565 \\ if (!ok) unreachable; // assertion failure
566 \\}
567 ,
568 "",
569 );
570 }
571
572 {
573 var case = ctx.exe("optionals", linux_arm);
574 case.addCompareOutput(
575 \\var x: u32 = 42;
576 \\
577 \\pub fn main() void {
578 \\ var p: ?*u32 = null;
579 \\ assert(p == null);
580 \\ p = &x;
581 \\ assert(p != null);
582 \\}
583 \\
584 \\fn assert(ok: bool) void {
585 \\ if (!ok) unreachable;
586 \\}
587 ,
588 "",
589 );
590 }
591
592 {
593 var case = ctx.exe("errors", linux_arm);
594 case.addCompareOutput(
595 \\pub fn main() void {
596 \\ foo() catch print();
597 \\}
598 \\
599 \\fn foo() anyerror!void {}
600 \\
601 \\fn print() void {
602 \\ asm volatile ("svc #0"
603 \\ :
604 \\ : [number] "{r7}" (4),
605 \\ [arg1] "{r0}" (1),
606 \\ [arg2] "{r1}" (@ptrToInt("Hello, World!\n")),
607 \\ [arg3] "{r2}" ("Hello, World!\n".len),
608 \\ : "memory"
609 \\ );
610 \\ return;
611 \\}
612 ,
613 "",
614 );
615
616 case.addCompareOutput(
617 \\pub fn main() void {
618 \\ foo() catch print();
619 \\}
620 \\
621 \\fn foo() anyerror!void {
622 \\ return error.Test;
623 \\}
624 \\
625 \\fn print() void {
626 \\ asm volatile ("svc #0"
627 \\ :
628 \\ : [number] "{r7}" (4),
629 \\ [arg1] "{r0}" (1),
630 \\ [arg2] "{r1}" (@ptrToInt("Hello, World!\n")),
631 \\ [arg3] "{r2}" ("Hello, World!\n".len),
632 \\ : "memory"
633 \\ );
634 \\ return;
635 \\}
636 ,
637 "Hello, World!\n",
638 );
639
640 case.addCompareOutput(
641 \\pub fn main() void {
642 \\ foo() catch |err| {
643 \\ assert(err == error.Foo);
644 \\ assert(err != error.Bar);
645 \\ assert(err != error.Baz);
646 \\ };
647 \\ bar() catch |err| {
648 \\ assert(err != error.Foo);
649 \\ assert(err == error.Bar);
650 \\ assert(err != error.Baz);
651 \\ };
652 \\}
653 \\
654 \\fn assert(ok: bool) void {
655 \\ if (!ok) unreachable;
656 \\}
657 \\
658 \\fn foo() anyerror!void {
659 \\ return error.Foo;
660 \\}
661 \\
662 \\fn bar() anyerror!void {
663 \\ return error.Bar;
664 \\}
665 ,
666 "",
667 );
668
669 case.addCompareOutput(
670 \\pub fn main() void {
671 \\ foo() catch unreachable;
672 \\}
673 \\
674 \\fn foo() anyerror!void {
675 \\ try bar();
676 \\}
677 \\
678 \\fn bar() anyerror!void {}
679 ,
680 "",
681 );
682 }
683
684 {
685 var case = ctx.exe("slices", linux_arm);
686 case.addCompareOutput(
687 \\var array = [_]u32{ 0, 42, 123, 69 };
688 \\var s: []const u32 = &array;
689 \\
690 \\pub fn main() void {
691 \\ assert(s[0] == 0);
692 \\ assert(s[1] == 42);
693 \\ assert(s[2] == 123);
694 \\ assert(s[3] == 69);
695 \\}
696 \\
697 \\fn assert(ok: bool) void {
698 \\ if (!ok) unreachable;
699 \\}
700 ,
701 "",
702 );
703 }
704
705 {
706 var case = ctx.exe("structs", linux_arm);
707 case.addCompareOutput(
708 \\var array = [_]SomeStruct{
709 \\ .{ .a = 0, .b = 42, .c = 69 },
710 \\ .{ .a = 1, .b = 2, .c = 3 },
711 \\ .{ .a = 123, .b = 456, .c = 789 },
712 \\};
713 \\var s: []const SomeStruct = &array;
714 \\
715 \\var some_struct: SomeStruct = .{
716 \\ .a = 0,
717 \\ .b = 42,
718 \\ .c = 69,
719 \\};
720 \\
721 \\const SomeStruct = struct {
722 \\ a: u32,
723 \\ b: u32,
724 \\ c: u32,
725 \\};
726 \\
727 \\pub fn main() void {
728 \\ assert(some_struct.a == 0);
729 \\ assert(some_struct.b == 42);
730 \\ assert(some_struct.c == 69);
731 \\
732 \\ assert(s[0].a == 0);
733 \\ assert(s[0].b == 42);
734 \\ assert(s[0].c == 69);
735 \\ assert(s[1].a == 1);
736 \\ assert(s[1].b == 2);
737 \\ assert(s[1].c == 3);
738 \\ assert(s[2].a == 123);
739 \\ assert(s[2].b == 456);
740 \\ assert(s[2].c == 789);
741 \\}
742 \\
743 \\fn assert(ok: bool) void {
744 \\ if (!ok) unreachable;
745 \\}
746 ,
747 "",
748 );
749 }
750
751 {
752 var case = ctx.exe("function pointers", linux_arm);
753 case.addCompareOutput(
754 \\const PrintFn = *const fn () void;
755 \\
756 \\pub fn main() void {
757 \\ var printFn: PrintFn = stopSayingThat;
758 \\ var i: u32 = 0;
759 \\ while (i < 4) : (i += 1) printFn();
760 \\
761 \\ printFn = moveEveryZig;
762 \\ printFn();
763 \\}
764 \\
765 \\fn stopSayingThat() void {
766 \\ asm volatile ("svc #0"
767 \\ :
768 \\ : [number] "{r7}" (4),
769 \\ [arg1] "{r0}" (1),
770 \\ [arg2] "{r1}" (@ptrToInt("Hello, my name is Inigo Montoya; you killed my father, prepare to die.\n")),
771 \\ [arg3] "{r2}" ("Hello, my name is Inigo Montoya; you killed my father, prepare to die.\n".len),
772 \\ : "memory"
773 \\ );
774 \\ return;
775 \\}
776 \\
777 \\fn moveEveryZig() void {
778 \\ asm volatile ("svc #0"
779 \\ :
780 \\ : [number] "{r7}" (4),
781 \\ [arg1] "{r0}" (1),
782 \\ [arg2] "{r1}" (@ptrToInt("All your codebase are belong to us\n")),
783 \\ [arg3] "{r2}" ("All your codebase are belong to us\n".len),
784 \\ : "memory"
785 \\ );
786 \\ return;
787 \\}
788 ,
789 \\Hello, my name is Inigo Montoya; you killed my father, prepare to die.
790 \\Hello, my name is Inigo Montoya; you killed my father, prepare to die.
791 \\Hello, my name is Inigo Montoya; you killed my father, prepare to die.
792 \\Hello, my name is Inigo Montoya; you killed my father, prepare to die.
793 \\All your codebase are belong to us
794 \\
795 ,
796 );
797 }
798}