mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
cbe: misc fixes
This commit is contained in:
parent
1dd4a6102f
commit
b48417aed2
4 changed files with 75 additions and 52 deletions
|
|
@ -88,23 +88,9 @@ pub fn typeToCIdentifier(ty: Type, mod: *Module) std.fmt.Formatter(formatTypeAsC
|
||||||
}
|
}
|
||||||
|
|
||||||
const reserved_idents = std.ComptimeStringMap(void, .{
|
const reserved_idents = std.ComptimeStringMap(void, .{
|
||||||
.{ "_Alignas", {
|
.{ "alignas", {
|
||||||
@setEvalBranchQuota(4000);
|
@setEvalBranchQuota(4000);
|
||||||
} },
|
} },
|
||||||
.{ "_Alignof", {} },
|
|
||||||
.{ "_Atomic", {} },
|
|
||||||
.{ "_Bool", {} },
|
|
||||||
.{ "_Complex", {} },
|
|
||||||
.{ "_Decimal128", {} },
|
|
||||||
.{ "_Decimal32", {} },
|
|
||||||
.{ "_Decimal64", {} },
|
|
||||||
.{ "_Generic", {} },
|
|
||||||
.{ "_Imaginary", {} },
|
|
||||||
.{ "_Noreturn", {} },
|
|
||||||
.{ "_Pragma", {} },
|
|
||||||
.{ "_Static_assert", {} },
|
|
||||||
.{ "_Thread_local", {} },
|
|
||||||
.{ "alignas", {} },
|
|
||||||
.{ "alignof", {} },
|
.{ "alignof", {} },
|
||||||
.{ "asm", {} },
|
.{ "asm", {} },
|
||||||
.{ "atomic_bool", {} },
|
.{ "atomic_bool", {} },
|
||||||
|
|
@ -199,6 +185,15 @@ const reserved_idents = std.ComptimeStringMap(void, .{
|
||||||
.{ "while ", {} },
|
.{ "while ", {} },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
fn isReservedIdent(ident: []const u8) bool {
|
||||||
|
if (ident.len >= 2 and ident[0] == '_') {
|
||||||
|
switch (ident[1]) {
|
||||||
|
'A'...'Z', '_' => return true,
|
||||||
|
else => return false,
|
||||||
|
}
|
||||||
|
} else return reserved_idents.has(ident);
|
||||||
|
}
|
||||||
|
|
||||||
fn formatIdent(
|
fn formatIdent(
|
||||||
ident: []const u8,
|
ident: []const u8,
|
||||||
comptime fmt: []const u8,
|
comptime fmt: []const u8,
|
||||||
|
|
@ -207,7 +202,7 @@ fn formatIdent(
|
||||||
) !void {
|
) !void {
|
||||||
_ = options;
|
_ = options;
|
||||||
const solo = fmt.len != 0 and fmt[0] == ' '; // space means solo; not part of a bigger ident.
|
const solo = fmt.len != 0 and fmt[0] == ' '; // space means solo; not part of a bigger ident.
|
||||||
if (solo and reserved_idents.has(ident)) {
|
if (solo and isReservedIdent(ident)) {
|
||||||
try writer.writeAll("zig_e_");
|
try writer.writeAll("zig_e_");
|
||||||
}
|
}
|
||||||
for (ident) |c, i| {
|
for (ident) |c, i| {
|
||||||
|
|
@ -601,12 +596,17 @@ pub const DeclGen = struct {
|
||||||
try dg.renderTypecast(writer, ty);
|
try dg.renderTypecast(writer, ty);
|
||||||
try writer.writeAll("){");
|
try writer.writeAll("){");
|
||||||
|
|
||||||
|
if (ty.unionTagTypeSafety()) |tag_ty| {
|
||||||
|
try writer.writeAll(".tag = ");
|
||||||
|
try dg.renderValue(writer, tag_ty, val, location);
|
||||||
|
try writer.writeAll(", .payload = {");
|
||||||
|
}
|
||||||
for (ty.unionFields().values()) |field| {
|
for (ty.unionFields().values()) |field| {
|
||||||
if (!field.ty.hasRuntimeBits()) continue;
|
if (!field.ty.hasRuntimeBits()) continue;
|
||||||
try dg.renderValue(writer, field.ty, val, location);
|
try dg.renderValue(writer, field.ty, val, location);
|
||||||
break;
|
break;
|
||||||
} else try writer.print("{x}", .{try dg.fmtIntLiteral(Type.u8, Value.undef)});
|
} else try writer.print("{x}", .{try dg.fmtIntLiteral(Type.u8, Value.undef)});
|
||||||
|
if (ty.unionTagTypeSafety()) |_| try writer.writeByte('}');
|
||||||
return writer.writeByte('}');
|
return writer.writeByte('}');
|
||||||
},
|
},
|
||||||
.ErrorUnion => {
|
.ErrorUnion => {
|
||||||
|
|
@ -3469,22 +3469,22 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
|
||||||
extra_i += (constraint.len + name.len + (2 + 3)) / 4;
|
extra_i += (constraint.len + name.len + (2 + 3)) / 4;
|
||||||
|
|
||||||
const output_ty = if (output == .none) inst_ty else f.air.typeOf(output).childType();
|
const output_ty = if (output == .none) inst_ty else f.air.typeOf(output).childType();
|
||||||
|
if (std.mem.startsWith(u8, constraint, "={") and std.mem.endsWith(u8, constraint, "}")) {
|
||||||
try writer.writeAll("register ");
|
try writer.writeAll("register ");
|
||||||
try f.object.dg.renderTypeAndName(writer, output_ty, .{
|
try f.object.dg.renderTypeAndName(writer, output_ty, .{
|
||||||
.local = output_locals_begin + index,
|
.local = output_locals_begin + index,
|
||||||
}, .Mut, 0);
|
}, .Mut, 0);
|
||||||
if (std.mem.startsWith(u8, constraint, "={") and std.mem.endsWith(u8, constraint, "}")) {
|
|
||||||
try writer.writeAll(" __asm(\"");
|
try writer.writeAll(" __asm(\"");
|
||||||
try writer.writeAll(constraint["={".len .. constraint.len - "}".len]);
|
try writer.writeAll(constraint["={".len .. constraint.len - "}".len]);
|
||||||
try writer.writeAll("\")");
|
try writer.writeAll("\")");
|
||||||
} else if (constraint.len < 2 or constraint[0] != '=') {
|
|
||||||
return f.fail("CBE: constraint not supported: '{s}'", .{constraint});
|
|
||||||
}
|
|
||||||
if (f.wantSafety()) {
|
if (f.wantSafety()) {
|
||||||
try writer.writeAll(" = ");
|
try writer.writeAll(" = ");
|
||||||
try f.object.dg.renderValue(writer, output_ty, Value.undef, .Other);
|
try f.object.dg.renderValue(writer, output_ty, Value.undef, .Other);
|
||||||
}
|
}
|
||||||
try writer.writeAll(";\n");
|
try writer.writeAll(";\n");
|
||||||
|
} else if (constraint.len < 2 or constraint[0] != '=') {
|
||||||
|
return f.fail("CBE: constraint not supported: '{s}'", .{constraint});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const input_locals_begin = f.next_local_index;
|
const input_locals_begin = f.next_local_index;
|
||||||
f.next_local_index += inputs.len;
|
f.next_local_index += inputs.len;
|
||||||
|
|
@ -3497,20 +3497,29 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
|
||||||
extra_i += (constraint.len + name.len + (2 + 3)) / 4;
|
extra_i += (constraint.len + name.len + (2 + 3)) / 4;
|
||||||
|
|
||||||
const input_ty = f.air.typeOf(input);
|
const input_ty = f.air.typeOf(input);
|
||||||
|
if (std.mem.startsWith(u8, constraint, "{") and std.mem.endsWith(u8, constraint, "}")) {
|
||||||
try writer.writeAll("register ");
|
try writer.writeAll("register ");
|
||||||
try f.object.dg.renderTypeAndName(writer, input_ty, .{
|
try f.object.dg.renderTypeAndName(writer, input_ty, .{
|
||||||
.local = input_locals_begin + index,
|
.local = input_locals_begin + index,
|
||||||
}, .Const, 0);
|
}, .Const, 0);
|
||||||
if (std.mem.startsWith(u8, constraint, "{") and std.mem.endsWith(u8, constraint, "}")) {
|
|
||||||
try writer.writeAll(" __asm(\"");
|
try writer.writeAll(" __asm(\"");
|
||||||
try writer.writeAll(constraint["{".len .. constraint.len - "}".len]);
|
try writer.writeAll(constraint["{".len .. constraint.len - "}".len]);
|
||||||
try writer.writeAll("\")");
|
try writer.writeAll("\") = ");
|
||||||
} else if (constraint.len < 1 or std.mem.indexOfScalar(u8, "=+&%", constraint[0]) != null) {
|
|
||||||
return f.fail("CBE: constraint not supported: '{s}'", .{constraint});
|
|
||||||
}
|
|
||||||
try writer.writeAll(" = ");
|
|
||||||
try f.writeCValue(writer, try f.resolveInst(input));
|
try f.writeCValue(writer, try f.resolveInst(input));
|
||||||
try writer.writeAll(";\n");
|
try writer.writeAll(";\n");
|
||||||
|
} else if (constraint.len >= 1 and std.mem.indexOfScalar(u8, "=+&%", constraint[0]) == null) {
|
||||||
|
const input_val = try f.resolveInst(input);
|
||||||
|
if (input_val == .constant) {
|
||||||
|
try f.object.dg.renderTypeAndName(writer, input_ty, .{
|
||||||
|
.local = input_locals_begin + index,
|
||||||
|
}, .Const, 0);
|
||||||
|
try writer.writeAll(" = ");
|
||||||
|
try f.writeCValue(writer, input_val);
|
||||||
|
try writer.writeAll(";\n");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return f.fail("CBE: constraint not supported: '{s}'", .{constraint});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
var clobber_i: u32 = 0;
|
var clobber_i: u32 = 0;
|
||||||
|
|
@ -3529,7 +3538,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
|
||||||
|
|
||||||
extra_i = constraints_extra_begin;
|
extra_i = constraints_extra_begin;
|
||||||
try writer.writeByte(':');
|
try writer.writeByte(':');
|
||||||
for (outputs) |_, index| {
|
for (outputs) |output, index| {
|
||||||
const extra_bytes = std.mem.sliceAsBytes(f.air.extra[extra_i..]);
|
const extra_bytes = std.mem.sliceAsBytes(f.air.extra[extra_i..]);
|
||||||
const constraint = std.mem.sliceTo(extra_bytes, 0);
|
const constraint = std.mem.sliceTo(extra_bytes, 0);
|
||||||
const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0);
|
const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0);
|
||||||
|
|
@ -3538,12 +3547,18 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
|
||||||
extra_i += (constraint.len + name.len + (2 + 3)) / 4;
|
extra_i += (constraint.len + name.len + (2 + 3)) / 4;
|
||||||
|
|
||||||
if (index > 0) try writer.writeByte(',');
|
if (index > 0) try writer.writeByte(',');
|
||||||
try writer.print(" {s}(", .{fmtStringLiteral(if (constraint[1] == '{') "=r" else constraint)});
|
try writer.writeByte(' ');
|
||||||
|
if (constraint[1] == '{') {
|
||||||
|
try writer.print("{s}(", .{fmtStringLiteral("=r")});
|
||||||
try f.writeCValue(writer, .{ .local = output_locals_begin + index });
|
try f.writeCValue(writer, .{ .local = output_locals_begin + index });
|
||||||
|
} else {
|
||||||
|
try writer.print("{s}(", .{fmtStringLiteral(constraint)});
|
||||||
|
try f.writeCValueDeref(writer, try f.resolveInst(output));
|
||||||
|
}
|
||||||
try writer.writeByte(')');
|
try writer.writeByte(')');
|
||||||
}
|
}
|
||||||
try writer.writeByte(':');
|
try writer.writeByte(':');
|
||||||
for (inputs) |_, index| {
|
for (inputs) |input, index| {
|
||||||
const extra_bytes = std.mem.sliceAsBytes(f.air.extra[extra_i..]);
|
const extra_bytes = std.mem.sliceAsBytes(f.air.extra[extra_i..]);
|
||||||
const constraint = std.mem.sliceTo(extra_bytes, 0);
|
const constraint = std.mem.sliceTo(extra_bytes, 0);
|
||||||
const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0);
|
const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0);
|
||||||
|
|
@ -3552,8 +3567,17 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
|
||||||
extra_i += (constraint.len + name.len + (2 + 3)) / 4;
|
extra_i += (constraint.len + name.len + (2 + 3)) / 4;
|
||||||
|
|
||||||
if (index > 0) try writer.writeByte(',');
|
if (index > 0) try writer.writeByte(',');
|
||||||
try writer.print(" {s}(", .{fmtStringLiteral(if (constraint[0] == '{') "r" else constraint)});
|
try writer.writeByte(' ');
|
||||||
|
if (constraint[0] == '{') {
|
||||||
|
try writer.print("{s}(", .{fmtStringLiteral("r")});
|
||||||
try f.writeCValue(writer, .{ .local = input_locals_begin + index });
|
try f.writeCValue(writer, .{ .local = input_locals_begin + index });
|
||||||
|
} else {
|
||||||
|
const input_val = try f.resolveInst(input);
|
||||||
|
try writer.print("{s}(", .{fmtStringLiteral(constraint)});
|
||||||
|
try f.writeCValue(writer, if (input_val == .constant) .{
|
||||||
|
.local = input_locals_begin + index,
|
||||||
|
} else input_val);
|
||||||
|
}
|
||||||
try writer.writeByte(')');
|
try writer.writeByte(')');
|
||||||
}
|
}
|
||||||
try writer.writeByte(':');
|
try writer.writeByte(':');
|
||||||
|
|
@ -3582,6 +3606,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
|
||||||
// for the string, we still use the next u32 for the null terminator.
|
// for the string, we still use the next u32 for the null terminator.
|
||||||
extra_i += (constraint.len + name.len + (2 + 3)) / 4;
|
extra_i += (constraint.len + name.len + (2 + 3)) / 4;
|
||||||
|
|
||||||
|
if (constraint[1] == '{') {
|
||||||
try f.writeCValueDeref(writer, if (output == .none) CValue{
|
try f.writeCValueDeref(writer, if (output == .none) CValue{
|
||||||
.local_ref = local.local,
|
.local_ref = local.local,
|
||||||
} else try f.resolveInst(output));
|
} else try f.resolveInst(output));
|
||||||
|
|
@ -3589,6 +3614,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
|
||||||
try f.writeCValue(writer, .{ .local = output_locals_begin + index });
|
try f.writeCValue(writer, .{ .local = output_locals_begin + index });
|
||||||
try writer.writeAll(";\n");
|
try writer.writeAll(";\n");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
f.object.indent_writer.popIndent();
|
f.object.indent_writer.popIndent();
|
||||||
try writer.writeAll("}\n");
|
try writer.writeAll("}\n");
|
||||||
|
|
@ -4415,12 +4441,12 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
|
||||||
const elem_ty = inst_ty.childType();
|
const elem_ty = inst_ty.childType();
|
||||||
var empty = true;
|
var empty = true;
|
||||||
for (elements) |element| {
|
for (elements) |element| {
|
||||||
if (empty) try writer.writeAll(", ");
|
if (!empty) try writer.writeAll(", ");
|
||||||
try f.writeCValue(writer, try f.resolveInst(element));
|
try f.writeCValue(writer, try f.resolveInst(element));
|
||||||
empty = false;
|
empty = false;
|
||||||
}
|
}
|
||||||
if (inst_ty.sentinel()) |sentinel| {
|
if (inst_ty.sentinel()) |sentinel| {
|
||||||
if (empty) try writer.writeAll(", ");
|
if (!empty) try writer.writeAll(", ");
|
||||||
try f.object.dg.renderValue(writer, elem_ty, sentinel, .Other);
|
try f.object.dg.renderValue(writer, elem_ty, sentinel, .Other);
|
||||||
empty = false;
|
empty = false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -112,7 +112,6 @@ test "sized integer/float in asm input" {
|
||||||
}
|
}
|
||||||
|
|
||||||
test "struct/array/union types as input values" {
|
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_wasm) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_x86_64) 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_arm) return error.SkipZigTest; // TODO
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ pub fn f(_: [:null]const ?u8) void {}
|
||||||
test {
|
test {
|
||||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
|
||||||
|
|
||||||
const c: u8 = 42;
|
const c: u8 = 42;
|
||||||
f(&[_:null]?u8{c});
|
f(&[_:null]?u8{c});
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ fn foo(val: U) !void {
|
||||||
}
|
}
|
||||||
|
|
||||||
test "runtime union init, most-aligned field != largest" {
|
test "runtime union init, most-aligned field != largest" {
|
||||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
|
||||||
if (builtin.zig_backend == .stage2_arm) 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_aarch64) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue