From: Robert Pengelly Date: Mon, 7 Sep 2026 20:18:24 +0000 (+0100) Subject: Added aligned attribute support X-Git-Url: https://git.candlhat.org/?a=commitdiff_plain;h=448b949fadd3513f9bdb795111ed4734a41a6d06;p=scc.git Added aligned attribute support --- diff --git a/amd64.c b/amd64.c index 332ff49..2384ba8 100644 --- a/amd64.c +++ b/amd64.c @@ -8646,11 +8646,11 @@ static void make_local_static_label (char *buf, size_t bufsz, const char *name) } -static void emit_global_object (const char *name, int size, int is_array, long array_count, const int *field_sizes, int field_count, const int64_s *values, char **symbols, int value_count, int is_aggregate, int is_static); +static void emit_global_object (const char *name, int size, int is_array, long array_count, const int *field_sizes, int field_count, const int64_s *values, char **symbols, int value_count, int is_aggregate, int is_static, int explicit_align); static void emit_extern_symbol (const char *name, int size, int is_function); static void emit_extern_reference_symbol (const char *name, int size); -static void emit_block_static_object (const char *label, int size, int is_array, long array_count, const int *field_sizes, int field_count, const int64_s *values, char **symbols, int value_count, int is_aggregate) { +static void emit_block_static_object (const char *label, int size, int is_array, long array_count, const int *field_sizes, int field_count, const int64_s *values, char **symbols, int value_count, int is_aggregate, int explicit_align) { int skip_label = anon_label++; int need_code_skip = current_parse_block_depth > 0; @@ -8679,7 +8679,7 @@ static void emit_block_static_object (const char *label, int size, int is_array, } - emit_global_object (label, size, is_array, array_count, field_sizes, field_count, values, symbols, value_count, is_aggregate, 1); + emit_global_object (label, size, is_array, array_count, field_sizes, field_count, values, symbols, value_count, is_aggregate, 1, explicit_align); /* * We may have switched to .data/.data? to emit the static object while @@ -8854,6 +8854,7 @@ static void parse_block (void) { int declaration_dllimport = parsed_dllimport; int declaration_noreturn = parsed_noreturn; + int declaration_alignment = parsed_alignment; int declared_pointer_depth; int declared_pointed_size; @@ -8869,6 +8870,10 @@ static void parse_block (void) { declaration_dllimport = declaration_dllimport || parsed_dllimport || declarator_dllimport; declaration_noreturn = declaration_noreturn || parsed_noreturn || declarator_noreturn; + if (declarator_alignment > declaration_alignment) { + declaration_alignment = declarator_alignment; + } + apply_typedef_array_to_declarator (); if (declarator_has_array && declarator_array_unsized && tok.kind == TOK_ASSIGN) { @@ -8963,6 +8968,10 @@ static void parse_block (void) { object_size = declarator_object_size (parsed_type_size); object_align = declarator_is_pointer ? type_alignment (DATA_PTR) : type_alignment (parsed_type_is_aggregate ? DATA_PTR : parsed_type_size); + if (declaration_alignment > object_align) { + object_align = declaration_alignment; + } + object_offset = add_local_symbol (name, object_size, object_align, (declarator_is_pointer ? 0 : parsed_type_is_unsigned), block_scope_start, name_line, name_start, name_caret); @@ -9378,7 +9387,7 @@ static void parse_block (void) { declarator_has_array, declarator_array_count, object_fields, object_field_count, init_values, init_symbols, init_value_count, - (!declarator_is_pointer && parsed_type_is_aggregate)); + (!declarator_is_pointer && parsed_type_is_aggregate), declaration_alignment); } @@ -40158,7 +40167,7 @@ static void emit_global_data_label (const char *name, int is_static) { } -static void emit_global_object (const char *name, int size, int is_array, long array_count, const int *field_sizes, int field_count, const int64_s *values, char **symbols, int value_count, int is_aggregate, int is_static) { +static void emit_global_object (const char *name, int size, int is_array, long array_count, const int *field_sizes, int field_count, const int64_s *values, char **symbols, int value_count, int is_aggregate, int is_static, int explicit_align) { int64_s zero; @@ -40187,7 +40196,7 @@ static void emit_global_object (const char *name, int size, int is_array, long a switch_section (SECTION_BSS); - emit_global_alignment (global_object_alignment (size, is_array, field_sizes, field_count, is_aggregate)); + emit_global_alignment (explicit_align > global_object_alignment (size, is_array, field_sizes, field_count, is_aggregate) ? explicit_align : global_object_alignment (size, is_array, field_sizes, field_count, is_aggregate)); emit_global_data_label (name, is_static); emit_global_space (total); @@ -40197,7 +40206,7 @@ static void emit_global_object (const char *name, int size, int is_array, long a switch_section (SECTION_DATA); - emit_global_alignment (global_object_alignment (size, is_array, field_sizes, field_count, is_aggregate)); + emit_global_alignment (explicit_align > global_object_alignment (size, is_array, field_sizes, field_count, is_aggregate) ? explicit_align : global_object_alignment (size, is_array, field_sizes, field_count, is_aggregate)); emit_global_data_label (name, is_static); value_index = 0; @@ -40523,6 +40532,8 @@ static void parse_external_after_type (void) { int declaration_dllimport = 0; int declaration_dllexport = 0; + int declaration_alignment = parsed_alignment; + int decl_is_pointer; int decl_pointer_depth; int decl_has_array; @@ -40547,6 +40558,11 @@ static void parse_external_after_type (void) { declaration_is_inline = parsed_type_is_inline; declaration_storage = parsed_storage_class; declaration_noreturn = parsed_noreturn; + + if (declarator_alignment > declaration_alignment) { + declaration_alignment = declarator_alignment; + } + declaration_dllimport = parsed_dllimport; declaration_dllexport = parsed_dllexport; @@ -40840,7 +40856,7 @@ static void parse_external_after_type (void) { emit_global_object (name, declarator_is_pointer ? DATA_PTR : (declarator_has_array ? parsed_type_size : (parsed_type_is_aggregate ? parsed_type_size : (parsed_type_size & 0x1f))), declarator_has_array, declarator_array_count, object_fields, object_field_count, init_values, init_symbols, init_value_count, (!declarator_is_pointer && parsed_type_is_aggregate), - declaration_storage == STORAGE_STATIC); + declaration_storage == STORAGE_STATIC, declaration_alignment); } diff --git a/i386.c b/i386.c index dda6887..91a2e8b 100644 --- a/i386.c +++ b/i386.c @@ -7853,13 +7853,13 @@ static void make_local_static_label (char *buf, size_t bufsz, const char *name) } -static void emit_global_object (const char *name, int size, int is_array, long array_count, const int *field_sizes, int field_count, const int64_s *values, char **symbols, int value_count, int is_aggregate, int is_static); +static void emit_global_object (const char *name, int size, int is_array, long array_count, const int *field_sizes, int field_count, const int64_s *values, char **symbols, int value_count, int is_aggregate, int is_static, int explicit_align); static void emit_extern_symbol (const char *name, int size, int is_function); static void emit_extern_reference_symbol (const char *name, int size); -static void emit_block_static_object (const char *label, int size, int is_array, long array_count, const int *field_sizes, int field_count, const int64_s *values, char **symbols, int value_count, int is_aggregate) { +static void emit_block_static_object (const char *label, int size, int is_array, long array_count, const int *field_sizes, int field_count, const int64_s *values, char **symbols, int value_count, int is_aggregate, int explicit_align) { - emit_global_object (label, size, is_array, array_count, field_sizes, field_count, values, symbols, value_count, is_aggregate, 1); + emit_global_object (label, size, is_array, array_count, field_sizes, field_count, values, symbols, value_count, is_aggregate, 1, explicit_align); /** * We may have switched to .data/.data? to emit the static object while @@ -8024,6 +8024,7 @@ static void parse_block (void) { int declaration_dllimport = parsed_dllimport; int declaration_noreturn = parsed_noreturn; + int declaration_alignment = parsed_alignment; for (i = 0; i < MAX_AGG_FIELDS; i++) { init_symbols[i] = 0; @@ -8034,6 +8035,10 @@ static void parse_block (void) { declaration_dllimport = declaration_dllimport || parsed_dllimport || declarator_dllimport; declaration_noreturn = declaration_noreturn || parsed_noreturn || declarator_noreturn; + if (declarator_alignment > declaration_alignment) { + declaration_alignment = declarator_alignment; + } + apply_typedef_array_to_declarator (); if (declarator_has_array && declarator_array_unsized && tok.kind == TOK_ASSIGN) { @@ -8113,6 +8118,10 @@ static void parse_block (void) { object_size = declarator_object_size (parsed_type_size); object_align = declarator_is_pointer ? type_alignment (DATA_PTR) : type_alignment (parsed_type_is_aggregate ? DATA_PTR : parsed_type_size); + if (declaration_alignment > object_align) { + object_align = declaration_alignment; + } + object_offset = add_local_symbol (name, object_size, object_align, (declarator_is_pointer ? 0 : parsed_type_is_unsigned), block_scope_start, name_line, name_start, name_caret); @@ -8531,13 +8540,13 @@ static void parse_block (void) { declarator_has_array, declarator_array_count, object_fields, object_field_count, init_values, init_symbols, init_value_count, - (!declarator_is_pointer && parsed_type_is_aggregate)); + (!declarator_is_pointer && parsed_type_is_aggregate), declaration_alignment); } add_static_local_symbol (name, static_label, declarator_object_size (parsed_type_size), - type_alignment (declarator_is_pointer ? DATA_PTR : parsed_type_size), + (declaration_alignment > type_alignment (declarator_is_pointer ? DATA_PTR : parsed_type_size) ? declaration_alignment : type_alignment (declarator_is_pointer ? DATA_PTR : parsed_type_size)), (declarator_is_pointer ? 0 : parsed_type_is_unsigned), block_scope_start, name_line, name_start, name_caret); @@ -37690,6 +37699,25 @@ static void emit_global_label (const char *name, int is_static) { } +static void emit_global_alignment (int align) { + + if (align <= 1) { + return; + } + + if (state->syntax & ASM_SYNTAX_MASM) { + + masm_flush_data_line (); + fprintf (state->ofp, "align %d\n", align); + + } else if (state->syntax & ASM_SYNTAX_NASM) { + fprintf (state->ofp, "align %d\n", align); + } else { + fprintf (state->ofp, " .balign %d\n", align); + } + +} + static void emit_global_data_label (const char *name, int is_static) { const char *asm_name = asm_global_symbol_name (name); @@ -37710,7 +37738,7 @@ static void emit_global_data_label (const char *name, int is_static) { } -static void emit_global_object (const char *name, int size, int is_array, long array_count, const int *field_sizes, int field_count, const int64_s *values, char **symbols, int value_count, int is_aggregate, int is_static) { +static void emit_global_object (const char *name, int size, int is_array, long array_count, const int *field_sizes, int field_count, const int64_s *values, char **symbols, int value_count, int is_aggregate, int is_static, int explicit_align) { int64_s zero; @@ -37739,6 +37767,7 @@ static void emit_global_object (const char *name, int size, int is_array, long a switch_section (SECTION_BSS); + emit_global_alignment (explicit_align); emit_global_data_label (name, is_static); emit_global_space (total); @@ -37747,6 +37776,8 @@ static void emit_global_object (const char *name, int size, int is_array, long a } switch_section (SECTION_DATA); + + emit_global_alignment (explicit_align); emit_global_data_label (name, is_static); value_index = 0; @@ -38023,6 +38054,8 @@ static void parse_external_after_type (void) { int declaration_dllimport = 0; int declaration_dllexport = 0; + int declaration_alignment = parsed_alignment; + int decl_is_pointer; int decl_pointer_depth; int decl_has_array; @@ -38050,6 +38083,10 @@ static void parse_external_after_type (void) { declaration_dllexport = parsed_dllexport; declaration_noreturn = parsed_noreturn; + if (declarator_alignment > declaration_alignment) { + declaration_alignment = declarator_alignment; + } + parse_declarator (&name); declaration_dllimport = declaration_dllimport || parsed_dllimport || declarator_dllimport; @@ -38340,7 +38377,7 @@ static void parse_external_after_type (void) { emit_global_object (name, declarator_is_pointer ? DATA_PTR : (declarator_has_array ? parsed_type_size : (parsed_type_is_aggregate ? parsed_type_size : (parsed_type_size & 0x1f))), declarator_has_array, declarator_array_count, object_fields, object_field_count, init_values, init_symbols, init_value_count, (!declarator_is_pointer && parsed_type_is_aggregate), - declaration_storage == STORAGE_STATIC); + declaration_storage == STORAGE_STATIC, declaration_alignment); } diff --git a/parse.c b/parse.c index 1706e24..f61509b 100644 --- a/parse.c +++ b/parse.c @@ -29,6 +29,7 @@ int parsed_dllexport = 0; int parsed_dllimport = 0; int parsed_noreturn = 0; int parsed_naked = 0; +int parsed_alignment = 0; int parsed_type_size = DATA_NONE; int parsed_type_is_inline = 0; @@ -67,6 +68,7 @@ int declarator_is_pointer = 0; int declarator_has_array = 0; int declarator_noreturn = 0; int declarator_naked = 0; +int declarator_alignment = 0; int declarator_dllexport = 0; int declarator_dllimport = 0; @@ -522,6 +524,46 @@ static int parse_alias_attribute_argument (void) { } +static int parse_aligned_attribute_argument (void) { + + enum token_kind kill[2]; + + int64_s value; + unsigned long align; + + if (!_accept (TOK_LPAREN)) { + + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "expected '(' after 'aligned'"); + return 0; + + } + + kill[0] = TOK_RPAREN; + kill[1] = 0; + + value = expr_const64 (kill); + expect (TOK_RPAREN, ")"); + + if (value.high != 0 || value.low == 0) { + + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "alignment must be a positive power of two"); + return 0; + + } + + align = value.low; + + if ((align & (align - 1)) != 0) { + + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "alignment must be a positive power of two"); + return 0; + + } + + return (int) align; + +} + static void apply_decl_attribute (const char *spelling, int is_gnu) { if (attribute_name_is (spelling, "dllexport")) { @@ -580,6 +622,22 @@ static void apply_decl_attribute (const char *spelling, int is_gnu) { } + } else if (is_gnu && attribute_name_is (spelling, "aligned")) { + + int align = parse_aligned_attribute_argument (); + + if (align > 0) { + + int *slot = declarator_depth == 0 ? &parsed_alignment : &declarator_alignment; + + if (*slot > 0 && *slot != align) { + report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "conflicting 'aligned' attributes"); + } else { + *slot = align; + } + + } + } else if (is_gnu && attribute_name_is (spelling, "stdcall")) { if (parsed_calling_convention == TOK_EOF && declarator_calling_convention == TOK_EOF) { @@ -649,6 +707,8 @@ static void parse_decl_modifier (void) { if (attribute_name_is (name, "alias")) { parse_alias_attribute_argument (); + } else if (attribute_name_is (name, "aligned")) { + apply_decl_attribute (name, 1); } else { apply_decl_attribute (name, 1); @@ -859,6 +919,7 @@ void parse_declarator (char **out_name) { int saved_declarator_dllimport = declarator_dllimport; int saved_declarator_noreturn = declarator_noreturn; int saved_declarator_naked = declarator_naked; + int saved_declarator_alignment = declarator_alignment; unsigned long saved_captured_declarator_name_line = captured_declarator_name_line; memcpy (saved_declarator_alias_target, declarator_alias_target, sizeof (declarator_alias_target)); @@ -878,6 +939,7 @@ void parse_declarator (char **out_name) { declarator_dllimport = 0; declarator_noreturn = 0; declarator_naked = 0; + declarator_alignment = 0; captured_declarator_name_location = 0; captured_declarator_name_start = 0; @@ -944,6 +1006,7 @@ void parse_declarator (char **out_name) { declarator_dllimport = saved_declarator_dllimport; declarator_noreturn = saved_declarator_noreturn; declarator_naked = saved_declarator_naked; + declarator_alignment = saved_declarator_alignment; } @@ -2933,6 +2996,7 @@ void parse_type_spec (void) { parsed_dllimport = 0; parsed_noreturn = 0; parsed_naked = 0; + parsed_alignment = 0; clear_parsed_fields (); diff --git a/parse.h b/parse.h index 16e3d79..bf38cd6 100644 --- a/parse.h +++ b/parse.h @@ -32,6 +32,7 @@ extern int parsed_dllexport; extern int parsed_dllimport; extern int parsed_noreturn; extern int parsed_naked; +extern int parsed_alignment; extern int parsed_type_size; extern int parsed_type_is_inline; @@ -74,6 +75,7 @@ extern int declarator_dllexport; extern int declarator_dllimport; extern int declarator_noreturn; extern int declarator_naked; +extern int declarator_alignment; extern enum token_kind declarator_calling_convention; extern int global_initializer_accept_symbol_addresses;