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