#ifdef USE_THREADS monitorenter/exit calls.
[cacao.git] / src / vm / jit / i386 / asmpart.S
1 /* vm/jit/i386/asmpart.S - Java-C interface functions for i386
2
3    Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4    R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5    C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6    Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
23    02111-1307, USA.
24
25    Contact: cacao@complang.tuwien.ac.at
26
27    Authors: Andreas Krall
28             Reinhard Grafl
29             Christian Thalinger
30
31    Changes: Joseph Wenninger
32
33    $Id: asmpart.S 1830 2004-12-29 13:47:15Z twisti $
34
35 */
36
37
38 #include "config.h"
39 #include "vm/jit/i386/offsets.h"
40 #include "vm/jit/i386/asmoffsets.h"
41
42
43 #define itmp1    %eax
44 #define itmp2    %ecx
45 #define itmp3    %edx
46
47 #define itmp1b   %al
48 #define itmp2b   %cl
49 #define itmp3b   %dl
50                 
51         .text
52
53
54 /********************* exported functions and variables ***********************/
55
56         .globl asm_calljavafunction
57         .globl calljava_xhandler
58         .globl asm_calljavafunction2
59         .globl asm_calljavafunction2long
60         .globl asm_calljavafunction2double
61         .globl calljava_xhandler2
62
63         .globl asm_call_jit_compiler
64         .globl asm_handle_builtin_exception
65         .globl asm_handle_nat_exception
66         .globl asm_handle_exception
67         .globl asm_check_clinit
68         .globl asm_builtin_checkcast    
69         .globl asm_builtin_checkarraycast
70         .globl asm_builtin_newarray
71         .globl asm_builtin_anewarray
72         .globl asm_builtin_newarray_array
73         .globl asm_builtin_aastore
74
75 #if defined(USE_THREADS)
76         .globl asm_builtin_monitorenter
77         .globl asm_builtin_monitorexit
78 #endif
79
80         .globl asm_builtin_ldiv
81         .globl asm_builtin_lrem
82     .globl asm_builtin_f2i
83     .globl asm_builtin_f2l
84     .globl asm_builtin_d2i
85     .globl asm_builtin_d2l
86         .globl asm_builtin_arrayinstanceof
87         .globl asm_perform_threadswitch
88         .globl asm_initialize_thread_stack
89         .globl asm_switchstackandcall
90         .globl asm_getcallingmethod
91         .globl asm_builtin_new
92         .globl asm_criticalsections
93         .globl asm_getclassvalues_atomic
94
95         .globl asm_throw_and_handle_exception
96         .globl asm_throw_and_handle_hardware_arithmetic_exception
97
98         .globl asm_prepare_native_stackinfo
99         .globl asm_remove_native_stackinfo
100
101
102 /********************* function asm_calljavafunction ***************************
103 *                                                                              *
104 *   This function calls a Java-method (which possibly needs compilation)       *
105 *   with up to 4 address parameters.                                           *
106 *                                                                              *
107 *   This functions calls the JIT-compiler which eventually translates the      *
108 *   method into machine code.                                                  *
109 *                                                                              *
110 *   C-prototype:                                                               *
111 *    javaobject_header *asm_calljavamethod (methodinfo *m,                     *
112 *         void *arg1, void *arg2, void *arg3, void *arg4);                     *
113 *                                                                              *
114 *******************************************************************************/
115
116 call_name:
117         .ascii  "calljavafunction\0\0"
118
119         .align  8
120         .long   0                         /* catch type all                       */
121         .long   calljava_xhandler         /* handler pc                           */
122         .long   calljava_xhandler         /* end pc                               */
123         .long   asm_calljavafunction      /* start pc                             */
124         .long   1                         /* extable size                         */
125         .long   0                         /* line number table  start             */
126         .long   0                         /* line number table  size              */
127         .long   0                         /* fltsave                              */
128         .long   0                         /* intsave                              */
129         .long   0                         /* isleaf                               */
130         .long   0                         /* IsSync                               */
131         .long   32                        /* frame size                           */
132         .long   0                         /* method pointer (pointer to name)     */
133
134 asm_calljavafunction:
135         push    %ebp                      /* allocate stack space                 */
136         mov     %esp, %ebp
137
138         push    %ebx                      /* save registers                       */
139         push    %esi
140         push    %edi
141         
142         sub     $32,%esp                  /* pass the remaining parameters        */
143         xor     %edx,%edx
144
145         mov     %edx,28(%esp)             /* convert parms to 8 byte              */
146         mov     24(%ebp),%eax
147         mov     %eax,24(%esp)
148                 
149         mov     %edx,20(%esp)
150         mov     20(%ebp),%eax
151         mov     %eax,16(%esp)
152
153         mov     %edx,12(%esp)
154         mov     16(%ebp),%eax
155         mov     %eax,8(%esp)
156
157         mov     %edx,4(%esp)
158         mov     12(%ebp),%eax
159         mov     %eax,(%esp)
160
161         mov     8(%ebp),%eax              /* move function pointer to %eax        */
162
163         lea     asm_call_jit_compiler,%edx 
164         call    *%edx                     /* call JIT compiler                    */
165         
166         add     $32,%esp
167         pop     %edi                      /* restore registers                    */
168         pop     %esi
169         pop     %ebx
170         leave
171         ret
172
173 calljava_xhandler:
174         push    %eax                      /* pass exception pointer               */
175         call    builtin_throw_exception
176         add     $4,%esp
177
178         add     $32,%esp
179         pop     %edi                      /* restore registers                    */
180         pop     %esi
181         pop     %ebx
182         leave
183         ret
184
185
186 /********************* function asm_calljavafunction ***************************
187 *                                                                              *
188 *   This function calls a Java-method (which possibly needs compilation)       *
189 *   with up to 4 address parameters.                                           *
190 *                                                                              *
191 *   This functions calls the JIT-compiler which eventually translates the      *
192 *   method into machine code.                                                  *
193 *                                                                              *
194 *   C-prototype:                                                               *
195 *    javaobject_header *asm_calljavafunction2(methodinfo *m,                   *
196 *         u4 count, u4 size, void *callblock);                                 *
197 *                                                                              *
198 *******************************************************************************/
199
200 call_name2:
201         .ascii  "calljavafunction2\0\0"
202
203         .align  8
204         .long   0                         /* catch type all                       */
205         .long   calljava_xhandler2        /* handler pc                           */
206         .long   calljava_xhandler2        /* end pc                               */
207         .long   asm_calljavafunction2     /* start pc                             */
208         .long   1                         /* extable size                         */
209         .long   0                         /* line number table start              */
210         .long   0                         /* line number table size               */
211         .long   0                         /* fltsave                              */
212         .long   0                         /* intsave                              */
213         .long   0                         /* isleaf                               */
214         .long   0                         /* IsSync                               */
215         .long   32                        /* frame size                           */
216         .long   0                         /* method pointer (pointer to name)     */
217
218 asm_calljavafunction2:
219 asm_calljavafunction2double:
220 asm_calljavafunction2long:
221         push    %ebp
222         mov     %esp,%ebp                 /* save stackptr                        */
223
224         push    %ebx                      /* save registers                       */
225         push    %esi
226         push    %edi
227
228         mov     20(%ebp),%eax             /* pointer to arg block                 */
229         mov     12(%ebp),%ecx             /* arg count                            */
230         test    %ecx,%ecx                 /* maybe we have no args                */
231         jle     calljava_copydone
232
233         mov     %ecx,%edx                 /* calculate stack size                 */
234         shl     $3,%edx
235         mov     %edx,%esi                 /* save in callee saved register        */
236         sub     %esi,%esp                 /* stack frame for arguments            */
237         mov     %esp,%edi
238
239 calljava_copyloop:
240     mov     offjniitem(%eax),%edx
241     mov     %edx,0(%edi)
242     mov     offjniitem+4(%eax),%edx
243     mov     %edx,4(%edi)
244
245         sub     $1,%ecx                   /* are there any args left?             */
246         test    %ecx,%ecx
247         jle     calljava_copydone
248
249         add     $sizejniblock,%eax        /* goto next argument block             */
250     add     $8,%edi                   /* increase sp to next argument         */
251         jmp     calljava_copyloop
252
253 calljava_copydone:
254         mov     8(%ebp),%eax              /* move function pointer to %eax        */
255
256         lea     asm_call_jit_compiler,%edx 
257         call    *%edx                     /* call JIT compiler                    */
258         
259 calljava_return2:
260         add     %esi,%esp                 /* remove arg stack frame               */
261         pop     %edi                      /* restore registers                    */
262         pop     %esi
263         pop     %ebx
264         leave
265         ret
266
267 calljava_xhandler2:
268         push    %eax                      /* pass exception pointer               */
269         call    builtin_throw_exception
270         add     $4,%esp
271     
272         add     %esi,%esp                 /* remove arg stack frame               */
273         pop     %edi                      /* restore registers                    */
274         pop     %esi
275         pop     %ebx
276         leave
277         ret
278
279
280 /****************** function asm_call_jit_compiler *****************************
281 *                                                                              *
282 *   invokes the compiler for untranslated JavaVM methods.                      *
283 *                                                                              *
284 *   Register R0 contains a pointer to the method info structure (prepared      *
285 *   by createcompilerstub). Using the return address in R26 and the            *
286 *   offset in the LDA instruction or using the value in methodptr R28 the      *
287 *   patching address for storing the method address can be computed:           *
288 *                                                                              *
289 *   method address was either loaded using                                     *
290 *                                                                              *
291 *   i386_mov_imm_reg(a, REG_ITMP2)                ; invokestatic/special       *
292 *   i386_call_reg(REG_ITMP2)                                                   *
293 *                                                                              *
294 *   or                                                                         *
295 *                                                                              *
296 *   i386_mov_membase_reg(REG_SP, 0, REG_ITMP1)    ; invokevirtual/interface    *
297 *   i386_mov_membase_reg(REG_ITMP1, OFFSET(, vftbl), REG_ITMP2)                *
298 *   i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, table[0]) + \                *
299 *       sizeof(methodptr) * m->vftblindex, REG_ITMP1)                          *
300 *   i386_call_reg(REG_ITMP1)                                                   *
301 *                                                                              *
302 *   in the static case the method pointer can be computed using the            *
303 *   return address and the lda function following the jmp instruction          *
304 *                                                                              *
305 *******************************************************************************/
306
307 asm_call_jit_compiler:
308         push    %ebx                /* save register                              */
309     push    %ebp
310                         
311         mov     8(%esp),%ebp        /* get return address (2 push)                */
312         mov     -1(%ebp),%bl        /* get function code                          */
313         cmp     $0xd1,%bl           /* called with `call *REG_ITMP2' (%ecx)?      */
314         jne             L_not_static_special
315
316         sub     $6,%ebp             /* calculate address of immediate             */
317         jmp             L_call_jit_compile
318                 
319 L_not_static_special:
320         cmp     $0xd0,%bl           /* called with `call *REG_ITMP1' (%eax)       */
321         jne             L_not_virtual_interface
322         
323         sub     $6,%ebp             /* calculate address of offset                */
324         mov     (%ebp),%ebp         /* get offset                                 */
325         add     itmp2,%ebp          /* add base address to get method address     */
326         jmp             L_call_jit_compile
327
328 L_not_virtual_interface:        /* a call from asm_calljavafunction           */
329         xor     %ebp,%ebp
330                 
331 L_call_jit_compile:
332         push    %ebp                /* save address for method pointer            */
333
334         push    %eax                /* push methodpointer on stack                */
335         call    jit_compile
336         add     $4,%esp
337
338         pop     %ebp                /* restore address for method pointer         */
339
340         test    %eax,%eax           /* check for exception                        */
341         je      L_exception
342
343         test    %ebp,%ebp           /* is address == 0 (asm_calljavafunction)     */
344         je              L_call_method
345         
346         mov     %eax,(%ebp)         /* and now save the new pointer               */
347
348 L_call_method:
349         pop     %ebp                /* restore registers                          */
350         pop     %ebx
351                 
352         jmp             *%eax               /* ...and now call the new method             */
353
354 L_exception:
355         pop     %ebp                /* restore registers                          */
356         pop     %ebx
357
358 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
359         call    builtin_asm_get_exceptionptrptr
360         mov     %eax,%ecx
361         mov     (%ecx),%eax         /* get the exception pointer                  */
362         movl    $0,(%ecx)           /* clear the exception pointer                */
363 #else
364         lea     _exceptionptr,%ecx
365         mov     (%ecx),%eax         /* get the exception pointer                  */
366         movl    $0,(%ecx)           /* clear the exception pointer                */
367 #endif
368
369         pop     %ecx                /* delete return address                      */
370         sub     $2,%ecx             /* faulting address is return adress - 2      */
371
372 L_refillinStacktrace:               /*a compilation error should cause a stacktrace
373                                     which starts at the method call, which caused
374                                     the compilation of the new function. Until this
375                                     point the trace is invalid anyways, since it is
376                                     not complete. Compared to other runtimes it will
377                                     not be correct either, since we report eg class
378                                     not found errors too early, since we always
379                                     compile methods completely. The native info
380                                     should be moved around the jit call to get
381                                     a more compliant trace for the "exception in
382                                     initializer" case*/
383         push %ecx               /* store fault adress */
384         push %eax               /* temporarily save exception pointer*/
385         push $0                 /* internal function */
386         call builtin_asm_get_stackframeinfo
387         push %eax       /* save location of thread specific stack info head pointer */
388         mov (%eax),%ecx /* save old value of pointer*/
389         push %ecx
390         mov %esp,(%eax) /*store pointer to this structure*/
391         mov 12(%esp),%eax  /* get the exception pointer again*/
392         movl $0,12(%esp) /*java stack begins just above structure*/
393         push $0 /*used for the jni_callblock structure*/
394         push %eax /*save eax for later */
395         /* get fillInStackTrace method*/
396         push utf_fillInStackTrace_desc
397         push utf_fillInStackTrace_name
398         mov offobjvftbl(%eax),%ecx
399         mov offclass(%ecx),%eax
400         push %eax
401         call class_resolvemethod
402         add $12,%esp
403         push $0
404         push $4 /*TYPE_ADR*/
405         push %esp
406         push $sizejniblock
407         push $1
408         push %eax
409         call asm_calljavafunction2
410         add $24,%esp
411
412         /*remove native stack info */
413         mov 8(%esp),%ecx
414         mov 12(%esp),%eax
415         mov %ecx,(%eax)
416         mov (%esp),%eax
417         add $24,%esp
418         pop %ecx
419
420         
421         jmp     asm_handle_exception
422
423
424 /********************* function asm_handle_exception ***************************
425 *                                                                              *
426 *   This function handles an exception. It does not use the usual calling      *
427 *   conventions. The exception pointer is passed in REG_ITMP1 and the          *
428 *   pc from the exception raising position is passed in REG_ITMP2. It searches *
429 *   the local exception table for a handler. If no one is found, it unwinds    *
430 *   stacks and continues searching the callers.                                *
431 *                                                                              *
432 *   void asm_handle_exception (exceptionptr, exceptionpc);                     *
433 *                                                                              *
434 *******************************************************************************/
435
436 asm_handle_nat_exception:
437                 add     $4,%esp                                         /* clear return address of native stub */
438                 
439 asm_handle_exception:
440 asm_handle_exception_loop:
441                 push    %ebp
442                 mov     %esp,%ebp
443         
444                 push    %eax                                            /* save exception pointer         */
445                 push    %ecx                        /* save exception pc              */
446
447                 call    codegen_findmethod          /* get the data segment ptr       */
448                 mov     %eax,%edx
449                         
450                 mov     -4(%ebp),%eax
451                 mov     -8(%ebp),%ecx               /* could be changed in findmethod */
452
453                 push    %edx                                            /* save data segment pointer      */
454                 push    %ebx
455                 push    %esi
456                 push    %edi
457                 
458 ex_stack_loop:
459                 sub     $20,%esp
460                 mov     %eax,(%esp)                                     /* exception pointer              */
461                 mov     MethodPointer(%edx),%eax        /* method pointer                 */
462                 mov     %eax,4(%esp)
463                 mov     %ecx,8(%esp)                            /* exception pc                   */
464                 movl    $0,12(%esp)                 /* line number                    */
465                 movl    $1,16(%esp)                                     /* set no unwind flag             */
466                 call    builtin_trace_exception
467                 add     $20,%esp
468                 mov     -12(%ebp),%esi                          /* %esi = data segment pointer    */
469                 mov     ExTableSize(%esi),%ecx          /* %ecx = exception table size    */
470                 test    %ecx,%ecx                                       /* if empty table skip            */
471                 je      empty_table
472
473                 lea             ExTableStart(%esi),%edi         /* %edi = start of exception table*/
474                 mov     -4(%ebp),%eax               /* get xptr                       */
475                 
476 ex_table_loop:
477                 mov     -8(%ebp),%edx                           /* get xpc                        */
478
479                 mov     ExStartPC(%edi),%ebx            /* %ebx = exception start pc      */
480                 cmp     %edx,%ebx                                       /* %ebx = (startpc <= xpc)        */
481                 jg      ex_table_cont                           /* if (false) continue            */
482                 mov     ExEndPC(%edi),%ebx                      /* %ebx = exception end pc        */
483                 cmp     %ebx,%edx                                       /* %ebx = (xpc < endpc)           */
484                 jge     ex_table_cont                           /* if (false) continue            */
485                 mov     ExCatchType(%edi),%ebx          /* arg1 = exception catch type    */
486                 test    %ebx,%ebx                                       /* NULL catches everything        */
487                 je      ex_handle_it
488
489         cmpl    $0,offclassloaded(%ebx)     /* check if class is loaded           */
490         jne     L_class_loaded
491
492         sub     $3*4,%esp
493         mov     %eax,1*4(%esp)              /* save not callee saved regs         */
494         mov     %ecx,2*4(%esp)
495
496         mov     %ebx,0*4(%esp)              /* exception class is argument        */
497         call    class_load
498
499         mov     0*4(%esp),%ebx
500         mov     1*4(%esp),%eax
501         mov     2*4(%esp),%ecx
502         add     $3*4,%esp
503
504 L_class_loaded:
505         cmpl    $0,offclasslinked(%ebx)
506         jne     L_class_linked
507
508         sub     $3*4,%esp
509         mov     %eax,1*4(%esp)              /* save not callee saved regs         */
510         mov     %ecx,2*4(%esp)
511
512         mov     %ebx,0*4(%esp)              /* exception class is argument        */
513         call    class_link
514
515         mov     0*4(%esp),%ebx
516         mov     1*4(%esp),%eax
517         mov     2*4(%esp),%ecx
518         add     $3*4,%esp
519
520 L_class_linked:
521 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
522         push    %ebx
523
524 _crit_restart1:
525         mov     0(%esp),%ebx
526 #endif
527                 
528 _crit_begin1:
529         mov     offobjvftbl(%eax),%esi          /* %esi = vftblptr(xptr)              */
530         mov     offclassvftbl(%ebx),%ebx    /* %ebx = vftblptr(catchtype) class (not obj) */
531         mov     offbaseval(%esi),%esi           /* %esi = baseval(xptr)               */
532         mov     offbaseval(%ebx),%edx           /* %edx = baseval(catchtype)          */
533         mov     offdiffval(%ebx),%ebx           /* %ebx = diffval(catchtype)          */
534 _crit_end1:
535         sub     %edx,%esi                                       /* %esi = baseval(xptr) - baseval(catchtype) */
536
537 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
538         add     $4,%esp
539 #endif
540         
541         cmp     %ebx,%esi                                       /* xptr is instanceof catchtype       */
542         ja      ex_table_cont
543                 
544 ex_handle_it:
545                 mov     ExHandlerPC(%edi),%edx
546                 
547                 pop     %edi                        /* restore registers              */
548                 pop     %esi
549                 pop     %ebx
550         add     $8,%esp                     /* suck %ecx, %edx                */
551         pop     %eax                        /* restore xptr                   */
552
553                 leave
554                 jmp             *%edx                       /* jump to exception handler      */
555
556 ex_table_cont:
557                 lea     ExEntrySize(%edi),%edi
558                 dec     %ecx
559                 test    %ecx,%ecx
560                 jg      ex_table_loop
561                 
562 empty_table:
563         pop     %edi
564         pop     %esi
565         pop     %ebx
566         pop     %edx                        /* restore data segment pointer   */
567         pop     %ecx
568         pop     %eax
569         pop     %ebp
570
571         push    %eax                        /* save exception pointer         */
572         
573 ex_already_cleared:
574                 mov     IsSync(%edx),%eax                       /* %eax = SyncOffset              */
575                 test    %eax,%eax                                       /* if zero no monitorexit         */
576                 je      no_monitor_exit
577
578 #if defined(USE_THREADS)
579         add     %esp,%eax
580         mov     -4(%eax),%eax               /* we have the xptr on the stack  */
581         push    %edx                        /* save regs                      */
582         push    %eax
583                 call    builtin_monitorexit
584                 add     $4,%esp
585         pop     %edx                        /* restore regs                   */
586 #endif
587
588 no_monitor_exit:
589         mov     %esp,%eax
590         add     FrameSize(%edx),%eax        /* %eax = frame size              */
591         add     $4,%eax                     /* we have the xptr on the stack  */
592         
593                 mov     IntSave(%edx),%ecx          /* %ecx = saved int register count*/
594                 test    %ecx,%ecx
595                 je      noint
596                 cmp     $1,%ecx
597                 je      int1
598                 cmp     $2,%ecx
599                 je      int2
600                 cmp     $3,%ecx
601                 je      int3
602
603 int4:   
604                 mov     -32(%eax),%ebx
605
606 int3:   
607                 mov     -24(%eax),%ebp
608
609 int2:   
610                 mov     -16(%eax),%esi
611
612 int1:   
613                 mov     -8(%eax),%edi
614
615                 shl     $3,%ecx                                         /* multiply by 8 bytes             */
616                 sub     %ecx,%eax
617                 
618 noint:
619                 mov     FltSave(%edx),%ecx                      /* %ecx = saved flt register count */
620                 test    %ecx,%ecx
621                 je      noflt
622                 cmp     $1,%ecx
623                 je      flt1
624                 cmp     $2,%ecx
625                 je      flt2
626                 cmp     $3,%ecx
627                 je      flt3
628                 
629 flt4:   
630                 fldl    -32(%eax)
631                 fstp    %st(1)
632
633 flt3:   
634                 fldl    -24(%eax)
635                 fstp    %st(2)
636                 
637 flt2:   
638                 fldl    -16(%eax)
639                 fstp    %st(3)
640                 
641 flt1:   
642                 fldl    -8(%eax)
643                 fstp    %st(4)
644                 
645 noflt:
646         pop     %eax                        /* restore exception pointer      */
647         
648         mov     FrameSize(%edx),%ecx        /* %ecx = frame size              */
649         add     %ecx,%esp                   /* unwind stack                   */
650         
651                 pop     %ecx                        /* the new xpc is return address  */
652                 sub     $2,%ecx
653                 
654                 jmp             asm_handle_exception_loop
655                 
656
657 /* asm_check_clinit ************************************************************
658
659    DOCUMENT ME!!!
660
661    Stack layout:
662
663         16  ra      ; return address of patched call in java machine code
664         12  xmcode  ; additional machine code (only for i386 and x86_64)
665         8   mcode   ; machine code to patch back in
666         4   class   ; pointer to class
667         0   sp      ; stack pointer of java stack frame + return address
668
669 *******************************************************************************/
670
671 asm_check_clinit:
672         mov     4(%esp),%eax                /* get fieldinfo's class pointer      */
673         mov     offclassinit(%eax),%eax     /* get initialized flag               */
674         test    %eax,%eax
675         jnz     L_is_initialized
676
677         /*3*4 bytes*/
678         mov 16(%esp),itmp1
679         push itmp1                        /*return adress into java machine code */
680         mov 4(%esp),itmp1
681         push itmp1                        /*begin of java stack frame*/
682         pushl $0                           /*internal (invisible) method*/
683         call asm_prepare_native_stackinfo /*puts additional 2 *4 bytes of
684                                                 data onto the stack */
685
686         sub     $4,%esp
687         mov     20+4+4(%esp),itmp1          /* get class pointer                  */
688         mov     itmp1,(%esp)                /* store class pointer as a0          */
689         call    class_init                  /* call class_init function           */
690         add     $4,%esp
691
692         call asm_remove_native_stackinfo  /* removes 4* 4 bytes and leaves ret
693                                                  into java machine code on stack  */
694         add     $4,%esp                   /* ret address no longer needed, is still
695                                                 on stack a few bytes above */
696
697         test    %eax,%eax                   /* we had an exception                */
698         je      L_initializererror
699
700 L_is_initialized:
701         mov     16(%esp),itmp1              /* get return address                 */
702         sub     $5,itmp1                    /* remove size of `call rel32'        */
703
704         mov     12(%esp),itmp2              /* get xmcode machine code            */
705         movb    itmp2b,(itmp1)              /* patch back in 1 byte               */
706         mov     8(%esp),itmp2               /* get mcode machine code             */
707         mov     itmp2,1(itmp1)              /* patch back in 4 bytes              */
708
709         add     $(5*4),%esp                 /* remove stub stack frame incl. ra   */
710
711         jmp     *itmp1                      /* jump to patched code an execute it */
712
713 L_initializererror:
714         add     $(4*4),%esp                 /* remove stub stack frame            */
715
716 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
717         call    builtin_asm_get_exceptionptrptr
718         mov     %eax,%ecx
719         mov     (%ecx),%eax                 /* get the exception pointer          */
720         movl    $0,(%ecx)                   /* clear the exception pointer        */
721 #else
722         lea     _exceptionptr,%ecx
723         mov     (%ecx),%eax                 /* get the exception pointer          */
724         movl    $0,(%ecx)                   /* clear the exception pointer        */
725 #endif
726
727         pop     itmp2                       /* get and delete ra                  */
728         sub     $5,itmp2                    /* faulting address is ra - 5         */
729
730         jmp     asm_handle_exception
731
732
733 /********************* function asm_builtin_monitorenter ***********************
734 *                                                                              *
735 *   Does null check and calls monitorenter or throws an exception              *
736 *                                                                              *
737 *******************************************************************************/
738
739 #if defined(USE_THREADS)
740 asm_builtin_monitorenter:
741         cmpl    $0,4(%esp)
742         je      nb_monitorenter             /* if (null) throw exception          */
743         jmp             builtin_monitorenter        /* else call builtin_monitorenter     */
744
745 nb_monitorenter:
746         mov string_java_lang_NullPointerException,%eax
747         pop %ecx
748         sub $2,%ecx
749         jmp asm_throw_and_handle_exception
750
751 #if 0
752         push    string_java_lang_NullPointerException
753         call    new_exception
754         add     $(1*4),%esp
755         
756         pop     %ecx                        /* delete return address              */
757         sub     $2,%ecx                     /* faulting address is return adress - 2 */
758         jmp     asm_handle_exception
759 #endif          
760 #endif
761
762
763 /********************* function asm_builtin_monitorexit ************************
764 *                                                                              *
765 *   Does null check and calls monitorexit or throws an exception               *
766 *                                                                              *
767 *******************************************************************************/
768
769 #if defined(USE_THREADS)
770 asm_builtin_monitorexit:
771         mov     4(%esp),%eax
772     test    %eax,%eax
773         je      nb_monitorexit              /* if (null) throw exception          */
774     push    %ecx                        /* save registers which could be used */
775     push    %edx
776     push    %eax
777         call    builtin_monitorexit         /* else call builtin_monitorenter     */
778     add     $4,%esp
779     pop     %edx                        /* restore registers which could be used */
780     pop     %ecx
781     ret
782
783 nb_monitorexit:
784         mov string_java_lang_NullPointerException,%eax
785         pop %ecx
786         sub $2,%ecx
787         jmp asm_throw_and_handle_exception
788
789 #if 0
790         push    string_java_lang_NullPointerException
791         call    new_exception
792         add     $(1*4),%esp
793         
794         pop     %ecx                    /* delete return address              */
795         sub     $2,%ecx                 /* faulting address is return adress - 2 */
796         jmp     asm_handle_exception
797 #endif
798 #endif
799
800
801 /************************ function asm_builtin_ldiv ****************************
802 *                                                                              *
803 *   Does null check and calls ldiv or throws an exception                      *
804 *                                                                              *
805 *******************************************************************************/
806
807 asm_builtin_ldiv:
808         mov     12(%esp),%eax
809         or      16(%esp),%eax
810         test    %eax,%eax                   /* if (null) throw exception          */
811         je      nb_ldiv
812
813         jmp     builtin_ldiv
814
815 nb_ldiv:
816         pop %ecx
817         sub $2,%ecx
818         jmp asm_throw_and_handle_hardware_arithmetic_exception
819 #if 0
820         push    string_java_lang_ArithmeticException_message
821         push    string_java_lang_ArithmeticException
822         call    new_exception_message
823         add     $(2*4),%esp
824         
825         pop     %ecx                        /* delete return address              */
826         sub     $2,%ecx                     /* faulting address is return adress - 2 */
827         jmp     asm_handle_exception
828 #endif                          
829
830 /************************ function asm_builtin_lrem ****************************
831 *                                                                              *
832 *   Does null check and calls lrem or throws an exception                      *
833 *                                                                              *
834 *******************************************************************************/
835
836 asm_builtin_lrem:
837         mov     12(%esp),%eax
838         or      16(%esp),%eax
839         test    %eax,%eax                   /* if (null) throw exception          */
840         je      nb_lrem
841
842         jmp     builtin_lrem
843
844 nb_lrem:
845         pop %ecx
846         sub $2,%ecx
847         jmp asm_throw_and_handle_hardware_arithmetic_exception
848 #if 0
849         push    string_java_lang_ArithmeticException_message
850         push    string_java_lang_ArithmeticException
851         call    new_exception_message
852         add     $(2*4),%esp
853
854         pop     %ecx                        /* delete return address              */
855         sub     $2,%ecx                     /* faulting address is return adress - 2 */
856         jmp     asm_handle_exception
857 #endif          
858
859 /************************ function asm_builtin_x2x *****************************
860 *                                                                              *
861 *   Wrapper functions for corner cases                                         *
862 *                                                                              *
863 *******************************************************************************/
864
865 asm_builtin_f2i:
866         sub     $4,%esp
867         fsts    (%esp)
868         call    builtin_f2i
869         add     $4,%esp
870         ret
871
872 asm_builtin_d2i:
873         sub     $8,%esp
874         fstl    (%esp)
875         call    builtin_d2i
876         add     $8,%esp
877         ret
878
879 asm_builtin_f2l:
880         sub     $4,%esp
881         fsts    (%esp)
882         call    builtin_f2l
883         add     $4,%esp
884         ret
885
886 asm_builtin_d2l:
887         sub     $8,%esp
888         fstl    (%esp)
889         call    builtin_d2l
890         add     $8,%esp
891         ret
892
893
894 /******************* function asm_builtin_checkarraycast ***********************
895 *                                                                              *
896 *   Does the cast check and eventually throws an exception                     *
897 *                                                                              *
898 *******************************************************************************/
899
900 asm_builtin_checkarraycast:
901         sub             $8,%esp                     /* build stack frame (2 * 4 bytes)    */
902
903         mov             12(%esp),%eax               /* 8 (frame) + 4 (return)             */
904         mov             %eax,(%esp)                 /* save object pointer                */
905
906         mov             20(%esp),%eax
907         mov             %eax,4(%esp)
908
909         call    builtin_checkarraycast      /* builtin_checkarraycast             */
910
911         test    %eax,%eax                   /* if (false) throw exception         */
912         je              nb_carray_throw
913
914         mov             12(%esp),%eax               /* return object pointer              */
915         add             $8,%esp
916         ret
917
918 nb_carray_throw:
919         add $8,%esp
920         mov string_java_lang_ClassCastException,%eax
921         pop %ecx
922         sub $2,%ecx
923         jmp asm_throw_and_handle_exception
924 #if 0
925         push    string_java_lang_ClassCastException
926         call    new_exception
927         add     $(1*4),%esp
928         
929         add             $8,%esp
930         
931         pop             %ecx                        /* delete return address              */
932         sub             $2,%ecx                     /* faulting address is return adress - 2 */
933         jmp             asm_handle_exception
934 #endif
935                 
936 /******************* function asm_builtin_newarray *****************************
937 *                                                                              *
938 *   Does the cast check and eventually throws an exception                     *
939 *                                                                              *
940 *******************************************************************************/
941
942 asm_builtin_newarray:
943         sub             $8,%esp                     /* build stack frame (2 * 4 bytes)    */
944
945         mov             12(%esp),%eax
946         mov             %eax,(%esp)
947
948         mov             20(%esp),%eax
949         mov             %eax,4(%esp)
950
951         call    builtin_newarray
952
953         add             $8,%esp
954         ret
955
956                 
957 /******************* function asm_builtin_aastore ******************************
958 *                                                                              *
959 *   Does the cast check and eventually throws an exception                     *
960 *                                                                              *
961 *******************************************************************************/
962
963 asm_builtin_aastore:
964         sub     $12,%esp                    /* build stack frame (3 * 4 bytes)    */
965
966         mov     16(%esp),%eax               /* 12 (frame) + 4 (return)            */
967         test    %eax,%eax                   /* if null pointer throw exception    */
968         je      nb_aastore_null
969
970         mov     offarraysize(%eax),%edx /* load size                          */
971         mov     24(%esp),%ecx               /* index                              */
972         cmp     %edx,%ecx                   /* do bound check                     */
973         jae     nb_aastore_bound            /* if out of bounds throw exception   */
974
975         shl     $2,%ecx                     /* index * 4                          */
976         add     %eax,%ecx                   /* add index * 4 to arrayref          */
977            
978         mov     %ecx,8(%esp)                /* save store position                */
979            
980         mov     16(%esp),%eax               /* 12 (frame) + 4 (return)            */
981         mov     %eax,(%esp)
982            
983         mov     32(%esp),%eax               /* object is second argument          */
984         mov     %eax,4(%esp)
985         
986         call    builtin_canstore            /* builtin_canstore(arrayref,object)  */
987
988         test    %eax,%eax                   /* if (false) throw exception         */
989         je      nb_aastore_store
990
991         mov     32(%esp),%eax
992         mov     8(%esp),%ecx
993         mov     %eax,offobjarrdata(%ecx)    /* store objectptr in array           */
994         
995         add     $12,%esp
996         ret
997
998 nb_aastore_null:
999         add $12,%esp
1000         mov string_java_lang_NullPointerException,%eax
1001         pop %ecx
1002         sub $2,%ecx
1003         jmp asm_throw_and_handle_exception
1004
1005 #if 0
1006         push    string_java_lang_NullPointerException
1007         call    new_exception
1008         add     $(1*4),%esp
1009         
1010         add     $12,%esp
1011         pop     %ecx                        /* delete return address              */
1012         sub     $2,%ecx                     /* faulting address is return adress - 2 */
1013         jmp             asm_handle_exception
1014 #endif
1015 nb_aastore_bound:
1016         add     $12,%esp
1017         mov     %ecx,%eax                        /* itmp2 contains array index         */
1018         pushl   $0  /*directly below return adress*/
1019         pushl   $0  /*internal (invisible) method*/
1020         call    asm_prepare_native_stackinfo /* puts 2*4 bytes onto stack*/
1021
1022         push    %eax
1023         call    new_arrayindexoutofboundsexception
1024         add     $(1*4),%esp
1025
1026         call    asm_remove_native_stackinfo /*return adress is the first on stack again*/
1027
1028         pop     %ecx                        /* delete return address              */
1029         sub     $2,%ecx                     /* faulting address is return adress - 2 */
1030         jmp     asm_handle_exception
1031                 
1032 nb_aastore_store:
1033         add     $12,%esp
1034
1035         mov string_java_lang_ArrayStoreException,%eax
1036         pop %ecx
1037         sub $2,%ecx
1038         jmp asm_throw_and_handle_exception
1039
1040 #if 0
1041         push    string_java_lang_ArrayStoreException
1042         call    new_exception
1043         add     $(1*4),%esp
1044         
1045         add     $12,%esp
1046         pop     %ecx                        /* delete return address              */
1047         sub     $2,%ecx                     /* faulting address is return adress - 2 */
1048         jmp     asm_handle_exception
1049 #endif
1050                 
1051 /******************* function asm_builtin_arrayinstanceof **********************
1052 *                                                                              *
1053 *   Does the instanceof check of arrays                                        *
1054 *                                                                              *
1055 *******************************************************************************/
1056
1057 asm_builtin_arrayinstanceof:
1058         sub             $8,%esp                     /* build stack frame (2 * 4 bytes)    */
1059
1060         mov     12(%esp),%eax
1061         mov     %eax,(%esp)
1062
1063         mov     20(%esp),%eax
1064         mov     %eax,4(%esp)
1065
1066         call    builtin_arrayinstanceof
1067
1068         add     $8,%esp
1069         ret
1070
1071                 
1072 /******************* function asm_initialize_thread_stack **********************
1073 *                                                                              *
1074 * initialized a thread stack                                                   *
1075 * (to)->restorePoint = asm_initialize_thread_stack((u1*)(func), (to)->stackEnd)*
1076 *                                                                              *
1077 *******************************************************************************/
1078
1079 asm_initialize_thread_stack:
1080                 mov             8(%esp),%eax            /* (to)->stackEnd                     */
1081                 sub             $36,%eax                /* 4 bytes * 8 regs + 4 bytes func    */
1082                                 
1083                 xor             %edx,%edx
1084                 mov             %edx,0(%eax)
1085                 mov             %edx,4(%eax)
1086                 mov             %edx,8(%eax)
1087                 mov             %edx,12(%eax)
1088                 mov             %edx,16(%eax)
1089                 mov             %edx,20(%eax)
1090                 mov     %edx,24(%eax)
1091                 mov     %edx,28(%eax)
1092                                 
1093                 mov     4(%esp),%edx            /* save (u1*) (func)                  */
1094                 mov     %edx,32(%eax)
1095
1096                 ret                             /* return restorepoint in %eax        */
1097
1098
1099 /******************* function asm_perform_threadswitch *************************
1100 *                                                                              *
1101 *   void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop);         *
1102 *                                                                              *
1103 *   performs a threadswitch                                                    *
1104 *                                                                              *
1105 *******************************************************************************/
1106
1107 asm_perform_threadswitch:
1108         sub     $36,%esp
1109            
1110         mov     %eax,0(%esp)
1111         mov     %ecx,4(%esp)
1112         mov     %edx,8(%esp)
1113         mov     %ebx,12(%esp)
1114         mov     %esp,16(%esp)
1115         mov     %ebp,20(%esp)
1116         mov     %esi,24(%esp)
1117         mov     %edi,28(%esp)
1118            
1119         mov     36(%esp),%eax         /* save current return address              */
1120         mov     %eax,32(%esp)
1121            
1122         mov     40(%esp),%eax         /* first argument **from                    */
1123         mov     %esp,0(%eax)
1124            
1125         mov     48(%esp),%eax         /* third argument **stackTop                */
1126         mov     %esp,0(%eax)
1127            
1128         mov     44(%esp),%eax         /* second argument **to                     */
1129         mov     0(%eax),%esp          /* load new stack pointer                   */
1130            
1131         mov     0(%esp),%eax
1132         mov     4(%esp),%ecx
1133         mov     8(%esp),%edx
1134         mov     12(%esp),%ebx
1135                                       /* skip stack pointer                       */
1136         mov     20(%esp),%ebp
1137         mov     24(%esp),%esi
1138         mov     28(%esp),%edi
1139            
1140         add     $32,%esp              /* leave return address on stack            */
1141         ret
1142                 
1143
1144 /********************* function asm_switchstackandcall *************************
1145 *                                                                              *
1146 *  int asm_switchstackandcall (void *stack, void *func, void **stacktopsave,   *
1147 *                                      void *p);                                       *
1148 *                                                                              *
1149 *   Switches to a new stack, calls a function and switches back.               *
1150 *       a0      new stack pointer                                              *
1151 *       a1      function pointer                                               *
1152 *               a2              pointer to variable where stack top should be stored           *
1153 *       a3      pointer to user data, is passed to the function                *
1154 *                                                                              *
1155 *******************************************************************************/
1156
1157 asm_switchstackandcall:
1158         mov     4(%esp),%edx          /* first argument *stack                    */
1159         sub     $8,%edx               /* allocate new stack                       */
1160
1161         mov     (%esp),%eax           /* save return address on new stack         */
1162         mov     %eax,(%edx)
1163
1164         mov     %esp,4(%edx)          /* save old stack pointer on new stack      */
1165
1166         mov     12(%esp),%eax         /* third argument **stacktopsave            */
1167         mov     %esp,(%eax)           /* save old stack pointer to variable       */
1168
1169         mov     8(%esp),%eax          /* load function pointer                    */
1170         mov     16(%esp),%ecx         /* fourth argument *p                       */
1171         
1172         mov     %edx,%esp             /* switch to new stack                      */
1173
1174         sub     $4,%esp
1175         mov     %ecx,0(%esp)          /* pass pointer                             */
1176         call    *%eax                 /* and call function                        */
1177         add     $4,%esp
1178
1179         mov     (%esp),%edx           /* load return address                      */
1180         mov     4(%esp),%esp          /* switch to old stack                      */
1181         mov     %edx,(%esp)
1182         ret
1183
1184                 
1185 asm_throw_and_handle_exception:
1186         push %ecx
1187         pushl $0 /* the pushed XPC is directly below the java frame*/
1188         pushl $0
1189         call asm_prepare_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
1190         
1191         push %eax
1192         call new_exception
1193         add $4,%esp   /*remove parameter*/
1194
1195         call asm_remove_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
1196
1197         pop %ecx
1198         jmp asm_handle_exception
1199         ret /*should never be reached */
1200
1201 asm_throw_and_handle_hardware_arithmetic_exception:
1202         
1203         push %ecx
1204         pushl $0 /* the pushed XPC is directly below the java frame*/
1205         pushl $0
1206         call asm_prepare_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
1207         
1208         mov string_java_lang_ArithmeticException_message,%eax
1209         push %eax
1210         mov string_java_lang_ArithmeticException,%eax
1211         push %eax
1212
1213         call new_exception_message
1214         add $8,%esp /*remove parameters */
1215
1216         call asm_remove_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
1217
1218         pop %ecx
1219         jmp asm_handle_exception
1220         ret /*should never be reached */
1221
1222 asm_builtin_new:
1223 /*optimize a littlebit */
1224                 mov %esp,%eax
1225 /*DEBUG*/
1226 /*              push %eax
1227                 call i386_native_stub_debug
1228                 pop %eax */
1229                 
1230                 movl 4(%esp),%eax
1231                 mov     offclassinit(%eax),%ecx     /* get initialized flag           */
1232                 test    %ecx,%ecx
1233                 jnz             L_builtin_new_noinit
1234
1235                 mov 4(%esp),%eax /* class pointer, is kept during the asm_prepare... calls */
1236
1237                 /* 2 *4 bytes, the return adress is used directy */
1238                 pushl $0  /* the structure is placed directly below the java stackframe*/
1239                 pushl $0  /* builtin (invisible) method */
1240                 call  asm_prepare_native_stackinfo /*puts 2*4 additional bytes on stack*/
1241 #if 0
1242                 sub             $16,%esp                                 /* build stack frame (4 * 4 bytes) */
1243
1244                 mov             20(%esp),%eax
1245                 mov             %eax,(%esp)
1246
1247                 call    builtin_asm_get_stackframeinfo
1248                 movl    $0,12(%esp)
1249                 mov     %eax,8(%esp)
1250                 mov     (%eax),%ebx
1251                 mov     %ebx,4(%esp)
1252                 mov     %esp,%ecx
1253                 add     $4,%ecx
1254                 mov     %ecx,(%eax)
1255 #endif
1256                 push    %eax
1257                 call    builtin_new
1258                 add     $4,%esp
1259
1260                 call    asm_remove_native_stackinfo /*first element on stack is return adress again*/
1261 #if 0           
1262                 call    
1263                 mov     4(%esp),%ebx
1264                 mov     8(%esp),%ecx
1265                 mov     %ebx,(%ecx)
1266
1267                 add             $16,%esp
1268 #endif
1269                 jmp L_builtin_new_patch
1270
1271
1272 L_builtin_new_noinit:
1273                 mov 4(%esp),%eax
1274                 push %eax
1275                 call builtin_new
1276                 add $4,%esp
1277                 /*jmp L_builtin_new_patch*/
1278
1279 L_builtin_new_patch:
1280 /*add patching code here */
1281                 lea builtin_new,%edx
1282                 mov (%esp),%ecx
1283                 mov %edx,-6(%ecx)       /*patch calling instruction, t directly call builtin_new the next time*/
1284                 ret
1285
1286
1287
1288
1289
1290
1291 asm_getclassvalues_atomic:
1292 _crit_restart2:
1293         mov     4(%esp),%ecx        /* super */
1294         mov     8(%esp),%edx        /* sub */
1295 _crit_begin2:
1296         mov     offbaseval(%ecx),%eax
1297         mov     offdiffval(%ecx),%ecx
1298         mov     offbaseval(%edx),%edx
1299 _crit_end2:
1300         push    %ebx
1301         mov     16(%esp),%ebx      /* out */
1302         mov     %eax,offcast_super_baseval(%ebx)
1303         mov     %ecx,offcast_super_diffval(%ebx)
1304         mov     %edx,offcast_sub_baseval(%ebx)
1305         pop     %ebx
1306         ret
1307
1308         .data
1309
1310 asm_criticalsections:
1311 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1312         .long   _crit_begin1
1313         .long   _crit_end1
1314         .long   _crit_restart1
1315         .long   _crit_begin2
1316         .long   _crit_end2
1317         .long   _crit_restart2
1318 #endif
1319         .long 0
1320
1321
1322
1323 /************************ function asm_prepare_native_stackinfo ****************************
1324 *                                                                                          *
1325 *    creates a stackfame for the begin of a native function (either builtin or not )       *
1326 *    expected stack at begin of function                                                   *
1327 *                                        ....                                              *
1328 *                   address of the jit call which invokes the native                       *
1329 *                   begin address of stack frame of the java method                        *
1330 *                   method pointer or 0 (for built ins)                                    *
1331 *                   return address                                                         *
1332 *                                                                                          *
1333 *    at end of function:                                                                   *
1334 *                                          ...                                             *
1335 *                   address of the jit call which invokes the native                       *
1336 *                   begin address of stack frame of the java method                        *
1337 *                   method pointer or 0 (for built ins)                                    *
1338 *                   address of thread specific top of native list                          *
1339 *                   old value of thread specific head                                      *
1340 *                   return address                                                         *
1341 *                                                                                          *
1342 *                                        ....                                              *
1343 * This thing is less efficient than the original #define (callerside)                      *
1344 * destroyes REG_ITMP2, keeps REG_ITMP1                                                     *
1345 ********************************************************************************************/
1346
1347
1348 asm_prepare_native_stackinfo:
1349         sub $8,%esp
1350         mov 8(%esp),%ecx
1351         mov %ecx,(%esp)
1352         push %eax
1353         lea     builtin_asm_get_stackframeinfo,%ecx
1354         call    *%ecx
1355         mov %eax, 12(%esp)
1356         mov (%eax),%ecx
1357         mov %ecx,8(%esp)
1358         mov %esp,%ecx
1359         add $8,%ecx
1360         mov %ecx,(%eax)
1361         pop %eax
1362         ret
1363 #if 0
1364 #define PREPARE_NATIVE_STACKINFO \
1365     i386_push_reg(cd, REG_ITMP1);       /*save itmp1, needed by some stubs */ \
1366     i386_alu_imm_reg(cd, I386_SUB, 2*4, REG_SP); /* build stack frame (2 * 4 bytes), together with previous =3*4 */ \
1367     i386_mov_imm_reg(cd, (s4) codegen_stubcalled,REG_ITMP1); \
1368     i386_call_reg(cd, REG_ITMP1);                /*call    codegen_stubcalled*/ \
1369     i386_mov_imm_reg(cd, (s4) builtin_asm_get_stackframeinfo,REG_ITMP1); \
1370     i386_call_reg(cd, REG_ITMP1);                /*call    builtin_asm_get_stackframeinfo*/ \
1371     i386_mov_reg_membase(cd, REG_RESULT,REG_SP,1*4); /* save thread pointer  to native call stack*/ \
1372     i386_mov_membase_reg(cd, REG_RESULT,0,REG_ITMP2); /* get old value of thread specific native call stack */ \
1373     i386_mov_reg_membase(cd, REG_ITMP2,REG_SP,0*4);     /* store value on stack */ \
1374     i386_mov_reg_membase(cd, REG_SP,REG_RESULT,0); /* store pointer to new stack frame information */ \
1375     i386_mov_membase_reg(cd, REG_SP,2*4,REG_ITMP1); /* restore ITMP1, need for some stubs*/ \
1376     i386_mov_imm_membase(cd, 0,REG_SP, 2*4);    /* builtin */
1377 #endif
1378
1379
1380 /************************ function asm_remove _native_stackinfo *******************************************
1381 *                                                                                                         *
1382 *    creates a stackfame for the begin of a native function (either builtin or not)                       *
1383 *    expected stack at begin of function                                                                  *
1384 *                   address of the jit call which invokes the native                                      *
1385 *                   begin address of stack frame of the java method                                       *
1386 *                   method pointer or 0 (for built ins)                                                   *
1387 *                   address thread specific top of native list                                            *
1388 *                   old value of thread specific head                                                     *
1389 *                   return address                                                                        *
1390 *                                                                                                         *
1391 *    at end of function:                                                                                  *
1392 *                             ....                                                                        *
1393 *                   return adresss of the jit call which invokes the native                               *
1394 *                   return address                                                                        *
1395 *                                                                                                         *
1396 *                   REG_ITMP2_XPC = address of the jit call which invokes the native                      *
1397 *                                                                                                         *
1398 *                                                                                                         *
1399 * This thing is less efficient than the original #define (callerside), uses ITMP3,uses ITMP3,keeps ITMP1  *
1400 ***********************************************************************************************************/
1401
1402 asm_remove_native_stackinfo:
1403         mov 4(%esp),%ecx
1404         mov 8(%esp),%edx
1405         mov %ecx,(%edx)
1406         pop %edx
1407         add $16,%esp
1408         push %edx
1409         ret
1410
1411 #if 0
1412 #define REMOVE_NATIVE_STACKINFO \
1413     i386_mov_membase_reg(cd, REG_SP,0,REG_ITMP2); \
1414     i386_mov_membase_reg(cd, REG_SP,4,REG_ITMP3); \
1415     i386_mov_reg_membase(cd, REG_ITMP2,REG_ITMP3,0); \
1416     i386_alu_imm_reg(cd, I386_ADD,3*4,REG_SP);
1417 #endif
1418
1419
1420
1421
1422 /*
1423  * These are local overrides for various environment variables in Emacs.
1424  * Please do not remove this and leave it at the end of the file, where
1425  * Emacs will automagically detect them.
1426  * ---------------------------------------------------------------------
1427  * Local variables:
1428  * mode: asm
1429  * indent-tabs-mode: t
1430  * c-basic-offset: 4
1431  * tab-width: 4
1432  * End:
1433  */