mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 12:27:41 +00:00
stage2: handle assembly input names
This commit is contained in:
parent
6655c6092e
commit
75c2cff40e
@ -815,6 +815,8 @@ pub const VectorCmp = struct {
|
||||
/// terminated string. pad to the next u32 after the null byte.
|
||||
/// 3. for every inputs_len
|
||||
/// - constraint: memory at this position is reinterpreted as a null
|
||||
/// terminated string.
|
||||
/// - name: memory at this position is reinterpreted as a null
|
||||
/// terminated string. pad to the next u32 after the null byte.
|
||||
/// 4. for every clobbers_len
|
||||
/// - clobber_name: memory at this position is reinterpreted as a null
|
||||
|
||||
20
src/Sema.zig
20
src/Sema.zig
@ -10295,15 +10295,12 @@ fn zirAsm(
|
||||
};
|
||||
|
||||
const args = try sema.arena.alloc(Air.Inst.Ref, inputs_len);
|
||||
const inputs = try sema.arena.alloc([]const u8, inputs_len);
|
||||
const inputs = try sema.arena.alloc(struct { c: []const u8, n: []const u8 }, inputs_len);
|
||||
|
||||
for (args) |*arg, arg_i| {
|
||||
const input = sema.code.extraData(Zir.Inst.Asm.Input, extra_i);
|
||||
extra_i = input.end;
|
||||
|
||||
const name = sema.code.nullTerminatedString(input.data.name);
|
||||
_ = name; // TODO: use the name
|
||||
|
||||
const uncasted_arg = sema.resolveInst(input.data.operand);
|
||||
const uncasted_arg_ty = sema.typeOf(uncasted_arg);
|
||||
switch (uncasted_arg_ty.zigTypeTag()) {
|
||||
@ -10313,8 +10310,9 @@ fn zirAsm(
|
||||
}
|
||||
|
||||
const constraint = sema.code.nullTerminatedString(input.data.constraint);
|
||||
needed_capacity += constraint.len / 4 + 1;
|
||||
inputs[arg_i] = constraint;
|
||||
const name = sema.code.nullTerminatedString(input.data.name);
|
||||
needed_capacity += (constraint.len + name.len + 1) / 4 + 1;
|
||||
inputs[arg_i] = .{ .c = constraint, .n = name };
|
||||
}
|
||||
|
||||
const clobbers = try sema.arena.alloc([]const u8, clobbers_len);
|
||||
@ -10353,11 +10351,13 @@ fn zirAsm(
|
||||
buffer[o.constraint.len] = 0;
|
||||
sema.air_extra.items.len += o.constraint.len / 4 + 1;
|
||||
}
|
||||
for (inputs) |constraint| {
|
||||
for (inputs) |input| {
|
||||
const buffer = mem.sliceAsBytes(sema.air_extra.unusedCapacitySlice());
|
||||
mem.copy(u8, buffer, constraint);
|
||||
buffer[constraint.len] = 0;
|
||||
sema.air_extra.items.len += constraint.len / 4 + 1;
|
||||
mem.copy(u8, buffer, input.c);
|
||||
buffer[input.c.len] = 0;
|
||||
mem.copy(u8, buffer[input.c.len + 1 ..], input.n);
|
||||
buffer[input.c.len + 1 + input.n.len] = 0;
|
||||
sema.air_extra.items.len += (input.c.len + input.n.len + 1) / 4 + 1;
|
||||
}
|
||||
for (clobbers) |clobber| {
|
||||
const buffer = mem.sliceAsBytes(sema.air_extra.unusedCapacitySlice());
|
||||
|
||||
@ -3200,10 +3200,12 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
|
||||
} else null;
|
||||
|
||||
for (inputs) |input| {
|
||||
const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(self.air.extra[extra_i..]), 0);
|
||||
const input_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]);
|
||||
const constraint = std.mem.sliceTo(input_bytes, 0);
|
||||
const input_name = std.mem.sliceTo(input_bytes[constraint.len + 1 ..], 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.
|
||||
extra_i += constraint.len / 4 + 1;
|
||||
extra_i += (constraint.len + input_name.len + 1) / 4 + 1;
|
||||
|
||||
if (constraint.len < 3 or constraint[0] != '{' or constraint[constraint.len - 1] != '}') {
|
||||
return self.fail("unrecognized asm input constraint: '{s}'", .{constraint});
|
||||
|
||||
@ -3609,10 +3609,12 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
|
||||
} else null;
|
||||
|
||||
for (inputs) |input| {
|
||||
const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(self.air.extra[extra_i..]), 0);
|
||||
const input_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]);
|
||||
const constraint = std.mem.sliceTo(input_bytes, 0);
|
||||
const input_name = std.mem.sliceTo(input_bytes[constraint.len + 1 ..], 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.
|
||||
extra_i += constraint.len / 4 + 1;
|
||||
extra_i += (constraint.len + input_name.len + 1) / 4 + 1;
|
||||
|
||||
if (constraint.len < 3 or constraint[0] != '{' or constraint[constraint.len - 1] != '}') {
|
||||
return self.fail("unrecognized asm input constraint: '{s}'", .{constraint});
|
||||
|
||||
@ -2113,10 +2113,12 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
|
||||
} else null;
|
||||
|
||||
for (inputs) |input| {
|
||||
const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(self.air.extra[extra_i..]), 0);
|
||||
const input_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]);
|
||||
const constraint = std.mem.sliceTo(input_bytes, 0);
|
||||
const input_name = std.mem.sliceTo(input_bytes[constraint.len + 1 ..], 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.
|
||||
extra_i += constraint.len / 4 + 1;
|
||||
extra_i += (constraint.len + input_name.len + 1) / 4 + 1;
|
||||
|
||||
if (constraint.len < 3 or constraint[0] != '{' or constraint[constraint.len - 1] != '}') {
|
||||
return self.fail("unrecognized asm input constraint: '{s}'", .{constraint});
|
||||
|
||||
@ -4618,10 +4618,12 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
|
||||
} else null;
|
||||
|
||||
for (inputs) |input| {
|
||||
const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(self.air.extra[extra_i..]), 0);
|
||||
const input_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]);
|
||||
const constraint = std.mem.sliceTo(input_bytes, 0);
|
||||
const input_name = std.mem.sliceTo(input_bytes[constraint.len + 1 ..], 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.
|
||||
extra_i += constraint.len / 4 + 1;
|
||||
extra_i += (constraint.len + input_name.len + 1) / 4 + 1;
|
||||
|
||||
if (constraint.len < 3 or constraint[0] != '{' or constraint[constraint.len - 1] != '}') {
|
||||
return self.fail("unrecognized asm input constraint: '{s}'", .{constraint});
|
||||
|
||||
@ -4545,11 +4545,14 @@ pub const FuncGen = struct {
|
||||
total_i += 1;
|
||||
}
|
||||
|
||||
const input_start_extra_i = extra_i;
|
||||
for (inputs) |input| {
|
||||
const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(self.air.extra[extra_i..]), 0);
|
||||
const input_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]);
|
||||
const constraint = std.mem.sliceTo(input_bytes, 0);
|
||||
const input_name = std.mem.sliceTo(input_bytes[constraint.len + 1 ..], 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.
|
||||
extra_i += constraint.len / 4 + 1;
|
||||
extra_i += (constraint.len + input_name.len + 1) / 4 + 1;
|
||||
|
||||
const arg_llvm_value = try self.resolveInst(input);
|
||||
|
||||
@ -4591,11 +4594,12 @@ pub const FuncGen = struct {
|
||||
var rendered_template = std.ArrayList(u8).init(self.gpa);
|
||||
defer rendered_template.deinit();
|
||||
|
||||
const State = enum { start, percent };
|
||||
const State = enum { start, percent, input };
|
||||
|
||||
var state: State = .start;
|
||||
|
||||
for (asm_source) |byte| {
|
||||
var name_start: usize = undefined;
|
||||
for (asm_source) |byte, i| {
|
||||
switch (state) {
|
||||
.start => switch (byte) {
|
||||
'%' => state = .percent,
|
||||
@ -4606,12 +4610,39 @@ pub const FuncGen = struct {
|
||||
try rendered_template.append('%');
|
||||
state = .start;
|
||||
},
|
||||
'[' => {
|
||||
try rendered_template.append('$');
|
||||
name_start = i + 1;
|
||||
state = .input;
|
||||
},
|
||||
else => {
|
||||
try rendered_template.append('%');
|
||||
try rendered_template.append(byte);
|
||||
state = .start;
|
||||
},
|
||||
},
|
||||
.input => switch (byte) {
|
||||
']' => {
|
||||
const name = asm_source[name_start..i];
|
||||
state = .start;
|
||||
|
||||
extra_i = input_start_extra_i;
|
||||
for (inputs) |_, input_i| {
|
||||
const input_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]);
|
||||
const constraint = std.mem.sliceTo(input_bytes, 0);
|
||||
const input_name = std.mem.sliceTo(input_bytes[constraint.len + 1 ..], 0);
|
||||
extra_i += (constraint.len + input_name.len + 1) / 4 + 1;
|
||||
|
||||
if (std.mem.eql(u8, name, input_name)) {
|
||||
try rendered_template.writer().print("{d}", .{input_i});
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
return self.todo("TODO validate asm in Sema", .{});
|
||||
}
|
||||
},
|
||||
else => {},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user