This commit was manufactured by cvs2svn to create branch 'captive'.
[reactos.git] / lib / msvcrt / setjmp / setjmp.c
1 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
2 /* modified by Boudewijn Dekker */
3 /* ms uses a smaller jmp_buf structure */
4 /* might do a realloc in setjmp */
5
6 typedef struct {
7   unsigned int __eax, __ebx, __ecx, __edx, __esi;
8   unsigned int __edi, __ebp, __esp, __eip, __eflags;
9   unsigned short __cs, __ds, __es, __fs, __gs, __ss;
10   unsigned long __sigmask; /* for POSIX signals only */
11   unsigned long __signum; /* for expansion */
12   unsigned long __exception_ptr; /* pointer to previous exception */
13   unsigned char __fpu_state[108]; /* for future use */
14 } jmp_buf[1];
15
16
17 /* jumps back to position specified in jmp_buf */
18
19 int longjmp( jmp_buf env, int value )
20 {
21   //push ebp             generated by the compiler
22   //mov ebp, esp
23
24 #ifdef __GNUC__
25   __asm__ __volatile__ (
26         "movl   8(%ebp),%edi\n\t"       /* get jmp_buf */
27         "movl   12(%ebp),%eax\n\t"      /* store retval in j->eax */
28         "movl   %eax,0(%edi)\n\t"
29
30         "movw   46(%edi),%fs\n\t"
31         "movw   48(%edi),%gs\n\t"
32         "movl   4(%edi),%ebx\n\t"
33         "movl   8(%edi),%ecx\n\t"
34         "movl   12(%edi),%edx\n\t"
35         "movl   24(%edi),%ebp\n\t"
36
37         /* Now for some uglyness.  The jmp_buf structure may be ABOVE the
38            point on the new SS:ESP we are moving to.  We don't allow overlap,
39            but do force that it always be valid.  We will use ES:ESI for
40            our new stack before swapping to it.  */
41
42         "movw   50(%edi),%es\n\t"
43         "movl   28(%edi),%esi\n\t"
44         "subl   $28,%esi\n\t"   /* We need 7 working longwords on stack */
45
46         "movl   60(%edi),%eax\n\t"
47         "es\n\t"
48         "movl   %eax,(%esi)\n\t"        /* Exception pointer */
49
50         "movzwl 42(%edi),%eax\n\t"
51         "es\n\t"
52         "movl   %eax,4(%esi)\n\t"       /* DS */
53
54         "movl   20(%edi),%eax\n\t"
55         "es\n\t"
56         "movl   %eax,8(%esi)\n\t"       /* EDI */
57
58         "movl   16(%edi),%eax\n\t"
59         "es\n\t"
60         "movl   %eax,12(%esi)\n\t"      /* ESI */
61
62         "movl   32(%edi),%eax\n\t"
63         "es\n\t"
64         "movl   %eax,16(%esi)\n\t"      /* EIP - start of IRET frame */
65
66         "movl   40(%edi),%eax\n\t"
67         "es\n\t"
68         "movl   %eax,20(%esi)\n\t"      /* CS */
69
70         "movl   36(%edi),%eax\n\t"
71         "es\n\t"
72         "movl   %eax,24(%esi)\n\t"      /* EFLAGS */
73
74         "movl   0(%edi),%eax\n\t"
75         "movw   44(%edi),%es\n\t"
76
77         "movw   50(%edi),%ss\n\t"
78         "movl   %esi,%esp\n\t"
79
80         //"popl ___djgpp_exception_state_ptr\n\t"
81         "popl   %edi\n\t"       // dummy popl instead of djgpp_exception_state_ptr
82         "popl   %ds\n\t"
83         "popl   %edi\n\t"
84         "popl   %esi\n\t"
85
86         "iret\n\t"              /* actually jump to new cs:eip loading flags */
87         );
88
89 #else
90 #endif /*__GNUC__*/
91   return value; // dummy return never reached
92 }
93
94 #ifdef __GNUC__
95
96 int _setjmp( jmp_buf env )
97 {
98   //push ebp             generated by the compiler
99   //mov ebp, esp
100   __asm__ __volatile__ (
101         "pushl  %edi\n\t"
102         "movl   8(%ebp),%edi\n\t"
103
104         "movl   %eax, (%edi)\n\t"
105         "movl   %ebx,4(%edi)\n\t"
106         "movl   %ecx,8(%edi)\n\t"
107         "movl   %edx,12(%edi)\n\t"
108         "movl   %esi,16(%edi)\n\t"
109
110         "movl   -4(%ebp),%eax\n\t"
111         "movl   %eax,20(%edi)\n\t"
112
113         "movl   (%ebp),%eax\n\t"
114         "movl   %eax,24(%edi)\n\t"
115
116         "movl   %esp,%eax\n\t"
117         "addl   $12,%eax\n\t"
118         "movl   %eax,28(%edi)\n\t"
119
120         "movl   4(%ebp),%eax\n\t"
121         "movl   %eax,32(%edi)\n\t"
122
123         "pushfl\n\t"
124         "popl   36(%edi)\n\t"
125
126         "movw   %cs, 40(%edi)\n\t"
127         "movw   %ds, 42(%edi)\n\t"
128         "movw   %es, 44(%edi)\n\t"
129         "movw   %fs, 46(%edi)\n\t"
130         "movw   %gs, 48(%edi)\n\t"
131         "movw   %ss, 50(%edi)\n\t"
132
133         //movl  ___djgpp_exception_state_ptr, %eax
134         //movl  %eax, 60(%edi)
135
136         "popl   %edi\n\t"
137         );
138   return 0;
139 }
140
141 #else
142 #endif /*__GNUC__*/