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