From: Robert Pengelly Date: Sun, 9 Aug 2026 07:51:18 +0000 (+0100) Subject: Compound and array fixes X-Git-Url: https://git.candlhat.org/?a=commitdiff_plain;h=72ebf31fdbb73bddfcf494973c7d21b1a053f51e;p=scc.git Compound and array fixes --- diff --git a/amd64.c b/amd64.c index 4e6ceb2..2c9a445 100644 --- a/amd64.c +++ b/amd64.c @@ -12540,6 +12540,8 @@ static void emit_load_floating_rhs_expression_now (int result_size); static void emit_load_assignment_rhs_to_reg (const char *reg); static int emit_load_deref_assignment_expression_to_reg_now (const char *reg); +static int emit_statement_rhs_const32_to_rdx_if_possible (void); + static void emit_floating_stack_to_int_pair_now (const char *lo, const char *hi); static void emit_integer_pair_to_floating_stack_now (const char *lo, const char *hi, int size); @@ -16308,6 +16310,23 @@ static int emit_parse_postfix_copy_source_address_now (const char *reg, struct l last_elem_size = elem_size; last_lvalue_size = elem_size; + /* + * A subscript changes the final lvalue from the whole array member + * to one array element. Keep the postfix metadata synchronized or + * the 64-bit expression loader will later use the array's total + * storage size as the scalar load width (e.g. UINT8 Length[2] + * becomes a 16-bit load for Length[i]). + */ + if (postfix_member_seen) { + + postfix_member_size = index_step_size (elem_size); + + if (postfix_member_pointer_depth > 0) { + postfix_member_pointer_depth--; + } + + } + current_object_size = elem_size; continue; @@ -19101,7 +19120,10 @@ static void emit_load_assignment_rhs_to_reg (const char *reg) { emit_push_reg_now ("rdx"); emit_push_reg_now (reg); - emit_load_assignment_rhs_expression_to_reg ("rdx"); + if (!emit_statement_rhs_const32_to_rdx_if_possible ()) { + emit_load_assignment_rhs_expression_to_reg ("rdx"); + } + emit_pop_reg_now (reg); emit_assignment_binary_op (op, 0); @@ -28517,9 +28539,11 @@ static int parse_parenthesized_pointer_member_indirect_assignment_statement (voi emit_load_member_from_addr_reg_now ("rax", "rdx", 0, prefix_deref_size); emit_push_reg_now ("rax"); - emit_load_assignment_rhs_expression_to_reg ("rdx"); - emit_pop_reg_now ("rax"); + if (!emit_statement_rhs_const32_to_rdx_if_possible ()) { + emit_load_assignment_rhs_expression_to_reg ("rdx"); + } + emit_pop_reg_now ("rax"); emit_assignment_binary_op (prefix_assign_op, 0); } @@ -28695,7 +28719,11 @@ static int parse_parenthesized_pointer_member_indirect_assignment_statement (voi emit_push_reg_now ("rdx"); emit_load_member_from_addr_reg_now ("rax", "rdx", 0, deref_size); emit_push_reg_now ("rax"); - emit_load_assignment_rhs_expression_to_reg ("rdx"); + + if (!emit_statement_rhs_const32_to_rdx_if_possible ()) { + emit_load_assignment_rhs_expression_to_reg ("rdx"); + } + emit_pop_reg_now ("rax"); emit_assignment_binary_op (op, 0); @@ -28991,7 +29019,11 @@ static int parse_parenthesized_pointer_member_indirect_assignment_statement (voi emit_load_member_from_addr_reg_now ("rax", "rdx", 0, deref_size); emit_push_reg_now ("rax"); - emit_load_assignment_rhs_expression_to_reg ("rdx"); + + if (!emit_statement_rhs_const32_to_rdx_if_possible ()) { + emit_load_assignment_rhs_expression_to_reg ("rdx"); + } + emit_pop_reg_now ("rax"); emit_assignment_binary_op (op, 0); @@ -29401,9 +29433,11 @@ static int parse_cast_indirect_assignment_statement (int lvalue_outer_paren_dept emit_pop_reg_now ("rax"); emit_load_deref_reg_ex_now ("rax", deref_size, deref_is_unsigned); - emit_push_reg_now ("rax"); - emit_load_assignment_rhs_expression_to_reg ("rdx"); + + if (!emit_statement_rhs_const32_to_rdx_if_possible ()) { + emit_load_assignment_rhs_expression_to_reg ("rdx"); + } emit_pop_reg_now ("rax"); @@ -29494,7 +29528,10 @@ static int parse_parenthesized_indirect_assignment_statement (void) { emit_load_deref_reg_now ("rax", deref_size); emit_push_reg_now ("rax"); - emit_load_assignment_rhs_expression_to_reg ("rdx"); + if (!emit_statement_rhs_const32_to_rdx_if_possible ()) { + emit_load_assignment_rhs_expression_to_reg ("rdx"); + } + emit_pop_reg_now ("rax"); emit_assignment_binary_op (op, 0); @@ -29624,7 +29661,10 @@ static int parse_indirect_assignment_statement (void) { emit_load_member_from_addr_reg_now ("rax", "rcx", 0, deref_size); emit_push_reg_now ("rax"); - emit_load_assignment_rhs_expression_to_reg ("rdx"); + if (!emit_statement_rhs_const32_to_rdx_if_possible ()) { + emit_load_assignment_rhs_expression_to_reg ("rdx"); + } + emit_pop_reg_now ("rax"); emit_assignment_binary_op (op, 0); @@ -29823,7 +29863,11 @@ static int parse_indirect_assignment_statement (void) { emit_push_reg_now ("rdx"); emit_load_member_from_addr_reg_now ("rax", "rdx", 0, deref_size); emit_push_reg_now ("rax"); - emit_load_assignment_rhs_expression_to_reg ("rdx"); + + if (!emit_statement_rhs_const32_to_rdx_if_possible ()) { + emit_load_assignment_rhs_expression_to_reg ("rdx"); + } + emit_pop_reg_now ("rax"); emit_assignment_binary_op (op, 0); @@ -30004,7 +30048,11 @@ static int parse_indirect_assignment_statement (void) { emit_load_member_from_addr_reg_now ("rax", "rdx", 0, deref_size); emit_push_reg_now ("rax"); - emit_load_assignment_rhs_expression_to_reg ("rdx"); + + if (!emit_statement_rhs_const32_to_rdx_if_possible ()) { + emit_load_assignment_rhs_expression_to_reg ("rdx"); + } + emit_pop_reg_now ("rax"); emit_assignment_binary_op (op, 0); @@ -30144,7 +30192,10 @@ static int parse_indirect_assignment_statement (void) { emit_push_reg_now ("rdx"); emit_push_reg_now ("rax"); - emit_load_assignment_rhs_expression_to_reg ("rdx"); + if (!emit_statement_rhs_const32_to_rdx_if_possible ()) { + emit_load_assignment_rhs_expression_to_reg ("rdx"); + } + emit_pop_reg_now ("rax"); emit_assignment_binary_op (op, 0); @@ -30417,7 +30468,11 @@ static int parse_parenthesized_indirect_member_assignment_statement (void) { emit_load_member_from_addr_reg_now ("rax", "rdx", 0, deref_size); emit_push_reg_now ("rdx"); emit_push_reg_now ("rax"); - emit_load_assignment_rhs_expression_to_reg ("rdx"); + + if (!emit_statement_rhs_const32_to_rdx_if_possible ()) { + emit_load_assignment_rhs_expression_to_reg ("rdx"); + } + emit_pop_reg_now ("rax"); emit_assignment_binary_op (op, 0); emit_pop_reg_now ("rdx"); @@ -30499,7 +30554,11 @@ static int parse_parenthesized_indirect_member_assignment_statement (void) { emit_load_member_from_addr_reg_now ("rax", "rdx", member_offset, member_size); emit_push_reg_now ("rdx"); emit_push_reg_now ("rax"); - emit_load_assignment_rhs_expression_to_reg ("rdx"); + + if (!emit_statement_rhs_const32_to_rdx_if_possible ()) { + emit_load_assignment_rhs_expression_to_reg ("rdx"); + } + emit_pop_reg_now ("rax"); emit_assignment_binary_op (op, 0); emit_pop_reg_now ("rdx"); @@ -31142,7 +31201,11 @@ static int parse_identifier_assignment_statement (void) { emit_load_member_from_addr_reg_now ("rax", "rdx", 0, elem_size); emit_push_reg_now ("rdx"); emit_push_reg_now ("rax"); - emit_load_assignment_rhs_expression_to_reg ("rdx"); + + if (!emit_statement_rhs_const32_to_rdx_if_possible ()) { + emit_load_assignment_rhs_expression_to_reg ("rdx"); + } + emit_pop_reg_now ("rax"); emit_assignment_binary_op (op, 0); emit_pop_reg_now ("rdx"); @@ -31229,7 +31292,11 @@ static int parse_identifier_assignment_statement (void) { emit_load_member_from_addr_reg_now ("rax", "rdx", 0, elem_size); emit_push_reg_now ("rdx"); emit_push_reg_now ("rax"); - emit_load_assignment_rhs_expression_to_reg ("rdx"); + + if (!emit_statement_rhs_const32_to_rdx_if_possible ()) { + emit_load_assignment_rhs_expression_to_reg ("rdx"); + } + emit_pop_reg_now ("rax"); emit_assignment_binary_op (op, 0); emit_pop_reg_now ("rdx"); @@ -31330,7 +31397,11 @@ static int parse_identifier_assignment_statement (void) { emit_load_member_from_addr_reg_now ("rax", "rdx", member_offset, member_size); emit_push_reg_now ("rdx"); emit_push_reg_now ("rax"); - emit_load_assignment_rhs_expression_to_reg ("rdx"); + + if (!emit_statement_rhs_const32_to_rdx_if_possible ()) { + emit_load_assignment_rhs_expression_to_reg ("rdx"); + } + emit_pop_reg_now ("rax"); emit_assignment_binary_op (op, 0); emit_pop_reg_now ("rdx"); @@ -36692,7 +36763,10 @@ static int parse_postfix_assignment_statement_now (void) { emit_load_member_from_addr_reg_now ("rax", "rdx", 0, lvalue_size); emit_push_reg_now ("rax"); - emit_load_assignment_rhs_expression_to_reg ("rdx"); + if (!emit_statement_rhs_const32_to_rdx_if_possible ()) { + emit_load_assignment_rhs_expression_to_reg ("rdx"); + } + emit_pop_reg_now ("rax"); emit_assignment_binary_op (assign_op, 0); diff --git a/i386.c b/i386.c index 46480c8..75e2a7e 100644 --- a/i386.c +++ b/i386.c @@ -11140,6 +11140,8 @@ static void emit_load_floating_rhs_expression_now (int result_size); static void emit_load_assignment_rhs_to_reg (const char *reg); static int emit_load_deref_assignment_expression_to_reg_now (const char *reg); +static int emit_statement_rhs_const32_to_edx_if_possible (void); + static void emit_floating_stack_to_int_pair_now (const char *lo, const char *hi); static void emit_integer_pair_to_floating_stack_now (const char *lo, const char *hi, int size); @@ -17118,9 +17120,11 @@ static int emit_load_deref_assignment_expression_to_reg_now (const char *reg) { } else { emit_load_deref_reg_now ("ecx", store_size); - emit_push_reg_now ("ecx"); - emit_load_assignment_rhs_expression_to_reg ("edx"); + + if (!emit_statement_rhs_const32_to_edx_if_possible ()) { + emit_load_assignment_rhs_expression_to_reg ("edx"); + } emit_pop_reg_now ("eax"); @@ -17869,7 +17873,10 @@ static void emit_load_assignment_rhs_to_reg (const char *reg) { emit_push_reg_now ("edx"); emit_push_reg_now (reg); - emit_load_assignment_rhs_expression_to_reg ("edx"); + if (!emit_statement_rhs_const32_to_edx_if_possible ()) { + emit_load_assignment_rhs_expression_to_reg ("edx"); + } + emit_pop_reg_now (reg); emit_assignment_binary_op (op, 0); @@ -24187,6 +24194,7 @@ static int arithmetic_operator_precedence_now (enum token_kind op) { static int emit_load_assignment_binary_expression_prec_to_reg (const char *reg, int min_prec) { int is_unsigned; + int expr_pointer_depth; int expr_pointed_size; @@ -25788,9 +25796,11 @@ static int parse_parenthesized_pointer_member_indirect_assignment_statement (voi emit_load_member_from_addr_reg_now ("eax", "edx", 0, prefix_deref_size); emit_push_reg_now ("eax"); - emit_load_assignment_rhs_expression_to_reg ("edx"); - emit_pop_reg_now ("eax"); + if (!emit_statement_rhs_const32_to_edx_if_possible ()) { + emit_load_assignment_rhs_expression_to_reg ("edx"); + } + emit_pop_reg_now ("eax"); emit_assignment_binary_op (prefix_assign_op, 0); } @@ -25958,7 +25968,11 @@ static int parse_parenthesized_pointer_member_indirect_assignment_statement (voi emit_push_reg_now ("edx"); emit_load_member_from_addr_reg_now ("eax", "edx", 0, deref_size); emit_push_reg_now ("eax"); - emit_load_assignment_rhs_expression_to_reg ("edx"); + + if (!emit_statement_rhs_const32_to_edx_if_possible ()) { + emit_load_assignment_rhs_expression_to_reg ("edx"); + } + emit_pop_reg_now ("eax"); emit_assignment_binary_op (op, 0); @@ -26254,7 +26268,11 @@ static int parse_parenthesized_pointer_member_indirect_assignment_statement (voi emit_load_member_from_addr_reg_now ("eax", "edx", 0, deref_size); emit_push_reg_now ("eax"); - emit_load_assignment_rhs_expression_to_reg ("edx"); + + if (!emit_statement_rhs_const32_to_edx_if_possible ()) { + emit_load_assignment_rhs_expression_to_reg ("edx"); + } + emit_pop_reg_now ("eax"); emit_assignment_binary_op (op, 0); @@ -26664,9 +26682,11 @@ static int parse_cast_indirect_assignment_statement (int lvalue_outer_paren_dept emit_pop_reg_now ("eax"); emit_load_deref_reg_ex_now ("eax", deref_size, deref_is_unsigned); - emit_push_reg_now ("eax"); - emit_load_assignment_rhs_expression_to_reg ("edx"); + + if (!emit_statement_rhs_const32_to_edx_if_possible ()) { + emit_load_assignment_rhs_expression_to_reg ("edx"); + } emit_pop_reg_now ("eax"); @@ -26757,7 +26777,10 @@ static int parse_parenthesized_indirect_assignment_statement (void) { emit_load_deref_reg_now ("eax", deref_size); emit_push_reg_now ("eax"); - emit_load_assignment_rhs_expression_to_reg ("edx"); + if (!emit_statement_rhs_const32_to_edx_if_possible ()) { + emit_load_assignment_rhs_expression_to_reg ("edx"); + } + emit_pop_reg_now ("eax"); emit_assignment_binary_op (op, 0); @@ -26887,7 +26910,10 @@ static int parse_indirect_assignment_statement (void) { emit_load_member_from_addr_reg_now ("eax", "ecx", 0, deref_size); emit_push_reg_now ("eax"); - emit_load_assignment_rhs_expression_to_reg ("edx"); + if (!emit_statement_rhs_const32_to_edx_if_possible ()) { + emit_load_assignment_rhs_expression_to_reg ("edx"); + } + emit_pop_reg_now ("eax"); emit_assignment_binary_op (op, 0); @@ -27078,7 +27104,11 @@ static int parse_indirect_assignment_statement (void) { emit_push_reg_now ("edx"); emit_load_member_from_addr_reg_now ("eax", "edx", 0, deref_size); emit_push_reg_now ("eax"); - emit_load_assignment_rhs_expression_to_reg ("edx"); + + if (!emit_statement_rhs_const32_to_edx_if_possible ()) { + emit_load_assignment_rhs_expression_to_reg ("edx"); + } + emit_pop_reg_now ("eax"); emit_assignment_binary_op (op, 0); @@ -27259,7 +27289,11 @@ static int parse_indirect_assignment_statement (void) { emit_load_member_from_addr_reg_now ("eax", "edx", 0, deref_size); emit_push_reg_now ("eax"); - emit_load_assignment_rhs_expression_to_reg ("edx"); + + if (!emit_statement_rhs_const32_to_edx_if_possible ()) { + emit_load_assignment_rhs_expression_to_reg ("edx"); + } + emit_pop_reg_now ("eax"); emit_assignment_binary_op (op, 0); @@ -27408,7 +27442,10 @@ static int parse_indirect_assignment_statement (void) { emit_push_reg_now ("edx"); emit_push_reg_now ("eax"); - emit_load_assignment_rhs_expression_to_reg ("edx"); + if (!emit_statement_rhs_const32_to_edx_if_possible ()) { + emit_load_assignment_rhs_expression_to_reg ("edx"); + } + emit_pop_reg_now ("eax"); emit_assignment_binary_op (op, 0); @@ -27685,7 +27722,11 @@ static int parse_parenthesized_indirect_member_assignment_statement (void) { emit_load_member_from_addr_reg_now ("eax", "edx", 0, deref_size); emit_push_reg_now ("edx"); emit_push_reg_now ("eax"); - emit_load_assignment_rhs_expression_to_reg ("edx"); + + if (!emit_statement_rhs_const32_to_edx_if_possible ()) { + emit_load_assignment_rhs_expression_to_reg ("edx"); + } + emit_pop_reg_now ("eax"); emit_assignment_binary_op (op, 0); emit_pop_reg_now ("edx"); @@ -27767,7 +27808,11 @@ static int parse_parenthesized_indirect_member_assignment_statement (void) { emit_load_member_from_addr_reg_now ("eax", "edx", member_offset, member_size); emit_push_reg_now ("edx"); emit_push_reg_now ("eax"); - emit_load_assignment_rhs_expression_to_reg ("edx"); + + if (!emit_statement_rhs_const32_to_edx_if_possible ()) { + emit_load_assignment_rhs_expression_to_reg ("edx"); + } + emit_pop_reg_now ("eax"); emit_assignment_binary_op (op, 0); emit_pop_reg_now ("edx"); @@ -28409,7 +28454,11 @@ static int parse_identifier_assignment_statement (void) { emit_load_member_from_addr_reg_now ("eax", "edx", 0, elem_size); emit_push_reg_now ("edx"); emit_push_reg_now ("eax"); - emit_load_assignment_rhs_expression_to_reg ("edx"); + + if (!emit_statement_rhs_const32_to_edx_if_possible ()) { + emit_load_assignment_rhs_expression_to_reg ("edx"); + } + emit_pop_reg_now ("eax"); emit_assignment_binary_op (op, 0); emit_pop_reg_now ("edx"); @@ -28496,7 +28545,11 @@ static int parse_identifier_assignment_statement (void) { emit_load_member_from_addr_reg_now ("eax", "edx", 0, elem_size); emit_push_reg_now ("edx"); emit_push_reg_now ("eax"); - emit_load_assignment_rhs_expression_to_reg ("edx"); + + if (!emit_statement_rhs_const32_to_edx_if_possible ()) { + emit_load_assignment_rhs_expression_to_reg ("edx"); + } + emit_pop_reg_now ("eax"); emit_assignment_binary_op (op, 0); emit_pop_reg_now ("edx"); @@ -28597,7 +28650,11 @@ static int parse_identifier_assignment_statement (void) { emit_load_member_from_addr_reg_now ("eax", "edx", member_offset, member_size); emit_push_reg_now ("edx"); emit_push_reg_now ("eax"); - emit_load_assignment_rhs_expression_to_reg ("edx"); + + if (!emit_statement_rhs_const32_to_edx_if_possible ()) { + emit_load_assignment_rhs_expression_to_reg ("edx"); + } + emit_pop_reg_now ("eax"); emit_assignment_binary_op (op, 0); emit_pop_reg_now ("edx"); @@ -34128,7 +34185,10 @@ static int parse_postfix_assignment_statement_now (void) { emit_load_member_from_addr_reg_now ("eax", "edx", 0, lvalue_size); emit_push_reg_now ("eax"); - emit_load_assignment_rhs_expression_to_reg ("edx"); + if (!emit_statement_rhs_const32_to_edx_if_possible ()) { + emit_load_assignment_rhs_expression_to_reg ("edx"); + } + emit_pop_reg_now ("eax"); emit_assignment_binary_op (assign_op, 0);