This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [ARM] Fix register r3 wrongly used to save ip in nested APCS frame


Eric,

My apologies for taking so long to look at this.

> 2013-09-05  Eric Botcazou  <ebotcazou@adacore.com>
>
> 	* config/arm/arm.c (arm_expand_prologue): In a nested APCS frame with
> 	arguments to push onto the stack and no varargs, save ip into a stack
> 	slot if r3 isn't available on entry.

Sorry, but this is not quite right either, as shown by the attached
testcase (in C this time, so we can commit it to gcc.target/arm :-)

The problem is that if we have some alignment padding we end up storing
ip in one location but restoring it from another.

	str	ip, [sp, #4]
	add	ip, sp, #8
	stmfd	sp!, {fp, ip, lr, pc}
	sub	fp, ip, #12
	ldr	ip, [fp, #4]	// <==== Should be fp + 8
	@ ip needed
	str	r3, [fp, #8]
	ldr	ip, [ip]

R.

On 14/10/13 09:46, Eric Botcazou wrote:
> p__f$1593:
> 	@ Nested: function declared inside another function.
> 	@ args = 16, pretend = 4, frame = 140
> 	@ frame_needed = 1, uses_anonymous_args = 0
> 	sub	sp, sp, #4
> 	str	ip, [sp]
> 	add	ip, sp, #4
> 	stmfd	sp!, {r4, r5, r6, r7, r8, r9, r10, fp, ip, lr, pc}


> 	sub	fp, ip, #8
> 	ldr	ip, [fp, #4]
> 	@ ip needed
> 	sub	sp, sp, #140
> 	str	r0, [fp, #-64]
> 	str	r1, [fp, #-72]
> 	str	r2, [fp, #-68]
> 	str	r3, [fp, #4]
> 
> which looks correct.  FWIW we have had the patch in our tree for 4 months now.
> 
> 
> p.adb
> 
> 
> procedure P (I : Integer) is
> 
>   SUBTYPE S IS INTEGER RANGE 1..100;
>   TYPE ARR IS ARRAY (S RANGE <>) OF INTEGER;
> 
>   A : ARR (2..9);
> 
>   FUNCTION F (AR_VAR1, AR_VAR2, AR_VAR3 : ARR) RETURN ARR IS
>   BEGIN
>     if I = 0 then
>       RETURN AR_VAR1 & AR_VAR2 & AR_VAR3;
>     else
>       RETURN AR_VAR1;
>     end if;
>   END;
> 
> begin
>   A := (8,7,6,5,4,3,2,1);
>   if F(A(2..3), A(2..4), A(2..4)) /= (8,7,8,7,6,8,7,6) then
>     raise Program_Error;
>   end if;
> end;
> 

Attachment: nested.c
Description: Text document


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]