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