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