| /* i386 support code for fibers and multithreading. | |
| Copyright (C) 2019-2026 Free Software Foundation, Inc. | |
| This file is part of GCC. | |
| GCC is free software; you can redistribute it and/or modify it under | |
| the terms of the GNU General Public License as published by the Free | |
| Software Foundation; either version 3, or (at your option) any later | |
| version. | |
| GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |
| WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| for more details. | |
| Under Section 7 of GPL version 3, you are granted additional | |
| permissions described in the GCC Runtime Library Exception, version | |
| 3.1, as published by the Free Software Foundation. | |
| You should have received a copy of the GNU General Public License and | |
| a copy of the GCC Runtime Library Exception along with this program; | |
| see the files COPYING3 and COPYING.RUNTIME respectively. If not, see | |
| <http://www.gnu.org/licenses/>. */ | |
| #include "../common/threadasm.S" | |
| /* NB: Generate the CET marker for -fcf-protection. */ | |
| #ifdef __CET__ | |
| # include <cet.h> | |
| #endif | |
| #if !defined(__CET__) | |
| # if defined(__ELF__) | |
| # if defined(__i386__) | |
| .text | |
| .globl CSYM(fiber_switchContext) | |
| .type CSYM(fiber_switchContext), @function | |
| .align 16 | |
| CSYM(fiber_switchContext): | |
| .cfi_startproc | |
| // save current stack state | |
| push %ebp | |
| mov %esp, %ebp | |
| push %edi | |
| push %esi | |
| push %ebx | |
| push %eax | |
| // store oldp again with more accurate address | |
| mov 8(%ebp), %eax | |
| mov %esp, (%eax) | |
| // load newp to begin context switch | |
| mov 12(%ebp), %esp | |
| // load saved state from new stack | |
| pop %eax | |
| pop %ebx | |
| pop %esi | |
| pop %edi | |
| pop %ebp | |
| // 'return' to complete switch | |
| ret | |
| .cfi_endproc | |
| .size CSYM(fiber_switchContext),.-CSYM(fiber_switchContext) | |
| # endif /* defined(__ELF__) && defined(__i386__) */ | |
| # if defined(__x86_64__) && !defined(__ILP32__) | |
| .text | |
| .globl CSYM(fiber_switchContext) | |
| .type CSYM(fiber_switchContext), @function | |
| .align 16 | |
| CSYM(fiber_switchContext): | |
| .cfi_startproc | |
| // Save current stack state.save current stack state | |
| push %rbp | |
| mov %rsp, %rbp | |
| push %rbx | |
| push %r12 | |
| push %r13 | |
| push %r14 | |
| push %r15 | |
| // store oldp again with more accurate address | |
| mov %rsp, (%rdi) | |
| // load newp to begin context switch | |
| mov %rsi, %rsp | |
| // load saved state from new stack | |
| pop %r15 | |
| pop %r14 | |
| pop %r13 | |
| pop %r12 | |
| pop %rbx | |
| pop %rbp | |
| // 'return' to complete switch | |
| ret | |
| .cfi_endproc | |
| .size CSYM(fiber_switchContext),.-CSYM(fiber_switchContext) | |
| # endif /* defined(__ELF__) && defined(__x86_64__) && !defined(__ILP32__) */ | |
| # endif /* defined(__ELF__) */ | |
| # if defined(__MACH__) | |
| # if defined(__i386__) | |
| .text | |
| .globl CSYM(fiber_switchContext) | |
| .p2align 4 | |
| CSYM(fiber_switchContext): | |
| LFB0: | |
| // save current stack state | |
| push %ebp | |
| mov %esp, %ebp | |
| push %edi | |
| push %esi | |
| push %ebx | |
| push %eax | |
| // store oldp again with more accurate address | |
| mov 8(%ebp), %eax | |
| mov %esp, (%eax) | |
| // load newp to begin context switch | |
| mov 12(%ebp), %esp | |
| // load saved state from new stack | |
| pop %eax | |
| pop %ebx | |
| pop %esi | |
| pop %edi | |
| pop %ebp | |
| // 'return' to complete switch | |
| ret | |
| LFE0: | |
| /* CFI */ | |
| .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support | |
| EH_frame1: | |
| .set L$set$0,LECIE1-LSCIE1 | |
| .long L$set$0 # Length of Common Information Entry | |
| LSCIE1: | |
| .long 0 # CIE Identifier Tag | |
| .byte 0x1 # CIE Version | |
| .ascii "zR\0" # CIE Augmentation | |
| .byte 0x1 # uleb128 0x1; CIE Code Alignment Factor | |
| .byte 0x7c # sleb128 -4; CIE Data Alignment Factor | |
| .byte 0x8 # CIE RA Column | |
| .byte 0x1 # uleb128 0x1; Augmentation size | |
| .byte 0x10 # FDE Encoding (pcrel) | |
| .byte 0xc # DW_CFA_def_cfa | |
| .byte 0x5 # uleb128 0x5 | |
| .byte 0x4 # uleb128 0x4 | |
| .byte 0x88 # DW_CFA_offset, column 0x8 | |
| .byte 0x1 # uleb128 0x1 | |
| .p2align 2,0 | |
| LECIE1: | |
| /* minimal FDE - does not record the stack frame changes. */ | |
| LSFDE1: | |
| .set L$set$1,LEFDE1-LASFDE1 | |
| .long L$set$1 # FDE Length | |
| LASFDE1: | |
| .long LASFDE1-EH_frame1 # FDE CIE offset | |
| .long LFB0-. # FDE initial location | |
| .set L$set$2,LFE0-LFB0 | |
| .long L$set$2 # FDE address range | |
| .byte 0 # uleb128 0; Augmentation size | |
| .p2align 2,0 | |
| LEFDE1: | |
| # endif /* defined(__MACH__) && defined(__i386__) */ | |
| # if defined(__x86_64__) && !defined(__ILP32__) | |
| .text | |
| .globl CSYM(fiber_switchContext) | |
| .p2align 4 | |
| CSYM(fiber_switchContext): | |
| LFB0: | |
| // Save current stack state.save current stack state | |
| push %rbp | |
| mov %rsp, %rbp | |
| push %r15 | |
| push %r14 | |
| push %r13 | |
| push %r12 | |
| push %rbx | |
| // store oldp again with more accurate address | |
| mov %rsp, (%rdi) | |
| // load newp to begin context switch | |
| mov %rsi, %rsp | |
| // load saved state from new stack | |
| pop %rbx | |
| pop %r12 | |
| pop %r13 | |
| pop %r14 | |
| pop %r15 | |
| pop %rbp | |
| // 'return' to complete switch | |
| ret | |
| LFE0: | |
| /* CFI */ | |
| .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support | |
| EH_frame1: | |
| .set L$set$0,LECIE1-LSCIE1 | |
| .long L$set$0 # Length of Common Information Entry | |
| LSCIE1: | |
| .long 0 # CIE Identifier Tag | |
| .byte 0x1 # CIE Version | |
| .ascii "zR\0" # CIE Augmentation | |
| .byte 0x1 # uleb128 0x1; CIE Code Alignment Factor | |
| .byte 0x78 # sleb128 -8; CIE Data Alignment Factor | |
| .byte 0x10 # CIE RA Column | |
| .byte 0x1 # uleb128 0x1; Augmentation size | |
| .byte 0x10 # FDE Encoding (pcrel) | |
| .byte 0xc # DW_CFA_def_cfa | |
| .byte 0x7 # uleb128 0x7 | |
| .byte 0x8 # uleb128 0x8 | |
| .byte 0x90 # DW_CFA_offset, column 0x10 | |
| .byte 0x1 # uleb128 0x1 | |
| .p2align 3,0 | |
| LECIE1: | |
| /* minimal FDE - does not record the stack frame changes. */ | |
| LSFDE1: | |
| .set L$set$1,LEFDE1-LASFDE1 | |
| .long L$set$1 # FDE Length | |
| LASFDE1: | |
| .long LASFDE1-EH_frame1 # FDE CIE offset | |
| .quad LFB0-. # FDE initial location | |
| .set L$set$2,LFE0-LFB0 | |
| .quad L$set$2 # FDE address range | |
| .byte 0 # uleb128 0; Augmentation size | |
| .p2align 3,0 | |
| LEFDE1: | |
| # endif /* defined(__MACH__) && defined(__x86_64__) && !defined(__ILP32__) */ | |
| # endif /* defined (__MACH__) */ | |
| #endif /* !defined(__CET__) */ |