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 {...@@ -3014,9 +3014,10 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
3014 } else null;3014 } else null;
30153015
3016 const writer = f.object.writer();3016 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| {
3020 const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(f.air.extra[extra_i..]), 0);3021 const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(f.air.extra[extra_i..]), 0);
3021 // This equation accounts for the fact that even if we have exactly 4 bytes3022 // This equation accounts for the fact that even if we have exactly 4 bytes
3022 // for the string, we still use the next u32 for the null terminator.3023 // 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 {...@@ -3032,7 +3033,11 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
3032 try f.writeCValue(writer, arg_c_value);3033 try f.writeCValue(writer, arg_c_value);
3033 try writer.writeAll(";\n");3034 try writer.writeAll(";\n");
3034 } else {3035 } 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");
3036 }3041 }
3037 }3042 }
30383043
...@@ -3074,12 +3079,15 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3074,12 +3079,15 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
3074 }3079 }
3075 try writer.print("\"r\"({s}_constant)", .{reg});3080 try writer.print("\"r\"({s}_constant)", .{reg});
3076 } else {3081 } else {
3077 // This is blocked by the earlier test3082 if (index > 0) {
3078 unreachable;3083 try writer.writeAll(", ");
3084 }
3085 try writer.print("\"r\"(input_{d})", .{index});
3079 }3086 }
3080 }3087 }
3081 }3088 }
3082 try writer.writeAll(");\n");3089 try writer.writeAll(");\n");
3090 try writer.writeAll("}\n");
30833091
3084 if (f.liveness.isUnused(inst))3092 if (f.liveness.isUnused(inst))
3085 return CValue.none;3093 return CValue.none;
test/behavior.zig+1-4
...@@ -165,10 +165,7 @@ test {...@@ -165,10 +165,7 @@ test {
165 }165 }
166166
167 if (builtin.os.tag != .wasi) {167 if (builtin.os.tag != .wasi) {
168 if (builtin.zig_backend == .stage1) {168 _ = @import("behavior/asm.zig");
169 // TODO get these tests passing with stage2
170 _ = @import("behavior/asm.zig");
171 }
172 }169 }
173170
174 if (builtin.zig_backend != .stage2_arm and171 if (builtin.zig_backend != .stage2_arm and
test/behavior/asm.zig+37-1
...@@ -5,7 +5,10 @@ const expect = std.testing.expect;...@@ -5,7 +5,10 @@ const expect = std.testing.expect;
5const is_x86_64_linux = builtin.cpu.arch == .x86_64 and builtin.os.tag == .linux;5const is_x86_64_linux = builtin.cpu.arch == .x86_64 and builtin.os.tag == .linux;
66
7comptime {7comptime {
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 {
9 asm (12 asm (
10 \\.globl this_is_my_alias;13 \\.globl this_is_my_alias;
11 \\.type this_is_my_alias, @function;14 \\.type this_is_my_alias, @function;
...@@ -15,12 +18,26 @@ comptime {...@@ -15,12 +18,26 @@ comptime {
15}18}
1619
17test "module level assembly" {20test "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
18 if (is_x86_64_linux) {28 if (is_x86_64_linux) {
19 try expect(this_is_my_alias() == 1234);29 try expect(this_is_my_alias() == 1234);
20 }30 }
21}31}
2232
23test "output constraint modifiers" {33test "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
24 // This is only testing compilation.41 // This is only testing compilation.
25 var a: u32 = 3;42 var a: u32 = 3;
26 asm volatile (""43 asm volatile (""
...@@ -36,6 +53,13 @@ test "output constraint modifiers" {...@@ -36,6 +53,13 @@ test "output constraint modifiers" {
36}53}
3754
38test "alternative constraints" {55test "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
39 // Make sure we allow commas as a separator for alternative constraints.63 // Make sure we allow commas as a separator for alternative constraints.
40 var a: u32 = 3;64 var a: u32 = 3;
41 asm volatile (""65 asm volatile (""
...@@ -46,6 +70,11 @@ test "alternative constraints" {...@@ -46,6 +70,11 @@ test "alternative constraints" {
46}70}
4771
48test "sized integer/float in asm input" {72test "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
49 asm volatile (""78 asm volatile (""
50 :79 :
51 : [_] "m" (@as(usize, 3)),80 : [_] "m" (@as(usize, 3)),
...@@ -89,6 +118,13 @@ test "sized integer/float in asm input" {...@@ -89,6 +118,13 @@ test "sized integer/float in asm input" {
89}118}
90119
91test "struct/array/union types as input values" {120test "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
92 asm volatile (""128 asm volatile (""
93 :129 :
94 : [_] "m" (@as([1]u32, undefined)),130 : [_] "m" (@as([1]u32, undefined)),