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