update for HEAD-2003091401
[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 /*
20  * @implemented
21  */
22 int longjmp( jmp_buf env, int value )
23 {
24                 //push ebp             generated by the compiler
25                 //mov ebp, esp
26
27 #ifdef __GNUC__
28         __asm__ __volatile__ (
29                 "movl   8(%ebp),%edi\n\t"       /* get jmp_buf */
30                 "movl   12(%ebp),%eax\n\t"      /* store retval in j->eax */
31                 "movl   %eax,0(%edi)\n\t"
32
33                 "movw   46(%edi),%fs\n\t"
34                 "movw   48(%edi),%gs\n\t"
35                 "movl   4(%edi),%ebx\n\t"
36                 "movl   8(%edi),%ecx\n\t"
37                 "movl   12(%edi),%edx\n\t"
38                 "movl   24(%edi),%ebp\n\t"
39
40         /* Now for some uglyness.  The jmp_buf structure may be ABOVE the
41            point on the new SS:ESP we are moving to.  We don't allow overlap,
42            but do force that it always be valid.  We will use ES:ESI for
43            our new stack before swapping to it.  */
44
45                 "movw   50(%edi),%es\n\t"
46                 "movl   28(%edi),%esi\n\t"
47                 "subl   $28,%esi\n\t"   /* We need 7 working longwords on stack */
48
49                 "movl   60(%edi),%eax\n\t"
50                 "es\n\t"
51                 "movl   %eax,(%esi)\n\t"        /* Exception pointer */
52
53                 "movzwl 42(%edi),%eax\n\t"
54                 "es\n\t"
55                 "movl   %eax,4(%esi)\n\t"       /* DS */
56
57                 "movl   20(%edi),%eax\n\t"
58                 "es\n\t"
59                 "movl   %eax,8(%esi)\n\t"       /* EDI */
60
61                 "movl   16(%edi),%eax\n\t"
62                 "es\n\t"
63                 "movl   %eax,12(%esi)\n\t"      /* ESI */
64
65                 "movl   32(%edi),%eax\n\t"
66                 "es\n\t"
67                 "movl   %eax,16(%esi)\n\t"      /* EIP - start of IRET frame */
68
69                 "movl   40(%edi),%eax\n\t"
70                 "es\n\t"
71                 "movl   %eax,20(%esi)\n\t"      /* CS */
72
73                 "movl   36(%edi),%eax\n\t"
74                 "es\n\t"
75                 "movl   %eax,24(%esi)\n\t"      /* EFLAGS */
76
77                 "movl   0(%edi),%eax\n\t"
78                 "movw   44(%edi),%es\n\t"
79
80                 "movw   50(%edi),%ss\n\t"
81                 "movl   %esi,%esp\n\t"
82
83                 //"popl ___djgpp_exception_state_ptr\n\t"
84                 "popl   %edi\n\t"       // dummy popl instead of djgpp_exception_state_ptr
85                 "popl   %ds\n\t"
86                 "popl   %edi\n\t"
87                 "popl   %esi\n\t"
88
89                 "iret\n\t"                      /* actually jump to new cs:eip loading flags */
90         );
91
92 #else
93 #endif /*__GNUC__*/
94         return value; // dummy return never reached
95 }
96
97 #ifdef __GNUC__
98
99 /*
100  * @implemented
101  */
102 int _setjmp( jmp_buf env )
103 {
104                 //push ebp             generated by the compiler
105                 //mov ebp, esp
106         __asm__ __volatile__ (
107                 "pushl  %edi\n\t"
108                 "movl   8(%ebp),%edi\n\t"
109
110                 "movl   %eax, (%edi)\n\t"
111                 "movl   %ebx,4(%edi)\n\t"
112                 "movl   %ecx,8(%edi)\n\t"
113                 "movl   %edx,12(%edi)\n\t"
114                 "movl   %esi,16(%edi)\n\t"
115
116                 "movl   -4(%ebp),%eax\n\t"
117                 "movl   %eax,20(%edi)\n\t"
118
119                 "movl   (%ebp),%eax\n\t"
120                 "movl   %eax,24(%edi)\n\t"
121
122                 "movl   %esp,%eax\n\t"
123                 "addl   $12,%eax\n\t"
124                 "movl   %eax,28(%edi)\n\t"
125         
126                 "movl   4(%ebp),%eax\n\t"
127                 "movl   %eax,32(%edi)\n\t"
128         
129                 "pushfl\n\t"
130                 "popl   36(%edi)\n\t"
131
132                 "movw   %cs, 40(%edi)\n\t"
133                 "movw   %ds, 42(%edi)\n\t"
134                 "movw   %es, 44(%edi)\n\t"
135                 "movw   %fs, 46(%edi)\n\t"
136                 "movw   %gs, 48(%edi)\n\t"
137                 "movw   %ss, 50(%edi)\n\t"
138         
139         //movl  ___djgpp_exception_state_ptr, %eax
140         //movl  %eax, 60(%edi)
141
142                 "popl   %edi\n\t"
143                 );
144         return 0;
145 }
146
147 #else
148 #endif /*__GNUC__*/