authorgravatar for daniele.cocca@gmail.comDaniele Cocca <daniele.cocca@gmail.com> 2022-03-20 21:04:28+00:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-03-30 12:10:02+03:00
log907dc1e13f657f349dbdecf739b2f1a13ad7011a
tree0026ce30fe407ce78c5e7b68a733b4c1f91b8a4a
parentebafdb958c1aa6b41c28fc7d45f44e38a69a3bd5

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.

3 files changed, 51 insertions(+), 10 deletions(-)

src/codegen/c.zig+13-5
......@@ -3014,9 +3014,10 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
30143014 } else null;
30153015
30163016 const writer = f.object.writer();
3017 const inputs_extra_begin = extra_i;
3017 try writer.writeAll("{\n");
30183018
3019 for (inputs) |input| {
3019 const inputs_extra_begin = extra_i;
3020 for (inputs) |input, i| {
30203021 const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(f.air.extra[extra_i..]), 0);
30213022 // This equation accounts for the fact that even if we have exactly 4 bytes
30223023 // 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 {
30323033 try f.writeCValue(writer, arg_c_value);
30333034 try writer.writeAll(";\n");
30343035 } else {
3035 return f.fail("TODO non-explicit inline asm regs", .{});
3036 try writer.writeAll("register ");
3037 try f.renderType(writer, f.air.typeOf(input));
3038 try writer.print(" input_{d} = ", .{i});
3039 try f.writeCValue(writer, try f.resolveInst(input));
3040 try writer.writeAll(";\n");
30363041 }
30373042 }
30383043
......@@ -3074,12 +3079,15 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
30743079 }
30753080 try writer.print("\"r\"({s}_constant)", .{reg});
30763081 } else {
3077 // This is blocked by the earlier test
3078 unreachable;
3082 if (index > 0) {
3083 try writer.writeAll(", ");
3084 }
3085 try writer.print("\"r\"(input_{d})", .{index});
30793086 }
30803087 }
30813088 }
30823089 try writer.writeAll(");\n");
3090 try writer.writeAll("}\n");
30833091
30843092 if (f.liveness.isUnused(inst))
30853093 return CValue.none;
test/behavior.zig+1-4
......@@ -165,10 +165,7 @@ test {
165165 }
166166
167167 if (builtin.os.tag != .wasi) {
168 if (builtin.zig_backend == .stage1) {
169 // TODO get these tests passing with stage2
170 _ = @import("behavior/asm.zig");
171 }
168 _ = @import("behavior/asm.zig");
172169 }
173170
174171 if (builtin.zig_backend != .stage2_arm and
test/behavior/asm.zig+37-1
......@@ -5,7 +5,10 @@ const expect = std.testing.expect;
55const is_x86_64_linux = builtin.cpu.arch == .x86_64 and builtin.os.tag == .linux;
66
77comptime {
8 if (is_x86_64_linux) {
8 if (builtin.zig_backend != .stage2_arm and
9 builtin.zig_backend != .stage2_aarch64 and
10 is_x86_64_linux)
11 {
912 asm (
1013 \\.globl this_is_my_alias;
1114 \\.type this_is_my_alias, @function;
......@@ -15,12 +18,26 @@ comptime {
1518}
1619
1720test "module level assembly" {
21 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
22 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
23 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
24 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
25 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
26 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO
27
1828 if (is_x86_64_linux) {
1929 try expect(this_is_my_alias() == 1234);
2030 }
2131}
2232
2333test "output constraint modifiers" {
34 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
35 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
36 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
37 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
38 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
39 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO
40
2441 // This is only testing compilation.
2542 var a: u32 = 3;
2643 asm volatile (""
......@@ -36,6 +53,13 @@ test "output constraint modifiers" {
3653}
3754
3855test "alternative constraints" {
56 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
57 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
58 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
59 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
60 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
61 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO
62
3963 // Make sure we allow commas as a separator for alternative constraints.
4064 var a: u32 = 3;
4165 asm volatile (""
......@@ -46,6 +70,11 @@ test "alternative constraints" {
4670}
4771
4872test "sized integer/float in asm input" {
73 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
74 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
75 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
76 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
77
4978 asm volatile (""
5079 :
5180 : [_] "m" (@as(usize, 3)),
......@@ -89,6 +118,13 @@ test "sized integer/float in asm input" {
89118}
90119
91120test "struct/array/union types as input values" {
121 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
122 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
123 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
124 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
125 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
126 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO
127
92128 asm volatile (""
93129 :
94130 : [_] "m" (@as([1]u32, undefined)),