branch update for HEAD-2003021201
[reactos.git] / lib / crtdll / 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__*/