Made code patch thread safe in check_clinit.
[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 1460 2004-11-05 16:23:29Z 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         add     $32,%esp
194         pop     %edi                      /* restore registers                    */
195         pop     %esi
196         pop     %ebx
197         leave
198         ret
199
200 calljava_xhandler:
201         push    %eax                      /* pass exception pointer               */
202         call    builtin_throw_exception
203         add     $4,%esp
204
205         add     $32,%esp
206         pop     %edi                      /* restore registers                    */
207         pop     %esi
208         pop     %ebx
209         leave
210         ret
211
212
213 /********************* function asm_calljavafunction ***************************
214 *                                                                              *
215 *   This function calls a Java-method (which possibly needs compilation)       *
216 *   with up to 4 address parameters.                                           *
217 *                                                                              *
218 *   This functions calls the JIT-compiler which eventually translates the      *
219 *   method into machine code.                                                  *
220 *                                                                              *
221 *   C-prototype:                                                               *
222 *    javaobject_header *asm_calljavafunction2(methodinfo *m,                   *
223 *         u4 count, u4 size, void *callblock);                                 *
224 *                                                                              *
225 *******************************************************************************/
226
227 call_name2:
228         .ascii  "calljavafunction2\0\0"
229
230         .align  8
231         .long   0                         /* catch type all                       */
232         .long   calljava_xhandler2        /* handler pc                           */
233         .long   calljava_xhandler2        /* end pc                               */
234         .long   asm_calljavafunction2     /* start pc                             */
235         .long   1                         /* extable size                         */
236         .long   0                         /* line number table start              */
237         .long   0                         /* line number table size               */
238         .long   0                         /* fltsave                              */
239         .long   0                         /* intsave                              */
240         .long   0                         /* isleaf                               */
241         .long   0                         /* IsSync                               */
242         .long   32                        /* frame size                           */
243         .long   0                         /* method pointer (pointer to name)     */
244
245 asm_calljavafunction2:
246 asm_calljavafunction2double:
247 asm_calljavafunction2long:
248         push    %ebp
249         mov     %esp,%ebp                 /* save stackptr                        */
250
251         push    %ebx                      /* save registers                       */
252         push    %esi
253         push    %edi
254
255         mov     20(%ebp),%eax             /* pointer to arg block                 */
256         mov     12(%ebp),%ecx             /* arg count                            */
257         test    %ecx,%ecx                 /* maybe we have no args                */
258         jle     calljava_copydone
259
260         mov     %ecx,%edx                 /* calculate stack size                 */
261         shl     $3,%edx
262         mov     %edx,%esi                 /* save in callee saved register        */
263         sub     %esi,%esp                 /* stack frame for arguments            */
264         mov     %esp,%edi
265
266 calljava_copyloop:
267     mov     offjniitem(%eax),%edx
268     mov     %edx,0(%edi)
269     mov     offjniitem+4(%eax),%edx
270     mov     %edx,4(%edi)
271
272         sub     $1,%ecx                   /* are there any args left?             */
273         test    %ecx,%ecx
274         jle     calljava_copydone
275
276         add     $sizejniblock,%eax        /* goto next argument block             */
277     add     $8,%edi                   /* increase sp to next argument         */
278         jmp     calljava_copyloop
279
280 calljava_copydone:
281         mov     8(%ebp),%eax              /* move function pointer to %eax        */
282
283         lea     asm_call_jit_compiler,%edx 
284         call    *%edx                     /* call JIT compiler                    */
285         
286 calljava_return2:
287         add     %esi,%esp                 /* remove arg stack frame               */
288         pop     %edi                      /* restore registers                    */
289         pop     %esi
290         pop     %ebx
291         leave
292         ret
293
294 calljava_xhandler2:
295         push    %eax                      /* pass exception pointer               */
296         call    builtin_throw_exception
297         add     $4,%esp
298     
299         add     %esi,%esp                 /* remove arg stack frame               */
300         pop     %edi                      /* restore registers                    */
301         pop     %esi
302         pop     %ebx
303         leave
304         ret
305
306
307 /****************** function asm_call_jit_compiler *****************************
308 *                                                                              *
309 *   invokes the compiler for untranslated JavaVM methods.                      *
310 *                                                                              *
311 *   Register R0 contains a pointer to the method info structure (prepared      *
312 *   by createcompilerstub). Using the return address in R26 and the            *
313 *   offset in the LDA instruction or using the value in methodptr R28 the      *
314 *   patching address for storing the method address can be computed:           *
315 *                                                                              *
316 *   method address was either loaded using                                     *
317 *                                                                              *
318 *   i386_mov_imm_reg(a, REG_ITMP2)                ; invokestatic/special       *
319 *   i386_call_reg(REG_ITMP2)                                                   *
320 *                                                                              *
321 *   or                                                                         *
322 *                                                                              *
323 *   i386_mov_membase_reg(REG_SP, 0, REG_ITMP1)    ; invokevirtual/interface    *
324 *   i386_mov_membase_reg(REG_ITMP1, OFFSET(, vftbl), REG_ITMP2)                *
325 *   i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, table[0]) + \                *
326 *       sizeof(methodptr) * m->vftblindex, REG_ITMP1)                          *
327 *   i386_call_reg(REG_ITMP1)                                                   *
328 *                                                                              *
329 *   in the static case the method pointer can be computed using the            *
330 *   return address and the lda function following the jmp instruction          *
331 *                                                                              *
332 *******************************************************************************/
333
334 asm_call_jit_compiler:
335         push    %ebx                /* save register                              */
336     push    %ebp
337                         
338         mov     8(%esp),%ebp        /* get return address (2 push)                */
339         mov     -1(%ebp),%bl        /* get function code                          */
340         cmp     $0xd1,%bl           /* called with `call *REG_ITMP2' (%ecx)?      */
341         jne             L_not_static_special
342
343         sub     $6,%ebp             /* calculate address of immediate             */
344         jmp             L_call_jit_compile
345                 
346 L_not_static_special:
347         cmp     $0xd0,%bl           /* called with `call *REG_ITMP1' (%eax)       */
348         jne             L_not_virtual_interface
349         
350         sub     $6,%ebp             /* calculate address of offset                */
351         mov     (%ebp),%ebp         /* get offset                                 */
352         add     itmp2,%ebp          /* add base address to get method address     */
353         jmp             L_call_jit_compile
354
355 L_not_virtual_interface:        /* a call from asm_calljavafunction           */
356         xor     %ebp,%ebp
357                 
358 L_call_jit_compile:
359         push    %ebp                /* save address for method pointer            */
360
361         push    %eax                /* push methodpointer on stack                */
362         call    jit_compile
363         add     $4,%esp
364
365         pop     %ebp                /* restore address for method pointer         */
366
367         test    %eax,%eax           /* check for exception                        */
368         je      L_exception
369
370         test    %ebp,%ebp           /* is address == 0 (asm_calljavafunction)     */
371         je              L_call_method
372         
373         mov     %eax,(%ebp)         /* and now save the new pointer               */
374
375 L_call_method:
376         pop     %ebp                /* restore registers                          */
377         pop     %ebx
378                 
379         jmp             *%eax               /* ...and now call the new method             */
380
381 L_exception:
382         pop     %ebp                /* restore registers                          */
383         pop     %ebx
384
385 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
386         call    builtin_asm_get_exceptionptrptr
387         mov     %eax,%ecx
388         mov     (%ecx),%eax         /* get the exception pointer                  */
389         movl    $0,(%ecx)           /* clear the exception pointer                */
390 #else
391         lea     _exceptionptr,%ecx
392         mov     (%ecx),%eax         /* get the exception pointer                  */
393         movl    $0,(%ecx)           /* clear the exception pointer                */
394 #endif
395
396         pop     %ecx                /* delete return address                      */
397         sub     $2,%ecx             /* faulting address is return adress - 2      */
398
399 L_refillinStacktrace:
400         push %ecx               /* store fault adress */
401         push %eax               /* temporarily save exception pointer*/
402         call builtin_asm_get_stackframeinfo
403         push %eax       /* save location of thread specific stack info head pointer */
404         mov (%eax),%ecx /* save old value of pointer*/
405         push %ecx
406         mov %esp,(%eax) /*store pointer to this structure*/
407         mov 8(%esp),%eax  /* get the exception pointer again*/
408         movl $0,8(%esp) /*mark this block as native*/
409         push $0 /*used for the jni_callblock structure*/
410         push %eax /*save eax for later */
411         /* get fillInStackTrace method*/
412         push utf_fillInStackTrace_desc
413         push utf_fillInStackTrace_name
414         mov offobjvftbl(%eax),%ecx
415         mov offclass(%ecx),%eax
416         push %eax
417         call class_resolvemethod
418         add $12,%esp
419         push $0
420         push $4 /*TYPE_ADR*/
421         push %esp
422         push $sizejniblock
423         push $1
424         push %eax
425         call asm_calljavafunction2
426         add $24,%esp
427
428         /*remove native stack info */
429         mov 8(%esp),%ecx
430         mov 12(%esp),%eax
431         mov %ecx,(%eax)
432         mov (%esp),%eax
433         add $20,%esp
434         pop %ecx
435
436         
437         jmp     asm_handle_exception
438
439
440 /********************* function asm_handle_exception ***************************
441 *                                                                              *
442 *   This function handles an exception. It does not use the usual calling      *
443 *   conventions. The exception pointer is passed in REG_ITMP1 and the          *
444 *   pc from the exception raising position is passed in REG_ITMP2. It searches *
445 *   the local exception table for a handler. If no one is found, it unwinds    *
446 *   stacks and continues searching the callers.                                *
447 *                                                                              *
448 *   void asm_handle_exception (exceptionptr, exceptionpc);                     *
449 *                                                                              *
450 *******************************************************************************/
451
452 asm_handle_nat_exception:
453                 add     $4,%esp                                         /* clear return address of native stub */
454                 
455 asm_handle_exception:
456 #if 0
457                 push %ebp
458                 mov %esp,%ebp
459                 push %eax       /* exception pointer */
460                 push %ecx       /* excepiton pc */
461
462                 call asm_get_stackTrace
463
464                 pop %ecx
465                 pop %eax
466                 pop %ebp
467 #endif
468 asm_handle_exception_loop:
469                 push    %ebp
470                 mov     %esp,%ebp
471         
472                 push    %eax                                            /* save exception pointer         */
473                 push    %ecx                        /* save exception pc              */
474
475                 call    codegen_findmethod          /* get the data segment ptr       */
476                 mov     %eax,%edx
477                         
478                 mov     -4(%ebp),%eax
479                 mov     -8(%ebp),%ecx               /* could be changed in findmethod */
480
481                 push    %edx                                            /* save data segment pointer      */
482                 push    %ebx
483                 push    %esi
484                 push    %edi
485                 
486 ex_stack_loop:
487                 sub     $20,%esp
488                 mov     %eax,(%esp)                                     /* exception pointer              */
489                 mov     MethodPointer(%edx),%eax        /* method pointer                 */
490                 mov     %eax,4(%esp)
491                 mov     %ecx,8(%esp)                            /* exception pc                   */
492                 movl    $0,12(%esp)                 /* line number                    */
493                 movl    $1,16(%esp)                                     /* set no unwind flag             */
494                 call    builtin_trace_exception
495                 add     $20,%esp
496                 mov     -12(%ebp),%esi                          /* %esi = data segment pointer    */
497                 mov     ExTableSize(%esi),%ecx          /* %ecx = exception table size    */
498                 test    %ecx,%ecx                                       /* if empty table skip            */
499                 je      empty_table
500
501                 lea             ExTableStart(%esi),%edi         /* %edi = start of exception table*/
502                 mov     -4(%ebp),%eax               /* get xptr                       */
503                 
504 ex_table_loop:
505                 mov     -8(%ebp),%edx                           /* get xpc                        */
506
507                 mov     ExStartPC(%edi),%ebx            /* %ebx = exception start pc      */
508                 cmp     %edx,%ebx                                       /* %ebx = (startpc <= xpc)        */
509                 jg      ex_table_cont                           /* if (false) continue            */
510                 mov     ExEndPC(%edi),%ebx                      /* %ebx = exception end pc        */
511                 cmp     %ebx,%edx                                       /* %ebx = (xpc < endpc)           */
512                 jge     ex_table_cont                           /* if (false) continue            */
513                 mov     ExCatchType(%edi),%ebx          /* arg1 = exception catch type    */
514                 test    %ebx,%ebx                                       /* NULL catches everything        */
515                 je      ex_handle_it
516
517         cmpl    $0,offclassloaded(%ebx)     /* check if class is loaded           */
518         jne     L_class_loaded
519
520         sub     $3*4,%esp
521         mov     %eax,1*4(%esp)              /* save not callee saved regs         */
522         mov     %ecx,2*4(%esp)
523
524         mov     %ebx,0*4(%esp)              /* exception class is argument        */
525         call    class_load
526
527         mov     0*4(%esp),%ebx
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     0*4(%esp),%ebx
544         mov     1*4(%esp),%eax
545         mov     2*4(%esp),%ecx
546         add     $3*4,%esp
547
548 L_class_linked:
549 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
550         push    %ebx
551
552 _crit_restart1:
553         mov     0(%esp),%ebx
554 #endif
555                 
556 _crit_begin1:
557         mov     offobjvftbl(%eax),%esi          /* %esi = vftblptr(xptr)              */
558         mov     offclassvftbl(%ebx),%ebx    /* %ebx = vftblptr(catchtype) class (not obj) */
559         mov     offbaseval(%esi),%esi           /* %esi = baseval(xptr)               */
560         mov     offbaseval(%ebx),%edx           /* %edx = baseval(catchtype)          */
561         mov     offdiffval(%ebx),%ebx           /* %ebx = diffval(catchtype)          */
562 _crit_end1:
563         sub     %edx,%esi                                       /* %esi = baseval(xptr) - baseval(catchtype) */
564
565 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
566         add     $4,%esp
567 #endif
568         
569         cmp     %ebx,%esi                                       /* xptr is instanceof catchtype       */
570         ja      ex_table_cont
571                 
572 ex_handle_it:
573                 mov     ExHandlerPC(%edi),%edx
574                 
575                 pop     %edi                        /* restore registers              */
576                 pop     %esi
577                 pop     %ebx
578         add     $8,%esp                     /* suck %ecx, %edx                */
579         pop     %eax                        /* restore xptr                   */
580
581                 leave
582                 jmp             *%edx                       /* jump to exception handler      */
583
584 ex_table_cont:
585                 lea     ExEntrySize(%edi),%edi
586                 dec     %ecx
587                 test    %ecx,%ecx
588                 jg      ex_table_loop
589                 
590 empty_table:
591         pop     %edi
592         pop     %esi
593         pop     %ebx
594         pop     %edx                        /* restore data segment pointer   */
595         pop     %ecx
596         pop     %eax
597         pop     %ebp
598
599         push    %eax                        /* save exception pointer         */
600         
601 ex_already_cleared:
602                 mov     IsSync(%edx),%eax                       /* %eax = SyncOffset              */
603                 test    %eax,%eax                                       /* if zero no monitorexit         */
604                 je      no_monitor_exit
605
606         add     %esp,%eax
607         mov     -4(%eax),%eax               /* we have the xptr on the stack  */
608         push    %edx                        /* save regs                      */
609         push    %eax
610                 call    builtin_monitorexit
611                 add     $4,%esp
612         pop     %edx                        /* restore regs                   */
613         
614 no_monitor_exit:
615         mov     %esp,%eax
616         add     FrameSize(%edx),%eax        /* %eax = frame size              */
617         add     $4,%eax                     /* we have the xptr on the stack  */
618         
619                 mov     IntSave(%edx),%ecx          /* %ecx = saved int register count*/
620                 test    %ecx,%ecx
621                 je      noint
622                 cmp     $1,%ecx
623                 je      int1
624                 cmp     $2,%ecx
625                 je      int2
626                 cmp     $3,%ecx
627                 je      int3
628
629 int4:   
630                 mov     -32(%eax),%ebx
631
632 int3:   
633                 mov     -24(%eax),%ebp
634
635 int2:   
636                 mov     -16(%eax),%esi
637
638 int1:   
639                 mov     -8(%eax),%edi
640
641                 shl     $3,%ecx                                         /* multiply by 8 bytes             */
642                 sub     %ecx,%eax
643                 
644 noint:
645                 mov     FltSave(%edx),%ecx                      /* %ecx = saved flt register count */
646                 test    %ecx,%ecx
647                 je      noflt
648                 cmp     $1,%ecx
649                 je      flt1
650                 cmp     $2,%ecx
651                 je      flt2
652                 cmp     $3,%ecx
653                 je      flt3
654                 
655 flt4:   
656                 fldl    -32(%eax)
657                 fstp    %st(1)
658
659 flt3:   
660                 fldl    -24(%eax)
661                 fstp    %st(2)
662                 
663 flt2:   
664                 fldl    -16(%eax)
665                 fstp    %st(3)
666                 
667 flt1:   
668                 fldl    -8(%eax)
669                 fstp    %st(4)
670                 
671 noflt:
672         pop     %eax                        /* restore exception pointer      */
673         
674         mov     FrameSize(%edx),%ecx        /* %ecx = frame size              */
675         add     %ecx,%esp                   /* unwind stack                   */
676         
677                 pop     %ecx                        /* the new xpc is return address  */
678                 sub     $2,%ecx
679                 
680                 jmp             asm_handle_exception_loop
681                 
682
683 /********************* function asm_check_clinit *******************************
684 *                                                                              *
685 *   Does null check and calls monitorenter or throws an exception              *
686 *                                                                              *
687 *******************************************************************************/
688
689 asm_check_clinit:
690         mov     offclassinit(%eax),%ecx     /* get initialized flag               */
691         test    %ecx,%ecx
692         jnz     L_is_initialized
693
694         sub     $16,%esp                    /* build stack frame (4 * 4 bytes)    */
695         mov     %eax,(%esp)                 /* put classpointer on stack          */
696         call    builtin_asm_get_stackframeinfo
697
698         movl    $0,12(%esp)
699     mov     %eax,8(%esp)
700         mov     (%eax),%ecx
701         mov     %ecx,4(%esp)
702         mov     %esp,%ecx
703         add     $4,%ecx
704         mov     %ecx,(%eax)
705
706         call    class_init                  /* call class_init function           */
707
708         mov     4(%esp),%edx
709         mov     8(%esp),%ecx
710         mov     %edx,(%ecx)
711
712         add     $16,%esp
713
714         test    %eax,%eax                   /* we had an exception                */
715         je      L_initializererror
716
717 L_is_initialized:
718         mov     (%esp),%eax                 /* get return address                 */
719         sub     $12,%eax                    /* asm_check_clinit call code size    */
720         movw    $0x0aeb,(%eax)              /* 0xeb = jmp rel8, 0x0a = 10 byte    */
721                                             /* 8-bit offset                       */
722         ret
723
724 L_initializererror:
725 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
726         call    builtin_asm_get_exceptionptrptr
727         mov     %eax,%ecx
728         mov     (%ecx),%eax                 /* get the exception pointer          */
729         movl    $0,(%ecx)                   /* clear the exception pointer        */
730 #else
731         lea     _exceptionptr,%ecx
732         mov     (%ecx),%eax                 /* get the exception pointer          */
733         movl    $0,(%ecx)                   /* clear the exception pointer        */
734 #endif
735
736         pop     %ecx                        /* delete return address              */
737         sub     $2,%ecx                     /* faulting address is return adress - 2 */
738
739         jmp     asm_handle_exception
740
741
742 /********************* function asm_builtin_monitorenter ***********************
743 *                                                                              *
744 *   Does null check and calls monitorenter or throws an exception              *
745 *                                                                              *
746 *******************************************************************************/
747
748 asm_builtin_monitorenter:
749         cmpl    $0,4(%esp)
750         je      nb_monitorenter             /* if (null) throw exception          */
751         jmp             builtin_monitorenter        /* else call builtin_monitorenter     */
752
753 nb_monitorenter:
754         mov string_java_lang_NullPointerException,%eax
755         pop %ecx
756         sub $2,%ecx
757         jmp asm_throw_and_handle_exception
758
759 #if 0
760         push    string_java_lang_NullPointerException
761         call    new_exception
762         add     $(1*4),%esp
763         
764         pop     %ecx                        /* delete return address              */
765         sub     $2,%ecx                     /* faulting address is return adress - 2 */
766         jmp     asm_handle_exception
767 #endif          
768
769 /********************* function asm_builtin_monitorexit ************************
770 *                                                                              *
771 *   Does null check and calls monitorexit or throws an exception               *
772 *                                                                              *
773 *******************************************************************************/
774
775 asm_builtin_monitorexit:
776         mov     4(%esp),%eax
777     test    %eax,%eax
778         je      nb_monitorexit              /* if (null) throw exception          */
779     push    %ecx                        /* save registers which could be used */
780     push    %edx
781     push    %eax
782         call    builtin_monitorexit         /* else call builtin_monitorenter     */
783     add     $4,%esp
784     pop     %edx                        /* restore registers which could be used */
785     pop     %ecx
786     ret
787
788 nb_monitorexit:
789         mov string_java_lang_NullPointerException,%eax
790         pop %ecx
791         sub $2,%ecx
792         jmp asm_throw_and_handle_exception
793
794 #if 0
795         push    string_java_lang_NullPointerException
796         call    new_exception
797         add     $(1*4),%esp
798         
799         pop     %ecx                    /* delete return address              */
800         sub     $2,%ecx                 /* faulting address is return adress - 2 */
801         jmp     asm_handle_exception
802 #endif
803
804 /************************ function asm_builtin_ldiv ****************************
805 *                                                                              *
806 *   Does null check and calls ldiv or throws an exception                      *
807 *                                                                              *
808 *******************************************************************************/
809
810 asm_builtin_ldiv:
811         mov     12(%esp),%eax
812         or      16(%esp),%eax
813         test    %eax,%eax                   /* if (null) throw exception          */
814         je      nb_ldiv
815
816         jmp     builtin_ldiv
817
818 nb_ldiv:
819         pop %ecx
820         sub $2,%ecx
821         jmp asm_throw_and_handle_hardware_arithmetic_exception
822 #if 0
823         push    string_java_lang_ArithmeticException_message
824         push    string_java_lang_ArithmeticException
825         call    new_exception_message
826         add     $(2*4),%esp
827         
828         pop     %ecx                        /* delete return address              */
829         sub     $2,%ecx                     /* faulting address is return adress - 2 */
830         jmp     asm_handle_exception
831 #endif                          
832
833 /************************ function asm_builtin_lrem ****************************
834 *                                                                              *
835 *   Does null check and calls lrem or throws an exception                      *
836 *                                                                              *
837 *******************************************************************************/
838
839 asm_builtin_lrem:
840         mov     12(%esp),%eax
841         or      16(%esp),%eax
842         test    %eax,%eax                   /* if (null) throw exception          */
843         je      nb_lrem
844
845         jmp     builtin_lrem
846
847 nb_lrem:
848         pop %ecx
849         sub $2,%ecx
850         jmp asm_throw_and_handle_hardware_arithmetic_exception
851 #if 0
852         push    string_java_lang_ArithmeticException_message
853         push    string_java_lang_ArithmeticException
854         call    new_exception_message
855         add     $(2*4),%esp
856
857         pop     %ecx                        /* delete return address              */
858         sub     $2,%ecx                     /* faulting address is return adress - 2 */
859         jmp     asm_handle_exception
860 #endif          
861
862 /************************ function asm_builtin_x2x *****************************
863 *                                                                              *
864 *   Wrapper functions for corner cases                                         *
865 *                                                                              *
866 *******************************************************************************/
867
868 asm_builtin_f2i:
869         sub     $4,%esp
870         fsts    (%esp)
871         call    builtin_f2i
872         add     $4,%esp
873         ret
874
875 asm_builtin_d2i:
876         sub     $8,%esp
877         fstl    (%esp)
878         call    builtin_d2i
879         add     $8,%esp
880         ret
881
882 asm_builtin_f2l:
883         sub     $4,%esp
884         fsts    (%esp)
885         call    builtin_f2l
886         add     $4,%esp
887         ret
888
889 asm_builtin_d2l:
890         sub     $8,%esp
891         fstl    (%esp)
892         call    builtin_d2l
893         add     $8,%esp
894         ret
895
896
897 /******************* function asm_builtin_checkarraycast ***********************
898 *                                                                              *
899 *   Does the cast check and eventually throws an exception                     *
900 *                                                                              *
901 *******************************************************************************/
902
903 asm_builtin_checkarraycast:
904         sub             $8,%esp                     /* build stack frame (2 * 4 bytes)    */
905
906         mov             12(%esp),%eax               /* 8 (frame) + 4 (return)             */
907         mov             %eax,(%esp)                 /* save object pointer                */
908
909         mov             20(%esp),%eax
910         mov             %eax,4(%esp)
911
912         call    builtin_checkarraycast      /* builtin_checkarraycast             */
913
914         test    %eax,%eax                   /* if (false) throw exception         */
915         je              nb_carray_throw
916
917         mov             12(%esp),%eax               /* return object pointer              */
918         add             $8,%esp
919         ret
920
921 nb_carray_throw:
922         add $8,%esp
923         mov string_java_lang_ClassCastException,%eax
924         pop %ecx
925         sub $2,%ecx
926         jmp asm_throw_and_handle_exception
927 #if 0
928         push    string_java_lang_ClassCastException
929         call    new_exception
930         add     $(1*4),%esp
931         
932         add             $8,%esp
933         
934         pop             %ecx                        /* delete return address              */
935         sub             $2,%ecx                     /* faulting address is return adress - 2 */
936         jmp             asm_handle_exception
937 #endif
938                 
939 /******************* function asm_builtin_newarray *****************************
940 *                                                                              *
941 *   Does the cast check and eventually throws an exception                     *
942 *                                                                              *
943 *******************************************************************************/
944
945 asm_builtin_newarray:
946         sub             $8,%esp                     /* build stack frame (2 * 4 bytes)    */
947
948         mov             12(%esp),%eax
949         mov             %eax,(%esp)
950
951         mov             20(%esp),%eax
952         mov             %eax,4(%esp)
953
954         call    builtin_newarray
955
956         add             $8,%esp
957         ret
958
959                 
960 /******************* function asm_builtin_aastore ******************************
961 *                                                                              *
962 *   Does the cast check and eventually throws an exception                     *
963 *                                                                              *
964 *******************************************************************************/
965
966 asm_builtin_aastore:
967         sub     $12,%esp                    /* build stack frame (3 * 4 bytes)    */
968
969         mov     16(%esp),%eax               /* 12 (frame) + 4 (return)            */
970         test    %eax,%eax                   /* if null pointer throw exception    */
971         je      nb_aastore_null
972
973         mov     offarraysize(%eax),%edx /* load size                          */
974         mov     24(%esp),%ecx               /* index                              */
975         cmp     %edx,%ecx                   /* do bound check                     */
976         jae     nb_aastore_bound            /* if out of bounds throw exception   */
977
978         shl     $2,%ecx                     /* index * 4                          */
979         add     %eax,%ecx                   /* add index * 4 to arrayref          */
980            
981         mov     %ecx,8(%esp)                /* save store position                */
982            
983         mov     16(%esp),%eax               /* 12 (frame) + 4 (return)            */
984         mov     %eax,(%esp)
985            
986         mov     32(%esp),%eax               /* object is second argument          */
987         mov     %eax,4(%esp)
988         
989         call    builtin_canstore            /* builtin_canstore(arrayref,object)  */
990
991         test    %eax,%eax                   /* if (false) throw exception         */
992         je      nb_aastore_store
993
994         mov     32(%esp),%eax
995         mov     8(%esp),%ecx
996         mov     %eax,offobjarrdata(%ecx)    /* store objectptr in array           */
997         
998         add     $12,%esp
999         ret
1000
1001 nb_aastore_null:
1002         add $12,%esp
1003         mov string_java_lang_NullPointerException,%eax
1004         pop %ecx
1005         sub $2,%ecx
1006         jmp asm_throw_and_handle_exception
1007
1008 #if 0
1009         push    string_java_lang_NullPointerException
1010         call    new_exception
1011         add     $(1*4),%esp
1012         
1013         add     $12,%esp
1014         pop     %ecx                        /* delete return address              */
1015         sub     $2,%ecx                     /* faulting address is return adress - 2 */
1016         jmp             asm_handle_exception
1017 #endif
1018 nb_aastore_bound:
1019         push    %ecx                        /* itmp2 contains array index         */
1020         call    new_arrayindexoutofboundsexception
1021         add     $(1*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         mov  cacao_initializing,%eax
1183         test %eax,%eax
1184         jz   Java_java_lang_VMSecurityManager_cont
1185
1186         mov $0,%eax
1187         ret
1188 Java_java_lang_VMSecurityManager_cont:
1189         lea  builtin_asm_getclassloader,%eax 
1190         push %eax       /*store collector function pointer*/
1191         jmp getClassContext_begin
1192 Java_java_lang_VMSecurityManager_getClassContext:
1193         lea  builtin_asm_createclasscontextarray,%eax 
1194         push %eax /*store collector function pointer*/
1195 getClassContext_begin:  /*start the real work*/
1196
1197         mov %esp,%eax
1198         sub $4,%eax
1199         sub $68,%esp /*64 memory location without overwriting return adress and collector function adress*/
1200         mov %esp,%ebx   /*end of allocated memory block for classpointers is the adress of the working data block +4 */
1201         push $0 /*%esp+32 was native*/
1202         push %eax /*%esp+24 blkbegin*/
1203         push %eax /*%esp+20 currentpos*/
1204         push %ebx /*%esp+16 blkend*/
1205
1206         call builtin_asm_get_threadrootmethod
1207         push %eax /*%esp+12*/
1208         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*/
1209         movl %esp,%edx
1210         addl $116, %edx
1211         push %edx /*esp+8*/ /*position of return address of native stub*/
1212         call builtin_asm_get_stackframeinfo
1213 /*      movl (%eax),%eax*/ /*TEST*/
1214         push 0(%eax) /*esp+4*/ /*address of frame info block*/
1215         movl 124(%esp),%edx
1216
1217 /*DEBUG*/
1218 /*      mov %esp,%eax
1219         addl $116,%eax
1220         push %eax
1221         call i386_native_stub_debug
1222         pop %eax*/
1223
1224         push %edx /*esp+0*/ /*return adress out of native stub*/
1225         call codegen_findmethod /*find calling java method, this one is still to be skipped (==SecurityManager.getClassContext (or .currentClassLoader)*/
1226
1227 /*DEBUGGING*/
1228 /*      push %eax
1229         movl MethodPointer(%eax),%eax
1230         push %eax
1231         call temporaryGetClassContextHelper
1232         pop %eax
1233         call traverseStackInfo
1234         pop %eax
1235 */
1236
1237         movl 20(%esp),%edx
1238         movl MethodPointer(%eax),%ebx
1239         movl offclassmethodinfo(%ebx),%ecx
1240         movl %ecx,(%edx)
1241         subl $4,%edx
1242         movl %edx,20(%esp)
1243
1244         mov 8(%esp),%ebx /*pos of return adress */
1245         add FrameSize(%eax),%ebx
1246         add $4,%ebx     /*adress of new return adress (out of Securitymanager.*/
1247         mov %ebx,8(%esp) 
1248         mov %eax,(%esp)
1249
1250         /* by now we have skipped this method call*/
1251
1252 getClassContext_next:   
1253         movl 8(%esp),%eax
1254         movl (%eax),%eax
1255         movl %eax,(%esp) /*return adress*/
1256
1257         call codegen_findmethod
1258
1259         cmp $1,32(%esp)
1260         mov 8(%esp),%ebx
1261         add FrameSize(%eax),%ebx
1262         add $4,%ebx
1263         mov %ebx,8(%esp) /*store adress of next return adress*/
1264 getClassContext_nextRetStored:
1265
1266         mov MethodPointer(%eax),%ecx    /*get struct methodinfo*/
1267
1268         cmp $0,%ecx
1269         je getClassContext_nativeCall
1270         /*save class pointer*/
1271         movl $0,32(%esp)
1272 getClassContext_saveClassPointer:
1273         movl 20(%esp),%ebx      /*get temporary memory adress in stack*/
1274         movl offclassmethodinfo(%ecx),%edx /* get class pointer of method*/
1275         movl %edx,(%ebx) /*save */
1276         sub $4,%ebx     /*calculate next position */
1277         movl %ebx,20(%esp) /* check if the new adress would overwrite our working data */
1278         cmp %ebx,16(%esp)
1279         je getClassContext_incStack
1280 getClassContext_checkLeave:
1281         
1282         cmp 12(%esp),%ecx       /*check if we reached the toplevel method of our thread*/
1283         je  getClassContext_leave /*yes ->leave*/
1284
1285 /*DEBUGING*/
1286 /*      mov %ecx,(%esp)
1287         call temporaryGetClassContextHelper
1288 */
1289         
1290         
1291         jmp getClassContext_next /*continue*/
1292
1293
1294 getClassContext_nativeCall:
1295         movl $1,32(%esp)
1296         movl 4(%esp),%eax       /*get top most element on stackframe help information stack*/
1297         test %eax,%eax
1298         jz getClassContext_leave
1299         movl 0(%eax),%ecx 
1300         movl %ecx,4(%esp)
1301         addl $8,%eax
1302         movl (%eax),%ecx
1303         addl $4,%eax
1304         movl %eax,8(%esp)
1305         
1306         cmp $0,%ecx
1307         je getClassContext_checkLeave
1308         jmp getClassContext_saveClassPointer
1309
1310 getClassContext_incStack:
1311         /*make another 64 in our temporary storage free and store the workingdata */
1312         movl %esp,%edx
1313         subl $40,%esp /*should be 32*/
1314         push 32(%edx)
1315         push 28(%edx)
1316         push 24(%edx)
1317         push 20(%edx)
1318         push 16(%edx)
1319         push 12(%edx)
1320         push 8(%edx)
1321         push 4(%edx)
1322         push 0(%edx)
1323         subl $64,16(%esp)
1324
1325         jmp getClassContext_checkLeave /* continue */
1326
1327 getClassContext_leave:
1328 /*DEBUGING*/
1329 /*      mov %ecx,(%esp)
1330         call temporaryGetClassContextHelper*/
1331
1332         /*call collector function with begin/end of temporary classarray*/
1333         push 24(%esp)
1334         push 24(%esp)
1335         
1336         movl 32(%esp),%eax
1337         add $4,%eax
1338         movl (%eax),%ebx
1339         call *%ebx
1340
1341         /* free stack memory of this function*/
1342         mov 32(%esp),%esp
1343         add $8,%esp
1344         ret
1345
1346
1347 asm_throw_and_handle_exception:
1348         sub $20,%esp /*build stack frame*/
1349         mov %ecx,16(%esp) /*save eip of problem */
1350         mov %eax,(%esp)
1351         movl $0,12(%esp) /*internal function -> no function description */
1352         call builtin_asm_get_stackframeinfo
1353         mov %eax,8(%esp)
1354         mov (%eax),%ecx
1355         mov %ecx,4(%esp)
1356         mov %esp,%ecx
1357         add $4,%ecx
1358         mov %ecx,(%eax)
1359         
1360 /*      mov string_java_lang_NullPointerException,%eax
1361         mov %eax,(%esp)*/
1362         call new_exception
1363         push %eax
1364         mov 8(%esp),%eax
1365         mov 12(%esp),%ecx
1366         mov %eax,(%ecx)
1367         pop %eax
1368         add $16,%esp
1369         pop %ecx
1370         jmp asm_handle_exception
1371         ret /*should never be reached */
1372
1373 asm_throw_and_handle_hardware_arithmetic_exception:
1374         sub $24,%esp /*build stack frame*/
1375         mov %ecx,20(%esp) /*save eip of problem */
1376         
1377         movl $0,16(%esp) /*internal function -> no function description */
1378         call builtin_asm_get_stackframeinfo
1379         mov %eax,12(%esp)
1380         mov (%eax),%ecx
1381         mov %ecx,8(%esp)
1382         mov %esp,%ecx
1383         add $8,%ecx
1384         mov %ecx,(%eax)
1385         
1386         mov string_java_lang_ArithmeticException,%eax
1387         mov %eax,(%esp)
1388         mov string_java_lang_ArithmeticException_message,%eax
1389         mov %eax,4(%esp)
1390
1391         call new_exception_message
1392
1393         push %eax
1394         mov 12(%esp),%eax
1395         mov 16(%esp),%ecx
1396         mov %eax,(%ecx)
1397         pop %eax
1398         add $20,%esp
1399         pop %ecx
1400         jmp asm_handle_exception
1401         ret /*should never be reached */
1402
1403 asm_builtin_new:
1404 /*optimize a littlebit */
1405                 mov %esp,%eax
1406 /*DEBUG*/
1407 /*              push %eax
1408                 call i386_native_stub_debug
1409                 pop %eax */
1410                 
1411                 movl 4(%esp),%eax
1412                 mov     offclassinit(%eax),%ecx     /* get initialized flag           */
1413                 test    %ecx,%ecx
1414                 jnz             L_builtin_new_noinit
1415
1416                 sub             $16,%esp                                 /* build stack frame (4 * 4 bytes) */
1417
1418                 mov             20(%esp),%eax
1419                 mov             %eax,(%esp)
1420
1421                 call    builtin_asm_get_stackframeinfo
1422                 movl    $0,12(%esp)
1423                 mov     %eax,8(%esp)
1424                 mov     (%eax),%ebx
1425                 mov     %ebx,4(%esp)
1426                 mov     %esp,%ecx
1427                 add     $4,%ecx
1428                 mov     %ecx,(%eax)
1429
1430                 call    builtin_new
1431
1432                 mov     4(%esp),%ebx
1433                 mov     8(%esp),%ecx
1434                 mov     %ebx,(%ecx)
1435
1436                 add             $16,%esp
1437
1438                 jmp L_builtin_new_patch
1439
1440
1441 L_builtin_new_noinit:
1442                 mov 4(%esp),%eax
1443                 push %eax
1444                 call builtin_new
1445                 add $4,%esp
1446                 /*jmp L_builtin_new_patch*/
1447
1448 L_builtin_new_patch:
1449 /*add patching code here */
1450                 lea builtin_new,%edx
1451                 mov (%esp),%ecx
1452                 mov %edx,-6(%ecx)       /*patch calling instruction, t directly call builtin_new the next time*/
1453                 ret
1454
1455
1456
1457
1458
1459 asm_get_stackTrace:
1460         push %ebp /*(%ebp-4)*/
1461         mov %esp,%ebp
1462         add $4,%ebp
1463         push %edi /*(%ebp-8)*/
1464         push %esi /*(%ebp-12)*/
1465         push %ebx /*(%ebp-16)*/
1466         call builtin_asm_get_stackframeinfo
1467         movl (%eax),%eax
1468         pushl 0(%eax) /*(%ebp-20)*/
1469         lea 12(%eax),%edi
1470         call builtin_asm_get_threadrootmethod
1471         pushl %eax /*(%ebp-24)*/
1472
1473         pushl (%edi)
1474 asm_get_stackTraceLoop:
1475         call codegen_findmethod
1476         mov %eax,%esi
1477         add $4,%esp
1478         pushl $1 /*no indent*/
1479
1480         mov (%edi),%edx
1481         sub $4,%edx
1482
1483 get_stackTrace_line:
1484         movl LineNumberTableSize(%esi),%ecx
1485         test    %ecx,%ecx /* skip if empty line table */
1486         je      get_stackTrace_noLineInfo
1487
1488         movl LineNumberTableStart(%esi),%ebx
1489         
1490 get_stackTrace_lineLoop:
1491         cmp %edx,LinePC(%ebx)
1492         jg get_stackTrace_nextLineInfo
1493
1494         pushl LineLine(%ebx)
1495         jmp get_stackTrace_cont
1496
1497 get_stackTrace_nextLineInfo:    
1498         lea LineEntrySize(%ebx),%ebx
1499         dec %ecx
1500         test %ecx,%ecx
1501
1502         jne get_stackTrace_lineLoop
1503
1504 get_stackTrace_noLineInfo:
1505         pushl $0
1506
1507
1508 get_stackTrace_cont:
1509         pushl (%edi) /*4*/
1510         pushl MethodPointer(%esi)
1511         pushl $0 /*8(%ebp)*/ /*exception ptr*/
1512         call builtin_trace_exception
1513         add $12,%esp
1514
1515         movl MethodPointer(%esi),%eax
1516         movl %eax,4(%esp)
1517         test %eax,%eax
1518         je get_stackTrace_nat
1519
1520         cmp %eax,-24(%ebp)
1521         je get_stackTrace_leave
1522
1523         mov FrameSize(%esi),%eax
1524         add $4,%edi
1525         add %eax,%edi
1526         pushl (%edi)
1527         jmp asm_get_stackTraceLoop
1528
1529 get_stackTrace_nat:
1530         add $8,%esp
1531         movl -20(%ebp),%eax
1532         cmp $0,%eax
1533         je get_stackTrace_leave
1534         movl  0(%eax),%ebx
1535         movl  %ebx,-20(%ebp)
1536         pushl 8(%eax)
1537         pushl $0
1538         lea 12(%eax),%edi
1539         pushl (%edi)
1540         jmp asm_get_stackTraceLoop
1541
1542 get_stackTrace_leave:
1543         mov %esp,%eax
1544         lea -24(%ebp),%ebx
1545         push %ebx
1546         push %eax
1547         push 4(%ebp)
1548         call builtin_stacktrace_copy
1549
1550         lea -16(%ebp),%esp
1551         pop %ebx
1552         pop %esi
1553         pop %edi
1554         pop %ebp
1555         ret
1556
1557
1558 asm_getclassvalues_atomic:
1559 _crit_restart2:
1560         mov     4(%esp),%ecx        /* super */
1561         mov     8(%esp),%edx        /* sub */
1562 _crit_begin2:
1563         mov     offbaseval(%ecx),%eax
1564         mov     offdiffval(%ecx),%ecx
1565         mov     offbaseval(%edx),%edx
1566 _crit_end2:
1567         push    %ebx
1568         mov     16(%esp),%ebx      /* out */
1569         mov     %eax,offcast_super_baseval(%ebx)
1570         mov     %ecx,offcast_super_diffval(%ebx)
1571         mov     %edx,offcast_sub_baseval(%ebx)
1572         pop     %ebx
1573         ret
1574
1575         .data
1576
1577 asm_criticalsections:
1578 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1579         .long   _crit_begin1
1580         .long   _crit_end1
1581         .long   _crit_restart1
1582         .long   _crit_begin2
1583         .long   _crit_end2
1584         .long   _crit_restart2
1585 #endif
1586         .long 0
1587
1588 /*
1589  * These are local overrides for various environment variables in Emacs.
1590  * Please do not remove this and leave it at the end of the file, where
1591  * Emacs will automagically detect them.
1592  * ---------------------------------------------------------------------
1593  * Local variables:
1594  * mode: asm
1595  * indent-tabs-mode: t
1596  * c-basic-offset: 4
1597  * tab-width: 4
1598  * End:
1599  */