| ... | @@ -121,7 +121,13 @@ pub const Function = struct { | ... | @@ -121,7 +121,13 @@ pub const Function = struct { |
| 121 | const decl_c_value = f.allocLocalValue(); | 121 | const decl_c_value = f.allocLocalValue(); |
| 122 | gop.value_ptr.* = decl_c_value; | 122 | gop.value_ptr.* = decl_c_value; |
| 123 | try writer.writeAll("static "); | 123 | try writer.writeAll("static "); |
| 124 | try f.object.dg.renderTypeAndName(writer, ty, decl_c_value, .Const); | 124 | try f.object.dg.renderTypeAndName( |
| | 125 | writer, |
| | 126 | ty, |
| | 127 | decl_c_value, |
| | 128 | .Const, |
| | 129 | Value.initTag(.abi_align_default), |
| | 130 | ); |
| 125 | try writer.writeAll(" = "); | 131 | try writer.writeAll(" = "); |
| 126 | try f.object.dg.renderValue(writer, ty, val); | 132 | try f.object.dg.renderValue(writer, ty, val); |
| 127 | try writer.writeAll(";\n "); | 133 | try writer.writeAll(";\n "); |
| ... | @@ -142,8 +148,18 @@ pub const Function = struct { | ... | @@ -142,8 +148,18 @@ pub const Function = struct { |
| 142 | } | 148 | } |
| 143 | | 149 | |
| 144 | fn allocLocal(f: *Function, ty: Type, mutability: Mutability) !CValue { | 150 | fn allocLocal(f: *Function, ty: Type, mutability: Mutability) !CValue { |
| | 151 | return f.allocAlignedLocal(ty, mutability, Value.initTag(.abi_align_default)); |
| | 152 | } |
| | 153 | |
| | 154 | fn allocAlignedLocal(f: *Function, ty: Type, mutability: Mutability, alignment: Value) !CValue { |
| 145 | const local_value = f.allocLocalValue(); | 155 | const local_value = f.allocLocalValue(); |
| 146 | try f.object.dg.renderTypeAndName(f.object.writer(), ty, local_value, mutability); | 156 | try f.object.dg.renderTypeAndName( |
| | 157 | f.object.writer(), |
| | 158 | ty, |
| | 159 | local_value, |
| | 160 | mutability, |
| | 161 | alignment, |
| | 162 | ); |
| 147 | return local_value; | 163 | return local_value; |
| 148 | } | 164 | } |
| 149 | | 165 | |
| ... | @@ -711,9 +727,11 @@ pub const DeclGen = struct { | ... | @@ -711,9 +727,11 @@ pub const DeclGen = struct { |
| 711 | while (it.next()) |entry| { | 727 | while (it.next()) |entry| { |
| 712 | const field_ty = entry.value_ptr.ty; | 728 | const field_ty = entry.value_ptr.ty; |
| 713 | if (!field_ty.hasCodeGenBits()) continue; | 729 | if (!field_ty.hasCodeGenBits()) continue; |
| | 730 | |
| | 731 | const alignment = entry.value_ptr.abi_align; |
| 714 | const name: CValue = .{ .bytes = entry.key_ptr.* }; | 732 | const name: CValue = .{ .bytes = entry.key_ptr.* }; |
| 715 | try buffer.append(' '); | 733 | try buffer.append(' '); |
| 716 | try dg.renderTypeAndName(buffer.writer(), field_ty, name, .Mut); | 734 | try dg.renderTypeAndName(buffer.writer(), field_ty, name, .Mut, alignment); |
| 717 | try buffer.appendSlice(";\n"); | 735 | try buffer.appendSlice(";\n"); |
| 718 | } | 736 | } |
| 719 | } | 737 | } |
| ... | @@ -950,6 +968,7 @@ pub const DeclGen = struct { | ... | @@ -950,6 +968,7 @@ pub const DeclGen = struct { |
| 950 | ty: Type, | 968 | ty: Type, |
| 951 | name: CValue, | 969 | name: CValue, |
| 952 | mutability: Mutability, | 970 | mutability: Mutability, |
| | 971 | alignment: Value, |
| 953 | ) error{ OutOfMemory, AnalysisFail }!void { | 972 | ) error{ OutOfMemory, AnalysisFail }!void { |
| 954 | var suffix = std.ArrayList(u8).init(dg.gpa); | 973 | var suffix = std.ArrayList(u8).init(dg.gpa); |
| 955 | defer suffix.deinit(); | 974 | defer suffix.deinit(); |
| ... | @@ -962,6 +981,8 @@ pub const DeclGen = struct { | ... | @@ -962,6 +981,8 @@ pub const DeclGen = struct { |
| 962 | render_ty = render_ty.elemType(); | 981 | render_ty = render_ty.elemType(); |
| 963 | } | 982 | } |
| 964 | | 983 | |
| | 984 | if (alignment.tag() != .abi_align_default and alignment.tag() != .null_value) |
| | 985 | try w.print("ZIG_ALIGN({}) ", .{alignment.toUnsignedInt()}); |
| 965 | try dg.renderType(w, render_ty); | 986 | try dg.renderType(w, render_ty); |
| 966 | | 987 | |
| 967 | const const_prefix = switch (mutability) { | 988 | const const_prefix = switch (mutability) { |
| ... | @@ -1118,7 +1139,7 @@ pub fn genDecl(o: *Object) !void { | ... | @@ -1118,7 +1139,7 @@ pub fn genDecl(o: *Object) !void { |
| 1118 | // https://github.com/ziglang/zig/issues/7582 | 1139 | // https://github.com/ziglang/zig/issues/7582 |
| 1119 | | 1140 | |
| 1120 | const decl_c_value: CValue = .{ .decl = o.dg.decl }; | 1141 | const decl_c_value: CValue = .{ .decl = o.dg.decl }; |
| 1121 | try o.dg.renderTypeAndName(writer, tv.ty, decl_c_value, .Mut); | 1142 | try o.dg.renderTypeAndName(writer, tv.ty, decl_c_value, .Mut, o.dg.decl.align_val); |
| 1122 | | 1143 | |
| 1123 | try writer.writeAll(" = "); | 1144 | try writer.writeAll(" = "); |
| 1124 | try o.dg.renderValue(writer, tv.ty, tv.val); | 1145 | try o.dg.renderValue(writer, tv.ty, tv.val); |
| ... | @@ -1460,8 +1481,16 @@ fn airAlloc(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -1460,8 +1481,16 @@ fn airAlloc(f: *Function, inst: Air.Inst.Index) !CValue { |
| 1460 | return CValue{ .bytes = literal }; | 1481 | return CValue{ .bytes = literal }; |
| 1461 | } | 1482 | } |
| 1462 | | 1483 | |
| | 1484 | const target = f.object.dg.module.getTarget(); |
| | 1485 | const alignment = inst_ty.ptrAlignment(target); |
| | 1486 | var payload = Value.Payload.U64{ |
| | 1487 | .base = .{ .tag = .int_u64 }, |
| | 1488 | .data = alignment, |
| | 1489 | }; |
| | 1490 | const alignment_value = Value.initPayload(&payload.base); |
| | 1491 | |
| 1463 | // First line: the variable used as data storage. | 1492 | // First line: the variable used as data storage. |
| 1464 | const local = try f.allocLocal(elem_type, mutability); | 1493 | const local = try f.allocAlignedLocal(elem_type, mutability, alignment_value); |
| 1465 | try writer.writeAll(";\n"); | 1494 | try writer.writeAll(";\n"); |
| 1466 | | 1495 | |
| 1467 | // Arrays are already pointers so they don't need to be referenced. | 1496 | // Arrays are already pointers so they don't need to be referenced. |