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...@@ -88,23 +88,9 @@ pub fn typeToCIdentifier(ty: Type, mod: *Module) std.fmt.Formatter(formatTypeAsC
88}88}
8989
90const reserved_idents = std.ComptimeStringMap(void, .{90const reserved_idents = std.ComptimeStringMap(void, .{
91 .{ "_Alignas", {91 .{ "alignas", {
92 @setEvalBranchQuota(4000);92 @setEvalBranchQuota(4000);
93 } },93 } },
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", {} },
108 .{ "alignof", {} },94 .{ "alignof", {} },
109 .{ "asm", {} },95 .{ "asm", {} },
110 .{ "atomic_bool", {} },96 .{ "atomic_bool", {} },
...@@ -199,6 +185,15 @@ const reserved_idents = std.ComptimeStringMap(void, .{...@@ -199,6 +185,15 @@ const reserved_idents = std.ComptimeStringMap(void, .{
199 .{ "while ", {} },185 .{ "while ", {} },
200});186});
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
202fn formatIdent(197fn formatIdent(
203 ident: []const u8,198 ident: []const u8,
204 comptime fmt: []const u8,199 comptime fmt: []const u8,
...@@ -207,7 +202,7 @@ fn formatIdent(...@@ -207,7 +202,7 @@ fn formatIdent(
207) !void {202) !void {
208 _ = options;203 _ = options;
209 const solo = fmt.len != 0 and fmt[0] == ' '; // space means solo; not part of a bigger ident.204 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)) {
211 try writer.writeAll("zig_e_");206 try writer.writeAll("zig_e_");
212 }207 }
213 for (ident) |c, i| {208 for (ident) |c, i| {
...@@ -601,12 +596,17 @@ pub const DeclGen = struct {...@@ -601,12 +596,17 @@ pub const DeclGen = struct {
601 try dg.renderTypecast(writer, ty);596 try dg.renderTypecast(writer, ty);
602 try writer.writeAll("){");597 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 }
604 for (ty.unionFields().values()) |field| {604 for (ty.unionFields().values()) |field| {
605 if (!field.ty.hasRuntimeBits()) continue;605 if (!field.ty.hasRuntimeBits()) continue;
606 try dg.renderValue(writer, field.ty, val, location);606 try dg.renderValue(writer, field.ty, val, location);
607 break;607 break;
608 } else try writer.print("{x}", .{try dg.fmtIntLiteral(Type.u8, Value.undef)});608 } else try writer.print("{x}", .{try dg.fmtIntLiteral(Type.u8, Value.undef)});
609609 if (ty.unionTagTypeSafety()) |_| try writer.writeByte('}');
610 return writer.writeByte('}');610 return writer.writeByte('}');
611 },611 },
612 .ErrorUnion => {612 .ErrorUnion => {
...@@ -3469,22 +3469,22 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3469,22 +3469,22 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
3469 extra_i += (constraint.len + name.len + (2 + 3)) / 4;3469 extra_i += (constraint.len + name.len + (2 + 3)) / 4;
34703470
3471 const output_ty = if (output == .none) inst_ty else f.air.typeOf(output).childType();3471 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);
3476 if (std.mem.startsWith(u8, constraint, "={") and std.mem.endsWith(u8, constraint, "}")) {3472 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);
3477 try writer.writeAll(" __asm(\"");3477 try writer.writeAll(" __asm(\"");
3478 try writer.writeAll(constraint["={".len .. constraint.len - "}".len]);3478 try writer.writeAll(constraint["={".len .. constraint.len - "}".len]);
3479 try writer.writeAll("\")");3479 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");
3480 } else if (constraint.len < 2 or constraint[0] != '=') {3485 } else if (constraint.len < 2 or constraint[0] != '=') {
3481 return f.fail("CBE: constraint not supported: '{s}'", .{constraint});3486 return f.fail("CBE: constraint not supported: '{s}'", .{constraint});
3482 }3487 }
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");
3488 }3488 }
3489 const input_locals_begin = f.next_local_index;3489 const input_locals_begin = f.next_local_index;
3490 f.next_local_index += inputs.len;3490 f.next_local_index += inputs.len;
...@@ -3497,20 +3497,29 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3497,20 +3497,29 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
3497 extra_i += (constraint.len + name.len + (2 + 3)) / 4;3497 extra_i += (constraint.len + name.len + (2 + 3)) / 4;
34983498
3499 const input_ty = f.air.typeOf(input);3499 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);
3504 if (std.mem.startsWith(u8, constraint, "{") and std.mem.endsWith(u8, constraint, "}")) {3500 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);
3505 try writer.writeAll(" __asm(\"");3505 try writer.writeAll(" __asm(\"");
3506 try writer.writeAll(constraint["{".len .. constraint.len - "}".len]);3506 try writer.writeAll(constraint["{".len .. constraint.len - "}".len]);
3507 try writer.writeAll("\")");3507 try writer.writeAll("\") = ");
3508 } else if (constraint.len < 1 or std.mem.indexOfScalar(u8, "=+&%", constraint[0]) != null) {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 {
3509 return f.fail("CBE: constraint not supported: '{s}'", .{constraint});3521 return f.fail("CBE: constraint not supported: '{s}'", .{constraint});
3510 }3522 }
3511 try writer.writeAll(" = ");
3512 try f.writeCValue(writer, try f.resolveInst(input));
3513 try writer.writeAll(";\n");
3514 }3523 }
3515 {3524 {
3516 var clobber_i: u32 = 0;3525 var clobber_i: u32 = 0;
...@@ -3529,7 +3538,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3529,7 +3538,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
35293538
3530 extra_i = constraints_extra_begin;3539 extra_i = constraints_extra_begin;
3531 try writer.writeByte(':');3540 try writer.writeByte(':');
3532 for (outputs) |_, index| {3541 for (outputs) |output, index| {
3533 const extra_bytes = std.mem.sliceAsBytes(f.air.extra[extra_i..]);3542 const extra_bytes = std.mem.sliceAsBytes(f.air.extra[extra_i..]);
3534 const constraint = std.mem.sliceTo(extra_bytes, 0);3543 const constraint = std.mem.sliceTo(extra_bytes, 0);
3535 const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0);3544 const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0);
...@@ -3538,12 +3547,18 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3538,12 +3547,18 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
3538 extra_i += (constraint.len + name.len + (2 + 3)) / 4;3547 extra_i += (constraint.len + name.len + (2 + 3)) / 4;
35393548
3540 if (index > 0) try writer.writeByte(',');3549 if (index > 0) try writer.writeByte(',');
3541 try writer.print(" {s}(", .{fmtStringLiteral(if (constraint[1] == '{') "=r" else constraint)});3550 try writer.writeByte(' ');
3542 try f.writeCValue(writer, .{ .local = output_locals_begin + index });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 }
3543 try writer.writeByte(')');3558 try writer.writeByte(')');
3544 }3559 }
3545 try writer.writeByte(':');3560 try writer.writeByte(':');
3546 for (inputs) |_, index| {3561 for (inputs) |input, index| {
3547 const extra_bytes = std.mem.sliceAsBytes(f.air.extra[extra_i..]);3562 const extra_bytes = std.mem.sliceAsBytes(f.air.extra[extra_i..]);
3548 const constraint = std.mem.sliceTo(extra_bytes, 0);3563 const constraint = std.mem.sliceTo(extra_bytes, 0);
3549 const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0);3564 const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0);
...@@ -3552,8 +3567,17 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3552,8 +3567,17 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
3552 extra_i += (constraint.len + name.len + (2 + 3)) / 4;3567 extra_i += (constraint.len + name.len + (2 + 3)) / 4;
35533568
3554 if (index > 0) try writer.writeByte(',');3569 if (index > 0) try writer.writeByte(',');
3555 try writer.print(" {s}(", .{fmtStringLiteral(if (constraint[0] == '{') "r" else constraint)});3570 try writer.writeByte(' ');
3556 try f.writeCValue(writer, .{ .local = input_locals_begin + index });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 }
3557 try writer.writeByte(')');3581 try writer.writeByte(')');
3558 }3582 }
3559 try writer.writeByte(':');3583 try writer.writeByte(':');
...@@ -3582,12 +3606,14 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3582,12 +3606,14 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
3582 // for the string, we still use the next u32 for the null terminator.3606 // for the string, we still use the next u32 for the null terminator.
3583 extra_i += (constraint.len + name.len + (2 + 3)) / 4;3607 extra_i += (constraint.len + name.len + (2 + 3)) / 4;
35843608
3585 try f.writeCValueDeref(writer, if (output == .none) CValue{3609 if (constraint[1] == '{') {
3586 .local_ref = local.local,3610 try f.writeCValueDeref(writer, if (output == .none) CValue{
3587 } else try f.resolveInst(output));3611 .local_ref = local.local,
3588 try writer.writeAll(" = ");3612 } else try f.resolveInst(output));
3589 try f.writeCValue(writer, .{ .local = output_locals_begin + index });3613 try writer.writeAll(" = ");
3590 try writer.writeAll(";\n");3614 try f.writeCValue(writer, .{ .local = output_locals_begin + index });
3615 try writer.writeAll(";\n");
3616 }
3591 }3617 }
35923618
3593 f.object.indent_writer.popIndent();3619 f.object.indent_writer.popIndent();
...@@ -4415,12 +4441,12 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4415,12 +4441,12 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
4415 const elem_ty = inst_ty.childType();4441 const elem_ty = inst_ty.childType();
4416 var empty = true;4442 var empty = true;
4417 for (elements) |element| {4443 for (elements) |element| {
4418 if (empty) try writer.writeAll(", ");4444 if (!empty) try writer.writeAll(", ");
4419 try f.writeCValue(writer, try f.resolveInst(element));4445 try f.writeCValue(writer, try f.resolveInst(element));
4420 empty = false;4446 empty = false;
4421 }4447 }
4422 if (inst_ty.sentinel()) |sentinel| {4448 if (inst_ty.sentinel()) |sentinel| {
4423 if (empty) try writer.writeAll(", ");4449 if (!empty) try writer.writeAll(", ");
4424 try f.object.dg.renderValue(writer, elem_ty, sentinel, .Other);4450 try f.object.dg.renderValue(writer, elem_ty, sentinel, .Other);
4425 empty = false;4451 empty = false;
4426 }4452 }
test/behavior/asm.zig-1
...@@ -112,7 +112,6 @@ test "sized integer/float in asm input" {...@@ -112,7 +112,6 @@ test "sized integer/float in asm input" {
112}112}
113113
114test "struct/array/union types as input values" {114test "struct/array/union types as input values" {
115 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
116 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO115 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
117 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO116 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
118 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO117 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 {}...@@ -5,7 +5,6 @@ pub fn f(_: [:null]const ?u8) void {}
5test {5test {
6 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO6 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
7 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO7 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
8 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
98
10 const c: u8 = 42;9 const c: u8 = 42;
11 f(&[_:null]?u8{c});10 f(&[_:null]?u8{c});
test/behavior/bugs/13128.zig-1
...@@ -12,7 +12,6 @@ fn foo(val: U) !void {...@@ -12,7 +12,6 @@ fn foo(val: U) !void {
12}12}
1313
14test "runtime union init, most-aligned field != largest" {14test "runtime union init, most-aligned field != largest" {
15 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
16 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO15 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
17 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO16 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
18 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO17 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO