1/* Windows i386 support code for fibers and multithreading.
2   Copyright (C) 2019-2021 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#if defined(__x86_64__)
28
29    .text
30    .globl CSYM(fiber_switchContext)
31    .def CSYM(fiber_switchContext)
32    .scl 2
33    .type 32
34    .endef
35    .align 16
36CSYM(fiber_switchContext):
37    .cfi_startproc
38    pushq %RBP;
39    movq %RSP, %RBP;
40    pushq %RBX;
41    pushq %R12;
42    pushq %R13;
43    pushq %R14;
44    pushq %R15;
45    pushq %GS:0;
46    pushq %GS:8;
47    pushq %GS:16;
48
49    // store oldp
50    movq %RSP, (%RCX);
51    // load newp to begin context switch
52    movq %RDX, %RSP;
53
54    // load saved state from new stack
55    popq %GS:16;
56    popq %GS:8;
57    popq %GS:0;
58    popq %R15;
59    popq %R14;
60    popq %R13;
61    popq %R12;
62    popq %RBX;
63    popq %RBP;
64
65    // 'return' to complete switch
66    popq %RCX;
67    jmp *%RCX;
68    .cfi_endproc
69
70#elif defined(_X86_)
71
72    .text
73    .globl CSYM(fiber_switchContext)
74    .def CSYM(fiber_switchContext)
75    .scl 2
76    .type 32
77    .endef
78    .align 16
79CSYM(fiber_switchContext):
80    .cfi_startproc
81    // Save current stack state.save current stack state
82    // Standard CDECL prologue.
83    push %EBP;
84    mov  %ESP, %EBP;
85    push %EDI;
86    push %ESI;
87    push %EBX;
88    push %FS:0;
89    push %FS:4;
90    push %FS:8;
91    push %EAX;
92
93    // store oldp again with more accurate address
94    mov 8(%EBP), %EAX;
95    mov %ESP, (%EAX);
96    // load newp to begin context switch
97    mov 12(%EBP), %ESP;
98
99    // load saved state from new stack
100    pop %EAX;
101    pop %FS:8;
102    pop %FS:4;
103    pop %FS:0;
104    pop %EBX;
105    pop %ESI;
106    pop %EDI;
107    pop %EBP;
108
109    // 'return' to complete switch
110    ret;
111    .cfi_endproc
112
113#endif
114