diff options
| author | Daniele Cocca <daniele.cocca@gmail.com> | 2022-03-20 21:04:28 +0000 |
|---|---|---|
| committer | Veikka Tuominen <git@vexu.eu> | 2022-03-30 12:10:02 +0300 |
| commit | 907dc1e13f657f349dbdecf739b2f1a13ad7011a (patch) | |
| tree | 0026ce30fe407ce78c5e7b68a733b4c1f91b8a4a | |
| parent | ebafdb958c1aa6b41c28fc7d45f44e38a69a3bd5 (diff) | |
| download | zig-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.zig | 18 | ||||
| -rw-r--r-- | test/behavior.zig | 5 | ||||
| -rw-r--r-- | test/behavior/asm.zig | 38 |
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)), |
