1/* stuff needed for libgcc on win32. 2 * 3 * Copyright (C) 1996-2014 Free Software Foundation, Inc. 4 * Written By Steve Chamberlain 5 * 6 * This file is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License as published by the 8 * Free Software Foundation; either version 3, or (at your option) any 9 * later version. 10 * 11 * This file is distributed in the hope that it will be useful, but 12 * WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * General Public License for more details. 15 * 16 * Under Section 7 of GPL version 3, you are granted additional 17 * permissions described in the GCC Runtime Library Exception, version 18 * 3.1, as published by the Free Software Foundation. 19 * 20 * You should have received a copy of the GNU General Public License and 21 * a copy of the GCC Runtime Library Exception along with this program; 22 * see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 * <http://www.gnu.org/licenses/>. 24 */ 25 26#include "auto-host.h" 27 28#ifdef HAVE_GAS_CFI_SECTIONS_DIRECTIVE 29 .cfi_sections .debug_frame 30# define cfi_startproc() .cfi_startproc 31# define cfi_endproc() .cfi_endproc 32# define cfi_adjust_cfa_offset(X) .cfi_adjust_cfa_offset X 33# define cfi_def_cfa_register(X) .cfi_def_cfa_register X 34# define cfi_register(D,S) .cfi_register D, S 35# ifdef __x86_64__ 36# define cfi_push(X) .cfi_adjust_cfa_offset 8; .cfi_rel_offset X, 0 37# define cfi_pop(X) .cfi_adjust_cfa_offset -8; .cfi_restore X 38# else 39# define cfi_push(X) .cfi_adjust_cfa_offset 4; .cfi_rel_offset X, 0 40# define cfi_pop(X) .cfi_adjust_cfa_offset -4; .cfi_restore X 41# endif 42#else 43# define cfi_startproc() 44# define cfi_endproc() 45# define cfi_adjust_cfa_offset(X) 46# define cfi_def_cfa_register(X) 47# define cfi_register(D,S) 48# define cfi_push(X) 49# define cfi_pop(X) 50#endif /* HAVE_GAS_CFI_SECTIONS_DIRECTIVE */ 51 52#ifdef L_chkstk 53/* Function prologue calls __chkstk to probe the stack when allocating more 54 than CHECK_STACK_LIMIT bytes in one go. Touching the stack at 4K 55 increments is necessary to ensure that the guard pages used 56 by the OS virtual memory manger are allocated in correct sequence. */ 57 58 .global ___chkstk 59 .global __alloca 60#ifdef __x86_64__ 61/* __alloca is a normal function call, which uses %rcx as the argument. */ 62 cfi_startproc() 63__alloca: 64 movq %rcx, %rax 65 /* FALLTHRU */ 66 67/* ___chkstk is a *special* function call, which uses %rax as the argument. 68 We avoid clobbering the 4 integer argument registers, %rcx, %rdx, 69 %r8 and %r9, which leaves us with %rax, %r10, and %r11 to use. */ 70 .align 4 71___chkstk: 72 popq %r11 /* pop return address */ 73 cfi_adjust_cfa_offset(-8) /* indicate return address in r11 */ 74 cfi_register(%rip, %r11) 75 movq %rsp, %r10 76 cmpq $0x1000, %rax /* > 4k ?*/ 77 jb 2f 78 791: subq $0x1000, %r10 /* yes, move pointer down 4k*/ 80 orl $0x0, (%r10) /* probe there */ 81 subq $0x1000, %rax /* decrement count */ 82 cmpq $0x1000, %rax 83 ja 1b /* and do it again */ 84 852: subq %rax, %r10 86 movq %rsp, %rax /* hold CFA until return */ 87 cfi_def_cfa_register(%rax) 88 orl $0x0, (%r10) /* less than 4k, just peek here */ 89 movq %r10, %rsp /* decrement stack */ 90 91 /* Push the return value back. Doing this instead of just 92 jumping to %r11 preserves the cached call-return stack 93 used by most modern processors. */ 94 pushq %r11 95 ret 96 cfi_endproc() 97#else 98 cfi_startproc() 99___chkstk: 100__alloca: 101 pushl %ecx /* save temp */ 102 cfi_push(%eax) 103 leal 8(%esp), %ecx /* point past return addr */ 104 cmpl $0x1000, %eax /* > 4k ?*/ 105 jb 2f 106 1071: subl $0x1000, %ecx /* yes, move pointer down 4k*/ 108 orl $0x0, (%ecx) /* probe there */ 109 subl $0x1000, %eax /* decrement count */ 110 cmpl $0x1000, %eax 111 ja 1b /* and do it again */ 112 1132: subl %eax, %ecx 114 orl $0x0, (%ecx) /* less than 4k, just peek here */ 115 movl %esp, %eax /* save current stack pointer */ 116 cfi_def_cfa_register(%eax) 117 movl %ecx, %esp /* decrement stack */ 118 movl (%eax), %ecx /* recover saved temp */ 119 120 /* Copy the return register. Doing this instead of just jumping to 121 the address preserves the cached call-return stack used by most 122 modern processors. */ 123 pushl 4(%eax) 124 ret 125 cfi_endproc() 126#endif /* __x86_64__ */ 127#endif /* L_chkstk */ 128 129#ifdef L_chkstk_ms 130/* ___chkstk_ms is a *special* function call, which uses %rax as the argument. 131 We avoid clobbering any registers. Unlike ___chkstk, it just probes the 132 stack and does no stack allocation. */ 133 .global ___chkstk_ms 134#ifdef __x86_64__ 135 cfi_startproc() 136___chkstk_ms: 137 pushq %rcx /* save temps */ 138 cfi_push(%rcx) 139 pushq %rax 140 cfi_push(%rax) 141 cmpq $0x1000, %rax /* > 4k ?*/ 142 leaq 24(%rsp), %rcx /* point past return addr */ 143 jb 2f 144 1451: subq $0x1000, %rcx /* yes, move pointer down 4k */ 146 orq $0x0, (%rcx) /* probe there */ 147 subq $0x1000, %rax /* decrement count */ 148 cmpq $0x1000, %rax 149 ja 1b /* and do it again */ 150 1512: subq %rax, %rcx 152 orq $0x0, (%rcx) /* less than 4k, just peek here */ 153 154 popq %rax 155 cfi_pop(%rax) 156 popq %rcx 157 cfi_pop(%rcx) 158 ret 159 cfi_endproc() 160#else 161 cfi_startproc() 162___chkstk_ms: 163 pushl %ecx /* save temp */ 164 cfi_push(%ecx) 165 pushl %eax 166 cfi_push(%eax) 167 cmpl $0x1000, %eax /* > 4k ?*/ 168 leal 12(%esp), %ecx /* point past return addr */ 169 jb 2f 170 1711: subl $0x1000, %ecx /* yes, move pointer down 4k*/ 172 orl $0x0, (%ecx) /* probe there */ 173 subl $0x1000, %eax /* decrement count */ 174 cmpl $0x1000, %eax 175 ja 1b /* and do it again */ 176 1772: subl %eax, %ecx 178 orl $0x0, (%ecx) /* less than 4k, just peek here */ 179 180 popl %eax 181 cfi_pop(%eax) 182 popl %ecx 183 cfi_pop(%ecx) 184 ret 185 cfi_endproc() 186#endif /* __x86_64__ */ 187#endif /* L_chkstk_ms */ 188