test: migrate arm incremental tests

This commit is contained in:
Jakub Konka
2022-04-28 00:09:26 +02:00
parent fc4fbfe8e1
commit ed51a5d02a
25 changed files with 571 additions and 799 deletions
-1
View File
@@ -9,7 +9,6 @@ const TestContext = @import("../src/test.zig").TestContext;
pub fn addCases(ctx: *TestContext) !void {
try @import("compile_errors.zig").addCases(ctx);
try @import("stage2/cbe.zig").addCases(ctx);
try @import("stage2/arm.zig").addCases(ctx);
try @import("stage2/llvm.zig").addCases(ctx);
try @import("stage2/plan9.zig").addCases(ctx);
try @import("stage2/x86_64.zig").addCases(ctx);
@@ -0,0 +1,21 @@
pub fn main() void {
print(2, 4);
print(1, 7);
}
fn print(a: u32, b: u32) void {
asm volatile ("svc #0"
:
: [number] "{r7}" (4),
[arg3] "{r2}" (a + b),
[arg1] "{r0}" (1),
[arg2] "{r1}" (@ptrToInt("123456789")),
: "memory"
);
return;
}
// run
// target=arm-linux
//
// 12345612345678
@@ -0,0 +1,20 @@
pub fn main() void {
print(10, 5);
print(4, 3);
}
fn print(a: u32, b: u32) void {
asm volatile ("svc #0"
:
: [number] "{r7}" (4),
[arg3] "{r2}" (a - b),
[arg1] "{r0}" (1),
[arg2] "{r1}" (@ptrToInt("123456789")),
: "memory"
);
return;
}
// run
//
// 123451
@@ -0,0 +1,20 @@
pub fn main() void {
print(8, 9);
print(3, 7);
}
fn print(a: u32, b: u32) void {
asm volatile ("svc #0"
:
: [number] "{r7}" (4),
[arg3] "{r2}" (a & b),
[arg1] "{r0}" (1),
[arg2] "{r1}" (@ptrToInt("123456789")),
: "memory"
);
return;
}
// run
//
// 12345678123
@@ -0,0 +1,20 @@
pub fn main() void {
print(4, 2);
print(3, 7);
}
fn print(a: u32, b: u32) void {
asm volatile ("svc #0"
:
: [number] "{r7}" (4),
[arg3] "{r2}" (a | b),
[arg1] "{r0}" (1),
[arg2] "{r1}" (@ptrToInt("123456789")),
: "memory"
);
return;
}
// run
//
// 1234561234567
@@ -0,0 +1,20 @@
pub fn main() void {
print(42, 42);
print(3, 5);
}
fn print(a: u32, b: u32) void {
asm volatile ("svc #0"
:
: [number] "{r7}" (4),
[arg3] "{r2}" (a ^ b),
[arg1] "{r0}" (1),
[arg2] "{r1}" (@ptrToInt("123456789")),
: "memory"
);
return;
}
// run
//
// 123456
@@ -0,0 +1,15 @@
pub fn main() void {
var x: u32 = 1;
assert(x << 1 == 2);
x <<= 1;
assert(x << 2 == 8);
assert(x << 3 == 16);
}
pub fn assert(ok: bool) void {
if (!ok) unreachable; // assertion failure
}
// run
//
@@ -0,0 +1,21 @@
pub fn main() void {
var a: u32 = 1024;
assert(a >> 1 == 512);
a >>= 1;
assert(a >> 2 == 128);
assert(a >> 3 == 64);
assert(a >> 4 == 32);
assert(a >> 5 == 16);
assert(a >> 6 == 8);
assert(a >> 7 == 4);
assert(a >> 8 == 2);
assert(a >> 9 == 1);
}
pub fn assert(ok: bool) void {
if (!ok) unreachable; // assertion failure
}
// run
//
+21
View File
@@ -0,0 +1,21 @@
pub fn main() void {
foo() catch print();
}
fn foo() anyerror!void {}
fn print() void {
asm volatile ("svc #0"
:
: [number] "{r7}" (4),
[arg1] "{r0}" (1),
[arg2] "{r1}" (@ptrToInt("Hello, World!\n")),
[arg3] "{r2}" ("Hello, World!\n".len),
: "memory"
);
return;
}
// run
// target=arm-linux
//
+24
View File
@@ -0,0 +1,24 @@
pub fn main() void {
foo() catch print();
}
fn foo() anyerror!void {
return error.Test;
}
fn print() void {
asm volatile ("svc #0"
:
: [number] "{r7}" (4),
[arg1] "{r0}" (1),
[arg2] "{r1}" (@ptrToInt("Hello, World!\n")),
[arg3] "{r2}" ("Hello, World!\n".len),
: "memory"
);
return;
}
// run
//
// Hello, World!
//
+27
View File
@@ -0,0 +1,27 @@
pub fn main() void {
foo() catch |err| {
assert(err == error.Foo);
assert(err != error.Bar);
assert(err != error.Baz);
};
bar() catch |err| {
assert(err != error.Foo);
assert(err == error.Bar);
assert(err != error.Baz);
};
}
fn assert(ok: bool) void {
if (!ok) unreachable;
}
fn foo() anyerror!void {
return error.Foo;
}
fn bar() anyerror!void {
return error.Bar;
}
// run
//
+12
View File
@@ -0,0 +1,12 @@
pub fn main() void {
foo() catch unreachable;
}
fn foo() anyerror!void {
try bar();
}
fn bar() anyerror!void {}
// run
//
@@ -0,0 +1,44 @@
const PrintFn = *const fn () void;
pub fn main() void {
var printFn: PrintFn = stopSayingThat;
var i: u32 = 0;
while (i < 4) : (i += 1) printFn();
printFn = moveEveryZig;
printFn();
}
fn stopSayingThat() void {
asm volatile ("svc #0"
:
: [number] "{r7}" (4),
[arg1] "{r0}" (1),
[arg2] "{r1}" (@ptrToInt("Hello, my name is Inigo Montoya; you killed my father, prepare to die.\n")),
[arg3] "{r2}" ("Hello, my name is Inigo Montoya; you killed my father, prepare to die.\n".len),
: "memory"
);
return;
}
fn moveEveryZig() void {
asm volatile ("svc #0"
:
: [number] "{r7}" (4),
[arg1] "{r0}" (1),
[arg2] "{r1}" (@ptrToInt("All your codebase are belong to us\n")),
[arg3] "{r2}" ("All your codebase are belong to us\n".len),
: "memory"
);
return;
}
// run
// target=arm-linux
//
// Hello, my name is Inigo Montoya; you killed my father, prepare to die.
// Hello, my name is Inigo Montoya; you killed my father, prepare to die.
// Hello, my name is Inigo Montoya; you killed my father, prepare to die.
// Hello, my name is Inigo Montoya; you killed my father, prepare to die.
// All your codebase are belong to us
//
@@ -0,0 +1,32 @@
pub export fn _start() noreturn {
print();
exit();
}
fn print() void {
asm volatile ("svc #0"
:
: [number] "{r7}" (4),
[arg1] "{r0}" (1),
[arg2] "{r1}" (@ptrToInt("Hello, World!\n")),
[arg3] "{r2}" (14),
: "memory"
);
return;
}
fn exit() noreturn {
asm volatile ("svc #0"
:
: [number] "{r7}" (1),
[arg1] "{r0}" (0),
: "memory"
);
unreachable;
}
// run
// target=arm-linux
//
// Hello, World!
//
@@ -0,0 +1,37 @@
pub export fn _start() noreturn {
print();
print();
print();
print();
exit();
}
fn print() void {
asm volatile ("svc #0"
:
: [number] "{r7}" (4),
[arg1] "{r0}" (1),
[arg2] "{r1}" (@ptrToInt("Hello, World!\n")),
[arg3] "{r2}" (14),
: "memory"
);
return;
}
fn exit() noreturn {
asm volatile ("svc #0"
:
: [number] "{r7}" (1),
[arg1] "{r0}" (0),
: "memory"
);
unreachable;
}
// run
//
// Hello, World!
// Hello, World!
// Hello, World!
// Hello, World!
//
@@ -0,0 +1,22 @@
pub fn main() void {
print();
print();
}
fn print() void {
asm volatile ("svc #0"
:
: [number] "{r7}" (4),
[arg1] "{r0}" (1),
[arg2] "{r1}" (@ptrToInt("Hello, World!\n")),
[arg3] "{r2}" (14),
: "memory"
);
return;
}
// run
//
// Hello, World!
// Hello, World!
//
@@ -0,0 +1,28 @@
pub fn main() void {
print(id(14));
}
fn id(x: u32) u32 {
return x;
}
// TODO: The parameters to the asm statement in print() had to
// be in a specific order because otherwise the write to r0
// would overwrite the len parameter which resides in r0
fn print(len: u32) void {
asm volatile ("svc #0"
:
: [number] "{r7}" (4),
[arg3] "{r2}" (len),
[arg1] "{r0}" (1),
[arg2] "{r1}" (@ptrToInt("Hello, World!\n")),
: "memory"
);
return;
}
// run
// target=arm-linux
//
// Hello, World!
//
@@ -0,0 +1,14 @@
pub fn main() void {
assert(add(1, 2, 3, 4, 5, 6) == 21);
}
fn add(a: u32, b: u32, c: u32, d: u32, e: u32, f: u32) u32 {
return a + b + c + d + e + f;
}
pub fn assert(ok: bool) void {
if (!ok) unreachable; // assertion failure
}
// run
//
+40
View File
@@ -0,0 +1,40 @@
pub fn main() void {
printNumberHex(0x00000000);
printNumberHex(0xaaaaaaaa);
printNumberHex(0xdeadbeef);
printNumberHex(0x31415926);
}
fn printNumberHex(x: u32) void {
var i: u5 = 28;
while (true) : (i -= 4) {
const digit = (x >> i) & 0xf;
asm volatile ("svc #0"
:
: [number] "{r7}" (4),
[arg1] "{r0}" (1),
[arg2] "{r1}" (@ptrToInt("0123456789abcdef") + digit),
[arg3] "{r2}" (1),
: "memory"
);
if (i == 0) break;
}
asm volatile ("svc #0"
:
: [number] "{r7}" (4),
[arg1] "{r0}" (1),
[arg2] "{r1}" (@ptrToInt("\n")),
[arg3] "{r2}" (1),
: "memory"
);
}
// run
// target=arm-linux
//
// 00000000
// aaaaaaaa
// deadbeef
// 31415926
//
@@ -0,0 +1,38 @@
pub fn main() void {
assert(add(3, 4) == 791);
}
fn add(a: u32, b: u32) u32 {
const x: u32 = blk: {
const c = a + b; // 7
const d = a + c; // 10
const e = d + b; // 14
const f = d + e; // 24
const g = e + f; // 38
const h = f + g; // 62
const i = g + h; // 100
const j = i + d; // 110
const k = i + j; // 210
const l = k + c; // 217
const m = l + d; // 227
const n = m + e; // 241
const o = n + f; // 265
const p = o + g; // 303
const q = p + h; // 365
const r = q + i; // 465
const s = r + j; // 575
const t = s + k; // 785
break :blk t;
};
const y = x + a; // 788
const z = y + a; // 791
return z;
}
fn assert(ok: bool) void {
if (!ok) unreachable;
}
// run
// target=arm-linux
//
@@ -0,0 +1,37 @@
pub fn main() void {
assert(addMul(3, 4) == 357747496);
}
fn addMul(a: u32, b: u32) u32 {
const x: u32 = blk: {
const c = a + b; // 7
const d = a + c; // 10
const e = d + b; // 14
const f = d + e; // 24
const g = e + f; // 38
const h = f + g; // 62
const i = g + h; // 100
const j = i + d; // 110
const k = i + j; // 210
const l = k + c; // 217
const m = l * d; // 2170
const n = m + e; // 2184
const o = n * f; // 52416
const p = o + g; // 52454
const q = p * h; // 3252148
const r = q + i; // 3252248
const s = r * j; // 357747280
const t = s + k; // 357747490
break :blk t;
};
const y = x + a; // 357747493
const z = y + a; // 357747496
return z;
}
fn assert(ok: bool) void {
if (!ok) unreachable;
}
// run
//
+12
View File
@@ -0,0 +1,12 @@
pub fn main() void {
foo();
}
fn foo() void {
bar();
}
fn bar() void {}
// run
//
+24
View File
@@ -0,0 +1,24 @@
pub fn main() void {
assert(fib(0) == 0);
assert(fib(1) == 1);
assert(fib(2) == 1);
assert(fib(3) == 2);
assert(fib(10) == 55);
assert(fib(20) == 6765);
}
fn fib(n: u32) u32 {
if (n < 2) {
return n;
} else {
return fib(n - 2) + fib(n - 1);
}
}
fn assert(ok: bool) void {
if (!ok) unreachable;
}
// run
// target=arm-linux,x86_64-linux,x86_64-macos,wasm32-wasi
//
@@ -0,0 +1,22 @@
pub fn main() void {
assert(foo() == 43);
}
fn foo() u32 {
return bar() + baz(42);
}
fn bar() u32 {
return 1;
}
fn baz(x: u32) u32 {
return x;
}
fn assert(ok: bool) void {
if (!ok) unreachable;
}
// run
//
-798
View File
@@ -1,798 +0,0 @@
const std = @import("std");
const TestContext = @import("../../src/test.zig").TestContext;
const linux_arm = std.zig.CrossTarget{
.cpu_arch = .arm,
.os_tag = .linux,
};
pub fn addCases(ctx: *TestContext) !void {
{
var case = ctx.exe("linux_arm hello world", linux_arm);
// Hello world using _start and inline asm.
case.addCompareOutput(
\\pub export fn _start() noreturn {
\\ print();
\\ exit();
\\}
\\
\\fn print() void {
\\ asm volatile ("svc #0"
\\ :
\\ : [number] "{r7}" (4),
\\ [arg1] "{r0}" (1),
\\ [arg2] "{r1}" (@ptrToInt("Hello, World!\n")),
\\ [arg3] "{r2}" (14)
\\ : "memory"
\\ );
\\ return;
\\}
\\
\\fn exit() noreturn {
\\ asm volatile ("svc #0"
\\ :
\\ : [number] "{r7}" (1),
\\ [arg1] "{r0}" (0)
\\ : "memory"
\\ );
\\ unreachable;
\\}
,
"Hello, World!\n",
);
}
{
var case = ctx.exe("parameters and return values", linux_arm);
// Testing simple parameters and return values
//
// TODO: The parameters to the asm statement in print() had to
// be in a specific order because otherwise the write to r0
// would overwrite the len parameter which resides in r0
case.addCompareOutput(
\\pub fn main() void {
\\ print(id(14));
\\}
\\
\\fn id(x: u32) u32 {
\\ return x;
\\}
\\
\\fn print(len: u32) void {
\\ asm volatile ("svc #0"
\\ :
\\ : [number] "{r7}" (4),
\\ [arg3] "{r2}" (len),
\\ [arg1] "{r0}" (1),
\\ [arg2] "{r1}" (@ptrToInt("Hello, World!\n"))
\\ : "memory"
\\ );
\\ return;
\\}
,
"Hello, World!\n",
);
case.addCompareOutput(
\\pub fn main() void {
\\ assert(add(1, 2, 3, 4, 5, 6) == 21);
\\}
\\
\\fn add(a: u32, b: u32, c: u32, d: u32, e: u32, f: u32) u32 {
\\ return a + b + c + d + e + f;
\\}
\\
\\pub fn assert(ok: bool) void {
\\ if (!ok) unreachable; // assertion failure
\\}
,
"",
);
}
{
var case = ctx.exe("non-leaf functions", linux_arm);
// Testing non-leaf functions
case.addCompareOutput(
\\pub fn main() void {
\\ foo();
\\}
\\
\\fn foo() void {
\\ bar();
\\}
\\
\\fn bar() void {}
,
"",
);
}
{
var case = ctx.exe("arithmetic operations", linux_arm);
// Add two numbers
case.addCompareOutput(
\\pub fn main() void {
\\ print(2, 4);
\\ print(1, 7);
\\}
\\
\\fn print(a: u32, b: u32) void {
\\ asm volatile ("svc #0"
\\ :
\\ : [number] "{r7}" (4),
\\ [arg3] "{r2}" (a + b),
\\ [arg1] "{r0}" (1),
\\ [arg2] "{r1}" (@ptrToInt("123456789"))
\\ : "memory"
\\ );
\\ return;
\\}
,
"12345612345678",
);
// Subtract two numbers
case.addCompareOutput(
\\pub fn main() void {
\\ print(10, 5);
\\ print(4, 3);
\\}
\\
\\fn print(a: u32, b: u32) void {
\\ asm volatile ("svc #0"
\\ :
\\ : [number] "{r7}" (4),
\\ [arg3] "{r2}" (a - b),
\\ [arg1] "{r0}" (1),
\\ [arg2] "{r1}" (@ptrToInt("123456789"))
\\ : "memory"
\\ );
\\ return;
\\}
,
"123451",
);
// Bitwise And
case.addCompareOutput(
\\pub fn main() void {
\\ print(8, 9);
\\ print(3, 7);
\\}
\\
\\fn print(a: u32, b: u32) void {
\\ asm volatile ("svc #0"
\\ :
\\ : [number] "{r7}" (4),
\\ [arg3] "{r2}" (a & b),
\\ [arg1] "{r0}" (1),
\\ [arg2] "{r1}" (@ptrToInt("123456789"))
\\ : "memory"
\\ );
\\ return;
\\}
,
"12345678123",
);
// Bitwise Or
case.addCompareOutput(
\\pub fn main() void {
\\ print(4, 2);
\\ print(3, 7);
\\}
\\
\\fn print(a: u32, b: u32) void {
\\ asm volatile ("svc #0"
\\ :
\\ : [number] "{r7}" (4),
\\ [arg3] "{r2}" (a | b),
\\ [arg1] "{r0}" (1),
\\ [arg2] "{r1}" (@ptrToInt("123456789"))
\\ : "memory"
\\ );
\\ return;
\\}
,
"1234561234567",
);
// Bitwise Xor
case.addCompareOutput(
\\pub fn main() void {
\\ print(42, 42);
\\ print(3, 5);
\\}
\\
\\fn print(a: u32, b: u32) void {
\\ asm volatile ("svc #0"
\\ :
\\ : [number] "{r7}" (4),
\\ [arg3] "{r2}" (a ^ b),
\\ [arg1] "{r0}" (1),
\\ [arg2] "{r1}" (@ptrToInt("123456789"))
\\ : "memory"
\\ );
\\ return;
\\}
,
"123456",
);
// Bit Shift Left
case.addCompareOutput(
\\pub fn main() void {
\\ var x: u32 = 1;
\\ assert(x << 1 == 2);
\\
\\ x <<= 1;
\\ assert(x << 2 == 8);
\\ assert(x << 3 == 16);
\\}
\\
\\pub fn assert(ok: bool) void {
\\ if (!ok) unreachable; // assertion failure
\\}
,
"",
);
// Bit Shift Right
case.addCompareOutput(
\\pub fn main() void {
\\ var a: u32 = 1024;
\\ assert(a >> 1 == 512);
\\
\\ a >>= 1;
\\ assert(a >> 2 == 128);
\\ assert(a >> 3 == 64);
\\ assert(a >> 4 == 32);
\\ assert(a >> 5 == 16);
\\ assert(a >> 6 == 8);
\\ assert(a >> 7 == 4);
\\ assert(a >> 8 == 2);
\\ assert(a >> 9 == 1);
\\}
\\
\\pub fn assert(ok: bool) void {
\\ if (!ok) unreachable; // assertion failure
\\}
,
"",
);
}
{
var case = ctx.exe("if statements", linux_arm);
// Simple if statement in assert
case.addCompareOutput(
\\pub fn main() void {
\\ var x: u32 = 123;
\\ var y: u32 = 42;
\\ assert(x > y);
\\}
\\
\\fn assert(ok: bool) void {
\\ if (!ok) unreachable;
\\}
,
"",
);
}
{
var case = ctx.exe("while loops", linux_arm);
// Simple while loop with assert
case.addCompareOutput(
\\pub fn main() void {
\\ var x: u32 = 2020;
\\ var i: u32 = 0;
\\ while (x > 0) {
\\ x -= 2;
\\ i += 1;
\\ }
\\ assert(i == 1010);
\\}
\\
\\fn assert(ok: bool) void {
\\ if (!ok) unreachable;
\\}
,
"",
);
}
{
var case = ctx.exe("integer multiplication", linux_arm);
// Simple u32 integer multiplication
case.addCompareOutput(
\\pub fn main() void {
\\ assert(mul(1, 1) == 1);
\\ assert(mul(42, 1) == 42);
\\ assert(mul(1, 42) == 42);
\\ assert(mul(123, 42) == 5166);
\\}
\\
\\fn mul(x: u32, y: u32) u32 {
\\ return x * y;
\\}
\\
\\fn assert(ok: bool) void {
\\ if (!ok) unreachable;
\\}
,
"",
);
}
{
var case = ctx.exe("save function return values in callee preserved register", linux_arm);
// Here, it is necessary to save the result of bar() into a
// callee preserved register, otherwise it will be overwritten
// by the first parameter to baz.
case.addCompareOutput(
\\pub fn main() void {
\\ assert(foo() == 43);
\\}
\\
\\fn foo() u32 {
\\ return bar() + baz(42);
\\}
\\
\\fn bar() u32 {
\\ return 1;
\\}
\\
\\fn baz(x: u32) u32 {
\\ return x;
\\}
\\
\\fn assert(ok: bool) void {
\\ if (!ok) unreachable;
\\}
,
"",
);
}
{
var case = ctx.exe("enums", linux_arm);
case.addCompareOutput(
\\const Number = enum { one, two, three };
\\
\\pub fn main() void {
\\ var x: Number = .one;
\\ var y = Number.two;
\\ var z = @intToEnum(Number, 2);
\\ assert(@enumToInt(x) == 0);
\\ assert(@enumToInt(y) == 1);
\\ assert(@enumToInt(z) == 2);
\\}
\\
\\fn assert(ok: bool) void {
\\ if (!ok) unreachable; // assertion failure
\\}
,
"",
);
case.addCompareOutput(
\\const Number = enum { one, two, three };
\\
\\pub fn main() void {
\\ var x: Number = .one;
\\ var y = Number.two;
\\ assert(@enumToInt(x) < @enumToInt(y));
\\}
\\
\\fn assert(ok: bool) void {
\\ if (!ok) unreachable; // assertion failure
\\}
,
"",
);
}
{
var case = ctx.exe("recursive fibonacci", linux_arm);
case.addCompareOutput(
\\pub fn main() void {
\\ assert(fib(0) == 0);
\\ assert(fib(1) == 1);
\\ assert(fib(2) == 1);
\\ assert(fib(3) == 2);
\\ assert(fib(10) == 55);
\\ assert(fib(20) == 6765);
\\}
\\
\\fn fib(n: u32) u32 {
\\ if (n < 2) {
\\ return n;
\\ } else {
\\ return fib(n - 2) + fib(n - 1);
\\ }
\\}
\\
\\fn assert(ok: bool) void {
\\ if (!ok) unreachable;
\\}
,
"",
);
}
{
var case = ctx.exe("spilling registers", linux_arm);
case.addCompareOutput(
\\pub fn main() void {
\\ assert(add(3, 4) == 791);
\\}
\\
\\fn add(a: u32, b: u32) u32 {
\\ const x: u32 = blk: {
\\ const c = a + b; // 7
\\ const d = a + c; // 10
\\ const e = d + b; // 14
\\ const f = d + e; // 24
\\ const g = e + f; // 38
\\ const h = f + g; // 62
\\ const i = g + h; // 100
\\ const j = i + d; // 110
\\ const k = i + j; // 210
\\ const l = k + c; // 217
\\ const m = l + d; // 227
\\ const n = m + e; // 241
\\ const o = n + f; // 265
\\ const p = o + g; // 303
\\ const q = p + h; // 365
\\ const r = q + i; // 465
\\ const s = r + j; // 575
\\ const t = s + k; // 785
\\ break :blk t;
\\ };
\\ const y = x + a; // 788
\\ const z = y + a; // 791
\\ return z;
\\}
\\
\\fn assert(ok: bool) void {
\\ if (!ok) unreachable;
\\}
,
"",
);
case.addCompareOutput(
\\pub fn main() void {
\\ assert(addMul(3, 4) == 357747496);
\\}
\\
\\fn addMul(a: u32, b: u32) u32 {
\\ const x: u32 = blk: {
\\ const c = a + b; // 7
\\ const d = a + c; // 10
\\ const e = d + b; // 14
\\ const f = d + e; // 24
\\ const g = e + f; // 38
\\ const h = f + g; // 62
\\ const i = g + h; // 100
\\ const j = i + d; // 110
\\ const k = i + j; // 210
\\ const l = k + c; // 217
\\ const m = l * d; // 2170
\\ const n = m + e; // 2184
\\ const o = n * f; // 52416
\\ const p = o + g; // 52454
\\ const q = p * h; // 3252148
\\ const r = q + i; // 3252248
\\ const s = r * j; // 357747280
\\ const t = s + k; // 357747490
\\ break :blk t;
\\ };
\\ const y = x + a; // 357747493
\\ const z = y + a; // 357747496
\\ return z;
\\}
\\
\\fn assert(ok: bool) void {
\\ if (!ok) unreachable;
\\}
,
"",
);
}
{
var case = ctx.exe("print u32s", linux_arm);
case.addCompareOutput(
\\pub fn main() void {
\\ printNumberHex(0x00000000);
\\ printNumberHex(0xaaaaaaaa);
\\ printNumberHex(0xdeadbeef);
\\ printNumberHex(0x31415926);
\\}
\\
\\fn printNumberHex(x: u32) void {
\\ var i: u5 = 28;
\\ while (true) : (i -= 4) {
\\ const digit = (x >> i) & 0xf;
\\ asm volatile ("svc #0"
\\ :
\\ : [number] "{r7}" (4),
\\ [arg1] "{r0}" (1),
\\ [arg2] "{r1}" (@ptrToInt("0123456789abcdef") + digit),
\\ [arg3] "{r2}" (1)
\\ : "memory"
\\ );
\\
\\ if (i == 0) break;
\\ }
\\ asm volatile ("svc #0"
\\ :
\\ : [number] "{r7}" (4),
\\ [arg1] "{r0}" (1),
\\ [arg2] "{r1}" (@ptrToInt("\n")),
\\ [arg3] "{r2}" (1)
\\ : "memory"
\\ );
\\}
,
\\00000000
\\aaaaaaaa
\\deadbeef
\\31415926
\\
,
);
}
{
var case = ctx.exe("save compare flags", linux_arm);
case.addCompareOutput(
\\pub fn main() void {
\\ foo(2, 1);
\\}
\\
\\fn foo(x: u32, y: u32) void {
\\ const b = x > y;
\\ assert(b);
\\ assert(b);
\\}
\\
\\pub fn assert(ok: bool) void {
\\ if (!ok) unreachable; // assertion failure
\\}
,
"",
);
}
{
var case = ctx.exe("optionals", linux_arm);
case.addCompareOutput(
\\var x: u32 = 42;
\\
\\pub fn main() void {
\\ var p: ?*u32 = null;
\\ assert(p == null);
\\ p = &x;
\\ assert(p != null);
\\}
\\
\\fn assert(ok: bool) void {
\\ if (!ok) unreachable;
\\}
,
"",
);
}
{
var case = ctx.exe("errors", linux_arm);
case.addCompareOutput(
\\pub fn main() void {
\\ foo() catch print();
\\}
\\
\\fn foo() anyerror!void {}
\\
\\fn print() void {
\\ asm volatile ("svc #0"
\\ :
\\ : [number] "{r7}" (4),
\\ [arg1] "{r0}" (1),
\\ [arg2] "{r1}" (@ptrToInt("Hello, World!\n")),
\\ [arg3] "{r2}" ("Hello, World!\n".len),
\\ : "memory"
\\ );
\\ return;
\\}
,
"",
);
case.addCompareOutput(
\\pub fn main() void {
\\ foo() catch print();
\\}
\\
\\fn foo() anyerror!void {
\\ return error.Test;
\\}
\\
\\fn print() void {
\\ asm volatile ("svc #0"
\\ :
\\ : [number] "{r7}" (4),
\\ [arg1] "{r0}" (1),
\\ [arg2] "{r1}" (@ptrToInt("Hello, World!\n")),
\\ [arg3] "{r2}" ("Hello, World!\n".len),
\\ : "memory"
\\ );
\\ return;
\\}
,
"Hello, World!\n",
);
case.addCompareOutput(
\\pub fn main() void {
\\ foo() catch |err| {
\\ assert(err == error.Foo);
\\ assert(err != error.Bar);
\\ assert(err != error.Baz);
\\ };
\\ bar() catch |err| {
\\ assert(err != error.Foo);
\\ assert(err == error.Bar);
\\ assert(err != error.Baz);
\\ };
\\}
\\
\\fn assert(ok: bool) void {
\\ if (!ok) unreachable;
\\}
\\
\\fn foo() anyerror!void {
\\ return error.Foo;
\\}
\\
\\fn bar() anyerror!void {
\\ return error.Bar;
\\}
,
"",
);
case.addCompareOutput(
\\pub fn main() void {
\\ foo() catch unreachable;
\\}
\\
\\fn foo() anyerror!void {
\\ try bar();
\\}
\\
\\fn bar() anyerror!void {}
,
"",
);
}
{
var case = ctx.exe("slices", linux_arm);
case.addCompareOutput(
\\var array = [_]u32{ 0, 42, 123, 69 };
\\var s: []const u32 = &array;
\\
\\pub fn main() void {
\\ assert(s[0] == 0);
\\ assert(s[1] == 42);
\\ assert(s[2] == 123);
\\ assert(s[3] == 69);
\\}
\\
\\fn assert(ok: bool) void {
\\ if (!ok) unreachable;
\\}
,
"",
);
}
{
var case = ctx.exe("structs", linux_arm);
case.addCompareOutput(
\\var array = [_]SomeStruct{
\\ .{ .a = 0, .b = 42, .c = 69 },
\\ .{ .a = 1, .b = 2, .c = 3 },
\\ .{ .a = 123, .b = 456, .c = 789 },
\\};
\\var s: []const SomeStruct = &array;
\\
\\var some_struct: SomeStruct = .{
\\ .a = 0,
\\ .b = 42,
\\ .c = 69,
\\};
\\
\\const SomeStruct = struct {
\\ a: u32,
\\ b: u32,
\\ c: u32,
\\};
\\
\\pub fn main() void {
\\ assert(some_struct.a == 0);
\\ assert(some_struct.b == 42);
\\ assert(some_struct.c == 69);
\\
\\ assert(s[0].a == 0);
\\ assert(s[0].b == 42);
\\ assert(s[0].c == 69);
\\ assert(s[1].a == 1);
\\ assert(s[1].b == 2);
\\ assert(s[1].c == 3);
\\ assert(s[2].a == 123);
\\ assert(s[2].b == 456);
\\ assert(s[2].c == 789);
\\}
\\
\\fn assert(ok: bool) void {
\\ if (!ok) unreachable;
\\}
,
"",
);
}
{
var case = ctx.exe("function pointers", linux_arm);
case.addCompareOutput(
\\const PrintFn = *const fn () void;
\\
\\pub fn main() void {
\\ var printFn: PrintFn = stopSayingThat;
\\ var i: u32 = 0;
\\ while (i < 4) : (i += 1) printFn();
\\
\\ printFn = moveEveryZig;
\\ printFn();
\\}
\\
\\fn stopSayingThat() void {
\\ asm volatile ("svc #0"
\\ :
\\ : [number] "{r7}" (4),
\\ [arg1] "{r0}" (1),
\\ [arg2] "{r1}" (@ptrToInt("Hello, my name is Inigo Montoya; you killed my father, prepare to die.\n")),
\\ [arg3] "{r2}" ("Hello, my name is Inigo Montoya; you killed my father, prepare to die.\n".len),
\\ : "memory"
\\ );
\\ return;
\\}
\\
\\fn moveEveryZig() void {
\\ asm volatile ("svc #0"
\\ :
\\ : [number] "{r7}" (4),
\\ [arg1] "{r0}" (1),
\\ [arg2] "{r1}" (@ptrToInt("All your codebase are belong to us\n")),
\\ [arg3] "{r2}" ("All your codebase are belong to us\n".len),
\\ : "memory"
\\ );
\\ return;
\\}
,
\\Hello, my name is Inigo Montoya; you killed my father, prepare to die.
\\Hello, my name is Inigo Montoya; you killed my father, prepare to die.
\\Hello, my name is Inigo Montoya; you killed my father, prepare to die.
\\Hello, my name is Inigo Montoya; you killed my father, prepare to die.
\\All your codebase are belong to us
\\
,
);
}
}