aboutsummaryrefslogtreecommitdiff
path: root/src/codegen
diff options
context:
space:
mode:
authorCody Tapscott <topolarity@tapscott.me>2022-11-10 14:02:05 -0700
committerVeikka Tuominen <git@vexu.eu>2022-11-11 16:01:31 +0200
commit2897641fb95a614ae61a444e43a0555804701910 (patch)
tree087c2e8dd0b2c2ea408cf9523eb095c62c24b826 /src/codegen
parentb605cb2742092530b7edf4c9d95c0ae28051ce95 (diff)
downloadzig-2897641fb95a614ae61a444e43a0555804701910.tar.gz
zig-2897641fb95a614ae61a444e43a0555804701910.zip
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
Diffstat (limited to 'src/codegen')
-rw-r--r--src/codegen/llvm.zig23
1 files changed, 20 insertions, 3 deletions
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig
index e93152df02..acbf5b337f 100644
--- a/src/codegen/llvm.zig
+++ b/src/codegen/llvm.zig
@@ -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 => {},
},