aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniele Cocca <daniele.cocca@gmail.com>2022-03-20 21:04:28 +0000
committerVeikka Tuominen <git@vexu.eu>2022-03-30 12:10:02 +0300
commit907dc1e13f657f349dbdecf739b2f1a13ad7011a (patch)
tree0026ce30fe407ce78c5e7b68a733b4c1f91b8a4a
parentebafdb958c1aa6b41c28fc7d45f44e38a69a3bd5 (diff)
downloadzig-907dc1e13f657f349dbdecf739b2f1a13ad7011a.tar.gz
zig-907dc1e13f657f349dbdecf739b2f1a13ad7011a.zip
CBE: improve support for asm inputs
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.
-rw-r--r--src/codegen/c.zig18
-rw-r--r--test/behavior.zig5
-rw-r--r--test/behavior/asm.zig38
3 files changed, 51 insertions, 10 deletions
diff --git a/src/codegen/c.zig b/src/codegen/c.zig
index 19556fe8c4..4085305941 100644
--- a/src/codegen/c.zig
+++ b/src/codegen/c.zig
@@ -3014,9 +3014,10 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
} else null;
const writer = f.object.writer();
- const inputs_extra_begin = extra_i;
+ try writer.writeAll("{\n");
- for (inputs) |input| {
+ const inputs_extra_begin = extra_i;
+ for (inputs) |input, i| {
const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(f.air.extra[extra_i..]), 0);
// This equation accounts for the fact that even if we have exactly 4 bytes
// for the string, we still use the next u32 for the null terminator.
@@ -3032,7 +3033,11 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
try f.writeCValue(writer, arg_c_value);
try writer.writeAll(";\n");
} else {
- return f.fail("TODO non-explicit inline asm regs", .{});
+ try writer.writeAll("register ");
+ try f.renderType(writer, f.air.typeOf(input));
+ try writer.print(" input_{d} = ", .{i});
+ try f.writeCValue(writer, try f.resolveInst(input));
+ try writer.writeAll(";\n");
}
}
@@ -3074,12 +3079,15 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
}
try writer.print("\"r\"({s}_constant)", .{reg});
} else {
- // This is blocked by the earlier test
- unreachable;
+ if (index > 0) {
+ try writer.writeAll(", ");
+ }
+ try writer.print("\"r\"(input_{d})", .{index});
}
}
}
try writer.writeAll(");\n");
+ try writer.writeAll("}\n");
if (f.liveness.isUnused(inst))
return CValue.none;
diff --git a/test/behavior.zig b/test/behavior.zig
index 60b8d2bae7..de61efa482 100644
--- a/test/behavior.zig
+++ b/test/behavior.zig
@@ -165,10 +165,7 @@ test {
}
if (builtin.os.tag != .wasi) {
- if (builtin.zig_backend == .stage1) {
- // TODO get these tests passing with stage2
- _ = @import("behavior/asm.zig");
- }
+ _ = @import("behavior/asm.zig");
}
if (builtin.zig_backend != .stage2_arm and
diff --git a/test/behavior/asm.zig b/test/behavior/asm.zig
index f856f0128e..dab6f12127 100644
--- a/test/behavior/asm.zig
+++ b/test/behavior/asm.zig
@@ -5,7 +5,10 @@ const expect = std.testing.expect;
const is_x86_64_linux = builtin.cpu.arch == .x86_64 and builtin.os.tag == .linux;
comptime {
- if (is_x86_64_linux) {
+ 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;
@@ -15,12 +18,26 @@ comptime {
}
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 (""
@@ -36,6 +53,13 @@ test "output constraint modifiers" {
}
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 (""
@@ -46,6 +70,11 @@ test "alternative constraints" {
}
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)),
@@ -89,6 +118,13 @@ test "sized integer/float in asm input" {
}
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)),