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