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