We are subtract an extra "cfun->machine->frame.fp_lr_offset" which is wrong, but the AARCH64_ROUND_UP below happen to compensate that, thus hiding this bug.
The offset from FRAME_POINTER_REGNUM to STACK_POINTER_REGNUM is exactly the sum of outgoing argument size, callee saved reg size and local variable size. Just as what commented in aarch64 target file: +-------------------------------+ <-- arg_pointer_rtx | | | callee-allocated save area | | for register varargs | | | +-------------------------------+ <-- frame_pointer_rtx (A) | | | local variables | | | +-------------------------------+ | padding0 | \ +-------------------------------+ | | | | | | | | callee-saved registers | | frame.saved_regs_size | | | +-------------------------------+ | | LR' | | +-------------------------------+ | | FP' | / P +-------------------------------+ <-- hard_frame_pointer_rtx | dynamic allocation | +-------------------------------+ | | | outgoing stack arguments | | | +-------------------------------+ <-- stack_pointer_rtx (B) When alloca invoked, frame pointer is always required, no elimination from FRAME_POINTER_REGNUM to STACK_POINTER_REGNUM. OK for stage 1? 2014-04-22 Renlin <renlin...@arm.com> 2014-04-22 Jiong Wang <jiong.w...@arm.com> gcc/ * config/aarch64/aarch64.h (aarch64_frame): Delete "fp_lr_offset". * config/aarch64/aarch64.c (aarch64_layout_frame): Likewise. * config/aarch64/aarch64.c (aarch64_initial_elimination_offset): Likewise.
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index ebd58c0..ee49bbe 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -1719,8 +1719,6 @@ aarch64_layout_frame (void) if (reload_completed && cfun->machine->frame.laid_out) return; - cfun->machine->frame.fp_lr_offset = 0; - /* First mark all the registers that really need to be saved... */ for (regno = R0_REGNUM; regno <= R30_REGNUM; regno++) cfun->machine->frame.reg_offset[regno] = -1; @@ -1770,14 +1768,12 @@ aarch64_layout_frame (void) { cfun->machine->frame.reg_offset[R29_REGNUM] = offset; offset += UNITS_PER_WORD; - cfun->machine->frame.fp_lr_offset = UNITS_PER_WORD; } if (cfun->machine->frame.reg_offset[R30_REGNUM] != -1) { cfun->machine->frame.reg_offset[R30_REGNUM] = offset; offset += UNITS_PER_WORD; - cfun->machine->frame.fp_lr_offset += UNITS_PER_WORD; } cfun->machine->frame.padding0 = @@ -4183,8 +4179,7 @@ aarch64_initial_elimination_offset (unsigned from, unsigned to) { HOST_WIDE_INT elim = crtl->outgoing_args_size + cfun->machine->frame.saved_regs_size - + get_frame_size () - - cfun->machine->frame.fp_lr_offset; + + get_frame_size (); elim = AARCH64_ROUND_UP (elim, STACK_BOUNDARY / BITS_PER_UNIT); return elim; } diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h index 1f71ee5..aa38f9f 100644 --- a/gcc/config/aarch64/aarch64.h +++ b/gcc/config/aarch64/aarch64.h @@ -520,7 +520,6 @@ struct GTY (()) aarch64_frame been saved. */ HOST_WIDE_INT padding0; HOST_WIDE_INT hardfp_offset; /* HARD_FRAME_POINTER_REGNUM */ - HOST_WIDE_INT fp_lr_offset; /* Space needed for saving fp and/or lr */ bool laid_out; };