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: [split] Add CFI ops, fix call/return prediction, other changes


Richard Henderson <rth@redhat.com> writes:

>> +	# Note that %esp is exactly 32 bytes below the CFA -- perfect for
>> +	# a 16-byte aligned stack.  That said, we still ought to compile
>> +	# generic-morestack.c with -mpreferred-stack-boundary=2.  FIXME.
>
> Without the ecx push this isn't true.  Not that it really matters; if
> the cfa were properly aligned on entry to our caller, we pushed 12
> bytes to get to __morestack, which means our cfa is not aligned.
>
>> +	movl	-4(%ebp),%eax		# Restore registers.
>> +	movl	-8(%ebp),%edx
>>
>> +	movl	4(%ebp),%ecx		# Increment the return address
>> +	inc	%ecx			# to skip the ret instruction;
>> +					# see above.
>>
>>  	call	*%ecx			# Call our caller!
>
> How about using some of that extra space we've got in the frame:
>
> 	movl	-12(%ebp), %ecx		# Restore 2 registers
> 	movl	-8(%ebp), %edx
>
> 	movl	4(%ebp), %eax		# Increment return address
> 	inc	%eax
> 	movl	%eax, -8(%ebp)		# Store it in an unused slot
>
> 	movl	-4(%ebp), %eax		# Restore 3rd register
>
> 	call	*-8(%ebp)		# Call our caller via slot

Excellent.  Committed to split branch as follows.  Thanks.

Ian


libgcc/:

2009-09-30  Ian Lance Taylor  <iant@google.com>
	    Richard Henderson  <rth@redhat.com>

	* config/i386/morestack.S (__morestack): In 32-bit case, use a
	stack slot to hold the incremented return address rather than
	trashing %ecx.

gcc/:

2009-09-30  Ian Lance Taylor  <iant@google.com>

	* config/i386/i386.c (ix86_expand_split_stack_prologue): Never
	save %ecx around the call to __morestack.


Index: libgcc/config/i386/morestack.S
===================================================================
--- libgcc/config/i386/morestack.S	(revision 152321)
+++ libgcc/config/i386/morestack.S	(working copy)
@@ -96,11 +96,11 @@ __morestack:
 
 	# In 32-bit mode the registers %eax, %edx, and %ecx may be
 	# used for parameters, depending on the regparm and fastcall
-	# attributes.  However, we don't have to worry about %ecx, as
-	# the function will have saved it on the stack if necessary.
+	# attributes.
 
 	pushl	%eax
 	pushl	%edx
+	pushl	%ecx
 
 	pushl	12(%ebp)		# The size of the parameters.
 	leal	20(%ebp),%eax		# Address of caller's parameters.
@@ -122,14 +122,19 @@ __morestack:
 	# gcc/config/i386/linux.h.
 	movl	%eax,%gs:0x30		# Save the new stack boundary.
 
-	movl	-4(%ebp),%eax		# Restore registers.
-	movl	-8(%ebp),%edx
+	movl	-8(%ebp),%edx		# Restore registers.
+	movl	-12(%ebp),%ecx
 
-	movl	4(%ebp),%ecx		# Increment the return address
-	inc	%ecx			# to skip the ret instruction;
+	movl	4(%ebp),%eax		# Increment the return address
+	inc	%eax			# to skip the ret instruction;
 					# see above.
+	
+	movl	%eax,-8(%ebp)		# Store return address in an
+					# unused slot.
 
-	call	*%ecx			# Call our caller!
+	movl	-4(%ebp),%eax		# Restore the last register.
+
+	call	*-8(%ebp)		# Call our caller!
 
 	# The caller will return here, as predicted.
 
Index: gcc/config/i386/i386.c
===================================================================
--- gcc/config/i386/i386.c	(revision 152321)
+++ gcc/config/i386/i386.c	(working copy)
@@ -9219,13 +9219,6 @@ ix86_expand_split_stack_prologue (void)
   call_fusage = NULL_RTX;
   if (!TARGET_64BIT)
     {
-      /* In order to give __morestack a scratch register, we save %ecx
-	 if necessary.  */
-      if (is_fastcall || regparm > 2)
-	{
-	  emit_insn (gen_push (gen_rtx_REG (Pmode, CX_REG)));
-	  args_size += UNITS_PER_WORD;
-	}
       emit_insn (gen_push (GEN_INT (args_size)));
       emit_insn (gen_push (allocate_rtx));
     }
@@ -9255,12 +9248,6 @@ ix86_expand_split_stack_prologue (void)
      label.  Therefore, we use an unspec.  */
   emit_insn (gen_split_stack_return ());
 
-  if (!TARGET_64BIT && (is_fastcall || regparm > 2))
-    {
-      /* Restore the scratch register we pushed earlier.  */
-      emit_insn (gen_popsi1 (gen_rtx_REG (Pmode, CX_REG)));
-    }
-
   emit_label (label);
   LABEL_NUSES (label) = 1;
 }

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