mirror of
https://github.com/ziglang/zig.git
synced 2025-12-15 18:53:07 +00:00
This is not complete support for asm expressions, but allows a few more
test cases from test/behavior/asm.zig to pass. Since the non-register
inputs are named `input_${n}` they can cause name collisions: I'm
wrapping the asm expressions in their own block to prevent that.
Contextually, this change also makes test/behavior/asm.zig run for
stage2, but skips individual tests for most backends (I only verified
the C and LLVM backends successfully run one new test case) and the
entire test file for aarch64, where it's running into preexisting
shortcomings.
147 lines
4.4 KiB
Zig
147 lines
4.4 KiB
Zig
const std = @import("std");
|
|
const builtin = @import("builtin");
|
|
const expect = std.testing.expect;
|
|
|
|
const is_x86_64_linux = builtin.cpu.arch == .x86_64 and builtin.os.tag == .linux;
|
|
|
|
comptime {
|
|
if (builtin.zig_backend != .stage2_arm and
|
|
builtin.zig_backend != .stage2_aarch64 and
|
|
is_x86_64_linux)
|
|
{
|
|
asm (
|
|
\\.globl this_is_my_alias;
|
|
\\.type this_is_my_alias, @function;
|
|
\\.set this_is_my_alias, derp;
|
|
);
|
|
}
|
|
}
|
|
|
|
test "module level assembly" {
|
|
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
|
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
|
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
|
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
|
if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO
|
|
|
|
if (is_x86_64_linux) {
|
|
try expect(this_is_my_alias() == 1234);
|
|
}
|
|
}
|
|
|
|
test "output constraint modifiers" {
|
|
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
|
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
|
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
|
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
|
if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO
|
|
|
|
// This is only testing compilation.
|
|
var a: u32 = 3;
|
|
asm volatile (""
|
|
: [_] "=m,r" (a),
|
|
:
|
|
: ""
|
|
);
|
|
asm volatile (""
|
|
: [_] "=r,m" (a),
|
|
:
|
|
: ""
|
|
);
|
|
}
|
|
|
|
test "alternative constraints" {
|
|
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
|
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
|
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
|
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
|
if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO
|
|
|
|
// Make sure we allow commas as a separator for alternative constraints.
|
|
var a: u32 = 3;
|
|
asm volatile (""
|
|
: [_] "=r,m" (a),
|
|
: [_] "r,m" (a),
|
|
: ""
|
|
);
|
|
}
|
|
|
|
test "sized integer/float in asm input" {
|
|
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
|
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
|
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
|
|
|
asm volatile (""
|
|
:
|
|
: [_] "m" (@as(usize, 3)),
|
|
: ""
|
|
);
|
|
asm volatile (""
|
|
:
|
|
: [_] "m" (@as(i15, -3)),
|
|
: ""
|
|
);
|
|
asm volatile (""
|
|
:
|
|
: [_] "m" (@as(u3, 3)),
|
|
: ""
|
|
);
|
|
asm volatile (""
|
|
:
|
|
: [_] "m" (@as(i3, 3)),
|
|
: ""
|
|
);
|
|
asm volatile (""
|
|
:
|
|
: [_] "m" (@as(u121, 3)),
|
|
: ""
|
|
);
|
|
asm volatile (""
|
|
:
|
|
: [_] "m" (@as(i121, 3)),
|
|
: ""
|
|
);
|
|
asm volatile (""
|
|
:
|
|
: [_] "m" (@as(f32, 3.17)),
|
|
: ""
|
|
);
|
|
asm volatile (""
|
|
:
|
|
: [_] "m" (@as(f64, 3.17)),
|
|
: ""
|
|
);
|
|
}
|
|
|
|
test "struct/array/union types as input values" {
|
|
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
|
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
|
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
|
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
|
if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO
|
|
|
|
asm volatile (""
|
|
:
|
|
: [_] "m" (@as([1]u32, undefined)),
|
|
); // fails
|
|
asm volatile (""
|
|
:
|
|
: [_] "m" (@as(struct { x: u32, y: u8 }, undefined)),
|
|
); // fails
|
|
asm volatile (""
|
|
:
|
|
: [_] "m" (@as(union { x: u32, y: u8 }, undefined)),
|
|
); // fails
|
|
}
|
|
|
|
extern fn this_is_my_alias() i32;
|
|
|
|
export fn derp() i32 {
|
|
return 1234;
|
|
}
|