diff options
author | Ian Lance Taylor <iant@google.com> | 2011-12-20 22:34:30 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2011-12-20 22:34:30 +0000 |
commit | a0c8d0c1e36976bf178b9eea29188e11a4e43b89 (patch) | |
tree | bbef8556fa5a1916624b2d5a114a335e949690c6 /libgcc/config | |
parent | 3752b2ab7cddf20ed4c99638a3ecf6ecfed6cf55 (diff) | |
download | gcc-a0c8d0c1e36976bf178b9eea29188e11a4e43b89.zip gcc-a0c8d0c1e36976bf178b9eea29188e11a4e43b89.tar.gz gcc-a0c8d0c1e36976bf178b9eea29188e11a4e43b89.tar.bz2 |
morestack.S (__morestack_non_split): If there is enough stack space already, don't split.
* 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.
From-SVN: r182555
Diffstat (limited to 'libgcc/config')
-rw-r--r-- | libgcc/config/i386/morestack.S | 104 |
1 files changed, 102 insertions, 2 deletions
diff --git a/libgcc/config/i386/morestack.S b/libgcc/config/i386/morestack.S index 0667590..8e0eb20 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 |