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