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