Compound and array fixes
authorRobert Pengelly <robertapengelly@hotmail.com>
Sun, 9 Aug 2026 07:51:18 +0000 (08:51 +0100)
committerRobert Pengelly <robertapengelly@hotmail.com>
Sun, 9 Aug 2026 07:51:18 +0000 (08:51 +0100)
amd64.c
i386.c

diff --git a/amd64.c b/amd64.c
index 4e6ceb2a80220cbd8957236fef5f5c2011b4caa0..2c9a4451b4bc99762c81352525d8534eebf8bc13 100644 (file)
--- 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 46480c8dcc4ef38f392b72e459d368e4db17442c..75e2a7ec300919a1a7af5582c731bb90a2800929 100644 (file)
--- 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);