1/* i386 support code for fibers and multithreading. 2 Copyright (C) 2019-2022 Free Software Foundation, Inc. 3 4This file is part of GCC. 5 6GCC is free software; you can redistribute it and/or modify it under 7the terms of the GNU General Public License as published by the Free 8Software Foundation; either version 3, or (at your option) any later 9version. 10 11GCC is distributed in the hope that it will be useful, but WITHOUT ANY 12WARRANTY; without even the implied warranty of MERCHANTABILITY or 13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14for more details. 15 16Under Section 7 of GPL version 3, you are granted additional 17permissions described in the GCC Runtime Library Exception, version 183.1, as published by the Free Software Foundation. 19 20You should have received a copy of the GNU General Public License and 21a copy of the GCC Runtime Library Exception along with this program; 22see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23<http://www.gnu.org/licenses/>. */ 24 25#include "../common/threadasm.S" 26 27/* NB: Generate the CET marker for -fcf-protection. */ 28#ifdef __CET__ 29# include <cet.h> 30#endif 31 32#if !defined(__CET__) 33 34# if defined(__ELF__) 35 36# if defined(__i386__) 37 38 .text 39 .globl CSYM(fiber_switchContext) 40 .type CSYM(fiber_switchContext), @function 41 .align 16 42CSYM(fiber_switchContext): 43 .cfi_startproc 44 // save current stack state 45 push %ebp 46 mov %esp, %ebp 47 push %edi 48 push %esi 49 push %ebx 50 push %eax 51 52 // store oldp again with more accurate address 53 mov 8(%ebp), %eax 54 mov %esp, (%eax) 55 // load newp to begin context switch 56 mov 12(%ebp), %esp 57 58 // load saved state from new stack 59 pop %eax 60 pop %ebx 61 pop %esi 62 pop %edi 63 pop %ebp 64 65 // 'return' to complete switch 66 ret 67 .cfi_endproc 68 .size CSYM(fiber_switchContext),.-CSYM(fiber_switchContext) 69 70# endif /* defined(__ELF__) && defined(__i386__) */ 71 72# if defined(__x86_64__) && !defined(__ILP32__) 73 74 .text 75 .globl CSYM(fiber_switchContext) 76 .type CSYM(fiber_switchContext), @function 77 .align 16 78CSYM(fiber_switchContext): 79 .cfi_startproc 80 // Save current stack state.save current stack state 81 push %rbp 82 mov %rsp, %rbp 83 push %rbx 84 push %r12 85 push %r13 86 push %r14 87 push %r15 88 89 // store oldp again with more accurate address 90 mov %rsp, (%rdi) 91 // load newp to begin context switch 92 mov %rsi, %rsp 93 94 // load saved state from new stack 95 pop %r15 96 pop %r14 97 pop %r13 98 pop %r12 99 pop %rbx 100 pop %rbp 101 102 // 'return' to complete switch 103 ret 104 .cfi_endproc 105 .size CSYM(fiber_switchContext),.-CSYM(fiber_switchContext) 106 107# endif /* defined(__ELF__) && defined(__x86_64__) && !defined(__ILP32__) */ 108 109# endif /* defined(__ELF__) */ 110 111# if defined(__MACH__) 112 113# if defined(__i386__) 114 115 .text 116 .globl CSYM(fiber_switchContext) 117 .p2align 4 118CSYM(fiber_switchContext): 119LFB0: 120 // save current stack state 121 push %ebp 122 mov %esp, %ebp 123 push %edi 124 push %esi 125 push %ebx 126 push %eax 127 128 // store oldp again with more accurate address 129 mov 8(%ebp), %eax 130 mov %esp, (%eax) 131 // load newp to begin context switch 132 mov 12(%ebp), %esp 133 134 // load saved state from new stack 135 pop %eax 136 pop %ebx 137 pop %esi 138 pop %edi 139 pop %ebp 140 141 // 'return' to complete switch 142 ret 143LFE0: 144 145/* CFI */ 146 .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support 147EH_frame1: 148 .set L$set$0,LECIE1-LSCIE1 149 .long L$set$0 # Length of Common Information Entry 150LSCIE1: 151 .long 0 # CIE Identifier Tag 152 .byte 0x1 # CIE Version 153 .ascii "zR\0" # CIE Augmentation 154 .byte 0x1 # uleb128 0x1; CIE Code Alignment Factor 155 .byte 0x7c # sleb128 -4; CIE Data Alignment Factor 156 .byte 0x8 # CIE RA Column 157 .byte 0x1 # uleb128 0x1; Augmentation size 158 .byte 0x10 # FDE Encoding (pcrel) 159 .byte 0xc # DW_CFA_def_cfa 160 .byte 0x5 # uleb128 0x5 161 .byte 0x4 # uleb128 0x4 162 .byte 0x88 # DW_CFA_offset, column 0x8 163 .byte 0x1 # uleb128 0x1 164 .p2align 2,0 165LECIE1: 166 167/* minimal FDE - does not record the stack frame changes. */ 168LSFDE1: 169 .set L$set$1,LEFDE1-LASFDE1 170 .long L$set$1 # FDE Length 171LASFDE1: 172 .long LASFDE1-EH_frame1 # FDE CIE offset 173 .long LFB0-. # FDE initial location 174 .set L$set$2,LFE0-LFB0 175 .long L$set$2 # FDE address range 176 .byte 0 # uleb128 0; Augmentation size 177 .p2align 2,0 178LEFDE1: 179 180# endif /* defined(__MACH__) && defined(__i386__) */ 181 182# if defined(__x86_64__) && !defined(__ILP32__) 183 184 .text 185 .globl CSYM(fiber_switchContext) 186 .p2align 4 187CSYM(fiber_switchContext): 188LFB0: 189 // Save current stack state.save current stack state 190 push %rbp 191 mov %rsp, %rbp 192 push %r15 193 push %r14 194 push %r13 195 push %r12 196 push %rbx 197 198 // store oldp again with more accurate address 199 mov %rsp, (%rdi) 200 // load newp to begin context switch 201 mov %rsi, %rsp 202 203 // load saved state from new stack 204 pop %rbx 205 pop %r12 206 pop %r13 207 pop %r14 208 pop %r15 209 pop %rbp 210 211 // 'return' to complete switch 212 ret 213LFE0: 214 215/* CFI */ 216 .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support 217EH_frame1: 218 .set L$set$0,LECIE1-LSCIE1 219 .long L$set$0 # Length of Common Information Entry 220LSCIE1: 221 .long 0 # CIE Identifier Tag 222 .byte 0x1 # CIE Version 223 .ascii "zR\0" # CIE Augmentation 224 .byte 0x1 # uleb128 0x1; CIE Code Alignment Factor 225 .byte 0x78 # sleb128 -8; CIE Data Alignment Factor 226 .byte 0x10 # CIE RA Column 227 .byte 0x1 # uleb128 0x1; Augmentation size 228 .byte 0x10 # FDE Encoding (pcrel) 229 .byte 0xc # DW_CFA_def_cfa 230 .byte 0x7 # uleb128 0x7 231 .byte 0x8 # uleb128 0x8 232 .byte 0x90 # DW_CFA_offset, column 0x10 233 .byte 0x1 # uleb128 0x1 234 .p2align 3,0 235LECIE1: 236 237/* minimal FDE - does not record the stack frame changes. */ 238LSFDE1: 239 .set L$set$1,LEFDE1-LASFDE1 240 .long L$set$1 # FDE Length 241LASFDE1: 242 .long LASFDE1-EH_frame1 # FDE CIE offset 243 .quad LFB0-. # FDE initial location 244 .set L$set$2,LFE0-LFB0 245 .quad L$set$2 # FDE address range 246 .byte 0 # uleb128 0; Augmentation size 247 .p2align 3,0 248LEFDE1: 249 250# endif /* defined(__MACH__) && defined(__x86_64__) && !defined(__ILP32__) */ 251 252# endif /* defined (__MACH__) */ 253 254#endif /* !defined(__CET__) */ 255