mirror of
https://github.com/ziglang/zig.git
synced 2025-12-29 09:33:18 +00:00
stage2: Support modifiers in inline asm
These are supported using %[ident:mod] syntax. This allows requesting, e.g., the "w" (32-bit) vs. "x" (64-bit) views of AArch64 registers. See https://llvm.org/docs/LangRef.html#asm-template-argument-modifiers
This commit is contained in:
parent
48798da29b
commit
bc33243650
@ -6290,11 +6290,12 @@ pub const FuncGen = struct {
|
||||
var rendered_template = std.ArrayList(u8).init(self.gpa);
|
||||
defer rendered_template.deinit();
|
||||
|
||||
const State = enum { start, percent, input };
|
||||
const State = enum { start, percent, input, modifier };
|
||||
|
||||
var state: State = .start;
|
||||
|
||||
var name_start: usize = undefined;
|
||||
var modifier_start: usize = undefined;
|
||||
for (asm_source) |byte, i| {
|
||||
switch (state) {
|
||||
.start => switch (byte) {
|
||||
@ -6309,6 +6310,7 @@ pub const FuncGen = struct {
|
||||
},
|
||||
'[' => {
|
||||
try rendered_template.append('$');
|
||||
try rendered_template.append('{');
|
||||
name_start = i + 1;
|
||||
state = .input;
|
||||
},
|
||||
@ -6319,15 +6321,30 @@ pub const FuncGen = struct {
|
||||
},
|
||||
},
|
||||
.input => switch (byte) {
|
||||
']' => {
|
||||
']', ':' => {
|
||||
const name = asm_source[name_start..i];
|
||||
state = .start;
|
||||
|
||||
const index = name_map.get(name) orelse {
|
||||
// we should validate the assembly in Sema; by now it is too late
|
||||
return self.todo("unknown input or output name: '{s}'", .{name});
|
||||
};
|
||||
try rendered_template.writer().print("{d}", .{index});
|
||||
if (byte == ':') {
|
||||
try rendered_template.append(':');
|
||||
modifier_start = i + 1;
|
||||
state = .modifier;
|
||||
} else {
|
||||
try rendered_template.append('}');
|
||||
state = .start;
|
||||
}
|
||||
},
|
||||
else => {},
|
||||
},
|
||||
.modifier => switch (byte) {
|
||||
']' => {
|
||||
try rendered_template.appendSlice(asm_source[modifier_start..i]);
|
||||
try rendered_template.append('}');
|
||||
state = .start;
|
||||
},
|
||||
else => {},
|
||||
},
|
||||
|
||||
@ -136,3 +136,16 @@ extern fn this_is_my_alias() i32;
|
||||
export fn derp() i32 {
|
||||
return 1234;
|
||||
}
|
||||
|
||||
test "asm modifiers (AArch64)" {
|
||||
if (builtin.target.cpu.arch != .aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
|
||||
var x: u32 = 15;
|
||||
const double = asm ("add %[ret:w], %[in:w], %[in:w]"
|
||||
: [ret] "=r" (-> u32),
|
||||
: [in] "r" (x),
|
||||
);
|
||||
try expect(double == 2 * x);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user