| ... | @@ -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 | } |
| 89 | | 89 | |
| 90 | const reserved_idents = std.ComptimeStringMap(void, .{ | 90 | const 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 | }); |
| 201 | | 187 | |
| | 188 | fn 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 | |
| 202 | fn formatIdent( | 197 | fn 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("){"); |
| 603 | | 598 | |
| | 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)}); |
| 609 | | 609 | 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; |
| 3470 | | 3470 | |
| 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; |
| 3498 | | 3498 | |
| 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 { |
| 3529 | | 3538 | |
| 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; |
| 3539 | | 3548 | |
| 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; |
| 3553 | | 3568 | |
| 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; |
| 3584 | | 3608 | |
| 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 | } |
| 3592 | | 3618 | |
| 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 | } |