summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCamil Staps2016-11-29 15:45:32 +0000
committerCamil Staps2016-11-29 15:45:32 +0000
commitb3249a61f983e682d6065639fa283236661623bd (patch)
tree623fdf95cdcfeb78f8e821539606178c9b37ca61
parentRemoved hardcoded register names except sp and pc in cgthumb2was.c (diff)
Fix issue with A stack negative offset
-rw-r--r--cgopt.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/cgopt.c b/cgopt.c
index bf585b5..01a16c4 100644
--- a/cgopt.c
+++ b/cgopt.c
@@ -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;
}