diff options
author | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-12-20 22:34:30 +0000 |
---|---|---|
committer | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-12-20 22:34:30 +0000 |
commit | 0d84f1645ee9ac09db43378156f779109ed076db (patch) | |
tree | bbef8556fa5a1916624b2d5a114a335e949690c6 /libgcc | |
parent | 4ccf368d026f1965bf7b9abc1656f47f9b1f2243 (diff) | |
download | gcc-0d84f1645ee9ac09db43378156f779109ed076db.tar.gz |
* config/i386/morestack.S (__morestack_non_split): If there is
enough stack space already, don't split. Ask for more stack space
than we required.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@182555 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgcc')
-rw-r--r-- | libgcc/ChangeLog | 6 | ||||
-rw-r--r-- | libgcc/config/i386/morestack.S | 104 |
2 files changed, 108 insertions, 2 deletions
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index 3f957673680..f5d02dd79fd 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,9 @@ +2011-12-20 Ian Lance Taylor <iant@google.com> + + * config/i386/morestack.S (__morestack_non_split): If there is + enough stack space already, don't split. Ask for more stack space + than we required. + 2011-12-20 Sergio Durigan Junior <sergiodj@redhat.com> * unwind-arm-common.inc: Include `tconfig.h', `tsystem.h' and diff --git a/libgcc/config/i386/morestack.S b/libgcc/config/i386/morestack.S index 0667590bcf0..8e0eb2009bc 100644 --- a/libgcc/config/i386/morestack.S +++ b/libgcc/config/i386/morestack.S @@ -96,13 +96,113 @@ #endif __morestack_non_split: + .cfi_startproc #ifndef __x86_64__ - addl $0x4000,4(%esp) + + # See below for an extended explanation of the CFI instructions. + .cfi_offset 8, 8 # New PC stored at CFA + 8 + .cfi_escape 0x15, 4, 0x7d # DW_CFA_val_offset_sf, %esp, 12/-4 + # i.e., next %esp is CFA + 12 + + pushl %eax # Save %eax in case it is a parameter. + + .cfi_def_cfa %esp,8 # Account for pushed register. + + movl %esp,%eax # Current stack, + subl 8(%esp),%eax # less required stack frame size, + subl $0x4000,%eax # less space for non-split code. + cmpl %gs:0x30,%eax # See if we have enough space. + jb 2f # Get more space if we need it. + + # Here the stack is + # %esp + 20: stack pointer after two returns + # %esp + 16: return address of morestack caller's caller + # %esp + 12: size of parameters + # %esp + 8: new stack frame size + # %esp + 4: return address of this function + # %esp: saved %eax + # + # Since we aren't doing a full split stack, we don't need to + # do anything when our caller returns. So we return to our + # caller rather than calling it, and let it return as usual. + # To make that work we adjust the return address. + + # This breaks call/return address prediction for the call to + # this function. I can't figure out a way to make it work + # short of copying the parameters down the stack, which will + # probably take more clock cycles than we will lose breaking + # call/return address prediction. We will only break + # prediction for this call, not for our caller. + + movl 4(%esp),%eax # Increment the return address + cmpb $0xc3,(%eax) # to skip the ret instruction; + je 1f # see above. + addl $2,%eax +1: inc %eax + movl %eax,4(%esp) # Update return address. + + popl %eax # Restore %eax and stack. + + .cfi_def_cfa %esp,4 # Account for popped register. + + ret $8 # Return to caller, popping args. + +2: + .cfi_def_cfa %esp,8 # Back to where we were. + + popl %eax # Restore %eax and stack. + + .cfi_def_cfa %esp,4 # Account for popped register. + + addl $0x5000+BACKOFF,4(%esp) # Increment space we request. + + # Fall through into morestack. + #else - addq $0x4000,%r10 + + # See below for an extended explanation of the CFI instructions. + .cfi_offset 16, 0 + .cfi_escape 0x15, 7, 0x7f # DW_CFA_val_offset_sf, %esp, 8/-8 + + pushq %rax # Save %rax in case caller is using + # it to preserve original %r10. + .cfi_def_cfa %rsp,16 # Adjust for pushed register. + + movq %rsp,%rax # Current stack, + subq %r10,%rax # less required stack frame size, + subq $0x4000,%rax # less space for non-split code. + +#ifdef __LP64__ + cmpq %fs:0x70,%rax # See if we have enough space. +#else + cmpl %fs:0x40,%eax #endif + jb 2f # Get more space if we need it. + + # This breaks call/return prediction, as described above. + incq 8(%rsp) # Increment the return address. + + popq %rax # Restore register. + + .cfi_def_cfa %rsp,8 # Adjust for popped register. + ret # Return to caller. + +2: + .cfi_def_cfa %rsp,16 # Back to where we were. + + popq %rax # Restore register. + + .cfi_def_cfa %rsp,8 # Adjust for popped register. + + addq $0x5000+BACKOFF,%r10 # Increment space we request. + + # Fall throug into morestack. + +#endif + + .cfi_endproc #ifdef __ELF__ .size __morestack_non_split, . - __morestack_non_split #endif |