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