diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/codegen/c.zig | 39 | ||||
| -rw-r--r-- | src/link/C/zig.h | 9 |
2 files changed, 43 insertions, 5 deletions
diff --git a/src/codegen/c.zig b/src/codegen/c.zig index 42778bccf8..de1636cd96 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -121,7 +121,13 @@ pub const Function = struct { const decl_c_value = f.allocLocalValue(); gop.value_ptr.* = decl_c_value; try writer.writeAll("static "); - try f.object.dg.renderTypeAndName(writer, ty, decl_c_value, .Const); + try f.object.dg.renderTypeAndName( + writer, + ty, + decl_c_value, + .Const, + Value.initTag(.abi_align_default), + ); try writer.writeAll(" = "); try f.object.dg.renderValue(writer, ty, val); try writer.writeAll(";\n "); @@ -142,8 +148,18 @@ pub const Function = struct { } fn allocLocal(f: *Function, ty: Type, mutability: Mutability) !CValue { + return f.allocAlignedLocal(ty, mutability, Value.initTag(.abi_align_default)); + } + + fn allocAlignedLocal(f: *Function, ty: Type, mutability: Mutability, alignment: Value) !CValue { const local_value = f.allocLocalValue(); - try f.object.dg.renderTypeAndName(f.object.writer(), ty, local_value, mutability); + try f.object.dg.renderTypeAndName( + f.object.writer(), + ty, + local_value, + mutability, + alignment, + ); return local_value; } @@ -711,9 +727,11 @@ pub const DeclGen = struct { while (it.next()) |entry| { const field_ty = entry.value_ptr.ty; if (!field_ty.hasCodeGenBits()) continue; + + const alignment = entry.value_ptr.abi_align; const name: CValue = .{ .bytes = entry.key_ptr.* }; try buffer.append(' '); - try dg.renderTypeAndName(buffer.writer(), field_ty, name, .Mut); + try dg.renderTypeAndName(buffer.writer(), field_ty, name, .Mut, alignment); try buffer.appendSlice(";\n"); } } @@ -950,6 +968,7 @@ pub const DeclGen = struct { ty: Type, name: CValue, mutability: Mutability, + alignment: Value, ) error{ OutOfMemory, AnalysisFail }!void { var suffix = std.ArrayList(u8).init(dg.gpa); defer suffix.deinit(); @@ -962,6 +981,8 @@ pub const DeclGen = struct { render_ty = render_ty.elemType(); } + if (alignment.tag() != .abi_align_default and alignment.tag() != .null_value) + try w.print("ZIG_ALIGN({}) ", .{alignment.toUnsignedInt()}); try dg.renderType(w, render_ty); const const_prefix = switch (mutability) { @@ -1118,7 +1139,7 @@ pub fn genDecl(o: *Object) !void { // https://github.com/ziglang/zig/issues/7582 const decl_c_value: CValue = .{ .decl = o.dg.decl }; - try o.dg.renderTypeAndName(writer, tv.ty, decl_c_value, .Mut); + try o.dg.renderTypeAndName(writer, tv.ty, decl_c_value, .Mut, o.dg.decl.align_val); try writer.writeAll(" = "); try o.dg.renderValue(writer, tv.ty, tv.val); @@ -1460,8 +1481,16 @@ fn airAlloc(f: *Function, inst: Air.Inst.Index) !CValue { return CValue{ .bytes = literal }; } + const target = f.object.dg.module.getTarget(); + const alignment = inst_ty.ptrAlignment(target); + var payload = Value.Payload.U64{ + .base = .{ .tag = .int_u64 }, + .data = alignment, + }; + const alignment_value = Value.initPayload(&payload.base); + // First line: the variable used as data storage. - const local = try f.allocLocal(elem_type, mutability); + const local = try f.allocAlignedLocal(elem_type, mutability, alignment_value); try writer.writeAll(";\n"); // Arrays are already pointers so they don't need to be referenced. diff --git a/src/link/C/zig.h b/src/link/C/zig.h index eeda93894b..4a725ca678 100644 --- a/src/link/C/zig.h +++ b/src/link/C/zig.h @@ -26,6 +26,15 @@ #define ZIG_RESTRICT #endif +#if __STDC_VERSION__ >= 201112L +#include <stdalign.h> +#define ZIG_ALIGN(alignment) alignas(alignment) +#elif defined(__GNUC__) +#define ZIG_ALIGN(alignment) __attribute__((aligned(alignment))) +#else +#define ZIG_ALIGN(alignment) zig_compile_error("the C compiler being used does not support aligning variables") +#endif + #if __STDC_VERSION__ >= 199901L #include <stdbool.h> #else |
