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.
This commit is contained in:
Daniele Cocca
2022-03-20 21:04:28 +00:00
committed by Veikka Tuominen
parent ebafdb958c
commit 907dc1e13f
3 changed files with 51 additions and 10 deletions

View File

@@ -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;