Files
zig/test/stage2/cbe.zig
2021-01-06 16:47:09 -07:00

262 lines
7.1 KiB
Zig

const std = @import("std");
const TestContext = @import("../../src/test.zig").TestContext;
// These tests should work with all platforms, but we're using linux_x64 for
// now for consistency. Will be expanded eventually.
const linux_x64 = std.zig.CrossTarget{
.cpu_arch = .x86_64,
.os_tag = .linux,
};
pub fn addCases(ctx: *TestContext) !void {
{
var case = ctx.exeFromCompiledC("hello world with updates", .{});
// Regular old hello world
case.addCompareOutput(
\\extern fn puts(s: [*:0]const u8) c_int;
\\export fn main() c_int {
\\ _ = puts("hello world!");
\\ return 0;
\\}
, "hello world!" ++ std.cstr.line_sep);
// Now change the message only
case.addCompareOutput(
\\extern fn puts(s: [*:0]const u8) c_int;
\\export fn main() c_int {
\\ _ = puts("yo");
\\ return 0;
\\}
, "yo" ++ std.cstr.line_sep);
// Add an unused Decl
case.addCompareOutput(
\\extern fn puts(s: [*:0]const u8) c_int;
\\export fn main() c_int {
\\ _ = puts("yo!");
\\ return 0;
\\}
\\fn unused() void {}
, "yo!" ++ std.cstr.line_sep);
}
{
var case = ctx.exeFromCompiledC("x86_64-linux inline assembly", linux_x64);
// Exit with 0
case.addCompareOutput(
\\fn exitGood() noreturn {
\\ asm volatile ("syscall"
\\ :
\\ : [number] "{rax}" (231),
\\ [arg1] "{rdi}" (0)
\\ );
\\ unreachable;
\\}
\\
\\export fn main() c_int {
\\ exitGood();
\\}
, "");
// Pass a usize parameter to exit
case.addCompareOutput(
\\export fn main() c_int {
\\ exit(0);
\\}
\\
\\fn exit(code: usize) noreturn {
\\ asm volatile ("syscall"
\\ :
\\ : [number] "{rax}" (231),
\\ [arg1] "{rdi}" (code)
\\ );
\\ unreachable;
\\}
, "");
// Change the parameter to u8
case.addCompareOutput(
\\export fn main() c_int {
\\ exit(0);
\\}
\\
\\fn exit(code: u8) noreturn {
\\ asm volatile ("syscall"
\\ :
\\ : [number] "{rax}" (231),
\\ [arg1] "{rdi}" (code)
\\ );
\\ unreachable;
\\}
, "");
// Do some arithmetic at the exit callsite
case.addCompareOutput(
\\export fn main() c_int {
\\ exitMath(1);
\\}
\\
\\fn exitMath(a: u8) noreturn {
\\ exit(0 + a - a);
\\}
\\
\\fn exit(code: u8) noreturn {
\\ asm volatile ("syscall"
\\ :
\\ : [number] "{rax}" (231),
\\ [arg1] "{rdi}" (code)
\\ );
\\ unreachable;
\\}
\\
, "");
// Invert the arithmetic
case.addCompareOutput(
\\export fn main() c_int {
\\ exitMath(1);
\\}
\\
\\fn exitMath(a: u8) noreturn {
\\ exit(a + 0 - a);
\\}
\\
\\fn exit(code: u8) noreturn {
\\ asm volatile ("syscall"
\\ :
\\ : [number] "{rax}" (231),
\\ [arg1] "{rdi}" (code)
\\ );
\\ unreachable;
\\}
\\
, "");
}
{
var case = ctx.exeFromCompiledC("alloc and retptr", .{});
case.addCompareOutput(
\\fn add(a: i32, b: i32) i32 {
\\ return a + b;
\\}
\\
\\fn addIndirect(a: i32, b: i32) i32 {
\\ return add(a, b);
\\}
\\
\\export fn main() c_int {
\\ return addIndirect(1, 2) - 3;
\\}
, "");
}
{
var case = ctx.exeFromCompiledC("inferred local const and var", .{});
case.addCompareOutput(
\\fn add(a: i32, b: i32) i32 {
\\ return a + b;
\\}
\\
\\export fn main() c_int {
\\ const x = add(1, 2);
\\ var y = add(3, 0);
\\ y -= x;
\\ return y;
\\}
, "");
}
{
var case = ctx.exeFromCompiledC("@setEvalBranchQuota", .{});
case.addCompareOutput(
\\export fn main() i32 {
\\ @setEvalBranchQuota(1001);
\\ const y = rec(1001);
\\ return y - 1;
\\}
\\
\\inline fn rec(n: usize) usize {
\\ if (n <= 1) return n;
\\ return rec(n - 1);
\\}
, "");
}
ctx.c("empty start function", linux_x64,
\\export fn _start() noreturn {
\\ unreachable;
\\}
,
\\ZIG_EXTERN_C zig_noreturn void _start(void);
\\
\\zig_noreturn void _start(void) {
\\ zig_breakpoint();
\\ zig_unreachable();
\\}
\\
);
ctx.h("simple header", linux_x64,
\\export fn start() void{}
,
\\ZIG_EXTERN_C void start(void);
\\
);
ctx.h("header with single param function", linux_x64,
\\export fn start(a: u8) void{}
,
\\ZIG_EXTERN_C void start(uint8_t a0);
\\
);
ctx.h("header with multiple param function", linux_x64,
\\export fn start(a: u8, b: u8, c: u8) void{}
,
\\ZIG_EXTERN_C void start(uint8_t a0, uint8_t a1, uint8_t a2);
\\
);
ctx.h("header with u32 param function", linux_x64,
\\export fn start(a: u32) void{}
,
\\ZIG_EXTERN_C void start(uint32_t a0);
\\
);
ctx.h("header with usize param function", linux_x64,
\\export fn start(a: usize) void{}
,
\\ZIG_EXTERN_C void start(uintptr_t a0);
\\
);
ctx.h("header with bool param function", linux_x64,
\\export fn start(a: bool) void{}
,
\\ZIG_EXTERN_C void start(bool a0);
\\
);
ctx.h("header with noreturn function", linux_x64,
\\export fn start() noreturn {
\\ unreachable;
\\}
,
\\ZIG_EXTERN_C zig_noreturn void start(void);
\\
);
ctx.h("header with multiple functions", linux_x64,
\\export fn a() void{}
\\export fn b() void{}
\\export fn c() void{}
,
\\ZIG_EXTERN_C void a(void);
\\ZIG_EXTERN_C void b(void);
\\ZIG_EXTERN_C void c(void);
\\
);
ctx.h("header with multiple includes", linux_x64,
\\export fn start(a: u32, b: usize) void{}
,
\\ZIG_EXTERN_C void start(uint32_t a0, uintptr_t a1);
\\
);
}