tccrun: win64: add unwind function table for dynamic code
[tinycc.git] / win32 / lib / chkstk.S
blob272606153bfde1dde98b220b9fbcfb35ca494bed
1 /* ---------------------------------------------- */
2 /* chkstk86.s */
4 /* ---------------------------------------------- */
5 #ifndef TCC_TARGET_X86_64
6 /* ---------------------------------------------- */
8 .globl __chkstk
10 __chkstk:
11     xchg    (%esp),%ebp     /* store ebp, get ret.addr */
12     push    %ebp            /* push ret.addr */
13     lea     4(%esp),%ebp    /* setup frame ptr */
14     push    %ecx            /* save ecx */
15     mov     %ebp,%ecx
16 P0:
17     sub     $4096,%ecx
18     test    %eax,(%ecx)
19     sub     $4096,%eax
20     cmp     $4096,%eax
21     jge     P0
22     sub     %eax,%ecx
23     test    %eax,(%ecx)
25     mov     %esp,%eax
26     mov     %ecx,%esp
27     mov     (%eax),%ecx     /* restore ecx */
28     jmp     *4(%eax)
30 /* ---------------------------------------------- */
31 #else
32 /* ---------------------------------------------- */
34 .globl __chkstk
36 __chkstk:
37     xchg    (%rsp),%rbp     /* store ebp, get ret.addr */
38     push    %rbp            /* push ret.addr */
39     lea     8(%rsp),%rbp    /* setup frame ptr */
40     push    %rcx            /* save ecx */
41     mov     %rbp,%rcx
42     movslq  %eax,%rax
43 P0:
44     sub     $4096,%rcx
45     test    %rax,(%rcx)
46     sub     $4096,%rax
47     cmp     $4096,%rax
48     jge     P0
49     sub     %rax,%rcx
50     test    %rax,(%rcx)
52     mov     %rsp,%rax
53     mov     %rcx,%rsp
54     mov     (%rax),%rcx     /* restore ecx */
55     jmp     *8(%rax)
57 /* ---------------------------------------------- */
58 /* setjmp/longjmp support */
60 .globl tinyc_getbp
61 tinyc_getbp:
62     mov %rbp,%rax
63     ret
65 /* ---------------------------------------------- */
66 #endif
67 /* ---------------------------------------------- */
70 /* ---------------------------------------------- */
71 #ifndef TCC_TARGET_X86_64
72 /* ---------------------------------------------- */
75     int _except_handler3(
76        PEXCEPTION_RECORD exception_record,
77        PEXCEPTION_REGISTRATION registration,
78        PCONTEXT context,
79        PEXCEPTION_REGISTRATION dispatcher
80     );
82     int __cdecl _XcptFilter(
83        unsigned long xcptnum,
84        PEXCEPTION_POINTERS pxcptinfoptrs
85     );
87     struct _sehrec {
88        void *esp;                // 0
89        void *exception_pointers; // 1
90        void *prev;               // 2
91        void *handler;            // 3
92        void *scopetable;         // 4
93        int trylevel;             // 5
94        void *ebp                 // 6
95     };
97     // this is what the assembler code below means:
98     __try
99     {
100          // ...
101     }
102     __except (_XcptFilter(GetExceptionCode(), GetExceptionInformation()))
103     {
104          exit(GetExceptionCode());
105     }
108 .globl _exception_info
109 _exception_info:
110     mov 1*4-24(%ebp),%eax
111     ret
113 .globl _exception_code
114 _exception_code:
115     call _exception_info
116     mov (%eax),%eax
117     mov (%eax),%eax
118     ret
120 seh_filter:
121     call _exception_info
122     push %eax
123     call _exception_code
124     push %eax
125     call _XcptFilter
126     add $ 8,%esp
127     ret
129 seh_except:
130     mov 0*4-24(%ebp),%esp
131     call _exception_code
132     push %eax
133     call _exit
135 // msvcrt wants scopetables aligned and in read-only segment (using .text)
136 .align 4
137 seh_scopetable:
138     .long -1
139     .long seh_filter
140     .long seh_except
142 seh_handler:
143     jmp _except_handler3
145 .globl ___try__
146 ___try__:
147 .globl __try__
148 __try__:
149     push %ebp
150     mov 8(%esp),%ebp
152 //    void *esp;
153     lea 12(%esp),%eax
154     mov %eax,0*4(%ebp)
156 //    void *exception_pointers;
157     xor %eax,%eax
158     mov %eax,1*4(%ebp)
160 //    void *prev;
161     mov %fs:0,%eax
162     mov %eax,2*4(%ebp)
164 //    void *handler;
165     mov $ seh_handler,%eax
166     mov %eax,3*4(%ebp)
168 //    void *scopetable;
169     mov $ seh_scopetable,%eax
170     mov %eax,4*4(%ebp)
172 //    int trylevel;
173     xor %eax,%eax
174     mov %eax,5*4(%ebp)
176 //    register new SEH
177     lea 2*4(%ebp),%eax
178     mov %eax,%fs:0
180     pop %ebp
181     ret
183 /* ---------------------------------------------- */
184 #else
185 /* ---------------------------------------------- */
187 /* SEH on x86-64 not implemented */
189 /* ---------------------------------------------- */
190 #endif
191 /* ---------------------------------------------- */