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