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