diff options
author | Camil Staps | 2016-11-29 15:45:32 +0000 |
---|---|---|
committer | Camil Staps | 2016-11-29 15:45:32 +0000 |
commit | b3249a61f983e682d6065639fa283236661623bd (patch) | |
tree | 623fdf95cdcfeb78f8e821539606178c9b37ca61 | |
parent | Removed hardcoded register names except sp and pc in cgthumb2was.c (diff) |
Fix issue with A stack negative offset
-rw-r--r-- | cgopt.c | 54 |
1 files changed, 54 insertions, 0 deletions
@@ -536,6 +536,37 @@ static void insert_decrement_b_stack_pointer (struct instruction *next_instructi } #endif +#ifdef THUMB2 +static void insert_decrement_a_stack_pointer (struct instruction *next_instruction,int offset) +{ + struct instruction *previous_instruction,*instruction; + + instruction=(struct instruction*)fast_memory_allocate (sizeof (struct instruction)+2*sizeof (struct parameter)); + + instruction->instruction_arity=2; + instruction->instruction_icode=ILEA; + + instruction->instruction_parameters[0].parameter_type=P_INDIRECT; + instruction->instruction_parameters[0].parameter_offset=-offset; + instruction->instruction_parameters[0].parameter_data.reg.r=A_STACK_POINTER; + + instruction->instruction_parameters[1].parameter_type=P_REGISTER; + instruction->instruction_parameters[1].parameter_data.i=A_STACK_POINTER; + + previous_instruction=next_instruction->instruction_prev; + if (previous_instruction==NULL) + last_block->block_instructions=instruction; + else + previous_instruction->instruction_next=instruction; + + instruction->instruction_next=next_instruction; + instruction->instruction_prev=previous_instruction; + + if (next_instruction!=NULL) + next_instruction->instruction_prev=instruction; +} +#endif + #if defined (I486) || defined (ARM) static void optimize_b_stack_access (struct parameter *parameter,struct instruction *instruction) { @@ -787,6 +818,17 @@ void optimize_stack_access (struct basic_block *block,int *a_offset_p,int *b_off previous_b_stack_parameter=NULL; # endif +# ifdef THUMB2 + int fix_a_offset=0; + if (*a_offset_p <= -256) + { + fix_a_offset=0-*a_offset_p; + insert_decrement_a_stack_pointer (block->block_instructions, fix_a_offset); + i_add_i_r (fix_a_offset, A_STACK_POINTER); + *a_offset_p=0; + } +# endif + b_offset=0; compute_maximum_b_stack_offsets (*b_offset_p); @@ -874,14 +916,26 @@ void optimize_stack_access (struct basic_block *block,int *a_offset_p,int *b_off for_l (instruction,block->block_instructions,instruction_next){ if (instruction->instruction_icode==IMOVE){ # ifdef ARM + if (*a_offset_p == -600) + fprintf(stderr, "%d, %d, %d, %d\n", + instruction->instruction_icode, + instruction->instruction_parameters[0].parameter_type, + instruction->instruction_parameters[0].parameter_data.reg.r, + instruction->instruction_parameters[0].parameter_offset); if (instruction->instruction_parameters[1].parameter_type==P_INDIRECT && instruction->instruction_parameters[1].parameter_data.reg.r==A_STACK_POINTER) { +# ifdef THUMB2 + instruction->instruction_parameters[1].parameter_offset+=fix_a_offset; +# endif 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) { +# ifdef THUMB2 + instruction->instruction_parameters[0].parameter_offset+=fix_a_offset; +# endif previous_a_stack_parameter=&instruction->instruction_parameters[0]; previous_a_stack_parameter_icode=IMOVE; } |