@@ -2159,7 +2159,164 @@ void read_expr(block_t *parent, basic_block_t **bb)
21592159 vd = require_var (parent );
21602160 gen_name_to (vd -> var_name );
21612161 opstack_push (vd );
2162- add_insn (parent , * bb , top_op , vd , rs1 , rs2 , 0 , NULL );
2162+
2163+ /* Handle pointer arithmetic:
2164+ * - If both operands are pointers (subtraction), divide by
2165+ * element size
2166+ * - If one operand is a pointer, handle scaling
2167+ * appropriately
2168+ */
2169+ if (top_op == OP_sub && rs1 -> is_ptr && rs2 -> is_ptr ) {
2170+ /* Subtracting two pointers - divide by element size */
2171+ var_t * diff = require_var (parent );
2172+ gen_name_to (diff -> var_name );
2173+ add_insn (parent , * bb , OP_sub , diff , rs1 , rs2 , 0 , NULL );
2174+
2175+ /* Get the element size */
2176+ int elem_size = 4 ; /* Default to int size */
2177+ if (rs1 -> type ) {
2178+ /* For pointers, check what they point to */
2179+ if (rs1 -> is_ptr || rs1 -> type -> ptr_level > 0 ) {
2180+ switch (rs1 -> type -> base_type ) {
2181+ case TYPE_char :
2182+ elem_size = 1 ;
2183+ break ;
2184+ case TYPE_int :
2185+ elem_size = 4 ;
2186+ break ;
2187+ default :
2188+ elem_size = 4 ;
2189+ break ;
2190+ }
2191+ } else {
2192+ /* For non-pointers, use the type size */
2193+ if (rs1 -> type -> size > 0 ) {
2194+ elem_size = rs1 -> type -> size ;
2195+ } else {
2196+ elem_size = 4 ;
2197+ }
2198+ }
2199+ }
2200+
2201+ /* Divide by element size */
2202+ if (elem_size > 1 ) {
2203+ var_t * size_const = require_var (parent );
2204+ size_const -> init_val = elem_size ;
2205+ gen_name_to (size_const -> var_name );
2206+ add_insn (parent , * bb , OP_load_constant , size_const ,
2207+ NULL , NULL , 0 , NULL );
2208+ add_insn (parent , * bb , OP_div , vd , diff , size_const ,
2209+ 0 , NULL );
2210+ } else {
2211+ /* If element size is 1, no division needed - use
2212+ * assignment */
2213+ add_insn (parent , * bb , OP_assign , vd , diff , NULL , 0 ,
2214+ NULL );
2215+ }
2216+ } else if ((top_op == OP_add || top_op == OP_sub ) &&
2217+ (rs1 -> is_ptr ||
2218+ (rs1 -> type && rs1 -> type -> ptr_level > 0 )) &&
2219+ !rs2 -> is_ptr ) {
2220+ /* Pointer +/- integer: scale the integer by element
2221+ * size */
2222+ int elem_size = 4 ;
2223+ if (rs1 -> type ) {
2224+ /* For pointers, check what they point to */
2225+ if (rs1 -> is_ptr || rs1 -> type -> ptr_level > 0 ) {
2226+ switch (rs1 -> type -> base_type ) {
2227+ case TYPE_char :
2228+ elem_size = 1 ;
2229+ break ;
2230+ case TYPE_int :
2231+ elem_size = 4 ;
2232+ break ;
2233+ default :
2234+ elem_size = 4 ;
2235+ break ;
2236+ }
2237+ } else {
2238+ /* For non-pointers, use the type size */
2239+ if (rs1 -> type -> size > 0 ) {
2240+ elem_size = rs1 -> type -> size ;
2241+ } else {
2242+ elem_size = 4 ;
2243+ }
2244+ }
2245+ }
2246+
2247+ /* Scale the integer operand if needed */
2248+ if (elem_size > 1 ) {
2249+ var_t * scaled = require_var (parent );
2250+ gen_name_to (scaled -> var_name );
2251+ var_t * size_const = require_var (parent );
2252+ size_const -> init_val = elem_size ;
2253+ gen_name_to (size_const -> var_name );
2254+ add_insn (parent , * bb , OP_load_constant , size_const ,
2255+ NULL , NULL , 0 , NULL );
2256+ add_insn (parent , * bb , OP_mul , scaled , rs2 ,
2257+ size_const , 0 , NULL );
2258+ add_insn (parent , * bb , top_op , vd , rs1 , scaled , 0 ,
2259+ NULL );
2260+ } else {
2261+ add_insn (parent , * bb , top_op , vd , rs1 , rs2 , 0 ,
2262+ NULL );
2263+ }
2264+ /* Result is still a pointer */
2265+ vd -> is_ptr = rs1 -> is_ptr ;
2266+ vd -> type = rs1 -> type ;
2267+ } else if ((top_op == OP_add ) && !rs1 -> is_ptr &&
2268+ (rs2 -> is_ptr ||
2269+ (rs2 -> type && rs2 -> type -> ptr_level > 0 ))) {
2270+ /* Integer + pointer: scale the integer by element size
2271+ */
2272+ int elem_size = 4 ;
2273+ if (rs2 -> type ) {
2274+ /* For pointers, check what they point to */
2275+ if (rs2 -> is_ptr || rs2 -> type -> ptr_level > 0 ) {
2276+ switch (rs2 -> type -> base_type ) {
2277+ case TYPE_char :
2278+ elem_size = 1 ;
2279+ break ;
2280+ case TYPE_int :
2281+ elem_size = 4 ;
2282+ break ;
2283+ default :
2284+ elem_size = 4 ;
2285+ break ;
2286+ }
2287+ } else {
2288+ /* For non-pointers, use the type size */
2289+ if (rs2 -> type -> size > 0 ) {
2290+ elem_size = rs2 -> type -> size ;
2291+ } else {
2292+ elem_size = 4 ;
2293+ }
2294+ }
2295+ }
2296+
2297+ /* Scale the integer operand if needed */
2298+ if (elem_size > 1 ) {
2299+ var_t * scaled = require_var (parent );
2300+ gen_name_to (scaled -> var_name );
2301+ var_t * size_const = require_var (parent );
2302+ size_const -> init_val = elem_size ;
2303+ gen_name_to (size_const -> var_name );
2304+ add_insn (parent , * bb , OP_load_constant , size_const ,
2305+ NULL , NULL , 0 , NULL );
2306+ add_insn (parent , * bb , OP_mul , scaled , rs1 ,
2307+ size_const , 0 , NULL );
2308+ add_insn (parent , * bb , top_op , vd , scaled , rs2 , 0 ,
2309+ NULL );
2310+ } else {
2311+ add_insn (parent , * bb , top_op , vd , rs1 , rs2 , 0 ,
2312+ NULL );
2313+ }
2314+ /* Result is a pointer */
2315+ vd -> is_ptr = rs2 -> is_ptr ;
2316+ vd -> type = rs2 -> type ;
2317+ } else {
2318+ add_insn (parent , * bb , top_op , vd , rs1 , rs2 , 0 , NULL );
2319+ }
21632320
21642321 oper_stack_idx -- ;
21652322 } else
@@ -2351,14 +2508,109 @@ void read_expr(block_t *parent, basic_block_t **bb)
23512508 vd = require_var (parent );
23522509 gen_name_to (vd -> var_name );
23532510 opstack_push (vd );
2354- add_insn (parent , * bb , top_op , vd , rs1 , rs2 , 0 , NULL );
2511+
2512+ /* Handle pointer subtraction */
2513+ if (top_op == OP_sub && rs1 -> is_ptr && rs2 -> is_ptr ) {
2514+ var_t * diff = require_var (parent );
2515+ gen_name_to (diff -> var_name );
2516+ add_insn (parent , * bb , OP_sub , diff , rs1 , rs2 , 0 , NULL );
2517+
2518+ int elem_size = 4 ;
2519+ if (rs1 -> type ) {
2520+ /* For pointers, check what they point to */
2521+ if (rs1 -> is_ptr || rs1 -> type -> ptr_level > 0 ) {
2522+ switch (rs1 -> type -> base_type ) {
2523+ case TYPE_char :
2524+ elem_size = 1 ;
2525+ break ;
2526+ case TYPE_int :
2527+ elem_size = 4 ;
2528+ break ;
2529+ default :
2530+ elem_size = 4 ;
2531+ break ;
2532+ }
2533+ } else {
2534+ /* For non-pointers, use the type size */
2535+ if (rs1 -> type -> size > 0 ) {
2536+ elem_size = rs1 -> type -> size ;
2537+ } else {
2538+ elem_size = 4 ;
2539+ }
2540+ }
2541+ }
2542+
2543+ if (elem_size > 1 ) {
2544+ var_t * size_const = require_var (parent );
2545+ size_const -> init_val = elem_size ;
2546+ gen_name_to (size_const -> var_name );
2547+ add_insn (parent , * bb , OP_load_constant , size_const ,
2548+ NULL , NULL , 0 , NULL );
2549+ add_insn (parent , * bb , OP_div , vd , diff , size_const , 0 ,
2550+ NULL );
2551+ } else {
2552+ /* If element size is 1, no division needed - use
2553+ * assignment */
2554+ add_insn (parent , * bb , OP_assign , vd , diff , NULL , 0 ,
2555+ NULL );
2556+ }
2557+ } else {
2558+ add_insn (parent , * bb , top_op , vd , rs1 , rs2 , 0 , NULL );
2559+ }
23552560 }
23562561 } else {
23572562 /* Normal operation */
23582563 vd = require_var (parent );
23592564 gen_name_to (vd -> var_name );
23602565 opstack_push (vd );
2361- add_insn (parent , * bb , top_op , vd , rs1 , rs2 , 0 , NULL );
2566+
2567+ /* Handle pointer subtraction */
2568+ if (top_op == OP_sub && rs1 -> is_ptr && rs2 -> is_ptr ) {
2569+ var_t * diff = require_var (parent );
2570+ gen_name_to (diff -> var_name );
2571+ add_insn (parent , * bb , OP_sub , diff , rs1 , rs2 , 0 , NULL );
2572+
2573+ int elem_size = 4 ;
2574+ if (rs1 -> type ) {
2575+ /* For pointers, check what they point to */
2576+ if (rs1 -> is_ptr || rs1 -> type -> ptr_level > 0 ) {
2577+ switch (rs1 -> type -> base_type ) {
2578+ case TYPE_char :
2579+ elem_size = 1 ;
2580+ break ;
2581+ case TYPE_int :
2582+ elem_size = 4 ;
2583+ break ;
2584+ default :
2585+ elem_size = 4 ;
2586+ break ;
2587+ }
2588+ } else {
2589+ /* For non-pointers, use the type size */
2590+ if (rs1 -> type -> size > 0 ) {
2591+ elem_size = rs1 -> type -> size ;
2592+ } else {
2593+ elem_size = 4 ;
2594+ }
2595+ }
2596+ }
2597+
2598+ if (elem_size > 1 ) {
2599+ var_t * size_const = require_var (parent );
2600+ size_const -> init_val = elem_size ;
2601+ gen_name_to (size_const -> var_name );
2602+ add_insn (parent , * bb , OP_load_constant , size_const , NULL ,
2603+ NULL , 0 , NULL );
2604+ add_insn (parent , * bb , OP_div , vd , diff , size_const , 0 ,
2605+ NULL );
2606+ } else {
2607+ /* If element size is 1, no division needed - use assignment
2608+ */
2609+ add_insn (parent , * bb , OP_assign , vd , diff , NULL , 0 , NULL );
2610+ }
2611+ } else {
2612+ add_insn (parent , * bb , top_op , vd , rs1 , rs2 , 0 , NULL );
2613+ }
23622614 }
23632615 }
23642616 while (has_prev_log_op ) {
0 commit comments