| ... | ... | @@ -88,23 +88,9 @@ pub fn typeToCIdentifier(ty: Type, mod: *Module) std.fmt.Formatter(formatTypeAsC |
| 88 | 88 | } |
| 89 | 89 | |
| 90 | 90 | const reserved_idents = std.ComptimeStringMap(void, .{ |
| 91 | | .{ "_Alignas", { |
| 91 | .{ "alignas", { |
| 92 | 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 | 94 | .{ "alignof", {} }, |
| 109 | 95 | .{ "asm", {} }, |
| 110 | 96 | .{ "atomic_bool", {} }, |
| ... | ... | @@ -199,6 +185,15 @@ const reserved_idents = std.ComptimeStringMap(void, .{ |
| 199 | 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 | 197 | fn formatIdent( |
| 203 | 198 | ident: []const u8, |
| 204 | 199 | comptime fmt: []const u8, |
| ... | ... | @@ -207,7 +202,7 @@ fn formatIdent( |
| 207 | 202 | ) !void { |
| 208 | 203 | _ = options; |
| 209 | 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 | 206 | try writer.writeAll("zig_e_"); |
| 212 | 207 | } |
| 213 | 208 | for (ident) |c, i| { |
| ... | ... | @@ -601,12 +596,17 @@ pub const DeclGen = struct { |
| 601 | 596 | try dg.renderTypecast(writer, ty); |
| 602 | 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 | 604 | for (ty.unionFields().values()) |field| { |
| 605 | 605 | if (!field.ty.hasRuntimeBits()) continue; |
| 606 | 606 | try dg.renderValue(writer, field.ty, val, location); |
| 607 | 607 | break; |
| 608 | 608 | } else try writer.print("{x}", .{try dg.fmtIntLiteral(Type.u8, Value.undef)}); |
| 609 | | |
| 609 | if (ty.unionTagTypeSafety()) |_| try writer.writeByte('}'); |
| 610 | 610 | return writer.writeByte('}'); |
| 611 | 611 | }, |
| 612 | 612 | .ErrorUnion => { |
| ... | ... | @@ -3469,22 +3469,22 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3469 | 3469 | extra_i += (constraint.len + name.len + (2 + 3)) / 4; |
| 3470 | 3470 | |
| 3471 | 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 | 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 | 3477 | try writer.writeAll(" __asm(\""); |
| 3478 | 3478 | try writer.writeAll(constraint["={".len .. constraint.len - "}".len]); |
| 3479 | 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 | 3485 | } else if (constraint.len < 2 or constraint[0] != '=') { |
| 3481 | 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 | 3489 | const input_locals_begin = f.next_local_index; |
| 3490 | 3490 | f.next_local_index += inputs.len; |
| ... | ... | @@ -3497,20 +3497,29 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3497 | 3497 | extra_i += (constraint.len + name.len + (2 + 3)) / 4; |
| 3498 | 3498 | |
| 3499 | 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 | 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 | 3505 | try writer.writeAll(" __asm(\""); |
| 3506 | 3506 | 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 { |
| 3509 | 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 | 3525 | var clobber_i: u32 = 0; |
| ... | ... | @@ -3529,7 +3538,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3529 | 3538 | |
| 3530 | 3539 | extra_i = constraints_extra_begin; |
| 3531 | 3540 | try writer.writeByte(':'); |
| 3532 | | for (outputs) |_, index| { |
| 3541 | for (outputs) |output, index| { |
| 3533 | 3542 | const extra_bytes = std.mem.sliceAsBytes(f.air.extra[extra_i..]); |
| 3534 | 3543 | const constraint = std.mem.sliceTo(extra_bytes, 0); |
| 3535 | 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 | 3547 | extra_i += (constraint.len + name.len + (2 + 3)) / 4; |
| 3539 | 3548 | |
| 3540 | 3549 | 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 | } |
| 3543 | 3558 | try writer.writeByte(')'); |
| 3544 | 3559 | } |
| 3545 | 3560 | try writer.writeByte(':'); |
| 3546 | | for (inputs) |_, index| { |
| 3561 | for (inputs) |input, index| { |
| 3547 | 3562 | const extra_bytes = std.mem.sliceAsBytes(f.air.extra[extra_i..]); |
| 3548 | 3563 | const constraint = std.mem.sliceTo(extra_bytes, 0); |
| 3549 | 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 | 3567 | extra_i += (constraint.len + name.len + (2 + 3)) / 4; |
| 3553 | 3568 | |
| 3554 | 3569 | 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 | } |
| 3557 | 3581 | try writer.writeByte(')'); |
| 3558 | 3582 | } |
| 3559 | 3583 | try writer.writeByte(':'); |
| ... | ... | @@ -3582,12 +3606,14 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3582 | 3606 | // for the string, we still use the next u32 for the null terminator. |
| 3583 | 3607 | extra_i += (constraint.len + name.len + (2 + 3)) / 4; |
| 3584 | 3608 | |
| 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 | } |
| 3591 | 3617 | } |
| 3592 | 3618 | |
| 3593 | 3619 | f.object.indent_writer.popIndent(); |
| ... | ... | @@ -4415,12 +4441,12 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4415 | 4441 | const elem_ty = inst_ty.childType(); |
| 4416 | 4442 | var empty = true; |
| 4417 | 4443 | for (elements) |element| { |
| 4418 | | if (empty) try writer.writeAll(", "); |
| 4444 | if (!empty) try writer.writeAll(", "); |
| 4419 | 4445 | try f.writeCValue(writer, try f.resolveInst(element)); |
| 4420 | 4446 | empty = false; |
| 4421 | 4447 | } |
| 4422 | 4448 | if (inst_ty.sentinel()) |sentinel| { |
| 4423 | | if (empty) try writer.writeAll(", "); |
| 4449 | if (!empty) try writer.writeAll(", "); |
| 4424 | 4450 | try f.object.dg.renderValue(writer, elem_ty, sentinel, .Other); |
| 4425 | 4451 | empty = false; |
| 4426 | 4452 | } |