diff options
-rw-r--r-- | cgcalc.c | 89 | ||||
-rw-r--r-- | cgcalc.h | 4 | ||||
-rw-r--r-- | cgcode.c | 204 | ||||
-rw-r--r-- | cgcode.h | 2 | ||||
-rw-r--r-- | cgcodep.h | 18 | ||||
-rw-r--r-- | cgconst.h | 11 | ||||
-rw-r--r-- | cgiconst.h | 54 | ||||
-rw-r--r-- | cginput.c | 18 | ||||
-rw-r--r-- | cginstructions.c | 385 | ||||
-rw-r--r-- | cginstructions.h | 4 | ||||
-rw-r--r-- | cglin.c | 369 | ||||
-rw-r--r-- | cglin.h | 48 | ||||
-rw-r--r-- | cgopt.c | 401 | ||||
-rw-r--r-- | cgopt.h | 6 | ||||
-rw-r--r-- | cgport.h | 12 | ||||
-rw-r--r-- | cgrconst.h | 7 | ||||
-rw-r--r-- | cgstack.c | 265 | ||||
-rw-r--r-- | cgstack.h | 2 | ||||
-rw-r--r-- | cgtypes.h | 11 |
19 files changed, 1391 insertions, 519 deletions
@@ -244,7 +244,7 @@ static void calculate_eor_operator (INSTRUCTION_GRAPH graph) graph->order_alterable=graph->node_count<=1; } -#ifdef I486 +#if defined (I486) || defined (ARM) static void calculate_mulud_operator (INSTRUCTION_GRAPH graph) { INSTRUCTION_GRAPH graph_1,graph_2; @@ -1438,7 +1438,7 @@ static void calculate_store_x_operator (INSTRUCTION_GRAPH graph) select_graph=select_graph->instruction_parameters[3].p; break; case GFLOAD_X: -#ifdef I486 +#if defined (I486) || defined (ARM) case GFLOAD_S_X: #endif case GREGISTER: @@ -1757,7 +1757,7 @@ static void calculate_fstore_x_operator (INSTRUCTION_GRAPH graph) while (select_graph!=NULL){ switch (select_graph->instruction_code){ case GFLOAD_X: -#ifdef I486 +#if defined (I486) || defined (ARM) case GFLOAD_S_X: #endif if (graph_2==select_graph->instruction_parameters[0].p){ @@ -2411,17 +2411,17 @@ void calculate_graph_register_uses (INSTRUCTION_GRAPH graph) calculate_dyadic_non_commutative_operator (graph); return; case GDIV: -#if defined (I486) || defined (G_POWER) +#if defined (I486) || defined (ARM) || defined (G_POWER) case GDIVU: #endif -#ifdef I486 +#if defined (I486) || defined (ARM) case GFLOORDIV: case GMOD: #endif calculate_dyadic_non_commutative_data_operator (graph); return; case GREM: -#ifdef I486 +#if defined (I486) || defined (ARM) case GREMU: #endif calculate_rem_operator (graph); @@ -2429,7 +2429,7 @@ void calculate_graph_register_uses (INSTRUCTION_GRAPH graph) case GLSL: case GLSR: case GASR: -#ifdef I486 +#if defined (I486) || defined (ARM) case GROTL: case GROTR: #endif @@ -2452,7 +2452,7 @@ void calculate_graph_register_uses (INSTRUCTION_GRAPH graph) return; case GCNOT: case GNEG: -#if defined (I486) || defined (G_POWER) +#if defined (I486) || defined (ARM) || defined (G_POWER) case GNOT: #endif calculate_cnot_operator (graph); @@ -2498,13 +2498,13 @@ void calculate_graph_register_uses (INSTRUCTION_GRAPH graph) calculate_fstore_operator (graph); return; case GFLOAD_X: -#ifdef I486 +#if defined (I486) || defined (ARM) case GFLOAD_S_X: #endif calculate_fload_x_operator (graph); return; case GFSTORE_X: -#ifdef I486 +#if defined (I486) || defined (ARM) case GFSTORE_S_X: #endif calculate_fstore_x_operator (graph); @@ -2606,7 +2606,7 @@ void calculate_graph_register_uses (INSTRUCTION_GRAPH graph) graph->order_alterable=graph_2->order_alterable; return; } -#ifdef I486 +#if defined (I486) || defined (ARM) case GRESULT0: case GRESULT1: { @@ -2616,7 +2616,10 @@ void calculate_graph_register_uses (INSTRUCTION_GRAPH graph) if (graph_0->order_mode==R_NOMODE) if (graph_0->instruction_code==GMULUD) calculate_mulud_operator (graph_0); - else if ( graph_0->instruction_code==GDIVDU || + else if ( +# ifdef I486 + graph_0->instruction_code==GDIVDU || +# endif graph_0->instruction_code==GADDDU || graph_0->instruction_code==GSUBDU) { @@ -2738,10 +2741,10 @@ void count_graph (INSTRUCTION_GRAPH graph) case GCMP_LT: case GCMP_LTU: case GDIV: -#if defined (I486) || defined (G_POWER) +#if defined (I486) || defined (ARM) || defined (G_POWER) case GDIVU: #endif -#ifdef I486 +#if defined (I486) || defined (ARM) case GFLOORDIV: case GMOD: #endif @@ -2759,7 +2762,7 @@ void count_graph (INSTRUCTION_GRAPH graph) case GLSL: case GLSR: case GREM: -#ifdef I486 +#if defined (I486) || defined (ARM) case GREMU: #endif case GMUL: @@ -2769,7 +2772,7 @@ void count_graph (INSTRUCTION_GRAPH graph) case GSUB_O: case GEOR: case GASR: -#ifdef I486 +#if defined (I486) || defined (ARM) case GROTL: case GROTR: #endif @@ -2778,7 +2781,7 @@ void count_graph (INSTRUCTION_GRAPH graph) #ifdef G_POWER case GUMULH: #endif -#ifdef I486 +#if defined (I486) || defined (ARM) case GMULUD: #endif if (++graph->node_count==1){ @@ -2814,12 +2817,12 @@ void count_graph (INSTRUCTION_GRAPH graph) case GFEXP: #endif case GNEG: -#if defined (I486) || defined (G_POWER) +#if defined (I486) || defined (ARM) || defined (G_POWER) case GNOT: #endif case GBEFORE0: case GTEST_O: -#ifdef I486 +#if defined (I486) || defined (ARM) case GRESULT0: case GRESULT1: #endif @@ -2882,7 +2885,7 @@ void count_graph (INSTRUCTION_GRAPH graph) #ifdef G_AI64 case GLOAD_S_X: #endif -#ifdef I486 +#if defined (I486) || defined (ARM) case GFLOAD_S_X: #endif if (++graph->node_count==1){ @@ -2899,7 +2902,7 @@ void count_graph (INSTRUCTION_GRAPH graph) count_gstore_x_node (graph); break; case GFSTORE_X: -#ifdef I486 +#if defined (I486) || defined (ARM) case GFSTORE_S_X: #endif if (++graph->node_count==1){ @@ -2933,10 +2936,12 @@ void count_graph (INSTRUCTION_GRAPH graph) case GREGISTER: ++graph->node_count; break; -#ifdef I486 +#if defined (I486) || defined (ARM) case GADDDU: case GSUBDU: +# ifdef I486 case GDIVDU: +# endif if (++graph->node_count==1){ count_graph (graph->instruction_parameters[0].p); count_graph (graph->instruction_parameters[1].p); @@ -2961,10 +2966,10 @@ void mark_graph_2 (register INSTRUCTION_GRAPH graph) case GCMP_LT: case GCMP_LTU: case GDIV: -#if defined (I486) || defined (G_POWER) +#if defined (I486) || defined (ARM) || defined (G_POWER) case GDIVU: #endif -#ifdef I486 +#if defined (I486) || defined (ARM) case GFLOORDIV: case GMOD: #endif @@ -2982,7 +2987,7 @@ void mark_graph_2 (register INSTRUCTION_GRAPH graph) case GLSL: case GLSR: case GREM: -#ifdef I486 +#if defined (I486) || defined (ARM) case GREMU: #endif case GMUL: @@ -2992,7 +2997,7 @@ void mark_graph_2 (register INSTRUCTION_GRAPH graph) case GSUB_O: case GEOR: case GASR: -#ifdef I486 +#if defined (I486) || defined (ARM) case GROTL: case GROTR: #endif @@ -3001,7 +3006,7 @@ void mark_graph_2 (register INSTRUCTION_GRAPH graph) #ifdef G_POWER case GUMULH: #endif -#ifdef I486 +#if defined (I486) || defined (ARM) case GMULUD: #endif if (graph->node_mark<2){ @@ -3038,12 +3043,12 @@ void mark_graph_2 (register INSTRUCTION_GRAPH graph) case GFEXP: #endif case GNEG: -#if defined (I486) || defined (G_POWER) +#if defined (I486) || defined (ARM) || defined (G_POWER) case GNOT: #endif case GBEFORE0: case GTEST_O: -#ifdef I486 +#if defined (I486) || defined (ARM) case GRESULT0: case GRESULT1: #endif @@ -3118,7 +3123,7 @@ void mark_graph_2 (register INSTRUCTION_GRAPH graph) #ifdef G_AI64 case GLOAD_S_X: #endif -#ifdef I486 +#if defined (I486) || defined (ARM) case GFLOAD_S_X: #endif if (graph->node_mark<2){ @@ -3134,7 +3139,7 @@ void mark_graph_2 (register INSTRUCTION_GRAPH graph) case GSTORE_S_X: #endif case GFSTORE_X: -#ifdef I486 +#if defined (I486) || defined (ARM) case GFSTORE_S_X: #endif if (graph->node_mark<2){ @@ -3171,10 +3176,12 @@ void mark_graph_2 (register INSTRUCTION_GRAPH graph) case GREGISTER: graph->node_mark=2; break; -#ifdef I486 +#if defined (I486) || defined (ARM) case GADDDU: case GSUBDU: +# ifdef I486 case GDIVDU: +# endif if (graph->node_mark<2){ graph->node_mark=2; mark_graph_2 (graph->instruction_parameters[0].p); @@ -3200,10 +3207,10 @@ void mark_graph_1 (register INSTRUCTION_GRAPH graph) case GCMP_LT: case GCMP_LTU: case GDIV: -#if defined (I486) || defined (G_POWER) +#if defined (I486) || defined (ARM) || defined (G_POWER) case GDIVU: #endif -#ifdef I486 +#if defined (I486) || defined (ARM) case GFLOORDIV: case GMOD: #endif @@ -3221,7 +3228,7 @@ void mark_graph_1 (register INSTRUCTION_GRAPH graph) case GLSL: case GLSR: case GREM: -#ifdef I486 +#if defined (I486) || defined (ARM) case GREMU: #endif case GMUL: @@ -3231,7 +3238,7 @@ void mark_graph_1 (register INSTRUCTION_GRAPH graph) case GSUB_O: case GEOR: case GASR: -#ifdef I486 +#if defined (I486) || defined (ARM) case GROTL: case GROTR: #endif @@ -3240,7 +3247,7 @@ void mark_graph_1 (register INSTRUCTION_GRAPH graph) #ifdef G_POWER case GUMULH: #endif -#ifdef I486 +#if defined (I486) || defined (ARM) case GMULUD: #endif if (!graph->node_mark){ @@ -3271,12 +3278,12 @@ void mark_graph_1 (register INSTRUCTION_GRAPH graph) case GFEXP: #endif case GNEG: -#if defined (I486) || defined (G_POWER) +#if defined (I486) || defined (ARM) || defined (G_POWER) case GNOT: #endif case GBEFORE0: case GTEST_O: -#ifdef I486 +#if defined (I486) || defined (ARM) case GRESULT0: case GRESULT1: #endif @@ -3345,7 +3352,7 @@ void mark_graph_1 (register INSTRUCTION_GRAPH graph) #ifdef G_AI64 case GLOAD_S_X: #endif -#ifdef I486 +#if defined (I486) || defined (ARM) case GFLOAD_S_X: #endif if (!graph->node_mark){ @@ -3361,7 +3368,7 @@ void mark_graph_1 (register INSTRUCTION_GRAPH graph) case GSTORE_S_X: #endif case GFSTORE_X: -#ifdef I486 +#if defined (I486) || defined (ARM) case GFSTORE_S_X: #endif if (!graph->node_mark){ @@ -8,6 +8,10 @@ extern void mark_and_count_graph (INSTRUCTION_GRAPH graph); /* # define A_FACTOR 2 */ /* # define D_FACTOR 2 */ # define AD_REG_WEIGHT(n_a_regs,n_d_regs) ((n_a_regs)+(n_d_regs)) +#elif defined (ARM) +/* # define A_FACTOR 5 */ +/* # define D_FACTOR 3 */ +# define AD_REG_WEIGHT(n_a_regs,n_d_regs) ((((n_a_regs)<<2)+(n_a_regs))+((n_d_regs)+(n_d_regs)+(n_d_regs))) #else /* # define A_FACTOR 7 */ /* # define D_FACTOR 3 */ @@ -21,7 +21,7 @@ #include "cgport.h" -#if defined (G_POWER) || defined (I486) || defined (sparc) +#if defined (G_POWER) || defined (I486) || defined (ARM) || defined (sparc) # define NO_STRING_ADDRESS_IN_DESCRIPTOR #endif @@ -29,7 +29,7 @@ # define SIN_COS_CSE #endif -#if defined (G_POWER) || defined (I486) +#if defined (G_POWER) || defined (I486) || defined (ARM) # define PROFILE # if defined (G_POWER) # if defined (MACH_O) @@ -60,7 +60,7 @@ # include "cgpas.h" # include "cgpwas.h" #else -# ifdef I486 +# if defined (I486) || defined (ARM) # ifdef G_AI64 # include "cgaas.h" # include "cgawas.h" @@ -223,16 +223,16 @@ int no_time_profiling; #define g_bounds(g1,g2) g_instruction_2(GBOUNDS,(g1),(g2)) #define g_cmp_eq(g1,g2) g_instruction_2(GCMP_EQ,(g1),(g2)) #define g_cmp_gt(g1,g2) g_instruction_2(GCMP_GT,(g1),(g2)) -#ifdef I486 +#if defined (I486) || defined (ARM) # define g_cmp_gtu(g1,g2) g_instruction_2(GCMP_GTU,(g1),(g2)) #endif #define g_cmp_lt(g1,g2) g_instruction_2(GCMP_LT,(g1),(g2)) -#ifdef I486 +#if defined (I486) || defined (ARM) # define g_cmp_ltu(g1,g2) g_instruction_2(GCMP_LTU,(g1),(g2)) #endif #define g_cnot(g1) g_instruction_1(GCNOT,(g1)) #define g_div(g1,g2) g_instruction_2(GDIV,(g1),(g2)) -#if defined (I486) || defined (G_POWER) +#if defined (I486) || defined (ARM) || defined (G_POWER) # define g_divu(g1,g2) g_instruction_2(GDIVU,(g1),(g2)) #endif #define g_eor(g1,g2) g_instruction_2(GEOR,(g1),(g2)) @@ -242,7 +242,7 @@ int no_time_profiling; #define g_fcmp_lt(g1,g2) g_instruction_2(GFCMP_LT,(g1),(g2)) #define g_fdiv(g1,g2) g_instruction_2(GFDIV,(g1),(g2)) #define g_fitor(g1) g_instruction_1(GFITOR,(g1)) -#ifdef I486 +#if defined (I486) || defined (ARM) # define g_floordiv(g1,g2) g_instruction_2(GFLOORDIV,(g1),(g2)) #endif #define g_fmul(g1,g2) g_instruction_2(GFMUL,(g1),(g2)) @@ -252,13 +252,13 @@ int no_time_profiling; #define g_lsl(g1,g2) g_instruction_2(GLSL,(g1),(g2)) #define g_lsr(g1,g2) g_instruction_2(GLSR,(g1),(g2)) #define g_rem(g1,g2) g_instruction_2(GREM,(g1),(g2)) -#ifdef I486 +#if defined (I486) || defined (ARM) # define g_mod(g1,g2) g_instruction_2(GMOD,(g1),(g2)) # define g_remu(g1,g2) g_instruction_2(GREMU,(g1),(g2)) #endif #define g_mul(g1,g2) g_instruction_2(GMUL,(g1),(g2)) #define g_neg(g1) g_instruction_1(GNEG,(g1)) -#if defined (I486) || defined (G_POWER) +#if defined (I486) || defined (ARM) || defined (G_POWER) # define g_not(g1) g_instruction_1(GNOT,(g1)) #endif #define g_or(g1,g2) g_instruction_2(GOR,(g1),(g2)) @@ -297,8 +297,11 @@ LABEL *cycle_in_spine_label,*reserve_label; static LABEL *halt_label,*cmp_string_label,*eqD_label, *slice_string_label,*print_label,*print_sc_label, *print_symbol_label,*print_symbol_sc_label,*D_to_S_label, +#if defined (M68000) || defined (ARM) + *div_label,*mod_label, +#endif #ifdef M68000 - *div_label,*mod_label,*mul_label, + *mul_label, #endif *update_string_label,*equal_string_label, *yet_args_needed_label, @@ -639,7 +642,7 @@ void code_addI (VOID) s_put_b (0,graph_3); } -#ifdef I486 +#if defined (I486) || defined (ARM) void code_addLU (VOID) { INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4,graph_5,graph_6; @@ -1127,7 +1130,7 @@ void code_buildB (int value) } #endif -#ifdef I486 +#if defined (I486) || defined (ARM) graph_3=g_load_i (value); #else graph_3=g_load_i (-value); @@ -1500,7 +1503,7 @@ void code_CtoAC (VOID) graph_2=g_load_i (1); graph_3=s_pop_b(); -#ifndef I486 +#if !(defined (I486) || defined (ARM)) graph_3=g_lsl (g_load_i (24),graph_3); #endif @@ -2271,26 +2274,40 @@ void code_del_args (int source_offset,int n_arguments,int destination_offset) void code_divI (VOID) { + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + + graph_2=s_get_b (1); + #ifdef M68000 if (!mc68000_flag){ #endif - INSTRUCTION_GRAPH graph_1,graph_2,graph_3; - +#ifdef ARM + if (graph_2->instruction_code==GLOAD_I && graph_2->instruction_parameters[0].i!=0){ +#endif graph_1=s_pop_b(); - graph_2=s_get_b (0); +#ifdef ARM + graph_2=g_load_i (graph_2->instruction_parameters[0].i); +#endif graph_3=g_div (graph_2,graph_1); s_put_b (0,graph_3); +#ifdef ARM + return; + } +#endif #ifdef sparc if (dot_div_label==NULL) dot_div_label=enter_label (".div",IMPORT_LABEL); #endif #ifdef M68000 - } else { + } else +#endif +#if defined (M68000) || defined (ARM) + { if (div_label==NULL) div_label=enter_label ("divide",IMPORT_LABEL); s_push_b (s_get_b (0)); - s_put_b (1,s_get_b (2)); + s_put_b (1,graph_2); s_put_b (2,NULL); insert_basic_block (JSR_BLOCK,0,2+1,i_i_vector,div_label); @@ -2347,7 +2364,7 @@ void code_divR (VOID) #endif } -#if defined (I486) || defined (G_POWER) +#if defined (I486) || defined (ARM) || defined (G_POWER) void code_divU (VOID) { INSTRUCTION_GRAPH graph_1,graph_2,graph_3; @@ -2420,7 +2437,7 @@ void code_eqB_a (int value,int a_offset) graph_1=s_get_a (a_offset); graph_2=g_load_id (ARGUMENTS_OFFSET-NODE_POINTER_OFFSET,graph_1); -#ifdef I486 +#if defined (I486) || defined (ARM) graph_3=g_load_i (value); #else graph_3=g_load_i (-value); @@ -2435,7 +2452,7 @@ void code_eqB_b (int value,int b_offset) INSTRUCTION_GRAPH graph_1,graph_2,graph_3; graph_1=s_get_b (b_offset); -#ifdef I486 +#if defined (I486) || defined (ARM) graph_2=g_load_i (value); #else graph_2=g_load_i (-value); @@ -3490,7 +3507,7 @@ void code_fillB (int value,int a_offset) #endif graph_1=s_get_a (a_offset); -#ifdef I486 +#if defined (I486) || defined (ARM) graph_3=g_load_i (value); #else graph_3=g_load_i (-value); @@ -3791,7 +3808,7 @@ void code_fillcaf (char *label_name,int a_stack_size,int b_stack_size) } } -#ifdef I486 +#if defined (I486) || defined (ARM) void code_floordivI (VOID) { INSTRUCTION_GRAPH graph_1,graph_2,graph_3; @@ -3976,7 +3993,7 @@ void code_gtR (VOID) #endif } -#ifdef I486 +#if defined (I486) || defined (ARM) void code_gtU (VOID) { INSTRUCTION_GRAPH graph_1,graph_2,graph_3; @@ -4024,7 +4041,7 @@ void code_is_record (int a_offset) INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4,graph_5,graph_6,graph_7; graph_1=s_get_a (a_offset); -#if defined (sparc) || defined (I486) || defined (G_POWER) +#if defined (sparc) || defined (I486) || defined (ARM) || defined (G_POWER) graph_2=g_load_id (0,graph_1); graph_5=g_load_des_id (-2,graph_2); #else @@ -4107,7 +4124,7 @@ static void code_jmp_label (LABEL *label); static void code_jmp_ap_ (int n_apply_args) { if (n_apply_args==1){ -#if defined (I486) +#if defined (I486) || defined (ARM) end_basic_block_with_registers (2,0,e_vector); i_move_id_r (0,REGISTER_A1,REGISTER_A2); # ifdef PROFILE @@ -4341,7 +4358,7 @@ void code_jmp_ap (int n_apply_args) void code_jmp_ap_upd (int n_apply_args) { -#if defined (I486) && !defined (G_AI64) +#if (defined (I486) || defined (ARM)) && !defined (G_AI64) char apupd_label_name[32]; code_d (1+n_apply_args,0,e_vector); @@ -4376,7 +4393,7 @@ void code_jmp_eval (VOID) # else i_bne_l (label); # endif -# ifdef I486 +# if defined (I486) || defined (ARM) # ifdef PROFILE if (profile_function_label!=NULL) i_jmp_r_profile (REGISTER_D0); @@ -4442,7 +4459,7 @@ void code_jmp_eval_upd (VOID) # else i_bne_l (label); # endif -# ifdef I486 +# if defined (I486) || defined (ARM) i_sub_i_r (20,REGISTER_D0); # ifdef PROFILE if (profile_function_label!=NULL) @@ -4483,7 +4500,7 @@ void code_jmp_eval_upd (VOID) i_move_id_id (0,REGISTER_A1,8,REGISTER_A0); # else i_move_r_id (REGISTER_D0,0,REGISTER_A0); -# ifdef I486 +# if defined (I486) || defined (ARM) # ifndef THREAD32 i_move_id_id (STACK_ELEMENT_SIZE,REGISTER_A1,STACK_ELEMENT_SIZE,REGISTER_A0); i_move_id_id (2*STACK_ELEMENT_SIZE,REGISTER_A1,2*STACK_ELEMENT_SIZE,REGISTER_A0); @@ -4602,7 +4619,7 @@ void code_jmp_true (char label_name[]) #endif } -#if defined (M68000) || defined (I486) +#if defined (M68000) || defined (I486) || defined (ARM) static void define_label_in_block (LABEL *label_2) { struct block_label *new_label; @@ -4650,7 +4667,7 @@ static void code_jsr_ap_ (int n_apply_args) INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4,graph_5; if (n_apply_args==1){ -#if !defined (I486) +#if !(defined (I486) || defined (ARM)) graph_1=s_get_a (0); # if defined (sparc) || defined (G_POWER) # pragma unused (graph_3,graph_4) @@ -4674,7 +4691,7 @@ static void code_jsr_ap_ (int n_apply_args) offered_after_jsr=1; demand_flag=0; -#if defined (I486) +#if defined (I486) || defined (ARM) insert_basic_block (APPLY_BLOCK,2,0,e_vector,NULL); #else insert_basic_block (APPLY_BLOCK,3,0,e_vector,NULL); @@ -4698,7 +4715,7 @@ static void code_jsr_label (LABEL *label) { INSTRUCTION_GRAPH graph; int b_stack_size,n_data_parameter_registers; -#if defined (M68000) || defined (I486) +#if defined (M68000) || defined (I486) || defined (ARM) LABEL *label_2; #endif @@ -4734,7 +4751,7 @@ static void code_jsr_label (LABEL *label) insert_basic_block (JSR_BLOCK,demanded_a_stack_size,b_stack_size,demanded_vector,label); -#if defined (M68000) || defined (I486) +#if defined (M68000) || defined (I486) || defined (ARM) if (graph!=NULL) define_label_in_block (label_2); #endif @@ -4777,7 +4794,7 @@ void code_jsr_from_c_to_clean (char *label_name) LABEL *label; INSTRUCTION_GRAPH graph; int b_stack_size,n_data_parameter_registers; -#if defined (M68000) || defined (I486) +#if defined (M68000) || defined (I486) || defined (ARM) LABEL *label_2; #endif @@ -4812,7 +4829,7 @@ void code_jsr_from_c_to_clean (char *label_name) insert_basic_block (JSR_BLOCK_WITH_INSTRUCTIONS,demanded_a_stack_size,b_stack_size,demanded_vector,label); -#if defined (M68000) || defined (I486) +#if defined (M68000) || defined (I486) || defined (ARM) if (graph!=NULL) define_label_in_block (label_2); #endif @@ -4964,7 +4981,7 @@ void code_ltR (VOID) #endif } -#ifdef I486 +#if defined (I486) || defined (ARM) void code_ltU (VOID) { INSTRUCTION_GRAPH graph_1,graph_2,graph_3; @@ -5071,26 +5088,40 @@ void code_modI (VOID) void code_remI (VOID) { + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + + graph_2=s_get_b (1); + #ifdef M68000 if (!mc68000_flag){ #endif - INSTRUCTION_GRAPH graph_1,graph_2,graph_3; - +#ifdef ARM + if (graph_2->instruction_code==GLOAD_I && graph_2->instruction_parameters[0].i!=0){ +#endif graph_1=s_pop_b(); - graph_2=s_get_b (0); +#ifdef ARM + graph_2=g_load_i (graph_2->instruction_parameters[0].i); +#endif graph_3=g_rem (graph_2,graph_1); s_put_b (0,graph_3); +#ifdef ARM + return; + } +#endif #ifdef sparc if (dot_rem_label==NULL) dot_rem_label=enter_label (".rem",IMPORT_LABEL); #endif #ifdef M68000 - } else { + } else +#endif +#if defined (M68000) || defined (ARM) + { if (mod_label==NULL) mod_label=enter_label ("modulo",IMPORT_LABEL); s_push_b (s_get_b (0)); - s_put_b (1,s_get_b (2)); + s_put_b (1,graph_2); s_put_b (2,NULL); insert_basic_block (JSR_BLOCK,0,2+1,i_i_vector,mod_label); @@ -5100,7 +5131,7 @@ void code_remI (VOID) #endif } -#ifdef I486 +#if defined (I486) || defined (ARM) void code_remU (VOID) { INSTRUCTION_GRAPH graph_1,graph_2,graph_3; @@ -5206,11 +5237,11 @@ void code_mulI (VOID) #endif } -#if defined (I486) || defined (G_POWER) +#if defined (I486) || defined (ARM) || defined (G_POWER) void code_mulUUL (VOID) { INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4; -# ifdef I486 +# if defined (I486) || defined (ARM) INSTRUCTION_GRAPH graph_5; # endif @@ -5403,7 +5434,7 @@ void code_not (VOID) INSTRUCTION_GRAPH graph_1,graph_2,graph_3; graph_1=s_get_b (0); -#if defined (I486) || defined (G_POWER) +#if defined (I486) || defined (ARM) || defined (G_POWER) graph_3=g_not (graph_1); #else graph_2=g_load_i (-1); @@ -5632,7 +5663,7 @@ void code_pushcaf (char *label_name,int a_stack_size,int b_stack_size) n_arguments=a_stack_size+b_stack_size; -#ifndef I486 +#if! (defined (I486) || defined (ARM)) if (n_arguments>2 && n_arguments<8){ INSTRUCTION_GRAPH graph_2; @@ -5684,7 +5715,7 @@ void code_pushB (int b) { INSTRUCTION_GRAPH graph_1; -#ifdef I486 +#if defined (I486) || defined (ARM) graph_1=g_load_i (b); #else graph_1=g_load_i (-b); @@ -5808,7 +5839,7 @@ void code_pushLc (char *c_function_name) INSTRUCTION_GRAPH graph_1; LABEL *label; -#if (defined (sparc) && !defined (SOLARIS)) || (defined (I486) && !defined (G_AI64) && !defined (LINUX_ELF)) || (defined (G_POWER) && !defined (LINUX_ELF)) || defined (MACH_O) || defined (MACH_O64) +#if (defined (sparc) && !defined (SOLARIS)) || ((defined (I486) || defined (ARM)) && !defined (G_AI64) && !defined (LINUX_ELF)) || (defined (G_POWER) && !defined (LINUX_ELF)) || defined (MACH_O) char label_name [202]; # if defined (G_POWER) && !defined (MACH_O) @@ -5934,7 +5965,7 @@ void code_push_t_r_a (int a_offset) INSTRUCTION_GRAPH graph_1,graph_2,graph_3; graph_1=s_get_a (a_offset); -#if defined (sparc) || defined (I486) || defined (G_POWER) +#if defined (sparc) || defined (I486) || defined (ARM) || defined (G_POWER) graph_2=g_load_id (0,graph_1); graph_3=g_add (g_load_i (2),graph_2); #else @@ -6026,7 +6057,7 @@ void code_push_args (int a_offset,int arity,int n_arguments) graph_4=g_load_id (0-NODE_POINTER_OFFSET,graph_3); s_push_a (graph_4); } else { -#ifndef I486 +#if ! (defined (I486) || defined (ARM)) if (n_arguments>=8){ #endif while (n_arguments!=0){ @@ -6038,7 +6069,7 @@ void code_push_args (int a_offset,int arity,int n_arguments) s_push_a (graph_5); } -#ifndef I486 +#if ! (defined (I486) || defined (ARM)) } else { graph_4=g_movem (0-NODE_POINTER_OFFSET,graph_3,n_arguments); while (n_arguments!=0){ @@ -6309,7 +6340,7 @@ void code_push_node (char *label_name,int n_arguments) if (n_arguments!=0){ if (n_arguments!=1){ int argument_n; -#ifdef I486 +#if defined (I486) || defined (ARM) argument_n=n_arguments; while (argument_n!=0){ graph_5=g_load_id ((argument_n<<STACK_ELEMENT_LOG_SIZE)-NODE_POINTER_OFFSET,graph_1); @@ -6385,7 +6416,7 @@ void code_push_node_u (char *label_name,int a_size,int b_size) if (a_size+b_size!=0){ if (a_size+b_size!=1){ int argument_n; -#ifdef I486 +#if defined (I486) || defined (ARM) argument_n=a_size+b_size; while (argument_n!=0){ graph_5=g_load_id ((argument_n<<(STACK_ELEMENT_LOG_SIZE))-NODE_POINTER_OFFSET,graph_1); @@ -6738,7 +6769,7 @@ static void code_replaceI (VOID) if (check_index_flag) graph_2=g_bounds (graph_1,graph_2); -#if defined (M68000) || defined (I486) +#if defined (M68000) || defined (I486) || defined (ARM) # ifdef M68000 if (mc68000_flag){ graph_2=g_lsl (g_load_i (2),graph_2); @@ -6842,7 +6873,7 @@ static void code_replaceBC (int offset,int ext_signed) if (check_index_flag) graph_2=g_bounds (graph_1,graph_2); -#if defined (M68000) || defined (I486) +#if defined (M68000) || defined (I486) || defined (ARM) { int new_offset; @@ -6881,7 +6912,7 @@ static void code_lazy_replace (VOID) if (check_index_flag) graph_3=g_bounds (graph_1,graph_3); -#if defined (M68000) || defined (I486) +#if defined (M68000) || defined (I486) || defined (ARM) # ifdef M68000 if (mc68000_flag){ graph_3=g_lsl (g_load_i (2),graph_3); @@ -6966,7 +6997,7 @@ static void code_replaceR (VOID) graph_4=g_fload_x (graph_1,offset,0,NULL); graph_8=g_fstore_x (graph_7,graph_1,offset,0,NULL); } else { -#if defined (M68000) || defined (I486) +#if defined (M68000) || defined (I486) || defined (ARM) int offset; graph_2=optimize_array_index (ARRAY_ELEMENTS_OFFSET,3,graph_2,&offset); @@ -7003,7 +7034,7 @@ static void code_replaceR (VOID) s_push_b (graph_9); } -#ifdef I486 +#if defined (I486) || defined (ARM) static void code_replaceR32 (VOID) { INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4,graph_7,graph_8,graph_9,graph_10; @@ -7196,7 +7227,7 @@ void code_replace (char element_descriptor[],int a_size,int b_size) code_replaceR(); return; } -#ifdef I486 +#if defined (I486) || defined (ARM) if (element_descriptor[4]=='3' && element_descriptor[5]=='2' && element_descriptor[6]=='\0'){ code_replaceR32(); return; @@ -7279,7 +7310,7 @@ void code_repl_args (int arity,int n_arguments) graph_4=g_load_id (0-NODE_POINTER_OFFSET,graph_3); s_push_a (graph_4); } else { -#ifndef I486 +#if ! (defined (I486) || defined (ARM)) if (n_arguments>=8){ #endif while (n_arguments!=0){ @@ -7290,7 +7321,7 @@ void code_repl_args (int arity,int n_arguments) graph_5=g_load_id ((n_arguments<<STACK_ELEMENT_LOG_SIZE)-NODE_POINTER_OFFSET,graph_3); s_push_a (graph_5); } -#ifndef I486 +#if ! (defined (I486) || defined (ARM)) } else { graph_4=g_movem (0-NODE_POINTER_OFFSET,graph_3,n_arguments); @@ -7450,7 +7481,7 @@ void code_rtn (void) if (n_data_registers>n_data_parameter_registers || n_float_registers>n_float_parameter_registers){ INSTRUCTION_GRAPH graph; -#ifndef I486 +#if ! (defined (I486) || defined (ARM)) graph=s_get_b (b_stack_size); for (offset=b_stack_size-1; offset>=0; --offset) s_put_b (offset+1,s_get_b (offset)); @@ -7512,11 +7543,11 @@ void code_rtn (void) } } -#ifndef I486 +#if ! (defined (I486) || defined (ARM)) if (return_with_rts){ #endif -#ifdef I486 +#if defined (I486) || defined (ARM) b_offset+= end_basic_block_with_registers_and_return_address_and_return_b_stack_offset (a_stack_size,b_stack_size,local_demanded_vector,n_data_parameter_registers); @@ -7547,7 +7578,7 @@ void code_rtn (void) # endif i_rts (b_offset-4,b_offset); #endif -#ifndef I486 +#if ! (defined (I486) || defined (ARM)) } else { b_offset+= end_basic_block_with_registers_and_return_b_stack_offset @@ -7593,7 +7624,7 @@ void code_RtoI (VOID) { INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4; -#if defined (G_POWER) || defined (I486) +#if defined (G_POWER) || defined (I486) || defined (ARM) # ifdef G_POWER if (r_to_i_buffer_label==NULL) r_to_i_buffer_label=enter_label ("r_to_i_buffer",IMPORT_LABEL); @@ -7647,7 +7678,7 @@ static void code_lazy_select (VOID) if (check_index_flag) graph_2=g_bounds (graph_1,graph_2); -#if defined (M68000) || defined (I486) +#if defined (M68000) || defined (I486) || defined (ARM) # ifdef M68000 if (mc68000_flag){ graph_2=g_lsl (g_load_i (2),graph_2); @@ -7684,7 +7715,7 @@ static void code_selectBC (int offset,int ext_signed) if (check_index_flag) graph_2=g_bounds (graph_1,graph_2); -#if defined (M68000) || defined (I486) +#if defined (M68000) || defined (I486) || defined (ARM) { int new_offset; @@ -7730,7 +7761,7 @@ static void code_selectI (VOID) if (check_index_flag) graph_2=g_bounds (graph_1,graph_2); -#if defined (M68000) || defined (I486) +#if defined (M68000) || defined (I486) || defined (ARM) # ifdef M68000 if (mc68000_flag){ graph_2=g_lsl (g_load_i (2),graph_2); @@ -7819,7 +7850,7 @@ static void code_selectR (VOID) { graph_4=g_fload_x (graph_1,REAL_ARRAY_ELEMENTS_OFFSET+(graph_2->instruction_parameters[0].i<<3),0,NULL); } else { -#if defined (M68000) || defined (I486) +#if defined (M68000) || defined (I486) || defined (ARM) int offset; graph_2=optimize_array_index (REAL_ARRAY_ELEMENTS_OFFSET,3,graph_2,&offset); @@ -7850,7 +7881,7 @@ static void code_selectR (VOID) s_push_b (graph_5); } -#ifdef I486 +#if defined (I486) || defined (ARM) static void code_selectR32 (VOID) { INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4,graph_5,graph_6; @@ -7981,7 +8012,7 @@ void code_select (char element_descriptor[],int a_size,int b_size) code_selectR(); return; } -#ifdef I486 +#if defined (I486) || defined (ARM) if (element_descriptor[4]=='3' && element_descriptor[5]=='2' && element_descriptor[6]=='\0'){ code_selectR32(); return; @@ -8270,7 +8301,7 @@ void code_subI (VOID) s_put_b (0,graph_3); } -#ifdef I486 +#if defined (I486) || defined (ARM) void code_subLU (VOID) { INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4,graph_5,graph_6; @@ -8444,7 +8475,7 @@ static void code_lazy_update (VOID) if (check_index_flag) graph_3=g_bounds (graph_1,graph_3); -#if defined (M68000) || defined (I486) +#if defined (M68000) || defined (I486) || defined (ARM) # ifdef M68000 if (mc68000_flag){ graph_3=g_lsl (g_load_i (2),graph_3); @@ -8482,7 +8513,7 @@ static void code_updateBC (int offset) if (check_index_flag) graph_2=g_bounds (graph_1,graph_2); -#if defined (M68000) || defined (I486) +#if defined (M68000) || defined (I486) || defined (ARM) { int new_offset; @@ -8526,7 +8557,7 @@ static void code_updateI (VOID) if (check_index_flag) graph_2=g_bounds (graph_1,graph_2); -#if defined (M68000) || defined (I486) +#if defined (M68000) || defined (I486) || defined (ARM) # ifdef M68000 if (mc68000_flag){ graph_2=g_lsl (g_load_i (2),graph_2); @@ -8624,7 +8655,7 @@ static void code_updateR (VOID) { graph_8=g_fstore_x (graph_7,graph_1,REAL_ARRAY_ELEMENTS_OFFSET+(graph_2->instruction_parameters[0].i<<3),0,NULL); } else { -#if defined (M68000) || defined (I486) +#if defined (M68000) || defined (I486) || defined (ARM) int offset; graph_2=optimize_array_index (REAL_ARRAY_ELEMENTS_OFFSET,3,graph_2,&offset); @@ -8646,7 +8677,7 @@ static void code_updateR (VOID) s_put_a (0,graph_8); } -#ifdef I486 +#if defined (I486) || defined (ARM) static void code_updateR32 (VOID) { INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4,graph_7,graph_8; @@ -8867,7 +8898,7 @@ void code_update (char element_descriptor[],int a_size,int b_size) code_updateR(); return; } -#ifdef I486 +#if defined (I486) || defined (ARM) if (element_descriptor[4]=='3' && element_descriptor[5]=='2' && element_descriptor[6]=='\0'){ code_updateR32(); return; @@ -9002,7 +9033,7 @@ void code_caf (char *label_name,int a_stack_size,int b_stack_size) void code_comp (int version,char *options) { -#if defined (G_POWER) || defined (I486) +#if defined (G_POWER) || defined (I486) || defined (ARM) int l; l=strlen (options); @@ -9227,14 +9258,14 @@ static void code_descriptor (char label_name[],char node_entry_label_name[],char #ifndef NEW_DESCRIPTORS # ifdef GEN_OBJ -# ifdef I486 +# if defined (I486) || defined (ARM) store_long_word_in_data_section ((arity<<16) | lazy_record_flag); # else store_2_words_in_data_section (lazy_record_flag,arity); # endif # endif if (assembly_flag){ -# if defined (sparc) || defined (I486) || defined (G_POWER) +# if defined (sparc) || defined (I486) || defined (ARM) || defined (G_POWER) w_as_word_in_data_section (lazy_record_flag); # endif w_as_word_in_data_section (arity); @@ -10530,8 +10561,11 @@ void initialize_coding (VOID) eval_22_label=enter_label ("eval_22",IMPORT_LABEL); #endif +#if defined (M68000) || defined (ARM) + div_label=mod_label=NULL; +#endif #ifdef M68000 - div_label=mod_label=mul_label=NULL; + mul_label=NULL; #endif first_dependency=NULL; @@ -59,7 +59,7 @@ extern LABEL *eval_01_label,*eval_11_label,*eval_02_label,*eval_12_label,*eval_22_label, #endif *EMPTY_label; -#if defined (G_POWER) || defined (I486) +#if defined (G_POWER) || defined (I486) || defined (ARM) extern LABEL *profile_l_label,*profile_l2_label,*profile_n_label,*profile_n2_label, *profile_s_label,*profile_s2_label,*profile_r_label,*profile_t_label; @@ -19,7 +19,7 @@ void code_absR (void); void code_acosR (VOID); void code_add_args (int source_offset,int n_arguments,int destination_offset); void code_addI (VOID); -#ifdef I486 +#if defined (I486) || defined (ARM) void code_addLU (VOID); #endif #ifndef M68000 @@ -71,7 +71,7 @@ void code_divI (VOID); void code_divLU (VOID); #endif void code_divR (VOID); -#if defined (I486) || defined (G_POWER) +#if defined (I486) || defined (ARM) || defined (G_POWER) void code_divU (VOID); #endif void code_entierR (VOID); @@ -119,7 +119,7 @@ void code_fillI_b (int b_offset,int a_offset); void code_fillR (double value,int a_offset); void code_fillR_b (int b_offset,int a_offset); void code_fill_a (int from_offset,int to_offset); -#ifdef I486 +#if defined (I486) || defined (ARM) void code_floordivI (VOID); #endif void code_get_desc_arity (int a_offset); @@ -129,7 +129,7 @@ void code_get_desc_flags_b (void); void code_gtC (VOID); void code_gtI (VOID); void code_gtR (VOID); -#ifdef I486 +#if defined (I486) || defined (ARM) void code_gtU (VOID); #endif void code_halt (VOID); @@ -164,12 +164,12 @@ void code_log10R (VOID); void code_ltC (VOID); void code_ltI (VOID); void code_ltR (VOID); -#ifdef I486 +#if defined (I486) || defined (ARM) void code_ltU (VOID); void code_modI (VOID); #endif void code_remI (VOID); -#ifdef I486 +#if defined (I486) || defined (ARM) void code_remU (VOID); #endif void code_mulI (VOID); @@ -177,7 +177,7 @@ void code_mulI (VOID); void code_mulIo (VOID); #endif void code_mulR (VOID); -#if defined (I486) || defined (G_POWER) +#if defined (I486) || defined (ARM) || defined (G_POWER) void code_mulUUL (VOID); #endif void code_negI (void); @@ -258,7 +258,7 @@ void code_replace (char element_descriptor[],int a_size,int b_size); void code_repl_arg (int arity,int argument_n); void code_repl_args (int arity,int n_arguments); void code_repl_args_b (VOID); -#ifdef I486 +#if defined (I486) || defined (ARM) void code_rotl (void); void code_rotr (void); #endif @@ -284,7 +284,7 @@ void code_sliceS (int source_offset,int destination_offset); void code_sqrtR (VOID); void code_stop_reducer (VOID); void code_subI (VOID); -#ifdef I486 +#if defined (I486) || defined (ARM) void code_subLU (VOID); #endif #ifndef M68000 @@ -14,7 +14,7 @@ enum { GMUL, GMUL_O, GNEG, GOR, GREGISTER, GSTORE, GSTORE_R, GSTORE_B_X, GSTORE_X, GSUB, GSUB_O, GTEST_O, GEXIT_IF -#if defined (I486) || defined (G_POWER) +#if defined (I486) || defined (ARM) || defined (G_POWER) ,GNOT #endif #ifndef G_A64 @@ -25,14 +25,17 @@ enum { #ifdef G_POWER ,GCREATE_S, GUMULH #endif -#if defined (I486) || defined (G_POWER) +#if defined (I486) || defined (ARM) || defined (G_POWER) ,GDIVU #endif -#ifdef I486 +#if defined (I486) || defined (ARM) ,GFLOORDIV, GMOD, GROTL, GROTR - ,GADDDU, GDIVDU, GMULUD, GREMU, GRESULT0, GRESULT1, GSUBDU + ,GADDDU, GMULUD, GREMU, GRESULT0, GRESULT1, GSUBDU ,GFLOAD_S_X,GFSTORE_S_X #endif +#ifdef I486 + ,GDIVDU +#endif #if defined (I486) && !defined (G_A64) ,GFSINCOS, GFRESULT0, GFRESULT1 #endif @@ -12,25 +12,34 @@ enum { IADD, IAND, IASR, IBEQ, IBGE, IBGEU, IBGT, IBGTU, IBLE, IBLEU, IBLT, IBLTU, IBNE, IBNO, - IBO, ICMP, IDIV, IEOR, IEXG, IEXT, IFADD, + IBO, ICMP, IDIV, IEOR, +#ifndef ARM + IEXG, +#endif + IEXT, IFADD, #if ! (defined (I486) && !defined (G_A64)) IFBEQ, IFBGE, IFBGT, IFBLE, IFBLT, IFBNE, #endif - IFABS, - IFCMP, IFCOS, IFDIV, IFMUL, IFNEG, IFREM, IFSEQ, - IFSGE, IFSGT, IFSIN, IFSLE, IFSLT, IFSNE, IFSUB, + IFABS, IFCMP, IFDIV, IFMUL, IFNEG, IFREM, + IFSEQ, IFSGE, IFSGT, IFSLE, IFSLT, IFSNE, IFSUB, IFTAN, IFTST, IFMOVE, IFMOVEL, IJMP, IJSR, ILEA, ILSL, ILSR, IREM, IMOVE, IMOVEB, IMOVEDB, IMUL, INEG, IOR, IRTS, ISCHEDULE, ISEQ, ISGE, ISGEU, ISGT, ISGTU, ISLE, ISLEU, ISLT, ISLTU, ISNE, ISNO, ISO, ISUB, ITST, IWORD +#ifndef ARM + ,IFCOS, IFSIN +#endif #if !defined (G_POWER) ,IFSQRT #endif #ifdef M68000 ,ICMPW - ,IFACOS, IFASIN, IFATAN, IFEXP, IFLN, IFLOG10, - IBMI, IBMOVE, IMOVEM, ITSTB + ,IFACOS, IFASIN, IFATAN, IFEXP, IFLN, IFLOG10 + ,IBMI, IBMOVE, ITSTB +#endif +#if defined (M68000) || defined (ARM) + ,IMOVEM #endif #if defined (M68000) || defined (G_POWER) ,IEXTB @@ -44,13 +53,16 @@ enum { #ifdef G_POWER ,IBNEP,IMTCTR #endif -#if defined (G_POWER) || defined (sparc) +#if defined (G_POWER) || defined (sparc) || defined (ARM) ,IADDI, ILSLI ,IADDO, ISUBO #endif #ifdef I486 ,IASR_S,ILSL_S,ILSR_S - ,IROTL,IROTR,IROTL_S,IROTR_S + ,IROTL,IROTL_S,IROTR_S +#endif +#if defined (I486) || defined (ARM) + ,IROTR #endif #if defined (I486) && !defined (G_A64) ,IFCEQ, IFCGE, IFCGT, IFCLE, IFCLT, IFCNE @@ -60,18 +72,26 @@ enum { ,ICMPLW ,IMULO #endif -#if defined (G_POWER) || defined (I486) +#if defined (G_POWER) || defined (I486) || defined (ARM) ,IJMPP ,IRTSP, INOT #endif #if defined (I486) && defined (FP_STACK_OPTIMIZATIONS) ,IFEXG #endif +#if defined (I486) || defined (ARM) + ,IADC ,ISBB +#endif #if defined (I486) - ,IADC ,ISBB, IRTSI - ,IDIVI, IREMI, IREMU, IFLOORDIV, IMOD, IMULUD, IDIVDU + ,IRTSI +#endif +#if defined (I486) || defined (ARM) + ,IDIVI, IREMI, IREMU, IFLOORDIV, IMOD, IMULUD ,IFLOADS, IFMOVES #endif -#if defined (I486) || defined (G_POWER) +#if defined (I486) + ,IDIVDU +#endif +#if defined (I486) || defined (ARM) || defined (G_POWER) ,IDIVU #endif #ifdef G_POWER @@ -88,10 +108,16 @@ enum { enum { P_REGISTER, P_LABEL, P_DESCRIPTOR_NUMBER, P_INDIRECT, P_IMMEDIATE, P_F_IMMEDIATE, P_F_REGISTER, P_INDEXED -#if defined (M68000) || defined (I486) +#if defined (M68000) || defined (I486) || defined (ARM) ,P_POST_INCREMENT, P_PRE_DECREMENT #endif +#if defined (G_POWER) || defined (ARM) + ,P_INDIRECT_WITH_UPDATE +#endif #if defined (G_POWER) - ,P_INDIRECT_WITH_UPDATE, P_INDIRECT_HP, P_STORE_HP_INSTRUCTION + ,P_INDIRECT_HP, P_STORE_HP_INSTRUCTION +#endif +#if defined (ARM) + ,P_INDIRECT_POST_ADD #endif }; @@ -2299,7 +2299,7 @@ static void put_instructions_in_table (void) put_instruction_name ("acosR", parse_instruction, code_acosR ); put_instruction_name ("add_args", parse_instruction_n_n_n, code_add_args ); put_instruction_name ("addI", parse_instruction, code_addI ); -#ifdef I486 +#if defined (I486) || defined (ARM) put_instruction_name ("addLU", parse_instruction, code_addLU ); #endif put_instruction_name ("addR", parse_instruction, code_addR ); @@ -2346,7 +2346,7 @@ static void put_instructions_in_table (void) put_instruction_name ("divLU", parse_instruction, code_divLU ); #endif put_instruction_name ("divR", parse_instruction, code_divR ); -#if defined (I486) || defined (G_POWER) +#if defined (I486) || defined (ARM) || defined (G_POWER) put_instruction_name ("divU", parse_instruction, code_divU ); #endif put_instruction_name ("entierR", parse_instruction, code_entierR ); @@ -2393,7 +2393,7 @@ static void put_instructions_in_table (void) put_instruction_name ("fillR_b", parse_instruction_n_n, code_fillR_b ); put_instruction_name ("fill_a", parse_instruction_n_n, code_fill_a ); put_instruction_name ("fill_r", parse_instruction_a_n_n_n_n_n, code_fill_r ); -#ifdef I486 +#if defined (I486) || defined (ARM) put_instruction_name ("floordivI", parse_instruction, code_floordivI ); #endif put_instruction_name ("getWL", parse_instruction_n, code_dummy ); @@ -2404,13 +2404,13 @@ static void put_instructions_in_table (void) put_instruction_name ("gtC", parse_instruction, code_gtC ); put_instruction_name ("gtI", parse_instruction, code_gtI ); put_instruction_name ("gtR", parse_instruction, code_gtR ); -#ifdef I486 +#if defined (I486) || defined (ARM) put_instruction_name ("gtU", parse_instruction, code_gtU ); #endif put_instruction_name ("halt", parse_instruction, code_halt ); put_instruction_name ("in", parse_instruction_in_or_out, code_in ); put_instruction_name ("incI", parse_instruction, code_incI ); -#if defined (I486) || defined (sparc) +#if defined (I486) || defined (ARM) || defined (sparc) put_instruction_name ("instruction", parse_instruction_i, code_instruction ); #else put_instruction_name ("instruction", parse_instruction_x, code_instruction ); @@ -2443,13 +2443,13 @@ static void put_instructions_in_table (void) put_instruction_name ("ltC", parse_instruction, code_ltC ); put_instruction_name ("ltI", parse_instruction, code_ltI ); put_instruction_name ("ltR", parse_instruction, code_ltR ); -#ifdef I486 +#if defined (I486) || defined (ARM) put_instruction_name ("ltU", parse_instruction, code_ltU ); put_instruction_name ("modI", parse_instruction, code_modI ); #endif put_instruction_name ("mulI", parse_instruction, code_mulI ); put_instruction_name ("mulR", parse_instruction, code_mulR ); -#if defined (I486) || defined (G_POWER) +#if defined (I486) || defined (ARM) || defined (G_POWER) put_instruction_name ("mulUUL", parse_instruction, code_mulUUL ); #endif put_instruction_name ("negI", parse_instruction, code_negI ); @@ -2531,7 +2531,7 @@ static void put_instructions_in_table2 (void) put_instruction_name ("randomP", parse_instruction, code_randomP ); put_instruction_name ("release", parse_instruction, code_release ); put_instruction_name ("remI", parse_instruction, code_remI ); -#ifdef I486 +#if defined (I486) || defined (ARM) put_instruction_name ("remU", parse_instruction, code_remU ); #endif put_instruction_name ("replace", parse_instruction_a_n_n, code_replace ); @@ -2567,7 +2567,7 @@ static void put_instructions_in_table2 (void) put_instruction_name ("sqrtR", parse_instruction, code_sqrtR ); put_instruction_name ("stop_reducer", parse_instruction, code_stop_reducer ); put_instruction_name ("subI", parse_instruction, code_subI ); -#ifdef I486 +#if defined (I486) || defined (ARM) put_instruction_name ("subLU", parse_instruction, code_subLU ); #endif #ifndef M68000 diff --git a/cginstructions.c b/cginstructions.c index 25ea347..6aa80bf 100644 --- a/cginstructions.c +++ b/cginstructions.c @@ -24,18 +24,17 @@ #ifdef G_POWER # include "cgpas.h" # include "cgpwas.h" -#else -# ifdef I486 +#elif defined (I486) # include "cgias.h" # include "cgiwas.h" -# else -# ifdef SOLARIS +#elif defined (ARM) +# include "cgarmas.h" +# include "cgarmwas.h" +#elif defined (SOLARIS) # include "cgswas.h" -# else +#else # include "cgas.h" # include "cgwas.h" -# endif -# endif #endif #if defined (THREAD32) || defined (THREAD64) # include "cgiconst.h" @@ -58,7 +57,7 @@ extern LABEL * system_sp_label, *string_to_string_node_label,*int_array_to_node_label,*real_array_to_node_label, *new_int_reducer_label,*channelP_label,*stop_reducer_label,*send_request_label,*send_graph_label; -#if (defined (I486) && !defined (THREAD64)) || defined (G_POWER) +#if ((defined (I486) || defined (ARM)) && !defined (THREAD64)) || defined (G_POWER) LABEL *saved_heap_p_label,*saved_a_stack_p_label; #endif #ifdef MACH_O @@ -70,7 +69,11 @@ LABEL *tlsp_tls_index_label; extern struct basic_block *last_block; -extern ULONG e_vector[],i_vector[],i_i_vector[],i_i_i_vector[],r_vector[]; +extern ULONG e_vector[],i_vector[],i_i_vector[],i_i_i_vector[], +#ifdef ARM + i_i_i_i_i_vector[], +#endif + r_vector[]; extern int reachable; extern int line_number; /* from cginput.c */ @@ -671,7 +674,7 @@ INSTRUCTION_GRAPH g_fload_x (INSTRUCTION_GRAPH graph_1,int offset,int shift,INST return instruction; } -#ifdef I486 +#if defined (I486) || defined (ARM) INSTRUCTION_GRAPH g_fload_s_x (INSTRUCTION_GRAPH graph_1,int offset,int shift,INSTRUCTION_GRAPH graph_2) { INSTRUCTION_GRAPH instruction; @@ -862,7 +865,7 @@ INSTRUCTION_GRAPH g_load_des_i (LABEL *descriptor_label,int arity) instruction=g_new_node (GLOAD_DES_I,0,2*sizeof (union instruction_parameter)); instruction->instruction_parameters[0].l=descriptor_label; -#ifdef I486 +#if defined (I486) || defined (ARM) # ifdef MACH_O64 instruction->instruction_parameters[1].i=(arity<<4)+2; # else @@ -994,7 +997,7 @@ INSTRUCTION_GRAPH g_fstore_x (INSTRUCTION_GRAPH graph_1,INSTRUCTION_GRAPH graph_ return instruction; } -#ifdef I486 +#if defined (I486) || defined (ARM) INSTRUCTION_GRAPH g_fstore_s_x (INSTRUCTION_GRAPH graph_1,INSTRUCTION_GRAPH graph_2,int offset,int shift,INSTRUCTION_GRAPH graph_3) { INSTRUCTION_GRAPH instruction; @@ -1581,7 +1584,7 @@ void code_push_args_u (int a_offset,int arity,int n_arguments) *--graph_p=graph_4; s_push_a (graph_4); } else { -#ifndef I486 +#if ! (defined (I486) || defined (ARM)) if (n_arguments>=8){ #endif while (n_arguments!=0){ @@ -1593,7 +1596,7 @@ void code_push_args_u (int a_offset,int arity,int n_arguments) *--graph_p=graph_5; s_push_a (graph_5); } -#ifndef I486 +#if ! (defined (I486) || defined (ARM)) } else { graph_4=g_movem (0-NODE_POINTER_OFFSET,graph_3,n_arguments); while (n_arguments!=0){ @@ -3637,7 +3640,7 @@ static void push_extra_clean_b_register_parameters (int n_extra_clean_b_register #endif } -#if (defined (sparc) && !defined (SOLARIS)) || (defined (I486) && !defined (LINUX_ELF) && !defined (G_AI64)) || (defined (G_POWER) && !defined (LINUX_ELF)) || defined (MACH_O) || defined (MACH_O64) +#if (defined (sparc) && !defined (SOLARIS)) || ((defined (I486) || defined (ARM)) && !defined (LINUX_ELF) && !defined (G_AI64)) || (defined (G_POWER) && !defined (LINUX_ELF)) || defined (MACH_O) || defined (MACH_O64) static LABEL *enter_c_function_name_label (char *c_function_name) { char label_name [202]; @@ -3729,21 +3732,18 @@ void code_ccall (char *c_function_name,char *s,int length) int first_pointer_result_index,callee_pops_arguments,save_state_in_global_variables; int function_address_parameter; int n_a_c_in_clean_out_parameters_size,n_b_c_in_clean_out_parameters_size; + int c_offset; -#if defined (sparc) || defined (G_POWER) - int c_parameter_n; -# ifdef G_POWER - int c_offset; -# endif -#elif defined (I486) - int c_offset; -#else - error ("ABC instruction 'ccall' not implemented"); +#if ! (defined (sparc) || defined (G_POWER) || defined (I486) || defined (ARM)) + error ("ABC instruction 'ccall' not implemented"); +#endif +#if defined (sparc) || defined (G_POWER) || defined (ARM) + int c_parameter_n; #endif #if defined (G_POWER) || (defined (G_A64) && (defined (LINUX_ELF) || defined (MACH_O64))) - int c_fp_parameter_n; - - c_fp_parameter_n=0; + int c_fp_parameter_n; + + c_fp_parameter_n=0; #endif function_address_parameter=0; @@ -3752,7 +3752,7 @@ void code_ccall (char *c_function_name,char *s,int length) ++s; --length; save_state_in_global_variables=1; -#if (defined (I486) && !defined (THREAD64)) || defined (G_POWER) +#if ((defined (I486) || defined (ARM)) && !defined (THREAD64)) || defined (G_POWER) if (saved_heap_p_label==NULL) saved_heap_p_label=enter_label ("saved_heap_p",IMPORT_LABEL); if (saved_a_stack_p_label==NULL) @@ -3772,7 +3772,7 @@ void code_ccall (char *c_function_name,char *s,int length) } else callee_pops_arguments=0; -#if defined (sparc) || defined (I486) || defined (G_POWER) +#if defined (sparc) || defined (I486) || defined (G_POWER) || defined (ARM) float_parameters=0; a_offset=0; @@ -3792,14 +3792,14 @@ void code_ccall (char *c_function_name,char *s,int length) b_offset+=STACK_ELEMENT_SIZE; if (!float_parameters) ++n_clean_b_register_parameters; -#if defined (I486) && !defined (G_AI64) +# if (defined (I486) || defined (ARM)) && !defined (G_AI64) if (s[l+1]=='>'){ ++l; n_b_c_in_clean_out_parameters_size+=STACK_ELEMENT_SIZE; } -#endif +# endif continue; -# if defined (I486) || defined (G_POWER) +# if defined (I486) || defined (ARM) || defined (G_POWER) case 'r': # endif case 'R': @@ -3813,12 +3813,12 @@ void code_ccall (char *c_function_name,char *s,int length) case 's': case 'A': a_offset+=STACK_ELEMENT_SIZE; -#if defined (I486) && !defined (G_AI64) +# if (defined (I486) || defined (ARM)) && !defined (G_AI64) if (s[l+1]=='>'){ ++l; n_a_c_in_clean_out_parameters_size+=STACK_ELEMENT_SIZE; } -#endif +# endif continue; case 'O': case 'F': @@ -4638,7 +4638,7 @@ void code_ccall (char *c_function_name,char *s,int length) c_offset_before_pushing_arguments=c_offset; - n_c_parameters=((a_offset+b_offset+a_result_offset+b_result_offset)>>3)+n_clean_b_register_parameters; + n_c_parameters=((a_offset+b_offset+a_result_offset+b_result_offset)>>STACK_ELEMENT_LOG_SIZE)+n_clean_b_register_parameters; used_clean_b_parameter_registers = ((1<<n_clean_b_register_parameters)-1)<<n_extra_clean_b_register_parameters; c_parameter_n=n_c_parameters; n_c_fp_register_parameters = c_fp_parameter_n<=8 ? c_fp_parameter_n : 8; @@ -5088,7 +5088,7 @@ void code_ccall (char *c_function_name,char *s,int length) c_offset_before_pushing_arguments=c_offset; - c_parameter_n=((a_offset+b_offset+a_result_offset+b_result_offset)>>3)+n_clean_b_register_parameters; + c_parameter_n=((a_offset+b_offset+a_result_offset+b_result_offset)>>STACK_ELEMENT_LOG_SIZE)+n_clean_b_register_parameters; i_move_r_r (B_STACK_POINTER,REGISTER_RBP); # ifdef THREAD64 @@ -5460,6 +5460,281 @@ void code_ccall (char *c_function_name,char *s,int length) error_s (ccall_error_string,c_function_name); } # endif + +#elif defined (ARM) + + { + int c_offset_before_pushing_arguments,function_address_reg,c_parameter_n; + + a_o=-b_result_offset-a_result_offset; + b_o=0; + + if (a_result_offset+b_result_offset>b_offset){ + i_sub_i_r (a_result_offset+b_result_offset-b_offset,B_STACK_POINTER); + c_offset=a_result_offset+b_result_offset; + } + + c_offset_before_pushing_arguments=c_offset; + + c_parameter_n=((a_offset+b_offset+a_result_offset+b_result_offset)>>STACK_ELEMENT_LOG_SIZE)+n_clean_b_register_parameters; + + i_move_r_r (B_STACK_POINTER,REGISTER_A2); + + if (c_parameter_n>=4 && (c_parameter_n & 1)!=0){ + i_sub_i_r (4,B_STACK_POINTER); + i_or_i_r (4,B_STACK_POINTER); + } else { + i_and_i_r (-8,B_STACK_POINTER); + } + + for (l=length-1; l>=first_pointer_result_index; --l){ + switch (s[l]){ + case 'I': + case 'p': + b_o-=STACK_ELEMENT_SIZE; + if (--c_parameter_n<4) + i_lea_id_r (b_o+c_offset_before_pushing_arguments,REGISTER_A2,REGISTER_D4-c_parameter_n); + else { + i_lea_id_r (b_o+c_offset_before_pushing_arguments,REGISTER_A2,REGISTER_A3); + i_move_r_pd (REGISTER_A3,B_STACK_POINTER); + c_offset+=STACK_ELEMENT_SIZE; + } + break; + case 'i': + case 'r': + --l; + case 'S': + if (--c_parameter_n<4) + i_lea_id_r (a_o+c_offset_before_pushing_arguments,REGISTER_A2,REGISTER_D4-c_parameter_n); + else { + i_lea_id_r (a_o+c_offset_before_pushing_arguments,REGISTER_A2,REGISTER_A3); + i_move_r_pd (REGISTER_A3,B_STACK_POINTER); + c_offset+=STACK_ELEMENT_SIZE; + } + a_o+=STACK_ELEMENT_SIZE; + break; + case 'V': + break; + default: + error_s (ccall_error_string,c_function_name); + } + } + + { + int last_register_parameter_index,reg_n,c_offset_1; + + last_register_parameter_index=-1; + + reg_n=0; + l=0; + while (reg_n<n_clean_b_register_parameters && l<min_index){ + if (s[l]=='I' || s[l]=='p' || s[l]=='F' || s[l]=='O'){ + ++reg_n; + last_register_parameter_index=l; + } + ++l; + } + + c_offset_1=0; + + { + int c_parameter_n_1,l; + + c_parameter_n_1 = c_parameter_n; + for (l=min_index-1; l>=0; --l){ + switch (s[l]){ + case 'I': + case 'p': + case 'S': + case 's': + if (--c_parameter_n_1>=4) + c_offset_1+=STACK_ELEMENT_SIZE; + break; + } + } + + if (c_offset_1!=0){ + i_sub_i_r (c_offset_1,B_STACK_POINTER); + c_offset += c_offset_1; + } + } + + { + int c_parameter_n_2,l,c_offset_2,not_finished,new_reg[5]; + + new_reg[0]=new_reg[1]=new_reg[2]=new_reg[3]=new_reg[4]=-1; /* [0] not used */ + + c_offset_2 = c_offset_1; + c_parameter_n_2 = c_parameter_n; + reg_n=0; + for (l=min_index-1; l>=0; --l){ + switch (s[l]){ + case 'I': + case 'p': + if (--c_parameter_n_2<4){ + if (l<=last_register_parameter_index){ + new_reg [4-c_parameter_n_2] = n_extra_clean_b_register_parameters+reg_n; + ++reg_n; + } + } else { + c_offset_2-=STACK_ELEMENT_SIZE; + if (l<=last_register_parameter_index){ + i_move_r_id (REGISTER_D0+n_extra_clean_b_register_parameters+reg_n,c_offset_2,B_STACK_POINTER); + ++reg_n; + } + } + break; + case 'S': + case 's': + if (--c_parameter_n_2>=4) + c_offset_2-=STACK_ELEMENT_SIZE; + break; + } + } + + do { + not_finished=0; + for (reg_n=1; reg_n<=4; ++reg_n){ + int n; + + n=new_reg[reg_n]; + if (n>=0 && n!=reg_n){ + if (n>4 || n==0){ + i_move_r_r (REGISTER_D0+n,REGISTER_D0+reg_n); + new_reg[reg_n]=-1; + } else if (new_reg[1]!=reg_n && new_reg[2]!=reg_n && new_reg[3]!=reg_n && new_reg[4]!=reg_n){ + i_move_r_r (REGISTER_D0+n,REGISTER_D0+reg_n); + new_reg[reg_n]=-1; + } else + not_finished=1; + } + } + } while (not_finished); /* infinite loop in case of cycle */ + } + + reg_n=0; + a_o=-a_offset; + b_o=0; + for (l=min_index-1; l>=0; --l){ + switch (s[l]){ + case 'I': + case 'p': + if (--c_parameter_n<4){ + if (l<=last_register_parameter_index){ + /* i_move_r_r (REGISTER_D0+n_extra_clean_b_register_parameters+reg_n,REGISTER_D4-c_parameter_n); */ + ++reg_n; + } else { + b_o-=STACK_ELEMENT_SIZE; + i_move_id_r (b_o+c_offset_before_pushing_arguments,REGISTER_A2,REGISTER_D4-c_parameter_n); + } + } else { + c_offset_1-=STACK_ELEMENT_SIZE; + if (l<=last_register_parameter_index){ + /* i_move_r_id (REGISTER_D0+n_extra_clean_b_register_parameters+reg_n,c_offset_1,B_STACK_POINTER); */ + ++reg_n; + } else { + b_o-=STACK_ELEMENT_SIZE; + i_move_id_r (b_o+c_offset_before_pushing_arguments,REGISTER_A2,6/*r12*/); + i_move_r_id (6/*r12*/,c_offset_1,B_STACK_POINTER); + } + } + break; + case 'S': + if (--c_parameter_n<4){ + i_move_id_r (a_o,A_STACK_POINTER,REGISTER_D4-c_parameter_n); + i_add_i_r (STACK_ELEMENT_SIZE,REGISTER_D4-c_parameter_n); + } else { + c_offset_1-=STACK_ELEMENT_SIZE; + i_move_id_r (a_o,A_STACK_POINTER,REGISTER_A0); + i_add_i_r (STACK_ELEMENT_SIZE,REGISTER_A0); + i_move_r_id (REGISTER_A0,c_offset_1,B_STACK_POINTER); + } + a_o+=STACK_ELEMENT_SIZE; + break; + case 's': + if (--c_parameter_n<4){ + i_move_id_r (a_o,A_STACK_POINTER,REGISTER_D4-c_parameter_n); + i_add_i_r (2*STACK_ELEMENT_SIZE,REGISTER_D4-c_parameter_n); + } else { + c_offset_1-=STACK_ELEMENT_SIZE; + i_move_id_r (a_o,A_STACK_POINTER,REGISTER_A0); + i_add_i_r (2*STACK_ELEMENT_SIZE,REGISTER_A0); + i_move_r_id (REGISTER_A0,c_offset_1,B_STACK_POINTER); + } + a_o+=STACK_ELEMENT_SIZE; + break; + default: + error_s (ccall_error_string,c_function_name); + } + } + } + + if (!function_address_parameter) + i_call_l (label); + else + i_call_r (function_address_reg); + + if (c_offset_before_pushing_arguments-(b_result_offset+a_result_offset)==0) + i_move_r_r (REGISTER_A2,B_STACK_POINTER); + else + i_lea_id_r (c_offset_before_pushing_arguments-(b_result_offset+a_result_offset),REGISTER_A2,B_STACK_POINTER); + } + + if (a_offset!=0) + i_sub_i_r (a_offset,A_STACK_POINTER); + + for (l=length-1; l>=first_pointer_result_index; --l){ + switch (s[l]){ + case 'I': + case 'p': + case 'R': + case 'V': + break; + case 'S': + if (string_to_string_node_label==NULL) + string_to_string_node_label=enter_label ("string_to_string_node",IMPORT_LABEL); + i_move_pi_r (B_STACK_POINTER,REGISTER_A0); + i_jsr_l_idu (string_to_string_node_label,-4); + i_move_r_id (REGISTER_A0,0,A_STACK_POINTER); + i_add_i_r (STACK_ELEMENT_SIZE,A_STACK_POINTER); + break; + default: + error_s (ccall_error_string,c_function_name); + } + } + + b_o=0; + for (l=first_pointer_result_index; l<length; ++l){ + switch (s[l]){ + case 'I': + case 'p': + b_o+=STACK_ELEMENT_SIZE; + break; + case 'S': + case 'V': + break; + default: + error_s (ccall_error_string,c_function_name); + } + } + + switch (result){ + case 'I': + case 'p': + begin_new_basic_block(); + init_b_stack (5,i_i_i_i_i_vector); + s_put_b (4,s_get_b (0)); + s_remove_b(); + s_remove_b(); + s_remove_b(); + s_remove_b(); + break; + case 'V': + begin_new_basic_block(); + break; + default: + error_s (ccall_error_string,c_function_name); + } #endif } @@ -5521,7 +5796,7 @@ static void load_constant_registers (void) static void save_registers_before_clean_call (void) { -#if defined (I486) +#if defined (I486) || defined (ARM) # ifdef G_AI64 i_sub_i_r (144,B_STACK_POINTER); @@ -5614,7 +5889,7 @@ static void save_registers_before_clean_call (void) static void restore_registers_after_clean_call (void) { -#if defined (I486) +#if defined (I486) || defined (ARM) # ifdef G_AI64 # ifdef THREAD64 @@ -5847,7 +6122,7 @@ static void call_pthread_getspecific (int n_integer_parameters,int n_float_param } #endif -#ifdef I486 +#if defined (I486) || defined (ARM) # ifdef G_AI64 # define REGISTER_EBP_OR_RBP (-5) # else @@ -5857,7 +6132,7 @@ static void call_pthread_getspecific (int n_integer_parameters,int n_float_param void code_centry (char *c_function_name,char *clean_function_label,char *s,int length) { -#if defined (I486) || defined (G_POWER) +#if defined (I486) || defined (ARM) || defined (G_POWER) struct block_label *new_label; LABEL *label; int i,n,callee_pops_arguments,n_integer_and_float_parameters; @@ -5906,7 +6181,7 @@ void code_centry (char *c_function_name,char *clean_function_label,char *s,int l c=s[i]; if (c=='I') ++n_integer_parameters; -#if defined (I486) +#if defined (I486) || defined (ARM) else if (c=='R'){ ++n_float_parameters; float_parameter_or_result=1; @@ -5934,7 +6209,7 @@ void code_centry (char *c_function_name,char *clean_function_label,char *s,int l else if (c=='I'){ integer_c_function_result=1; ++n_integer_results; -#if defined (I486) +#if defined (I486) || defined (ARM) } else if (c=='R'){ float_c_function_result=1; ++n_float_results; @@ -5963,7 +6238,7 @@ void code_centry (char *c_function_name,char *clean_function_label,char *s,int l c=s[i]; if (c=='I') ++n_integer_results; -#if defined (I486) +#if defined (I486) || defined (ARM) else if (c=='R'){ ++n_float_results; float_parameter_or_result=1; @@ -5993,7 +6268,7 @@ void code_centry (char *c_function_name,char *clean_function_label,char *s,int l string_or_array_c_function_result=string_c_function_result+array_c_function_result; -#ifdef I486 +#if defined (I486) || defined (ARM) if (n_integer_results==0 && n_float_results==0 && n_string_or_array_results==0) #else if (n_integer_results!=1) @@ -6006,7 +6281,7 @@ void code_centry (char *c_function_name,char *clean_function_label,char *s,int l n_integer_and_float_parameters=n_integer_parameters+n_float_parameters; #endif -# if (defined (sparc) && !defined (SOLARIS)) || (defined (I486) && !defined (LINUX_ELF) && !defined (G_AI64)) || (defined (G_POWER) && !defined (LINUX_ELF)) || defined (MACH_O) || defined (MACH_O64) +# if (defined (sparc) && !defined (SOLARIS)) || ((defined (I486) || defined (ARM)) && !defined (LINUX_ELF) && !defined (G_AI64)) || (defined (G_POWER) && !defined (LINUX_ELF)) || defined (MACH_O) || defined (MACH_O64) { char label_name [202]; @@ -6094,7 +6369,7 @@ void code_centry (char *c_function_name,char *clean_function_label,char *s,int l } #endif -#if defined (I486) +#if defined (I486) || defined (ARM) if (n_string_or_array_parameters!=0){ int i,offset; @@ -6126,7 +6401,11 @@ void code_centry (char *c_function_name,char *clean_function_label,char *s,int l string_to_string_node_label=enter_string_to_string_node_label(); offset-=STACK_ELEMENT_SIZE; i_move_id_r (offset,B_STACK_POINTER,REGISTER_A0); +# ifndef ARM i_jsr_l (string_to_string_node_label,0); +# else + i_jsr_l_idu (string_to_string_node_label,-4); +# endif i_move_r_id (REGISTER_A0,0,A_STACK_POINTER); i_add_i_r (STACK_ELEMENT_SIZE,A_STACK_POINTER); } else if (c=='i'){ @@ -6135,7 +6414,11 @@ void code_centry (char *c_function_name,char *clean_function_label,char *s,int l int_array_to_node_label=enter_label ("int_array_to_node",IMPORT_LABEL); offset-=STACK_ELEMENT_SIZE; i_move_id_r (offset,B_STACK_POINTER,REGISTER_A0); +# ifndef ARM i_jsr_l (int_array_to_node_label,0); +# else + i_jsr_l_idu (int_array_to_node_label,-4); +# endif i_move_r_id (REGISTER_A0,0,A_STACK_POINTER); i_add_i_r (STACK_ELEMENT_SIZE,A_STACK_POINTER); } else if (c=='r'){ @@ -6144,7 +6427,11 @@ void code_centry (char *c_function_name,char *clean_function_label,char *s,int l real_array_to_node_label=enter_label ("real_array_to_node",IMPORT_LABEL); offset-=STACK_ELEMENT_SIZE; i_move_id_r (offset,B_STACK_POINTER,REGISTER_A0); +# ifndef ARM i_jsr_l (real_array_to_node_label,0); +# else + i_jsr_l_idu (real_array_to_node_label,-4); +# endif i_move_r_id (REGISTER_A0,0,A_STACK_POINTER); i_add_i_r (STACK_ELEMENT_SIZE,A_STACK_POINTER); } else @@ -6169,7 +6456,7 @@ void code_centry (char *c_function_name,char *clean_function_label,char *s,int l init_a_stack (0); init_b_stack (0,e_vector); -#if defined (I486) +#if defined (I486) || defined (ARM) if (n_string_or_array_parameters!=0){ int i,offset; @@ -6949,7 +7236,7 @@ void init_cginstructions (void) profile_function_label=NULL; profile_flag=PROFILE_NORMAL; -#if defined (G_POWER) || defined (I486) +#if defined (G_POWER) || defined (I486) || defined (ARM) profile_l_label=NULL; profile_l2_label=NULL; profile_n_label=NULL; @@ -6962,7 +7249,7 @@ void init_cginstructions (void) profile_ti_label=NULL; # endif #endif -#if (defined (I486) && !defined (THREAD64)) || defined (G_POWER) +#if ((defined (I486) || defined (ARM)) && !defined (THREAD64)) || defined (G_POWER) saved_heap_p_label=NULL; saved_a_stack_p_label=NULL; #endif diff --git a/cginstructions.h b/cginstructions.h index 1d3fd7e..18366a9 100644 --- a/cginstructions.h +++ b/cginstructions.h @@ -22,7 +22,7 @@ extern INSTRUCTION_GRAPH g_fload (int offset,int stack); extern INSTRUCTION_GRAPH g_fload_i (DOUBLE v); extern INSTRUCTION_GRAPH g_fload_id (int offset,INSTRUCTION_GRAPH graph_1); extern INSTRUCTION_GRAPH g_fload_x (INSTRUCTION_GRAPH graph_1,int offset,int shift,INSTRUCTION_GRAPH graph_2); -#ifdef I486 +#if defined (I486) || defined (ARM) extern INSTRUCTION_GRAPH g_fload_s_x (INSTRUCTION_GRAPH graph_1,int offset,int shift,INSTRUCTION_GRAPH graph_2); #endif extern INSTRUCTION_GRAPH g_lea (LABEL *label); @@ -42,7 +42,7 @@ extern INSTRUCTION_GRAPH g_movem (int offset,INSTRUCTION_GRAPH graph_1,int n); extern INSTRUCTION_GRAPH g_movemi (int number,INSTRUCTION_GRAPH movem_graph); extern INSTRUCTION_GRAPH g_fregister (int float_reg); extern INSTRUCTION_GRAPH g_fstore_x (INSTRUCTION_GRAPH graph_1,INSTRUCTION_GRAPH graph_2,int offset,int shift,INSTRUCTION_GRAPH graph_3); -#ifdef I486 +#if defined (I486) || defined (ARM) extern INSTRUCTION_GRAPH g_fstore_s_x (INSTRUCTION_GRAPH graph_1,INSTRUCTION_GRAPH graph_2,int offset,int shift,INSTRUCTION_GRAPH graph_3); #endif extern INSTRUCTION_GRAPH g_g_register (int reg); @@ -164,7 +164,7 @@ void i_add_r_r (int register_1,int register_2) parameter_data.i=register_2); } -#if defined (G_POWER) || defined (sparc) +#if defined (G_POWER) || defined (sparc) || defined (ARM) static void i_addi_r_r (LONG value,int register_1,int register_2) { struct instruction *instruction; @@ -182,7 +182,7 @@ static void i_addi_r_r (LONG value,int register_1,int register_2) } #endif -#if defined (M68000) || defined (G_POWER) || defined (G_AI64) +#if defined (M68000) || defined (G_POWER) || defined (G_AI64) || defined (ARM) # if defined (M68000) static # endif @@ -235,7 +235,7 @@ void i_bnep_l (LABEL *label) } #endif -#if defined (sparc) || defined (I486) +#if defined (sparc) || defined (I486) || defined (ARM) void i_bne_l (LABEL *label) { register struct instruction *instruction; @@ -281,7 +281,7 @@ static void i_bmove_pi_pi_r (int reg_1,int reg_2,int reg_3) } #endif -#ifdef I486 +#if defined (I486) || defined (ARM) void i_btst_i_id (LONG i,int offset,int register_1) { register struct instruction *instruction; @@ -297,7 +297,7 @@ void i_btst_i_id (LONG i,int offset,int register_1) } #endif -#if defined (sparc) || defined (I486) || defined (G_POWER) +#if defined (sparc) || defined (I486) || defined (ARM) || defined (G_POWER) void i_btst_i_r (LONG i,int register_1) { register struct instruction *instruction; @@ -444,7 +444,7 @@ static void i_fexg_fr_fr (int register_1,int register_2) } #endif -#ifdef I486 +#if defined (I486) || defined (ARM) static void i_floads_id_fr (int offset,int register_2,int register_1) { struct instruction *instruction; @@ -635,7 +635,7 @@ static void i_fmovel_fr_r (int register_1,int register_2) parameter_data.i=register_2); } -#ifdef I486 +#if defined (I486) || defined (ARM) void i_fmoves_fr_id (int register_1,int offset,int register_2) { struct instruction *instruction; @@ -702,7 +702,7 @@ static void i_fmove_x_fr (int offset,int register_1,int register_2,int register_ set_float_register_parameter (instruction->instruction_parameters[1],register_3); } -#ifdef I486 +#if defined (I486) || defined (ARM) static void i_floads_x_fr (int offset,int register_1,int register_2,int register_3) { struct instruction *instruction; @@ -735,7 +735,7 @@ void i_jmp_id (int offset_1,int register_1,int n_a_registers) instruction->instruction_parameters[0].parameter_data.reg.u=n_a_registers; } -#if defined (G_POWER) || defined (I486) +#if defined (G_POWER) || defined (I486) || defined (ARM) void i_jmp_id_profile (int offset_1,int register_1,int n_a_registers) { struct instruction *instruction; @@ -762,7 +762,7 @@ void i_jmp_l (LABEL *label,int n_a_registers) instruction->instruction_parameters[0].parameter_offset=n_a_registers; } -#if defined (G_POWER) || defined (I486) +#if defined (G_POWER) || defined (I486) || defined (ARM) void i_jmp_l_profile (LABEL *label,int offset) { struct instruction *instruction; @@ -776,7 +776,7 @@ void i_jmp_l_profile (LABEL *label,int offset) } #endif -#ifdef I486 +#if defined (I486) || defined (ARM) void i_jmp_r (int a_reg) { struct instruction *instruction; @@ -824,6 +824,7 @@ void i_jsr_l (LABEL *label,int n_a_registers) instruction->instruction_parameters[0].parameter_offset=n_a_registers; /* for parallel code on MC680x0 */ } #else +# ifndef ARM void i_jsr_id_id (int offset_1,int register_1,int offset_2) { struct instruction *instruction; @@ -838,22 +839,25 @@ void i_jsr_id_id (int offset_1,int register_1,int offset_2) /* instruction->instruction_parameters[1].parameter_data.reg.r=B_STACK_POINTER; */ instruction->instruction_parameters[1].parameter_data.i=offset_2; } - +# endif void i_jsr_l_id (LABEL *label,int offset) { - register struct instruction *instruction; + struct instruction *instruction; instruction=i_new_instruction2 (IJSR); - - instruction->instruction_parameters[0].parameter_type=P_LABEL; - instruction->instruction_parameters[0].parameter_data.l=label; + + S2(instruction->instruction_parameters[0], parameter_type=P_LABEL, + parameter_data.l=label); instruction->instruction_parameters[1].parameter_type=P_INDIRECT; /* instruction->instruction_parameters[1].parameter_data.reg.r=B_STACK_POINTER; */ +# ifdef ARM + instruction->instruction_parameters[1].parameter_offset=offset; +# else instruction->instruction_parameters[1].parameter_data.i=offset; +# endif } - -# ifdef G_POWER +# if defined (G_POWER) || defined (ARM) void i_jsr_id_idu (int offset_1,int register_1,int offset_2) { struct instruction *instruction; @@ -863,10 +867,10 @@ void i_jsr_l_id (LABEL *label,int offset) instruction->instruction_parameters[0].parameter_type=P_INDIRECT; instruction->instruction_parameters[0].parameter_offset=offset_1; instruction->instruction_parameters[0].parameter_data.i=register_1; - + instruction->instruction_parameters[1].parameter_type=P_INDIRECT_WITH_UPDATE; -/* instruction->instruction_parameters[1].parameter_data.reg.r=B_STACK_POINTER; */ - instruction->instruction_parameters[1].parameter_data.i=offset_2; + instruction->instruction_parameters[1].parameter_offset=offset_2; + instruction->instruction_parameters[1].parameter_data.i=B_STACK_POINTER; } void i_jsr_l_idu (LABEL *label,int offset) @@ -877,10 +881,10 @@ void i_jsr_l_id (LABEL *label,int offset) instruction->instruction_parameters[0].parameter_type=P_LABEL; instruction->instruction_parameters[0].parameter_data.l=label; - + instruction->instruction_parameters[1].parameter_type=P_INDIRECT_WITH_UPDATE; -/* instruction->instruction_parameters[1].parameter_data.reg.r=B_STACK_POINTER; */ - instruction->instruction_parameters[1].parameter_data.i=offset; + instruction->instruction_parameters[1].parameter_offset=offset; + instruction->instruction_parameters[1].parameter_data.i=B_STACK_POINTER; } # endif #endif @@ -897,8 +901,24 @@ void i_jsr_r (int register_1) } #endif -#if defined (sparc) || defined (G_POWER) -# ifdef sparc +#if defined (ARM) +void i_jsr_r_idu (int register_1,int offset) +{ + struct instruction *instruction; + + instruction=i_new_instruction2 (IJSR); + + S2(instruction->instruction_parameters[0], parameter_type=P_REGISTER, + parameter_data.reg.r=register_1); + + instruction->instruction_parameters[1].parameter_type=P_INDIRECT_WITH_UPDATE; + instruction->instruction_parameters[1].parameter_offset=offset; + instruction->instruction_parameters[1].parameter_data.i=B_STACK_POINTER; +} +#endif + +#if defined (sparc) || defined (G_POWER) || defined (ARM) +# ifndef G_POWER void i_call_l (LABEL *label) # else void i_call_l (LABEL *label,int frame_size) @@ -917,7 +937,7 @@ void i_call_l (LABEL *label,int frame_size) # endif } -# ifdef sparc +# ifndef G_POWER void i_call_r (int register_1) # else void i_call_r (int register_1,int frame_size) @@ -983,7 +1003,7 @@ void i_lea_l_i_r (LABEL *label,int offset,int register_1) instruction->instruction_parameters[1].parameter_data.reg.r=register_1; } -#if defined (sparc) || defined (I486) || defined (G_POWER) +#if defined (sparc) || defined (I486) || defined (ARM) || defined (G_POWER) static void i_lea_x_r (int register_1,int register_2,int register_3) { register struct instruction *instruction; @@ -1004,7 +1024,7 @@ static void i_lea_x_r (int register_1,int register_2,int register_3) } #endif -#if defined (G_POWER) || defined (sparc) +#if defined (G_POWER) || defined (sparc) || defined (ARM) static void i_lsli_r_r (LONG value,int register_1,int register_2) { struct instruction *instruction; @@ -1036,7 +1056,7 @@ static void i_moveb_id_r (int offset,int register_1,int register_2) parameter_data.i=register_2); } -#if !(defined (M68000) || defined (I486)) +#if !(defined (M68000) || defined (I486) || defined (ARM)) static void i_moveb_x_r (int register_1,int register_2,int register_3) { struct instruction *instruction; @@ -1079,9 +1099,9 @@ static void i_moveb_x_r (int offset,int register_1,int register_2,int register_3 #ifdef M68000 static void i_movem_id (int offset_1,int register_1,int n_arguments,int arguments[]) { - register struct instruction *instruction; - register struct parameter *parameter; - register int argument_number; + struct instruction *instruction; + struct parameter *parameter; + int argument_number; instruction=i_new_instruction (IMOVEM,n_arguments+1,(n_arguments+1)*sizeof (struct parameter)); @@ -1153,6 +1173,72 @@ void i_movem_id_r (int offset,int register_1,int register_2) } #endif +#if defined (ARM) +void i_movem_pd_rs (int register_1,int n_arguments,int arguments[]) +{ + struct instruction *instruction; + int argument_number; + + instruction=i_new_instruction (IMOVEM,n_arguments+1,(n_arguments+1)*sizeof (struct parameter)); + + instruction->instruction_parameters[0].parameter_type=P_PRE_DECREMENT; + instruction->instruction_parameters[0].parameter_data.i=register_1; + + for (argument_number=0; argument_number<n_arguments; ++argument_number){ + S2 (instruction->instruction_parameters[1+argument_number], parameter_type=P_REGISTER, + parameter_data.i=arguments[argument_number]); + } +} + +void i_movem_pi_rs (int register_1,int n_arguments,int arguments[]) +{ + struct instruction *instruction; + int argument_number; + + instruction=i_new_instruction (IMOVEM,n_arguments+1,(n_arguments+1)*sizeof (struct parameter)); + + instruction->instruction_parameters[0].parameter_type=P_POST_INCREMENT; + instruction->instruction_parameters[0].parameter_data.i=register_1; + + for (argument_number=0; argument_number<n_arguments; ++argument_number){ + S2 (instruction->instruction_parameters[1+argument_number], parameter_type=P_REGISTER, + parameter_data.i=arguments[argument_number]); + } +} + +void i_movem_rs_pd (int n_arguments,int arguments[],int register_1) +{ + struct instruction *instruction; + int argument_number; + + instruction=i_new_instruction (IMOVEM,n_arguments+1,(n_arguments+1)*sizeof (struct parameter)); + + instruction->instruction_parameters[n_arguments].parameter_type=P_PRE_DECREMENT; + instruction->instruction_parameters[n_arguments].parameter_data.i=register_1; + + for (argument_number=0; argument_number<n_arguments; ++argument_number){ + S2 (instruction->instruction_parameters[argument_number], parameter_type=P_REGISTER, + parameter_data.i=arguments[argument_number]); + } +} + +void i_movem_rs_pi (int n_arguments,int arguments[],int register_1) +{ + struct instruction *instruction; + int argument_number; + + instruction=i_new_instruction (IMOVEM,n_arguments+1,(n_arguments+1)*sizeof (struct parameter)); + + instruction->instruction_parameters[n_arguments].parameter_type=P_POST_INCREMENT; + instruction->instruction_parameters[n_arguments].parameter_data.i=register_1; + + for (argument_number=0; argument_number<n_arguments; ++argument_number){ + S2 (instruction->instruction_parameters[argument_number], parameter_type=P_REGISTER, + parameter_data.i=arguments[argument_number]); + } +} +#endif + #ifdef G_AI64 void i_loadsqb_r_r (int register_1,int register_2) { @@ -1262,7 +1348,7 @@ void i_move_i_r (CleanInt i,int register_1) parameter_data.i=register_1); } -#if defined (M68000) || defined (I486) +#if defined (M68000) || defined (I486) || defined (ARM) # ifdef G_A64 static void i_move_i_x (int_64 i,int offset,int register_1,int register_2) # else @@ -1363,21 +1449,39 @@ void i_move_id_r (int offset,int register_1,int register_2) parameter_data.i=register_2); } -#ifdef G_POWER - void i_move_idu_r (int offset,int register_1,int register_2) - { - struct instruction *instruction; - - instruction=i_new_instruction2 (IMOVE); - - instruction->instruction_parameters[0].parameter_type=P_INDIRECT_WITH_UPDATE; - instruction->instruction_parameters[0].parameter_offset=offset; - instruction->instruction_parameters[0].parameter_data.i=register_1; - - instruction->instruction_parameters[1].parameter_type=P_REGISTER; - instruction->instruction_parameters[1].parameter_data.i=register_2; - } +#if defined (G_POWER) || defined (ARM) +void i_move_idu_r (int offset,int register_1,int register_2) +{ + struct instruction *instruction; + + instruction=i_new_instruction2 (IMOVE); + + instruction->instruction_parameters[0].parameter_type=P_INDIRECT_WITH_UPDATE; + instruction->instruction_parameters[0].parameter_offset=offset; + instruction->instruction_parameters[0].parameter_data.i=register_1; + + instruction->instruction_parameters[1].parameter_type=P_REGISTER; + instruction->instruction_parameters[1].parameter_data.i=register_2; +} +#endif + +#if defined (ARM) +void i_move_r_idpa (int register_1,int register_2,int offset) +{ + struct instruction *instruction; + + instruction=i_new_instruction2 (IMOVE); + + instruction->instruction_parameters[0].parameter_type=P_REGISTER; + instruction->instruction_parameters[0].parameter_data.i=register_1; + + instruction->instruction_parameters[1].parameter_type=P_INDIRECT_POST_ADD; + instruction->instruction_parameters[1].parameter_offset=offset; + instruction->instruction_parameters[1].parameter_data.i=register_2; +} +#endif +#ifdef G_POWER void i_move_id_idu (int offset1,int register_1,int offset2,int register_2) { struct instruction *instruction; @@ -1437,7 +1541,7 @@ void i_move_id_r (int offset,int register_1,int register_2) } #endif -#if defined (M68000) || defined (I486) +#if defined (M68000) || defined (I486) || defined (ARM) # ifndef THREAD32 static void i_move_id_x (int offset_1,int register_1,int offset_2,int register_2,int register_3) { @@ -1517,7 +1621,7 @@ static void i_move_pi_pi (int register_1,int register_2) } #endif -#if defined (M68000) | defined (I486) +#if defined (M68000) | defined (I486) || defined (ARM) void i_move_pi_r (int register_1,int register_2) { register struct instruction *instruction; @@ -1571,7 +1675,7 @@ static struct instruction *instruction_move_r_idhp (int register_1,LONG offset) } #endif -#if defined (I486) +#if defined (I486) || defined (ARM) void i_move_r_l (int register_1,LABEL *label) { struct instruction *instruction; @@ -1598,7 +1702,7 @@ void i_move_r_id (int register_1,int offset,int register_2) instruction->instruction_parameters[1].parameter_data.i=register_2; } -#if defined (M68000) | defined (I486) +#if defined (M68000) || defined (I486) || defined (ARM) void i_move_r_pd (int register_1,int register_2) { register struct instruction *instruction; @@ -1807,7 +1911,7 @@ void i_movew_r_pd (int register_1,int register_2) } #endif -#ifdef I486 +#if defined (I486) || defined (ARM) # ifdef THREAD32 void i_mulud_r_r_r (int register_1,int register_2,int register_3) # else @@ -1835,7 +1939,7 @@ void i_mulud_r_r (int register_1,int register_2) } #endif -#if defined (G_POWER) || defined (G_AI64) +#if defined (G_POWER) || defined (G_AI64) || defined (ARM) void i_or_i_r (LONG value,int register_1) { struct instruction *instruction; @@ -1878,7 +1982,8 @@ void i_mtctr (int register_1) S2 (instruction->instruction_parameters[0], parameter_type=P_IMMEDIATE, parameter_data.imm=offset); } - +# endif +# if defined (I486) || defined (ARM) void i_rts_profile (void) { i_new_instruction (IRTSP,0,0); @@ -2185,7 +2290,7 @@ void free_all_dregisters (VOID) { free_dregisters.r_s_first_free=d_reg_num (REGISTER_D0); free_dregisters.r_s_highest=8; -#if defined (I486) && !defined (G_AI64) +#if (defined (I486) || defined (ARM)) && !defined (G_AI64) free_dregisters.r_s_list.r_l_vector= (1<<d_reg_num (REGISTER_D0)) | (1<<d_reg_num (REGISTER_D1)); #else @@ -2225,7 +2330,7 @@ void free_all_aregisters (VOID) free_aregisters.r_s_highest=N_REAL_A_REGISTERS; free_aregisters.r_s_list.r_l_vector= (1<<a_reg_num (REGISTER_A0)) | (1<<a_reg_num (REGISTER_A1)) -#ifndef I486 +#if !(defined (I486) || defined (ARM)) | (1<<a_reg_num (REGISTER_A2)) #endif ; @@ -2255,7 +2360,7 @@ void free_all_fregisters (VOID) (1<<REGISTER_FP2) | (1<<REGISTER_FP3) | (1<<REGISTER_FP4) | (1<<REGISTER_FP5) | (1<<REGISTER_FP6) -#ifndef I486 +#if !(defined (I486) || defined (ARM)) | (1<<REGISTER_FP7) #endif ; @@ -2699,7 +2804,7 @@ static void instruction_i_r_r_r (int instruction_code,int i,int register_1,int r } #endif -#ifdef I486 +#if defined (I486) || defined (ARM) static void instruction_r_r_r_i (int instruction_code,int register_1,int register_2,int register_3,int i) { struct instruction *instruction; @@ -3034,7 +3139,7 @@ static void in_alterable_data_register (ADDRESS *ad_p) ad_p->ad_count=1; } -#ifdef I486 +#if defined (I486) || defined (ARM) static void in_preferred_alterable_register (ADDRESS *ad_p,int preferred_reg) { int dreg; @@ -3344,10 +3449,13 @@ static void float_register_node (INSTRUCTION_GRAPH graph,int reg) static void linearize_graph (INSTRUCTION_GRAPH,ADDRESS *); #if defined (G_POWER) -# define SMALL_IMMEDIATE(i) (((short int)i)==((int)i)) +# define ADDI_IMMEDIATE(i) (((short int)i)==((int)i)) #endif #if defined (sparc) -# define SMALL_IMMEDIATE(i) ((int)i<4096 && (int)i>=-4095) +# define ADDI_IMMEDIATE(i) ((int)i<4096 && (int)i>=-4095) +#endif +#if defined (ARM) +# define ADDI_IMMEDIATE(i) 1 #endif static void linearize_dyadic_commutative_operator (int i_instruction_code,INSTRUCTION_GRAPH graph,ADDRESS *ad_p) @@ -3379,10 +3487,10 @@ static void linearize_dyadic_commutative_operator (int i_instruction_code,INSTRU --*ad_1.ad_count_p; reg_1=ad_1.ad_register; } else { -#ifndef M68000 /* optimization added 18-8-1998 */ +#ifndef M68000 if (ad_2.ad_mode==P_IMMEDIATE){ -# if defined (G_POWER) || defined (sparc) - if (ad_1.ad_mode==P_REGISTER && SMALL_IMMEDIATE (ad_2.ad_offset) && i_instruction_code==IADD){ +# if defined (G_POWER) || defined (sparc) || defined (ARM) + if (ad_1.ad_mode==P_REGISTER && ADDI_IMMEDIATE (ad_2.ad_offset) && i_instruction_code==IADD){ if (--*ad_1.ad_count_p==0) free_register (ad_1.ad_register); reg_1=get_dregister(); @@ -3401,8 +3509,8 @@ static void linearize_dyadic_commutative_operator (int i_instruction_code,INSTRU } } else { #endif -#if defined (G_POWER) || defined (sparc) - if (ad_1.ad_mode==P_IMMEDIATE && ad_2.ad_mode==P_REGISTER && SMALL_IMMEDIATE (ad_1.ad_offset) && i_instruction_code==IADD){ +#if defined (G_POWER) || defined (sparc) || defined (ARM) + if (ad_1.ad_mode==P_IMMEDIATE && ad_2.ad_mode==P_REGISTER && ADDI_IMMEDIATE (ad_1.ad_offset) && i_instruction_code==IADD){ if (--*ad_2.ad_count_p==0) free_register (ad_2.ad_register); reg_1=get_dregister(); @@ -3423,13 +3531,13 @@ static void linearize_dyadic_commutative_operator (int i_instruction_code,INSTRU #endif } } else { -# if defined (G_POWER) || defined (sparc) - if (ad_1.ad_mode==P_IMMEDIATE && ad_2.ad_mode==P_REGISTER && SMALL_IMMEDIATE (ad_1.ad_offset) && i_instruction_code==IADD){ +# if defined (G_POWER) || defined (sparc) || defined (ARM) + if (ad_1.ad_mode==P_IMMEDIATE && ad_2.ad_mode==P_REGISTER && ADDI_IMMEDIATE (ad_1.ad_offset) && i_instruction_code==IADD){ if (--*ad_2.ad_count_p==0) free_register (ad_2.ad_register); reg_1=get_aregister(); i_addi_r_r (ad_1.ad_offset,ad_2.ad_register,reg_1); - } else if (ad_2.ad_mode==P_IMMEDIATE && ad_1.ad_mode==P_REGISTER && SMALL_IMMEDIATE (ad_2.ad_offset) && i_instruction_code==IADD){ + } else if (ad_2.ad_mode==P_IMMEDIATE && ad_1.ad_mode==P_REGISTER && ADDI_IMMEDIATE (ad_2.ad_offset) && i_instruction_code==IADD){ if (--*ad_1.ad_count_p==0) free_register (ad_1.ad_register); reg_1=get_aregister(); @@ -3942,8 +4050,8 @@ static void linearize_dyadic_non_commutative_operator (int i_instruction_code,IN linearize_graph (graph_1,&ad_1); } -# if defined (G_POWER) || defined (sparc) - if (ad_1.ad_mode==P_IMMEDIATE && ad_2.ad_mode==P_REGISTER && SMALL_IMMEDIATE (-ad_1.ad_offset) && i_instruction_code==ISUB){ +# if defined (G_POWER) || defined (sparc) || defined (ARM) + if (ad_1.ad_mode==P_IMMEDIATE && ad_2.ad_mode==P_REGISTER && ADDI_IMMEDIATE (-ad_1.ad_offset) && i_instruction_code==ISUB){ int reg_1; if (--*ad_2.ad_count_p==0) @@ -4067,7 +4175,7 @@ static void linearize_monadic_data_operator (int i_instruction_code,INSTRUCTION_ register_node (graph,reg_1); } -#if defined (I486) || defined (G_POWER) +#if defined (I486) || defined (ARM) || defined (G_POWER) static void linearize_div_rem_operator (int i_instruction_code,INSTRUCTION_GRAPH graph,ADDRESS *ad_p) { INSTRUCTION_GRAPH graph_1,graph_2; @@ -4084,12 +4192,12 @@ static void linearize_div_rem_operator (int i_instruction_code,INSTRUCTION_GRAPH linearize_graph (graph_2,&ad_2); linearize_graph (graph_1,&ad_1); } -# ifdef I486 +# if defined (I486) || defined (ARM) in_preferred_alterable_register (&ad_2,REGISTER_D0); # else in_alterable_data_register (&ad_2); # endif -# ifdef I486 +# if defined (I486) || defined (ARM) if (ad_1.ad_mode==P_IMMEDIATE){ if (i_instruction_code==IDIVU || i_instruction_code==IREMU){ in_data_register (&ad_1); @@ -4115,28 +4223,31 @@ static void linearize_div_rem_operator (int i_instruction_code,INSTRUCTION_GRAPH # endif i=-i; +# ifdef ARM + instruction_ad_r (i_instruction_code,&ad_1,ad_2.ad_register); +# else if ((i & (i-1))==0 && (i_instruction_code==IREM ? i>1 : i>0)){ -# ifndef THREAD32 +# ifndef THREAD32 instruction_ad_r (i_instruction_code,&ad_1,ad_2.ad_register); -# else +# else int tmp_reg; tmp_reg=get_dregister(); instruction_ad_r_r (i_instruction_code,&ad_1,ad_2.ad_register,tmp_reg); free_dregister (tmp_reg); -# endif -# ifndef G_A64 +# endif +# ifndef G_A64 } else if (i>1 || (i<-1 && i!=0x80000000)){ -# else +# else } else if (i>1 || (i<-1 && i!=0x8000000000000000ll)){ -# endif -# ifndef THREAD32 +# endif +# ifndef THREAD32 int tmp_reg; tmp_reg=get_dregister(); instruction_ad_r_r (i_instruction_code==IDIV ? IDIVI : IREMI,&ad_1,ad_2.ad_register,tmp_reg); free_dregister (tmp_reg); -# else +# else int tmp_reg,tmp2_reg; tmp_reg=get_dregister(); @@ -4144,12 +4255,12 @@ static void linearize_div_rem_operator (int i_instruction_code,INSTRUCTION_GRAPH instruction_i_r_r_r (i_instruction_code==IDIV ? IDIVI : IREMI,i,ad_2.ad_register,tmp_reg,tmp2_reg); free_dregister (tmp2_reg); free_dregister (tmp_reg); -# endif +# endif } else { in_data_register (&ad_1); -# ifndef THREAD32 +# ifndef THREAD32 instruction_ad_r (i_instruction_code,&ad_1,ad_2.ad_register); -# else +# else { int tmp_reg; @@ -4157,8 +4268,9 @@ static void linearize_div_rem_operator (int i_instruction_code,INSTRUCTION_GRAPH instruction_ad_r_r (i_instruction_code,&ad_1,ad_2.ad_register,tmp_reg); free_dregister (tmp_reg); } -# endif +# endif } +# endif } } else { to_data_addressing_mode (&ad_1); @@ -4251,7 +4363,7 @@ static void linearize_rem_operator (int i_instruction_code,INSTRUCTION_GRAPH gra } #endif -#ifdef I486 +#if defined (I486) || defined (ARM) static void linearize_floordiv_mod_operator (int i_instruction_code,INSTRUCTION_GRAPH graph,ADDRESS *ad_p) { INSTRUCTION_GRAPH graph_1,graph_2; @@ -4329,7 +4441,7 @@ static void linearize_floordiv_mod_operator (int i_instruction_code,INSTRUCTION_ } #endif -#ifdef I486 +#if defined (I486) || defined (ARM) static int linearize_first_graph_first (INSTRUCTION_GRAPH a_graph_1,INSTRUCTION_GRAPH a_graph_2) { int i1,i2,u1,u2; @@ -4429,7 +4541,9 @@ static void linearize_two_results_operator (INSTRUCTION_GRAPH result_graph,ADDRE # else i_mulud_r_r (reg_1,reg_2); # endif - } else if (graph->instruction_code==GDIVDU){ + } else +# ifdef I486 + if (graph->instruction_code==GDIVDU){ ADDRESS ad_3; linearize_3_graphs (graph->instruction_parameters[0].p,&ad_1, @@ -4445,7 +4559,9 @@ static void linearize_two_results_operator (INSTRUCTION_GRAPH result_graph,ADDRE if (--*ad_3.ad_count_p==0) free_register (ad_3.ad_register); i_divdu_r_r_r (ad_3.ad_register,reg_1,reg_2); - } else if (graph->instruction_code==GADDDU){ + } else +# endif + if (graph->instruction_code==GADDDU){ ADDRESS ad_3,ad_4; linearize_3_graphs (graph->instruction_parameters[0].p,&ad_1, @@ -4532,7 +4648,7 @@ static void linearize_shift_operator (int i_instruction_code,int i_instruction_c linearize_graph (graph_1,&ad_1); } -#if defined (G_POWER) || defined (sparc) +#if defined (G_POWER) || defined (sparc) || defined (ARM) if (i_instruction_code==ILSL && ad_1.ad_mode==P_IMMEDIATE && (unsigned)ad_1.ad_offset<(unsigned)32){ in_register (&ad_2); if (--*ad_2.ad_count_p==0) @@ -4542,7 +4658,7 @@ static void linearize_shift_operator (int i_instruction_code,int i_instruction_c reg_1=get_dregister(); else reg_1=get_aregister(); - + i_lsli_r_r (ad_1.ad_offset,ad_2.ad_register,reg_1); } else { #endif @@ -4586,7 +4702,7 @@ static void linearize_shift_operator (int i_instruction_code,int i_instruction_c reg_1=areg; } -#if defined (G_POWER) || defined (sparc) +#if defined (G_POWER) || defined (sparc) || defined (ARM) } #endif @@ -4642,7 +4758,7 @@ static void linearize_integer_o_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_r_ static void linearize_add_o_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_r_p,ADDRESS *ad_f_p) { linearize_integer_o_operator (graph,ad_r_p,ad_f_p,linearize_dyadic_commutative_operator, -#if defined (sparc) || defined (G_POWER) +#if defined (sparc) || defined (G_POWER) || defined (ARM) IADDO #else IADD @@ -4653,7 +4769,7 @@ static void linearize_add_o_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_r_p,AD static void linearize_sub_o_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_r_p,ADDRESS *ad_f_p) { linearize_integer_o_operator (graph,ad_r_p,ad_f_p,linearize_dyadic_non_commutative_operator, -#if defined (sparc) || defined (G_POWER) +#if defined (sparc) || defined (G_POWER) || defined (ARM) ISUBO #else ISUB @@ -5003,7 +5119,7 @@ static void move_float_ad_id (ADDRESS *ad_p,int offset,int areg) if (--*i_ad_p->ad_count_p==0) free_aregister (i_ad_p->ad_areg); # ifndef G_A64 -# if defined (M68000) || defined (I486) +# if defined (M68000) || defined (I486) || defined (ARM) i_move_x_id (i_ad_p->ad_offset+(4<<2),i_ad_p->ad_areg,i_ad_p->ad_dreg,offset+4,areg); # else { @@ -5170,7 +5286,7 @@ static void linearize_create_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_p,int ad_a=evaluate_arguments (graph->instruction_parameters,arity); #ifndef M68000 -# ifdef I486 +# if defined (I486) || defined (ARM) if (offset_from_heap_register+(arity<<2) >= 127){ # else # ifdef G_POWER @@ -5634,7 +5750,7 @@ static void move_float_ad_x (ADDRESS *ad_p,int offset,int areg,int dreg) free_fregister (ad_p->ad_register); } return; -#if defined (M68000) || defined (I486) +#if defined (M68000) || defined (I486) || defined (ARM) case P_INDIRECT: # ifdef M68000 if (ad_p->ad_offset==0 && *ad_p->ad_count_p==1){ @@ -7093,7 +7209,7 @@ static void linearize_dyadic_non_commutative_float_operator (int instruction_cod } #if 1 -# if (defined (I486) && !defined (G_AI64)) || defined (G_POWER) +# if ((defined (I486) || defined (ARM)) && !defined (G_AI64)) || defined (G_POWER) if (ad_1.ad_mode==P_F_REGISTER && *ad_1.ad_count_p==1 && !(ad_2.ad_mode==P_F_REGISTER && ad_2.ad_register<ad_1.ad_register && *ad_2.ad_count_p==1) ){ @@ -7122,7 +7238,7 @@ static void linearize_dyadic_non_commutative_float_operator (int instruction_cod } reg_1=ad_2.ad_register; instruction_p_fr (instruction_code,¶meter1,reg_1); -# if defined (I486) || defined (G_POWER) +# if defined (I486) || defined (ARM) || defined (G_POWER) last_instruction->instruction_parameters[1].parameter_flags=0; # endif } @@ -7130,7 +7246,7 @@ static void linearize_dyadic_non_commutative_float_operator (int instruction_cod in_alterable_float_register (&ad_2); reg_1=ad_2.ad_register; instruction_ad_fr (instruction_code,&ad_1,reg_1); -# if defined (I486) || defined (G_POWER) +# if defined (I486) || defined (ARM) || defined (G_POWER) last_instruction->instruction_parameters[1].parameter_flags=0; # endif #endif @@ -7338,7 +7454,7 @@ static void linearize_fload_x_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_p) } } -#ifdef I486 +#if defined (I486) || defined (ARM) static void linearize_fload_s_x_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_p) { INSTRUCTION_GRAPH graph_1,graph_2; @@ -7532,7 +7648,7 @@ static void linearize_float_graph (INSTRUCTION_GRAPH graph,ADDRESS *ad_p) case GFLOAD_X: linearize_fload_x_operator (graph,ad_p); return; -#ifdef I486 +#if defined (I486) || defined (ARM) case GFLOAD_S_X: linearize_fload_s_x_operator (graph,ad_p); return; @@ -7560,18 +7676,22 @@ static void linearize_float_graph (INSTRUCTION_GRAPH graph,ADDRESS *ad_p) case GFITOR: linearize_itor_operator (graph,ad_p); return; +#ifndef ARM case GFCOS: linearize_monadic_float_operator (graph,ad_p,IFCOS); break; +#endif case GFNEG: linearize_monadic_float_operator (graph,ad_p,IFNEG); break; case GFABS: linearize_monadic_float_operator (graph,ad_p,IFABS); break; +#ifndef ARM case GFSIN: linearize_monadic_float_operator (graph,ad_p,IFSIN); break; +#endif case GFTAN: linearize_monadic_float_operator (graph,ad_p,IFTAN); break; @@ -7642,7 +7762,7 @@ static void linearize_fstore_operator (INSTRUCTION_GRAPH graph) } static void linearize_fstore_x_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_p); -#ifdef I486 +#if defined (I486) || defined (ARM) static void linearize_fstore_s_x_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_p); #endif @@ -7767,7 +7887,7 @@ static void linearize_create_r_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_p,i #endif #ifndef M68000 -# ifdef I486 +# if defined (I486) || defined (ARM) # ifdef G_A64 if (offset_from_heap_register+(2<<3) >= 127){ # else @@ -8152,8 +8272,9 @@ static void linearize_store_r_node (INSTRUCTION_GRAPH graph) graph=*register_graph_1_p; *register_graph_1_p=*register_graph_2_p; *register_graph_2_p=graph; - } else { + } else #endif + { register int reg_2; register_graph_2_p=NULL; @@ -8181,7 +8302,7 @@ static void linearize_store_r_node (INSTRUCTION_GRAPH graph) *register_graph_2_p=*register_graph_1_p; *register_graph_1_p=NULL; -#if defined (M68000) || defined (I486) +#if defined (M68000) || defined (I486) || defined (ARM) } #endif } else { @@ -8348,7 +8469,7 @@ static void linearize_load_b_x_operator (register INSTRUCTION_GRAPH graph,regist free_dregister (ad_1.ad_register); reg_1=get_dregister(); -# ifdef I486 +# if defined (I486) || defined (ARM) i_moveb_x_r (offset & ~3,ad_p->ad_register,ad_1.ad_register,reg_1); # else if (offset & 1){ @@ -8546,7 +8667,7 @@ static void do_array_selects_before_update (INSTRUCTION_GRAPH select_graph,INSTR } } break; -#ifdef I486 +#if defined (I486) || defined (ARM) case GFLOAD_S_X: if (graph_2==select_graph->instruction_parameters[0].p){ if (select_graph->node_count>0 && !(select_graph->inode_arity & LOAD_X_TO_REGISTER)){ @@ -8909,7 +9030,7 @@ static void linearize_graph (INSTRUCTION_GRAPH graph,ADDRESS *ad_p) { int reg_1; -#if defined (I486) && !defined (MACH_O64) +#if (defined (I486) || defined (ARM)) && !defined (MACH_O64) if (graph->node_count==1 # if defined (G_AI64) && defined (LINUX) && !pic_flag @@ -8955,7 +9076,7 @@ static void linearize_graph (INSTRUCTION_GRAPH graph,ADDRESS *ad_p) ad_p->ad_count_p=&graph->node_count; return; -#if defined (I486) && !defined (MACH_O64) +#if (defined (I486) || defined (ARM)) && !defined (MACH_O64) } #endif } @@ -9256,7 +9377,7 @@ static void linearize_graph (INSTRUCTION_GRAPH graph,ADDRESS *ad_p) case GFSTORE_X: linearize_fstore_x_operator (graph,ad_p); return; -#ifdef I486 +#if defined (I486) || defined (ARM) case GFSTORE_S_X: linearize_fstore_s_x_operator (graph,ad_p); return; @@ -9286,7 +9407,7 @@ static void linearize_graph (INSTRUCTION_GRAPH graph,ADDRESS *ad_p) case GSUB: linearize_dyadic_non_commutative_operator (ISUB,graph,ad_p); return; -#if defined (I486) || defined (G_POWER) +#if defined (I486) || defined (ARM) || defined (G_POWER) case GDIV: linearize_div_rem_operator (IDIV,graph,ad_p); return; @@ -9296,7 +9417,7 @@ static void linearize_graph (INSTRUCTION_GRAPH graph,ADDRESS *ad_p) case GDIVU: linearize_div_rem_operator (IDIVU,graph,ad_p); return; -# ifdef I486 +# if defined (I486) || defined (ARM) case GREMU: linearize_div_rem_operator (IREMU,graph,ad_p); return; @@ -9309,7 +9430,7 @@ static void linearize_graph (INSTRUCTION_GRAPH graph,ADDRESS *ad_p) linearize_rem_operator (IREM,graph,ad_p); return; #endif -#ifdef I486 +#if defined (I486) || defined (ARM) case GFLOORDIV: linearize_floordiv_mod_operator (IFLOORDIV,graph,ad_p); return; @@ -9377,12 +9498,16 @@ static void linearize_graph (INSTRUCTION_GRAPH graph,ADDRESS *ad_p) case GNEG: linearize_monadic_data_operator (INEG,graph,ad_p); return; -#if defined (I486) || defined (G_POWER) +#if defined (I486) || defined (ARM) || defined (G_POWER) case GNOT: linearize_monadic_data_operator (INOT,graph,ad_p); return; #endif -#ifdef I486 +#ifdef ARM + case GROTR: + linearize_shift_operator (IROTR,graph,ad_p); + return; +#elif defined (I486) case GROTL: linearize_shift_operator (IROTL,IROTL_S,graph,ad_p); return; @@ -9444,7 +9569,7 @@ static void linearize_graph (INSTRUCTION_GRAPH graph,ADDRESS *ad_p) linearize_dyadic_commutative_data_operator (IUMULH,graph,ad_p); return; #endif -#ifdef I486 +#if defined (I486) || defined (ARM) case GRESULT0: case GRESULT1: linearize_two_results_operator (graph,ad_p); @@ -9552,7 +9677,7 @@ static void linearize_fstore_x_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_p) free_dregister (ad_3.ad_register); #ifndef M68000 -# ifdef I486 +# if defined (I486) || defined (ARM) if (ad_1.ad_mode==P_INDEXED) # else if (ad_1.ad_mode!=P_F_REGISTER) @@ -9572,7 +9697,7 @@ static void linearize_fstore_x_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_p) } } -#ifdef I486 +#if defined (I486) || defined (ARM) static void linearize_fstore_s_x_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_p) { INSTRUCTION_GRAPH graph_1,graph_2,graph_3; @@ -9912,7 +10037,7 @@ static void show_parameter (struct parameter *parameter) printf ("(A%d)+",a_reg_num (parameter->parameter_data.reg.r)); break; #endif -#if defined (M68000) || defined (I486) +#if defined (M68000) || defined (I486) || defined (ARM) case P_PRE_DECREMENT: printf ("-(A%d)",a_reg_num (parameter->parameter_data.reg.r)); break; @@ -14,23 +14,29 @@ void allocate_aregister (int aregister); void allocate_dregister (int dregister); void allocate_fregister (int fregister); #ifdef M68000 -void instruction_pd (int instruction_code,int register_1); + void instruction_pd (int instruction_code,int register_1); #endif void i_jmp_l (LABEL *label,int n_a_registers); void i_jmp_id (int offset_1,int register_1,int n_a_registers); -#if ! (defined (sparc) || defined (G_POWER)) +#if defined (M68000) || defined (I486) void i_jsr_id (int offset,int register_1,int n_a_registers); void i_jsr_l (LABEL *label,int n_a_registers); +#endif +#if ! (defined (sparc) || defined (G_POWER)) void i_rts (void); # ifdef I486 void i_rts_i (int offset); +# endif +# if defined (I486) || defined (ARM) void i_rts_profile (void); void i_jmp_r_profile (int a_reg); void i_jmp_l_profile (LABEL *label,int offset); void i_jmp_id_profile (int offset_1,int register_1,int n_a_registers); # endif #else - void i_jsr_id_id (int offset_1,int register_1,int offset_2); +# ifndef ARM + void i_jsr_id_id (int offset_1,int register_1,int offset_2); +# endif void i_jsr_l_id (LABEL *label,int offset); void i_rts (int offset_1,int offset_2); # ifdef G_POWER @@ -40,11 +46,16 @@ void i_jmp_id (int offset_1,int register_1,int n_a_registers); void i_jmp_l_profile (LABEL *label,int offset); void i_jmp_id_profile (int offset_1,int register_1,int n_a_registers); void i_rts_profile (int offset_1,int offset_2); - void i_jsr_id_idu (int offset_1,int register_1,int offset_2); - void i_jsr_l_idu (LABEL *label,int offset); # endif #endif -#if defined (sparc) +#if defined (G_POWER) || defined (ARM) + void i_jsr_id_idu (int offset_1,int register_1,int offset_2); + void i_jsr_l_idu (LABEL *label,int offset); +#endif +#if defined (ARM) + void i_jsr_r_idu (int register_1,int offset); +#endif +#if defined (sparc) || defined (ARM) void i_call_l (LABEL *label); void i_call_r (int register_1); #elif defined (G_POWER) @@ -56,15 +67,17 @@ void i_beq_l (LABEL *label); extern LONG *i_bmi_i (VOID); void i_bmi_l (LABEL *label); #endif -#if defined (G_POWER) || defined (G_AI64) +#if defined (G_POWER) || defined (G_AI64) || defined (ARM) void i_or_i_r (LONG value,int register_1); #endif -#ifdef G_POWER +#if defined (G_POWER) || defined (ARM) void i_and_i_r (LONG value,int register_1); +#endif +#ifdef G_POWER void i_bnep_l (LABEL *label); void i_mtctr (int register_1); #endif -#if defined (sparc) || defined (I486) || defined (G_POWER) +#if defined (sparc) || defined (I486) || defined (ARM) || defined (G_POWER) void i_btst_i_r (LONG i,int register_1); #endif void i_ext_r (int register_1); @@ -82,14 +95,19 @@ void i_fmove_id_fr (int offset,int register_2,int register_1); void i_fmove_pd_fr (int register_1,int register_2); void i_fmove_pi_fr (int register_1,int register_2); void i_move_id_pd (int offset,int register_1,int register_2); -#ifdef I486 +#if defined (I486) || defined (ARM) void i_fmoves_fr_id (int register_1,int offset,int register_2); #endif #endif void i_move_id_id (int offset_1,int register_1,int offset_2,int register_2); void i_move_id_r (int offset,int register_1,int register_2); -#ifdef G_POWER +#if defined (G_POWER) || defined (ARM) void i_move_idu_r (int offset,int register_1,int register_2); +#endif +#if defined (ARM) +void i_move_r_idpa (int register_1,int register_2,int offset); +#endif +#ifdef G_POWER void i_move_id_idu (int offset1,int register_1,int offset2,int register_2); void i_move_r_idu (int register_1,int offset,int register_2); void i_movew_id_idu (int offset1,int register_1,int offset2,int register_2); @@ -102,7 +120,7 @@ void i_move_pi_id (int register_1,int offset_2,int register_2); void i_move_pi_r (int register_1,int register_2); void i_move_pd_r (int register_1,int register_2); #endif -#if defined (I486) +#if defined (I486) || defined (ARM) void i_move_r_l (int register_1,LABEL *label); #endif void i_move_r_id (int register_1,int offset,int register_2); @@ -120,6 +138,12 @@ void i_movew_pi_id (int register_1,int offset_2,int register_2); void i_movew_pi_r (int register_1,int register_2); void i_movew_r_pd (int register_1,int register_2); #endif +#if defined (ARM) + void i_movem_pd_rs (int register_1,int n_arguments,int arguments[]); + void i_movem_pi_rs (int register_1,int n_arguments,int arguments[]); + void i_movem_rs_pd (int n_arguments,int arguments[],int register_1); + void i_movem_rs_pi (int n_arguments,int arguments[],int register_1); +#endif void i_movew_id_r (int offset,int register_1,int register_2); void i_lea_id_r (int offset,int register_1,int register_2); void i_lea_l_i_r (LABEL *label,int offset,int register_1); @@ -38,7 +38,7 @@ # define IF_G_SPARC(a) #endif -#if defined (G_POWER) || defined (sparc) +#if defined (G_POWER) || defined (sparc) || defined (ARM) # define IF_G_RISC(a) a #else # define IF_G_RISC(a) @@ -47,7 +47,7 @@ #define for_l(v,l,n) for(v=(l);v!=NULL;v=v->n) #define POWER_PC_A_STACK_OPTIMIZE -#ifdef I486 +#if defined (I486) || defined (ARM) # define OPTIMIZE_LOOPS #endif @@ -74,7 +74,7 @@ static void optimize_branch_jump (struct instruction *branch,LABEL *new_branch_l case IBGTU: branch->instruction_icode=IBLEU; break; case IBLEU: branch->instruction_icode=IBGTU; break; case IBLTU: branch->instruction_icode=IBGEU; break; -#if !defined (I486_USE_SCRATCH_REGISTER) || defined (G_A64) +#if !defined (I486_USE_SCRATCH_REGISTER) || defined (G_A64) || defined (ARM) case IFBEQ: branch->instruction_icode=IFBNE; break; case IFBGE: branch->instruction_icode=IFBLT; break; case IFBGT: branch->instruction_icode=IFBLE; break; @@ -118,7 +118,7 @@ void optimize_jumps (void) switch (branch->instruction_icode){ case IBEQ: case IBGE: case IBGT: case IBLE: case IBLT: case IBNE: case IBGEU: case IBGTU: case IBLEU: case IBLTU: -#if !defined (I486_USE_SCRATCH_REGISTER) || defined (G_A64) +#if !defined (I486_USE_SCRATCH_REGISTER) || defined (G_A64) || defined (ARM) case IFBEQ: case IFBGE: case IFBGT: case IFBLE: case IFBLT: case IFBNE: #endif { @@ -275,7 +275,7 @@ void optimize_jumps (void) struct block_label *branch_block_label,*branch_next_block_label; struct instruction *old_cmp_instruction,*old_branch_instruction,*new_branch_instruction; LABEL *branch_label,*new_jmp_label; -# ifdef I486 +# if defined (I486) || defined (ARM) struct instruction *previous_instruction; # endif @@ -298,7 +298,7 @@ void optimize_jumps (void) if (branch_block_label->block_label_label==branch_label) break; -# ifdef I486 +# if defined (I486) || defined (ARM) if (old_cmp_instruction->instruction_parameters[0].parameter_type==P_IMMEDIATE && old_cmp_instruction->instruction_parameters[0].parameter_data.i==0 && old_cmp_instruction->instruction_parameters[1].parameter_type==P_REGISTER && @@ -309,6 +309,13 @@ void optimize_jumps (void) { new_jmp_label = get_label_of_block (jmp_next_block); +# ifdef ARM + if (previous_instruction->instruction_icode==ISUB) + previous_instruction->instruction_icode=ISUBO; + else if (previous_instruction->instruction_icode==IADD) + previous_instruction->instruction_icode=IADDO; +# endif + if (branch_next_block_label!=NULL){ branch->instruction_icode=old_branch_instruction->instruction_icode; branch->instruction_parameters[0]=old_branch_instruction->instruction_parameters[0]; @@ -401,7 +408,7 @@ void optimize_jumps (void) #endif } -#if defined (M68000) || defined (I486) +#if defined (M68000) || defined (I486) || defined (ARM) # ifdef M68000 static struct parameter *previous_a_parameter; @@ -419,12 +426,17 @@ static int get_argument_size (int instruction_code) case IEOR: case ILSL: case ILSR: case IREM: case IMOVE: case IMUL: case IOR: case ISUB: case ITST: IF_G_RISC (case IADDI: case ILSLI:) -IF_G_SPARC (case IADDO: case ISUBO: ) -#ifdef I486 - case IDIVI: case IREMI: case IREMU: case IMULUD: case IDIVDU: +#if defined (sparc) || defined (ARM) + case IADDO: case ISUBO: +#endif +#if defined (I486) || defined (ARM) + case IDIVI: case IREMI: case IREMU: case IMULUD: case IFLOORDIV: case IMOD: #endif -#if (defined (I486) && !defined (I486_USE_SCRATCH_REGISTER)) || defined (G_POWER) +#ifdef I486 + case IDIVDU: +#endif +#if ((defined (I486) || defined (ARM)) && !defined (I486_USE_SCRATCH_REGISTER)) || defined (G_POWER) case IDIVU: #endif IF_G_POWER ( case IUMULH: ) @@ -486,7 +498,7 @@ static void optimize_a_stack_access (struct parameter *parameter,int instruction extern struct basic_block *last_block; extern struct instruction *last_instruction; -#if defined (M68000) | defined (I486) +#if defined (M68000) || defined (I486) || defined (ARM) static void insert_decrement_b_stack_pointer (struct instruction *next_instruction,int offset) { struct instruction *previous_instruction,*instruction; @@ -524,7 +536,7 @@ static void insert_decrement_b_stack_pointer (struct instruction *next_instructi } #endif -#ifdef I486 +#if defined (I486) || defined (ARM) static void optimize_b_stack_access (struct parameter *parameter,struct instruction *instruction) { if (parameter->parameter_offset<b_offset){ @@ -673,7 +685,11 @@ static void compute_maximum_b_stack_offsets (register int b_offset) #ifdef M68000 instruction->instruction_icode!=IMOVEM && #endif -#ifdef I486 +#ifdef ARM + instruction->instruction_icode!=IADDI && + instruction->instruction_icode!=ILSLI && +#endif +#if defined (I486) || defined (ARM) # ifdef THREAD32 instruction->instruction_icode!=IDIV && instruction->instruction_icode!=IDIVU && @@ -682,14 +698,18 @@ static void compute_maximum_b_stack_offsets (register int b_offset) instruction->instruction_icode!=IDIVI && instruction->instruction_icode!=IREMI && instruction->instruction_icode!=IREMU && +# ifndef ARM instruction->instruction_icode!=IDIVDU && instruction->instruction_icode!=IASR_S && instruction->instruction_icode!=ILSL_S && instruction->instruction_icode!=ILSR_S && +# endif instruction->instruction_icode!=IFLOORDIV && instruction->instruction_icode!=IMOD && +# ifndef ARM instruction->instruction_icode!=IROTL_S && instruction->instruction_icode!=IROTR_S && +# endif #endif instruction->instruction_icode!=IREM) #ifdef M68000 @@ -728,7 +748,30 @@ static void compute_maximum_b_stack_offsets (register int b_offset) } } -void optimize_stack_access (struct basic_block *block,int *a_offset_p,int *b_offset_p) +#ifdef ARM +static int is_int_instruction (int icode) +{ + switch (icode){ + case IMOVE: + case IADD: case ISUB: case ICMP: case ITST: case INEG: /* case IADDI: */ + case IAND: case IOR: case IEOR: case INOT: + case ILSL: case ILSR: case IASR: case IROTR: /* case ILSLI: */ + case IMUL: case IMULUD: + case IDIV: case IDIVI: case IFLOORDIV: case IDIVU: + case IREM: case IREMI: case IREMU: case IMOD: + case IADC: case ISBB: case IADDO: case ISUBO: + return 1; + default: + return 0; + } +} +#endif + +void optimize_stack_access (struct basic_block *block,int *a_offset_p,int *b_offset_p +# ifdef ARM + ,int try_adjust_b_stack_pointer +# endif + ) { struct instruction *instruction; @@ -736,6 +779,13 @@ void optimize_stack_access (struct basic_block *block,int *a_offset_p,int *b_off a_offset=0; previous_a_parameter=NULL; # endif +# ifdef ARM + struct parameter *previous_a_stack_parameter,*previous_b_stack_parameter; + int previous_a_stack_parameter_icode,previous_b_stack_parameter_icode; + + previous_a_stack_parameter=NULL; + previous_b_stack_parameter=NULL; +# endif b_offset=0; @@ -746,15 +796,11 @@ void optimize_stack_access (struct basic_block *block,int *a_offset_p,int *b_off switch (instruction->instruction_arity){ default: if ( -# ifdef M68000 instruction->instruction_icode!=IMOVEM && -# endif instruction->instruction_icode!=IREM) -# ifdef M68000 if (instruction->instruction_icode==IBMOVE) break; else -# endif internal_error_in_function ("optimize_stack_access"); /* only first argument of movem or mod might be register indirect */ /* no break ! */ @@ -824,9 +870,22 @@ void optimize_stack_access (struct basic_block *block,int *a_offset_p,int *b_off *a_offset_p-=a_offset; # endif -# ifdef I486 +# if defined (I486) || defined (ARM) for_l (instruction,block->block_instructions,instruction_next){ if (instruction->instruction_icode==IMOVE){ +# ifdef ARM + if (instruction->instruction_parameters[1].parameter_type==P_INDIRECT && + instruction->instruction_parameters[1].parameter_data.reg.r==A_STACK_POINTER) + { + previous_a_stack_parameter=&instruction->instruction_parameters[1]; + previous_a_stack_parameter_icode=IMOVE; + } else if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT && + instruction->instruction_parameters[0].parameter_data.reg.r==A_STACK_POINTER) + { + previous_a_stack_parameter=&instruction->instruction_parameters[0]; + previous_a_stack_parameter_icode=IMOVE; + } +# endif if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT && instruction->instruction_parameters[0].parameter_data.reg.r==B_STACK_POINTER) { @@ -837,14 +896,29 @@ void optimize_stack_access (struct basic_block *block,int *a_offset_p,int *b_off parameter0=&instruction->instruction_parameters[0]; parameter1=&instruction->instruction_parameters[1]; - +# ifdef ARM + previous_b_stack_parameter=parameter1; + previous_b_stack_parameter_icode=IMOVE; +# endif if (parameter1->parameter_offset<b_offset && parameter1->parameter_offset!=b_offset-STACK_ELEMENT_SIZE){ +# ifdef ARM + parameter0->parameter_offset-=b_offset; + parameter1->parameter_type=P_INDIRECT_WITH_UPDATE; + { + int offset=parameter1->parameter_offset; + + parameter1->parameter_offset=offset-b_offset; + b_offset=offset; + } + continue; +# else insert_decrement_b_stack_pointer (instruction,b_offset-parameter1->parameter_offset); b_offset=parameter1->parameter_offset; parameter0->parameter_offset-=b_offset; parameter1->parameter_offset=0; continue; +# endif } if (parameter0->parameter_offset<b_offset){ @@ -878,10 +952,25 @@ void optimize_stack_access (struct basic_block *block,int *a_offset_p,int *b_off struct parameter *parameter; parameter=&instruction->instruction_parameters[0]; - +# ifdef ARM + previous_b_stack_parameter=parameter; + previous_b_stack_parameter_icode=IMOVE; +# endif + if (parameter->parameter_offset<b_offset){ +# ifdef ARM + parameter->parameter_type=P_INDIRECT_WITH_UPDATE; + { + int offset=parameter->parameter_offset; + + parameter->parameter_offset=offset-b_offset; + b_offset=offset; + } + continue; +# else insert_decrement_b_stack_pointer (instruction,b_offset-parameter->parameter_offset); b_offset=parameter->parameter_offset; +# endif } else if (parameter->parameter_offset==b_offset && b_offset<((WORD)parameter->parameter_data.reg.u)) @@ -902,15 +991,29 @@ void optimize_stack_access (struct basic_block *block,int *a_offset_p,int *b_off struct parameter *parameter; parameter=&instruction->instruction_parameters[1]; - +# ifdef ARM + previous_b_stack_parameter=parameter; + previous_b_stack_parameter_icode=IMOVE; +# endif if (parameter->parameter_offset<b_offset){ if (parameter->parameter_offset==b_offset-STACK_ELEMENT_SIZE){ b_offset-=STACK_ELEMENT_SIZE; parameter->parameter_type=P_PRE_DECREMENT; continue; } else { +# ifdef ARM + parameter->parameter_type=P_INDIRECT_WITH_UPDATE; + { + int offset=parameter->parameter_offset; + + parameter->parameter_offset=offset-b_offset; + b_offset=offset; + } + continue; +# else insert_decrement_b_stack_pointer (instruction,b_offset-parameter->parameter_offset); b_offset=parameter->parameter_offset; +# endif } } @@ -922,6 +1025,10 @@ void optimize_stack_access (struct basic_block *block,int *a_offset_p,int *b_off switch (instruction->instruction_arity){ default: if ( +#ifdef ARM + instruction->instruction_icode!=IADDI && + instruction->instruction_icode!=ILSLI && +#endif # ifdef THREAD32 instruction->instruction_icode!=IDIV && instruction->instruction_icode!=IDIVU && @@ -930,39 +1037,119 @@ void optimize_stack_access (struct basic_block *block,int *a_offset_p,int *b_off instruction->instruction_icode!=IDIVI && instruction->instruction_icode!=IREMI && instruction->instruction_icode!=IREMU && +# ifndef ARM instruction->instruction_icode!=IDIVDU && instruction->instruction_icode!=IASR_S && instruction->instruction_icode!=ILSL_S && instruction->instruction_icode!=ILSR_S && +# endif instruction->instruction_icode!=IFLOORDIV && instruction->instruction_icode!=IMOD && - instruction->instruction_icode!=IREM && - instruction->instruction_icode!=IROTL_S && - instruction->instruction_icode!=IROTR_S) + instruction->instruction_icode!=IREM +# ifndef ARM + && instruction->instruction_icode!=IROTL_S + && instruction->instruction_icode!=IROTR_S +# endif + ) internal_error_in_function ("optimize_stack_access"); /* only first argument of mod might be register indirect */ /* no break ! */ case 1: - if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT && - instruction->instruction_parameters[0].parameter_data.reg.r==B_STACK_POINTER) - optimize_b_stack_access - (&instruction->instruction_parameters[0],instruction); + if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT){ + if (instruction->instruction_parameters[0].parameter_data.reg.r==B_STACK_POINTER){ + optimize_b_stack_access (&instruction->instruction_parameters[0],instruction); +# ifdef ARM + previous_b_stack_parameter=&instruction->instruction_parameters[0]; + previous_b_stack_parameter_icode=instruction->instruction_icode; + } else if (instruction->instruction_parameters[0].parameter_data.reg.r==A_STACK_POINTER){ + previous_a_stack_parameter=&instruction->instruction_parameters[0]; + previous_a_stack_parameter_icode=instruction->instruction_icode; +# endif + } + } break; case 2: if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT && instruction->instruction_parameters[0].parameter_data.reg.r==B_STACK_POINTER) { - if (instruction->instruction_parameters[1].parameter_type==P_INDIRECT - && instruction->instruction_parameters[1].parameter_data.reg.r==B_STACK_POINTER) + if (instruction->instruction_parameters[1].parameter_type==P_INDIRECT && + instruction->instruction_parameters[1].parameter_data.reg.r==B_STACK_POINTER) { optimize_b_stack_access2 (instruction); - } else +# ifdef ARM + previous_b_stack_parameter=&instruction->instruction_parameters[1]; + previous_b_stack_parameter_icode=instruction->instruction_icode; +# endif + } else { optimize_b_stack_access (&instruction->instruction_parameters[0],instruction); +# ifdef ARM + previous_b_stack_parameter=&instruction->instruction_parameters[0]; + previous_b_stack_parameter_icode=instruction->instruction_icode; +# endif + } + } else if (instruction->instruction_parameters[1].parameter_type==P_INDIRECT && + instruction->instruction_parameters[1].parameter_data.reg.r==B_STACK_POINTER) + { + optimize_b_stack_access (&instruction->instruction_parameters[1],instruction); +# ifdef ARM + previous_b_stack_parameter=&instruction->instruction_parameters[1]; + previous_b_stack_parameter_icode=instruction->instruction_icode; +# endif } +# ifdef ARM if (instruction->instruction_parameters[1].parameter_type==P_INDIRECT && - instruction->instruction_parameters[1].parameter_data.reg.r==B_STACK_POINTER) - optimize_b_stack_access - (&instruction->instruction_parameters[1],instruction); + instruction->instruction_parameters[1].parameter_data.reg.r==A_STACK_POINTER) + { + previous_a_stack_parameter=&instruction->instruction_parameters[1]; + previous_a_stack_parameter_icode=instruction->instruction_icode; + } else if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT && + instruction->instruction_parameters[0].parameter_data.reg.r==A_STACK_POINTER) + { + previous_a_stack_parameter=&instruction->instruction_parameters[0]; + previous_a_stack_parameter_icode=instruction->instruction_icode; + } +# endif + } + } +# endif + +# ifdef ARM + { + int offset; + + offset=*b_offset_p-b_offset; + if (previous_b_stack_parameter!=NULL && offset!=0 && is_int_instruction (previous_b_stack_parameter_icode)){ + if (previous_b_stack_parameter->parameter_type==P_INDIRECT && try_adjust_b_stack_pointer){ + if (previous_b_stack_parameter->parameter_offset==0){ + if (offset==STACK_ELEMENT_SIZE){ + previous_b_stack_parameter->parameter_type=P_POST_INCREMENT; + } else { + previous_b_stack_parameter->parameter_type=P_INDIRECT_POST_ADD; + previous_b_stack_parameter->parameter_offset=offset; + } + b_offset = *b_offset_p; + } else if (previous_b_stack_parameter->parameter_offset==offset){ + previous_b_stack_parameter->parameter_type=P_INDIRECT_WITH_UPDATE; + b_offset = *b_offset_p; + } + } else if (previous_b_stack_parameter->parameter_type==P_POST_INCREMENT){ + previous_b_stack_parameter->parameter_type=P_INDIRECT_POST_ADD; + previous_b_stack_parameter->parameter_offset=STACK_ELEMENT_SIZE+offset; + b_offset = *b_offset_p; + } + } + + if (previous_a_stack_parameter!=NULL && *a_offset_p!=0 && is_int_instruction (previous_a_stack_parameter_icode)){ + if (previous_a_stack_parameter->parameter_type==P_INDIRECT){ + if (previous_a_stack_parameter->parameter_offset==0){ + previous_a_stack_parameter->parameter_type=P_INDIRECT_POST_ADD; + previous_a_stack_parameter->parameter_offset=*a_offset_p; + *a_offset_p=0; + } else if (previous_a_stack_parameter->parameter_offset==*a_offset_p){ + previous_a_stack_parameter->parameter_type=P_INDIRECT_WITH_UPDATE; + *a_offset_p = 0; + } + } } } # endif @@ -1330,7 +1517,7 @@ static void use_parameter (struct parameter *parameter) switch (parameter->parameter_type){ case P_REGISTER: case P_INDIRECT: -#if defined (M68000) || defined (I486) +#if defined (M68000) || defined (I486) || defined (ARM) case P_POST_INCREMENT: case P_PRE_DECREMENT: #endif @@ -1439,7 +1626,7 @@ static void define_parameter (struct parameter *parameter) r_use_p->value_used=0; break; case P_INDIRECT: -#if defined (M68000) || defined (I486) +#if defined (M68000) || defined (I486) || defined (ARM) case P_POST_INCREMENT: case P_PRE_DECREMENT: #endif @@ -1552,27 +1739,34 @@ static void store_next_uses (struct instruction *instruction) #ifndef I486_USE_SCRATCH_REGISTER case IASR: case ILSL: case ILSR: case IDIV: -# ifdef I486 - case IROTL: case IROTR: +# if defined (I486) || defined (ARM) +# ifndef ARM + case IROTL: +# endif + case IROTR: # endif #endif -#if defined (I486) && !defined (I486_USE_SCRATCH_REGISTER) +#if (defined (I486) || defined (ARM)) && !defined (I486_USE_SCRATCH_REGISTER) case IMULUD: #endif -#if (defined (I486) && !defined (I486_USE_SCRATCH_REGISTER)) || defined (G_POWER) +#if ((defined (I486) || defined (ARM)) && !defined (I486_USE_SCRATCH_REGISTER)) || defined (G_POWER) case IDIVU: #endif case IEOR: case IFADD: case IFCMP: case IFDIV: case IFMUL: case IFREM: case IFSUB: case IMUL: case IOR: case ISUB: case ICMP: +#ifndef ARM case IEXG: +#endif IF_G_POWER (case ICMPLW:) -IF_G_SPARC (case IADDO: case ISUBO:) +#if defined (sparc) || defined (ARM) + case IADDO: case ISUBO: +#endif #if defined (I486) && defined (FP_STACK_OPTIMIZATIONS) case IFEXG: #endif IF_G_POWER ( case IUMULH: ) -#ifdef I486 +#if defined (I486) || defined (ARM) case IADC: case ISBB: #endif #ifdef M68000 @@ -1582,7 +1776,10 @@ IF_G_POWER ( case IUMULH: ) use_parameter (&instruction->instruction_parameters[0]); break; #ifdef I486_USE_SCRATCH_REGISTER - case IASR: case ILSL: case ILSR: case IROTL: case IROTR: + case IASR: case ILSL: case ILSR: case IROTR: +# ifndef ARM + case IROTL: +# endif if (instruction->instruction_parameters[0].parameter_type!=P_IMMEDIATE) define_scratch_register(); use_parameter (&instruction->instruction_parameters[1]); @@ -1609,7 +1806,7 @@ IF_G_POWER ( case IUMULH: ) use_parameter (&instruction->instruction_parameters[0]); break; #endif -#ifdef I486 +#if defined (I486) || defined (ARM) case IDIVI: case IREMI: # if defined (I486_USE_SCRATCH_REGISTER) && !defined (THREAD32) define_scratch_register(); @@ -1629,7 +1826,10 @@ IF_G_POWER ( case IUMULH: ) #ifdef G_AI64 case IMOVEQB: #endif - case IFCOS: case IFSIN: case IFTAN: +#ifndef ARM + case IFCOS: case IFSIN: +#endif + case IFTAN: #ifdef M68000 case IFACOS: case IFASIN: case IFATAN: case IFEXP: case IFLN: case IFLOG10: #endif @@ -1643,7 +1843,7 @@ IF_G_RISC (case IADDI: case ILSLI:) #ifdef G_AI64 case ILOADSQB: case IFCVT2S: #endif -#ifdef I486 +#if defined (I486) || defined (ARM) case IFLOADS: case IFMOVES: #endif #if defined (I486) && !defined (G_A64) @@ -1657,7 +1857,7 @@ IF_G_RISC (case IADDI: case ILSLI:) case IEXTB: #endif case INEG: -#if defined (I486) || defined (G_POWER) +#if defined (I486) || defined (ARM) || defined (G_POWER) case INOT: #endif /* case IJMP: case IJSR: */ @@ -1673,9 +1873,9 @@ IF_G_RISC (case IADDI: case ILSLI:) break; #ifndef I486_USE_SCRATCH_REGISTER case IREM: -# if defined (I486) || defined (G_POWER) +# if defined (I486) || defined (ARM) || defined (G_POWER) use_parameter (&instruction->instruction_parameters[1]); -# ifdef I486 +# if defined (I486) || defined (ARM) case IREMU: # endif use_parameter (&instruction->instruction_parameters[0]); @@ -1721,7 +1921,7 @@ IF_G_RISC (case IADDI: case ILSLI:) use_parameter (&instruction->instruction_parameters[0]); break; #endif -#ifdef I486 +#if defined (I486) || defined (ARM) case IFLOORDIV: case IMOD: define_parameter (&instruction->instruction_parameters[2]); use_parameter (&instruction->instruction_parameters[1]); @@ -2054,7 +2254,7 @@ static int find_register (int reg_n,register struct register_allocation *reg_all real_reg_n=REAL_D1; i=reg_alloc[REAL_D1].instruction_n; } -#ifndef I486 +# ifndef I486 if (reg_alloc[REAL_D2].instruction_n<i){ real_reg_n=REAL_D2; i=reg_alloc[REAL_D2].instruction_n; @@ -2067,6 +2267,8 @@ static int find_register (int reg_n,register struct register_allocation *reg_all real_reg_n=REAL_D4; i=reg_alloc[REAL_D4].instruction_n; } +# endif +# if ! (defined (I486) || defined (ARM)) if (reg_alloc[REAL_D5].instruction_n<i){ real_reg_n=REAL_D5; i=reg_alloc[REAL_D5].instruction_n; @@ -2079,7 +2281,7 @@ static int find_register (int reg_n,register struct register_allocation *reg_all real_reg_n=REAL_D7; i=reg_alloc[REAL_D7].instruction_n; } -#endif +# endif if (reg_alloc[REAL_A0].instruction_n<i){ real_reg_n=REAL_A0; i=reg_alloc[REAL_A0].instruction_n; @@ -2110,7 +2312,7 @@ static int find_register (int reg_n,register struct register_allocation *reg_all i=reg_alloc[REAL_A4].instruction_n; } #endif -#if ! (defined (I486) || defined (G_POWER)) +#if ! (defined (I486) || defined (ARM) || defined (G_POWER)) if (reg_alloc[REAL_A6].instruction_n<i){ real_reg_n=REAL_A6; i=reg_alloc[REAL_A6].instruction_n; @@ -2144,7 +2346,7 @@ static int find_register (int reg_n,register struct register_allocation *reg_all real_reg_n=6; i=reg_alloc[6].instruction_n; } -# if ! (defined (I486) && !defined (G_AI64)) +# if ! ((defined (I486) || defined (ARM)) && !defined (G_AI64)) if (reg_alloc[7].instruction_n<i){ real_reg_n=7; i=reg_alloc[7].instruction_n; @@ -2189,7 +2391,7 @@ static int find_register (int reg_n,register struct register_allocation *reg_all real_reg_n=1; i=reg_alloc[1].instruction_n; } -# ifdef I486 +# if defined (I486) || defined (ARM) if (register_flag!=D_REGISTER){ if (register_flag==F_REGISTER) if (reg_alloc[2].instruction_n<i){ @@ -2281,7 +2483,7 @@ static int find_non_reg_2_register (int reg_n,int avoid_reg_n, real_reg_n=REAL_D1; i=reg_alloc[REAL_D1].instruction_n; } -#ifndef I486 +# ifndef I486 if (reg_alloc[REAL_D2].instruction_n<i && avoid_reg_n!=REAL_D2){ real_reg_n=REAL_D2; i=reg_alloc[REAL_D2].instruction_n; @@ -2294,6 +2496,8 @@ static int find_non_reg_2_register (int reg_n,int avoid_reg_n, real_reg_n=REAL_D4; i=reg_alloc[REAL_D4].instruction_n; } +# endif +# if ! (defined (I486) || defined (ARM)) if (reg_alloc[REAL_D5].instruction_n<i && avoid_reg_n!=REAL_D5){ real_reg_n=REAL_D5; i=reg_alloc[REAL_D5].instruction_n; @@ -2306,7 +2510,7 @@ static int find_non_reg_2_register (int reg_n,int avoid_reg_n, real_reg_n=REAL_D7; i=reg_alloc[REAL_D7].instruction_n; } -#endif +# endif if (reg_alloc[REAL_A0].instruction_n<i && avoid_reg_n!=REAL_A0){ real_reg_n=REAL_A0; i=reg_alloc[REAL_A0].instruction_n; @@ -2337,7 +2541,7 @@ static int find_non_reg_2_register (int reg_n,int avoid_reg_n, i=reg_alloc[REAL_A4].instruction_n; } #endif -#if ! (defined (I486) || defined (G_POWER)) +#if ! (defined (I486) || defined (ARM) || defined (G_POWER)) if (reg_alloc[REAL_A6].instruction_n<i && avoid_reg_n!=REAL_A6){ real_reg_n=REAL_A6; i=reg_alloc[REAL_A6].instruction_n; @@ -2372,7 +2576,7 @@ static int find_non_reg_2_register (int reg_n,int avoid_reg_n, real_reg_n=6; i=reg_alloc[6].instruction_n; } -# if ! (defined (I486) && !defined (G_AI64)) +# if ! ((defined (I486) || defined (ARM)) && !defined (G_AI64)) if (reg_alloc[7].instruction_n<i && avoid_reg_n!=7){ real_reg_n=7; i=reg_alloc[7].instruction_n; @@ -2418,7 +2622,7 @@ static int find_non_reg_2_register (int reg_n,int avoid_reg_n, real_reg_n=1; i=reg_alloc[1].instruction_n; } -# ifdef I486 +# if defined (I486) || defined (ARM) if (register_flag!=D_REGISTER){ if (register_flag==F_REGISTER) if (reg_alloc[2].instruction_n<i && avoid_reg_n!=2){ @@ -2526,6 +2730,8 @@ static int find_reg_not_in_set real_reg_n=REAL_D4; i=reg_alloc[REAL_D4].instruction_n; } +# endif +# if ! (defined (I486) || defined (ARM)) if (reg_alloc[REAL_D5].instruction_n<i && !(avoid_reg_set & (1<<REAL_D5))){ real_reg_n=REAL_D5; i=reg_alloc[REAL_D5].instruction_n; @@ -2569,7 +2775,7 @@ static int find_reg_not_in_set i=reg_alloc[REAL_A4].instruction_n; } #endif -#if ! (defined (I486) || defined (G_POWER)) +#if ! (defined (I486) || defined (ARM) || defined (G_POWER)) if (reg_alloc[REAL_A6].instruction_n<i && !(avoid_reg_set & (1<<REAL_A6))){ real_reg_n=REAL_A6; i=reg_alloc[REAL_A6].instruction_n; @@ -2604,7 +2810,7 @@ static int find_reg_not_in_set real_reg_n=6; i=reg_alloc[6].instruction_n; } -# if ! (defined (I486) && !defined (G_AI64)) +# if ! ((defined (I486) || defined (ARM)) && !defined (G_AI64)) if (reg_alloc[7].instruction_n<i && !(avoid_reg_set & 128)){ real_reg_n=7; i=reg_alloc[7].instruction_n; @@ -3322,7 +3528,7 @@ static void instruction_use_def_reg (struct instruction *instruction) float_register_use (&instruction->instruction_parameters[1],DEF); } break; -#if defined (M68000) || defined (I486) +#if defined (M68000) || defined (I486) || defined (ARM) case P_POST_INCREMENT: case P_PRE_DECREMENT: register_use (&instruction->instruction_parameters[0].parameter_data.reg,USE_DEF); @@ -3400,7 +3606,7 @@ static void instruction_use_2 (struct instruction *instruction,int use_flag) (&instruction->instruction_parameters[0].parameter_data.reg,USE, &instruction->instruction_parameters[1].parameter_data.reg,USE); break; -#if defined (M68000) || defined (I486) +#if defined (M68000) || defined (I486) || defined (ARM) case P_POST_INCREMENT: case P_PRE_DECREMENT: register_use_2 @@ -3429,7 +3635,7 @@ static void instruction_use_2 (struct instruction *instruction,int use_flag) register_use (&instruction->instruction_parameters[0].parameter_data.reg,USE); } break; -#if defined (M68000) || defined (I486) +#if defined (M68000) || defined (I486) || defined (ARM) case P_POST_INCREMENT: case P_PRE_DECREMENT: switch (instruction->instruction_parameters[1].parameter_type){ @@ -3481,7 +3687,7 @@ static void instruction_use_2 (struct instruction *instruction,int use_flag) float_register_use (&instruction->instruction_parameters[0],USE); register_use (&instruction->instruction_parameters[1].parameter_data.reg,USE); break; -#if defined (M68000) || defined (I486) +#if defined (M68000) || defined (I486) || defined (ARM) case P_POST_INCREMENT: case P_PRE_DECREMENT: float_register_use (&instruction->instruction_parameters[0],USE); @@ -3524,7 +3730,7 @@ static void instruction_use_2 (struct instruction *instruction,int use_flag) &instruction->instruction_parameters[0].parameter_data.ir->d_reg, &instruction->instruction_parameters[1].parameter_data.reg,USE); break; -#if defined (M68000) || defined (I486) +#if defined (M68000) || defined (I486) || defined (ARM) case P_POST_INCREMENT: case P_PRE_DECREMENT: register_use_3_s_indexed @@ -3591,7 +3797,7 @@ static void instruction_use_2 (struct instruction *instruction,int use_flag) case P_INDIRECT: register_use (&instruction->instruction_parameters[1].parameter_data.reg,USE); break; -#if defined (M68000) || defined (I486) +#if defined (M68000) || defined (I486) || defined (ARM) case P_POST_INCREMENT: case P_PRE_DECREMENT: register_use (&instruction->instruction_parameters[1].parameter_data.reg,USE_DEF); @@ -3620,7 +3826,7 @@ static void instruction_use (struct instruction *instruction) case P_INDIRECT: register_use (&instruction->instruction_parameters[0].parameter_data.reg,USE); break; -#if defined (M68000) || defined (I486) +#if defined (M68000) || defined (I486) || defined (ARM) case P_POST_INCREMENT: case P_PRE_DECREMENT: register_use (&instruction->instruction_parameters[0].parameter_data.reg,USE_DEF); @@ -3645,7 +3851,7 @@ static void instruction_usedef (struct instruction *instruction) { switch (instruction->instruction_parameters[0].parameter_type){ case P_REGISTER: -#if defined (M68000) || defined (I486) +#if defined (M68000) || defined (I486) || defined (ARM) case P_POST_INCREMENT: case P_PRE_DECREMENT: register_use (&instruction->instruction_parameters[0].parameter_data.reg,USE_DEF); @@ -3678,7 +3884,7 @@ static void instruction_def (struct instruction *instruction) case P_INDIRECT: register_use (&instruction->instruction_parameters[0].parameter_data.reg,USE); break; -#if defined (M68000) || defined (I486) +#if defined (M68000) || defined (I486) || defined (ARM) case P_POST_INCREMENT: case P_PRE_DECREMENT: register_use (&instruction->instruction_parameters[0].parameter_data.reg,USE_DEF); @@ -3713,7 +3919,7 @@ static void instruction_fexg_usedef_usedef (struct instruction *instruction) } #endif -#ifndef I486 +#if ! (defined (I486) || defined (ARM)) static void instruction_mod_use_def_use (struct instruction *instruction) { switch (instruction->instruction_parameters[0].parameter_type){ @@ -3745,7 +3951,7 @@ static void instruction_mod_use_def_use (struct instruction *instruction) &instruction->instruction_parameters[2].parameter_data.reg,USE, D_REGISTER); break; -#if defined (M68000) || defined (I486) +#if defined (M68000) || defined (I486) || defined (ARM) case P_POST_INCREMENT: case P_PRE_DECREMENT: register_use (&instruction->instruction_parameters[0].parameter_data.reg,USE_DEF); @@ -3904,25 +4110,33 @@ static void allocate_registers (struct basic_block *basic_block) #ifndef I486_USE_SCRATCH_REGISTER case IASR: case ILSL: case ILSR: case IDIV: -# ifdef I486 - case IROTL: case IROTR: +# if defined (I486) || defined (ARM) +# ifndef ARM + case IROTL: +# endif + case IROTR: # endif #endif -#if (defined (I486) && !defined (I486_USE_SCRATCH_REGISTER)) || defined (G_POWER) +#if ((defined (I486) || defined (ARM)) && !defined (I486_USE_SCRATCH_REGISTER)) || defined (G_POWER) case IDIVU: #endif case IEOR: case IFADD: case IFCMP: case IFDIV: case IFMUL: case IFREM: case IFSUB: case IMUL: case IOR: case ISUB: -IF_G_SPARC (case IADDO: case ISUBO:) +#if defined (sparc) || defined (ARM) + case IADDO: case ISUBO: +#endif IF_G_POWER ( case IUMULH: ) -#ifdef I486 +#if defined (I486) || defined (ARM) case IADC: case ISBB: #endif instruction_use_2 (instruction,USE_DEF); break; #ifdef I486_USE_SCRATCH_REGISTER - case IASR: case ILSL: case ILSR: case IROTL: case IROTR: + case IASR: case ILSL: case ILSR: case IROTR: +# ifndef ARM + case IROTL: +# endif if (instruction->instruction_parameters[0].parameter_type!=P_IMMEDIATE){ use_scratch_register(); instruction_use_2 (instruction,USE_DEF); @@ -3980,7 +4194,10 @@ IF_G_POWER (case ICMPLW:) #ifdef G_AI64 case IMOVEQB: #endif - case IFCOS: case IFSIN: case IFTAN: +#ifndef ARM + case IFCOS: case IFSIN: +#endif + case IFTAN: #ifdef M68000 case IFACOS: case IFASIN: case IFATAN: case IFEXP: case IFLN: case IFLOG10: #endif @@ -3994,7 +4211,7 @@ IF_G_RISC (case IADDI: case ILSLI:) #ifdef G_AI64 case ILOADSQB: case IFCVT2S: #endif -#ifdef I486 +#if defined (I486) || defined (ARM) case IFLOADS: case IFMOVES: #endif #if 1 @@ -4013,7 +4230,7 @@ IF_G_RISC (case IADDI: case ILSLI:) case IEXTB: #endif case INEG: -#if defined (I486) || defined (G_POWER) +#if defined (I486) || defined (ARM) || defined (G_POWER) case INOT: #endif instruction_usedef (instruction); @@ -4030,10 +4247,12 @@ IF_G_RISC (case IADDI: case ILSLI:) #endif instruction_def (instruction); break; +#ifndef ARM case IEXG: instruction_usedef_usedef (instruction); break; -#ifdef I486 +#endif +#if defined (I486) || defined (ARM) case IMULUD: # ifdef THREAD32 use_3_same_type_registers @@ -4067,8 +4286,8 @@ IF_G_RISC (case IADDI: case ILSLI:) #endif #ifndef I486_USE_SCRATCH_REGISTER case IREM: -# if defined (I486) || defined (G_POWER) -# ifdef I486 +# if defined (I486) || defined (ARM) || defined (G_POWER) +# if defined (I486) || defined (ARM) case IREMU: # endif instruction_use_2 (instruction,USE_DEF); @@ -4077,7 +4296,7 @@ IF_G_RISC (case IADDI: case ILSLI:) # endif break; #endif -#ifdef I486 +#if defined (I486) || defined (ARM) case IDIVI: case IREMI: # ifndef THREAD32 # ifdef I486_USE_SCRATCH_REGISTER @@ -4119,7 +4338,7 @@ IF_G_RISC (case IADDI: case ILSLI:) # endif break; #endif -#ifdef I486 +#if defined (I486) || defined (ARM) case IFLOORDIV: case IMOD: if (instruction->instruction_arity==4) use_3_same_type_registers @@ -4224,7 +4443,7 @@ int do_register_allocation do_not_alter_condition_codes=0; -#ifndef I486 +#if !(defined (I486) || defined (ARM)) end_d_registers |= ((unsigned)1<<d_reg_num (REGISTER_D7)); #endif @@ -4243,7 +4462,7 @@ int do_register_allocation end_a_registers |= ((unsigned)1<<a_reg_num (A_STACK_POINTER)) | ((unsigned)1<<a_reg_num (B_STACK_POINTER)) | -#ifndef I486 +#if !(defined (I486) || defined (ARM)) ((unsigned)1<<a_reg_num (REGISTER_A5)) | #endif #ifdef G_POWER @@ -1,6 +1,10 @@ extern void optimize_jumps (VOID); -extern void optimize_stack_access (struct basic_block *block,int *a_offset_p,int *b_offset_p); +extern void optimize_stack_access (struct basic_block *block,int *a_offset_p,int *b_offset_p +# ifdef ARM + ,int try_adjust_b_stack_pointer +# endif + ); extern int do_register_allocation (struct instruction *last_instruction,struct basic_block *basic_block, int highest_a_register,int highest_d_register,int highest_f_register, @@ -18,7 +18,7 @@ # endif #endif -#if defined (I486) || defined (G_POWER) || defined (sparc) +#if defined (I486) || defined (ARM) || defined (G_POWER) || defined (sparc) # define NEW_DESCRIPTORS #endif @@ -73,12 +73,8 @@ # define DOUBLE double #endif -#ifdef sparc -#else -# if defined (I486) || defined (G_POWER) -# else -# define M68000 -# endif +#if ! (defined (sparc) || defined (I486) || defined (ARM) || defined (G_POWER)) +# define M68000 #endif #ifndef G_A64 @@ -99,7 +95,7 @@ # endif #endif -#if defined (I486) || (defined (G_POWER) || defined (ALIGN_C_CALLS)) || defined (MACH_O) +#if defined (I486) || defined (ARM) || (defined (G_POWER) || defined (ALIGN_C_CALLS)) || defined (MACH_O) # define SEPARATE_A_AND_B_STACK_OVERFLOW_CHECKS #endif @@ -42,6 +42,13 @@ enum { REGISTER_FP0, REGISTER_FP1, REGISTER_FP2, REGISTER_FP3, # define N_DATA_PARAMETER_REGISTERS 2 # define N_FLOAT_PARAMETER_REGISTERS 7 # endif +#elif defined (ARM) +# define A_STACK_POINTER REGISTER_A4 +# define HEAP_POINTER REGISTER_A5 +# define B_STACK_POINTER REGISTER_A6 +# define N_ADDRESS_PARAMETER_REGISTERS 3 +# define N_DATA_PARAMETER_REGISTERS 5 +# define N_FLOAT_PARAMETER_REGISTERS 8 #else # define A_STACK_POINTER REGISTER_A4 # if !(defined (sparc) || defined (G_POWER)) @@ -1345,7 +1345,7 @@ static int set_basic_block_begin_d_registers for (offset=0; offset<b_stack_size; ++offset) if (!test_bit (vector,offset)){ -#ifdef I486 +#if defined (I486) || defined (ARM) if (n_d_registers<n_data_parameter_registers) #else if (n_d_registers<n_data_parameter_registers-1) @@ -3364,7 +3364,11 @@ int block_stack_displacement; static WORD *check_size_p; #endif -static int stack_access_and_adjust_a_stack_pointer (int extra_b_offset,int do_not_alter_condition_codes) +static int stack_access_and_adjust_a_stack_pointer (int extra_b_offset,int do_not_alter_condition_codes +# ifdef ARM + ,int try_adjust_b_stack_pointer +# endif + ) { int a_offset,b_offset,minimum_b_offset; @@ -3434,8 +3438,12 @@ static int stack_access_and_adjust_a_stack_pointer (int extra_b_offset,int do_no b_offset+=extra_b_offset; -#if defined (M68000) || defined (I486) || defined (G_POWER) - optimize_stack_access (last_block,&a_offset,&b_offset); +#if defined (M68000) || defined (I486) || defined (ARM) || defined (G_POWER) + optimize_stack_access (last_block,&a_offset,&b_offset +# ifdef ARM + ,try_adjust_b_stack_pointer +# endif + ); #endif if (a_offset!=0) @@ -3456,7 +3464,11 @@ static void stack_access (int do_not_alter_condition_codes) { register int b_offset; - b_offset=stack_access_and_adjust_a_stack_pointer (0,do_not_alter_condition_codes); + b_offset=stack_access_and_adjust_a_stack_pointer (0,do_not_alter_condition_codes +# ifdef ARM + ,1 +# endif + ); if (b_offset!=0) #ifdef I486 @@ -3470,13 +3482,21 @@ static void stack_access (int do_not_alter_condition_codes) i_sub_i_r (-b_offset,B_STACK_POINTER); } -static int local_register_allocation_and_adjust_a_stack_pointer (int extra_b_offset) +static int local_register_allocation_and_adjust_a_stack_pointer (int extra_b_offset +# ifdef ARM + ,int try_adjust_b_stack_pointer +# endif + ) { int n_virtual_a_regs,n_virtual_d_regs,n_virtual_f_regs; get_n_virtual_registers (&n_virtual_a_regs,&n_virtual_d_regs,&n_virtual_f_regs); do_register_allocation (last_instruction,last_block,n_virtual_a_regs,n_virtual_d_regs,n_virtual_f_regs,0,0); - return stack_access_and_adjust_a_stack_pointer (extra_b_offset,0); + return stack_access_and_adjust_a_stack_pointer (extra_b_offset,0 +# ifdef ARM + ,try_adjust_b_stack_pointer +# endif + ); } void adjust_stack_pointers (void) @@ -3543,14 +3563,20 @@ generate_code_for_jsr_eval (int n_a_registers,int n_d_registers,int n_f_register int code_size; #endif -#if defined (sparc) || defined (I486) || defined (G_POWER) +#if defined (sparc) || defined (I486) || defined (ARM) || defined (G_POWER) int a_offset,b_offset; -#else +#endif +#if defined (M68000) static int d_registers[]={ REGISTER_D0,REGISTER_D1,REGISTER_D2,REGISTER_D3,REGISTER_D4, REGISTER_D5,REGISTER_D6 }; #endif +#if defined (ARM) + static int reversed_d_registers[]={ + REGISTER_D4,REGISTER_D3,REGISTER_D2,REGISTER_D1,REGISTER_D0 + }; +#endif node_a_register=n_a_registers-offset-1; @@ -3584,6 +3610,31 @@ generate_code_for_jsr_eval (int n_a_registers,int n_d_registers,int n_f_register if (n_a_registers>1) i_mtctr (num_to_d_reg (n_d_registers)); # else +# if defined (ARM) + if (node_a_register!=0 && (n_a_registers==1 || (n_a_registers==2 && node_a_register==1))){ + i_move_r_idpa (num_to_a_reg (0),A_STACK_POINTER,STACK_ELEMENT_SIZE); + } else if (node_a_register==0 && n_a_registers==2){ + i_move_r_idpa (num_to_a_reg (1),A_STACK_POINTER,STACK_ELEMENT_SIZE); + } else { + if (n_a_registers>2){ + int a_registers[3],a_reg_n; + + a_reg_n=0; + for (n=0; n<n_a_registers; ++n) + if (n!=node_a_register) + a_registers[a_reg_n++]=num_to_a_reg (n); + i_movem_rs_pi (a_reg_n,a_registers,A_STACK_POINTER); + } else { + for (n=0; n<n_a_registers; ++n) + if (n!=node_a_register){ + i_move_r_id (num_to_a_reg (n),a_offset,A_STACK_POINTER); + a_offset+=STACK_ELEMENT_SIZE; + } + if (a_offset>0) + i_add_i_r (a_offset,A_STACK_POINTER); + } + } +# else for (n=n_a_registers-1; n>=0; --n) if (n!=node_a_register){ i_move_r_id (num_to_a_reg (n),a_offset,A_STACK_POINTER); @@ -3591,6 +3642,7 @@ generate_code_for_jsr_eval (int n_a_registers,int n_d_registers,int n_f_register } if (a_offset>0) i_add_i_r (a_offset,A_STACK_POINTER); +# endif # endif #endif @@ -3612,17 +3664,34 @@ generate_code_for_jsr_eval (int n_a_registers,int n_d_registers,int n_f_register i_move_r_pd (num_to_d_reg (n),B_STACK_POINTER); code_size+=2; } -#else +#elif defined (I486) b_offset=0; -# ifdef I486 - for (n=0; n<n_d_registers; ++n) - i_move_r_pd (num_to_d_reg (n),B_STACK_POINTER); -# else - for (n=0; n<n_d_registers; ++n){ - b_offset+=STACK_ELEMENT_SIZE; - i_move_r_id (num_to_d_reg (n),-b_offset,B_STACK_POINTER); + for (n=0; n<n_d_registers; ++n) + i_move_r_pd (num_to_d_reg (n),B_STACK_POINTER); +#elif defined (ARM) + b_offset = n_d_registers << STACK_ELEMENT_LOG_SIZE; + if (n_d_registers!=0){ + if (n_d_registers==1){ + i_move_r_pd (num_to_d_reg (0),B_STACK_POINTER); + b_offset=0; + } else { + i_movem_rs_pd (n_d_registers,&reversed_d_registers[5-n_d_registers],B_STACK_POINTER); + b_offset=0; + /* + i_sub_i_r (b_offset,B_STACK_POINTER); + for (n=0; n<n_d_registers; ++n){ + b_offset-=STACK_ELEMENT_SIZE; + i_move_r_id (num_to_d_reg (n),b_offset,B_STACK_POINTER); + } + */ } -# endif + } +#else + b_offset=0; + for (n=0; n<n_d_registers; ++n){ + b_offset+=STACK_ELEMENT_SIZE; + i_move_r_id (num_to_d_reg (n),-b_offset,B_STACK_POINTER); + } #endif #ifdef M68000 @@ -3635,7 +3704,7 @@ generate_code_for_jsr_eval (int n_a_registers,int n_d_registers,int n_f_register b_offset+=8; i_fmove_fr_id (n,-b_offset,B_STACK_POINTER); } -# ifdef I486 +# if defined (I486) || defined (ARM) if (b_offset) i_sub_i_r (b_offset,B_STACK_POINTER); # else @@ -3649,28 +3718,26 @@ generate_code_for_jsr_eval (int n_a_registers,int n_d_registers,int n_f_register i_move_r_r (num_to_d_reg (n_d_registers),REGISTER_A1); i_jsr_id (0,REGISTER_A1,256); code_size+=4; -#else -# if defined (I486) - i_jsr_id (0,num_to_a_reg (node_a_register),0); -# else -# if defined (G_POWER) -# ifdef SMALLER_EVAL - if (n_a_registers>1){ - struct label *eval_label; +#elif defined (I486) + i_jsr_id (0,num_to_a_reg (node_a_register),0); +#elif defined (ARM) + i_jsr_r_idu (REGISTER_D6,-4); +#elif defined (G_POWER) +# ifdef SMALLER_EVAL + if (n_a_registers>1){ + struct label *eval_label; - if (n_a_registers==2) - eval_label = node_a_register==0 ? eval_01_label : eval_11_label; - else - eval_label = node_a_register==0 ? eval_02_label : node_a_register==1 ? eval_12_label : eval_22_label; + if (n_a_registers==2) + eval_label = node_a_register==0 ? eval_01_label : eval_11_label; + else + eval_label = node_a_register==0 ? eval_02_label : node_a_register==1 ? eval_12_label : eval_22_label; - i_jsr_l_idu (eval_label,-(b_offset+4)); - } else -# endif - i_jsr_id_idu (0,num_to_d_reg (n_d_registers),-(b_offset+4)); -# else - i_jsr_id_id (0,num_to_d_reg (n_d_registers),0); -# endif + i_jsr_l_idu (eval_label,-(b_offset+4)); + } else # endif + i_jsr_id_idu (0,num_to_d_reg (n_d_registers),-(b_offset+4)); +#else + i_jsr_id_id (0,num_to_d_reg (n_d_registers),0); #endif #ifdef M68000 @@ -3695,20 +3762,31 @@ generate_code_for_jsr_eval (int n_a_registers,int n_d_registers,int n_f_register i_move_pi_r (B_STACK_POINTER,num_to_d_reg (n)); code_size+=2; } -#else -# ifdef I486 +#elif defined (I486) if (b_offset>0) i_add_i_r (b_offset,B_STACK_POINTER); for (n=n_d_registers-1; n>=0; --n) i_move_pi_r (B_STACK_POINTER,num_to_d_reg (n)); -# else - for (n=n_d_registers-1; n>=0; --n){ - i_move_id_r (-offset,B_STACK_POINTER,num_to_d_reg (n)); - offset-=STACK_ELEMENT_SIZE; - } - if (b_offset>0) - i_add_i_r (b_offset,B_STACK_POINTER); +#else +# if defined (ARM) + if (offset==0){ + if (n_d_registers==1){ + i_move_pi_r (B_STACK_POINTER,num_to_d_reg (0)); + offset -= STACK_ELEMENT_SIZE; + } else if (n_d_registers>1){ + i_movem_pi_rs (B_STACK_POINTER,n_d_registers,&reversed_d_registers[5-n_d_registers]); + offset -= n_d_registers << STACK_ELEMENT_LOG_SIZE; + } + } else # endif + { + for (n=n_d_registers-1; n>=0; --n){ + i_move_id_r (-offset,B_STACK_POINTER,num_to_d_reg (n)); + offset-=STACK_ELEMENT_SIZE; + } + if (offset!=0) + i_add_i_r (-offset,B_STACK_POINTER); + } #endif if (node_a_register!=0){ @@ -3743,15 +3821,40 @@ generate_code_for_jsr_eval (int n_a_registers,int n_d_registers,int n_f_register i_move_id_r (offset,A_STACK_POINTER,num_to_a_reg (n)); } } -# else +# elif defined (ARM) + if (n_a_registers>2){ + int a_registers[3],a_reg_n; + + a_reg_n=0; for (n=0; n<n_a_registers; ++n) + if (n!=node_a_register) + a_registers[a_reg_n++]=num_to_a_reg (n); + i_movem_pd_rs (A_STACK_POINTER,a_reg_n,a_registers); + } else { + int last_a_register; + + last_a_register=0; + if (last_a_register==node_a_register) + ++last_a_register; + + for (n=n_a_registers-1; n>=0; --n) if (n!=node_a_register){ offset-=STACK_ELEMENT_SIZE; - i_move_id_r (offset,A_STACK_POINTER,num_to_a_reg (n)); + if (n==last_a_register) + i_move_idu_r (offset,A_STACK_POINTER,num_to_a_reg (n)); + else + i_move_id_r (offset,A_STACK_POINTER,num_to_a_reg (n)); } - if (a_offset>0) - i_sub_i_r (a_offset,A_STACK_POINTER); -#endif + } +# else + for (n=0; n<n_a_registers; ++n) + if (n!=node_a_register){ + offset-=STACK_ELEMENT_SIZE; + i_move_id_r (offset,A_STACK_POINTER,num_to_a_reg (n)); + } + if (a_offset>0) + i_sub_i_r (a_offset,A_STACK_POINTER); +# endif #endif #ifdef M68000 @@ -3798,7 +3901,7 @@ static void generate_code_for_basic_block (struct block_graph *next_block_graph) } n_data_parameter_registers = -#ifndef I486 +#if !(defined (I486) || defined (ARM)) block_graph->block_graph_kind==JSR_EVAL_BLOCK ? N_DATA_PARAMETER_REGISTERS-1 : #endif N_DATA_PARAMETER_REGISTERS; @@ -3848,7 +3951,7 @@ static void generate_code_for_basic_block (struct block_graph *next_block_graph) for (n=0; n<b_stack_size; ++n) if (!test_bit (vector,n)){ -#ifdef I486 +#if defined (I486) || defined (ARM) if (n_allocated_d_regs<n_data_parameter_registers) #else if (n_allocated_d_regs<n_data_parameter_registers-1) @@ -3868,14 +3971,22 @@ static void generate_code_for_basic_block (struct block_graph *next_block_graph) #else i_move_id_r (0-NODE_POINTER_OFFSET,num_to_a_reg (block_graph->block_graph_end_a_stack_size -block_graph->block_graph_jsr_eval_offset-1), +# if defined (ARM) + REGISTER_D6); +# else num_to_d_reg (n_allocated_d_regs)); +# endif # ifdef M68000 if (check_stack || parallel_flag) i_bmi_l (block_graph->block_graph_last_instruction_label); else branch_offset_p=i_bmi_i(); # else +# if defined (ARM) + i_btst_i_r (2,REGISTER_D6); +# else i_btst_i_r (2,num_to_d_reg (n_allocated_d_regs)); +# endif # ifdef G_POWER i_bnep_l (block_graph->block_graph_last_instruction_label); # else @@ -3903,14 +4014,18 @@ static void generate_code_for_basic_block (struct block_graph *next_block_graph) { int b_offset; -#if ! (defined (sparc) || defined (G_POWER)) +#if ! (defined (sparc) || defined (G_POWER) || defined (ARM)) b_offset=local_register_allocation_and_adjust_a_stack_pointer (end_b_stack_size==global_block.block_graph_b_stack_end_displacement ? STACK_ELEMENT_SIZE : 0); #else - b_offset=local_register_allocation_and_adjust_a_stack_pointer (0); + b_offset=local_register_allocation_and_adjust_a_stack_pointer (0 +# ifdef ARM + ,end_b_stack_size!=global_block.block_graph_b_stack_end_displacement +# endif + ); #endif -#ifdef G_POWER +#if defined (G_POWER) || defined (ARM) { int return_offset; @@ -4009,12 +4124,16 @@ static void generate_code_for_basic_block (struct block_graph *next_block_graph) } case APPLY_BLOCK: { - register int b_offset; + int b_offset; #if defined (sparc) || defined (G_POWER) b_offset=local_register_allocation_and_adjust_a_stack_pointer (-4); #else - b_offset=local_register_allocation_and_adjust_a_stack_pointer (0); + b_offset=local_register_allocation_and_adjust_a_stack_pointer (0 +# ifdef ARM + ,1 +# endif + ); #endif if (b_offset!=0) @@ -4023,24 +4142,24 @@ static void generate_code_for_basic_block (struct block_graph *next_block_graph) else i_add_i_r (b_offset,B_STACK_POINTER); -#if defined (I486) +#if defined (I486) || defined (ARM) i_move_id_r (0,REGISTER_A1,REGISTER_A2); # ifdef MACH_O64 i_jsr_id (8-2,REGISTER_A2,0); # elif defined (G_A64) && defined (LINUX) i_jsr_id (pic_flag ? 8-2 : 4-2,REGISTER_A2,0); +# elif defined (ARM) + i_jsr_id_idu (4-2,REGISTER_A2,-4); # else i_jsr_id (4-2,REGISTER_A2,0); # endif -#else -# ifdef M68000 -# if !defined (SUN) +#elif defined (M68000) +# if !defined (SUN) i_add_r_r (GLOBAL_DATA_REGISTER,REGISTER_A2); -# endif +# endif i_jsr_id (0,REGISTER_A2,2<<4); -# else +#else i_jsr_id_id (0,REGISTER_A2,0); -# endif #endif break; } @@ -4329,7 +4448,7 @@ void generate_code_for_previous_blocks (int jmp_jsr_or_rtn_flag) } } -#ifdef I486 +#if defined (I486) || defined (ARM) int end_basic_block_with_registers_and_return_address_and_return_b_stack_offset (int n_a_parameters,int n_b_parameters,ULONG vector[],int n_data_parameter_registers) { @@ -4353,7 +4472,11 @@ int end_basic_block_with_registers_and_return_address_and_return_b_stack_offset ); linearize_stack_graphs(); - b_stack_offset=local_register_allocation_and_adjust_a_stack_pointer (0); + b_stack_offset=local_register_allocation_and_adjust_a_stack_pointer (0 +# ifdef ARM + ,1 +# endif + ); return b_stack_offset; } @@ -4381,7 +4504,11 @@ int end_basic_block_with_registers_and_return_b_stack_offset (int n_a_parameters ); linearize_stack_graphs(); - b_stack_offset=local_register_allocation_and_adjust_a_stack_pointer (0); + b_stack_offset=local_register_allocation_and_adjust_a_stack_pointer (0 +# ifdef ARM + ,1 +# endif + ); return b_stack_offset; } @@ -39,7 +39,7 @@ extern void insert_basic_block_with_extra_parameters_on_stack (int block_graph_k extern void adjust_stack_pointers (VOID); extern void end_basic_block_with_registers (int n_a_parameters,int n_b_parameters,ULONG vector[]); -#ifdef I486 +#if defined (I486) || defined (ARM) extern int end_basic_block_with_registers_and_return_address_and_return_b_stack_offset (int n_a_parameters,int n_b_parameters,ULONG vector[],int n_data_parameter_registers); #endif @@ -43,6 +43,9 @@ typedef struct label { #if defined (G_A64) && defined (LINUX) struct label * u_got_jump_label; /* cgaas.c */ #endif +#ifdef ARM + struct literal_entry * u_literal_entry; /* cgarmas.c */ +#endif } label_u2; WORD label_last_lea_arity; } LABEL; @@ -55,6 +58,9 @@ typedef struct label { #if defined (G_A64) && defined (LINUX) # define label_got_jump_label label_u2.u_got_jump_label #endif +#ifdef ARM +# define label_literal_entry label_u2.u_literal_entry +#endif #define label_last_lea label_u1.u_last_lea #define label_ea_label label_u1.u_ea_label @@ -77,6 +83,9 @@ typedef struct label { #if defined (G_A64) && defined (LINUX) # define USE_PLT_LABEL 4096 #endif +#ifdef ARM +# define HAS_LITERAL_ENTRY 256 +#endif #define CMP_BRANCH_BLOCK_LABEL 8192 #if defined (G_A64) && defined (LINUX) # define USE_GOT_LABEL 16384 @@ -94,7 +103,7 @@ struct local_label { struct label local_label_label; }; -#ifdef I486 +#if defined (I486) || defined (ARM) struct reg { WORD r; UWORD u; |