authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2022-10-18 21:41:00-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2022-10-25 05:11:29-04:00
logb48417aed25db27aa3b200c2f118b88b8f91c48c
tree5eeca5f7c80a5f37df350ea23ea1c0acdb7e183a
parent1dd4a6102ff983c828cdaa3dbadef37272ffce7c

cbe: misc fixes


4 files changed, 75 insertions(+), 52 deletions(-)

src/codegen/c.zig+75-49
......@@ -88,23 +88,9 @@ pub fn typeToCIdentifier(ty: Type, mod: *Module) std.fmt.Formatter(formatTypeAsC
8888}
8989
9090const reserved_idents = std.ComptimeStringMap(void, .{
91 .{ "_Alignas", {
91 .{ "alignas", {
9292 @setEvalBranchQuota(4000);
9393 } },
94 .{ "_Alignof", {} },
95 .{ "_Atomic", {} },
96 .{ "_Bool", {} },
97 .{ "_Complex", {} },
98 .{ "_Decimal128", {} },
99 .{ "_Decimal32", {} },
100 .{ "_Decimal64", {} },
101 .{ "_Generic", {} },
102 .{ "_Imaginary", {} },
103 .{ "_Noreturn", {} },
104 .{ "_Pragma", {} },
105 .{ "_Static_assert", {} },
106 .{ "_Thread_local", {} },
107 .{ "alignas", {} },
10894 .{ "alignof", {} },
10995 .{ "asm", {} },
11096 .{ "atomic_bool", {} },
......@@ -199,6 +185,15 @@ const reserved_idents = std.ComptimeStringMap(void, .{
199185 .{ "while ", {} },
200186});
201187
188fn isReservedIdent(ident: []const u8) bool {
189 if (ident.len >= 2 and ident[0] == '_') {
190 switch (ident[1]) {
191 'A'...'Z', '_' => return true,
192 else => return false,
193 }
194 } else return reserved_idents.has(ident);
195}
196
202197fn formatIdent(
203198 ident: []const u8,
204199 comptime fmt: []const u8,
......@@ -207,7 +202,7 @@ fn formatIdent(
207202) !void {
208203 _ = options;
209204 const solo = fmt.len != 0 and fmt[0] == ' '; // space means solo; not part of a bigger ident.
210 if (solo and reserved_idents.has(ident)) {
205 if (solo and isReservedIdent(ident)) {
211206 try writer.writeAll("zig_e_");
212207 }
213208 for (ident) |c, i| {
......@@ -601,12 +596,17 @@ pub const DeclGen = struct {
601596 try dg.renderTypecast(writer, ty);
602597 try writer.writeAll("){");
603598
599 if (ty.unionTagTypeSafety()) |tag_ty| {
600 try writer.writeAll(".tag = ");
601 try dg.renderValue(writer, tag_ty, val, location);
602 try writer.writeAll(", .payload = {");
603 }
604604 for (ty.unionFields().values()) |field| {
605605 if (!field.ty.hasRuntimeBits()) continue;
606606 try dg.renderValue(writer, field.ty, val, location);
607607 break;
608608 } else try writer.print("{x}", .{try dg.fmtIntLiteral(Type.u8, Value.undef)});
609
609 if (ty.unionTagTypeSafety()) |_| try writer.writeByte('}');
610610 return writer.writeByte('}');
611611 },
612612 .ErrorUnion => {
......@@ -3469,22 +3469,22 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
34693469 extra_i += (constraint.len + name.len + (2 + 3)) / 4;
34703470
34713471 const output_ty = if (output == .none) inst_ty else f.air.typeOf(output).childType();
3472 try writer.writeAll("register ");
3473 try f.object.dg.renderTypeAndName(writer, output_ty, .{
3474 .local = output_locals_begin + index,
3475 }, .Mut, 0);
34763472 if (std.mem.startsWith(u8, constraint, "={") and std.mem.endsWith(u8, constraint, "}")) {
3473 try writer.writeAll("register ");
3474 try f.object.dg.renderTypeAndName(writer, output_ty, .{
3475 .local = output_locals_begin + index,
3476 }, .Mut, 0);
34773477 try writer.writeAll(" __asm(\"");
34783478 try writer.writeAll(constraint["={".len .. constraint.len - "}".len]);
34793479 try writer.writeAll("\")");
3480 if (f.wantSafety()) {
3481 try writer.writeAll(" = ");
3482 try f.object.dg.renderValue(writer, output_ty, Value.undef, .Other);
3483 }
3484 try writer.writeAll(";\n");
34803485 } else if (constraint.len < 2 or constraint[0] != '=') {
34813486 return f.fail("CBE: constraint not supported: '{s}'", .{constraint});
34823487 }
3483 if (f.wantSafety()) {
3484 try writer.writeAll(" = ");
3485 try f.object.dg.renderValue(writer, output_ty, Value.undef, .Other);
3486 }
3487 try writer.writeAll(";\n");
34883488 }
34893489 const input_locals_begin = f.next_local_index;
34903490 f.next_local_index += inputs.len;
......@@ -3497,20 +3497,29 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
34973497 extra_i += (constraint.len + name.len + (2 + 3)) / 4;
34983498
34993499 const input_ty = f.air.typeOf(input);
3500 try writer.writeAll("register ");
3501 try f.object.dg.renderTypeAndName(writer, input_ty, .{
3502 .local = input_locals_begin + index,
3503 }, .Const, 0);
35043500 if (std.mem.startsWith(u8, constraint, "{") and std.mem.endsWith(u8, constraint, "}")) {
3501 try writer.writeAll("register ");
3502 try f.object.dg.renderTypeAndName(writer, input_ty, .{
3503 .local = input_locals_begin + index,
3504 }, .Const, 0);
35053505 try writer.writeAll(" __asm(\"");
35063506 try writer.writeAll(constraint["{".len .. constraint.len - "}".len]);
3507 try writer.writeAll("\")");
3508 } else if (constraint.len < 1 or std.mem.indexOfScalar(u8, "=+&%", constraint[0]) != null) {
3507 try writer.writeAll("\") = ");
3508 try f.writeCValue(writer, try f.resolveInst(input));
3509 try writer.writeAll(";\n");
3510 } else if (constraint.len >= 1 and std.mem.indexOfScalar(u8, "=+&%", constraint[0]) == null) {
3511 const input_val = try f.resolveInst(input);
3512 if (input_val == .constant) {
3513 try f.object.dg.renderTypeAndName(writer, input_ty, .{
3514 .local = input_locals_begin + index,
3515 }, .Const, 0);
3516 try writer.writeAll(" = ");
3517 try f.writeCValue(writer, input_val);
3518 try writer.writeAll(";\n");
3519 }
3520 } else {
35093521 return f.fail("CBE: constraint not supported: '{s}'", .{constraint});
35103522 }
3511 try writer.writeAll(" = ");
3512 try f.writeCValue(writer, try f.resolveInst(input));
3513 try writer.writeAll(";\n");
35143523 }
35153524 {
35163525 var clobber_i: u32 = 0;
......@@ -3529,7 +3538,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
35293538
35303539 extra_i = constraints_extra_begin;
35313540 try writer.writeByte(':');
3532 for (outputs) |_, index| {
3541 for (outputs) |output, index| {
35333542 const extra_bytes = std.mem.sliceAsBytes(f.air.extra[extra_i..]);
35343543 const constraint = std.mem.sliceTo(extra_bytes, 0);
35353544 const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0);
......@@ -3538,12 +3547,18 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
35383547 extra_i += (constraint.len + name.len + (2 + 3)) / 4;
35393548
35403549 if (index > 0) try writer.writeByte(',');
3541 try writer.print(" {s}(", .{fmtStringLiteral(if (constraint[1] == '{') "=r" else constraint)});
3542 try f.writeCValue(writer, .{ .local = output_locals_begin + index });
3550 try writer.writeByte(' ');
3551 if (constraint[1] == '{') {
3552 try writer.print("{s}(", .{fmtStringLiteral("=r")});
3553 try f.writeCValue(writer, .{ .local = output_locals_begin + index });
3554 } else {
3555 try writer.print("{s}(", .{fmtStringLiteral(constraint)});
3556 try f.writeCValueDeref(writer, try f.resolveInst(output));
3557 }
35433558 try writer.writeByte(')');
35443559 }
35453560 try writer.writeByte(':');
3546 for (inputs) |_, index| {
3561 for (inputs) |input, index| {
35473562 const extra_bytes = std.mem.sliceAsBytes(f.air.extra[extra_i..]);
35483563 const constraint = std.mem.sliceTo(extra_bytes, 0);
35493564 const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0);
......@@ -3552,8 +3567,17 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
35523567 extra_i += (constraint.len + name.len + (2 + 3)) / 4;
35533568
35543569 if (index > 0) try writer.writeByte(',');
3555 try writer.print(" {s}(", .{fmtStringLiteral(if (constraint[0] == '{') "r" else constraint)});
3556 try f.writeCValue(writer, .{ .local = input_locals_begin + index });
3570 try writer.writeByte(' ');
3571 if (constraint[0] == '{') {
3572 try writer.print("{s}(", .{fmtStringLiteral("r")});
3573 try f.writeCValue(writer, .{ .local = input_locals_begin + index });
3574 } else {
3575 const input_val = try f.resolveInst(input);
3576 try writer.print("{s}(", .{fmtStringLiteral(constraint)});
3577 try f.writeCValue(writer, if (input_val == .constant) .{
3578 .local = input_locals_begin + index,
3579 } else input_val);
3580 }
35573581 try writer.writeByte(')');
35583582 }
35593583 try writer.writeByte(':');
......@@ -3582,12 +3606,14 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
35823606 // for the string, we still use the next u32 for the null terminator.
35833607 extra_i += (constraint.len + name.len + (2 + 3)) / 4;
35843608
3585 try f.writeCValueDeref(writer, if (output == .none) CValue{
3586 .local_ref = local.local,
3587 } else try f.resolveInst(output));
3588 try writer.writeAll(" = ");
3589 try f.writeCValue(writer, .{ .local = output_locals_begin + index });
3590 try writer.writeAll(";\n");
3609 if (constraint[1] == '{') {
3610 try f.writeCValueDeref(writer, if (output == .none) CValue{
3611 .local_ref = local.local,
3612 } else try f.resolveInst(output));
3613 try writer.writeAll(" = ");
3614 try f.writeCValue(writer, .{ .local = output_locals_begin + index });
3615 try writer.writeAll(";\n");
3616 }
35913617 }
35923618
35933619 f.object.indent_writer.popIndent();
......@@ -4415,12 +4441,12 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
44154441 const elem_ty = inst_ty.childType();
44164442 var empty = true;
44174443 for (elements) |element| {
4418 if (empty) try writer.writeAll(", ");
4444 if (!empty) try writer.writeAll(", ");
44194445 try f.writeCValue(writer, try f.resolveInst(element));
44204446 empty = false;
44214447 }
44224448 if (inst_ty.sentinel()) |sentinel| {
4423 if (empty) try writer.writeAll(", ");
4449 if (!empty) try writer.writeAll(", ");
44244450 try f.object.dg.renderValue(writer, elem_ty, sentinel, .Other);
44254451 empty = false;
44264452 }
test/behavior/asm.zig-1
......@@ -112,7 +112,6 @@ test "sized integer/float in asm input" {
112112}
113113
114114test "struct/array/union types as input values" {
115 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
116115 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
117116 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
118117 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
test/behavior/bugs/12972.zig-1
......@@ -5,7 +5,6 @@ pub fn f(_: [:null]const ?u8) void {}
55test {
66 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
77 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
8 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
98
109 const c: u8 = 42;
1110 f(&[_:null]?u8{c});
test/behavior/bugs/13128.zig-1
......@@ -12,7 +12,6 @@ fn foo(val: U) !void {
1212}
1313
1414test "runtime union init, most-aligned field != largest" {
15 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1615 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1716 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1817 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO